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 */ 180TW_INT32 181tw_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 + 1)) + 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 + 1)) + (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 */ 248TW_INT32 249tw_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 + 1)) + 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 + 1)) + 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 + 1; 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 * If 64 bit cmd pkt addresses are used, we will need to serialize 326 * writes to the hardware (across registers), since existing (G66) 327 * hardware will get confused if, for example, we wrote the low 32 bits 328 * of the cmd pkt address, followed by a response interrupt mask to the 329 * control register, followed by the high 32 bits of the cmd pkt 330 * address. It will then interpret the value written to the control 331 * register as the low cmd pkt address. So, for this case, we will 332 * make a note that we will need to synchronize control register writes 333 * with command register writes. 334 */ 335 if ((ctlr->flags & TW_CL_64BIT_ADDRESSES) && 336 ((ctlr->device_id == TW_CL_DEVICE_ID_9K) || 337 (ctlr->device_id == TW_CL_DEVICE_ID_9K_X) ||
|
340 ctlr->state |= TW_CLI_CTLR_STATE_G66_WORKAROUND_NEEDED; 341 ctlr->intr_lock = ctlr->io_lock; 342 } else { 343 ctlr->intr_lock = &(ctlr->intr_lock_handle); 344 tw_osl_init_lock(ctlr_handle, "tw_cl_intr_lock", 345 ctlr->intr_lock); 346 } 347 348 /* Initialize CL internal request context packets. */ 349 ctlr->req_ctxt_buf = (struct tw_cli_req_context *)free_non_dma_mem; 350 free_non_dma_mem += (sizeof(struct tw_cli_req_context) * 351 ( 352 max_simult_reqs + 353 1)); 354 355 ctlr->cmd_pkt_buf = (struct tw_cl_command_packet *)dma_mem; 356 ctlr->cmd_pkt_phys = dma_mem_phys; 357 358 ctlr->internal_req_data = (TW_UINT8 *) 359 (ctlr->cmd_pkt_buf + 360 ( 361 max_simult_reqs + 362 1)); 363 ctlr->internal_req_data_phys = ctlr->cmd_pkt_phys + 364 (sizeof(struct tw_cl_command_packet) * 365 ( 366 max_simult_reqs + 367 1)); 368 369 for (i = 0; 370 i < ( 371 max_simult_reqs + 372 1); i++) { 373 req = &(ctlr->req_ctxt_buf[i]); 374 375 req->cmd_pkt = &(ctlr->cmd_pkt_buf[i]); 376 req->cmd_pkt_phys = ctlr->cmd_pkt_phys + 377 (i * sizeof(struct tw_cl_command_packet)); 378 379 req->request_id = i; 380 req->ctlr = ctlr; 381 382 /* Insert request into the free queue. */ 383 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q); 384 } 385 386 /* Initialize the AEN queue. */ 387 ctlr->aen_queue = (struct tw_cl_event_packet *)free_non_dma_mem; 388 389 390start_ctlr: 391 /* 392 * Disable interrupts. Interrupts will be enabled in tw_cli_start_ctlr 393 * (only) if initialization succeeded. 394 */ 395 tw_cli_disable_interrupts(ctlr); 396 397 /* Initialize the controller. */ 398 if ((error = tw_cli_start_ctlr(ctlr))) { 399 /* Soft reset the controller, and try one more time. */ 400 tw_cl_create_event(ctlr_handle, TW_CL_FALSE, 401 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 402 0x1002, 0x1, TW_CL_SEVERITY_ERROR_STRING, 403 "Controller initialization failed. Retrying...", 404 "error = %d\n", error); 405 if ((error = tw_cli_soft_reset(ctlr))) { 406 tw_cl_create_event(ctlr_handle, TW_CL_FALSE, 407 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 408 0x1003, 0x1, TW_CL_SEVERITY_ERROR_STRING, 409 "Controller soft reset failed", 410 "error = %d\n", error); 411 return(error); 412 } else if ((error = tw_cli_start_ctlr(ctlr))) { 413 tw_cl_create_event(ctlr_handle, TW_CL_FALSE, 414 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 415 0x1004, 0x1, TW_CL_SEVERITY_ERROR_STRING, 416 "Controller initialization retry failed", 417 "error = %d\n", error); 418 return(error); 419 } 420 } 421 /* Notify some info about the controller to the OSL. */ 422 tw_cli_notify_ctlr_info(ctlr); 423 424 /* Mark the controller as active. */ 425 ctlr->state |= TW_CLI_CTLR_STATE_ACTIVE; 426 return(error); 427} 428 429/* 430 * Function name: tw_cli_start_ctlr 431 * Description: Establishes a logical connection with the controller. 432 * Determines whether or not the driver is compatible 433 * with the firmware on the controller, before proceeding 434 * to work with it. 435 * 436 * Input: ctlr -- ptr to per ctlr structure 437 * Output: None 438 * Return value: 0 -- success 439 * non-zero-- failure 440 */ 441TW_INT32 442tw_cli_start_ctlr(struct tw_cli_ctlr_context *ctlr) 443{ 444 TW_UINT16 fw_on_ctlr_srl = 0; 445 TW_UINT16 fw_on_ctlr_arch_id = 0; 446 TW_UINT16 fw_on_ctlr_branch = 0; 447 TW_UINT16 fw_on_ctlr_build = 0; 448 TW_UINT32 init_connect_result = 0; 449 TW_INT32 error = TW_OSL_ESUCCESS; 450 451 tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 452 453 /* Wait for the controller to become ready. */ 454 if ((error = tw_cli_poll_status(ctlr, 455 TWA_STATUS_MICROCONTROLLER_READY, 456 TW_CLI_REQUEST_TIMEOUT_PERIOD))) { 457 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 458 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 459 0x1009, 0x1, TW_CL_SEVERITY_ERROR_STRING, 460 "Microcontroller not ready", 461 "error = %d", error); 462 return(error); 463 } 464 /* Drain the response queue. */ 465 if ((error = tw_cli_drain_response_queue(ctlr))) { 466 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 467 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 468 0x100A, 0x1, TW_CL_SEVERITY_ERROR_STRING, 469 "Can't drain response queue", 470 "error = %d", error); 471 return(error); 472 } 473 /* Establish a logical connection with the controller. */ 474 if ((error = tw_cli_init_connection(ctlr, 475 (TW_UINT16)(ctlr->max_simult_reqs), 476 TWA_EXTENDED_INIT_CONNECT, TWA_CURRENT_FW_SRL, 477 (TW_UINT16)(ctlr->arch_id), 478 TWA_CURRENT_FW_BRANCH(ctlr->arch_id), 479 TWA_CURRENT_FW_BUILD(ctlr->arch_id), 480 &fw_on_ctlr_srl, &fw_on_ctlr_arch_id, 481 &fw_on_ctlr_branch, &fw_on_ctlr_build, 482 &init_connect_result))) { 483 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 484 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 485 0x100B, 0x2, TW_CL_SEVERITY_WARNING_STRING, 486 "Can't initialize connection in current mode", 487 "error = %d", error); 488 return(error); 489 } 490 { 491 /* See if we can at least work with the firmware on the 492 * controller in the current mode. 493 */ 494 if (init_connect_result & TWA_CTLR_FW_COMPATIBLE) { 495 /* Yes, we can. Make note of the operating mode. */ 496 if (init_connect_result & TWA_CTLR_FW_SAME_OR_NEWER) { 497 ctlr->working_srl = TWA_CURRENT_FW_SRL; 498 ctlr->working_branch = 499 TWA_CURRENT_FW_BRANCH(ctlr->arch_id); 500 ctlr->working_build = 501 TWA_CURRENT_FW_BUILD(ctlr->arch_id); 502 } else { 503 ctlr->working_srl = fw_on_ctlr_srl; 504 ctlr->working_branch = fw_on_ctlr_branch; 505 ctlr->working_build = fw_on_ctlr_build; 506 } 507 } else { 508 /* 509 * No, we can't. See if we can at least work with 510 * it in the base mode. 511 */ 512 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 513 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 514 0x1010, 0x2, TW_CL_SEVERITY_WARNING_STRING, 515 "Driver/Firmware mismatch. " 516 "Negotiating for base level...", 517 " "); 518 if ((error = tw_cli_init_connection(ctlr, 519 (TW_UINT16)(ctlr->max_simult_reqs), 520 TWA_EXTENDED_INIT_CONNECT, 521 TWA_BASE_FW_SRL, 522 (TW_UINT16)(ctlr->arch_id), 523 TWA_BASE_FW_BRANCH, TWA_BASE_FW_BUILD, 524 &fw_on_ctlr_srl, &fw_on_ctlr_arch_id, 525 &fw_on_ctlr_branch, &fw_on_ctlr_build, 526 &init_connect_result))) { 527 tw_cl_create_event(ctlr->ctlr_handle, 528 TW_CL_FALSE, 529 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 530 0x1011, 0x1, 531 TW_CL_SEVERITY_ERROR_STRING, 532 "Can't initialize connection in " 533 "base mode", 534 " "); 535 return(error); 536 } 537 if (!(init_connect_result & TWA_CTLR_FW_COMPATIBLE)) { 538 /* 539 * The firmware on the controller is not even 540 * compatible with our base mode. We cannot 541 * work with it. Bail... 542 */ 543 return(1); 544 } 545 /* 546 * We can work with this firmware, but only in 547 * base mode. 548 */ 549 ctlr->working_srl = TWA_BASE_FW_SRL; 550 ctlr->working_branch = TWA_BASE_FW_BRANCH; 551 ctlr->working_build = TWA_BASE_FW_BUILD; 552 ctlr->operating_mode = TWA_BASE_MODE; 553 } 554 ctlr->fw_on_ctlr_srl = fw_on_ctlr_srl; 555 ctlr->fw_on_ctlr_branch = fw_on_ctlr_branch; 556 ctlr->fw_on_ctlr_build = fw_on_ctlr_build; 557 } 558 559 /* Drain the AEN queue */ 560 if ((error = tw_cli_drain_aen_queue(ctlr))) 561 /* 562 * We will just print that we couldn't drain the AEN queue. 563 * There's no need to bail out. 564 */ 565 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 566 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 567 0x1014, 0x2, TW_CL_SEVERITY_WARNING_STRING, 568 "Can't drain AEN queue", 569 "error = %d", error); 570 571 /* Enable interrupts. */ 572 tw_cli_enable_interrupts(ctlr); 573 574 return(TW_OSL_ESUCCESS); 575} 576 577 578/* 579 * Function name: tw_cl_shutdown_ctlr 580 * Description: Closes logical connection with the controller. 581 * 582 * Input: ctlr -- ptr to per ctlr structure 583 * flags -- more info passed by the OS Layer 584 * Output: None 585 * Return value: 0 -- success 586 * non-zero-- failure 587 */ 588TW_INT32 589tw_cl_shutdown_ctlr(struct tw_cl_ctlr_handle *ctlr_handle, TW_UINT32 flags) 590{ 591 struct tw_cli_ctlr_context *ctlr = 592 (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt); 593 TW_INT32 error; 594 595 tw_cli_dbg_printf(3, ctlr_handle, tw_osl_cur_func(), "entered"); 596 /* 597 * Mark the controller as inactive, disable any further interrupts, 598 * and notify the controller that we are going down. 599 */ 600 ctlr->state &= ~TW_CLI_CTLR_STATE_ACTIVE; 601 602 tw_cli_disable_interrupts(ctlr); 603 604 /* Let the controller know that we are going down. */ 605 if ((error = tw_cli_init_connection(ctlr, TWA_SHUTDOWN_MESSAGE_CREDITS, 606 0, 0, 0, 0, 0, TW_CL_NULL, TW_CL_NULL, TW_CL_NULL, 607 TW_CL_NULL, TW_CL_NULL))) 608 tw_cl_create_event(ctlr_handle, TW_CL_FALSE, 609 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 610 0x1015, 0x1, TW_CL_SEVERITY_ERROR_STRING, 611 "Can't close connection with controller", 612 "error = %d", error); 613 614 if (flags & TW_CL_STOP_CTLR_ONLY) 615 goto ret; 616 617 /* Destroy all locks used by CL. */ 618 tw_osl_destroy_lock(ctlr_handle, ctlr->gen_lock); 619 tw_osl_destroy_lock(ctlr_handle, ctlr->io_lock); 620 if (!(ctlr->flags & TW_CL_64BIT_ADDRESSES)) 621 tw_osl_destroy_lock(ctlr_handle, ctlr->intr_lock); 622 623ret: 624 return(error); 625} 626 627 628 629/* 630 * Function name: tw_cli_init_connection 631 * Description: Sends init_connection cmd to firmware 632 * 633 * Input: ctlr -- ptr to per ctlr structure 634 * message_credits -- max # of requests that we might send 635 * down simultaneously. This will be 636 * typically set to 256 at init-time or 637 * after a reset, and to 1 at shutdown-time 638 * set_features -- indicates if we intend to use 64-bit 639 * sg, also indicates if we want to do a 640 * basic or an extended init_connection; 641 * 642 * Note: The following input/output parameters are valid, only in case of an 643 * extended init_connection: 644 * 645 * current_fw_srl -- srl of fw we are bundled 646 * with, if any; 0 otherwise 647 * current_fw_arch_id -- arch_id of fw we are bundled 648 * with, if any; 0 otherwise 649 * current_fw_branch -- branch # of fw we are bundled 650 * with, if any; 0 otherwise 651 * current_fw_build -- build # of fw we are bundled 652 * with, if any; 0 otherwise 653 * Output: fw_on_ctlr_srl -- srl of fw on ctlr 654 * fw_on_ctlr_arch_id -- arch_id of fw on ctlr 655 * fw_on_ctlr_branch -- branch # of fw on ctlr 656 * fw_on_ctlr_build -- build # of fw on ctlr 657 * init_connect_result -- result bitmap of fw response 658 * Return value: 0 -- success 659 * non-zero-- failure 660 */ 661TW_INT32 662tw_cli_init_connection(struct tw_cli_ctlr_context *ctlr, 663 TW_UINT16 message_credits, TW_UINT32 set_features, 664 TW_UINT16 current_fw_srl, TW_UINT16 current_fw_arch_id, 665 TW_UINT16 current_fw_branch, TW_UINT16 current_fw_build, 666 TW_UINT16 *fw_on_ctlr_srl, TW_UINT16 *fw_on_ctlr_arch_id, 667 TW_UINT16 *fw_on_ctlr_branch, TW_UINT16 *fw_on_ctlr_build, 668 TW_UINT32 *init_connect_result) 669{ 670 struct tw_cli_req_context *req; 671 struct tw_cl_command_init_connect *init_connect; 672 TW_INT32 error = TW_OSL_EBUSY; 673 674 tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 675 676 /* Get a request packet. */ 677 if ((req = tw_cli_get_request(ctlr 678 )) == TW_CL_NULL) 679 goto out; 680 681 req->flags |= TW_CLI_REQ_FLAGS_INTERNAL; 682 683 /* Build the cmd pkt. */ 684 init_connect = &(req->cmd_pkt->command.cmd_pkt_7k.init_connect); 685 686 req->cmd_pkt->cmd_hdr.header_desc.size_header = 128; 687 688 init_connect->res1__opcode = 689 BUILD_RES__OPCODE(0, TWA_FW_CMD_INIT_CONNECTION); 690 init_connect->request_id = 691 (TW_UINT8)(TW_CL_SWAP16(req->request_id)); 692 init_connect->message_credits = TW_CL_SWAP16(message_credits); 693 init_connect->features = TW_CL_SWAP32(set_features); 694 if (ctlr->flags & TW_CL_64BIT_ADDRESSES) 695 init_connect->features |= TWA_64BIT_SG_ADDRESSES; 696 if (set_features & TWA_EXTENDED_INIT_CONNECT) { 697 /* 698 * Fill in the extra fields needed for an extended 699 * init_connect. 700 */ 701 init_connect->size = 6; 702 init_connect->fw_srl = TW_CL_SWAP16(current_fw_srl); 703 init_connect->fw_arch_id = TW_CL_SWAP16(current_fw_arch_id); 704 init_connect->fw_branch = TW_CL_SWAP16(current_fw_branch); 705 init_connect->fw_build = TW_CL_SWAP16(current_fw_build); 706 } else 707 init_connect->size = 3; 708 709 /* Submit the command, and wait for it to complete. */ 710 error = tw_cli_submit_and_poll_request(req, 711 TW_CLI_REQUEST_TIMEOUT_PERIOD); 712 if (error == TW_OSL_ETIMEDOUT) 713 /* Clean-up done by tw_cli_submit_and_poll_request. */ 714 return(error); 715 if (error) 716 goto out; 717 if ((error = init_connect->status)) { 718 tw_cli_create_ctlr_event(ctlr, 719 TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR, 720 &(req->cmd_pkt->cmd_hdr)); 721 goto out; 722 } 723 if (set_features & TWA_EXTENDED_INIT_CONNECT) { 724 *fw_on_ctlr_srl = TW_CL_SWAP16(init_connect->fw_srl); 725 *fw_on_ctlr_arch_id = TW_CL_SWAP16(init_connect->fw_arch_id); 726 *fw_on_ctlr_branch = TW_CL_SWAP16(init_connect->fw_branch); 727 *fw_on_ctlr_build = TW_CL_SWAP16(init_connect->fw_build); 728 *init_connect_result = TW_CL_SWAP32(init_connect->result); 729 } 730 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q); 731 return(error); 732 733out: 734 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 735 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 736 0x1016, 0x1, TW_CL_SEVERITY_ERROR_STRING, 737 "init_connection failed", 738 "error = %d", error); 739 if (req) 740 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q); 741 return(error); 742} 743 744
|