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