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