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