1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* Copyright 2009 QLogic Corporation */ 23 24 /* 25 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 #pragma ident "Copyright 2009 QLogic Corporation; ql_mbx.c" 30 31 /* 32 * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file. 33 * 34 * *********************************************************************** 35 * * ** 36 * * NOTICE ** 37 * * COPYRIGHT (C) 1996-2009 QLOGIC CORPORATION ** 38 * * ALL RIGHTS RESERVED ** 39 * * ** 40 * *********************************************************************** 41 * 42 */ 43 44 #include <ql_apps.h> 45 #include <ql_api.h> 46 #include <ql_debug.h> 47 #include <ql_iocb.h> 48 #include <ql_isr.h> 49 #include <ql_mbx.h> 50 #include <ql_xioctl.h> 51 52 /* 53 * Local data 54 */ 55 56 /* 57 * Local prototypes 58 */ 59 static int ql_mailbox_command(ql_adapter_state_t *, mbx_cmd_t *); 60 static int ql_task_mgmt_iocb(ql_adapter_state_t *, ql_tgt_t *, uint16_t, 61 uint32_t, uint16_t); 62 static int ql_abort_cmd_iocb(ql_adapter_state_t *, ql_srb_t *); 63 static int ql_setup_mbox_dma_transfer(ql_adapter_state_t *, dma_mem_t *, 64 caddr_t, uint32_t); 65 static int ql_setup_mbox_dma_resources(ql_adapter_state_t *, dma_mem_t *, 66 uint32_t); 67 static void ql_setup_mbox_dma_data(dma_mem_t *, caddr_t); 68 static void ql_get_mbox_dma_data(dma_mem_t *, caddr_t); 69 70 /* 71 * ql_mailbox_command 72 * Issue mailbox command and waits for completion. 73 * 74 * Input: 75 * ha = adapter state pointer. 76 * mcp = mailbox command parameter structure pointer. 77 * 78 * Returns: 79 * ql local function return status code. 80 * 81 * Context: 82 * Kernel context. 83 */ 84 static int 85 ql_mailbox_command(ql_adapter_state_t *vha, mbx_cmd_t *mcp) 86 { 87 uint16_t cnt; 88 uint32_t data; 89 clock_t timer, cv_stat; 90 int rval; 91 uint32_t set_flags = 0; 92 uint32_t reset_flags = 0; 93 ql_adapter_state_t *ha = vha->pha; 94 int mbx_cmd = mcp->mb[0]; 95 96 ASSERT(!MUTEX_HELD(&ha->mutex)); 97 98 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 99 100 /* Acquire mailbox register lock. */ 101 MBX_REGISTER_LOCK(ha); 102 103 /* Check for mailbox available, if not wait for signal. */ 104 while (ha->mailbox_flags & MBX_BUSY_FLG) { 105 ha->mailbox_flags = (uint8_t) 106 (ha->mailbox_flags | MBX_WANT_FLG); 107 108 if (ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) { 109 EL(vha, "failed availability cmd=%xh\n", mcp->mb[0]); 110 MBX_REGISTER_UNLOCK(ha); 111 return (QL_LOCK_TIMEOUT); 112 } 113 114 /* Set timeout after command that is running. */ 115 timer = ddi_get_lbolt(); 116 timer += (mcp->timeout + 20) * drv_usectohz(1000000); 117 cv_stat = cv_timedwait_sig(&ha->cv_mbx_wait, 118 &ha->pha->mbx_mutex, timer); 119 if (cv_stat == -1 || cv_stat == 0) { 120 /* 121 * The timeout time 'timer' was 122 * reached without the condition 123 * being signaled. 124 */ 125 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & 126 ~MBX_WANT_FLG); 127 cv_broadcast(&ha->cv_mbx_wait); 128 129 /* Release mailbox register lock. */ 130 MBX_REGISTER_UNLOCK(ha); 131 132 if (cv_stat == 0) { 133 EL(vha, "waiting for availability aborted, " 134 "cmd=%xh\n", mcp->mb[0]); 135 return (QL_ABORTED); 136 } 137 EL(vha, "failed availability cmd=%xh\n", mcp->mb[0]); 138 return (QL_LOCK_TIMEOUT); 139 } 140 } 141 142 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_BUSY_FLG); 143 144 /* Structure pointer for return mailbox registers. */ 145 ha->mcp = mcp; 146 147 /* Load mailbox registers. */ 148 data = mcp->out_mb; 149 for (cnt = 0; cnt < ha->reg_off->mbox_cnt && data; cnt++) { 150 if (data & MBX_0) { 151 WRT16_IO_REG(ha, mailbox[cnt], mcp->mb[cnt]); 152 } 153 data >>= 1; 154 } 155 156 /* Issue set host interrupt command. */ 157 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & ~MBX_INTERRUPT); 158 CFG_IST(ha, CFG_CTRL_242581) ? 159 WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT) : 160 WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT); 161 162 /* Wait for command to complete. */ 163 if (ha->flags & INTERRUPTS_ENABLED && 164 !(ha->task_daemon_flags & (TASK_THREAD_CALLED | 165 TASK_DAEMON_POWERING_DOWN)) && 166 !ddi_in_panic()) { 167 while (!(ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT)) && 168 !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) { 169 170 /* 30 seconds from now */ 171 timer = ddi_get_lbolt(); 172 timer += mcp->timeout * drv_usectohz(1000000); 173 if (cv_timedwait(&ha->cv_mbx_intr, &ha->pha->mbx_mutex, 174 timer) == -1) { 175 /* 176 * The timeout time 'timer' was 177 * reached without the condition 178 * being signaled. 179 */ 180 break; 181 } 182 } 183 } else { 184 /* Release mailbox register lock. */ 185 MBX_REGISTER_UNLOCK(ha); 186 187 /* Acquire interrupt lock. */ 188 for (timer = mcp->timeout * 100; timer; timer--) { 189 /* Check for pending interrupts. */ 190 while (RD16_IO_REG(ha, istatus) & RISC_INT) { 191 (void) ql_isr((caddr_t)ha); 192 INTR_LOCK(ha); 193 ha->intr_claimed = B_TRUE; 194 INTR_UNLOCK(ha); 195 if (ha->mailbox_flags & 196 (MBX_INTERRUPT | MBX_ABORT) || 197 ha->task_daemon_flags & ISP_ABORT_NEEDED) { 198 break; 199 } 200 } 201 if (ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT) || 202 ha->task_daemon_flags & ISP_ABORT_NEEDED) { 203 break; 204 } else if (!ddi_in_panic() && timer % 101 == 0) { 205 delay(drv_usectohz(10000)); 206 } else { 207 drv_usecwait(10000); 208 } 209 } 210 211 /* Acquire mailbox register lock. */ 212 MBX_REGISTER_LOCK(ha); 213 } 214 215 /* Mailbox command timeout? */ 216 if (ha->task_daemon_flags & ISP_ABORT_NEEDED || 217 ha->mailbox_flags & MBX_ABORT) { 218 rval = QL_ABORTED; 219 } else if ((ha->mailbox_flags & MBX_INTERRUPT) == 0) { 220 if (CFG_IST(ha, CFG_DUMP_MAILBOX_TIMEOUT)) { 221 (void) ql_binary_fw_dump(ha, FALSE); 222 } 223 EL(vha, "command timeout, isp_abort_needed\n"); 224 set_flags |= ISP_ABORT_NEEDED; 225 rval = QL_FUNCTION_TIMEOUT; 226 } else { 227 ha->mailbox_flags = (uint8_t) 228 (ha->mailbox_flags & ~MBX_INTERRUPT); 229 /* 230 * This is the expected completion path so 231 * return the actual mbx cmd completion status. 232 */ 233 rval = mcp->mb[0]; 234 } 235 236 /* 237 * Clear outbound to risc mailbox registers per spec. The exception 238 * is on 2200 mailbox 4 and 5 affect the req and resp que indexes 239 * so avoid writing them. 240 */ 241 if (ha->cfg_flags & CFG_CTRL_2200) { 242 data = ((mcp->out_mb & ~(MBX_4 | MBX_5)) >> 1); 243 } else { 244 data = (mcp->out_mb >> 1); 245 } 246 for (cnt = 1; cnt < ha->reg_off->mbox_cnt && data; cnt++) { 247 if (data & MBX_0) { 248 WRT16_IO_REG(ha, mailbox[cnt], (uint16_t)0); 249 } 250 data >>= 1; 251 } 252 253 /* Reset busy status. */ 254 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & 255 ~(MBX_BUSY_FLG | MBX_ABORT)); 256 ha->mcp = NULL; 257 258 /* If thread is waiting for mailbox go signal it to start. */ 259 if (ha->mailbox_flags & MBX_WANT_FLG) { 260 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & 261 ~MBX_WANT_FLG); 262 cv_broadcast(&ha->cv_mbx_wait); 263 } 264 265 /* Release mailbox register lock. */ 266 MBX_REGISTER_UNLOCK(ha); 267 268 if (set_flags != 0 || reset_flags != 0) { 269 ql_awaken_task_daemon(ha, NULL, set_flags, reset_flags); 270 } 271 272 if (rval != QL_SUCCESS) { 273 EL(vha, "%s failed, rval=%xh, mcp->mb[0]=%xh\n", 274 mbx_cmd_text(mbx_cmd), rval, mcp->mb[0]); 275 } else { 276 /*EMPTY*/ 277 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 278 } 279 280 return (rval); 281 } 282 283 /* 284 * ql_setup_mbox_dma_resources 285 * Prepare the data for a mailbox dma transfer. 286 * 287 * Input: 288 * ha = adapter state pointer. 289 * mem_desc = descriptor to contain the dma resource information. 290 * data = pointer to the data. 291 * size = size of the data in bytes. 292 * 293 * Returns: 294 * ql local function return status code. 295 * 296 * Context: 297 * Kernel context. 298 */ 299 static int 300 ql_setup_mbox_dma_transfer(ql_adapter_state_t *ha, dma_mem_t *mem_desc, 301 caddr_t data, uint32_t size) 302 { 303 int rval = QL_SUCCESS; 304 305 if ((rval = ql_setup_mbox_dma_resources(ha, mem_desc, size)) == 306 QL_SUCCESS) { 307 ql_setup_mbox_dma_data(mem_desc, data); 308 } else { 309 EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval); 310 } 311 312 return (rval); 313 } 314 315 /* 316 * ql_setup_mbox_dma_resources 317 * Prepare a dma buffer. 318 * 319 * Input: 320 * ha = adapter state pointer. 321 * mem_desc = descriptor to contain the dma resource information. 322 * data = pointer to the data. 323 * size = size of the data in bytes. 324 * 325 * Returns: 326 * ql local function return status code. 327 * 328 * Context: 329 * Kernel context. 330 */ 331 static int 332 ql_setup_mbox_dma_resources(ql_adapter_state_t *ha, dma_mem_t *mem_desc, 333 uint32_t size) 334 { 335 int rval = QL_SUCCESS; 336 337 if ((rval = ql_get_dma_mem(ha, mem_desc, size, LITTLE_ENDIAN_DMA, 338 QL_DMA_RING_ALIGN)) != QL_SUCCESS) { 339 EL(ha, "failed, ql_get_dma_mem FC_NOMEM\n"); 340 rval = QL_MEMORY_ALLOC_FAILED; 341 } 342 343 return (rval); 344 } 345 346 /* 347 * ql_setup_mbox_dma_data 348 * Move data to the dma buffer. 349 * 350 * Input: 351 * mem_desc = descriptor to contain the dma resource information. 352 * data = pointer to the data. 353 * 354 * Returns: 355 * 356 * Context: 357 * Kernel context. 358 */ 359 static void 360 ql_setup_mbox_dma_data(dma_mem_t *mem_desc, caddr_t data) 361 { 362 /* Copy out going data to DMA buffer. */ 363 ddi_rep_put8(mem_desc->acc_handle, (uint8_t *)data, 364 (uint8_t *)mem_desc->bp, mem_desc->size, DDI_DEV_AUTOINCR); 365 366 /* Sync DMA buffer. */ 367 (void) ddi_dma_sync(mem_desc->dma_handle, 0, mem_desc->size, 368 DDI_DMA_SYNC_FORDEV); 369 } 370 371 /* 372 * ql_get_mbox_dma_data 373 * Recover data from the dma buffer. 374 * 375 * Input: 376 * mem_desc = descriptor to contain the dma resource information. 377 * data = pointer to the data. 378 * 379 * Returns: 380 * 381 * Context: 382 * Kernel context. 383 */ 384 static void 385 ql_get_mbox_dma_data(dma_mem_t *mem_desc, caddr_t data) 386 { 387 /* Sync in coming DMA buffer. */ 388 (void) ddi_dma_sync(mem_desc->dma_handle, 0, mem_desc->size, 389 DDI_DMA_SYNC_FORKERNEL); 390 /* Copy in coming DMA data. */ 391 ddi_rep_get8(mem_desc->acc_handle, (uint8_t *)data, 392 (uint8_t *)mem_desc->bp, mem_desc->size, DDI_DEV_AUTOINCR); 393 } 394 395 /* 396 * ql_initialize_ip 397 * Initialize IP receive buffer queue. 398 * 399 * Input: 400 * ha = adapter state pointer. 401 * ha->ip_init_ctrl_blk = setup for transmit. 402 * 403 * Returns: 404 * ql local function return status code. 405 * 406 * Context: 407 * Kernel context. 408 */ 409 int 410 ql_initialize_ip(ql_adapter_state_t *ha) 411 { 412 ql_link_t *link; 413 ql_tgt_t *tq; 414 uint16_t index; 415 int rval; 416 dma_mem_t mem_desc; 417 mbx_cmd_t mc = {0}; 418 mbx_cmd_t *mcp = &mc; 419 420 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 421 422 if (CFG_IST(ha, (CFG_CTRL_6322 | CFG_CTRL_2581)) || 423 ha->vp_index != 0) { 424 ha->flags &= ~IP_INITIALIZED; 425 EL(ha, "HBA does not support IP\n"); 426 return (QL_FUNCTION_FAILED); 427 } 428 429 ha->rcvbuf_ring_ptr = ha->rcvbuf_ring_bp; 430 ha->rcvbuf_ring_index = 0; 431 432 /* Reset all sequence counts. */ 433 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) { 434 for (link = ha->dev[index].first; link != NULL; 435 link = link->next) { 436 tq = link->base_address; 437 tq->ub_total_seg_cnt = 0; 438 } 439 } 440 441 rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, 442 (caddr_t)&ha->ip_init_ctrl_blk, sizeof (ql_comb_ip_init_cb_t)); 443 if (rval != QL_SUCCESS) { 444 EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval); 445 return (rval); 446 } 447 448 mcp->mb[0] = MBC_INITIALIZE_IP; 449 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 450 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 451 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 452 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 453 mcp->mb[8] = 0; 454 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 455 mcp->in_mb = MBX_8|MBX_0; 456 mcp->timeout = MAILBOX_TOV; 457 rval = ql_mailbox_command(ha, mcp); 458 459 ql_free_dma_resource(ha, &mem_desc); 460 461 if (rval == QL_SUCCESS) { 462 ADAPTER_STATE_LOCK(ha); 463 ha->flags |= IP_INITIALIZED; 464 ADAPTER_STATE_UNLOCK(ha); 465 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 466 } else { 467 ha->flags &= ~IP_INITIALIZED; 468 EL(ha, "failed, rval = %xh\n", rval); 469 } 470 return (rval); 471 } 472 473 /* 474 * ql_shutdown_ip 475 * Disconnects firmware IP from system buffers. 476 * 477 * Input: 478 * ha = adapter state pointer. 479 * 480 * Returns: 481 * ql local function return status code. 482 * 483 * Context: 484 * Kernel context. 485 */ 486 int 487 ql_shutdown_ip(ql_adapter_state_t *ha) 488 { 489 int rval; 490 mbx_cmd_t mc = {0}; 491 mbx_cmd_t *mcp = &mc; 492 fc_unsol_buf_t *ubp; 493 ql_srb_t *sp; 494 uint16_t index; 495 496 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 497 498 mcp->mb[0] = MBC_UNLOAD_IP; 499 mcp->out_mb = MBX_0; 500 mcp->in_mb = MBX_0; 501 mcp->timeout = MAILBOX_TOV; 502 rval = ql_mailbox_command(ha, mcp); 503 504 ADAPTER_STATE_LOCK(ha); 505 QL_UB_LOCK(ha); 506 /* Return all unsolicited buffers that ISP-IP has. */ 507 for (index = 0; index < QL_UB_LIMIT; index++) { 508 ubp = ha->ub_array[index]; 509 if (ubp != NULL) { 510 sp = ubp->ub_fca_private; 511 sp->flags &= ~SRB_UB_IN_ISP; 512 } 513 } 514 515 ha->ub_outcnt = 0; 516 QL_UB_UNLOCK(ha); 517 ha->flags &= ~IP_INITIALIZED; 518 ADAPTER_STATE_UNLOCK(ha); 519 520 if (rval == QL_SUCCESS) { 521 /* EMPTY - no need to check return value of MBC_SHUTDOWN_IP */ 522 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 523 } else { 524 EL(ha, "failed, rval = %xh\n", rval); 525 } 526 return (rval); 527 } 528 529 /* 530 * ql_online_selftest 531 * Issue online self test mailbox command. 532 * 533 * Input: 534 * ha = adapter state pointer. 535 * 536 * Returns: 537 * ql local function return status code. 538 * 539 * Context: 540 * Kernel context. 541 */ 542 int 543 ql_online_selftest(ql_adapter_state_t *ha) 544 { 545 int rval; 546 mbx_cmd_t mc = {0}; 547 mbx_cmd_t *mcp = &mc; 548 549 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 550 551 mcp->mb[0] = MBC_ONLINE_SELF_TEST; 552 mcp->out_mb = MBX_0; 553 mcp->in_mb = MBX_0 | MBX_1 | MBX_2 | MBX_3; 554 mcp->timeout = MAILBOX_TOV; 555 rval = ql_mailbox_command(ha, mcp); 556 557 if (rval != QL_SUCCESS) { 558 EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n", 559 rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]); 560 } else { 561 /*EMPTY*/ 562 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 563 } 564 return (rval); 565 } 566 567 /* 568 * ql_loop_back 569 * Issue diagnostic loop back frame mailbox command. 570 * 571 * Input: 572 * ha = adapter state pointer. 573 * lb = loop back parameter structure pointer. 574 * 575 * Returns: 576 * ql local function return status code. 577 * 578 * Context: 579 * Kernel context. 580 */ 581 #ifndef apps_64bit 582 int 583 ql_loop_back(ql_adapter_state_t *ha, lbp_t *lb, uint32_t h_xmit, 584 uint32_t h_rcv) 585 { 586 int rval; 587 mbx_cmd_t mc = {0}; 588 mbx_cmd_t *mcp = &mc; 589 590 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 591 592 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; 593 mcp->mb[1] = lb->options; 594 mcp->mb[6] = LSW(h_rcv); 595 mcp->mb[7] = MSW(h_rcv); 596 mcp->mb[10] = LSW(lb->transfer_count); 597 mcp->mb[11] = MSW(lb->transfer_count); 598 mcp->mb[12] = lb->transfer_segment_count; 599 mcp->mb[13] = lb->receive_segment_count; 600 mcp->mb[14] = LSW(lb->transfer_data_address); 601 mcp->mb[15] = MSW(lb->transfer_data_address); 602 mcp->mb[16] = LSW(lb->receive_data_address); 603 mcp->mb[17] = MSW(lb->receive_data_address); 604 mcp->mb[18] = LSW(lb->iteration_count); 605 mcp->mb[19] = MSW(lb->iteration_count); 606 mcp->mb[20] = LSW(h_xmit); 607 mcp->mb[21] = MSW(h_xmit); 608 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15| 609 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0; 610 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0; 611 mcp->timeout = lb->iteration_count / 300; 612 613 if (mcp->timeout < MAILBOX_TOV) { 614 mcp->timeout = MAILBOX_TOV; 615 } 616 617 rval = ql_mailbox_command(ha, mcp); 618 619 if (rval != QL_SUCCESS) { 620 EL(ha, "failed, rval = %xh\n", rval); 621 } else { 622 /*EMPTY*/ 623 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 624 } 625 626 return (rval); 627 } 628 #else 629 int 630 ql_loop_back(ql_adapter_state_t *ha, lbp_t *lb) 631 { 632 int rval; 633 mbx_cmd_t mc = {0}; 634 mbx_cmd_t *mcp = &mc; 635 636 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 637 638 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; 639 mcp->mb[1] = lb->options; 640 mcp->mb[6] = LSW(h_rcv); 641 mcp->mb[7] = MSW(h_rcv); 642 mcp->mb[6] = LSW(MSD(lb->receive_data_address)); 643 mcp->mb[7] = MSW(MSD(lb->receive_data_address)); 644 mcp->mb[10] = LSW(lb->transfer_count); 645 mcp->mb[11] = MSW(lb->transfer_count); 646 mcp->mb[12] = lb->transfer_segment_count; 647 mcp->mb[13] = lb->receive_segment_count; 648 mcp->mb[14] = LSW(lb->transfer_data_address); 649 mcp->mb[15] = MSW(lb->transfer_data_address); 650 mcp->mb[14] = LSW(LSD(lb->transfer_data_address)); 651 mcp->mb[15] = MSW(LSD(lb->transfer_data_address)); 652 mcp->mb[16] = LSW(lb->receive_data_address); 653 mcp->mb[17] = MSW(lb->receive_data_address); 654 mcp->mb[16] = LSW(LSD(lb->receive_data_address)); 655 mcp->mb[17] = MSW(LSD(lb->receive_data_address)); 656 mcp->mb[18] = LSW(lb->iteration_count); 657 mcp->mb[19] = MSW(lb->iteration_count); 658 mcp->mb[20] = LSW(h_xmit); 659 mcp->mb[21] = MSW(h_xmit); 660 mcp->mb[20] = LSW(MSD(lb->transfer_data_address)); 661 mcp->mb[21] = MSW(MSD(lb->transfer_data_address)); 662 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15| 663 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0; 664 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0; 665 mcp->timeout = lb->iteration_count / 300; 666 667 if (mcp->timeout < MAILBOX_TOV) { 668 mcp->timeout = MAILBOX_TOV; 669 } 670 671 rval = ql_mailbox_command(ha, mcp); 672 673 if (rval != QL_SUCCESS) { 674 EL(ha, "failed, rval = %xh\n", rval); 675 } else { 676 /*EMPTY*/ 677 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 678 } 679 return (rval); 680 } 681 #endif 682 683 /* 684 * ql_echo 685 * Issue an ELS echo using the user specified data to a user specified 686 * destination 687 * 688 * Input: 689 * ha: adapter state pointer. 690 * echo_pt: echo parameter structure pointer. 691 * 692 * Returns: 693 * ql local function return status code. 694 * 695 * Context: 696 * Kernel context. 697 */ 698 int 699 ql_echo(ql_adapter_state_t *ha, echo_t *echo_pt) 700 { 701 int rval; 702 mbx_cmd_t mc = {0}; 703 mbx_cmd_t *mcp = &mc; 704 705 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 706 707 mcp->mb[0] = MBC_ECHO; /* ECHO command */ 708 mcp->mb[1] = echo_pt->options; /* command options; 64 bit */ 709 /* addressing (bit 6) and */ 710 /* real echo (bit 15 */ 711 712 /* 713 * I know this looks strange, using a field labled "not used" 714 * The way the ddi_dma_cookie_t structure/union is defined 715 * is a union of one 64 bit entity with an array of two 32 716 * bit enititys. Since we have routines to convert 32 bit 717 * entities into 16 bit entities it is easier to use 718 * both 32 bit union members then the one 64 bit union 719 * member 720 */ 721 if (echo_pt->options & BIT_6) { 722 /* 64 bit addressing */ 723 /* Receive data dest add in system memory bits 47-32 */ 724 mcp->mb[6] = LSW(echo_pt->receive_data_address.dmac_notused); 725 726 /* Receive data dest add in system memory bits 63-48 */ 727 mcp->mb[7] = MSW(echo_pt->receive_data_address.dmac_notused); 728 729 /* Transmit data source address in system memory bits 47-32 */ 730 mcp->mb[20] = LSW(echo_pt->transfer_data_address.dmac_notused); 731 732 /* Transmit data source address in system memory bits 63-48 */ 733 mcp->mb[21] = MSW(echo_pt->transfer_data_address.dmac_notused); 734 } 735 736 /* transfer count bits 15-0 */ 737 mcp->mb[10] = LSW(echo_pt->transfer_count); 738 739 /* Transmit data source address in system memory bits 15-0 */ 740 mcp->mb[14] = LSW(echo_pt->transfer_data_address.dmac_address); 741 742 /* Transmit data source address in system memory bits 31-16 */ 743 mcp->mb[15] = MSW(echo_pt->transfer_data_address.dmac_address); 744 745 /* Receive data destination address in system memory bits 15-0 */ 746 mcp->mb[16] = LSW(echo_pt->receive_data_address.dmac_address); 747 748 /* Receive data destination address in system memory bits 31-16 */ 749 mcp->mb[17] = MSW(echo_pt->receive_data_address.dmac_address); 750 751 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|MBX_14|MBX_10| 752 MBX_7|MBX_6|MBX_1|MBX_0; 753 mcp->in_mb = MBX_1|MBX_0; 754 mcp->timeout = MAILBOX_TOV; 755 756 rval = ql_mailbox_command(ha, mcp); 757 758 if (rval != QL_SUCCESS) { 759 EL(ha, "failed, rval = %xh\n", rval); 760 } else { 761 /*EMPTY*/ 762 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 763 } 764 return (rval); 765 } 766 767 /* 768 * ql_send_change_request 769 * Issue send change request mailbox command. 770 * 771 * Input: 772 * ha: adapter state pointer. 773 * fmt: Registration format. 774 * 775 * Returns: 776 * ql local function return status code. 777 * 778 * Context: 779 * Kernel context. 780 */ 781 int 782 ql_send_change_request(ql_adapter_state_t *ha, uint16_t fmt) 783 { 784 int rval; 785 mbx_cmd_t mc = {0}; 786 mbx_cmd_t *mcp = &mc; 787 788 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 789 790 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST; 791 mcp->mb[1] = fmt; 792 mcp->out_mb = MBX_1|MBX_0; 793 if (ha->flags & VP_ENABLED) { 794 mcp->mb[9] = ha->vp_index; 795 mcp->out_mb |= MBX_9; 796 } 797 mcp->in_mb = MBX_0; 798 mcp->timeout = MAILBOX_TOV; 799 rval = ql_mailbox_command(ha, mcp); 800 801 if (rval != QL_SUCCESS) { 802 EL(ha, "failed=%xh\n", rval); 803 } else { 804 /*EMPTY*/ 805 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 806 } 807 return (rval); 808 } 809 810 /* 811 * ql_send_lfa 812 * Send a Loop Fabric Address mailbox command. 813 * 814 * Input: 815 * ha: adapter state pointer. 816 * lfa: LFA command structure pointer. 817 * 818 * Returns: 819 * ql local function return status code. 820 * 821 * Context: 822 * Kernel context. 823 */ 824 int 825 ql_send_lfa(ql_adapter_state_t *ha, lfa_cmd_t *lfa) 826 { 827 int rval; 828 uint16_t size; 829 dma_mem_t mem_desc; 830 mbx_cmd_t mc = {0}; 831 mbx_cmd_t *mcp = &mc; 832 833 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 834 835 /* LFA_CB sz = 4 16bit words subcommand + 10 16bit words header. */ 836 size = (uint16_t)((lfa->subcommand_length[0] + 10) << 1); 837 838 rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, (caddr_t)lfa, size); 839 if (rval != QL_SUCCESS) { 840 EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval); 841 return (rval); 842 } 843 844 mcp->mb[0] = MBC_SEND_LFA_COMMAND; 845 mcp->mb[1] = (uint16_t)(size >> 1); 846 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 847 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 848 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 849 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 850 mcp->in_mb = MBX_0; 851 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 852 if (ha->flags & VP_ENABLED) { 853 mcp->mb[9] = ha->vp_index; 854 mcp->out_mb |= MBX_9; 855 } 856 mcp->timeout = MAILBOX_TOV; 857 rval = ql_mailbox_command(ha, mcp); 858 859 ql_free_dma_resource(ha, &mem_desc); 860 861 if (rval != QL_SUCCESS) { 862 EL(ha, "failed, rval = %xh\n", rval); 863 } else { 864 /*EMPTY*/ 865 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 866 } 867 868 return (rval); 869 } 870 871 /* 872 * ql_clear_aca 873 * Issue clear ACA mailbox command. 874 * 875 * Input: 876 * ha: adapter state pointer. 877 * tq: target queue pointer. 878 * lun: LUN. 879 * 880 * Returns: 881 * ql local function return status code. 882 * 883 * Context: 884 * Kernel context. 885 */ 886 int 887 ql_clear_aca(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun) 888 { 889 int rval; 890 mbx_cmd_t mc = {0}; 891 mbx_cmd_t *mcp = &mc; 892 893 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 894 895 if (CFG_IST(ha, CFG_CTRL_242581)) { 896 rval = ql_task_mgmt_iocb(ha, tq, lun, CF_CLEAR_ACA, 0); 897 } else { 898 mcp->mb[0] = MBC_CLEAR_ACA; 899 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 900 mcp->mb[1] = tq->loop_id; 901 } else { 902 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 903 } 904 mcp->mb[2] = lun; 905 mcp->out_mb = MBX_2|MBX_1|MBX_0; 906 mcp->in_mb = MBX_0; 907 mcp->timeout = MAILBOX_TOV; 908 rval = ql_mailbox_command(ha, mcp); 909 } 910 911 (void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID); 912 913 if (rval != QL_SUCCESS) { 914 EL(ha, "failed, rval = %xh\n", rval); 915 } else { 916 /*EMPTY*/ 917 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 918 } 919 920 return (rval); 921 } 922 923 /* 924 * ql_target_reset 925 * Issue target reset mailbox command. 926 * 927 * Input: 928 * ha: adapter state pointer. 929 * tq: target queue pointer. 930 * delay: seconds. 931 * 932 * Returns: 933 * ql local function return status code. 934 * 935 * Context: 936 * Kernel context. 937 */ 938 int 939 ql_target_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay) 940 { 941 ql_link_t *link; 942 uint16_t index; 943 int rval; 944 mbx_cmd_t mc = {0}; 945 mbx_cmd_t *mcp = &mc; 946 947 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 948 949 if (CFG_IST(ha, CFG_CTRL_242581)) { 950 /* queue = NULL, all targets. */ 951 if (tq == NULL) { 952 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; 953 index++) { 954 for (link = ha->dev[index].first; link != 955 NULL; link = link->next) { 956 tq = link->base_address; 957 if (!VALID_DEVICE_ID(ha, 958 tq->loop_id)) { 959 continue; 960 } 961 rval = ql_task_mgmt_iocb(ha, tq, 0, 962 CF_TARGET_RESET, delay); 963 964 if (rval != QL_SUCCESS) { 965 break; 966 } 967 } 968 969 if (link != NULL) { 970 break; 971 } 972 } 973 tq = NULL; 974 } else { 975 rval = ql_task_mgmt_iocb(ha, tq, 0, CF_TARGET_RESET, 976 delay); 977 } 978 } else { 979 /* queue = NULL, all targets. */ 980 if (tq == NULL) { 981 mcp->mb[0] = MBC_RESET; 982 mcp->mb[1] = delay; 983 mcp->out_mb = MBX_1|MBX_0; 984 } else { 985 mcp->mb[0] = MBC_TARGET_RESET; 986 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 987 mcp->mb[1] = tq->loop_id; 988 } else { 989 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 990 } 991 mcp->mb[2] = delay; 992 mcp->out_mb = MBX_2|MBX_1|MBX_0; 993 } 994 mcp->in_mb = MBX_0; 995 mcp->timeout = MAILBOX_TOV; 996 rval = ql_mailbox_command(ha, mcp); 997 } 998 999 tq == NULL ? (void) ql_marker(ha, 0, 0, MK_SYNC_ALL) : 1000 (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID); 1001 1002 if (rval != QL_SUCCESS) { 1003 EL(ha, "failed, rval = %xh\n", rval); 1004 } else { 1005 /*EMPTY*/ 1006 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1007 } 1008 1009 return (rval); 1010 } 1011 1012 /* 1013 * ql_abort_target 1014 * Issue abort target mailbox command. 1015 * 1016 * Input: 1017 * ha: adapter state pointer. 1018 * tq: target queue pointer. 1019 * delay: in seconds. 1020 * 1021 * Returns: 1022 * ql local function return status code. 1023 * 1024 * Context: 1025 * Kernel context. 1026 */ 1027 int 1028 ql_abort_target(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay) 1029 { 1030 int rval; 1031 mbx_cmd_t mc = {0}; 1032 mbx_cmd_t *mcp = &mc; 1033 1034 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1035 1036 if (CFG_IST(ha, CFG_CTRL_242581)) { 1037 rval = ql_task_mgmt_iocb(ha, tq, 0, 1038 CF_DO_NOT_SEND | CF_TARGET_RESET, delay); 1039 } else { 1040 mcp->mb[0] = MBC_ABORT_TARGET; 1041 /* Don't send Task Mgt */ 1042 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1043 mcp->mb[1] = tq->loop_id; 1044 mcp->mb[10] = BIT_0; 1045 mcp->out_mb = MBX_10|MBX_2|MBX_1|MBX_0; 1046 } else { 1047 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | BIT_0); 1048 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1049 } 1050 mcp->mb[2] = delay; 1051 mcp->in_mb = MBX_0; 1052 mcp->timeout = MAILBOX_TOV; 1053 rval = ql_mailbox_command(ha, mcp); 1054 } 1055 1056 (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID); 1057 1058 if (rval != QL_SUCCESS) { 1059 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1060 } else { 1061 /*EMPTY*/ 1062 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1063 } 1064 return (rval); 1065 } 1066 1067 /* 1068 * ql_lun_reset 1069 * Issue LUN reset task management mailbox command. 1070 * 1071 * Input: 1072 * ha: adapter state pointer. 1073 * tq: target queue pointer. 1074 * lun: LUN. 1075 * 1076 * Returns: 1077 * ql local function return status code. 1078 * 1079 * Context: 1080 * Kernel context. 1081 */ 1082 int 1083 ql_lun_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun) 1084 { 1085 int rval; 1086 mbx_cmd_t mc = {0}; 1087 mbx_cmd_t *mcp = &mc; 1088 1089 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1090 1091 if (CFG_IST(ha, CFG_CTRL_242581)) { 1092 rval = ql_task_mgmt_iocb(ha, tq, lun, CF_LUN_RESET, 0); 1093 } else { 1094 mcp->mb[0] = MBC_LUN_RESET; 1095 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1096 mcp->mb[1] = tq->loop_id; 1097 } else { 1098 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1099 } 1100 mcp->mb[2] = lun; 1101 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1102 mcp->in_mb = MBX_0; 1103 mcp->timeout = MAILBOX_TOV; 1104 rval = ql_mailbox_command(ha, mcp); 1105 } 1106 1107 (void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID); 1108 1109 if (rval != QL_SUCCESS) { 1110 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1111 } else { 1112 /*EMPTY*/ 1113 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1114 } 1115 return (rval); 1116 } 1117 1118 /* 1119 * ql_clear_task_set 1120 * Issue clear task set mailbox command. 1121 * 1122 * Input: 1123 * ha: adapter state pointer. 1124 * tq: target queue pointer. 1125 * lun: LUN. 1126 * 1127 * Returns: 1128 * ql local function return status code. 1129 * 1130 * Context: 1131 * Kernel context. 1132 */ 1133 int 1134 ql_clear_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun) 1135 { 1136 int rval; 1137 mbx_cmd_t mc = {0}; 1138 mbx_cmd_t *mcp = &mc; 1139 1140 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1141 1142 if (CFG_IST(ha, CFG_CTRL_242581)) { 1143 rval = ql_task_mgmt_iocb(ha, tq, lun, CF_CLEAR_TASK_SET, 0); 1144 } else { 1145 mcp->mb[0] = MBC_CLEAR_TASK_SET; 1146 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1147 mcp->mb[1] = tq->loop_id; 1148 } else { 1149 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1150 } 1151 mcp->mb[2] = lun; 1152 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1153 mcp->in_mb = MBX_0; 1154 mcp->timeout = MAILBOX_TOV; 1155 rval = ql_mailbox_command(ha, mcp); 1156 } 1157 1158 (void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID); 1159 1160 if (rval != QL_SUCCESS) { 1161 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1162 } else { 1163 /*EMPTY*/ 1164 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1165 } 1166 1167 return (rval); 1168 } 1169 1170 /* 1171 * ql_abort_task_set 1172 * Issue abort task set mailbox command. 1173 * 1174 * Input: 1175 * ha: adapter state pointer. 1176 * tq: target queue pointer. 1177 * lun: LUN. 1178 * 1179 * Returns: 1180 * ql local function return status code. 1181 * 1182 * Context: 1183 * Kernel context. 1184 */ 1185 int 1186 ql_abort_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun) 1187 { 1188 int rval; 1189 mbx_cmd_t mc = {0}; 1190 mbx_cmd_t *mcp = &mc; 1191 1192 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1193 1194 if (CFG_IST(ha, CFG_CTRL_242581)) { 1195 rval = ql_task_mgmt_iocb(ha, tq, lun, CF_ABORT_TASK_SET, 0); 1196 } else { 1197 mcp->mb[0] = MBC_ABORT_TASK_SET; 1198 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1199 mcp->mb[1] = tq->loop_id; 1200 } else { 1201 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1202 } 1203 mcp->mb[2] = lun; 1204 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1205 mcp->in_mb = MBX_0; 1206 mcp->timeout = MAILBOX_TOV; 1207 rval = ql_mailbox_command(ha, mcp); 1208 } 1209 1210 (void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID); 1211 1212 if (rval != QL_SUCCESS) { 1213 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1214 } else { 1215 /*EMPTY*/ 1216 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1217 } 1218 1219 return (rval); 1220 } 1221 1222 /* 1223 * ql_task_mgmt_iocb 1224 * Function issues task management IOCB. 1225 * 1226 * Input: 1227 * ha: adapter state pointer. 1228 * tq: target queue pointer. 1229 * lun: LUN. 1230 * flags: control flags. 1231 * delay: seconds. 1232 * 1233 * Returns: 1234 * ql local function return status code. 1235 * 1236 * Context: 1237 * Kernel context 1238 */ 1239 static int 1240 ql_task_mgmt_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun, 1241 uint32_t flags, uint16_t delay) 1242 { 1243 ql_mbx_iocb_t *pkt; 1244 int rval; 1245 uint32_t pkt_size; 1246 1247 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1248 1249 pkt_size = sizeof (ql_mbx_iocb_t); 1250 pkt = kmem_zalloc(pkt_size, KM_SLEEP); 1251 if (pkt == NULL) { 1252 EL(ha, "failed, kmem_zalloc\n"); 1253 return (QL_MEMORY_ALLOC_FAILED); 1254 } 1255 1256 pkt->mgmt.entry_type = TASK_MGMT_TYPE; 1257 pkt->mgmt.entry_count = 1; 1258 1259 pkt->mgmt.n_port_hdl = (uint16_t)LE_16(tq->loop_id); 1260 pkt->mgmt.delay = (uint16_t)LE_16(delay); 1261 pkt->mgmt.timeout = LE_16(MAILBOX_TOV); 1262 pkt->mgmt.fcp_lun[2] = LSB(lun); 1263 pkt->mgmt.fcp_lun[3] = MSB(lun); 1264 pkt->mgmt.control_flags = LE_32(flags); 1265 pkt->mgmt.target_id[0] = tq->d_id.b.al_pa; 1266 pkt->mgmt.target_id[1] = tq->d_id.b.area; 1267 pkt->mgmt.target_id[2] = tq->d_id.b.domain; 1268 pkt->mgmt.vp_index = ha->vp_index; 1269 1270 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size); 1271 if (rval == QL_SUCCESS && (pkt->sts24.entry_status & 0x3c) != 0) { 1272 EL(ha, "failed, entry_status=%xh, d_id=%xh\n", 1273 pkt->sts24.entry_status, tq->d_id.b24); 1274 rval = QL_FUNCTION_PARAMETER_ERROR; 1275 } 1276 1277 LITTLE_ENDIAN_16(&pkt->sts24.comp_status); 1278 1279 if (rval == QL_SUCCESS && pkt->sts24.comp_status != CS_COMPLETE) { 1280 EL(ha, "failed, comp_status=%xh, d_id=%xh\n", 1281 pkt->sts24.comp_status, tq->d_id.b24); 1282 rval = QL_FUNCTION_FAILED; 1283 } 1284 1285 kmem_free(pkt, pkt_size); 1286 1287 if (rval != QL_SUCCESS) { 1288 EL(ha, "failed, rval = %xh\n", rval); 1289 } else { 1290 /*EMPTY*/ 1291 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1292 } 1293 1294 return (rval); 1295 } 1296 1297 /* 1298 * ql_loop_port_bypass 1299 * Issue loop port bypass mailbox command. 1300 * 1301 * Input: 1302 * ha: adapter state pointer. 1303 * tq: target queue pointer. 1304 * 1305 * Returns: 1306 * ql local function return status code. 1307 * 1308 * Context: 1309 * Kernel context. 1310 */ 1311 int 1312 ql_loop_port_bypass(ql_adapter_state_t *ha, ql_tgt_t *tq) 1313 { 1314 int rval; 1315 mbx_cmd_t mc = {0}; 1316 mbx_cmd_t *mcp = &mc; 1317 1318 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1319 1320 mcp->mb[0] = MBC_LOOP_PORT_BYPASS; 1321 1322 if (CFG_IST(ha, CFG_CTRL_242581)) { 1323 mcp->mb[1] = tq->d_id.b.al_pa; 1324 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1325 mcp->mb[1] = tq->loop_id; 1326 } else { 1327 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1328 } 1329 1330 mcp->out_mb = MBX_1|MBX_0; 1331 mcp->in_mb = MBX_0; 1332 mcp->timeout = MAILBOX_TOV; 1333 rval = ql_mailbox_command(ha, mcp); 1334 1335 if (rval != QL_SUCCESS) { 1336 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1337 } else { 1338 /*EMPTY*/ 1339 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1340 } 1341 1342 return (rval); 1343 } 1344 1345 /* 1346 * ql_loop_port_enable 1347 * Issue loop port enable mailbox command. 1348 * 1349 * Input: 1350 * ha: adapter state pointer. 1351 * tq: target queue pointer. 1352 * 1353 * Returns: 1354 * ql local function return status code. 1355 * 1356 * Context: 1357 * Kernel context. 1358 */ 1359 int 1360 ql_loop_port_enable(ql_adapter_state_t *ha, ql_tgt_t *tq) 1361 { 1362 int rval; 1363 mbx_cmd_t mc = {0}; 1364 mbx_cmd_t *mcp = &mc; 1365 1366 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1367 1368 mcp->mb[0] = MBC_LOOP_PORT_ENABLE; 1369 1370 if (CFG_IST(ha, CFG_CTRL_242581)) { 1371 mcp->mb[1] = tq->d_id.b.al_pa; 1372 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1373 mcp->mb[1] = tq->loop_id; 1374 } else { 1375 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1376 } 1377 mcp->out_mb = MBX_1|MBX_0; 1378 mcp->in_mb = MBX_0; 1379 mcp->timeout = MAILBOX_TOV; 1380 rval = ql_mailbox_command(ha, mcp); 1381 1382 if (rval != QL_SUCCESS) { 1383 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1384 } else { 1385 /*EMPTY*/ 1386 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1387 } 1388 1389 return (rval); 1390 } 1391 1392 /* 1393 * ql_login_lport 1394 * Issue login loop port mailbox command. 1395 * 1396 * Input: 1397 * ha: adapter state pointer. 1398 * tq: target queue pointer. 1399 * loop_id: FC loop id. 1400 * opt: options. 1401 * LLF_NONE, LLF_PLOGI 1402 * 1403 * Returns: 1404 * ql local function return status code. 1405 * 1406 * Context: 1407 * Kernel context. 1408 */ 1409 int 1410 ql_login_lport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id, 1411 uint16_t opt) 1412 { 1413 int rval; 1414 uint16_t flags; 1415 ql_mbx_data_t mr; 1416 mbx_cmd_t mc = {0}; 1417 mbx_cmd_t *mcp = &mc; 1418 1419 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n", 1420 ha->instance, tq->d_id.b24, loop_id); 1421 1422 if (CFG_IST(ha, CFG_CTRL_242581)) { 1423 flags = CF_CMD_PLOGI; 1424 if ((opt & LLF_PLOGI) == 0) { 1425 flags = (uint16_t)(flags | CFO_COND_PLOGI); 1426 } 1427 rval = ql_log_iocb(ha, tq, loop_id, flags, &mr); 1428 } else { 1429 mcp->mb[0] = MBC_LOGIN_LOOP_PORT; 1430 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1431 mcp->mb[1] = loop_id; 1432 } else { 1433 mcp->mb[1] = (uint16_t)(loop_id << 8); 1434 } 1435 mcp->mb[2] = opt; 1436 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1437 mcp->in_mb = MBX_0; 1438 mcp->timeout = MAILBOX_TOV; 1439 rval = ql_mailbox_command(ha, mcp); 1440 } 1441 1442 if (rval != QL_SUCCESS) { 1443 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24, 1444 loop_id, rval); 1445 } else { 1446 /*EMPTY*/ 1447 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1448 } 1449 1450 return (rval); 1451 } 1452 1453 /* 1454 * ql_login_fport 1455 * Issue login fabric port mailbox command. 1456 * 1457 * Input: 1458 * ha: adapter state pointer. 1459 * tq: target queue pointer. 1460 * loop_id: FC loop id. 1461 * opt: options. 1462 * LFF_NONE, LFF_NO_PLOGI, LFF_NO_PRLI 1463 * mr: pointer for mailbox data. 1464 * 1465 * Returns: 1466 * ql local function return status code. 1467 * 1468 * Context: 1469 * Kernel context. 1470 */ 1471 int 1472 ql_login_fport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id, 1473 uint16_t opt, ql_mbx_data_t *mr) 1474 { 1475 int rval; 1476 uint16_t flags; 1477 mbx_cmd_t mc = {0}; 1478 mbx_cmd_t *mcp = &mc; 1479 1480 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n", 1481 ha->instance, tq->d_id.b24, loop_id); 1482 1483 if ((tq->d_id.b24 & 0xffffff) == 0xfffffa) { 1484 opt = (uint16_t)(opt | LFF_NO_PRLI); 1485 } 1486 1487 if (CFG_IST(ha, CFG_CTRL_242581)) { 1488 flags = CF_CMD_PLOGI; 1489 if (opt & LFF_NO_PLOGI) { 1490 flags = (uint16_t)(flags | CFO_COND_PLOGI); 1491 } 1492 if (opt & LFF_NO_PRLI) { 1493 flags = (uint16_t)(flags | CFO_SKIP_PRLI); 1494 } 1495 rval = ql_log_iocb(ha, tq, loop_id, flags, mr); 1496 } else { 1497 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT; 1498 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1499 mcp->mb[1] = loop_id; 1500 mcp->mb[10] = opt; 1501 mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0; 1502 } else { 1503 mcp->mb[1] = (uint16_t)(loop_id << 8 | opt); 1504 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1505 } 1506 mcp->mb[2] = MSW(tq->d_id.b24); 1507 mcp->mb[3] = LSW(tq->d_id.b24); 1508 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 1509 mcp->timeout = MAILBOX_TOV; 1510 rval = ql_mailbox_command(ha, mcp); 1511 1512 /* Return mailbox data. */ 1513 if (mr != NULL) { 1514 mr->mb[0] = mcp->mb[0]; 1515 mr->mb[1] = mcp->mb[1]; 1516 mr->mb[2] = mcp->mb[2]; 1517 mr->mb[6] = mcp->mb[6]; 1518 mr->mb[7] = mcp->mb[7]; 1519 } 1520 } 1521 1522 if (rval != QL_SUCCESS) { 1523 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh, mb1=%02xh, " 1524 "mb2=%04x\n", tq->d_id.b24, loop_id, rval, mr->mb[1], 1525 mr->mb[2]); 1526 } else { 1527 /*EMPTY*/ 1528 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1529 } 1530 1531 return (rval); 1532 } 1533 1534 /* 1535 * ql_logout_fabric_port 1536 * Issue logout fabric port mailbox command. 1537 * 1538 * Input: 1539 * ha: adapter state pointer. 1540 * tq: target queue pointer. 1541 * 1542 * Returns: 1543 * ql local function return status code. 1544 * 1545 * Context: 1546 * Kernel context. 1547 */ 1548 int 1549 ql_logout_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq) 1550 { 1551 int rval; 1552 uint16_t flag; 1553 ql_mbx_data_t mr; 1554 mbx_cmd_t mc = {0}; 1555 mbx_cmd_t *mcp = &mc; 1556 1557 QL_PRINT_3(CE_CONT, "(%d): started, loop_id=%xh d_id=%xh\n", 1558 ha->instance, tq->loop_id, tq->d_id.b24); 1559 1560 if (CFG_IST(ha, CFG_CTRL_242581)) { 1561 flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ? 1562 CFO_EXPLICIT_LOGO |CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE : 1563 CFO_IMPLICIT_LOGO |CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE); 1564 rval = ql_log_iocb(ha, tq, tq->loop_id, flag, &mr); 1565 } else { 1566 flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ? 1 : 0); 1567 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; 1568 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1569 mcp->mb[1] = tq->loop_id; 1570 mcp->mb[10] = flag; 1571 mcp->out_mb = MBX_10|MBX_1|MBX_0; 1572 } else { 1573 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | flag); 1574 mcp->out_mb = MBX_1|MBX_0; 1575 } 1576 mcp->in_mb = MBX_0; 1577 mcp->timeout = MAILBOX_TOV; 1578 rval = ql_mailbox_command(ha, mcp); 1579 } 1580 1581 if (rval != QL_SUCCESS) { 1582 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", rval, 1583 tq->d_id.b24, tq->loop_id); 1584 } else { 1585 /*EMPTY*/ 1586 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1587 } 1588 1589 return (rval); 1590 } 1591 1592 /* 1593 * ql_log_iocb 1594 * Function issues login/logout IOCB. 1595 * 1596 * Input: 1597 * ha: adapter state pointer. 1598 * tq: target queue pointer. 1599 * loop_id: FC Loop ID. 1600 * flags: control flags. 1601 * mr: pointer for mailbox data. 1602 * 1603 * Returns: 1604 * ql local function return status code. 1605 * 1606 * Context: 1607 * Kernel context. 1608 */ 1609 int 1610 ql_log_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id, 1611 uint16_t flags, ql_mbx_data_t *mr) 1612 { 1613 ql_mbx_iocb_t *pkt; 1614 int rval; 1615 uint32_t pkt_size; 1616 1617 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1618 1619 pkt_size = sizeof (ql_mbx_iocb_t); 1620 pkt = kmem_zalloc(pkt_size, KM_SLEEP); 1621 if (pkt == NULL) { 1622 EL(ha, "failed, kmem_zalloc\n"); 1623 return (QL_MEMORY_ALLOC_FAILED); 1624 } 1625 1626 pkt->log.entry_type = LOG_TYPE; 1627 pkt->log.entry_count = 1; 1628 pkt->log.n_port_hdl = (uint16_t)LE_16(loop_id); 1629 pkt->log.control_flags = (uint16_t)LE_16(flags); 1630 pkt->log.port_id[0] = tq->d_id.b.al_pa; 1631 pkt->log.port_id[1] = tq->d_id.b.area; 1632 pkt->log.port_id[2] = tq->d_id.b.domain; 1633 pkt->log.vp_index = ha->vp_index; 1634 1635 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size); 1636 if (rval == QL_SUCCESS && (pkt->log.entry_status & 0x3c) != 0) { 1637 EL(ha, "failed, entry_status=%xh, d_id=%xh\n", 1638 pkt->log.entry_status, tq->d_id.b24); 1639 rval = QL_FUNCTION_PARAMETER_ERROR; 1640 } 1641 1642 if (rval == QL_SUCCESS) { 1643 if (pkt->log.rsp_size == 0xB) { 1644 LITTLE_ENDIAN_32(&pkt->log.io_param[5]); 1645 tq->cmn_features = MSW(pkt->log.io_param[5]); 1646 LITTLE_ENDIAN_32(&pkt->log.io_param[6]); 1647 tq->conc_sequences = MSW(pkt->log.io_param[6]); 1648 tq->relative_offset = LSW(pkt->log.io_param[6]); 1649 LITTLE_ENDIAN_32(&pkt->log.io_param[9]); 1650 tq->class3_recipient_ctl = MSW(pkt->log.io_param[9]); 1651 tq->class3_conc_sequences = LSW(pkt->log.io_param[9]); 1652 LITTLE_ENDIAN_32(&pkt->log.io_param[10]); 1653 tq->class3_open_sequences_per_exch = 1654 MSW(pkt->log.io_param[10]); 1655 tq->prli_payload_length = 0x14; 1656 } 1657 if (mr != NULL) { 1658 LITTLE_ENDIAN_16(&pkt->log.status); 1659 LITTLE_ENDIAN_32(&pkt->log.io_param[0]); 1660 LITTLE_ENDIAN_32(&pkt->log.io_param[1]); 1661 1662 if (pkt->log.status != CS_COMPLETE) { 1663 EL(ha, "failed, status=%xh, iop0=%xh, iop1=" 1664 "%xh\n", pkt->log.status, 1665 pkt->log.io_param[0], 1666 pkt->log.io_param[1]); 1667 1668 switch (pkt->log.io_param[0]) { 1669 case CS0_NO_LINK: 1670 case CS0_FIRMWARE_NOT_READY: 1671 mr->mb[0] = MBS_COMMAND_ERROR; 1672 mr->mb[1] = 1; 1673 break; 1674 case CS0_NO_IOCB: 1675 case CS0_NO_PCB_ALLOCATED: 1676 mr->mb[0] = MBS_COMMAND_ERROR; 1677 mr->mb[1] = 2; 1678 break; 1679 case CS0_NO_EXCH_CTRL_BLK: 1680 mr->mb[0] = MBS_COMMAND_ERROR; 1681 mr->mb[1] = 3; 1682 break; 1683 case CS0_COMMAND_FAILED: 1684 mr->mb[0] = MBS_COMMAND_ERROR; 1685 mr->mb[1] = 4; 1686 switch (LSB(pkt->log.io_param[1])) { 1687 case CS1_PLOGI_RESPONSE_FAILED: 1688 mr->mb[2] = 3; 1689 break; 1690 case CS1_PRLI_FAILED: 1691 mr->mb[2] = 4; 1692 break; 1693 case CS1_PRLI_RESPONSE_FAILED: 1694 mr->mb[2] = 5; 1695 break; 1696 case CS1_COMMAND_LOGGED_OUT: 1697 mr->mb[2] = 7; 1698 break; 1699 case CS1_PLOGI_FAILED: 1700 default: 1701 EL(ha, "log iop1 = %xh\n", 1702 LSB(pkt->log.io_param[1])) 1703 mr->mb[2] = 2; 1704 break; 1705 } 1706 break; 1707 case CS0_PORT_NOT_LOGGED_IN: 1708 mr->mb[0] = MBS_COMMAND_ERROR; 1709 mr->mb[1] = 4; 1710 mr->mb[2] = 7; 1711 break; 1712 case CS0_NO_FLOGI_ACC: 1713 case CS0_NO_FABRIC_PRESENT: 1714 mr->mb[0] = MBS_COMMAND_ERROR; 1715 mr->mb[1] = 5; 1716 break; 1717 case CS0_ELS_REJECT_RECEIVED: 1718 mr->mb[0] = MBS_COMMAND_ERROR; 1719 mr->mb[1] = 0xd; 1720 break; 1721 case CS0_PORT_ID_USED: 1722 mr->mb[0] = MBS_PORT_ID_USED; 1723 mr->mb[1] = LSW(pkt->log.io_param[1]); 1724 break; 1725 case CS0_N_PORT_HANDLE_USED: 1726 mr->mb[0] = MBS_LOOP_ID_USED; 1727 mr->mb[1] = MSW(pkt->log.io_param[1]); 1728 mr->mb[2] = LSW(pkt->log.io_param[1]); 1729 break; 1730 case CS0_NO_N_PORT_HANDLE_AVAILABLE: 1731 mr->mb[0] = MBS_ALL_IDS_IN_USE; 1732 break; 1733 case CS0_CMD_PARAMETER_ERROR: 1734 default: 1735 EL(ha, "pkt->log iop[0]=%xh\n", 1736 pkt->log.io_param[0]); 1737 mr->mb[0] = 1738 MBS_COMMAND_PARAMETER_ERROR; 1739 break; 1740 } 1741 } else { 1742 QL_PRINT_3(CE_CONT, "(%d): status=%xh\n", 1743 ha->instance, pkt->log.status); 1744 1745 mr->mb[0] = MBS_COMMAND_COMPLETE; 1746 mr->mb[1] = (uint16_t) 1747 (pkt->log.io_param[0] & BIT_4 ? 0 : BIT_0); 1748 if (pkt->log.io_param[0] & BIT_8) { 1749 mr->mb[1] = (uint16_t) 1750 (mr->mb[1] | BIT_1); 1751 } 1752 } 1753 rval = mr->mb[0]; 1754 } 1755 1756 } 1757 1758 kmem_free(pkt, pkt_size); 1759 1760 if (rval != QL_SUCCESS) { 1761 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1762 } else { 1763 /*EMPTY*/ 1764 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1765 } 1766 1767 return (rval); 1768 } 1769 1770 /* 1771 * ql_get_port_database 1772 * Issue get port database mailbox command 1773 * and copy context to device queue. 1774 * 1775 * Input: 1776 * ha: adapter state pointer. 1777 * tq: target queue pointer. 1778 * opt: options. 1779 * PDF_NONE, PDF_PLOGI, PDF_ADISC 1780 * Returns: 1781 * ql local function return status code. 1782 * 1783 * Context: 1784 * Kernel context. 1785 */ 1786 int 1787 ql_get_port_database(ql_adapter_state_t *ha, ql_tgt_t *tq, uint8_t opt) 1788 { 1789 int rval; 1790 dma_mem_t mem_desc; 1791 mbx_cmd_t mc = {0}; 1792 mbx_cmd_t *mcp = &mc; 1793 port_database_23_t *pd23; 1794 1795 ASSERT(!MUTEX_HELD(&ha->mutex)); 1796 1797 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1798 1799 pd23 = (port_database_23_t *)kmem_zalloc(PORT_DATABASE_SIZE, KM_SLEEP); 1800 if (pd23 == NULL) { 1801 rval = QL_MEMORY_ALLOC_FAILED; 1802 EL(ha, "failed, rval = %xh\n", rval); 1803 return (rval); 1804 } 1805 1806 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 1807 PORT_DATABASE_SIZE)) != QL_SUCCESS) { 1808 return (QL_MEMORY_ALLOC_FAILED); 1809 } 1810 1811 if (CFG_IST(ha, CFG_CTRL_242581)) { 1812 mcp->mb[0] = MBC_GET_PORT_DATABASE; 1813 mcp->mb[1] = tq->loop_id; 1814 mcp->mb[4] = CHAR_TO_SHORT(tq->d_id.b.al_pa, tq->d_id.b.area); 1815 mcp->mb[5] = (uint16_t)tq->d_id.b.domain; 1816 mcp->mb[9] = ha->vp_index; 1817 mcp->mb[10] = (uint16_t)(opt | PDF_ADISC); 1818 mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3| 1819 MBX_2|MBX_1|MBX_0; 1820 } else { 1821 mcp->mb[0] = (uint16_t)(opt == PDF_NONE ? 1822 MBC_GET_PORT_DATABASE : MBC_ENHANCED_GET_PORT_DATABASE); 1823 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1824 mcp->mb[1] = tq->loop_id; 1825 mcp->mb[10] = opt; 1826 mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3| 1827 MBX_2|MBX_1|MBX_0; 1828 } else { 1829 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | opt); 1830 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 1831 } 1832 } 1833 1834 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 1835 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 1836 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 1837 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 1838 mcp->in_mb = MBX_0; 1839 mcp->timeout = MAILBOX_TOV; 1840 rval = ql_mailbox_command(ha, mcp); 1841 1842 if (rval == QL_SUCCESS) { 1843 ql_get_mbox_dma_data(&mem_desc, (caddr_t)pd23); 1844 } 1845 1846 ql_free_dma_resource(ha, &mem_desc); 1847 1848 if (rval == QL_SUCCESS) { 1849 if (CFG_IST(ha, CFG_CTRL_242581)) { 1850 port_database_24_t *pd24 = (port_database_24_t *)pd23; 1851 1852 tq->master_state = pd24->current_login_state; 1853 tq->slave_state = pd24->last_stable_login_state; 1854 if (PD_PORT_LOGIN(tq)) { 1855 /* Names are big endian. */ 1856 bcopy((void *)&pd24->port_name[0], 1857 (void *)&tq->port_name[0], 8); 1858 bcopy((void *)&pd24->node_name[0], 1859 (void *)&tq->node_name[0], 8); 1860 tq->hard_addr.b.al_pa = pd24->hard_address[2]; 1861 tq->hard_addr.b.area = pd24->hard_address[1]; 1862 tq->hard_addr.b.domain = pd24->hard_address[0]; 1863 tq->class3_rcv_data_size = 1864 pd24->receive_data_size; 1865 LITTLE_ENDIAN_16(&tq->class3_rcv_data_size); 1866 tq->prli_svc_param_word_0 = 1867 pd24->PRLI_service_parameter_word_0; 1868 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0); 1869 tq->prli_svc_param_word_3 = 1870 pd24->PRLI_service_parameter_word_3; 1871 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3); 1872 } 1873 } else { 1874 tq->master_state = pd23->master_state; 1875 tq->slave_state = pd23->slave_state; 1876 if (PD_PORT_LOGIN(tq)) { 1877 /* Names are big endian. */ 1878 bcopy((void *)&pd23->port_name[0], 1879 (void *)&tq->port_name[0], 8); 1880 bcopy((void *)&pd23->node_name[0], 1881 (void *)&tq->node_name[0], 8); 1882 tq->hard_addr.b.al_pa = pd23->hard_address[2]; 1883 tq->hard_addr.b.area = pd23->hard_address[1]; 1884 tq->hard_addr.b.domain = pd23->hard_address[0]; 1885 tq->cmn_features = pd23->common_features; 1886 LITTLE_ENDIAN_16(&tq->cmn_features); 1887 tq->conc_sequences = 1888 pd23->total_concurrent_sequences; 1889 LITTLE_ENDIAN_16(&tq->conc_sequences); 1890 tq->relative_offset = 1891 pd23->RO_by_information_category; 1892 LITTLE_ENDIAN_16(&tq->relative_offset); 1893 tq->class3_recipient_ctl = pd23->recipient; 1894 LITTLE_ENDIAN_16(&tq->class3_recipient_ctl); 1895 tq->class3_rcv_data_size = 1896 pd23->receive_data_size; 1897 LITTLE_ENDIAN_16(&tq->class3_rcv_data_size); 1898 tq->class3_conc_sequences = 1899 pd23->concurrent_sequences; 1900 LITTLE_ENDIAN_16(&tq->class3_conc_sequences); 1901 tq->class3_open_sequences_per_exch = 1902 pd23->open_sequences_per_exchange; 1903 LITTLE_ENDIAN_16( 1904 &tq->class3_open_sequences_per_exch); 1905 tq->prli_payload_length = 1906 pd23->PRLI_payload_length; 1907 LITTLE_ENDIAN_16(&tq->prli_payload_length); 1908 tq->prli_svc_param_word_0 = 1909 pd23->PRLI_service_parameter_word_0; 1910 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0); 1911 tq->prli_svc_param_word_3 = 1912 pd23->PRLI_service_parameter_word_3; 1913 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3); 1914 } 1915 } 1916 1917 if (!PD_PORT_LOGIN(tq)) { 1918 EL(ha, "d_id=%xh, loop_id=%xh, not logged in " 1919 "master=%xh, slave=%xh\n", tq->d_id.b24, 1920 tq->loop_id, tq->master_state, tq->slave_state); 1921 rval = QL_NOT_LOGGED_IN; 1922 } else { 1923 tq->flags = tq->prli_svc_param_word_3 & 1924 PRLI_W3_TARGET_FUNCTION ? 1925 tq->flags & ~TQF_INITIATOR_DEVICE : 1926 tq->flags | TQF_INITIATOR_DEVICE; 1927 1928 if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) { 1929 tq->flags = tq->prli_svc_param_word_3 & 1930 PRLI_W3_RETRY ? 1931 tq->flags | TQF_TAPE_DEVICE : 1932 tq->flags & ~TQF_TAPE_DEVICE; 1933 } else { 1934 tq->flags &= ~TQF_TAPE_DEVICE; 1935 } 1936 } 1937 } 1938 1939 kmem_free(pd23, PORT_DATABASE_SIZE); 1940 1941 if ((rval != QL_SUCCESS) && (rval != QL_PARAMETER_ERROR)) { 1942 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24, 1943 tq->loop_id, rval); 1944 } else { 1945 /*EMPTY*/ 1946 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1947 } 1948 1949 return (rval); 1950 } 1951 1952 /* 1953 * ql_get_loop_position_map 1954 * Issue get loop position map mailbox command. 1955 * 1956 * Input: 1957 * ha: adapter state pointer. 1958 * size: size of data buffer. 1959 * bufp: data pointer for DMA data. 1960 * 1961 * Returns: 1962 * ql local function return status code. 1963 * 1964 * Context: 1965 * Kernel context. 1966 */ 1967 int 1968 ql_get_loop_position_map(ql_adapter_state_t *ha, size_t size, caddr_t bufp) 1969 { 1970 int rval; 1971 dma_mem_t mem_desc; 1972 mbx_cmd_t mc = {0}; 1973 mbx_cmd_t *mcp = &mc; 1974 1975 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1976 1977 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 1978 (uint32_t)size)) != QL_SUCCESS) { 1979 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval); 1980 return (QL_MEMORY_ALLOC_FAILED); 1981 } 1982 1983 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP; 1984 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 1985 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 1986 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 1987 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 1988 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 1989 mcp->in_mb = MBX_1|MBX_0; 1990 mcp->timeout = MAILBOX_TOV; 1991 rval = ql_mailbox_command(ha, mcp); 1992 1993 if (rval == QL_SUCCESS) { 1994 ql_get_mbox_dma_data(&mem_desc, bufp); 1995 } 1996 1997 ql_free_dma_resource(ha, &mem_desc); 1998 1999 if (rval != QL_SUCCESS) { 2000 EL(ha, "failed=%xh\n", rval); 2001 } else { 2002 /*EMPTY*/ 2003 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2004 } 2005 2006 return (rval); 2007 } 2008 2009 /* 2010 * ql_set_rnid_params 2011 * Issue set RNID parameters mailbox command. 2012 * 2013 * Input: 2014 * ha: adapter state pointer. 2015 * size: size of data buffer. 2016 * bufp: data pointer for DMA data. 2017 * 2018 * Returns: 2019 * ql local function return status code. 2020 * 2021 * Context: 2022 * Kernel context. 2023 */ 2024 int 2025 ql_set_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp) 2026 { 2027 int rval; 2028 dma_mem_t mem_desc; 2029 mbx_cmd_t mc = {0}; 2030 mbx_cmd_t *mcp = &mc; 2031 2032 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2033 2034 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bufp, 2035 (uint32_t)size)) != QL_SUCCESS) { 2036 EL(ha, "failed, setup_mbox_dma_transfer: %x\n", rval); 2037 return (rval); 2038 } 2039 2040 mcp->mb[0] = MBC_SET_PARAMETERS; 2041 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2042 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2043 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2044 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2045 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2046 mcp->in_mb = MBX_0; 2047 mcp->timeout = MAILBOX_TOV; 2048 rval = ql_mailbox_command(ha, mcp); 2049 2050 ql_free_dma_resource(ha, &mem_desc); 2051 2052 if (rval != QL_SUCCESS) { 2053 EL(ha, "failed, rval = %xh\n", rval); 2054 } else { 2055 /*EMPTY*/ 2056 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2057 } 2058 2059 return (rval); 2060 } 2061 2062 /* 2063 * ql_send_rnid_els 2064 * Issue a send node identfication data mailbox command. 2065 * 2066 * Input: 2067 * ha: adapter state pointer. 2068 * loop_id: FC loop id. 2069 * opt: options. 2070 * size: size of data buffer. 2071 * bufp: data pointer for DMA data. 2072 * 2073 * Returns: 2074 * ql local function return status code. 2075 * 2076 * Context: 2077 * Kernel context. 2078 */ 2079 int 2080 ql_send_rnid_els(ql_adapter_state_t *ha, uint16_t loop_id, uint8_t opt, 2081 size_t size, caddr_t bufp) 2082 { 2083 int rval; 2084 dma_mem_t mem_desc; 2085 mbx_cmd_t mc = {0}; 2086 mbx_cmd_t *mcp = &mc; 2087 2088 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2089 2090 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2091 (uint32_t)size)) != QL_SUCCESS) { 2092 return (QL_MEMORY_ALLOC_FAILED); 2093 } 2094 2095 mcp->mb[0] = MBC_SEND_RNID_ELS; 2096 if (CFG_IST(ha, CFG_CTRL_242581)) { 2097 mcp->mb[1] = loop_id; 2098 mcp->mb[9] = ha->vp_index; 2099 mcp->mb[10] = opt; 2100 mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2101 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2102 mcp->mb[1] = loop_id; 2103 mcp->mb[10] = opt; 2104 mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2105 } else { 2106 mcp->mb[1] = (uint16_t)(loop_id << 8 | opt); 2107 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2108 } 2109 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2110 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2111 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2112 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2113 mcp->in_mb = MBX_0; 2114 mcp->timeout = MAILBOX_TOV; 2115 rval = ql_mailbox_command(ha, mcp); 2116 2117 if (rval == QL_SUCCESS) { 2118 ql_get_mbox_dma_data(&mem_desc, bufp); 2119 } 2120 2121 ql_free_dma_resource(ha, &mem_desc); 2122 2123 if (rval != QL_SUCCESS) { 2124 EL(ha, "failed, rval = %xh\n", rval); 2125 } else { 2126 /*EMPTY*/ 2127 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2128 } 2129 2130 return (rval); 2131 } 2132 2133 /* 2134 * ql_get_rnid_params 2135 * Issue get RNID parameters mailbox command. 2136 * 2137 * Input: 2138 * ha: adapter state pointer. 2139 * size: size of data buffer. 2140 * bufp: data pointer for DMA data. 2141 * 2142 * Returns: 2143 * ql local function return status code. 2144 * 2145 * Context: 2146 * Kernel context. 2147 */ 2148 int 2149 ql_get_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp) 2150 { 2151 int rval; 2152 dma_mem_t mem_desc; 2153 mbx_cmd_t mc = {0}; 2154 mbx_cmd_t *mcp = &mc; 2155 2156 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2157 2158 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2159 (uint32_t)size)) != QL_SUCCESS) { 2160 return (QL_MEMORY_ALLOC_FAILED); 2161 } 2162 2163 mcp->mb[0] = MBC_GET_PARAMETERS; 2164 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2165 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2166 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2167 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2168 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2169 mcp->in_mb = MBX_0; 2170 mcp->timeout = MAILBOX_TOV; 2171 rval = ql_mailbox_command(ha, mcp); 2172 2173 if (rval == QL_SUCCESS) { 2174 ql_get_mbox_dma_data(&mem_desc, bufp); 2175 } 2176 2177 ql_free_dma_resource(ha, &mem_desc); 2178 2179 if (rval != QL_SUCCESS) { 2180 EL(ha, "failed=%xh\n", rval); 2181 } else { 2182 /*EMPTY*/ 2183 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2184 } 2185 2186 return (rval); 2187 } 2188 2189 /* 2190 * ql_get_link_status 2191 * Issue get link status mailbox command. 2192 * 2193 * Input: 2194 * ha: adapter state pointer. 2195 * loop_id: FC loop id or n_port_hdl. 2196 * size: size of data buffer. 2197 * bufp: data pointer for DMA data. 2198 * port_no: port number to query. 2199 * 2200 * Returns: 2201 * ql local function return status code. 2202 * 2203 * Context: 2204 * Kernel context. 2205 */ 2206 int 2207 ql_get_link_status(ql_adapter_state_t *ha, uint16_t loop_id, size_t size, 2208 caddr_t bufp, uint8_t port_no) 2209 { 2210 dma_mem_t mem_desc; 2211 mbx_cmd_t mc = {0}; 2212 mbx_cmd_t *mcp = &mc; 2213 int rval = QL_SUCCESS; 2214 int retry = 0; 2215 2216 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2217 2218 do { 2219 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2220 (uint32_t)size)) != QL_SUCCESS) { 2221 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval); 2222 return (QL_MEMORY_ALLOC_FAILED); 2223 } 2224 2225 mcp->mb[0] = MBC_GET_LINK_STATUS; 2226 if (CFG_IST(ha, CFG_CTRL_242581)) { 2227 if (loop_id == ha->loop_id) { 2228 mcp->mb[0] = MBC_GET_STATUS_COUNTS; 2229 mcp->mb[8] = (uint16_t)(size >> 2); 2230 mcp->out_mb = MBX_10|MBX_8; 2231 } else { 2232 mcp->mb[1] = loop_id; 2233 mcp->mb[4] = port_no; 2234 mcp->mb[10] = (uint16_t)(retry ? BIT_3 : 0); 2235 mcp->out_mb = MBX_10|MBX_4; 2236 } 2237 } else { 2238 if (retry) { 2239 port_no = (uint8_t)(port_no | BIT_3); 2240 } 2241 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2242 mcp->mb[1] = loop_id; 2243 mcp->mb[10] = port_no; 2244 mcp->out_mb = MBX_10; 2245 } else { 2246 mcp->mb[1] = (uint16_t)((loop_id << 8) | 2247 port_no); 2248 mcp->out_mb = 0; 2249 } 2250 } 2251 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2252 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2253 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2254 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2255 mcp->in_mb = MBX_1|MBX_0; 2256 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2257 mcp->timeout = MAILBOX_TOV; 2258 2259 rval = ql_mailbox_command(ha, mcp); 2260 2261 if (rval == QL_SUCCESS) { 2262 ql_get_mbox_dma_data(&mem_desc, bufp); 2263 } 2264 2265 ql_free_dma_resource(ha, &mem_desc); 2266 2267 if (rval != QL_SUCCESS) { 2268 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 2269 } 2270 2271 /* 2272 * Some of the devices want d_id in the payload, 2273 * strictly as per standard. Let's retry. 2274 */ 2275 2276 } while (rval == QL_COMMAND_ERROR && !retry++); 2277 2278 if (rval != QL_SUCCESS) { 2279 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 2280 } else { 2281 /*EMPTY*/ 2282 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2283 } 2284 2285 return (rval); 2286 } 2287 2288 /* 2289 * ql_get_status_counts 2290 * Issue get adapter link status counts mailbox command. 2291 * 2292 * Input: 2293 * ha: adapter state pointer. 2294 * loop_id: FC loop id or n_port_hdl. 2295 * size: size of data buffer. 2296 * bufp: data pointer for DMA data. 2297 * port_no: port number to query. 2298 * 2299 * Returns: 2300 * ql local function return status code. 2301 * 2302 * Context: 2303 * Kernel context. 2304 */ 2305 int 2306 ql_get_status_counts(ql_adapter_state_t *ha, uint16_t loop_id, size_t size, 2307 caddr_t bufp, uint8_t port_no) 2308 { 2309 dma_mem_t mem_desc; 2310 mbx_cmd_t mc = {0}; 2311 mbx_cmd_t *mcp = &mc; 2312 int rval = QL_SUCCESS; 2313 2314 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2315 2316 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2317 (uint32_t)size)) != QL_SUCCESS) { 2318 EL(ha, "setup_mbox_dma_resources failed: %x\n", rval); 2319 return (QL_MEMORY_ALLOC_FAILED); 2320 } 2321 2322 if (CFG_IST(ha, CFG_CTRL_242581)) { 2323 mcp->mb[0] = MBC_GET_STATUS_COUNTS; 2324 mcp->mb[8] = (uint16_t)(size / 4); 2325 mcp->out_mb = MBX_10|MBX_8; 2326 } else { 2327 mcp->mb[0] = MBC_GET_LINK_STATUS; 2328 2329 /* allows reporting when link is down */ 2330 if (CFG_IST(ha, CFG_CTRL_2200) == 0) { 2331 port_no = (uint8_t)(port_no | BIT_6); 2332 } 2333 2334 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2335 mcp->mb[1] = loop_id; 2336 mcp->mb[10] = port_no; 2337 mcp->out_mb = MBX_10|MBX_1; 2338 } else { 2339 mcp->mb[1] = (uint16_t)((loop_id << 8) | 2340 port_no); 2341 mcp->out_mb = MBX_1; 2342 } 2343 } 2344 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2345 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2346 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2347 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2348 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 2349 mcp->in_mb = MBX_2|MBX_1|MBX_0; 2350 mcp->timeout = MAILBOX_TOV; 2351 rval = ql_mailbox_command(ha, mcp); 2352 2353 if (rval == QL_SUCCESS) { 2354 ql_get_mbox_dma_data(&mem_desc, bufp); 2355 } 2356 2357 ql_free_dma_resource(ha, &mem_desc); 2358 2359 if (rval != QL_SUCCESS) { 2360 EL(ha, "failed=%xh, mbx1=%xh, mbx2=%xh\n", rval, 2361 mcp->mb[1], mcp->mb[2]); 2362 } else { 2363 /*EMPTY*/ 2364 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2365 } 2366 2367 return (rval); 2368 } 2369 2370 /* 2371 * ql_reset_link_status 2372 * Issue Reset Link Error Status mailbox command 2373 * 2374 * Input: 2375 * ha: adapter state pointer. 2376 * 2377 * Returns: 2378 * ql local function return status code. 2379 * 2380 * Context: 2381 * Kernel context. 2382 */ 2383 int 2384 ql_reset_link_status(ql_adapter_state_t *ha) 2385 { 2386 int rval; 2387 mbx_cmd_t mc = {0}; 2388 mbx_cmd_t *mcp = &mc; 2389 2390 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2391 2392 mcp->mb[0] = MBC_RESET_LINK_STATUS; 2393 mcp->out_mb = MBX_0; 2394 mcp->in_mb = MBX_0; 2395 mcp->timeout = MAILBOX_TOV; 2396 rval = ql_mailbox_command(ha, mcp); 2397 2398 if (rval != QL_SUCCESS) { 2399 EL(ha, "failed=%xh\n", rval); 2400 } else { 2401 /*EMPTY*/ 2402 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2403 } 2404 2405 return (rval); 2406 } 2407 2408 /* 2409 * ql_loop_reset 2410 * Issue loop reset. 2411 * 2412 * Input: 2413 * ha: adapter state pointer. 2414 * 2415 * Returns: 2416 * ql local function return status code. 2417 * 2418 * Context: 2419 * Kernel context. 2420 */ 2421 int 2422 ql_loop_reset(ql_adapter_state_t *ha) 2423 { 2424 int rval; 2425 2426 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2427 2428 if (CFG_IST(ha, CFG_ENABLE_LIP_RESET)) { 2429 rval = ql_lip_reset(ha, 0xff); 2430 } else if (CFG_IST(ha, CFG_ENABLE_FULL_LIP_LOGIN)) { 2431 rval = ql_full_login_lip(ha); 2432 } else if (CFG_IST(ha, CFG_ENABLE_TARGET_RESET)) { 2433 rval = ql_target_reset(ha, NULL, ha->loop_reset_delay); 2434 } else { 2435 rval = ql_initiate_lip(ha); 2436 } 2437 2438 if (rval != QL_SUCCESS) { 2439 EL(ha, "failed, rval = %xh\n", rval); 2440 } else { 2441 /*EMPTY*/ 2442 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2443 } 2444 2445 return (rval); 2446 } 2447 2448 /* 2449 * ql_initiate_lip 2450 * Initiate LIP mailbox command. 2451 * 2452 * Input: 2453 * ha: adapter state pointer. 2454 * 2455 * Returns: 2456 * ql local function return status code. 2457 * 2458 * Context: 2459 * Kernel context. 2460 */ 2461 int 2462 ql_initiate_lip(ql_adapter_state_t *ha) 2463 { 2464 int rval; 2465 mbx_cmd_t mc = {0}; 2466 mbx_cmd_t *mcp = &mc; 2467 2468 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2469 2470 if (CFG_IST(ha, CFG_CTRL_242581)) { 2471 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 2472 mcp->mb[1] = BIT_4; 2473 mcp->mb[3] = ha->loop_reset_delay; 2474 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2475 } else { 2476 mcp->mb[0] = MBC_INITIATE_LIP; 2477 mcp->out_mb = MBX_0; 2478 } 2479 mcp->in_mb = MBX_0; 2480 mcp->timeout = MAILBOX_TOV; 2481 rval = ql_mailbox_command(ha, mcp); 2482 2483 if (rval != QL_SUCCESS) { 2484 EL(ha, "failed, rval = %xh\n", rval); 2485 } else { 2486 /*EMPTY*/ 2487 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2488 } 2489 2490 return (rval); 2491 } 2492 2493 /* 2494 * ql_full_login_lip 2495 * Issue full login LIP mailbox command. 2496 * 2497 * Input: 2498 * ha: adapter state pointer. 2499 * 2500 * Returns: 2501 * ql local function return status code. 2502 * 2503 * Context: 2504 * Kernel context. 2505 */ 2506 int 2507 ql_full_login_lip(ql_adapter_state_t *ha) 2508 { 2509 int rval; 2510 mbx_cmd_t mc = {0}; 2511 mbx_cmd_t *mcp = &mc; 2512 2513 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2514 2515 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 2516 if (CFG_IST(ha, CFG_CTRL_2425)) { 2517 mcp->mb[1] = BIT_3; 2518 } else if (CFG_IST(ha, CFG_CTRL_81XX)) { 2519 mcp->mb[1] = BIT_1; 2520 } 2521 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2522 mcp->in_mb = MBX_0; 2523 mcp->timeout = MAILBOX_TOV; 2524 rval = ql_mailbox_command(ha, mcp); 2525 2526 if (rval != QL_SUCCESS) { 2527 EL(ha, "failed, rval = %xh\n", rval); 2528 } else { 2529 /*EMPTY*/ 2530 QL_PRINT_3(CE_CONT, "(%d): done", ha->instance); 2531 } 2532 2533 return (rval); 2534 } 2535 2536 /* 2537 * ql_lip_reset 2538 * Issue lip reset to a port. 2539 * 2540 * Input: 2541 * ha: adapter state pointer. 2542 * loop_id: FC loop id. 2543 * 2544 * Returns: 2545 * ql local function return status code. 2546 * 2547 * Context: 2548 * Kernel context. 2549 */ 2550 int 2551 ql_lip_reset(ql_adapter_state_t *ha, uint16_t loop_id) 2552 { 2553 int rval; 2554 mbx_cmd_t mc = {0}; 2555 mbx_cmd_t *mcp = &mc; 2556 2557 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2558 2559 if (CFG_IST(ha, CFG_CTRL_242581)) { 2560 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 2561 mcp->mb[1] = BIT_6; 2562 mcp->mb[3] = ha->loop_reset_delay; 2563 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2564 } else { 2565 mcp->mb[0] = MBC_LIP_RESET; 2566 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2567 mcp->mb[1] = loop_id; 2568 mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0; 2569 } else { 2570 mcp->mb[1] = (uint16_t)(loop_id << 8); 2571 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2572 } 2573 mcp->mb[2] = ha->loop_reset_delay; 2574 } 2575 mcp->in_mb = MBX_0; 2576 mcp->timeout = MAILBOX_TOV; 2577 rval = ql_mailbox_command(ha, mcp); 2578 2579 if (rval != QL_SUCCESS) { 2580 EL(ha, "failed, rval = %xh\n", rval); 2581 } else { 2582 /*EMPTY*/ 2583 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2584 } 2585 2586 return (rval); 2587 } 2588 2589 /* 2590 * ql_abort_command 2591 * Abort command aborts a specified IOCB. 2592 * 2593 * Input: 2594 * ha: adapter state pointer. 2595 * sp: SRB structure pointer. 2596 * 2597 * Returns: 2598 * ql local function return status code. 2599 * 2600 * Context: 2601 * Kernel context. 2602 */ 2603 int 2604 ql_abort_command(ql_adapter_state_t *ha, ql_srb_t *sp) 2605 { 2606 int rval; 2607 mbx_cmd_t mc = {0}; 2608 mbx_cmd_t *mcp = &mc; 2609 ql_tgt_t *tq = sp->lun_queue->target_queue; 2610 2611 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2612 2613 if (CFG_IST(ha, CFG_CTRL_242581)) { 2614 rval = ql_abort_cmd_iocb(ha, sp); 2615 } else { 2616 mcp->mb[0] = MBC_ABORT_COMMAND_IOCB; 2617 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2618 mcp->mb[1] = tq->loop_id; 2619 } else { 2620 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 2621 } 2622 mcp->mb[2] = LSW(sp->handle); 2623 mcp->mb[3] = MSW(sp->handle); 2624 mcp->mb[6] = (uint16_t)(sp->flags & SRB_FCP_CMD_PKT ? 2625 sp->lun_queue->lun_no : 0); 2626 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2627 mcp->in_mb = MBX_0; 2628 mcp->timeout = MAILBOX_TOV; 2629 rval = ql_mailbox_command(ha, mcp); 2630 } 2631 2632 if (rval != QL_SUCCESS) { 2633 EL(ha, "failed=%xh, d_id=%xh, handle=%xh\n", rval, 2634 tq->d_id.b24, sp->handle); 2635 } else { 2636 /*EMPTY*/ 2637 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2638 } 2639 2640 return (rval); 2641 } 2642 2643 /* 2644 * ql_abort_cmd_iocb 2645 * Function issues abort command IOCB. 2646 * 2647 * Input: 2648 * ha: adapter state pointer. 2649 * sp: SRB structure pointer. 2650 * 2651 * Returns: 2652 * ql local function return status code. 2653 * 2654 * Context: 2655 * Interrupt or Kernel context, no mailbox commands allowed. 2656 */ 2657 static int 2658 ql_abort_cmd_iocb(ql_adapter_state_t *ha, ql_srb_t *sp) 2659 { 2660 ql_mbx_iocb_t *pkt; 2661 int rval; 2662 uint32_t pkt_size; 2663 uint16_t comp_status; 2664 ql_tgt_t *tq = sp->lun_queue->target_queue; 2665 2666 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2667 2668 pkt_size = sizeof (ql_mbx_iocb_t); 2669 if ((pkt = kmem_zalloc(pkt_size, KM_SLEEP)) == NULL) { 2670 EL(ha, "failed, kmem_zalloc\n"); 2671 return (QL_MEMORY_ALLOC_FAILED); 2672 } 2673 2674 pkt->abo.entry_type = ABORT_CMD_TYPE; 2675 pkt->abo.entry_count = 1; 2676 pkt->abo.n_port_hdl = (uint16_t)LE_16(tq->loop_id); 2677 pkt->abo.options = AF_NO_ABTS; 2678 pkt->abo.cmd_handle = LE_32(sp->handle); 2679 pkt->abo.target_id[0] = tq->d_id.b.al_pa; 2680 pkt->abo.target_id[1] = tq->d_id.b.area; 2681 pkt->abo.target_id[2] = tq->d_id.b.domain; 2682 pkt->abo.vp_index = ha->vp_index; 2683 2684 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size); 2685 2686 if (rval == QL_SUCCESS && (pkt->abo.entry_status & 0x3c) != 0) { 2687 EL(ha, "failed, entry_status=%xh, d_id=%xh\n", 2688 pkt->abo.entry_status, tq->d_id.b24); 2689 rval = QL_FUNCTION_PARAMETER_ERROR; 2690 } 2691 2692 comp_status = (uint16_t)LE_16(pkt->abo.n_port_hdl); 2693 if (rval == QL_SUCCESS && comp_status != CS_COMPLETE) { 2694 EL(ha, "failed, comp_status=%xh, d_id=%xh\n", 2695 comp_status, tq->d_id.b24); 2696 rval = QL_FUNCTION_FAILED; 2697 } 2698 2699 kmem_free(pkt, pkt_size); 2700 2701 if (rval != QL_SUCCESS) { 2702 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 2703 } else { 2704 /*EMPTY*/ 2705 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2706 } 2707 2708 return (rval); 2709 } 2710 2711 /* 2712 * ql_verify_checksum 2713 * Verify loaded RISC firmware. 2714 * 2715 * Input: 2716 * ha = adapter state pointer. 2717 * 2718 * Returns: 2719 * ql local function return status code. 2720 * 2721 * Context: 2722 * Kernel context. 2723 */ 2724 int 2725 ql_verify_checksum(ql_adapter_state_t *ha) 2726 { 2727 int rval; 2728 mbx_cmd_t mc = {0}; 2729 mbx_cmd_t *mcp = &mc; 2730 2731 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2732 2733 mcp->mb[0] = MBC_VERIFY_CHECKSUM; 2734 if (CFG_IST(ha, CFG_CTRL_242581)) { 2735 mcp->mb[1] = MSW(ha->risc_fw[0].addr); 2736 mcp->mb[2] = LSW(ha->risc_fw[0].addr); 2737 } else { 2738 mcp->mb[1] = LSW(ha->risc_fw[0].addr); 2739 } 2740 mcp->out_mb = MBX_2|MBX_1|MBX_0; 2741 mcp->in_mb = MBX_2|MBX_1|MBX_0; 2742 mcp->timeout = MAILBOX_TOV; 2743 rval = ql_mailbox_command(ha, mcp); 2744 2745 if (rval != QL_SUCCESS) { 2746 EL(ha, "failed, rval = %xh\n", rval); 2747 } else { 2748 /*EMPTY*/ 2749 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2750 } 2751 2752 return (rval); 2753 } 2754 2755 /* 2756 * ql_get_id_list 2757 * Get d_id and loop ID list. 2758 * 2759 * Input: 2760 * ha: adapter state pointer. 2761 * bp: data pointer for DMA data. 2762 * size: size of data buffer. 2763 * mr: pointer for mailbox data. 2764 * 2765 * Returns: 2766 * ql local function return status code. 2767 * 2768 * Context: 2769 * Kernel context. 2770 */ 2771 int 2772 ql_get_id_list(ql_adapter_state_t *ha, caddr_t bp, uint32_t size, 2773 ql_mbx_data_t *mr) 2774 { 2775 int rval; 2776 dma_mem_t mem_desc; 2777 mbx_cmd_t mc = {0}; 2778 mbx_cmd_t *mcp = &mc; 2779 2780 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2781 2782 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2783 (uint32_t)size)) != QL_SUCCESS) { 2784 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval); 2785 return (QL_MEMORY_ALLOC_FAILED); 2786 } 2787 2788 mcp->mb[0] = MBC_GET_ID_LIST; 2789 if (CFG_IST(ha, CFG_CTRL_242581)) { 2790 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2791 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2792 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2793 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2794 mcp->mb[8] = (uint16_t)size; 2795 mcp->mb[9] = ha->vp_index; 2796 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 2797 } else { 2798 mcp->mb[1] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2799 mcp->mb[2] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2800 mcp->mb[3] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2801 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2802 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2803 } 2804 mcp->in_mb = MBX_1|MBX_0; 2805 mcp->timeout = MAILBOX_TOV; 2806 rval = ql_mailbox_command(ha, mcp); 2807 2808 if (rval == QL_SUCCESS) { 2809 ql_get_mbox_dma_data(&mem_desc, bp); 2810 } 2811 2812 ql_free_dma_resource(ha, &mem_desc); 2813 2814 /* Return mailbox data. */ 2815 if (mr != NULL) { 2816 mr->mb[0] = mcp->mb[0]; 2817 mr->mb[1] = mcp->mb[1]; 2818 } 2819 2820 if (rval != QL_SUCCESS) { 2821 EL(ha, "failed, rval = %xh\n", rval); 2822 } else { 2823 /*EMPTY*/ 2824 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2825 } 2826 2827 return (rval); 2828 } 2829 2830 /* 2831 * ql_wrt_risc_ram 2832 * Load RISC RAM. 2833 * 2834 * Input: 2835 * ha: adapter state pointer. 2836 * risc_address: risc ram word address. 2837 * bp: DMA pointer. 2838 * word_count: 16/32bit word count. 2839 * 2840 * Returns: 2841 * ql local function return status code. 2842 * 2843 * Context: 2844 * Kernel context. 2845 */ 2846 int 2847 ql_wrt_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp, 2848 uint32_t word_count) 2849 { 2850 int rval; 2851 mbx_cmd_t mc = {0}; 2852 mbx_cmd_t *mcp = &mc; 2853 2854 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2855 2856 if (CFG_IST(ha, CFG_CTRL_242581)) { 2857 mcp->mb[0] = MBC_LOAD_RAM_EXTENDED; 2858 mcp->mb[4] = MSW(word_count); 2859 mcp->mb[5] = LSW(word_count); 2860 mcp->mb[6] = MSW(MSD(bp)); 2861 mcp->mb[7] = LSW(MSD(bp)); 2862 mcp->mb[8] = MSW(risc_address); 2863 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1| 2864 MBX_0; 2865 } else { 2866 mcp->mb[0] = MBC_LOAD_RAM; 2867 mcp->mb[4] = LSW(word_count); 2868 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 2869 } 2870 mcp->mb[1] = LSW(risc_address); 2871 mcp->mb[2] = MSW(LSD(bp)); 2872 mcp->mb[3] = LSW(LSD(bp)); 2873 mcp->in_mb = MBX_0; 2874 mcp->timeout = MAILBOX_TOV; 2875 2876 rval = ql_mailbox_command(ha, mcp); 2877 2878 if (rval != QL_SUCCESS) { 2879 EL(ha, "failed, rval = %xh\n", rval); 2880 } else { 2881 /*EMPTY*/ 2882 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2883 } 2884 2885 return (rval); 2886 } 2887 2888 /* 2889 * ql_rd_risc_ram 2890 * Get RISC RAM. 2891 * 2892 * Input: 2893 * ha: adapter state pointer. 2894 * risc_address: risc ram word address. 2895 * bp: direct data pointer. 2896 * word_count: 16/32bit word count. 2897 * 2898 * Returns: 2899 * ql local function return status code. 2900 * 2901 * Context: 2902 * Kernel context. 2903 */ 2904 int 2905 ql_rd_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp, 2906 uint32_t word_count) 2907 { 2908 int rval; 2909 mbx_cmd_t mc = {0}; 2910 mbx_cmd_t *mcp = &mc; 2911 2912 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2913 2914 if (CFG_IST(ha, CFG_CTRL_242581)) { 2915 mcp->mb[0] = MBC_DUMP_RAM_EXTENDED; 2916 mcp->mb[1] = LSW(risc_address); 2917 mcp->mb[2] = MSW(LSD(bp)); 2918 mcp->mb[3] = LSW(LSD(bp)); 2919 mcp->mb[4] = MSW(word_count); 2920 mcp->mb[5] = LSW(word_count); 2921 mcp->mb[6] = MSW(MSD(bp)); 2922 mcp->mb[7] = LSW(MSD(bp)); 2923 mcp->mb[8] = MSW(risc_address); 2924 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1| 2925 MBX_0; 2926 } else { 2927 mcp->mb[0] = MBC_DUMP_RAM; /* doesn't support 64bit addr */ 2928 mcp->mb[1] = LSW(risc_address); 2929 mcp->mb[2] = MSW(LSD(bp)); 2930 mcp->mb[3] = LSW(LSD(bp)); 2931 mcp->mb[4] = LSW(word_count); 2932 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 2933 } 2934 mcp->in_mb = MBX_0; 2935 mcp->timeout = MAILBOX_TOV; 2936 rval = ql_mailbox_command(ha, mcp); 2937 2938 if (rval != QL_SUCCESS) { 2939 EL(ha, "failed, rval = %xh\n", rval); 2940 } else { 2941 /*EMPTY*/ 2942 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2943 } 2944 2945 return (rval); 2946 } 2947 2948 /* 2949 * ql_issue_mbx_iocb 2950 * Issue IOCB using mailbox command 2951 * 2952 * Input: 2953 * ha: adapter state pointer. 2954 * bp: buffer pointer. 2955 * size: buffer size. 2956 * 2957 * Returns: 2958 * ql local function return status code. 2959 * 2960 * Context: 2961 * Kernel context. 2962 */ 2963 int 2964 ql_issue_mbx_iocb(ql_adapter_state_t *ha, caddr_t bp, uint32_t size) 2965 { 2966 int rval; 2967 dma_mem_t mem_desc; 2968 mbx_cmd_t mc = {0}; 2969 mbx_cmd_t *mcp = &mc; 2970 2971 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2972 2973 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) != 2974 QL_SUCCESS) { 2975 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval); 2976 return (rval); 2977 } 2978 2979 mcp->mb[0] = MBC_EXECUTE_IOCB; 2980 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2981 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2982 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2983 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2984 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2985 mcp->in_mb = MBX_1|MBX_0; 2986 mcp->timeout = MAILBOX_TOV + 5; 2987 rval = ql_mailbox_command(ha, mcp); 2988 2989 if (rval == QL_SUCCESS) { 2990 ql_get_mbox_dma_data(&mem_desc, bp); 2991 } 2992 2993 ql_free_dma_resource(ha, &mem_desc); 2994 2995 if (rval != QL_SUCCESS) { 2996 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 2997 } else { 2998 /*EMPTY*/ 2999 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3000 } 3001 3002 return (rval); 3003 } 3004 3005 /* 3006 * ql_mbx_wrap_test 3007 * Mailbox register wrap test. 3008 * 3009 * Input: 3010 * ha: adapter state pointer. 3011 * mr: pointer for in/out mailbox data. 3012 * 3013 * Returns: 3014 * ql local function return status code. 3015 * 3016 * Context: 3017 * Kernel context. 3018 */ 3019 int 3020 ql_mbx_wrap_test(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3021 { 3022 int rval; 3023 mbx_cmd_t mc = {0}; 3024 mbx_cmd_t *mcp = &mc; 3025 3026 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3027 3028 if (mr != NULL) { 3029 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; 3030 mcp->mb[1] = mr->mb[1]; 3031 mcp->mb[2] = mr->mb[2]; 3032 mcp->mb[3] = mr->mb[3]; 3033 mcp->mb[4] = mr->mb[4]; 3034 mcp->mb[5] = mr->mb[5]; 3035 mcp->mb[6] = mr->mb[6]; 3036 mcp->mb[7] = mr->mb[7]; 3037 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3038 mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3039 mcp->timeout = MAILBOX_TOV; 3040 rval = ql_mailbox_command(ha, mcp); 3041 if (rval == QL_SUCCESS) { 3042 mr->mb[1] = mcp->mb[1]; 3043 mr->mb[2] = mcp->mb[2]; 3044 mr->mb[3] = mcp->mb[3]; 3045 mr->mb[4] = mcp->mb[4]; 3046 mr->mb[5] = mcp->mb[5]; 3047 mr->mb[6] = mcp->mb[6]; 3048 mr->mb[7] = mcp->mb[7]; 3049 } 3050 } else { 3051 rval = QL_FUNCTION_PARAMETER_ERROR; 3052 } 3053 3054 if (rval != QL_SUCCESS) { 3055 EL(ha, "failed=%xh\n", rval); 3056 } else { 3057 /*EMPTY*/ 3058 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3059 } 3060 3061 return (rval); 3062 } 3063 3064 /* 3065 * ql_execute_fw 3066 * Start adapter firmware. 3067 * 3068 * Input: 3069 * ha: adapter state pointer. 3070 * 3071&