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