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_isr.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_init.h> 49 #include <ql_mbx.h> 50 #include <ql_nx.h> 51 #include <ql_xioctl.h> 52 53 /* 54 * Local Function Prototypes. 55 */ 56 static void ql_handle_uncommon_risc_intr(ql_adapter_state_t *, uint32_t, 57 uint32_t *); 58 static void ql_spurious_intr(ql_adapter_state_t *, int); 59 static void ql_mbx_completion(ql_adapter_state_t *, uint16_t, uint32_t *, 60 uint32_t *, int); 61 static void ql_async_event(ql_adapter_state_t *, uint32_t, ql_head_t *, 62 uint32_t *, uint32_t *, int); 63 static void ql_fast_fcp_post(ql_srb_t *); 64 static void ql_response_pkt(ql_adapter_state_t *, ql_head_t *, uint32_t *, 65 uint32_t *, int); 66 static void ql_error_entry(ql_adapter_state_t *, response_t *, ql_head_t *, 67 uint32_t *, uint32_t *); 68 static int ql_status_entry(ql_adapter_state_t *, sts_entry_t *, ql_head_t *, 69 uint32_t *, uint32_t *); 70 static int ql_24xx_status_entry(ql_adapter_state_t *, sts_24xx_entry_t *, 71 ql_head_t *, uint32_t *, uint32_t *); 72 static int ql_status_error(ql_adapter_state_t *, ql_srb_t *, sts_entry_t *, 73 ql_head_t *, uint32_t *, uint32_t *); 74 static void ql_status_cont_entry(ql_adapter_state_t *, sts_cont_entry_t *, 75 ql_head_t *, uint32_t *, uint32_t *); 76 static void ql_ip_entry(ql_adapter_state_t *, ip_entry_t *, ql_head_t *, 77 uint32_t *, uint32_t *); 78 static void ql_ip_rcv_entry(ql_adapter_state_t *, ip_rcv_entry_t *, 79 ql_head_t *, uint32_t *, uint32_t *); 80 static void ql_ip_rcv_cont_entry(ql_adapter_state_t *, 81 ip_rcv_cont_entry_t *, ql_head_t *, uint32_t *, uint32_t *); 82 static void ql_ip_24xx_rcv_entry(ql_adapter_state_t *, ip_rcv_24xx_entry_t *, 83 ql_head_t *, uint32_t *, uint32_t *); 84 static void ql_ms_entry(ql_adapter_state_t *, ms_entry_t *, ql_head_t *, 85 uint32_t *, uint32_t *); 86 static void ql_report_id_entry(ql_adapter_state_t *, report_id_1_t *, 87 ql_head_t *, uint32_t *, uint32_t *); 88 static void ql_els_passthru_entry(ql_adapter_state_t *, 89 els_passthru_entry_rsp_t *, ql_head_t *, uint32_t *, uint32_t *); 90 static ql_srb_t *ql_verify_preprocessed_cmd(ql_adapter_state_t *, uint32_t *, 91 uint32_t *, uint32_t *); 92 static void ql_signal_abort(ql_adapter_state_t *ha, uint32_t *set_flags); 93 94 /* 95 * Spurious interrupt counter 96 */ 97 uint32_t ql_spurious_cnt = 4; 98 uint32_t ql_max_intr_loop = 16; 99 100 /* 101 * ql_isr 102 * Process all INTX intr types. 103 * 104 * Input: 105 * arg1: adapter state pointer. 106 * 107 * Returns: 108 * DDI_INTR_CLAIMED or DDI_INTR_UNCLAIMED 109 * 110 * Context: 111 * Interrupt or Kernel context, no mailbox commands allowed. 112 */ 113 /* ARGSUSED */ 114 uint_t 115 ql_isr(caddr_t arg1) 116 { 117 return (ql_isr_aif(arg1, 0)); 118 } 119 120 /* 121 * ql_isr_default 122 * Process unknown/unvectored intr types 123 * 124 * Input: 125 * arg1: adapter state pointer. 126 * arg2: interrupt vector. 127 * 128 * Returns: 129 * DDI_INTR_CLAIMED or DDI_INTR_UNCLAIMED 130 * 131 * Context: 132 * Interrupt or Kernel context, no mailbox commands allowed. 133 */ 134 /* ARGSUSED */ 135 uint_t 136 ql_isr_default(caddr_t arg1, caddr_t arg2) 137 { 138 ql_adapter_state_t *ha = (void *)arg1; 139 140 EL(ha, "isr_default called: idx=%x\n", arg2); 141 return (ql_isr_aif(arg1, arg2)); 142 } 143 144 /* 145 * ql_isr_aif 146 * Process mailbox and I/O command completions. 147 * 148 * Input: 149 * arg: adapter state pointer. 150 * intvec: interrupt vector. 151 * 152 * Returns: 153 * DDI_INTR_CLAIMED or DDI_INTR_UNCLAIMED 154 * 155 * Context: 156 * Interrupt or Kernel context, no mailbox commands allowed. 157 */ 158 /* ARGSUSED */ 159 uint_t 160 ql_isr_aif(caddr_t arg, caddr_t intvec) 161 { 162 uint16_t mbx; 163 uint32_t stat; 164 ql_adapter_state_t *ha = (void *)arg; 165 uint32_t set_flags = 0; 166 uint32_t reset_flags = 0; 167 ql_head_t isr_done_q = {NULL, NULL}; 168 uint_t rval = DDI_INTR_UNCLAIMED; 169 int spurious_intr = 0; 170 boolean_t intr = B_FALSE, daemon = B_FALSE; 171 int intr_loop = 4; 172 boolean_t clear_spurious = B_TRUE; 173 174 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 175 176 QL_PM_LOCK(ha); 177 if (ha->power_level != PM_LEVEL_D0) { 178 /* 179 * Looks like we are about to go down soon, exit early. 180 */ 181 QL_PM_UNLOCK(ha); 182 QL_PRINT_3(CE_CONT, "(%d): power down exit\n", ha->instance); 183 return (DDI_INTR_UNCLAIMED); 184 } 185 ha->busy++; 186 QL_PM_UNLOCK(ha); 187 188 /* Acquire interrupt lock. */ 189 INTR_LOCK(ha); 190 191 if (CFG_IST(ha, CFG_CTRL_2200)) { 192 while (RD16_IO_REG(ha, istatus) & RISC_INT) { 193 /* Reset idle timer. */ 194 ha->idle_timer = 0; 195 rval = DDI_INTR_CLAIMED; 196 if (intr_loop) { 197 intr_loop--; 198 } 199 200 /* Special Fast Post 2200. */ 201 stat = 0; 202 if (ha->task_daemon_flags & FIRMWARE_LOADED && 203 ha->flags & ONLINE) { 204 ql_srb_t *sp; 205 206 mbx = RD16_IO_REG(ha, mailbox_out[23]); 207 208 if ((mbx & 3) == MBX23_SCSI_COMPLETION) { 209 /* Release mailbox registers. */ 210 WRT16_IO_REG(ha, semaphore, 0); 211 212 if (intr_loop) { 213 WRT16_IO_REG(ha, hccr, 214 HC_CLR_RISC_INT); 215 } 216 217 /* Get handle. */ 218 mbx >>= 4; 219 stat = mbx & OSC_INDEX_MASK; 220 221 /* Validate handle. */ 222 sp = stat < MAX_OUTSTANDING_COMMANDS ? 223 ha->outstanding_cmds[stat] : NULL; 224 225 if (sp != NULL && (sp->handle & 0xfff) 226 == mbx) { 227 ha->outstanding_cmds[stat] = 228 NULL; 229 sp->handle = 0; 230 sp->flags &= 231 ~SRB_IN_TOKEN_ARRAY; 232 233 /* Set completed status. */ 234 sp->flags |= SRB_ISP_COMPLETED; 235 236 /* Set completion status */ 237 sp->pkt->pkt_reason = 238 CS_COMPLETE; 239 240 ql_fast_fcp_post(sp); 241 } else if (mbx != 242 (QL_FCA_BRAND & 0xfff)) { 243 if (sp == NULL) { 244 EL(ha, "unknown IOCB" 245 " handle=%xh\n", 246 mbx); 247 } else { 248 EL(ha, "mismatch IOCB" 249 " handle pkt=%xh, " 250 "sp=%xh\n", mbx, 251 sp->handle & 0xfff); 252 } 253 254 (void) ql_binary_fw_dump(ha, 255 FALSE); 256 257 if (!(ha->task_daemon_flags & 258 (ISP_ABORT_NEEDED | 259 ABORT_ISP_ACTIVE))) { 260 EL(ha, "ISP Invalid " 261 "handle, " 262 "isp_abort_needed" 263 "\n"); 264 set_flags |= 265 ISP_ABORT_NEEDED; 266 } 267 } 268 } 269 } 270 271 if (stat == 0) { 272 /* Check for mailbox interrupt. */ 273 mbx = RD16_IO_REG(ha, semaphore); 274 if (mbx & BIT_0) { 275 /* Release mailbox registers. */ 276 WRT16_IO_REG(ha, semaphore, 0); 277 278 /* Get mailbox data. */ 279 mbx = RD16_IO_REG(ha, mailbox_out[0]); 280 if (mbx > 0x3fff && mbx < 0x8000) { 281 ql_mbx_completion(ha, mbx, 282 &set_flags, &reset_flags, 283 intr_loop); 284 } else if (mbx > 0x7fff && 285 mbx < 0xc000) { 286 ql_async_event(ha, mbx, 287 &isr_done_q, &set_flags, 288 &reset_flags, intr_loop); 289 } else { 290 EL(ha, "UNKNOWN interrupt " 291 "type\n"); 292 intr = B_TRUE; 293 } 294 } else { 295 ha->isp_rsp_index = RD16_IO_REG(ha, 296 resp_in); 297 298 if (ha->isp_rsp_index != 299 ha->rsp_ring_index) { 300 ql_response_pkt(ha, 301 &isr_done_q, &set_flags, 302 &reset_flags, intr_loop); 303 } else if (++spurious_intr == 304 MAX_SPURIOUS_INTR) { 305 /* 306 * Process excessive 307 * spurious intrrupts 308 */ 309 ql_spurious_intr(ha, 310 intr_loop); 311 EL(ha, "excessive spurious " 312 "interrupts, " 313 "isp_abort_needed\n"); 314 set_flags |= ISP_ABORT_NEEDED; 315 } else { 316 intr = B_TRUE; 317 } 318 } 319 } 320 321 /* Clear RISC interrupt */ 322 if (intr || intr_loop == 0) { 323 intr = B_FALSE; 324 WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT); 325 } 326 327 if (set_flags != 0 || reset_flags != 0) { 328 TASK_DAEMON_LOCK(ha); 329 ha->task_daemon_flags |= set_flags; 330 ha->task_daemon_flags &= ~reset_flags; 331 TASK_DAEMON_UNLOCK(ha); 332 set_flags = 0; 333 reset_flags = 0; 334 daemon = B_TRUE; 335 } 336 } 337 } else { 338 uint32_t ql_max_intr_loop_cnt = 0; 339 340 if (CFG_IST(ha, CFG_CTRL_8021)) { 341 ql_8021_clr_hw_intr(ha); 342 intr_loop = 1; 343 } 344 while (((stat = RD32_IO_REG(ha, risc2host)) & RH_RISC_INT) && 345 (++ql_max_intr_loop_cnt < ql_max_intr_loop)) { 346 347 clear_spurious = B_TRUE; /* assume ok */ 348 349 /* Capture FW defined interrupt info */ 350 mbx = MSW(stat); 351 352 /* Reset idle timer. */ 353 ha->idle_timer = 0; 354 rval = DDI_INTR_CLAIMED; 355 356 if (CFG_IST(ha, CFG_CTRL_8021) && 357 (RD32_IO_REG(ha, nx_risc_int) == 0 || 358 intr_loop == 0)) { 359 break; 360 } 361 362 if (intr_loop) { 363 intr_loop--; 364 } 365 366 switch (stat & 0x1ff) { 367 case ROM_MBX_SUCCESS: 368 case ROM_MBX_ERR: 369 ql_mbx_completion(ha, mbx, &set_flags, 370 &reset_flags, intr_loop); 371 372 /* Release mailbox registers. */ 373 if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) { 374 WRT16_IO_REG(ha, semaphore, 0); 375 } 376 break; 377 378 case MBX_SUCCESS: 379 case MBX_ERR: 380 /* Sun FW, Release mailbox registers. */ 381 if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) { 382 WRT16_IO_REG(ha, semaphore, 0); 383 } 384 ql_mbx_completion(ha, mbx, &set_flags, 385 &reset_flags, intr_loop); 386 break; 387 388 case ASYNC_EVENT: 389 /* Sun FW, Release mailbox registers. */ 390 if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) { 391 WRT16_IO_REG(ha, semaphore, 0); 392 } 393 ql_async_event(ha, (uint32_t)mbx, &isr_done_q, 394 &set_flags, &reset_flags, intr_loop); 395 break; 396 397 case RESP_UPDATE: 398 if (mbx != ha->rsp_ring_index) { 399 ha->isp_rsp_index = mbx; 400 ql_response_pkt(ha, &isr_done_q, 401 &set_flags, &reset_flags, 402 intr_loop); 403 } else if (++spurious_intr == 404 ql_spurious_cnt) { 405 /* Process excessive spurious intr. */ 406 ql_spurious_intr(ha, intr_loop); 407 EL(ha, "excessive spurious " 408 "interrupts, isp_abort_needed\n"); 409 set_flags |= ISP_ABORT_NEEDED; 410 clear_spurious = B_FALSE; 411 } else { 412 QL_PRINT_10(CE_CONT, "(%d): response " 413 "ring index same as before\n", 414 ha->instance); 415 intr = B_TRUE; 416 clear_spurious = B_FALSE; 417 } 418 break; 419 420 case SCSI_FAST_POST_16: 421 stat = (stat & 0xffff0000) | MBA_CMPLT_1_16BIT; 422 ql_async_event(ha, stat, &isr_done_q, 423 &set_flags, &reset_flags, intr_loop); 424 break; 425 426 case SCSI_FAST_POST_32: 427 stat = (stat & 0xffff0000) | MBA_CMPLT_1_32BIT; 428 ql_async_event(ha, stat, &isr_done_q, 429 &set_flags, &reset_flags, intr_loop); 430 break; 431 432 case CTIO_FAST_POST: 433 stat = (stat & 0xffff0000) | 434 MBA_CTIO_COMPLETION; 435 ql_async_event(ha, stat, &isr_done_q, 436 &set_flags, &reset_flags, intr_loop); 437 break; 438 439 case IP_FAST_POST_XMT: 440 stat = (stat & 0xffff0000) | MBA_IP_COMPLETION; 441 ql_async_event(ha, stat, &isr_done_q, 442 &set_flags, &reset_flags, intr_loop); 443 break; 444 445 case IP_FAST_POST_RCV: 446 stat = (stat & 0xffff0000) | MBA_IP_RECEIVE; 447 ql_async_event(ha, stat, &isr_done_q, 448 &set_flags, &reset_flags, intr_loop); 449 break; 450 451 case IP_FAST_POST_BRD: 452 stat = (stat & 0xffff0000) | MBA_IP_BROADCAST; 453 ql_async_event(ha, stat, &isr_done_q, 454 &set_flags, &reset_flags, intr_loop); 455 break; 456 457 case IP_FAST_POST_RCV_ALN: 458 stat = (stat & 0xffff0000) | 459 MBA_IP_HDR_DATA_SPLIT; 460 ql_async_event(ha, stat, &isr_done_q, 461 &set_flags, &reset_flags, intr_loop); 462 break; 463 464 case ATIO_UPDATE: 465 EL(ha, "unsupported ATIO queue update" 466 " interrupt, status=%xh\n", stat); 467 intr = B_TRUE; 468 break; 469 470 case ATIO_RESP_UPDATE: 471 EL(ha, "unsupported ATIO response queue " 472 "update interrupt, status=%xh\n", stat); 473 intr = B_TRUE; 474 break; 475 476 default: 477 ql_handle_uncommon_risc_intr(ha, stat, 478 &set_flags); 479 intr = B_TRUE; 480 break; 481 } 482 483 /* Clear RISC interrupt */ 484 if (intr || intr_loop == 0) { 485 intr = B_FALSE; 486 if (CFG_IST(ha, CFG_CTRL_8021)) { 487 ql_8021_clr_fw_intr(ha); 488 } else if (CFG_IST(ha, CFG_CTRL_242581)) { 489 WRT32_IO_REG(ha, hccr, 490 HC24_CLR_RISC_INT); 491 } else { 492 WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT); 493 } 494 } 495 496 if (set_flags != 0 || reset_flags != 0) { 497 TASK_DAEMON_LOCK(ha); 498 ha->task_daemon_flags |= set_flags; 499 ha->task_daemon_flags &= ~reset_flags; 500 TASK_DAEMON_UNLOCK(ha); 501 set_flags = 0; 502 reset_flags = 0; 503 daemon = B_TRUE; 504 } 505 506 if (ha->flags & PARITY_ERROR) { 507 EL(ha, "parity/pause exit\n"); 508 mbx = RD16_IO_REG(ha, hccr); /* PCI posting */ 509 break; 510 } 511 512 if (clear_spurious) { 513 spurious_intr = 0; 514 } 515 } 516 } 517 518 /* Process claimed interrupts during polls. */ 519 if (rval == DDI_INTR_UNCLAIMED && ha->intr_claimed == B_TRUE) { 520 ha->intr_claimed = B_FALSE; 521 rval = DDI_INTR_CLAIMED; 522 } 523 524 /* Release interrupt lock. */ 525 INTR_UNLOCK(ha); 526 527 if (daemon) { 528 ql_awaken_task_daemon(ha, NULL, 0, 0); 529 } 530 531 if (isr_done_q.first != NULL) { 532 ql_done(isr_done_q.first); 533 } 534 535 if (rval == DDI_INTR_CLAIMED) { 536 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 537 ha->xioctl->TotalInterrupts++; 538 } else { 539 /*EMPTY*/ 540 QL_PRINT_3(CE_CONT, "(%d): interrupt not claimed\n", 541 ha->instance); 542 } 543 544 QL_PM_LOCK(ha); 545 ha->busy--; 546 QL_PM_UNLOCK(ha); 547 548 return (rval); 549 } 550 551 /* 552 * ql_handle_uncommon_risc_intr 553 * Handle an uncommon RISC interrupt. 554 * 555 * Input: 556 * ha: adapter state pointer. 557 * stat: interrupt status 558 * 559 * Context: 560 * Interrupt or Kernel context, no mailbox commands allowed. 561 */ 562 static void 563 ql_handle_uncommon_risc_intr(ql_adapter_state_t *ha, uint32_t stat, 564 uint32_t *set_flags) 565 { 566 uint16_t hccr_reg; 567 568 hccr_reg = RD16_IO_REG(ha, hccr); 569 570 if (stat & RH_RISC_PAUSED || 571 (hccr_reg & (BIT_15 | BIT_13 | BIT_11 | BIT_8))) { 572 573 ADAPTER_STATE_LOCK(ha); 574 ha->flags |= PARITY_ERROR; 575 ADAPTER_STATE_UNLOCK(ha); 576 577 if (ha->parity_pause_errors == 0 || 578 ha->parity_hccr_err != hccr_reg || 579 ha->parity_stat_err != stat) { 580 cmn_err(CE_WARN, "qlc(%d): isr, Internal Parity/" 581 "Pause Error - hccr=%xh, stat=%xh, count=%d", 582 ha->instance, hccr_reg, stat, 583 ha->parity_pause_errors); 584 ha->parity_hccr_err = hccr_reg; 585 ha->parity_stat_err = stat; 586 } 587 588 EL(ha, "parity/pause error, isp_abort_needed\n"); 589 590 if (ql_binary_fw_dump(ha, FALSE) != QL_SUCCESS) { 591 ql_reset_chip(ha); 592 } 593 594 if (ha->parity_pause_errors == 0) { 595 ha->log_parity_pause = B_TRUE; 596 } 597 598 if (ha->parity_pause_errors < 0xffffffff) { 599 ha->parity_pause_errors++; 600 } 601 602 *set_flags |= ISP_ABORT_NEEDED; 603 604 /* Disable ISP interrupts. */ 605 CFG_IST(ha, CFG_CTRL_8021) ? ql_8021_disable_intrs(ha) : 606 WRT16_IO_REG(ha, ictrl, 0); 607 ADAPTER_STATE_LOCK(ha); 608 ha->flags &= ~INTERRUPTS_ENABLED; 609 ADAPTER_STATE_UNLOCK(ha); 610 } else { 611 EL(ha, "UNKNOWN interrupt status=%xh, hccr=%xh\n", 612 stat, hccr_reg); 613 } 614 } 615 616 /* 617 * ql_spurious_intr 618 * Inform Solaris of spurious interrupts. 619 * 620 * Input: 621 * ha: adapter state pointer. 622 * intr_clr: early interrupt clear 623 * 624 * Context: 625 * Interrupt or Kernel context, no mailbox commands allowed. 626 */ 627 static void 628 ql_spurious_intr(ql_adapter_state_t *ha, int intr_clr) 629 { 630 ddi_devstate_t state; 631 632 EL(ha, "Spurious interrupt\n"); 633 634 /* Disable ISP interrupts. */ 635 WRT16_IO_REG(ha, ictrl, 0); 636 ADAPTER_STATE_LOCK(ha); 637 ha->flags &= ~INTERRUPTS_ENABLED; 638 ADAPTER_STATE_UNLOCK(ha); 639 640 /* Clear RISC interrupt */ 641 if (intr_clr) { 642 if (CFG_IST(ha, CFG_CTRL_8021)) { 643 ql_8021_clr_fw_intr(ha); 644 } else if (CFG_IST(ha, CFG_CTRL_242581)) { 645 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT); 646 } else { 647 WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT); 648 } 649 } 650 651 state = ddi_get_devstate(ha->dip); 652 if (state == DDI_DEVSTATE_UP) { 653 /*EMPTY*/ 654 ddi_dev_report_fault(ha->dip, DDI_SERVICE_DEGRADED, 655 DDI_DEVICE_FAULT, "spurious interrupts"); 656 } 657 } 658 659 /* 660 * ql_mbx_completion 661 * Processes mailbox completions. 662 * 663 * Input: 664 * ha: adapter state pointer. 665 * mb0: Mailbox 0 contents. 666 * set_flags: task daemon flags to set. 667 * reset_flags: task daemon flags to reset. 668 * intr_clr: early interrupt clear 669 * 670 * Context: 671 * Interrupt context. 672 */ 673 /* ARGSUSED */ 674 static void 675 ql_mbx_completion(ql_adapter_state_t *ha, uint16_t mb0, uint32_t *set_flags, 676 uint32_t *reset_flags, int intr_clr) 677 { 678 uint32_t index; 679 uint16_t cnt; 680 681 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 682 683 /* Load return mailbox registers. */ 684 MBX_REGISTER_LOCK(ha); 685 686 if (ha->mcp != NULL) { 687 ha->mcp->mb[0] = mb0; 688 index = ha->mcp->in_mb & ~MBX_0; 689 690 for (cnt = 1; cnt < MAX_MBOX_COUNT && index != 0; cnt++) { 691 index >>= 1; 692 if (index & MBX_0) { 693 ha->mcp->mb[cnt] = RD16_IO_REG(ha, 694 mailbox_out[cnt]); 695 } 696 } 697 698 } else { 699 EL(ha, "mcp == NULL\n"); 700 } 701 702 if (intr_clr) { 703 /* Clear RISC interrupt. */ 704 if (CFG_IST(ha, CFG_CTRL_8021)) { 705 ql_8021_clr_fw_intr(ha); 706 } else if (CFG_IST(ha, CFG_CTRL_242581)) { 707 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT); 708 } else { 709 WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT); 710 } 711 } 712 713 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_INTERRUPT); 714 if (ha->flags & INTERRUPTS_ENABLED) { 715 cv_broadcast(&ha->cv_mbx_intr); 716 } 717 718 MBX_REGISTER_UNLOCK(ha); 719 720 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 721 } 722 723 /* 724 * ql_async_event 725 * Processes asynchronous events. 726 * 727 * Input: 728 * ha: adapter state pointer. 729 * mbx: Mailbox 0 register. 730 * done_q: head pointer to done queue. 731 * set_flags: task daemon flags to set. 732 * reset_flags: task daemon flags to reset. 733 * intr_clr: early interrupt clear 734 * 735 * Context: 736 * Interrupt or Kernel context, no mailbox commands allowed. 737 */ 738 static void 739 ql_async_event(ql_adapter_state_t *ha, uint32_t mbx, ql_head_t *done_q, 740 uint32_t *set_flags, uint32_t *reset_flags, int intr_clr) 741 { 742 uint32_t handle; 743 uint32_t index; 744 uint16_t cnt; 745 uint16_t mb[MAX_MBOX_COUNT]; 746 ql_srb_t *sp; 747 port_id_t s_id; 748 ql_tgt_t *tq; 749 boolean_t intr = B_TRUE; 750 ql_adapter_state_t *vha; 751 752 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 753 754 /* Setup to process fast completion. */ 755 mb[0] = LSW(mbx); 756 switch (mb[0]) { 757 case MBA_SCSI_COMPLETION: 758 handle = SHORT_TO_LONG(RD16_IO_REG(ha, mailbox_out[1]), 759 RD16_IO_REG(ha, mailbox_out[2])); 760 break; 761 762 case MBA_CMPLT_1_16BIT: 763 handle = MSW(mbx); 764 mb[0] = MBA_SCSI_COMPLETION; 765 break; 766 767 case MBA_CMPLT_1_32BIT: 768 handle = SHORT_TO_LONG(MSW(mbx), 769 RD16_IO_REG(ha, mailbox_out[2])); 770 mb[0] = MBA_SCSI_COMPLETION; 771 break; 772 773 case MBA_CTIO_COMPLETION: 774 case MBA_IP_COMPLETION: 775 handle = CFG_IST(ha, CFG_CTRL_2200) ? SHORT_TO_LONG( 776 RD16_IO_REG(ha, mailbox_out[1]), 777 RD16_IO_REG(ha, mailbox_out[2])) : 778 SHORT_TO_LONG(MSW(mbx), RD16_IO_REG(ha, mailbox_out[2])); 779 mb[0] = MBA_SCSI_COMPLETION; 780 break; 781 782 default: 783 break; 784 } 785 786 /* Handle asynchronous event */ 787 switch (mb[0]) { 788 case MBA_SCSI_COMPLETION: 789 QL_PRINT_5(CE_CONT, "(%d): Fast post completion\n", 790 ha->instance); 791 792 if (intr_clr) { 793 /* Clear RISC interrupt */ 794 if (CFG_IST(ha, CFG_CTRL_8021)) { 795 ql_8021_clr_fw_intr(ha); 796 } else if (CFG_IST(ha, CFG_CTRL_242581)) { 797 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT); 798 } else { 799 WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT); 800 } 801 intr = B_FALSE; 802 } 803 804 if ((ha->flags & ONLINE) == 0) { 805 break; 806 } 807 808 /* Get handle. */ 809 index = handle & OSC_INDEX_MASK; 810 811 /* Validate handle. */ 812 sp = index < MAX_OUTSTANDING_COMMANDS ? 813 ha->outstanding_cmds[index] : NULL; 814 815 if (sp != NULL && sp->handle == handle) { 816 ha->outstanding_cmds[index] = NULL; 817 sp->handle = 0; 818 sp->flags &= ~SRB_IN_TOKEN_ARRAY; 819 820 /* Set completed status. */ 821 sp->flags |= SRB_ISP_COMPLETED; 822 823 /* Set completion status */ 824 sp->pkt->pkt_reason = CS_COMPLETE; 825 826 if (!(sp->flags & SRB_FCP_CMD_PKT)) { 827 /* Place block on done queue */ 828 ql_add_link_b(done_q, &sp->cmd); 829 } else { 830 ql_fast_fcp_post(sp); 831 } 832 } else if (handle != QL_FCA_BRAND) { 833 if (sp == NULL) { 834 EL(ha, "%xh unknown IOCB handle=%xh\n", 835 mb[0], handle); 836 } else { 837 EL(ha, "%xh mismatch IOCB handle pkt=%xh, " 838 "sp=%xh\n", mb[0], handle, sp->handle); 839 } 840 841 EL(ha, "%xh Fast post, mbx1=%xh, mbx2=%xh, mbx3=%xh," 842 "mbx6=%xh, mbx7=%xh\n", mb[0], 843 RD16_IO_REG(ha, mailbox_out[1]), 844 RD16_IO_REG(ha, mailbox_out[2]), 845 RD16_IO_REG(ha, mailbox_out[3]), 846 RD16_IO_REG(ha, mailbox_out[6]), 847 RD16_IO_REG(ha, mailbox_out[7])); 848 849 (void) ql_binary_fw_dump(ha, FALSE); 850 851 if (!(ha->task_daemon_flags & 852 (ISP_ABORT_NEEDED | ABORT_ISP_ACTIVE))) { 853 EL(ha, "%xh ISP Invalid handle, " 854 "isp_abort_needed\n", mb[0]); 855 *set_flags |= ISP_ABORT_NEEDED; 856 } 857 } 858 break; 859 860 case MBA_RESET: /* Reset */ 861 EL(ha, "%xh Reset received\n", mb[0]); 862 *set_flags |= RESET_MARKER_NEEDED; 863 break; 864 865 case MBA_SYSTEM_ERR: /* System Error */ 866 mb[1] = RD16_IO_REG(ha, mailbox_out[1]); 867 mb[2] = RD16_IO_REG(ha, mailbox_out[2]); 868 mb[3] = RD16_IO_REG(ha, mailbox_out[3]); 869 mb[7] = RD16_IO_REG(ha, mailbox_out[7]); 870 871 EL(ha, "%xh ISP System Error, isp_abort_needed\n mbx1=%xh, " 872 "mbx2=%xh, mbx3=%xh, mbx4=%xh, mbx5=%xh, mbx6=%xh,\n " 873 "mbx7=%xh, mbx8=%xh, mbx9=%xh, mbx10=%xh, mbx11=%xh, " 874 "mbx12=%xh,\n", mb[0], mb[1], mb[2], mb[3], 875 RD16_IO_REG(ha, mailbox_out[4]), 876 RD16_IO_REG(ha, mailbox_out[5]), 877 RD16_IO_REG(ha, mailbox_out[6]), mb[7], 878 RD16_IO_REG(ha, mailbox_out[8]), 879 RD16_IO_REG(ha, mailbox_out[9]), 880 RD16_IO_REG(ha, mailbox_out[10]), 881 RD16_IO_REG(ha, mailbox_out[11]), 882 RD16_IO_REG(ha, mailbox_out[12])); 883 884 EL(ha, "%xh ISP System Error, isp_abort_needed\n mbx13=%xh, " 885 "mbx14=%xh, mbx15=%xh, mbx16=%xh, mbx17=%xh, mbx18=%xh,\n" 886 "mbx19=%xh, mbx20=%xh, mbx21=%xh, mbx22=%xh, mbx23=%xh\n", 887 mb[0], RD16_IO_REG(ha, mailbox_out[13]), 888 RD16_IO_REG(ha, mailbox_out[14]), 889 RD16_IO_REG(ha, mailbox_out[15]), 890 RD16_IO_REG(ha, mailbox_out[16]), 891 RD16_IO_REG(ha, mailbox_out[17]), 892 RD16_IO_REG(ha, mailbox_out[18]), 893 RD16_IO_REG(ha, mailbox_out[19]), 894 RD16_IO_REG(ha, mailbox_out[20]), 895 RD16_IO_REG(ha, mailbox_out[21]), 896 RD16_IO_REG(ha, mailbox_out[22]), 897 RD16_IO_REG(ha, mailbox_out[23])); 898 899 if (ha->reg_off->mbox_cnt > 24) { 900 EL(ha, "%xh ISP System Error, mbx24=%xh, mbx25=%xh, " 901 "mbx26=%xh,\n mbx27=%xh, mbx28=%xh, mbx29=%xh, " 902 "mbx30=%xh, mbx31=%xh\n", mb[0], 903 RD16_IO_REG(ha, mailbox_out[24]), 904 RD16_IO_REG(ha, mailbox_out[25]), 905 RD16_IO_REG(ha, mailbox_out[26]), 906 RD16_IO_REG(ha, mailbox_out[27]), 907 RD16_IO_REG(ha, mailbox_out[28]), 908 RD16_IO_REG(ha, mailbox_out[29]), 909 RD16_IO_REG(ha, mailbox_out[30]), 910 RD16_IO_REG(ha, mailbox_out[31])); 911 } 912 913 (void) ql_binary_fw_dump(ha, FALSE); 914 915 (void) ql_flash_errlog(ha, FLASH_ERRLOG_AEN_8002, mb[1], 916 mb[2], mb[3]); 917 918 if (CFG_IST(ha, CFG_CTRL_81XX) && mb[7] & SE_MPI_RISC) { 919 ADAPTER_STATE_LOCK(ha); 920 ha->flags |= MPI_RESET_NEEDED; 921 ADAPTER_STATE_UNLOCK(ha); 922 } 923 924 *set_flags |= ISP_ABORT_NEEDED; 925 ha->xioctl->ControllerErrorCount++; 926 break; 927 928 case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */ 929 EL(ha, "%xh Request Transfer Error received, " 930 "isp_abort_needed\n", mb[0]); 931 932 (void) ql_flash_errlog(ha, FLASH_ERRLOG_AEN_8003, 933 RD16_IO_REG(ha, mailbox_out[1]), 934 RD16_IO_REG(ha, mailbox_out[2]), 935 RD16_IO_REG(ha, mailbox_out[3])); 936 937 *set_flags |= ISP_ABORT_NEEDED; 938 ha->xioctl->ControllerErrorCount++; 939 break; 940 941 case MBA_RSP_TRANSFER_ERR: /* Response Xfer Err */ 942 EL(ha, "%xh Response Transfer Error received," 943 " isp_abort_needed\n", mb[0]); 944 945 (void) ql_flash_errlog(ha, FLASH_ERRLOG_AEN_8004, 946 RD16_IO_REG(ha, mailbox_out[1]), 947 RD16_IO_REG(ha, mailbox_out[2]), 948 RD16_IO_REG(ha, mailbox_out[3])); 949 950 *set_flags |= ISP_ABORT_NEEDED; 951 ha->xioctl->ControllerErrorCount++; 952 break; 953 954 case MBA_WAKEUP_THRES: /* Request Queue Wake-up */ 955 EL(ha, "%xh Request Queue Wake-up received\n", 956 mb[0]); 957 break; 958 959 case MBA_MENLO_ALERT: /* Menlo Alert Notification */ 960 mb[1] = RD16_IO_REG(ha, mailbox_out[1]); 961 mb[2] = RD16_IO_REG(ha, mailbox_out[2]); 962 mb[3] = RD16_IO_REG(ha, mailbox_out[3]); 963 964 EL(ha, "%xh Menlo Alert Notification received, mbx1=%xh," 965 " mbx2=%xh, mbx3=%xh\n", mb[0], mb[1], mb[2], mb[3]); 966 967 switch (mb[1]) { 968 case MLA_LOGIN_OPERATIONAL_FW: 969 ADAPTER_STATE_LOCK(ha); 970 ha->flags |= MENLO_LOGIN_OPERATIONAL; 971 ADAPTER_STATE_UNLOCK(ha); 972 break; 973 case MLA_PANIC_RECOVERY: 974 case MLA_LOGIN_DIAGNOSTIC_FW: 975 case MLA_LOGIN_GOLDEN_FW: 976 case MLA_REJECT_RESPONSE: 977 default: 978 break; 979 } 980 break; 981 982 case MBA_LIP_F8: /* Received a LIP F8. */ 983 case MBA_LIP_RESET: /* LIP reset occurred. */ 984 case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */ 985 if (CFG_IST(ha, CFG_CTRL_8081)) { 986 EL(ha, "%xh DCBX_STARTED received, mbx1=%xh, mbx2=%xh" 987 "\n", mb[0], RD16_IO_REG(ha, mailbox_out[1]), 988 RD16_IO_REG(ha, mailbox_out[2])); 989 } else { 990 EL(ha, "%xh LIP received\n", mb[0]); 991 } 992 993 ADAPTER_STATE_LOCK(ha); 994 ha->flags &= ~POINT_TO_POINT; 995 ADAPTER_STATE_UNLOCK(ha); 996 997 if (!(ha->task_daemon_flags & LOOP_DOWN)) { 998 *set_flags |= LOOP_DOWN; 999 } 1000 ql_port_state(ha, FC_STATE_OFFLINE, 1001 FC_STATE_CHANGE | COMMAND_WAIT_NEEDED | LOOP_DOWN); 1002 1003 if (ha->loop_down_timer == LOOP_DOWN_TIMER_OFF) { 1004 ha->loop_down_timer = LOOP_DOWN_TIMER_START; 1005 } 1006 1007 ha->adapter_stats->lip_count++; 1008 1009 /* Update AEN queue. */ 1010 ha->xioctl->TotalLipResets++; 1011 if (ha->xioctl->flags & QL_AEN_TRACKING_ENABLE) { 1012 ql_enqueue_aen(ha, mb[0], NULL); 1013 } 1014 break; 1015 1016 case MBA_LOOP_UP: 1017 if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322 | 1018 CFG_CTRL_24258081))) { 1019 ha->iidma_rate = RD16_IO_REG(ha, mailbox_out[1]); 1020 if (ha->iidma_rate == IIDMA_RATE_1GB) { 1021 ha->state = FC_PORT_STATE_MASK( 1022 ha->state) | FC_STATE_1GBIT_SPEED; 1023 index = 1; 1024 } else if (ha->iidma_rate == IIDMA_RATE_2GB) { 1025 ha->state = FC_PORT_STATE_MASK( 1026 ha->state) | FC_STATE_2GBIT_SPEED; 1027 index = 2; 1028 } else if (ha->iidma_rate == IIDMA_RATE_4GB) { 1029 ha->state = FC_PORT_STATE_MASK( 1030 ha->state) | FC_STATE_4GBIT_SPEED; 1031 index = 4; 1032 } else if (ha->iidma_rate == IIDMA_RATE_8GB) { 1033 ha->state = FC_PORT_STATE_MASK( 1034 ha->state) | FC_STATE_8GBIT_SPEED; 1035 index = 8; 1036 } else if (ha->iidma_rate == IIDMA_RATE_10GB) { 1037 ha->state = FC_PORT_STATE_MASK( 1038 ha->state) | FC_STATE_10GBIT_SPEED; 1039 index = 10; 1040 } else { 1041 ha->state = FC_PORT_STATE_MASK( 1042 ha->state); 1043 index = 0; 1044 } 1045 } else { 1046 ha->iidma_rate = IIDMA_RATE_1GB; 1047 ha->state = FC_PORT_STATE_MASK(ha->state) | 1048 FC_STATE_FULL_SPEED; 1049 index = 1; 1050 } 1051 1052 for (vha = ha; vha != NULL; vha = vha->vp_next) { 1053 vha->state = FC_PORT_STATE_MASK(vha->state) | 1054 FC_PORT_SPEED_MASK(ha->state); 1055 } 1056 EL(ha, "%d GB %xh Loop Up received\n", index, mb[0]); 1057 1058 /* Update AEN queue. */ 1059 if (ha->xioctl->flags & QL_AEN_TRACKING_ENABLE) { 1060 ql_enqueue_aen(ha, mb[0], NULL); 1061 } 1062 break; 1063 1064 case MBA_LOOP_DOWN: 1065 EL(ha, "%xh Loop Down received, mbx1=%xh, mbx2=%xh, mbx3=%xh, " 1066 "mbx4=%xh\n", mb[0], RD16_IO_REG(ha, mailbox_out[1]), 1067 RD16_IO_REG(ha, mailbox_out[2]), 1068 RD16_IO_REG(ha, mailbox_out[3]), 1069 RD16_IO_REG(ha, mailbox_out[4])); 1070 1071 if (!(ha->task_daemon_flags & LOOP_DOWN)) { 1072 *set_flags |= LOOP_DOWN; 1073 } 1074 ql_port_state(ha, FC_STATE_OFFLINE, 1075 FC_STATE_CHANGE | COMMAND_WAIT_NEEDED | LOOP_DOWN); 1076 1077 if (ha->loop_down_timer == LOOP_DOWN_TIMER_OFF) { 1078 ha->loop_down_timer = LOOP_DOWN_TIMER_START; 1079 } 1080 1081 if (CFG_IST(ha, CFG_CTRL_258081)) { 1082 ha->sfp_stat = RD16_IO_REG(ha, mailbox_out[2]); 1083 } 1084 1085 /* Update AEN queue. */ 1086 if (ha->xioctl->flags & QL_AEN_TRACKING_ENABLE) { 1087 ql_enqueue_aen(ha, mb[0], NULL); 1088 } 1089 break; 1090 1091 case MBA_PORT_UPDATE: 1092 mb[1] = RD16_IO_REG(ha, mailbox_out[1]); 1093 mb[2] = RD16_IO_REG(ha, mailbox_out[2]); 1094 mb[3] = (uint16_t)(ha->flags & VP_ENABLED ? 1095 RD16_IO_REG(ha, mailbox_out[3]) : 0); 1096 1097 /* Locate port state structure. */ 1098 for (vha = ha; vha != NULL; vha = vha->vp_next) { 1099 if (vha->vp_index == LSB(mb[3])) { 1100 break; 1101 } 1102 } 1103 if (vha == NULL) { 1104 break; 1105 } 1106 1107 if (CFG_IST(ha, CFG_CTRL_8081) && mb[1] == 0xffff && 1108 mb[2] == 7 && (MSB(mb[3]) == 0xe || MSB(mb[3]) == 0x1a || 1109 MSB(mb[3]) == 0x1c || MSB(mb[3]) == 0x1d || 1110 MSB(mb[3]) == 0x1e)) { 1111 /* 1112 * received FLOGI reject 1113 * received FLOGO 1114 * FCF configuration changed 1115 * FIP Clear Virtual Link received 1116 * FKA timeout 1117 */ 1118 if (!(ha->task_daemon_flags & LOOP_DOWN)) { 1119 *set_flags |= LOOP_DOWN; 1120 } 1121 ql_port_state(ha, FC_STATE_OFFLINE, FC_STATE_CHANGE | 1122 COMMAND_WAIT_NEEDED | LOOP_DOWN); 1123 if (ha->loop_down_timer == LOOP_DOWN_TIMER_OFF) { 1124 ha->loop_down_timer = LOOP_DOWN_TIMER_START; 1125 } 1126 /* 1127 * In N port 2 N port topology the FW provides a port 1128 * database entry at loop_id 0x7fe which we use to 1129 * acquire the Ports WWPN. 1130 */ 1131 } else if ((mb[1] != 0x7fe) && 1132 ((FC_PORT_STATE_MASK(vha->state) != FC_STATE_OFFLINE || 1133 (CFG_IST(ha, CFG_CTRL_24258081) && 1134 (mb[1] != 0xffff || mb[2] != 6 || mb[3] != 0))))) { 1135 EL(ha, "%xh Port Database Update, Login/Logout " 1136 "received, mbx1=%xh, mbx2=%xh, mbx3=%xh\n", 1137 mb[0], mb[1], mb[2], mb[3]); 1138 } else { 1139 EL(ha, "%xh Port Database Update received, mbx1=%xh," 1140 " mbx2=%xh, mbx3=%xh\n", mb[0], mb[1], mb[2], 1141 mb[3]); 1142 *set_flags |= LOOP_RESYNC_NEEDED; 1143 *set_flags &= ~LOOP_DOWN; 1144 *reset_flags |= LOOP_DOWN; 1145 *reset_flags &= ~LOOP_RESYNC_NEEDED; 1146 vha->loop_down_timer = LOOP_DOWN_TIMER_OFF; 1147 TASK_DAEMON_LOCK(ha); 1148 vha->task_daemon_flags |= LOOP_RESYNC_NEEDED; 1149 vha->task_daemon_flags &= ~LOOP_DOWN; 1150 TASK_DAEMON_UNLOCK(ha); 1151 ADAPTER_STATE_LOCK(ha); 1152 vha->flags &= ~ABORT_CMDS_LOOP_DOWN_TMO; 1153 ADAPTER_STATE_UNLOCK(ha); 1154 } 1155 1156 /* Update AEN queue. */ 1157 if (ha->xioctl->flags & QL_AEN_TRACKING_ENABLE) { 1158 ql_enqueue_aen(ha, mb[0], NULL); 1159 } 1160 break; 1161 1162 case MBA_RSCN_UPDATE: 1163 mb[1] = RD16_IO_REG(ha, mailbox_out[1]); 1164 mb[2] = RD16_IO_REG(ha, mailbox_out[2]); 1165 mb[3] = (uint16_t)(ha->flags & VP_ENABLED ? 1166 RD16_IO_REG(ha, mailbox_out[3]) : 0); 1167 1168 /* Locate port state structure. */ 1169 for (vha = ha; vha != NULL; vha = vha->vp_next) { 1170 if (vha->vp_index == LSB(mb[3])) { 1171 break; 1172 } 1173 } 1174 1175 if (vha == NULL) { 1176 break; 1177 } 1178 1179 if (LSB(mb[1]) == vha->d_id.b.domain && 1180 MSB(mb[2]) == vha->d_id.b.area && 1181 LSB(mb[2]) == vha->d_id.b.al_pa) { 1182 EL(ha, "%xh RSCN match adapter, mbx1=%xh, mbx2=%xh, " 1183 "mbx3=%xh\n", mb[0], mb[1], mb[2], mb[3]); 1184 } else { 1185 EL(ha, "%xh RSCN received, mbx1=%xh, mbx2=%xh, " 1186 "mbx3=%xh\n", mb[0], mb[1], mb[2], mb[3]); 1187 if (FC_PORT_STATE_MASK(vha->state) != 1188 FC_STATE_OFFLINE) { 1189 ql_rcv_rscn_els(vha, &mb[0], done_q); 1190 TASK_DAEMON_LOCK(ha); 1191 vha->task_daemon_flags |= RSCN_UPDATE_NEEDED; 1192 TASK_DAEMON_UNLOCK(ha); 1193 *set_flags |= RSCN_UPDATE_NEEDED; 1194 } 1195 } 1196 1197 /* Update AEN queue. */ 1198 if (ha->xioctl->flags & QL_AEN_TRACKING_ENABLE) { 1199 ql_enqueue_aen(ha, mb[0], NULL); 1200 } 1201 break; 1202 1203 case MBA_LIP_ERROR: /* Loop initialization errors. */ 1204 EL(ha, "%xh LIP error received, mbx1=%xh\n", mb[0], 1205 RD16_IO_REG(ha, mailbox_out[1])); 1206 break; 1207 1208 case MBA_IP_RECEIVE: 1209 case MBA_IP_BROADCAST: 1210 mb[1] = RD16_IO_REG(ha, mailbox_out[1]); 1211 mb[2] = RD16_IO_REG(ha, mailbox_out[2]); 1212 mb[3] = RD16_IO_REG(ha, mailbox_out[3]); 1213 1214 EL(ha, "%xh IP packet/broadcast received, mbx1=%xh, " 1215 "mbx2=%xh, mbx3=%xh\n", mb[0], mb[1], mb[2], mb[3]); 1216 1217 /* Locate device queue. */ 1218 s_id.b.al_pa = LSB(mb[2]); 1219 s_id.b.area = MSB(mb[2]); 1220 s_id.b.domain = LSB(mb[1]); 1221 if ((tq = ql_d_id_to_queue(ha, s_id)) == NULL) { 1222 EL(ha, "Unknown IP device=%xh\n", s_id.b24); 1223 break; 1224 } 1225 1226 cnt = (uint16_t)(CFG_IST(ha, CFG_CTRL_24258081) ? 1227 CHAR_TO_SHORT(ha->ip_init_ctrl_blk.cb24.buf_size[0], 1228 ha->ip_init_ctrl_blk.cb24.buf_size[1]) : 1229 CHAR_TO_SHORT(ha->ip_init_ctrl_blk.cb.buf_size[0], 1230 ha->ip_init_ctrl_blk.cb.buf_size[1])); 1231 1232 tq->ub_sequence_length = mb[3]; 1233 tq->ub_total_seg_cnt = (uint8_t)(mb[3] / cnt); 1234 if (mb[3] % cnt) { 1235 tq->ub_total_seg_cnt++; 1236 } 1237 cnt = (uint16_t)(tq->ub_total_seg_cnt + 10); 1238 1239 for (index = 10; index < ha->reg_off->mbox_cnt && index < cnt; 1240 index++) { 1241 mb[index] = RD16_IO_REG(ha, mailbox_out[index]); 1242 } 1243 1244 tq->ub_seq_id = ++ha->ub_seq_id; 1245 tq->ub_seq_cnt = 0; 1246 tq->ub_frame_ro = 0; 1247 tq->ub_loop_id = (uint16_t)(mb[0] == MBA_IP_BROADCAST ? 1248 (CFG_IST(ha, CFG_CTRL_24258081) ? BROADCAST_24XX_HDL : 1249 IP_BROADCAST_LOOP_ID) : tq->loop_id); 1250 ha->rcv_dev_q = tq; 1251 1252 for (cnt = 10; cnt < ha->reg_off->mbox_cnt && 1253 tq->ub_seq_cnt < tq->ub_total_seg_cnt; cnt++) { 1254 if (ql_ub_frame_hdr(ha, tq, mb[cnt], done_q) != 1255 QL_SUCCESS) { 1256 EL(ha, "ql_ub_frame_hdr failed, " 1257 "isp_abort_needed\n"); 1258 *set_flags |= ISP_ABORT_NEEDED; 1259 break; 1260 } 1261 } 1262 break; 1263 1264 case MBA_IP_LOW_WATER_MARK: 1265 case MBA_IP_RCV_BUFFER_EMPTY: 1266 EL(ha, "%xh IP low water mark / RCV buffer empty received\n", 1267 mb[0]); 1268 *set_flags |= NEED_UNSOLICITED_BUFFERS; 1269 break; 1270 1271 case MBA_IP_HDR_DATA_SPLIT: 1272 EL(ha, "%xh IP HDR data split received\n", mb[0]); 1273 break; 1274 1275 case MBA_ERROR_LOGGING_DISABLED: 1276 EL(ha, "%xh error logging disabled received, " 1277 "mbx1=%xh\n", mb[0], RD16_IO_REG(ha, mailbox_out[1])); 1278 break; 1279 1280 case MBA_POINT_TO_POINT: 1281 /* case MBA_DCBX_COMPLETED: */ 1282 if (CFG_IST(ha, CFG_CTRL_8081)) { 1283 EL(ha, "%xh DCBX completed received\n", mb[0]); 1284 } else { 1285 EL(ha, "%xh Point to Point Mode received\n", mb[0]); 1286 } 1287 ADAPTER_STATE_LOCK(ha); 1288 ha->flags |= POINT_TO_POINT; 1289 ADAPTER_STATE_UNLOCK(ha); 1290 break; 1291 1292 case MBA_FCF_CONFIG_ERROR: 1293 EL(ha, "%xh FCF configuration Error received, mbx1=%xh\n", 1294 mb[0], RD16_IO_REG(ha, mailbox_out[1])); 1295 break; 1296 1297 case MBA_DCBX_PARAM_CHANGED: 1298 EL(ha, "%xh DCBX parameters changed received, mbx1=%xh\n", 1299 mb[0], RD16_IO_REG(ha, mailbox_out[1])); 1300 break; 1301 1302 case MBA_CHG_IN_CONNECTION: 1303 mb[1] = RD16_IO_REG(ha, mailbox_out[1]); 1304 if (mb[1] == 2) { 1305 EL(ha, "%xh Change In Connection received, " 1306 "mbx1=%xh\n", mb[0], mb[1]); 1307 ADAPTER_STATE_LOCK(ha); 1308 ha->flags &= ~POINT_TO_POINT; 1309 ADAPTER_STATE_UNLOCK(ha); 1310 if (ha->topology & QL_N_PORT) { 1311 ha->topology = (uint8_t)(ha->topology & 1312 ~QL_N_PORT); 1313 ha->topology = (uint8_t)(ha->topology | 1314 QL_NL_PORT); 1315 } 1316 } else { 1317 EL(ha, "%xh Change In Connection received, " 1318 "mbx1=%xh, isp_abort_needed\n", mb[0], mb[1]); 1319 *set_flags |= ISP_ABORT_NEEDED; 1320 } 1321 break; 1322 1323 case MBA_ZIO_UPDATE: 1324 EL(ha, "%xh ZIO response received\n", mb[0]); 1325 1326 ha->isp_rsp_index = RD16_IO_REG(ha, resp_in); 1327 ql_response_pkt(ha, done_q, set_flags, reset_flags, intr_clr); 1328 intr = B_FALSE; 1329 break; 1330 1331 case MBA_PORT_BYPASS_CHANGED: 1332 EL(ha, "%xh Port Bypass Changed received, mbx1=%xh\n", 1333 mb[0], RD16_IO_REG(ha, mailbox_out[1])); 1334 /* 1335 * Event generated when there is a transition on 1336 * port bypass of crystal+. 1337 * Mailbox 1: Bit 0 - External. 1338 * Bit 2 - Internal. 1339 * When the bit is 0, the port is bypassed. 1340 * 1341 * For now we will generate a LIP for all cases. 1342 */ 1343 *set_flags |= HANDLE_PORT_BYPASS_CHANGE; 1344 break; 1345 1346 case MBA_RECEIVE_ERROR: 1347 EL(ha, "%xh Receive Error received, mbx1=%xh, mbx2=%xh\n", 1348 mb[0], RD16_IO_REG(ha, mailbox_out[1]), 1349 RD16_IO_REG(ha, mailbox_out[2])); 1350 break; 1351 1352 case MBA_LS_RJT_SENT: 1353 EL(ha, "%xh LS_RJT Response Sent ELS=%xh\n", mb[0], 1354 RD16_IO_REG(ha, mailbox_out[1])); 1355 break; 1356 1357 case MBA_FW_RESTART_COMP: 1358 EL(ha, "%xh firmware restart complete received mb1=%xh\n", 1359 mb[0], RD16_IO_REG(ha, mailbox_out[1])); 1360 break; 1361 1362 /* 1363 * MBA_IDC_COMPLETE & MBA_IDC_NOTIFICATION: We won't get another 1364 * IDC async event until we ACK the current one. 1365 */ 1366 case MBA_IDC_COMPLETE: 1367 ha->idc_mb[0] = mb[0]; 1368 ha->idc_mb[1] = RD16_IO_REG(ha, mailbox_out[1]); 1369 ha->idc_mb[2] = RD16_IO_REG(ha, mailbox_out[2]); 1370 ha->idc_mb[3] = RD16_IO_REG(ha, mailbox_out[3]); 1371 ha->idc_mb[4] = RD16_IO_REG(ha, mailbox_out[4]); 1372 ha->idc_mb[5] = RD16_IO_REG(ha, mailbox_out[5]); 1373 ha->idc_mb[6] = RD16_IO_REG(ha, mailbox_out[6]); 1374 ha->idc_mb[7] = RD16_IO_REG(ha, mailbox_out[7]); 1375 EL(ha, "%xh Inter-driver communication complete received, " 1376 " mbx1=%xh, mbx2=%xh, mbx3=%xh, mbx4=%xh, mbx5=%xh," 1377 " mbx6=%xh, mbx7=%xh\n", mb[0], ha->idc_mb[1], 1378 ha->idc_mb[2], ha->idc_mb[3], ha->idc_mb[4], ha->idc_mb[5], 1379 ha->idc_mb[6], ha->idc_mb[7]); 1380 *set_flags |= IDC_EVENT; 1381 break; 1382 1383 case MBA_IDC_NOTIFICATION: 1384 ha->idc_mb[0] = mb[0]; 1385 ha->idc_mb[1] = RD16_IO_REG(ha, mailbox_out[1]); 1386 ha->idc_mb[2] = RD16_IO_REG(ha, mailbox_out[2]); 1387 ha->idc_mb[3] = RD16_IO_REG(ha, mailbox_out[3]); 1388 ha->idc_mb[4] = RD16_IO_REG(ha, mailbox_out[4]); 1389 ha->idc_mb[5] = RD16_IO_REG(ha, mailbox_out[5]); 1390 ha->idc_mb[6] = RD16_IO_REG(ha, mailbox_out[6]); 1391 ha->idc_mb[7] = RD16_IO_REG(ha, mailbox_out[7]); 1392 EL(ha, "%xh Inter-driver communication request notification " 1393 "received, mbx1=%xh, mbx2=%xh, mbx3=%xh, mbx4=%xh, " 1394 "mbx5=%xh, mbx6=%xh, mbx7=%xh\n", mb[0], ha->idc_mb[1], 1395 ha->idc_mb[2], ha->idc_mb[3], ha->idc_mb[4], ha->idc_mb[5], 1396 ha->idc_mb[6], ha->idc_mb[7]); 1397 *set_flags |= IDC_EVENT; 1398 break; 1399 1400 case MBA_IDC_TIME_EXTENDED: 1401 EL(ha, "%xh Inter-driver communication time extended received," 1402 " mbx1=%xh, mbx2=%xh\n", mb[0], 1403 RD16_IO_REG(ha, mailbox_out[1]), 1404 RD16_IO_REG(ha, mailbox_out[2])); 1405 break; 1406 1407 default: 1408 EL(ha, "%xh UNKNOWN event received, mbx1=%xh, mbx2=%xh, " 1409 "mbx3=%xh\n", mb[0], RD16_IO_REG(ha, mailbox_out[1]), 1410 RD16_IO_REG(ha, mailbox_out[2]), 1411 RD16_IO_REG(ha, mailbox_out[3])); 1412 break; 1413 } 1414 1415 /* Clear RISC interrupt */ 1416 if (intr && intr_clr) { 1417 if (CFG_IST(ha, CFG_CTRL_8021)) { 1418 ql_8021_clr_fw_intr(ha); 1419 } else if (CFG_IST(ha, CFG_CTRL_242581)) { 1420 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT); 1421 } else { 1422 WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT); 1423 } 1424 } 1425 1426 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1427 } 1428 1429 /* 1430 * ql_fast_fcp_post 1431 * Fast path for good SCSI I/O completion. 1432 * 1433 * Input: 1434 * sp: SRB pointer. 1435 * 1436 * Context: 1437 * Interrupt or Kernel context, no mailbox commands allowed. 1438 */ 1439 static void 1440 ql_fast_fcp_post(ql_srb_t *sp) 1441 { 1442 ql_adapter_state_t *ha = sp->ha; 1443 ql_lun_t *lq = sp->lun_queue; 1444 ql_tgt_t *tq = lq->target_queue; 1445 1446 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1447 1448 /* Acquire device queue lock. */ 1449 DEVICE_QUEUE_LOCK(tq); 1450 1451 /* Decrement outstanding commands on device. */ 1452 if (tq->outcnt != 0) { 1453 tq->outcnt--; 1454 } 1455 1456 if (sp->flags & SRB_FCP_CMD_PKT) { 1457 if (sp->fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_UNTAGGED) { 1458 /* 1459 * Clear the flag for this LUN so that 1460 * untagged commands can be submitted 1461 * for it. 1462 */ 1463 lq->flags &= ~LQF_UNTAGGED_PENDING; 1464 } 1465 1466 if (lq->lun_outcnt != 0) { 1467 lq->lun_outcnt--; 1468 } 1469 } 1470 1471 /* Reset port down retry count on good completion. */ 1472 tq->port_down_retry_count = ha->port_down_retry_count; 1473 tq->qfull_retry_count = ha->qfull_retry_count; 1474 ha->pha->timeout_cnt = 0; 1475 1476 /* Remove command from watchdog queue. */ 1477 if (sp->flags & SRB_WATCHDOG_ENABLED) { 1478 ql_remove_link(&tq->wdg, &sp->wdg); 1479 sp->flags &= ~SRB_WATCHDOG_ENABLED; 1480 } 1481 1482 if (lq->cmd.first != NULL) { 1483 ql_next(ha, lq); 1484 } else { 1485 /* Release LU queue specific lock. */ 1486 DEVICE_QUEUE_UNLOCK(tq); 1487 if (ha->pha->pending_cmds.first != NULL) { 1488 ql_start_iocb(ha, NULL); 1489 } 1490 } 1491 1492 /* Sync buffers if required. */ 1493 if (sp->flags & SRB_MS_PKT) { 1494 (void) ddi_dma_sync(sp->pkt->pkt_resp_dma, 0, 0, 1495 DDI_DMA_SYNC_FORCPU); 1496 } 1497 1498 /* Map ISP completion codes. */ 1499 sp->pkt->pkt_expln = FC_EXPLN_NONE; 1500 sp->pkt->pkt_action = FC_ACTION_RETRYABLE; 1501 sp->pkt->pkt_state = FC_PKT_SUCCESS; 1502 1503 /* Now call the pkt completion callback */ 1504 if (sp->flags & SRB_POLL) { 1505 sp->flags &= ~SRB_POLL; 1506 } else if (sp->pkt->pkt_comp) { 1507 INTR_UNLOCK(ha); 1508 (*sp->pkt->pkt_comp)(sp->pkt); 1509 INTR_LOCK(ha); 1510 } 1511 1512 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1513 } 1514 1515 /* 1516 * ql_response_pkt 1517 * Processes response entry. 1518 * 1519 * Input: 1520 * ha: adapter state pointer. 1521 * done_q: head pointer to done queue. 1522 * set_flags: task daemon flags to set. 1523 * reset_flags: task daemon flags to reset. 1524 * intr_clr: early interrupt clear 1525 * 1526 * Context: 1527 * Interrupt or Kernel context, no mailbox commands allowed. 1528 */ 1529 static void 1530 ql_response_pkt(ql_adapter_state_t *ha, ql_head_t *done_q, uint32_t *set_flags, 1531 uint32_t *reset_flags, int intr_clr) 1532 { 1533 response_t *pkt; 1534 uint32_t dma_sync_size_1 = 0; 1535 uint32_t dma_sync_size_2 = 0; 1536 int status = 0; 1537 1538 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1539 1540 /* Clear RISC interrupt */ 1541 if (intr_clr) { 1542 if (CFG_IST(ha, CFG_CTRL_8021)) { 1543 ql_8021_clr_fw_intr(ha); 1544 } else if (CFG_IST(ha, CFG_CTRL_242581)) { 1545 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT); 1546 } else { 1547 WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT); 1548 } 1549 } 1550 1551 if (ha->isp_rsp_index >= RESPONSE_ENTRY_CNT) { 1552 EL(ha, "index error = %xh, isp_abort_needed", 1553 ha->isp_rsp_index); 1554 *set_flags |= ISP_ABORT_NEEDED; 1555 return; 1556 } 1557 1558 if ((ha->flags & ONLINE) == 0) { 1559 QL_PRINT_3(CE_CONT, "(%d): not onlne, done\n", ha->instance); 1560 return; 1561 } 1562 1563 /* Calculate size of response queue entries to sync. */ 1564 if (ha->isp_rsp_index > ha->rsp_ring_index) { 1565 dma_sync_size_1 = (uint32_t) 1566 ((uint32_t)(ha->isp_rsp_index - ha->rsp_ring_index) * 1567 RESPONSE_ENTRY_SIZE); 1568 } else if (ha->isp_rsp_index == 0) { 1569 dma_sync_size_1 = (uint32_t) 1570 ((uint32_t)(RESPONSE_ENTRY_CNT - ha->rsp_ring_index) * 1571 RESPONSE_ENTRY_SIZE); 1572 } else { 1573 /* Responses wrap around the Q */ 1574 dma_sync_size_1 = (uint32_t) 1575 ((uint32_t)(RESPONSE_ENTRY_CNT - ha->rsp_ring_index) * 1576 RESPONSE_ENTRY_SIZE); 1577 dma_sync_size_2 = (uint32_t) 1578 (ha->isp_rsp_index * RESPONSE_ENTRY_SIZE); 1579 } 1580 1581 /* Sync DMA buffer. */ 1582 (void) ddi_dma_sync(ha->hba_buf.dma_handle, 1583 (off_t)(ha->rsp_ring_index * RESPONSE_ENTRY_SIZE + 1584 RESPONSE_Q_BUFFER_OFFSET), dma_sync_size_1, 1585 DDI_DMA_SYNC_FORKERNEL); 1586 if (dma_sync_size_2) { 1587 (void) ddi_dma_sync(ha->hba_buf.dma_handle, 1588 RESPONSE_Q_BUFFER_OFFSET, dma_sync_size_2, 1589 DDI_DMA_SYNC_FORKERNEL); 1590 } 1591 1592 while (ha->rsp_ring_index != ha->isp_rsp_index) { 1593 pkt = ha->response_ring_ptr; 1594 1595 QL_PRINT_5(CE_CONT, "(%d): ha->rsp_rg_idx=%xh, mbx[5]=%xh\n", 1596 ha->instance, ha->rsp_ring_index, ha->isp_rsp_index); 1597 QL_DUMP_5((uint8_t *)ha->response_ring_ptr, 8, 1598 RESPONSE_ENTRY_SIZE); 1599 1600 /* Adjust ring index. */ 1601 ha->rsp_ring_index++; 1602 if (ha->rsp_ring_index == RESPONSE_ENTRY_CNT) { 1603 ha->rsp_ring_index = 0; 1604 ha->response_ring_ptr = ha->response_ring_bp; 1605 } else { 1606 ha->response_ring_ptr++; 1607 } 1608 1609 /* Process packet. */ 1610 if (ha->status_srb != NULL && pkt->entry_type != 1611 STATUS_CONT_TYPE) { 1612 ql_add_link_b(done_q, &ha->status_srb->cmd); 1613 ha->status_srb = NULL; 1614 } 1615 1616 pkt->entry_status = (uint8_t)(CFG_IST(ha, CFG_CTRL_24258081) ? 1617 pkt->entry_status & 0x3c : pkt->entry_status & 0x7e); 1618 1619 if (pkt->entry_status != 0) { 1620 ql_error_entry(ha, pkt, done_q, set_flags, 1621 reset_flags); 1622 } else { 1623 switch (pkt->entry_type) { 1624 case STATUS_TYPE: 1625 status |= CFG_IST(ha, CFG_CTRL_24258081) ? 1626 ql_24xx_status_entry(ha, 1627 (sts_24xx_entry_t *)pkt, done_q, set_flags, 1628 reset_flags) : 1629 ql_status_entry(ha, (sts_entry_t *)pkt, 1630 done_q, set_flags, reset_flags); 1631 break; 1632 case STATUS_CONT_TYPE: 1633 ql_status_cont_entry(ha, 1634 (sts_cont_entry_t *)pkt, done_q, set_flags, 1635 reset_flags); 1636 break; 1637 case IP_TYPE: 1638 case IP_A64_TYPE: 1639 case IP_CMD_TYPE: 1640 ql_ip_entry(ha, (ip_entry_t *)pkt, done_q, 1641 set_flags, reset_flags); 1642 break; 1643 case IP_RECEIVE_TYPE: 1644 ql_ip_rcv_entry(ha, 1645 (ip_rcv_entry_t *)pkt, done_q, set_flags, 1646 reset_flags); 1647 break; 1648 case IP_RECEIVE_CONT_TYPE: 1649 ql_ip_rcv_cont_entry(ha, 1650 (ip_rcv_cont_entry_t *)pkt, done_q, 1651 set_flags, reset_flags); 1652 break; 1653 case IP_24XX_RECEIVE_TYPE: 1654 ql_ip_24xx_rcv_entry(ha, 1655 (ip_rcv_24xx_entry_t *)pkt, done_q, 1656 set_flags, reset_flags); 1657 break; 1658 case MS_TYPE: 1659 ql_ms_entry(ha, (ms_entry_t *)pkt, done_q, 1660 set_flags, reset_flags); 1661 break; 1662 case REPORT_ID_TYPE: 1663 ql_report_id_entry(ha, (report_id_1_t *)pkt, 1664 done_q, set_flags, reset_flags); 1665 break; 1666 case ELS_PASSTHRU_TYPE: 1667 ql_els_passthru_entry(ha, 1668 (els_passthru_entry_rsp_t *)pkt, 1669 done_q, set_flags, reset_flags); 1670 break; 1671 case IP_BUF_POOL_TYPE: 1672 case MARKER_TYPE: 1673 case VP_MODIFY_TYPE: 1674 case VP_CONTROL_TYPE: 1675 break; 1676 default: 1677 EL(ha, "Unknown IOCB entry type=%xh\n", 1678 pkt->entry_type); 1679 break; 1680 } 1681 } 1682 } 1683 1684 /* Inform RISC of processed responses. */ 1685 WRT16_IO_REG(ha, resp_out, ha->rsp_ring_index); 1686 1687 /* RESET packet received delay for possible async event. */ 1688 if (status & BIT_0) { 1689 drv_usecwait(500000); 1690 } 1691 1692 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1693 } 1694 1695 /* 1696 * ql_error_entry 1697 * Processes error entry. 1698 * 1699 * Input: 1700 * ha = adapter state pointer. 1701 * pkt = entry pointer. 1702 * done_q = head pointer to done queue. 1703 * set_flags = task daemon flags to set. 1704 * reset_flags = task daemon flags to reset. 1705 * 1706 * Context: 1707 * Interrupt or Kernel context, no mailbox commands allowed. 1708 */ 1709 /* ARGSUSED */ 1710 static void 1711 ql_error_entry(ql_adapter_state_t *ha, response_t *pkt, ql_head_t *done_q, 1712 uint32_t *set_flags, uint32_t *reset_flags) 1713 { 1714 ql_srb_t *sp; 1715 uint32_t index, resp_identifier; 1716 1717 if (pkt->entry_type == INVALID_ENTRY_TYPE) { 1718 EL(ha, "Aborted command\n"); 1719 return; 1720 } 1721 1722 QL_PRINT_2(CE_CONT, "(%d): started, packet:\n", ha->instance); 1723 QL_DUMP_2((uint8_t *)pkt, 8, RESPONSE_ENTRY_SIZE); 1724 1725 if (pkt->entry_status & BIT_6) { 1726 EL(ha, "Request Queue DMA error\n"); 1727 } else if (pkt->entry_status & BIT_5) { 1728 EL(ha, "Invalid Entry Order\n"); 1729 } else if (pkt->entry_status & BIT_4) { 1730 EL(ha, "Invalid Entry Count\n"); 1731 } else if (pkt->entry_status & BIT_3) { 1732 EL(ha, "Invalid Entry Parameter\n"); 1733 } else if (pkt->entry_status & BIT_2) { 1734 EL(ha, "Invalid Entry Type\n"); 1735 } else if (pkt->entry_status & BIT_1) { 1736 EL(ha, "Busy\n"); 1737 } else { 1738 EL(ha, "UNKNOWN flag = %xh error\n", pkt->entry_status); 1739 } 1740 1741 /* Validate the response entry handle. */ 1742 resp_identifier = ddi_get32(ha->hba_buf.acc_handle, &pkt->handle); 1743 index = resp_identifier & OSC_INDEX_MASK; 1744 if (index < MAX_OUTSTANDING_COMMANDS) { 1745 /* the index seems reasonable */ 1746 sp = ha->outstanding_cmds[index]; 1747 if (sp != NULL) { 1748 if (sp->handle == resp_identifier) { 1749 /* Neo, you're the one... */ 1750 ha->outstanding_cmds[index] = NULL; 1751 sp->handle = 0; 1752 sp->flags &= ~SRB_IN_TOKEN_ARRAY; 1753 } else { 1754 EL(ha, "IOCB handle mismatch pkt=%xh, sp=%xh\n", 1755 resp_identifier, sp->handle); 1756 sp = NULL; 1757 ql_signal_abort(ha, set_flags); 1758 } 1759 } else { 1760 sp = ql_verify_preprocessed_cmd(ha, 1761 (uint32_t *)&pkt->handle, set_flags, reset_flags); 1762 } 1763 } else { 1764 EL(ha, "osc index out of range, index=%xh, handle=%xh\n", 1765 index, resp_identifier); 1766 ql_signal_abort(ha, set_flags); 1767 } 1768 1769 if (sp != NULL) { 1770 /* Bad payload or header */ 1771 if (pkt->entry_status & (BIT_5 + BIT_4 + BIT_3 + BIT_2)) { 1772 /* Bad payload or header, set error status. */ 1773 sp->pkt->pkt_reason = CS_BAD_PAYLOAD; 1774 } else if (pkt->entry_status & BIT_1) /* FULL flag */ { 1775 sp->pkt->pkt_reason = CS_QUEUE_FULL; 1776 } else { 1777 /* Set error status. */ 1778 sp->pkt->pkt_reason = CS_UNKNOWN; 1779 } 1780 1781 /* Set completed status. */ 1782 sp->flags |= SRB_ISP_COMPLETED; 1783 1784 /* Place command on done queue. */ 1785 ql_add_link_b(done_q, &sp->cmd); 1786 1787 } 1788 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1789 } 1790 1791 /* 1792 * ql_status_entry 1793 * Processes received ISP2200-2300 status entry. 1794 * 1795 * Input: 1796 * ha: adapter state pointer. 1797 * pkt: entry pointer. 1798 * done_q: done queue pointer. 1799 * set_flags: task daemon flags to set. 1800 * reset_flags: task daemon flags to reset. 1801 * 1802 * Returns: 1803 * BIT_0 = CS_RESET status received. 1804 * 1805 * Context: 1806 * Interrupt or Kernel context, no mailbox commands allowed. 1807 */ 1808 /* ARGSUSED */ 1809 static int 1810 ql_status_entry(ql_adapter_state_t *ha, sts_entry_t *pkt, 1811 ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags) 1812 { 1813 ql_srb_t *sp; 1814 uint32_t index, resp_identifier; 1815 uint16_t comp_status; 1816 int rval = 0; 1817 1818 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1819 1820 /* Validate the response entry handle. */ 1821 resp_identifier = ddi_get32(ha->hba_buf.acc_handle, &pkt->handle); 1822 index = resp_identifier & OSC_INDEX_MASK; 1823 if (index < MAX_OUTSTANDING_COMMANDS) { 1824 /* the index seems reasonable */ 1825 sp = ha->outstanding_cmds[index]; 1826 if (sp != NULL) { 1827 if (sp->handle == resp_identifier) { 1828 /* Neo, you're the one... */ 1829 ha->outstanding_cmds[index] = NULL; 1830 sp->handle = 0; 1831 sp->flags &= ~SRB_IN_TOKEN_ARRAY; 1832 } else { 1833 EL(ha, "IOCB handle mismatch pkt=%xh, sp=%xh\n", 1834 resp_identifier, sp->handle); 1835 sp = NULL; 1836 ql_signal_abort(ha, set_flags); 1837 } 1838 } else { 1839 sp = ql_verify_preprocessed_cmd(ha, 1840 (uint32_t *)&pkt->handle, set_flags, reset_flags); 1841 } 1842 } else { 1843 EL(ha, "osc index out of range, index=%xh, handle=%xh\n", 1844 index, resp_identifier); 1845 ql_signal_abort(ha, set_flags); 1846 } 1847 1848 if (sp != NULL) { 1849 comp_status = (uint16_t)ddi_get16(ha->hba_buf.acc_handle, 1850 &pkt->comp_status); 1851 1852 /* 1853 * We dont care about SCSI QFULLs. 1854 */ 1855 if (comp_status == CS_QUEUE_FULL) { 1856 EL(ha, "CS_QUEUE_FULL, d_id=%xh, lun=%xh\n", 1857 sp->lun_queue->target_queue->d_id.b24, 1858 sp->lun_queue->lun_no); 1859 comp_status = CS_COMPLETE; 1860 } 1861 1862 /* 1863 * 2300 firmware marks completion status as data underrun 1864 * for scsi qfulls. Make it transport complete. 1865 */ 1866 if ((CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) && 1867 (comp_status == CS_DATA_UNDERRUN) && 1868 (pkt->scsi_status_l != 0)) { 1869 comp_status = CS_COMPLETE; 1870 } 1871 1872 /* 1873 * Workaround T3 issue where we do not get any data xferred 1874 * but get back a good status. 1875 */ 1876 if ((pkt->state_flags_h & SF_XFERRED_DATA) == 0 && 1877 comp_status == CS_COMPLETE && 1878 pkt->scsi_status_l == 0 && 1879 (pkt->scsi_status_h & FCP_RSP_MASK) == 0 && 1880 pkt->residual_length == 0 && 1881 sp->fcp && 1882 sp->fcp->fcp_data_len != 0 && 1883 (pkt->state_flags_l & (SF_DATA_OUT | SF_DATA_IN)) == 1884 SF_DATA_OUT) { 1885 comp_status = CS_ABORTED; 1886 } 1887 1888 if (sp->flags & SRB_MS_PKT) { 1889 /* 1890 * Ideally it should never be true. But there 1891 * is a bug in FW which upon receiving invalid 1892 * parameters in MS IOCB returns it as 1893 * status entry and not as ms entry type. 1894 */ 1895 ql_ms_entry(ha, (ms_entry_t *)pkt, done_q, 1896 set_flags, reset_flags); 1897 QL_PRINT_3(CE_CONT, "(%d): ql_ms_entry done\n", 1898 ha->instance); 1899 return (0); 1900 } 1901 1902 /* 1903 * Fast path to good SCSI I/O completion 1904 */ 1905 if ((comp_status == CS_COMPLETE) & 1906 (!pkt->scsi_status_l) & 1907 (!(pkt->scsi_status_h & FCP_RSP_MASK))) { 1908 /* Set completed status. */ 1909 sp->flags |= SRB_ISP_COMPLETED; 1910 sp->pkt->pkt_reason = comp_status; 1911 ql_fast_fcp_post(sp); 1912 QL_PRINT_3(CE_CONT, "(%d): ql_fast_fcp_post done\n", 1913 ha->instance); 1914 return (0); 1915 } 1916 rval = ql_status_error(ha, sp, pkt, done_q, set_flags, 1917 reset_flags); 1918 } 1919 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1920 1921 return (rval); 1922 } 1923 1924 /* 1925 * ql_24xx_status_entry 1926 * Processes received ISP24xx status entry. 1927 * 1928 * Input: 1929 * ha: adapter state pointer. 1930 * pkt: entry pointer. 1931 * done_q: done queue pointer. 1932 * set_flags: task daemon flags to set. 1933 * reset_flags: task daemon flags to reset. 1934 * 1935 * Returns: 1936 * BIT_0 = CS_RESET status received. 1937 * 1938 * Context: 1939 * Interrupt or Kernel context, no mailbox commands allowed. 1940 */ 1941 /* ARGSUSED */ 1942 static int 1943 ql_24xx_status_entry(ql_adapter_state_t *ha, sts_24xx_entry_t *pkt, 1944 ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags) 1945 { 1946 ql_srb_t *sp = NULL; 1947 uint16_t comp_status; 1948 uint32_t index, resp_identifier; 1949 int rval = 0; 1950 1951 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1952 1953 /* Validate the response entry handle. */ 1954 resp_identifier = ddi_get32(ha->hba_buf.acc_handle, &pkt->handle); 1955 index = resp_identifier & OSC_INDEX_MASK; 1956 if (index < MAX_OUTSTANDING_COMMANDS) { 1957 /* the index seems reasonable */ 1958 sp = ha->outstanding_cmds[index]; 1959 if (sp != NULL) { 1960 if (sp->handle == resp_identifier) { 1961 /* Neo, you're the one... */ 1962 ha->outstanding_cmds[index] = NULL; 1963 sp->handle = 0; 1964 sp->flags &= ~SRB_IN_TOKEN_ARRAY; 1965 } else { 1966 EL(ha, "IOCB handle mismatch pkt=%xh, sp=%xh\n", 1967 resp_identifier, sp->handle); 1968 sp = NULL; 1969 ql_signal_abort(ha, set_flags); 1970 } 1971 } else { 1972 sp = ql_verify_preprocessed_cmd(ha, 1973 (uint32_t *)&pkt->handle, set_flags, reset_flags); 1974 } 1975 } else { 1976 EL(ha, "osc index out of range, index=%xh, handle=%xh\n", 1977 index, resp_identifier); 1978 ql_signal_abort(ha, set_flags); 1979 } 1980 1981 if (sp != NULL) { 1982 comp_status = (uint16_t)ddi_get16(ha->hba_buf.acc_handle, 1983 &pkt->comp_status); 1984 1985 /* We dont care about SCSI QFULLs. */ 1986 if (comp_status == CS_QUEUE_FULL) { 1987 EL(sp->ha, "CS_QUEUE_FULL, d_id=%xh, lun=%xh\n", 1988 sp->lun_queue->target_queue->d_id.b24, 1989 sp->lun_queue->lun_no); 1990 comp_status = CS_COMPLETE; 1991 } 1992 1993 /* 1994 * 2300 firmware marks completion status as data underrun 1995 * for scsi qfulls. Make it transport complete. 1996 */ 1997 if ((comp_status == CS_DATA_UNDERRUN) && 1998 (pkt->scsi_status_l != 0)) { 1999 comp_status = CS_COMPLETE; 2000 } 2001 2002 /* 2003 * Workaround T3 issue where we do not get any data xferred 2004 * but get back a good status. 2005 */ 2006 if (comp_status == CS_COMPLETE && 2007 pkt->scsi_status_l == 0 && 2008 (pkt->scsi_status_h & FCP_RSP_MASK) == 0 && 2009 pkt->residual_length != 0 && 2010 sp->fcp && 2011 sp->fcp->fcp_data_len != 0 && 2012 sp->fcp->fcp_cntl.cntl_write_data) { 2013 comp_status = CS_ABORTED; 2014 } 2015 2016 /* 2017 * Fast path to good SCSI I/O completion 2018 */ 2019 if ((comp_status == CS_COMPLETE) & 2020 (!pkt->scsi_status_l) & 2021 (!(pkt->scsi_status_h & FCP_RSP_MASK))) { 2022 /* Set completed status. */ 2023 sp->flags |= SRB_ISP_COMPLETED; 2024 sp->pkt->pkt_reason = comp_status; 2025 ql_fast_fcp_post(sp); 2026 QL_PRINT_3(CE_CONT, "(%d): ql_fast_fcp_post done\n", 2027 ha->instance); 2028 return (0); 2029 } 2030 rval = ql_status_error(ha, sp, (sts_entry_t *)pkt, done_q, 2031 set_flags, reset_flags); 2032 } 2033 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2034 2035 return (rval); 2036 } 2037 2038 /* 2039 * ql_verify_preprocessed_cmd 2040 * Handles preprocessed cmds.. 2041 * 2042 * Input: 2043 * ha: adapter state pointer. 2044 * pkt_handle: handle pointer. 2045 * set_flags: task daemon flags to set. 2046 * reset_flags: task daemon flags to reset. 2047 * 2048 * Returns: 2049 * srb pointer or NULL 2050 * 2051 * Context: 2052 * Interrupt or Kernel context, no mailbox commands allowed. 2053 */ 2054 /* ARGSUSED */ 2055 ql_srb_t * 2056 ql_verify_preprocessed_cmd(ql_adapter_state_t *ha, uint32_t *pkt_handle, 2057 uint32_t *set_flags, uint32_t *reset_flags) 2058 { 2059 ql_srb_t *sp = NULL; 2060 uint32_t index, resp_identifier; 2061 uint32_t get_handle = 10; 2062 2063 while (get_handle) { 2064 /* Get handle. */ 2065 resp_identifier = ddi_get32(ha->hba_buf.acc_handle, pkt_handle); 2066 index = resp_identifier & OSC_INDEX_MASK; 2067 /* Validate handle. */ 2068 if (index < MAX_OUTSTANDING_COMMANDS) { 2069 sp = ha->outstanding_cmds[index]; 2070 } 2071 2072 if (sp != NULL) { 2073 EL(ha, "sp=%xh, resp_id=%xh, get=%d, index=%xh\n", sp, 2074 resp_identifier, get_handle, index); 2075 break; 2076 } else { 2077 get_handle -= 1; 2078 drv_usecwait(10000); 2079 if (get_handle == 1) { 2080 /* Last chance, Sync whole DMA buffer. */ 2081 (void) ddi_dma_sync(ha->hba_buf.dma_handle, 2082 RESPONSE_Q_BUFFER_OFFSET, 2083 RESPONSE_QUEUE_SIZE, 2084 DDI_DMA_SYNC_FORKERNEL); 2085 EL(ha, "last chance DMA sync, index=%xh\n", 2086 index); 2087 } 2088 } 2089 } 2090 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2091 2092 return (sp); 2093 } 2094 2095 2096 /* 2097 * ql_status_error 2098 * Processes received ISP status entry error. 2099 * 2100 * Input: 2101 * ha: adapter state pointer. 2102 * sp: SRB pointer. 2103 * pkt: entry pointer. 2104 * done_q: done queue pointer. 2105 * set_flags: task daemon flags to set. 2106 * reset_flags: task daemon flags to reset. 2107 * 2108 * Returns: 2109 * BIT_0 = CS_RESET status received. 2110 * 2111 * Context: 2112 * Interrupt or Kernel context, no mailbox commands allowed. 2113 */ 2114 /* ARGSUSED */ 2115 static int 2116 ql_status_error(ql_adapter_state_t *ha, ql_srb_t *sp, sts_entry_t *pkt23, 2117 ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags) 2118 { 2119 uint32_t sense_sz = 0; 2120 uint32_t cnt; 2121 ql_tgt_t *tq; 2122 fcp_rsp_t *fcpr; 2123 struct fcp_rsp_info *rsp; 2124 int rval = 0; 2125 2126 struct { 2127 uint8_t *rsp_info; 2128 uint8_t *req_sense_data; 2129 uint32_t residual_length; 2130 uint32_t fcp_residual_length; 2131 uint32_t rsp_info_length; 2132 uint32_t req_sense_length; 2133 uint16_t comp_status; 2134 uint8_t state_flags_l; 2135 uint8_t state_flags_h; 2136 uint8_t scsi_status_l; 2137 uint8_t scsi_status_h; 2138 } sts; 2139 2140 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2141 2142 if (CFG_IST(ha, CFG_CTRL_24258081)) { 2143 sts_24xx_entry_t *pkt24 = (sts_24xx_entry_t *)pkt23; 2144 2145 /* Setup status. */ 2146 sts.comp_status = (uint16_t)ddi_get16(ha->hba_buf.acc_handle, 2147 &pkt24->comp_status); 2148 sts.scsi_status_l = pkt24->scsi_status_l; 2149 sts.scsi_status_h = pkt24->scsi_status_h; 2150 2151 /* Setup firmware residuals. */ 2152 sts.residual_length = sts.comp_status == CS_DATA_UNDERRUN ? 2153 ddi_get32(ha->hba_buf.acc_handle, 2154 (uint32_t *)&pkt24->residual_length) : 0; 2155 2156 /* Setup FCP residuals. */ 2157 sts.fcp_residual_length = sts.scsi_status_h & 2158 (FCP_RESID_UNDER | FCP_RESID_OVER) ? 2159 ddi_get32(ha->hba_buf.acc_handle, 2160 (uint32_t *)&pkt24->fcp_rsp_residual_count) : 0; 2161 2162 if ((sts.comp_status == CS_DATA_UNDERRUN) && 2163 (sts.scsi_status_h & FCP_RESID_UNDER) && 2164 (sts.residual_length != pkt24->fcp_rsp_residual_count)) { 2165 2166 EL(sp->ha, "mismatch resid's: fw=%xh, pkt=%xh\n", 2167 sts.residual_length, 2168 pkt24->fcp_rsp_residual_count); 2169 sts.scsi_status_h = (uint8_t) 2170 (sts.scsi_status_h & ~FCP_RESID_UNDER); 2171 } 2172 2173 /* Setup state flags. */ 2174 sts.state_flags_l = pkt24->state_flags_l; 2175 sts.state_flags_h = pkt24->state_flags_h; 2176 2177 if (sp->fcp->fcp_data_len && 2178 (sts.comp_status != CS_DATA_UNDERRUN || 2179 sts.residual_length != sp->fcp->fcp_data_len)) { 2180 sts.state_flags_h = (uint8_t) 2181 (sts.state_flags_h | SF_GOT_BUS | 2182 SF_GOT_TARGET | SF_SENT_CMD | 2183 SF_XFERRED_DATA | SF_GOT_STATUS); 2184 } else { 2185 sts.state_flags_h = (uint8_t) 2186 (sts.state_flags_h | SF_GOT_BUS | 2187 SF_GOT_TARGET | SF_SENT_CMD | 2188 SF_GOT_STATUS); 2189 } 2190 if (sp->fcp->fcp_cntl.cntl_write_data) { 2191 sts.state_flags_l = (uint8_t) 2192 (sts.state_flags_l | SF_DATA_OUT); 2193 } else if (sp->fcp->fcp_cntl.cntl_read_data) { 2194 sts.state_flags_l = (uint8_t) 2195 (sts.state_flags_l | SF_DATA_IN); 2196 } 2197 if (sp->fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_HEAD_OF_Q) { 2198 sts.state_flags_l = (uint8_t) 2199 (sts.state_flags_l | SF_HEAD_OF_Q); 2200 } else if (sp->fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_ORDERED) { 2201 sts.state_flags_l = (uint8_t) 2202 (sts.state_flags_l | SF_ORDERED_Q); 2203 } else if (sp->fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_SIMPLE) { 2204 sts.state_flags_l = (uint8_t) 2205 (sts.state_flags_l | SF_SIMPLE_Q); 2206 } 2207 2208 /* Setup FCP response info. */ 2209 sts.rsp_info = &pkt24->rsp_sense_data[0]; 2210 if ((sts.scsi_status_h & FCP_RSP_LEN_VALID) != 0) { 2211 sts.rsp_info_length = ddi_get32(ha->hba_buf.acc_handle, 2212 (uint32_t *)&pkt24->fcp_rsp_data_length); 2213 if (sts.rsp_info_length > 2214 sizeof (struct fcp_rsp_info)) { 2215 sts.rsp_info_length = 2216 sizeof (struct fcp_rsp_info); 2217 } 2218 for (cnt = 0; cnt < sts.rsp_info_length; cnt += 4) { 2219 ql_chg_endian(sts.rsp_info + cnt, 4); 2220 } 2221 } else { 2222 sts.rsp_info_length = 0; 2223 } 2224 2225 /* Setup sense data. */ 2226 sts.req_sense_data = 2227 &pkt24->rsp_sense_data[sts.rsp_info_length]; 2228 if (sts.scsi_status_h & FCP_SNS_LEN_VALID) { 2229 sts.req_sense_length = 2230 ddi_get32(ha->hba_buf.acc_handle, 2231 (uint32_t *)&pkt24->fcp_sense_length); 2232 sts.state_flags_h = (uint8_t) 2233 (sts.state_flags_h | SF_ARQ_DONE); 2234 sense_sz = (uint32_t) 2235 (((uintptr_t)pkt24 + sizeof (sts_24xx_entry_t)) - 2236 (uintptr_t)sts.req_sense_data); 2237 for (cnt = 0; cnt < sense_sz; cnt += 4) { 2238 ql_chg_endian(sts.req_sense_data + cnt, 4); 2239 } 2240 } else { 2241 sts.req_sense_length = 0; 2242 } 2243 } else { 2244 /* Setup status. */ 2245 sts.comp_status = (uint16_t)ddi_get16( 2246 ha->hba_buf.acc_handle, &pkt23->comp_status); 2247 sts.scsi_status_l = pkt23->scsi_status_l; 2248 sts.scsi_status_h = pkt23->scsi_status_h; 2249 2250 /* Setup firmware residuals. */ 2251 sts.residual_length = sts.comp_status == CS_DATA_UNDERRUN ? 2252 ddi_get32(ha->hba_buf.acc_handle, 2253 (uint32_t *)&pkt23->residual_length) : 0; 2254 2255 /* Setup FCP residuals. */ 2256 sts.fcp_residual_length = sts.scsi_status_h & 2257 (FCP_RESID_UNDER | FCP_RESID_OVER) ? 2258 sts.residual_length : 0; 2259 2260 /* Setup state flags. */ 2261 sts.state_flags_l = pkt23->state_flags_l; 2262 sts.state_flags_h = pkt23->state_flags_h; 2263 2264 /* Setup FCP response info. */ 2265 sts.rsp_info = &pkt23->rsp_info[0]; 2266 if ((sts.scsi_status_h & FCP_RSP_LEN_VALID) != 0) { 2267 sts.rsp_info_length = ddi_get16( 2268 ha->hba_buf.acc_handle, 2269 (uint16_t *)&pkt23->rsp_info_length); 2270 if (sts.rsp_info_length > 2271 sizeof (struct fcp_rsp_info)) { 2272 sts.rsp_info_length = 2273 sizeof (struct fcp_rsp_info); 2274 } 2275 } else { 2276 sts.rsp_info_length = 0; 2277 } 2278 2279 /* Setup sense data. */ 2280 sts.req_sense_data = &pkt23->req_sense_data[0]; 2281 sts.req_sense_length = sts.scsi_status_h & FCP_SNS_LEN_VALID ? 2282 ddi_get16(ha->hba_buf.acc_handle, 2283 (uint16_t *)&pkt23->req_sense_length) : 0; 2284 } 2285 2286 bzero(sp->pkt->pkt_resp, sp->pkt->pkt_rsplen); 2287 2288 fcpr = (fcp_rsp_t *)sp->pkt->pkt_resp; 2289 rsp = (struct fcp_rsp_info *)(sp->pkt->pkt_resp + 2290 sizeof (fcp_rsp_t)); 2291 2292 tq = sp->lun_queue->target_queue; 2293 2294 fcpr->fcp_u.fcp_status.scsi_status = sts.scsi_status_l; 2295 if (sts.scsi_status_h & FCP_RSP_LEN_VALID) { 2296 fcpr->fcp_u.fcp_status.rsp_len_set = 1; 2297 } 2298 if (sts.scsi_status_h & FCP_SNS_LEN_VALID) { 2299 fcpr->fcp_u.fcp_status.sense_len_set = 1; 2300 } 2301 if (sts.scsi_status_h & FCP_RESID_OVER) { 2302 fcpr->fcp_u.fcp_status.resid_over = 1; 2303 } 2304 if (sts.scsi_status_h & FCP_RESID_UNDER) { 2305 fcpr->fcp_u.fcp_status.resid_under = 1; 2306 } 2307 fcpr->fcp_u.fcp_status.reserved_1 = 0; 2308 2309 /* Set ISP completion status */ 2310 sp->pkt->pkt_reason = sts.comp_status; 2311 2312 /* Update statistics. */ 2313 if ((sts.scsi_status_h & FCP_RSP_LEN_VALID) && 2314 (sp->pkt->pkt_rsplen > sizeof (fcp_rsp_t))) { 2315 2316 sense_sz = sp->pkt->pkt_rsplen - (uint32_t)sizeof (fcp_rsp_t); 2317 if (sense_sz > sts.rsp_info_length) { 2318 sense_sz = sts.rsp_info_length; 2319 } 2320 2321 /* copy response information data. */ 2322 if (sense_sz) { 2323 ddi_rep_get8(ha->hba_buf.acc_handle, (uint8_t *)rsp, 2324 sts.rsp_info, sense_sz, DDI_DEV_AUTOINCR); 2325 } 2326 fcpr->fcp_response_len = sense_sz; 2327 2328 rsp = (struct fcp_rsp_info *)((caddr_t)rsp + 2329 fcpr->fcp_response_len); 2330 2331 switch (*(sts.rsp_info + 3)) { 2332 case FCP_NO_FAILURE: 2333 break; 2334 case FCP_DL_LEN_MISMATCH: 2335 ha->adapter_stats->d_stats[lobyte( 2336 tq->loop_id)].dl_len_mismatches++; 2337 break; 2338 case FCP_CMND_INVALID: 2339 break; 2340 case FCP_DATA_RO_MISMATCH: 2341 ha->adapter_stats->d_stats[lobyte( 2342 tq->loop_id)].data_ro_mismatches++; 2343 break; 2344 case FCP_TASK_MGMT_NOT_SUPPTD: 2345 break; 2346 case FCP_TASK_MGMT_FAILED: 2347 ha->adapter_stats->d_stats[lobyte( 2348 tq->loop_id)].task_mgmt_failures++; 2349 break; 2350 default: 2351 break; 2352 } 2353 } else { 2354 /* 2355 * EL(sp->ha, "scsi_h=%xh, pkt_rsplen=%xh\n", 2356 * sts.scsi_status_h, sp->pkt->pkt_rsplen); 2357 */ 2358 fcpr->fcp_response_len = 0; 2359 } 2360 2361 /* Set reset status received. */ 2362 if (sts.comp_status == CS_RESET && LOOP_READY(ha)) { 2363 rval |= BIT_0; 2364 } 2365 2366 if (!(tq->flags & TQF_TAPE_DEVICE) && 2367 (!(CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING)) || 2368 ha->loop_down_abort_time < LOOP_DOWN_TIMER_START) && 2369 ha->task_daemon_flags & LOOP_DOWN) { 2370 EL(sp->ha, "Loop Not Ready Retry, d_id=%xh, lun=%xh\n", 2371 tq->d_id.b24, sp->lun_queue->lun_no); 2372 2373 /* Set retry status. */ 2374 sp->flags |= SRB_RETRY; 2375 } else if (!(tq->flags & TQF_TAPE_DEVICE) && 2376 tq->port_down_retry_count != 0 && 2377 (sts.comp_status == CS_INCOMPLETE || 2378 sts.comp_status == CS_PORT_UNAVAILABLE || 2379 sts.comp_status == CS_PORT_LOGGED_OUT || 2380 sts.comp_status == CS_PORT_CONFIG_CHG || 2381 sts.comp_status == CS_PORT_BUSY)) { 2382 EL(sp->ha, "Port Down Retry=%xh, d_id=%xh, lun=%xh, count=%d" 2383 "\n", sts.comp_status, tq->d_id.b24, sp->lun_queue->lun_no, 2384 tq->port_down_retry_count); 2385 2386 /* Set retry status. */ 2387 sp->flags |= SRB_RETRY; 2388 2389 if ((tq->flags & TQF_QUEUE_SUSPENDED) == 0) { 2390 /* Acquire device queue lock. */ 2391 DEVICE_QUEUE_LOCK(tq); 2392 2393 tq->flags |= TQF_QUEUE_SUSPENDED; 2394 2395 /* Decrement port down count. */ 2396 if (CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING)) { 2397 tq->port_down_retry_count--; 2398 } 2399 2400 DEVICE_QUEUE_UNLOCK(tq); 2401 2402 if ((ha->task_daemon_flags & ABORT_ISP_ACTIVE) 2403 == 0 && 2404 (sts.comp_status == CS_PORT_LOGGED_OUT || 2405 sts.comp_status == CS_PORT_UNAVAILABLE)) { 2406 sp->ha->adapter_stats->d_stats[lobyte( 2407 tq->loop_id)].logouts_recvd++; 2408 ql_send_logo(sp->ha, tq, done_q); 2409 } 2410 2411 ADAPTER_STATE_LOCK(ha); 2412 if (ha->port_retry_timer == 0) { 2413 if ((ha->port_retry_timer = 2414 ha->port_down_retry_delay) == 0) { 2415 *set_flags |= 2416 PORT_RETRY_NEEDED; 2417 } 2418 } 2419 ADAPTER_STATE_UNLOCK(ha); 2420 } 2421 } else if (!(tq->flags & TQF_TAPE_DEVICE) && 2422 (sts.comp_status == CS_RESET || 2423 (sts.comp_status == CS_QUEUE_FULL && tq->qfull_retry_count != 0) || 2424 (sts.comp_status == CS_ABORTED && !(sp->flags & SRB_ABORTING)))) { 2425 if (sts.comp_status == CS_RESET) { 2426 EL(sp->ha, "Reset Retry, d_id=%xh, lun=%xh\n", 2427 tq->d_id.b24, sp->lun_queue->lun_no); 2428 } else if (sts.comp_status == CS_QUEUE_FULL) { 2429 EL(sp->ha, "Queue Full Retry, d_id=%xh, lun=%xh, " 2430 "cnt=%d\n", tq->d_id.b24, sp->lun_queue->lun_no, 2431 tq->qfull_retry_count); 2432 if ((tq->flags & TQF_QUEUE_SUSPENDED) == 0) { 2433 tq->flags |= TQF_QUEUE_SUSPENDED; 2434 2435 tq->qfull_retry_count--; 2436 2437 ADAPTER_STATE_LOCK(ha); 2438 if (ha->port_retry_timer == 0) { 2439 if ((ha->port_retry_timer = 2440 ha->qfull_retry_delay) == 2441 0) { 2442 *set_flags |= 2443 PORT_RETRY_NEEDED; 2444 } 2445 } 2446 ADAPTER_STATE_UNLOCK(ha); 2447 } 2448 } else { 2449 EL(sp->ha, "Abort Retry, d_id=%xh, lun=%xh\n", 2450 tq->d_id.b24, sp->lun_queue->lun_no); 2451 } 2452 2453 /* Set retry status. */ 2454 sp->flags |= SRB_RETRY; 2455 } else { 2456 fcpr->fcp_resid = 2457 sts.fcp_residual_length > sp->fcp->fcp_data_len ? 2458 sp->fcp->fcp_data_len : sts.fcp_residual_length; 2459 2460 if ((sts.comp_status == CS_DATA_UNDERRUN) && 2461 (sts.scsi_status_h & FCP_RESID_UNDER) == 0) { 2462 2463 if (sts.scsi_status_l == STATUS_CHECK) { 2464 sp->pkt->pkt_reason = CS_COMPLETE; 2465 } else { 2466 EL(ha, "transport error - " 2467 "underrun & invalid resid\n"); 2468 EL(ha, "ssh=%xh, ssl=%xh\n", 2469 sts.scsi_status_h, sts.scsi_status_l); 2470 sp->pkt->pkt_reason = CS_FCP_RESPONSE_ERROR; 2471 } 2472 } 2473 2474 /* Ignore firmware underrun error. */ 2475 if (sts.comp_status == CS_DATA_UNDERRUN && 2476 (sts.scsi_status_h & FCP_RESID_UNDER || 2477 (sts.scsi_status_l != STATUS_CHECK && 2478 sts.scsi_status_l != STATUS_GOOD))) { 2479 sp->pkt->pkt_reason = CS_COMPLETE; 2480 } 2481 2482 if (sp->pkt->pkt_reason != CS_COMPLETE) { 2483 ha->xioctl->DeviceErrorCount++; 2484 EL(sp->ha, "Cmplt status err = %xh, d_id=%xh, lun=%xh" 2485 "\n", sts.comp_status, tq->d_id.b24, 2486 sp->lun_queue->lun_no); 2487 } 2488 2489 /* Set target request sense data. */ 2490 if (sts.scsi_status_l == STATUS_CHECK) { 2491 if (sts.scsi_status_h & FCP_SNS_LEN_VALID) { 2492 2493 if (sp->pkt->pkt_reason == CS_COMPLETE && 2494 sts.req_sense_data[2] != KEY_NO_SENSE && 2495 sts.req_sense_data[2] != 2496 KEY_UNIT_ATTENTION) { 2497 ha->xioctl->DeviceErrorCount++; 2498 } 2499 2500 sense_sz = sts.req_sense_length; 2501 2502 /* Insure data does not exceed buf. */ 2503 if (sp->pkt->pkt_rsplen <= 2504 (uint32_t)sizeof (fcp_rsp_t) + 2505 fcpr->fcp_response_len) { 2506 sp->request_sense_length = 0; 2507 } else { 2508 sp->request_sense_length = (uint32_t) 2509 (sp->pkt->pkt_rsplen - 2510 sizeof (fcp_rsp_t) - 2511 fcpr->fcp_response_len); 2512 } 2513 2514 if (sense_sz < 2515 sp->request_sense_length) { 2516 sp->request_sense_length = 2517 sense_sz; 2518 } 2519 2520 sp->request_sense_ptr = (caddr_t)rsp; 2521 2522 sense_sz = (uint32_t) 2523 (((uintptr_t)pkt23 + 2524 sizeof (sts_entry_t)) - 2525 (uintptr_t)sts.req_sense_data); 2526 if (sp->request_sense_length < 2527 sense_sz) { 2528 sense_sz = 2529 sp->request_sense_length; 2530 } 2531 2532 fcpr->fcp_sense_len = sense_sz; 2533 2534 /* Move sense data. */ 2535 ddi_rep_get8(ha->hba_buf.acc_handle, 2536 (uint8_t *)sp->request_sense_ptr, 2537 sts.req_sense_data, 2538 (size_t)sense_sz, 2539 DDI_DEV_AUTOINCR); 2540 2541 sp->request_sense_ptr += sense_sz; 2542 sp->request_sense_length -= sense_sz; 2543 if (sp->request_sense_length != 0 && 2544 !(CFG_IST(ha, CFG_CTRL_8021))) { 2545 ha->status_srb = sp; 2546 } 2547 } 2548 2549 if (sense_sz != 0) { 2550 EL(sp->ha, "check condition sense data, " 2551 "d_id=%xh, lun=%xh\n%2xh%3xh%3xh%3xh" 2552 "%3xh%3xh%3xh%3xh%3xh%3xh%3xh%3xh%3xh" 2553 "%3xh%3xh%3xh%3xh%3xh\n", tq->d_id.b24, 2554 sp->lun_queue->lun_no, 2555 sts.req_sense_data[0], 2556 sts.req_sense_data[1], 2557 sts.req_sense_data[2], 2558 sts.req_sense_data[3], 2559 sts.req_sense_data[4], 2560 sts.req_sense_data[5], 2561 sts.req_sense_data[6], 2562 sts.req_sense_data[7], 2563 sts.req_sense_data[8], 2564 sts.req_sense_data[9], 2565 sts.req_sense_data[10], 2566 sts.req_sense_data[11], 2567 sts.req_sense_data[12], 2568 sts.req_sense_data[13], 2569 sts.req_sense_data[14], 2570 sts.req_sense_data[15], 2571 sts.req_sense_data[16], 2572 sts.req_sense_data[17]); 2573 } else { 2574 EL(sp->ha, "check condition, d_id=%xh, lun=%xh" 2575 "\n", tq->d_id.b24, sp->lun_queue->lun_no); 2576 } 2577 } 2578 } 2579 2580 /* Set completed status. */ 2581 sp->flags |= SRB_ISP_COMPLETED; 2582 2583 /* Place command on done queue. */ 2584 if (ha->status_srb == NULL) { 2585 ql_add_link_b(done_q, &sp->cmd); 2586 } 2587 2588 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2589 2590 return (rval); 2591 } 2592 2593 /* 2594 * ql_status_cont_entry 2595 * Processes status continuation entry. 2596 * 2597 * Input: 2598 * ha: adapter state pointer. 2599 * pkt: entry pointer. 2600 * done_q: done queue pointer. 2601 * set_flags: task daemon flags to set. 2602 * reset_flags: task daemon flags to reset. 2603 * 2604 * Context: 2605 * Interrupt or Kernel context, no mailbox commands allowed. 2606 */ 2607 /* ARGSUSED */ 2608 static void 2609 ql_status_cont_entry(ql_adapter_state_t *ha, sts_cont_entry_t *pkt, 2610 ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags) 2611 { 2612 uint32_t sense_sz, index; 2613 ql_srb_t *sp = ha->status_srb; 2614 2615 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2616 2617 if (sp != NULL && sp->request_sense_length) { 2618 if (sp->request_sense_length > sizeof (pkt->req_sense_data)) { 2619 sense_sz = sizeof (pkt->req_sense_data); 2620 } else { 2621 sense_sz = sp->request_sense_length; 2622 } 2623 2624 if (CFG_IST(ha, CFG_CTRL_24258081)) { 2625 for (index = 0; index < sense_sz; index += 4) { 2626 ql_chg_endian((uint8_t *) 2627 &pkt->req_sense_data[0] + index, 4); 2628 } 2629 } 2630 2631 /* Move sense data. */ 2632 ddi_rep_get8(ha->hba_buf.acc_handle, 2633 (uint8_t *)sp->request_sense_ptr, 2634 (uint8_t *)&pkt->req_sense_data[0], (size_t)sense_sz, 2635 DDI_DEV_AUTOINCR); 2636 2637 sp->request_sense_ptr += sense_sz; 2638 sp->request_sense_length -= sense_sz; 2639 2640 /* Place command on done queue. */ 2641 if (sp->request_sense_length == 0) { 2642 ql_add_link_b(done_q, &sp->cmd); 2643 ha->status_srb = NULL; 2644 } 2645 } 2646 2647 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2648 } 2649 2650 /* 2651 * ql_ip_entry 2652 * Processes received ISP IP entry. 2653 * 2654 * Input: 2655 * ha: adapter state pointer. 2656 * pkt: entry pointer. 2657 * done_q: done queue pointer. 2658 * set_flags: task daemon flags to set. 2659 * reset_flags: task daemon flags to reset. 2660 * 2661 * Context: 2662 * Interrupt or Kernel context, no mailbox commands allowed. 2663 */ 2664 /* ARGSUSED */ 2665 static void 2666 ql_ip_entry(ql_adapter_state_t *ha, ip_entry_t *pkt23, ql_head_t *done_q, 2667 uint32_t *set_flags, uint32_t *reset_flags) 2668 { 2669 ql_srb_t *sp; 2670 uint32_t index, resp_identifier; 2671 ql_tgt_t *tq; 2672 2673 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2674 2675 /* Validate the response entry handle. */ 2676 resp_identifier = ddi_get32(ha->hba_buf.acc_handle, &pkt23->handle); 2677 index = resp_identifier & OSC_INDEX_MASK; 2678 if (index < MAX_OUTSTANDING_COMMANDS) { 2679 /* the index seems reasonable */ 2680 sp = ha->outstanding_cmds[index]; 2681 if (sp != NULL) { 2682 if (sp->handle == resp_identifier) { 2683 /* Neo, you're the one... */ 2684 ha->outstanding_cmds[index] = NULL; 2685 sp->handle = 0; 2686 sp->flags &= ~SRB_IN_TOKEN_ARRAY; 2687 } else { 2688 EL(ha, "IOCB handle mismatch pkt=%xh, sp=%xh\n", 2689 resp_identifier, sp->handle); 2690 sp = NULL; 2691 ql_signal_abort(ha, set_flags); 2692 } 2693 } else { 2694 sp = ql_verify_preprocessed_cmd(ha, 2695 (uint32_t *)&pkt23->handle, set_flags, reset_flags); 2696 } 2697 } else { 2698 EL(ha, "osc index out of range, index=%xh, handle=%xh\n", 2699 index, resp_identifier); 2700 ql_signal_abort(ha, set_flags); 2701 } 2702 2703 if (sp != NULL) { 2704 tq = sp->lun_queue->target_queue; 2705 2706 /* Set ISP completion status */ 2707 if (CFG_IST(ha, CFG_CTRL_24258081)) { 2708 ip_cmd_entry_t *pkt24 = (ip_cmd_entry_t *)pkt23; 2709 2710 sp->pkt->pkt_reason = ddi_get16( 2711 ha->hba_buf.acc_handle, &pkt24->hdl_status); 2712 } else { 2713 sp->pkt->pkt_reason = ddi_get16( 2714 ha->hba_buf.acc_handle, &pkt23->comp_status); 2715 } 2716 2717 if (ha->task_daemon_flags & LOOP_DOWN) { 2718 EL(ha, "Loop Not Ready Retry, d_id=%xh\n", 2719 tq->d_id.b24); 2720 2721 /* Set retry status. */ 2722 sp->flags |= SRB_RETRY; 2723 2724 } else if (tq->port_down_retry_count && 2725 (sp->pkt->pkt_reason == CS_INCOMPLETE || 2726 sp->pkt->pkt_reason == CS_PORT_UNAVAILABLE || 2727 sp->pkt->pkt_reason == CS_PORT_LOGGED_OUT || 2728 sp->pkt->pkt_reason == CS_PORT_CONFIG_CHG || 2729 sp->pkt->pkt_reason == CS_PORT_BUSY)) { 2730 EL(ha, "Port Down Retry=%xh, d_id=%xh, count=%d\n", 2731 sp->pkt->pkt_reason, tq->d_id.b24, 2732 tq->port_down_retry_count); 2733 2734 /* Set retry status. */ 2735 sp->flags |= SRB_RETRY; 2736 2737 if (sp->pkt->pkt_reason == CS_PORT_LOGGED_OUT || 2738 sp->pkt->pkt_reason == CS_PORT_UNAVAILABLE) { 2739 ha->adapter_stats->d_stats[lobyte( 2740 tq->loop_id)].logouts_recvd++; 2741 ql_send_logo(ha, tq, done_q); 2742 } 2743 2744 /* Acquire device queue lock. */ 2745 DEVICE_QUEUE_LOCK(tq); 2746 2747 if ((tq->flags & TQF_QUEUE_SUSPENDED) == 0) { 2748 tq->flags |= TQF_QUEUE_SUSPENDED; 2749 2750 tq->port_down_retry_count--; 2751 2752 ADAPTER_STATE_LOCK(ha); 2753 if (ha->port_retry_timer == 0) { 2754 if ((ha->port_retry_timer = 2755 ha->port_down_retry_delay) == 0) { 2756 *set_flags |= 2757 PORT_RETRY_NEEDED; 2758 } 2759 } 2760 ADAPTER_STATE_UNLOCK(ha); 2761 } 2762 2763 /* Release device queue specific lock. */ 2764 DEVICE_QUEUE_UNLOCK(tq); 2765 2766 } else if (sp->pkt->pkt_reason == CS_RESET) { 2767 EL(ha, "Reset Retry, d_id=%xh\n", tq->d_id.b24); 2768 2769 /* Set retry status. */ 2770 sp->flags |= SRB_RETRY; 2771 } else { 2772 if (sp->pkt->pkt_reason != CS_COMPLETE) { 2773 EL(ha, "Cmplt status err=%xh, d_id=%xh\n", 2774 sp->pkt->pkt_reason, tq->d_id.b24); 2775 } 2776 } 2777 2778 /* Set completed status. */ 2779 sp->flags |= SRB_ISP_COMPLETED; 2780 2781 ql_add_link_b(done_q, &sp->cmd); 2782 2783 } 2784 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2785 } 2786 2787 /* 2788 * ql_ip_rcv_entry 2789 * Processes received ISP IP buffers entry. 2790 * 2791 * Input: 2792 * ha: adapter state pointer. 2793 * pkt: entry pointer. 2794 * done_q: done queue pointer. 2795 * set_flags: task daemon flags to set. 2796 * reset_flags: task daemon flags to reset. 2797 * 2798 * Context: 2799 * Interrupt or Kernel context, no mailbox commands allowed. 2800 */ 2801 /* ARGSUSED */ 2802 static void 2803 ql_ip_rcv_entry(ql_adapter_state_t *ha, ip_rcv_entry_t *pkt, 2804 ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags) 2805 { 2806 port_id_t s_id; 2807 uint16_t index; 2808 uint8_t cnt; 2809 ql_tgt_t *tq; 2810 2811 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2812 2813 /* Locate device queue. */ 2814 s_id.b.al_pa = pkt->s_id[0]; 2815 s_id.b.area = pkt->s_id[1]; 2816 s_id.b.domain = pkt->s_id[2]; 2817 if ((tq = ql_d_id_to_queue(ha, s_id)) == NULL) { 2818 EL(ha, "Unknown IP device ID=%xh\n", s_id.b24); 2819 return; 2820 } 2821 2822 tq->ub_sequence_length = (uint16_t)ddi_get16(ha->hba_buf.acc_handle, 2823 &pkt->seq_length); 2824 tq->ub_total_seg_cnt = pkt->segment_count; 2825 tq->ub_seq_id = ++ha->ub_seq_id; 2826 tq->ub_seq_cnt = 0; 2827 tq->ub_frame_ro = 0; 2828 tq->ub_loop_id = pkt->loop_id; 2829 ha->rcv_dev_q = tq; 2830 2831 for (cnt = 0; cnt < IP_RCVBUF_HANDLES && tq->ub_seq_cnt < 2832 tq->ub_total_seg_cnt; cnt++) { 2833 2834 index = (uint16_t)ddi_get16(ha->hba_buf.acc_handle, 2835 &pkt->buffer_handle[cnt]); 2836 2837 if (ql_ub_frame_hdr(ha, tq, index, done_q) != QL_SUCCESS) { 2838 EL(ha, "ql_ub_frame_hdr failed, isp_abort_needed\n"); 2839 *set_flags |= ISP_ABORT_NEEDED; 2840 break; 2841 } 2842 } 2843 2844 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2845 } 2846 2847 /* 2848 * ql_ip_rcv_cont_entry 2849 * Processes received ISP IP buffers continuation entry. 2850 * 2851 * Input: 2852 * ha: adapter state pointer. 2853 * pkt: entry pointer. 2854 * done_q: done queue pointer. 2855 * set_flags: task daemon flags to set. 2856 * reset_flags: task daemon flags to reset. 2857 * 2858 * Context: 2859 * Interrupt or Kernel context, no mailbox commands allowed. 2860 */ 2861 /* ARGSUSED */ 2862 static void 2863 ql_ip_rcv_cont_entry(ql_adapter_state_t *ha, ip_rcv_cont_entry_t *pkt, 2864 ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags) 2865 { 2866 uint16_t index; 2867 uint8_t cnt; 2868 ql_tgt_t *tq; 2869 2870 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2871 2872 if ((tq = ha->rcv_dev_q) == NULL) { 2873 EL(ha, "No IP receive device\n"); 2874 return; 2875 } 2876 2877 for (cnt = 0; cnt < IP_RCVBUF_CONT_HANDLES && 2878 tq->ub_seq_cnt < tq->ub_total_seg_cnt; cnt++) { 2879 2880 index = (uint16_t)ddi_get16(ha->hba_buf.acc_handle, 2881 &pkt->buffer_handle[cnt]); 2882 2883 if (ql_ub_frame_hdr(ha, tq, index, done_q) != QL_SUCCESS) { 2884 EL(ha, "ql_ub_frame_hdr failed, isp_abort_needed\n"); 2885 *set_flags |= ISP_ABORT_NEEDED; 2886 break; 2887 } 2888 } 2889 2890 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2891 } 2892 2893 /* 2894 * ip_rcv_24xx_entry_t 2895 * Processes received ISP24xx IP buffers entry. 2896 * 2897 * Input: 2898 * ha: adapter state pointer. 2899 * pkt: entry pointer. 2900 * done_q: done queue pointer. 2901 * set_flags: task daemon flags to set. 2902 * reset_flags: task daemon flags to reset. 2903 * 2904 * Context: 2905 * Interrupt or Kernel context, no mailbox commands allowed. 2906 */ 2907 /* ARGSUSED */ 2908 static void 2909 ql_ip_24xx_rcv_entry(ql_adapter_state_t *ha, ip_rcv_24xx_entry_t *pkt, 2910 ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags) 2911 { 2912 port_id_t s_id; 2913 uint16_t index; 2914 uint8_t cnt; 2915 ql_tgt_t *tq; 2916 2917 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2918 2919 /* Locate device queue. */ 2920 s_id.b.al_pa = pkt->s_id[0]; 2921 s_id.b.area = pkt->s_id[1]; 2922 s_id.b.domain = pkt->s_id[2]; 2923 if ((tq = ql_d_id_to_queue(ha, s_id)) == NULL) { 2924 EL(ha, "Unknown IP device ID=%xh\n", s_id.b24); 2925 return; 2926 } 2927 2928 if (tq->ub_total_seg_cnt == 0) { 2929 tq->ub_sequence_length = (uint16_t)ddi_get16( 2930 ha->hba_buf.acc_handle, &pkt->seq_length); 2931 tq->ub_total_seg_cnt = pkt->segment_count; 2932 tq->ub_seq_id = ++ha->ub_seq_id; 2933 tq->ub_seq_cnt = 0; 2934 tq->ub_frame_ro = 0; 2935 tq->ub_loop_id = (uint16_t)ddi_get16( 2936 ha->hba_buf.acc_handle, &pkt->n_port_hdl); 2937 } 2938 2939 for (cnt = 0; cnt < IP_24XX_RCVBUF_HANDLES && tq->ub_seq_cnt < 2940 tq->ub_total_seg_cnt; cnt++) { 2941 2942 index = (uint16_t)ddi_get16(ha->hba_buf.acc_handle, 2943 &pkt->buffer_handle[cnt]); 2944 2945 if (ql_ub_frame_hdr(ha, tq, index, done_q) != QL_SUCCESS) { 2946 EL(ha, "ql_ub_frame_hdr failed, isp_abort_needed\n"); 2947 *set_flags |= ISP_ABORT_NEEDED; 2948 break; 2949 } 2950 } 2951 2952 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2953 } 2954 2955 /* 2956 * ql_ms_entry 2957 * Processes received Name/Management/CT Pass-Through entry. 2958 * 2959 * Input: 2960 * ha: adapter state pointer. 2961 * pkt23: entry pointer. 2962 * done_q: done queue pointer. 2963 * set_flags: task daemon flags to set. 2964 * reset_flags: task daemon flags to reset. 2965 * 2966 * Context: 2967 * Interrupt or Kernel context, no mailbox commands allowed. 2968 */ 2969 /* ARGSUSED */ 2970 static void 2971 ql_ms_entry(ql_adapter_state_t *ha, ms_entry_t *pkt23, ql_head_t *done_q, 2972 uint32_t *set_flags, uint32_t *reset_flags) 2973 { 2974 ql_srb_t *sp; 2975 uint32_t index, cnt, resp_identifier; 2976 ql_tgt_t *tq; 2977 ct_passthru_entry_t *pkt24 = (ct_passthru_entry_t *)pkt23; 2978 2979 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2980 2981 /* Validate the response entry handle. */ 2982 resp_identifier = ddi_get32(ha->hba_buf.acc_handle, &pkt23->handle); 2983 index = resp_identifier & OSC_INDEX_MASK; 2984 if (index < MAX_OUTSTANDING_COMMANDS) { 2985 /* the index seems reasonable */ 2986 sp = ha->outstanding_cmds[index]; 2987 if (sp != NULL) { 2988 if (sp->handle == resp_identifier) { 2989 /* Neo, you're the one... */ 2990 ha->outstanding_cmds[index] = NULL; 2991 sp->handle = 0; 2992 sp->flags &= ~SRB_IN_TOKEN_ARRAY; 2993 } else { 2994 EL(ha, "IOCB handle mismatch pkt=%xh, sp=%xh\n", 2995 resp_identifier, sp->handle); 2996 sp = NULL; 2997 ql_signal_abort(ha, set_flags); 2998 } 2999 } else { 3000 sp = ql_verify_preprocessed_cmd(ha, 3001 (uint32_t *)&pkt23->handle, set_flags, reset_flags); 3002 } 3003 } else { 3004 EL(ha, "osc index out of range, index=%xh, handle=%xh\n", 3005 index, resp_identifier); 3006 ql_signal_abort(ha, set_flags); 3007 } 3008 3009 if (sp != NULL) { 3010 if (!(sp->flags & SRB_MS_PKT)) { 3011 EL(ha, "Not SRB_MS_PKT flags=%xh, isp_abort_needed", 3012 sp->flags); 3013 *set_flags |= ISP_ABORT_NEEDED; 3014 return; 3015 } 3016 3017 tq = sp->lun_queue->target_queue; 3018 3019 /* Set ISP completion status */ 3020 if (CFG_IST(ha, CFG_CTRL_24258081)) { 3021 sp->pkt->pkt_reason = ddi_get16( 3022 ha->hba_buf.acc_handle, &pkt24->status); 3023 } else { 3024 sp->pkt->pkt_reason = ddi_get16( 3025 ha->hba_buf.acc_handle, &pkt23->comp_status); 3026 } 3027 3028 if (sp->pkt->pkt_reason == CS_RESOUCE_UNAVAILABLE && 3029 sp->retry_count) { 3030 EL(ha, "Resouce Unavailable Retry = %d\n", 3031 sp->retry_count); 3032 3033 /* Set retry status. */ 3034 sp->retry_count--; 3035 sp->flags |= SRB_RETRY; 3036 3037 /* Acquire device queue lock. */ 3038 DEVICE_QUEUE_LOCK(tq); 3039 3040 if (!(tq->flags & TQF_QUEUE_SUSPENDED)) { 3041 tq->flags |= TQF_QUEUE_SUSPENDED; 3042 3043 ADAPTER_STATE_LOCK(ha); 3044 if (ha->port_retry_timer == 0) { 3045 ha->port_retry_timer = 2; 3046 } 3047 ADAPTER_STATE_UNLOCK(ha); 3048 } 3049 3050 /* Release device queue specific lock. */ 3051 DEVICE_QUEUE_UNLOCK(tq); 3052 3053 } else if (tq->port_down_retry_count && 3054 (sp->pkt->pkt_reason == CS_PORT_CONFIG_CHG || 3055 sp->pkt->pkt_reason == CS_PORT_BUSY)) { 3056 EL(ha, "Port Down Retry\n"); 3057 3058 /* Set retry status. */ 3059 sp->flags |= SRB_RETRY; 3060 3061 /* Acquire device queue lock. */ 3062 DEVICE_QUEUE_LOCK(tq); 3063 3064 if ((tq->flags & TQF_QUEUE_SUSPENDED) == 0) { 3065 tq->flags |= TQF_QUEUE_SUSPENDED; 3066 3067 tq->port_down_retry_count--; 3068 3069 ADAPTER_STATE_LOCK(ha); 3070 if (ha->port_retry_timer == 0) { 3071 if ((ha->port_retry_timer = 3072 ha->port_down_retry_delay) == 0) { 3073 *set_flags |= 3074 PORT_RETRY_NEEDED; 3075 } 3076 } 3077 ADAPTER_STATE_UNLOCK(ha); 3078 } 3079 /* Release device queue specific lock. */ 3080 DEVICE_QUEUE_UNLOCK(tq); 3081 3082 } else if (sp->pkt->pkt_reason == CS_RESET) { 3083 EL(ha, "Reset Retry\n"); 3084 3085 /* Set retry status. */ 3086 sp->flags |= SRB_RETRY; 3087 3088 } else if (CFG_IST(ha, CFG_CTRL_24258081) && 3089 sp->pkt->pkt_reason == CS_DATA_UNDERRUN) { 3090 cnt = ddi_get32(ha->hba_buf.acc_handle, 3091 &pkt24->resp_byte_count); 3092 if (cnt < sizeof (fc_ct_header_t)) { 3093 EL(ha, "Data underrun\n"); 3094 } else { 3095 sp->pkt->pkt_reason = CS_COMPLETE; 3096 } 3097 3098 } else if (sp->pkt->pkt_reason != CS_COMPLETE) { 3099 EL(ha, "status err=%xh\n", sp->pkt->pkt_reason); 3100 } 3101 3102 if (sp->pkt->pkt_reason == CS_COMPLETE) { 3103 /*EMPTY*/ 3104 QL_PRINT_3(CE_CONT, "(%d): ct_cmdrsp=%x%02xh resp\n", 3105 ha->instance, sp->pkt->pkt_cmd[8], 3106 sp->pkt->pkt_cmd[9]); 3107 QL_DUMP_3(sp->pkt->pkt_resp, 8, sp->pkt->pkt_rsplen); 3108 } 3109 3110 /* For nameserver restore command, management change header. */ 3111 if ((sp->flags & SRB_RETRY) == 0) { 3112 tq->d_id.b24 == 0xfffffc ? 3113 ql_cthdr_endian(sp->pkt->pkt_cmd_acc, 3114 sp->pkt->pkt_cmd, B_TRUE) : 3115 ql_cthdr_endian(sp->pkt->pkt_resp_acc, 3116 sp->pkt->pkt_resp, B_TRUE); 3117 } 3118 3119 /* Set completed status. */ 3120 sp->flags |= SRB_ISP_COMPLETED; 3121 3122 /* Place command on done queue. */ 3123 ql_add_link_b(done_q, &sp->cmd); 3124 3125 } 3126 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3127 } 3128 3129 /* 3130 * ql_report_id_entry 3131 * Processes received Name/Management/CT Pass-Through entry. 3132 * 3133 * Input: 3134 * ha: adapter state pointer. 3135 * pkt: entry pointer. 3136 * done_q: done queue pointer. 3137 * set_flags: task daemon flags to set. 3138 * reset_flags: task daemon flags to reset. 3139 * 3140 * Context: 3141 * Interrupt or Kernel context, no mailbox commands allowed. 3142 */ 3143 /* ARGSUSED */ 3144 static void 3145 ql_report_id_entry(ql_adapter_state_t *ha, report_id_1_t *pkt, 3146 ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags) 3147 { 3148 ql_adapter_state_t *vha; 3149 3150 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3151 3152 EL(ha, "format=%d, vp=%d, status=%d\n", 3153 pkt->format, pkt->vp_index, pkt->status); 3154 3155 if (pkt->format == 1) { 3156 /* Locate port state structure. */ 3157 for (vha = ha; vha != NULL; vha = vha->vp_next) { 3158 if (vha->vp_index == pkt->vp_index) { 3159 break; 3160 } 3161 } 3162 if (vha != NULL && vha->vp_index != 0 && 3163 (pkt->status == CS_COMPLETE || 3164 pkt->status == CS_PORT_ID_CHANGE)) { 3165 *set_flags |= LOOP_RESYNC_NEEDED; 3166 *reset_flags &= ~LOOP_RESYNC_NEEDED; 3167 vha->loop_down_timer = LOOP_DOWN_TIMER_OFF; 3168 TASK_DAEMON_LOCK(ha); 3169 vha->task_daemon_flags |= LOOP_RESYNC_NEEDED; 3170 vha->task_daemon_flags &= ~LOOP_DOWN; 3171 TASK_DAEMON_UNLOCK(ha); 3172 } 3173 } 3174 3175 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3176 } 3177 3178 /* 3179 * ql_els_entry 3180 * Processes received ELS Pass-Through entry. 3181 * 3182 * Input: 3183 * ha: adapter state pointer. 3184 * pkt23: entry pointer. 3185 * done_q: done queue pointer. 3186 * set_flags: task daemon flags to set. 3187 * reset_flags: task daemon flags to reset. 3188 * 3189 * Context: 3190 * Interrupt or Kernel context, no mailbox commands allowed. 3191 */ 3192 /* ARGSUSED */ 3193 static void 3194 ql_els_passthru_entry(ql_adapter_state_t *ha, els_passthru_entry_rsp_t *rsp, 3195 ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags) 3196 { 3197 ql_tgt_t *tq; 3198 port_id_t d_id, s_id; 3199 ql_srb_t *srb; 3200 uint32_t index, resp_identifier; 3201 3202 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3203 3204 /* Validate the response entry handle. */ 3205 resp_identifier = ddi_get32(ha->hba_buf.acc_handle, &rsp->handle); 3206 index = resp_identifier & OSC_INDEX_MASK; 3207 if (index < MAX_OUTSTANDING_COMMANDS) { 3208 /* the index seems reasonable */ 3209 srb = ha->outstanding_cmds[index]; 3210 if (srb != NULL) { 3211 if (srb->handle == resp_identifier) { 3212 /* Neo, you're the one... */ 3213 ha->outstanding_cmds[index] = NULL; 3214 srb->handle = 0; 3215 srb->flags &= ~SRB_IN_TOKEN_ARRAY; 3216 } else { 3217 EL(ha, "IOCB handle mismatch pkt=%xh, sp=%xh\n", 3218 resp_identifier, srb->handle); 3219 srb = NULL; 3220 ql_signal_abort(ha, set_flags); 3221 } 3222 } else { 3223 srb = ql_verify_preprocessed_cmd(ha, 3224 (uint32_t *)&rsp->handle, set_flags, reset_flags); 3225 } 3226 } else { 3227 EL(ha, "osc index out of range, index=%xh, handle=%xh\n", 3228 index, resp_identifier); 3229 ql_signal_abort(ha, set_flags); 3230 } 3231 3232 if (srb != NULL) { 3233 if (!(srb->flags & SRB_ELS_PKT)) { 3234 EL(ha, "Not SRB_ELS_PKT flags=%xh, isp_abort_needed", 3235 srb->flags); 3236 *set_flags |= ISP_ABORT_NEEDED; 3237 return; 3238 } 3239 3240 (void) ddi_dma_sync(srb->pkt->pkt_resp_dma, 0, 0, 3241 DDI_DMA_SYNC_FORKERNEL); 3242 3243 /* Set ISP completion status */ 3244 srb->pkt->pkt_reason = ddi_get16( 3245 ha->hba_buf.acc_handle, &rsp->comp_status); 3246 3247 if (srb->pkt->pkt_reason != CS_COMPLETE) { 3248 la_els_rjt_t rjt; 3249 EL(ha, "status err=%xh\n", srb->pkt->pkt_reason); 3250 3251 if (srb->pkt->pkt_reason == CS_LOGIN_LOGOUT_ERROR) { 3252 EL(ha, "e1=%xh e2=%xh\n", 3253 rsp->error_subcode1, rsp->error_subcode2); 3254 } 3255 3256 srb->pkt->pkt_state = FC_PKT_TRAN_ERROR; 3257 3258 /* Build RJT in the response. */ 3259 rjt.ls_code.ls_code = LA_ELS_RJT; 3260 rjt.reason = FC_REASON_NO_CONNECTION; 3261 3262 ddi_rep_put8(srb->pkt->pkt_resp_acc, (uint8_t *)&rjt, 3263 (uint8_t *)srb->pkt->pkt_resp, 3264 sizeof (rjt), DDI_DEV_AUTOINCR); 3265 3266 srb->pkt->pkt_state = FC_PKT_TRAN_ERROR; 3267 srb->pkt->pkt_reason = FC_REASON_NO_CONNECTION; 3268 } 3269 3270 if (srb->pkt->pkt_reason == CS_COMPLETE) { 3271 uint8_t opcode; 3272 uint16_t loop_id; 3273 3274 /* Indicate ISP completion */ 3275 srb->flags |= SRB_ISP_COMPLETED; 3276 3277 loop_id = ddi_get16(ha->hba_buf.acc_handle, 3278 &rsp->n_port_hdl); 3279 3280 if (ha->topology & QL_N_PORT) { 3281 /* create a target Q if there isn't one */ 3282 tq = ql_loop_id_to_queue(ha, loop_id); 3283 if (tq == NULL) { 3284 d_id.b.al_pa = rsp->d_id_7_0; 3285 d_id.b.area = rsp->d_id_15_8; 3286 d_id.b.domain = rsp->d_id_23_16; 3287 /* Acquire adapter state lock. */ 3288 ADAPTER_STATE_LOCK(ha); 3289 3290 tq = ql_dev_init(ha, d_id, loop_id); 3291 EL(ha, " tq = %x\n", tq); 3292 3293 ADAPTER_STATE_UNLOCK(ha); 3294 } 3295 3296 /* on plogi success assume the chosen s_id */ 3297 opcode = ddi_get8(ha->hba_buf.acc_handle, 3298 &rsp->els_cmd_opcode); 3299 3300 EL(ha, "els_cmd_opcode=%x srb->pkt=%x\n", 3301 opcode, srb->pkt); 3302 3303 if (opcode == LA_ELS_PLOGI) { 3304 s_id.b.al_pa = rsp->s_id_7_0; 3305 s_id.b.area = rsp->s_id_15_8; 3306 s_id.b.domain = rsp->s_id_23_16; 3307 3308 ha->d_id.b24 = s_id.b24; 3309 EL(ha, "Set port's source ID %xh\n", 3310 ha->d_id.b24); 3311 } 3312 } 3313 ql_isp_els_handle_rsp_endian(ha, srb); 3314 3315 if (ha != srb->ha) { 3316 EL(ha, "ha=%x srb->ha=%x\n", ha, srb->ha); 3317 } 3318 3319 if (tq != NULL) { 3320 tq->logout_sent = 0; 3321 tq->flags &= ~TQF_NEED_AUTHENTICATION; 3322 3323 if (CFG_IST(ha, CFG_CTRL_24258081)) { 3324 tq->flags |= TQF_IIDMA_NEEDED; 3325 } 3326 srb->pkt->pkt_state = FC_PKT_SUCCESS; 3327 } 3328 } 3329 /* invoke the callback */ 3330 ql_awaken_task_daemon(ha, srb, 0, 0); 3331 } 3332 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3333 } 3334 3335 /* 3336 * ql_signal_abort 3337 * Signal to the task daemon that a condition warranting an 3338 * isp reset has been detected. 3339 * 3340 * Input: 3341 * ha: adapter state pointer. 3342 * set_flags: task daemon flags to set. 3343 * 3344 * Context: 3345 * Interrupt or Kernel context, no mailbox commands allowed. 3346 */ 3347 static void 3348 ql_signal_abort(ql_adapter_state_t *ha, uint32_t *set_flags) 3349 { 3350 if (!CFG_IST(ha, CFG_CTRL_8021) && 3351 !(ha->task_daemon_flags & (ISP_ABORT_NEEDED | ABORT_ISP_ACTIVE))) { 3352 *set_flags |= ISP_ABORT_NEEDED; 3353 } 3354 } 3355