1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2004-07 Applied Micro Circuits Corporation. 5 * Copyright (c) 2004-05 Vinod Kashyap 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 /* 33 * AMCC'S 3ware driver for 9000 series storage controllers. 34 * 35 * Author: Vinod Kashyap 36 * Modifications by: Adam Radford 37 * Modifications by: Manjunath Ranganathaiah 38 */ 39 40 /* 41 * Common Layer initialization functions. 42 */ 43 44 #include "tw_osl_share.h" 45 #include "tw_cl_share.h" 46 #include "tw_cl_fwif.h" 47 #include "tw_cl_ioctl.h" 48 #include "tw_cl.h" 49 #include "tw_cl_externs.h" 50 #include "tw_osl_ioctl.h" 51 52 /* 53 * Function name: tw_cl_ctlr_supported 54 * Description: Determines if a controller is supported. 55 * 56 * Input: vendor_id -- vendor id of the controller 57 * device_id -- device id of the controller 58 * Output: None 59 * Return value: TW_CL_TRUE-- controller supported 60 * TW_CL_FALSE-- controller not supported 61 */ 62 TW_INT32 63 tw_cl_ctlr_supported(TW_INT32 vendor_id, TW_INT32 device_id) 64 { 65 if ((vendor_id == TW_CL_VENDOR_ID) && 66 ((device_id == TW_CL_DEVICE_ID_9K) || 67 (device_id == TW_CL_DEVICE_ID_9K_X) || 68 (device_id == TW_CL_DEVICE_ID_9K_E) || 69 (device_id == TW_CL_DEVICE_ID_9K_SA))) 70 return(TW_CL_TRUE); 71 return(TW_CL_FALSE); 72 } 73 74 /* 75 * Function name: tw_cl_get_pci_bar_info 76 * Description: Returns PCI BAR info. 77 * 78 * Input: device_id -- device id of the controller 79 * bar_type -- type of PCI BAR in question 80 * Output: bar_num -- PCI BAR number corresponding to bar_type 81 * bar0_offset -- byte offset from BAR 0 (0x10 in 82 * PCI config space) 83 * bar_size -- size, in bytes, of the BAR in question 84 * Return value: 0 -- success 85 * non-zero -- failure 86 */ 87 TW_INT32 88 tw_cl_get_pci_bar_info(TW_INT32 device_id, TW_INT32 bar_type, 89 TW_INT32 *bar_num, TW_INT32 *bar0_offset, TW_INT32 *bar_size) 90 { 91 TW_INT32 error = TW_OSL_ESUCCESS; 92 93 switch(device_id) { 94 case TW_CL_DEVICE_ID_9K: 95 switch(bar_type) { 96 case TW_CL_BAR_TYPE_IO: 97 *bar_num = 0; 98 *bar0_offset = 0; 99 *bar_size = 4; 100 break; 101 102 case TW_CL_BAR_TYPE_MEM: 103 *bar_num = 1; 104 *bar0_offset = 0x4; 105 *bar_size = 8; 106 break; 107 108 case TW_CL_BAR_TYPE_SBUF: 109 *bar_num = 2; 110 *bar0_offset = 0xC; 111 *bar_size = 8; 112 break; 113 } 114 break; 115 116 case TW_CL_DEVICE_ID_9K_X: 117 case TW_CL_DEVICE_ID_9K_E: 118 case TW_CL_DEVICE_ID_9K_SA: 119 switch(bar_type) { 120 case TW_CL_BAR_TYPE_IO: 121 *bar_num = 2; 122 *bar0_offset = 0x10; 123 *bar_size = 4; 124 break; 125 126 case TW_CL_BAR_TYPE_MEM: 127 *bar_num = 1; 128 *bar0_offset = 0x8; 129 *bar_size = 8; 130 break; 131 132 case TW_CL_BAR_TYPE_SBUF: 133 *bar_num = 0; 134 *bar0_offset = 0; 135 *bar_size = 8; 136 break; 137 } 138 break; 139 140 default: 141 error = TW_OSL_ENOTTY; 142 break; 143 } 144 145 return(error); 146 } 147 148 /* 149 * Function name: tw_cl_get_mem_requirements 150 * Description: Provides info about Common Layer requirements for a 151 * controller, given the controller type (in 'flags'). 152 * Input: ctlr_handle -- controller handle 153 * flags -- more info passed by the OS Layer 154 * device_id -- device id of the controller 155 * max_simult_reqs -- maximum # of simultaneous 156 * requests that the OS Layer expects 157 * the Common Layer to support 158 * max_aens -- maximun # of AEN's needed to be supported 159 * Output: alignment -- alignment needed for all DMA'able 160 * buffers 161 * sg_size_factor -- every SG element should have a size 162 * that's a multiple of this number 163 * non_dma_mem_size -- # of bytes of memory needed for 164 * non-DMA purposes 165 * dma_mem_size -- # of bytes of DMA'able memory needed 166 * per_req_dma_mem_size -- # of bytes of DMA'able memory 167 * needed per request, if applicable 168 * per_req_non_dma_mem_size -- # of bytes of memory needed 169 * per request for non-DMA purposes, 170 * if applicable 171 * Output: None 172 * Return value: 0 -- success 173 * non-zero-- failure 174 */ 175 TW_INT32 176 tw_cl_get_mem_requirements(struct tw_cl_ctlr_handle *ctlr_handle, 177 TW_UINT32 flags, TW_INT32 device_id, TW_INT32 max_simult_reqs, 178 TW_INT32 max_aens, TW_UINT32 *alignment, TW_UINT32 *sg_size_factor, 179 TW_UINT32 *non_dma_mem_size, TW_UINT32 *dma_mem_size 180 ) 181 { 182 if (device_id == 0) 183 device_id = TW_CL_DEVICE_ID_9K; 184 185 if (max_simult_reqs > TW_CL_MAX_SIMULTANEOUS_REQUESTS) { 186 tw_cl_create_event(ctlr_handle, TW_CL_FALSE, 187 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 188 0x1000, 0x1, TW_CL_SEVERITY_ERROR_STRING, 189 "Too many simultaneous requests to support!", 190 "requested = %d, supported = %d, error = %d\n", 191 max_simult_reqs, TW_CL_MAX_SIMULTANEOUS_REQUESTS, 192 TW_OSL_EBIG); 193 return(TW_OSL_EBIG); 194 } 195 196 *alignment = TWA_ALIGNMENT(device_id); 197 *sg_size_factor = TWA_SG_ELEMENT_SIZE_FACTOR(device_id); 198 199 /* 200 * Total non-DMA memory needed is the sum total of memory needed for 201 * the controller context, request packets (including the 1 needed for 202 * CL internal requests), and event packets. 203 */ 204 205 *non_dma_mem_size = sizeof(struct tw_cli_ctlr_context) + 206 (sizeof(struct tw_cli_req_context) * max_simult_reqs) + 207 (sizeof(struct tw_cl_event_packet) * max_aens); 208 209 /* 210 * Total DMA'able memory needed is the sum total of memory needed for 211 * all command packets (including the 1 needed for CL internal 212 * requests), and memory needed to hold the payload for internal 213 * requests. 214 */ 215 216 *dma_mem_size = (sizeof(struct tw_cl_command_packet) * 217 (max_simult_reqs)) + (TW_CLI_SECTOR_SIZE); 218 219 return(0); 220 } 221 222 /* 223 * Function name: tw_cl_init_ctlr 224 * Description: Initializes driver data structures for the controller. 225 * 226 * Input: ctlr_handle -- controller handle 227 * flags -- more info passed by the OS Layer 228 * device_id -- device id of the controller 229 * max_simult_reqs -- maximum # of simultaneous requests 230 * that the OS Layer expects the Common 231 * Layer to support 232 * max_aens -- maximun # of AEN's needed to be supported 233 * non_dma_mem -- ptr to allocated non-DMA memory 234 * dma_mem -- ptr to allocated DMA'able memory 235 * dma_mem_phys -- physical address of dma_mem 236 * Output: None 237 * Return value: 0 -- success 238 * non-zero-- failure 239 */ 240 TW_INT32 241 tw_cl_init_ctlr(struct tw_cl_ctlr_handle *ctlr_handle, TW_UINT32 flags, 242 TW_INT32 device_id, TW_INT32 max_simult_reqs, TW_INT32 max_aens, 243 TW_VOID *non_dma_mem, TW_VOID *dma_mem, TW_UINT64 dma_mem_phys 244 ) 245 { 246 struct tw_cli_ctlr_context *ctlr; 247 struct tw_cli_req_context *req; 248 TW_UINT8 *free_non_dma_mem; 249 TW_INT32 error = TW_OSL_ESUCCESS; 250 TW_INT32 i; 251 252 tw_cli_dbg_printf(3, ctlr_handle, tw_osl_cur_func(), "entered"); 253 254 if (flags & TW_CL_START_CTLR_ONLY) { 255 ctlr = (struct tw_cli_ctlr_context *) 256 (ctlr_handle->cl_ctlr_ctxt); 257 goto start_ctlr; 258 } 259 260 if (max_simult_reqs > TW_CL_MAX_SIMULTANEOUS_REQUESTS) { 261 tw_cl_create_event(ctlr_handle, TW_CL_FALSE, 262 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 263 0x1000, 0x1, TW_CL_SEVERITY_ERROR_STRING, 264 "Too many simultaneous requests to support!", 265 "requested = %d, supported = %d, error = %d\n", 266 max_simult_reqs, TW_CL_MAX_SIMULTANEOUS_REQUESTS, 267 TW_OSL_EBIG); 268 return(TW_OSL_EBIG); 269 } 270 271 if ((non_dma_mem == TW_CL_NULL) || (dma_mem == TW_CL_NULL) 272 ) { 273 tw_cl_create_event(ctlr_handle, TW_CL_FALSE, 274 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 275 0x1001, 0x1, TW_CL_SEVERITY_ERROR_STRING, 276 "Insufficient memory for Common Layer's internal usage", 277 "error = %d\n", TW_OSL_ENOMEM); 278 return(TW_OSL_ENOMEM); 279 } 280 281 tw_osl_memzero(non_dma_mem, sizeof(struct tw_cli_ctlr_context) + 282 (sizeof(struct tw_cli_req_context) * max_simult_reqs) + 283 (sizeof(struct tw_cl_event_packet) * max_aens)); 284 285 tw_osl_memzero(dma_mem, 286 (sizeof(struct tw_cl_command_packet) * 287 max_simult_reqs) + 288 TW_CLI_SECTOR_SIZE); 289 290 free_non_dma_mem = (TW_UINT8 *)non_dma_mem; 291 292 ctlr = (struct tw_cli_ctlr_context *)free_non_dma_mem; 293 free_non_dma_mem += sizeof(struct tw_cli_ctlr_context); 294 295 ctlr_handle->cl_ctlr_ctxt = ctlr; 296 ctlr->ctlr_handle = ctlr_handle; 297 298 ctlr->device_id = (TW_UINT32)device_id; 299 ctlr->arch_id = TWA_ARCH_ID(device_id); 300 ctlr->flags = flags; 301 ctlr->sg_size_factor = TWA_SG_ELEMENT_SIZE_FACTOR(device_id); 302 ctlr->max_simult_reqs = max_simult_reqs; 303 ctlr->max_aens_supported = max_aens; 304 305 /* Initialize queues of CL internal request context packets. */ 306 tw_cli_req_q_init(ctlr, TW_CLI_FREE_Q); 307 tw_cli_req_q_init(ctlr, TW_CLI_BUSY_Q); 308 tw_cli_req_q_init(ctlr, TW_CLI_PENDING_Q); 309 tw_cli_req_q_init(ctlr, TW_CLI_COMPLETE_Q); 310 tw_cli_req_q_init(ctlr, TW_CLI_RESET_Q); 311 312 /* Initialize all locks used by CL. */ 313 ctlr->gen_lock = &(ctlr->gen_lock_handle); 314 tw_osl_init_lock(ctlr_handle, "tw_cl_gen_lock", ctlr->gen_lock); 315 ctlr->io_lock = &(ctlr->io_lock_handle); 316 tw_osl_init_lock(ctlr_handle, "tw_cl_io_lock", ctlr->io_lock); 317 318 /* Initialize CL internal request context packets. */ 319 ctlr->req_ctxt_buf = (struct tw_cli_req_context *)free_non_dma_mem; 320 free_non_dma_mem += (sizeof(struct tw_cli_req_context) * 321 max_simult_reqs); 322 323 ctlr->cmd_pkt_buf = (struct tw_cl_command_packet *)dma_mem; 324 ctlr->cmd_pkt_phys = dma_mem_phys; 325 326 ctlr->internal_req_data = (TW_UINT8 *) 327 (ctlr->cmd_pkt_buf + 328 max_simult_reqs); 329 ctlr->internal_req_data_phys = ctlr->cmd_pkt_phys + 330 (sizeof(struct tw_cl_command_packet) * 331 max_simult_reqs); 332 333 for (i = 0; i < max_simult_reqs; i++) { 334 req = &(ctlr->req_ctxt_buf[i]); 335 336 req->cmd_pkt = &(ctlr->cmd_pkt_buf[i]); 337 req->cmd_pkt_phys = ctlr->cmd_pkt_phys + 338 (i * sizeof(struct tw_cl_command_packet)); 339 340 req->request_id = i; 341 req->ctlr = ctlr; 342 343 /* Insert request into the free queue. */ 344 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q); 345 } 346 347 /* Initialize the AEN queue. */ 348 ctlr->aen_queue = (struct tw_cl_event_packet *)free_non_dma_mem; 349 350 start_ctlr: 351 /* 352 * Disable interrupts. Interrupts will be enabled in tw_cli_start_ctlr 353 * (only) if initialization succeeded. 354 */ 355 tw_cli_disable_interrupts(ctlr); 356 357 /* Initialize the controller. */ 358 if ((error = tw_cli_start_ctlr(ctlr))) { 359 /* Soft reset the controller, and try one more time. */ 360 tw_cl_create_event(ctlr_handle, TW_CL_FALSE, 361 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 362 0x1002, 0x1, TW_CL_SEVERITY_ERROR_STRING, 363 "Controller initialization failed. Retrying...", 364 "error = %d\n", error); 365 if ((error = tw_cli_soft_reset(ctlr))) { 366 tw_cl_create_event(ctlr_handle, TW_CL_FALSE, 367 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 368 0x1003, 0x1, TW_CL_SEVERITY_ERROR_STRING, 369 "Controller soft reset failed", 370 "error = %d\n", error); 371 return(error); 372 } else if ((error = tw_cli_start_ctlr(ctlr))) { 373 tw_cl_create_event(ctlr_handle, TW_CL_FALSE, 374 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 375 0x1004, 0x1, TW_CL_SEVERITY_ERROR_STRING, 376 "Controller initialization retry failed", 377 "error = %d\n", error); 378 return(error); 379 } 380 } 381 /* Notify some info about the controller to the OSL. */ 382 tw_cli_notify_ctlr_info(ctlr); 383 384 /* Mark the controller active. */ 385 ctlr->active = TW_CL_TRUE; 386 return(error); 387 } 388 389 /* 390 * Function name: tw_cli_start_ctlr 391 * Description: Establishes a logical connection with the controller. 392 * Determines whether or not the driver is compatible 393 * with the firmware on the controller, before proceeding 394 * to work with it. 395 * 396 * Input: ctlr -- ptr to per ctlr structure 397 * Output: None 398 * Return value: 0 -- success 399 * non-zero-- failure 400 */ 401 TW_INT32 402 tw_cli_start_ctlr(struct tw_cli_ctlr_context *ctlr) 403 { 404 TW_UINT16 fw_on_ctlr_srl = 0; 405 TW_UINT16 fw_on_ctlr_arch_id = 0; 406 TW_UINT16 fw_on_ctlr_branch = 0; 407 TW_UINT16 fw_on_ctlr_build = 0; 408 TW_UINT32 init_connect_result = 0; 409 TW_INT32 error = TW_OSL_ESUCCESS; 410 411 tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 412 413 /* Wait for the controller to become ready. */ 414 if ((error = tw_cli_poll_status(ctlr, 415 TWA_STATUS_MICROCONTROLLER_READY, 416 TW_CLI_REQUEST_TIMEOUT_PERIOD))) { 417 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 418 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 419 0x1009, 0x1, TW_CL_SEVERITY_ERROR_STRING, 420 "Microcontroller not ready", 421 "error = %d", error); 422 return(error); 423 } 424 /* Drain the response queue. */ 425 if ((error = tw_cli_drain_response_queue(ctlr))) { 426 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 427 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 428 0x100A, 0x1, TW_CL_SEVERITY_ERROR_STRING, 429 "Can't drain response queue", 430 "error = %d", error); 431 return(error); 432 } 433 /* Establish a logical connection with the controller. */ 434 if ((error = tw_cli_init_connection(ctlr, 435 (TW_UINT16)(ctlr->max_simult_reqs), 436 TWA_EXTENDED_INIT_CONNECT, TWA_CURRENT_FW_SRL, 437 (TW_UINT16)(ctlr->arch_id), 438 TWA_CURRENT_FW_BRANCH(ctlr->arch_id), 439 TWA_CURRENT_FW_BUILD(ctlr->arch_id), 440 &fw_on_ctlr_srl, &fw_on_ctlr_arch_id, 441 &fw_on_ctlr_branch, &fw_on_ctlr_build, 442 &init_connect_result))) { 443 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 444 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 445 0x100B, 0x2, TW_CL_SEVERITY_WARNING_STRING, 446 "Can't initialize connection in current mode", 447 "error = %d", error); 448 return(error); 449 } 450 { 451 /* See if we can at least work with the firmware on the 452 * controller in the current mode. 453 */ 454 if (init_connect_result & TWA_CTLR_FW_COMPATIBLE) { 455 /* Yes, we can. Make note of the operating mode. */ 456 if (init_connect_result & TWA_CTLR_FW_SAME_OR_NEWER) { 457 ctlr->working_srl = TWA_CURRENT_FW_SRL; 458 ctlr->working_branch = 459 TWA_CURRENT_FW_BRANCH(ctlr->arch_id); 460 ctlr->working_build = 461 TWA_CURRENT_FW_BUILD(ctlr->arch_id); 462 } else { 463 ctlr->working_srl = fw_on_ctlr_srl; 464 ctlr->working_branch = fw_on_ctlr_branch; 465 ctlr->working_build = fw_on_ctlr_build; 466 } 467 } else { 468 /* 469 * No, we can't. See if we can at least work with 470 * it in the base mode. 471 */ 472 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 473 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 474 0x1010, 0x2, TW_CL_SEVERITY_WARNING_STRING, 475 "Driver/Firmware mismatch. " 476 "Negotiating for base level...", 477 " "); 478 if ((error = tw_cli_init_connection(ctlr, 479 (TW_UINT16)(ctlr->max_simult_reqs), 480 TWA_EXTENDED_INIT_CONNECT, 481 TWA_BASE_FW_SRL, 482 (TW_UINT16)(ctlr->arch_id), 483 TWA_BASE_FW_BRANCH, TWA_BASE_FW_BUILD, 484 &fw_on_ctlr_srl, &fw_on_ctlr_arch_id, 485 &fw_on_ctlr_branch, &fw_on_ctlr_build, 486 &init_connect_result))) { 487 tw_cl_create_event(ctlr->ctlr_handle, 488 TW_CL_FALSE, 489 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 490 0x1011, 0x1, 491 TW_CL_SEVERITY_ERROR_STRING, 492 "Can't initialize connection in " 493 "base mode", 494 " "); 495 return(error); 496 } 497 if (!(init_connect_result & TWA_CTLR_FW_COMPATIBLE)) { 498 /* 499 * The firmware on the controller is not even 500 * compatible with our base mode. We cannot 501 * work with it. Bail... 502 */ 503 return(1); 504 } 505 /* 506 * We can work with this firmware, but only in 507 * base mode. 508 */ 509 ctlr->working_srl = TWA_BASE_FW_SRL; 510 ctlr->working_branch = TWA_BASE_FW_BRANCH; 511 ctlr->working_build = TWA_BASE_FW_BUILD; 512 ctlr->operating_mode = TWA_BASE_MODE; 513 } 514 ctlr->fw_on_ctlr_srl = fw_on_ctlr_srl; 515 ctlr->fw_on_ctlr_branch = fw_on_ctlr_branch; 516 ctlr->fw_on_ctlr_build = fw_on_ctlr_build; 517 } 518 519 /* Drain the AEN queue */ 520 if ((error = tw_cli_drain_aen_queue(ctlr))) 521 /* 522 * We will just print that we couldn't drain the AEN queue. 523 * There's no need to bail out. 524 */ 525 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 526 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 527 0x1014, 0x2, TW_CL_SEVERITY_WARNING_STRING, 528 "Can't drain AEN queue", 529 "error = %d", error); 530 531 /* Enable interrupts. */ 532 tw_cli_enable_interrupts(ctlr); 533 534 return(TW_OSL_ESUCCESS); 535 } 536 537 /* 538 * Function name: tw_cl_shutdown_ctlr 539 * Description: Closes logical connection with the controller. 540 * 541 * Input: ctlr -- ptr to per ctlr structure 542 * flags -- more info passed by the OS Layer 543 * Output: None 544 * Return value: 0 -- success 545 * non-zero-- failure 546 */ 547 TW_INT32 548 tw_cl_shutdown_ctlr(struct tw_cl_ctlr_handle *ctlr_handle, TW_UINT32 flags) 549 { 550 struct tw_cli_ctlr_context *ctlr = 551 (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt); 552 TW_INT32 error; 553 554 tw_cli_dbg_printf(3, ctlr_handle, tw_osl_cur_func(), "entered"); 555 /* 556 * Mark the controller as inactive, disable any further interrupts, 557 * and notify the controller that we are going down. 558 */ 559 ctlr->active = TW_CL_FALSE; 560 561 tw_cli_disable_interrupts(ctlr); 562 563 /* Let the controller know that we are going down. */ 564 if ((error = tw_cli_init_connection(ctlr, TWA_SHUTDOWN_MESSAGE_CREDITS, 565 0, 0, 0, 0, 0, TW_CL_NULL, TW_CL_NULL, TW_CL_NULL, 566 TW_CL_NULL, TW_CL_NULL))) 567 tw_cl_create_event(ctlr_handle, TW_CL_FALSE, 568 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 569 0x1015, 0x1, TW_CL_SEVERITY_ERROR_STRING, 570 "Can't close connection with controller", 571 "error = %d", error); 572 573 if (flags & TW_CL_STOP_CTLR_ONLY) 574 goto ret; 575 576 /* Destroy all locks used by CL. */ 577 tw_osl_destroy_lock(ctlr_handle, ctlr->gen_lock); 578 tw_osl_destroy_lock(ctlr_handle, ctlr->io_lock); 579 580 ret: 581 return(error); 582 } 583 584 /* 585 * Function name: tw_cli_init_connection 586 * Description: Sends init_connection cmd to firmware 587 * 588 * Input: ctlr -- ptr to per ctlr structure 589 * message_credits -- max # of requests that we might send 590 * down simultaneously. This will be 591 * typically set to 256 at init-time or 592 * after a reset, and to 1 at shutdown-time 593 * set_features -- indicates if we intend to use 64-bit 594 * sg, also indicates if we want to do a 595 * basic or an extended init_connection; 596 * 597 * Note: The following input/output parameters are valid, only in case of an 598 * extended init_connection: 599 * 600 * current_fw_srl -- srl of fw we are bundled 601 * with, if any; 0 otherwise 602 * current_fw_arch_id -- arch_id of fw we are bundled 603 * with, if any; 0 otherwise 604 * current_fw_branch -- branch # of fw we are bundled 605 * with, if any; 0 otherwise 606 * current_fw_build -- build # of fw we are bundled 607 * with, if any; 0 otherwise 608 * Output: fw_on_ctlr_srl -- srl of fw on ctlr 609 * fw_on_ctlr_arch_id -- arch_id of fw on ctlr 610 * fw_on_ctlr_branch -- branch # of fw on ctlr 611 * fw_on_ctlr_build -- build # of fw on ctlr 612 * init_connect_result -- result bitmap of fw response 613 * Return value: 0 -- success 614 * non-zero-- failure 615 */ 616 TW_INT32 617 tw_cli_init_connection(struct tw_cli_ctlr_context *ctlr, 618 TW_UINT16 message_credits, TW_UINT32 set_features, 619 TW_UINT16 current_fw_srl, TW_UINT16 current_fw_arch_id, 620 TW_UINT16 current_fw_branch, TW_UINT16 current_fw_build, 621 TW_UINT16 *fw_on_ctlr_srl, TW_UINT16 *fw_on_ctlr_arch_id, 622 TW_UINT16 *fw_on_ctlr_branch, TW_UINT16 *fw_on_ctlr_build, 623 TW_UINT32 *init_connect_result) 624 { 625 struct tw_cli_req_context *req; 626 struct tw_cl_command_init_connect *init_connect; 627 TW_INT32 error = TW_OSL_EBUSY; 628 629 tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 630 631 /* Get a request packet. */ 632 if ((req = tw_cli_get_request(ctlr 633 )) == TW_CL_NULL) 634 goto out; 635 636 req->flags |= TW_CLI_REQ_FLAGS_INTERNAL; 637 638 /* Build the cmd pkt. */ 639 init_connect = &(req->cmd_pkt->command.cmd_pkt_7k.init_connect); 640 641 req->cmd_pkt->cmd_hdr.header_desc.size_header = 128; 642 643 init_connect->res1__opcode = 644 BUILD_RES__OPCODE(0, TWA_FW_CMD_INIT_CONNECTION); 645 init_connect->request_id = 646 (TW_UINT8)(TW_CL_SWAP16(req->request_id)); 647 init_connect->message_credits = TW_CL_SWAP16(message_credits); 648 init_connect->features = TW_CL_SWAP32(set_features); 649 if (ctlr->flags & TW_CL_64BIT_ADDRESSES) 650 init_connect->features |= TW_CL_SWAP32(TWA_64BIT_SG_ADDRESSES); 651 if (set_features & TWA_EXTENDED_INIT_CONNECT) { 652 /* 653 * Fill in the extra fields needed for an extended 654 * init_connect. 655 */ 656 init_connect->size = 6; 657 init_connect->fw_srl = TW_CL_SWAP16(current_fw_srl); 658 init_connect->fw_arch_id = TW_CL_SWAP16(current_fw_arch_id); 659 init_connect->fw_branch = TW_CL_SWAP16(current_fw_branch); 660 init_connect->fw_build = TW_CL_SWAP16(current_fw_build); 661 } else 662 init_connect->size = 3; 663 664 /* Submit the command, and wait for it to complete. */ 665 error = tw_cli_submit_and_poll_request(req, 666 TW_CLI_REQUEST_TIMEOUT_PERIOD); 667 if (error) 668 goto out; 669 if ((error = init_connect->status)) { 670 #if 0 671 tw_cli_create_ctlr_event(ctlr, 672 TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR, 673 &(req->cmd_pkt->cmd_hdr)); 674 #endif // 0 675 goto out; 676 } 677 if (set_features & TWA_EXTENDED_INIT_CONNECT) { 678 *fw_on_ctlr_srl = TW_CL_SWAP16(init_connect->fw_srl); 679 *fw_on_ctlr_arch_id = TW_CL_SWAP16(init_connect->fw_arch_id); 680 *fw_on_ctlr_branch = TW_CL_SWAP16(init_connect->fw_branch); 681 *fw_on_ctlr_build = TW_CL_SWAP16(init_connect->fw_build); 682 *init_connect_result = TW_CL_SWAP32(init_connect->result); 683 } 684 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q); 685 return(error); 686 687 out: 688 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 689 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 690 0x1016, 0x1, TW_CL_SEVERITY_ERROR_STRING, 691 "init_connection failed", 692 "error = %d", error); 693 if (req) 694 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q); 695 return(error); 696 } 697