1 /* $NetBSD: isp_target.c,v 1.30 2007/05/24 21:30:43 mjacob Exp $ */ 2 /*- 3 * Copyright (c) 1997-2006 by Matthew Jacob 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 /* 29 * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters. 30 */ 31 /* 32 * Bug fixes gratefully acknowledged from: 33 * Oded Kedem <oded@kashya.com> 34 */ 35 /* 36 * Include header file appropriate for platform we're building on. 37 */ 38 39 #ifdef __NetBSD__ 40 #include <sys/cdefs.h> 41 __KERNEL_RCSID(0, "$NetBSD: isp_target.c,v 1.30 2007/05/24 21:30:43 mjacob Exp $"); 42 #include <dev/ic/isp_netbsd.h> 43 #endif 44 #ifdef __FreeBSD__ 45 #include <sys/cdefs.h> 46 __FBSDID("$FreeBSD:$"); 47 #include <dev/isp/isp_freebsd.h> 48 #endif 49 #ifdef __OpenBSD__ 50 #include <dev/ic/isp_openbsd.h> 51 #endif 52 #ifdef __linux__ 53 #include "isp_linux.h" 54 #endif 55 56 #ifdef ISP_TARGET_MODE 57 static const char atiocope[] = 58 "ATIO returned for lun %d because it was in the middle of Bus Device Reset " 59 "on bus %d"; 60 static const char atior[] = 61 "ATIO returned on for lun %d on from loopid %d because a Bus Reset " 62 "occurred on bus %d"; 63 64 static void isp_got_msg(ispsoftc_t *, in_entry_t *); 65 static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *); 66 static void isp_got_tmf_24xx(ispsoftc_t *, at7_entry_t *); 67 static void isp_handle_atio(ispsoftc_t *, at_entry_t *); 68 static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *); 69 static void isp_handle_ctio(ispsoftc_t *, ct_entry_t *); 70 static void isp_handle_ctio2(ispsoftc_t *, ct2_entry_t *); 71 static void isp_handle_ctio7(ispsoftc_t *, ct7_entry_t *); 72 73 /* 74 * The Qlogic driver gets an interrupt to look at response queue entries. 75 * Some of these are status completions for initiatior mode commands, but 76 * if target mode is enabled, we get a whole wad of response queue entries 77 * to be handled here. 78 * 79 * Basically the split into 3 main groups: Lun Enable/Modification responses, 80 * SCSI Command processing, and Immediate Notification events. 81 * 82 * You start by writing a request queue entry to enable target mode (and 83 * establish some resource limitations which you can modify later). 84 * The f/w responds with a LUN ENABLE or LUN MODIFY response with 85 * the status of this action. If the enable was successful, you can expect... 86 * 87 * Response queue entries with SCSI commands encapsulate show up in an ATIO 88 * (Accept Target IO) type- sometimes with enough info to stop the command at 89 * this level. Ultimately the driver has to feed back to the f/w's request 90 * queue a sequence of CTIOs (continue target I/O) that describe data to 91 * be moved and/or status to be sent) and finally finishing with sending 92 * to the f/w's response queue an ATIO which then completes the handshake 93 * with the f/w for that command. There's a lot of variations on this theme, 94 * including flags you can set in the CTIO for the Qlogic 2X00 fibre channel 95 * cards that 'auto-replenish' the f/w's ATIO count, but this is the basic 96 * gist of it. 97 * 98 * The third group that can show up in the response queue are Immediate 99 * Notification events. These include things like notifications of SCSI bus 100 * resets, or Bus Device Reset messages or other messages received. This 101 * a classic oddbins area. It can get a little weird because you then turn 102 * around and acknowledge the Immediate Notify by writing an entry onto the 103 * request queue and then the f/w turns around and gives you an acknowledgement 104 * to *your* acknowledgement on the response queue (the idea being to let 105 * the f/w tell you when the event is *really* over I guess). 106 * 107 */ 108 109 110 /* 111 * A new response queue entry has arrived. The interrupt service code 112 * has already swizzled it into the platform dependent from canonical form. 113 * 114 * Because of the way this driver is designed, unfortunately most of the 115 * actual synchronization work has to be done in the platform specific 116 * code- we have no synchroniation primitives in the common code. 117 */ 118 119 int 120 isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp) 121 { 122 uint16_t status; 123 uint32_t seqid; 124 union { 125 at_entry_t *atiop; 126 at2_entry_t *at2iop; 127 at2e_entry_t *at2eiop; 128 at7_entry_t *at7iop; 129 ct_entry_t *ctiop; 130 ct2_entry_t *ct2iop; 131 ct2e_entry_t *ct2eiop; 132 ct7_entry_t *ct7iop; 133 lun_entry_t *lunenp; 134 in_entry_t *inotp; 135 in_fcentry_t *inot_fcp; 136 in_fcentry_e_t *inote_fcp; 137 in_fcentry_24xx_t *inot_24xx; 138 na_entry_t *nackp; 139 na_fcentry_t *nack_fcp; 140 na_fcentry_e_t *nacke_fcp; 141 na_fcentry_24xx_t *nack_24xx; 142 isphdr_t *hp; 143 abts_t *abts; 144 abts_rsp_t *abts_rsp; 145 els_t *els; 146 void * *vp; 147 #define atiop unp.atiop 148 #define at2iop unp.at2iop 149 #define at2eiop unp.at2eiop 150 #define at7iop unp.at7iop 151 #define ctiop unp.ctiop 152 #define ct2iop unp.ct2iop 153 #define ct2eiop unp.ct2eiop 154 #define ct7iop unp.ct7iop 155 #define lunenp unp.lunenp 156 #define inotp unp.inotp 157 #define inot_fcp unp.inot_fcp 158 #define inote_fcp unp.inote_fcp 159 #define inot_24xx unp.inot_24xx 160 #define nackp unp.nackp 161 #define nack_fcp unp.nack_fcp 162 #define nacke_fcp unp.nacke_fcp 163 #define nack_24xx unp.nack_24xx 164 #define abts unp.abts 165 #define abts_rsp unp.abts_rsp 166 #define els unp.els 167 #define hdrp unp.hp 168 } unp; 169 uint8_t local[QENTRY_LEN]; 170 int bus, type, level, rval = 1; 171 172 type = isp_get_response_type(isp, (isphdr_t *)vptr); 173 unp.vp = vptr; 174 175 ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr); 176 177 switch(type) { 178 case RQSTYPE_ATIO: 179 if (IS_24XX(isp)) { 180 int len; 181 182 isp_get_atio7(isp, at7iop, (at7_entry_t *) local); 183 at7iop = (at7_entry_t *) local; 184 /* 185 * Check for and do something with commands whose IULEN 186 * extends past a singel queue entry. 187 */ 188 len = at7iop->at_ta_len & 0xfffff; 189 if (len > (QENTRY_LEN - 8)) { 190 len -= (QENTRY_LEN - 8); 191 isp_prt(isp, ISP_LOGINFO, 192 "long IU length (%d) ignored", len); 193 while (len > 0) { 194 *optrp = ISP_NXT_QENTRY(*optrp, 195 RESULT_QUEUE_LEN(isp)); 196 len -= QENTRY_LEN; 197 } 198 } 199 /* 200 * Check for a task management function 201 */ 202 if (at7iop->at_cmnd.fcp_cmnd_task_management) { 203 isp_got_tmf_24xx(isp, at7iop); 204 break; 205 } 206 /* 207 * Just go straight to outer layer for this one. 208 */ 209 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, local); 210 } else { 211 isp_get_atio(isp, atiop, (at_entry_t *) local); 212 isp_handle_atio(isp, (at_entry_t *) local); 213 } 214 break; 215 216 case RQSTYPE_CTIO: 217 isp_get_ctio(isp, ctiop, (ct_entry_t *) local); 218 isp_handle_ctio(isp, (ct_entry_t *) local); 219 break; 220 221 case RQSTYPE_ATIO2: 222 if (FCPARAM(isp)->isp_2klogin) { 223 isp_get_atio2e(isp, at2eiop, (at2e_entry_t *) local); 224 } else { 225 isp_get_atio2(isp, at2iop, (at2_entry_t *) local); 226 } 227 isp_handle_atio2(isp, (at2_entry_t *) local); 228 break; 229 230 case RQSTYPE_CTIO3: 231 case RQSTYPE_CTIO2: 232 if (FCPARAM(isp)->isp_2klogin) { 233 isp_get_ctio2e(isp, ct2eiop, (ct2e_entry_t *) local); 234 } else { 235 isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local); 236 } 237 isp_handle_ctio2(isp, (ct2_entry_t *) local); 238 break; 239 240 case RQSTYPE_CTIO7: 241 isp_get_ctio7(isp, ct7iop, (ct7_entry_t *) local); 242 isp_handle_ctio7(isp, (ct7_entry_t *) local); 243 break; 244 245 case RQSTYPE_ENABLE_LUN: 246 case RQSTYPE_MODIFY_LUN: 247 isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local); 248 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, local); 249 break; 250 251 case RQSTYPE_NOTIFY: 252 /* 253 * Either the ISP received a SCSI message it can't 254 * handle, or it's returning an Immed. Notify entry 255 * we sent. We can send Immed. Notify entries to 256 * increment the firmware's resource count for them 257 * (we set this initially in the Enable Lun entry). 258 */ 259 bus = 0; 260 if (IS_24XX(isp)) { 261 isp_get_notify_24xx(isp, inot_24xx, 262 (in_fcentry_24xx_t *)local); 263 inot_24xx = (in_fcentry_24xx_t *) local; 264 status = inot_24xx->in_status; 265 seqid = inot_24xx->in_rxid; 266 isp_prt(isp, ISP_LOGTDEBUG0, 267 "Immediate Notify status=0x%x seqid=0x%x", 268 status, seqid); 269 switch (status) { 270 case IN24XX_LIP_RESET: 271 case IN24XX_LINK_RESET: 272 case IN24XX_PORT_LOGOUT: 273 case IN24XX_PORT_CHANGED: 274 case IN24XX_LINK_FAILED: 275 case IN24XX_SRR_RCVD: 276 case IN24XX_ELS_RCVD: 277 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, 278 &local); 279 break; 280 default: 281 isp_prt(isp, ISP_LOGINFO, 282 "isp_target_notify: unknown status (0x%x)", 283 status); 284 isp_notify_ack(isp, local); 285 break; 286 } 287 break; 288 } else if (IS_FC(isp)) { 289 if (FCPARAM(isp)->isp_2klogin) { 290 isp_get_notify_fc_e(isp, inote_fcp, 291 (in_fcentry_e_t *)local); 292 } else { 293 isp_get_notify_fc(isp, inot_fcp, 294 (in_fcentry_t *)local); 295 } 296 inot_fcp = (in_fcentry_t *) local; 297 status = inot_fcp->in_status; 298 seqid = inot_fcp->in_seqid; 299 } else { 300 isp_get_notify(isp, inotp, (in_entry_t *)local); 301 inotp = (in_entry_t *) local; 302 status = inotp->in_status & 0xff; 303 seqid = inotp->in_seqid; 304 if (IS_DUALBUS(isp)) { 305 bus = GET_BUS_VAL(inotp->in_iid); 306 SET_BUS_VAL(inotp->in_iid, 0); 307 } 308 } 309 310 isp_prt(isp, ISP_LOGTDEBUG0, 311 "Immediate Notify On Bus %d, status=0x%x seqid=0x%x", 312 bus, status, seqid); 313 314 switch (status) { 315 case IN_MSG_RECEIVED: 316 case IN_IDE_RECEIVED: 317 if (IS_FC(isp)) { 318 isp_got_msg_fc(isp, (in_fcentry_t *)local); 319 } else { 320 isp_got_msg(isp, (in_entry_t *)local); 321 } 322 break; 323 case IN_RSRC_UNAVAIL: 324 isp_prt(isp, ISP_LOGINFO, "Firmware out of ATIOs"); 325 isp_notify_ack(isp, local); 326 break; 327 case IN_RESET: 328 { 329 /* 330 * We form the notify structure here because we need 331 * to mark it as needing a NOTIFY ACK on return. 332 */ 333 tmd_notify_t notify; 334 335 MEMZERO(¬ify, sizeof (tmd_notify_t)); 336 notify.nt_hba = isp; 337 notify.nt_iid = INI_ANY; 338 /* nt_tgt set in outer layers */ 339 notify.nt_lun = LUN_ANY; 340 notify.nt_tagval = TAG_ANY; 341 notify.nt_ncode = NT_BUS_RESET; 342 notify.nt_need_ack = 1; 343 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 344 break; 345 } 346 case IN_PORT_LOGOUT: 347 case IN_ABORT_TASK: 348 case IN_PORT_CHANGED: 349 case IN_GLOBAL_LOGO: 350 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local); 351 break; 352 default: 353 isp_prt(isp, ISP_LOGINFO, 354 "isp_target_notify: unknown status (0x%x)", 355 status); 356 isp_notify_ack(isp, local); 357 break; 358 } 359 break; 360 361 case RQSTYPE_NOTIFY_ACK: 362 /* 363 * The ISP is acknowledging our acknowledgement of an 364 * Immediate Notify entry for some asynchronous event. 365 */ 366 if (IS_24XX(isp)) { 367 isp_get_notify_ack_24xx(isp, nack_24xx, 368 (na_fcentry_24xx_t *) local); 369 nack_24xx = (na_fcentry_24xx_t *) local; 370 if (nack_24xx->na_status != NA_OK) { 371 level = ISP_LOGINFO; 372 } else { 373 level = ISP_LOGTDEBUG1; 374 } 375 isp_prt(isp, level, 376 "Notify Ack Status=0x%x; Subcode 0x%x seqid=0x%x", 377 nack_24xx->na_status, nack_24xx->na_status_subcode, 378 nack_24xx->na_rxid); 379 } else if (IS_FC(isp)) { 380 if (FCPARAM(isp)->isp_2klogin) { 381 isp_get_notify_ack_fc_e(isp, nacke_fcp, 382 (na_fcentry_e_t *)local); 383 } else { 384 isp_get_notify_ack_fc(isp, nack_fcp, 385 (na_fcentry_t *)local); 386 } 387 nack_fcp = (na_fcentry_t *)local; 388 if (nack_fcp->na_status != NA_OK) { 389 level = ISP_LOGINFO; 390 } else { 391 level = ISP_LOGTDEBUG1; 392 } 393 isp_prt(isp, level, 394 "Notify Ack Status=0x%x seqid 0x%x", 395 nack_fcp->na_status, nack_fcp->na_seqid); 396 } else { 397 isp_get_notify_ack(isp, nackp, (na_entry_t *)local); 398 nackp = (na_entry_t *)local; 399 if (nackp->na_status != NA_OK) { 400 level = ISP_LOGINFO; 401 } else { 402 level = ISP_LOGTDEBUG1; 403 } 404 isp_prt(isp, level, 405 "Notify Ack event 0x%x status=0x%x seqid 0x%x", 406 nackp->na_event, nackp->na_status, nackp->na_seqid); 407 } 408 break; 409 410 case RQSTYPE_ABTS_RCVD: 411 isp_get_abts(isp, abts, (abts_t *)local); 412 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local); 413 break; 414 case RQSTYPE_ABTS_RSP: 415 isp_get_abts_rsp(isp, abts_rsp, (abts_rsp_t *)local); 416 abts_rsp = (abts_rsp_t *) local; 417 if (abts_rsp->abts_rsp_status) { 418 level = ISP_LOGINFO; 419 } else { 420 level = ISP_LOGTDEBUG0; 421 } 422 isp_prt(isp, level, 423 "ABTS RSP response[0x%x]: status=0x%x sub=(0x%x 0x%x)", 424 abts_rsp->abts_rsp_rxid_task, abts_rsp->abts_rsp_status, 425 abts_rsp->abts_rsp_payload.rsp.subcode1, 426 abts_rsp->abts_rsp_payload.rsp.subcode2); 427 break; 428 default: 429 isp_prt(isp, ISP_LOGERR, 430 "Unknown entry type 0x%x in isp_target_notify", type); 431 rval = 0; 432 break; 433 } 434 #undef atiop 435 #undef at2iop 436 #undef at2eiop 437 #undef at7iop 438 #undef ctiop 439 #undef ct2iop 440 #undef ct2eiop 441 #undef ct7iop 442 #undef lunenp 443 #undef inotp 444 #undef inot_fcp 445 #undef inote_fcp 446 #undef inot_24xx 447 #undef nackp 448 #undef nack_fcp 449 #undef nacke_fcp 450 #undef hack_24xx 451 #undef abts 452 #undef abts_rsp 453 #undef els 454 #undef hdrp 455 return (rval); 456 } 457 458 459 /* 460 * Toggle (on/off) target mode for bus/target/lun 461 * 462 * The caller has checked for overlap and legality. 463 * 464 * Note that not all of bus, target or lun can be paid attention to. 465 * Note also that this action will not be complete until the f/w writes 466 * response entry. The caller is responsible for synchronizing this. 467 */ 468 int 469 isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int tgt, int lun, 470 int cmd_cnt, int inot_cnt, uint32_t opaque) 471 { 472 lun_entry_t el; 473 uint32_t nxti, optr; 474 void *outp; 475 476 477 MEMZERO(&el, sizeof (el)); 478 if (IS_DUALBUS(isp)) { 479 el.le_rsvd = (bus & 0x1) << 7; 480 } 481 el.le_cmd_count = cmd_cnt; 482 el.le_in_count = inot_cnt; 483 if (cmd == RQSTYPE_ENABLE_LUN) { 484 if (IS_SCSI(isp)) { 485 el.le_flags = LUN_TQAE|LUN_DISAD; 486 el.le_cdb6len = 12; 487 el.le_cdb7len = 12; 488 } 489 } else if (cmd == -RQSTYPE_ENABLE_LUN) { 490 cmd = RQSTYPE_ENABLE_LUN; 491 el.le_cmd_count = 0; 492 el.le_in_count = 0; 493 } else if (cmd == -RQSTYPE_MODIFY_LUN) { 494 cmd = RQSTYPE_MODIFY_LUN; 495 el.le_ops = LUN_CCDECR | LUN_INDECR; 496 } else { 497 el.le_ops = LUN_CCINCR | LUN_ININCR; 498 } 499 el.le_header.rqs_entry_type = cmd; 500 el.le_header.rqs_entry_count = 1; 501 el.le_reserved = opaque; 502 if (IS_SCSI(isp)) { 503 el.le_tgt = tgt; 504 el.le_lun = lun; 505 } else if (FCPARAM(isp)->isp_sccfw == 0) { 506 el.le_lun = lun; 507 } 508 el.le_timeout = 30; 509 510 if (isp_getrqentry(isp, &nxti, &optr, &outp)) { 511 isp_prt(isp, ISP_LOGERR, 512 "Request Queue Overflow in isp_lun_cmd"); 513 return (-1); 514 } 515 ISP_TDQE(isp, "isp_lun_cmd", (int) optr, &el); 516 isp_put_enable_lun(isp, &el, outp); 517 ISP_ADD_REQUEST(isp, nxti); 518 return (0); 519 } 520 521 522 int 523 isp_target_put_entry(ispsoftc_t *isp, void *ap) 524 { 525 void *outp; 526 uint32_t nxti, optr; 527 uint8_t etype = ((isphdr_t *) ap)->rqs_entry_type; 528 529 if (isp_getrqentry(isp, &nxti, &optr, &outp)) { 530 isp_prt(isp, ISP_LOGWARN, 531 "Request Queue Overflow in isp_target_put_entry"); 532 return (-1); 533 } 534 switch (etype) { 535 case RQSTYPE_ATIO: 536 isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp); 537 break; 538 case RQSTYPE_ATIO2: 539 if (FCPARAM(isp)->isp_2klogin) { 540 isp_put_atio2e(isp, (at2e_entry_t *) ap, 541 (at2e_entry_t *) outp); 542 } else { 543 isp_put_atio2(isp, (at2_entry_t *) ap, 544 (at2_entry_t *) outp); 545 } 546 break; 547 case RQSTYPE_CTIO: 548 isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp); 549 break; 550 case RQSTYPE_CTIO2: 551 if (FCPARAM(isp)->isp_2klogin) { 552 isp_put_ctio2e(isp, (ct2e_entry_t *) ap, 553 (ct2e_entry_t *) outp); 554 } else { 555 isp_put_ctio2(isp, (ct2_entry_t *) ap, 556 (ct2_entry_t *) outp); 557 } 558 break; 559 case RQSTYPE_CTIO7: 560 isp_put_ctio7(isp, (ct7_entry_t *) ap, (ct7_entry_t *) outp); 561 break; 562 default: 563 isp_prt(isp, ISP_LOGERR, 564 "Unknown type 0x%x in isp_put_entry", etype); 565 return (-1); 566 } 567 ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap); 568 ISP_ADD_REQUEST(isp, nxti); 569 return (0); 570 } 571 572 int 573 isp_target_put_atio(ispsoftc_t *isp, void *arg) 574 { 575 union { 576 at_entry_t _atio; 577 at2_entry_t _atio2; 578 at2e_entry_t _atio2e; 579 } atun; 580 581 MEMZERO(&atun, sizeof atun); 582 if (IS_FC(isp)) { 583 at2_entry_t *aep = arg; 584 atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2; 585 atun._atio2.at_header.rqs_entry_count = 1; 586 if (FCPARAM(isp)->isp_sccfw) { 587 atun._atio2.at_scclun = aep->at_scclun; 588 } else { 589 atun._atio2.at_lun = (uint8_t) aep->at_lun; 590 } 591 if (FCPARAM(isp)->isp_2klogin) { 592 atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid; 593 } else { 594 atun._atio2.at_iid = aep->at_iid; 595 } 596 atun._atio2.at_rxid = aep->at_rxid; 597 atun._atio2.at_status = CT_OK; 598 } else { 599 at_entry_t *aep = arg; 600 atun._atio.at_header.rqs_entry_type = RQSTYPE_ATIO; 601 atun._atio.at_header.rqs_entry_count = 1; 602 atun._atio.at_handle = aep->at_handle; 603 atun._atio.at_iid = aep->at_iid; 604 atun._atio.at_tgt = aep->at_tgt; 605 atun._atio.at_lun = aep->at_lun; 606 atun._atio.at_tag_type = aep->at_tag_type; 607 atun._atio.at_tag_val = aep->at_tag_val; 608 atun._atio.at_status = (aep->at_flags & AT_TQAE); 609 atun._atio.at_status |= CT_OK; 610 } 611 return (isp_target_put_entry(isp, &atun)); 612 } 613 614 /* 615 * Command completion- both for handling cases of no resources or 616 * no blackhole driver, or other cases where we have to, inline, 617 * finish the command sanely, or for normal command completion. 618 * 619 * The 'completion' code value has the scsi status byte in the low 8 bits. 620 * If status is a CHECK CONDITION and bit 8 is nonzero, then bits 12..15 have 621 * the sense key and bits 16..23 have the ASCQ and bits 24..31 have the ASC 622 * values. 623 * 624 * NB: the key, asc, ascq, cannot be used for parallel SCSI as it doesn't 625 * NB: inline SCSI sense reporting. As such, we lose this information. XXX. 626 * 627 * For both parallel && fibre channel, we use the feature that does 628 * an automatic resource autoreplenish so we don't have then later do 629 * put of an atio to replenish the f/w's resource count. 630 */ 631 632 int 633 isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint32_t hdl) 634 { 635 int sts; 636 union { 637 ct_entry_t _ctio; 638 ct2_entry_t _ctio2; 639 ct2e_entry_t _ctio2e; 640 ct7_entry_t _ctio7; 641 } un; 642 643 MEMZERO(&un, sizeof un); 644 sts = code & 0xff; 645 646 if (IS_24XX(isp)) { 647 at7_entry_t *aep = arg; 648 ct7_entry_t *cto = &un._ctio7; 649 650 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; 651 cto->ct_header.rqs_entry_count = 1; 652 /* XXXX */ cto->ct_nphdl = aep->at_hdr.seq_id; 653 cto->ct_rxid = aep->at_rxid; 654 cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) | 655 aep->at_hdr.s_id[2]; 656 cto->ct_iid_hi = aep->at_hdr.s_id[0]; 657 cto->ct_oxid = aep->at_hdr.ox_id; 658 cto->ct_scsi_status = sts; 659 cto->ct_flags = CT7_FLAG_MODE1 | CT7_NO_DATA | CT7_SENDSTATUS; 660 if (sts == SCSI_CHECK && (code & ECMD_SVALID)) { 661 cto->rsp.m1.ct_resplen = 16; 662 cto->rsp.m1.ct_resp[0] = 0xf0; 663 cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf; 664 cto->rsp.m1.ct_resp[7] = 8; 665 cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff; 666 cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff; 667 } 668 if (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl) { 669 cto->ct_resid = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl; 670 cto->ct_scsi_status |= CT2_DATA_UNDER; 671 } 672 cto->ct_syshandle = hdl; 673 } else if (IS_FC(isp)) { 674 at2_entry_t *aep = arg; 675 ct2_entry_t *cto = &un._ctio2; 676 677 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2; 678 cto->ct_header.rqs_entry_count = 1; 679 if (FCPARAM(isp)->isp_sccfw == 0) { 680 cto->ct_lun = aep->at_lun; 681 } 682 if (FCPARAM(isp)->isp_2klogin) { 683 un._ctio2e.ct_iid = ((at2e_entry_t *)aep)->at_iid; 684 } else { 685 cto->ct_iid = aep->at_iid; 686 } 687 cto->ct_rxid = aep->at_rxid; 688 cto->rsp.m1.ct_scsi_status = sts; 689 cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1; 690 if (hdl == 0) { 691 cto->ct_flags |= CT2_CCINCR; 692 } 693 if (aep->at_datalen) { 694 cto->ct_resid = aep->at_datalen; 695 cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER; 696 } 697 if (sts == SCSI_CHECK && (code & ECMD_SVALID)) { 698 cto->rsp.m1.ct_resp[0] = 0xf0; 699 cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf; 700 cto->rsp.m1.ct_resp[7] = 8; 701 cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff; 702 cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff; 703 cto->rsp.m1.ct_senselen = 16; 704 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID; 705 } 706 cto->ct_syshandle = hdl; 707 } else { 708 at_entry_t *aep = arg; 709 ct_entry_t *cto = &un._ctio; 710 711 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO; 712 cto->ct_header.rqs_entry_count = 1; 713 cto->ct_fwhandle = aep->at_handle; 714 cto->ct_iid = aep->at_iid; 715 cto->ct_tgt = aep->at_tgt; 716 cto->ct_lun = aep->at_lun; 717 cto->ct_tag_type = aep->at_tag_type; 718 cto->ct_tag_val = aep->at_tag_val; 719 if (aep->at_flags & AT_TQAE) { 720 cto->ct_flags |= CT_TQAE; 721 } 722 cto->ct_flags = CT_SENDSTATUS | CT_NO_DATA; 723 if (hdl == 0) { 724 cto->ct_flags |= CT_CCINCR; 725 } 726 cto->ct_scsi_status = sts; 727 cto->ct_syshandle = hdl; 728 } 729 return (isp_target_put_entry(isp, &un)); 730 } 731 732 /* 733 * These are either broadcast events or specifically CTIO fast completion 734 */ 735 int 736 isp_target_async(ispsoftc_t *isp, int bus, int event) 737 { 738 tmd_notify_t notify; 739 740 MEMZERO(¬ify, sizeof (tmd_notify_t)); 741 notify.nt_hba = isp; 742 notify.nt_iid = INI_ANY; 743 /* nt_tgt set in outer layers */ 744 notify.nt_lun = LUN_ANY; 745 notify.nt_tagval = TAG_ANY; 746 747 if (IS_SCSI(isp)) { 748 TAG_INSERT_BUS(notify.nt_tagval, bus); 749 } 750 751 switch (event) { 752 case ASYNC_LOOP_UP: 753 case ASYNC_PTPMODE: 754 notify.nt_ncode = NT_LINK_UP; 755 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 756 break; 757 case ASYNC_LOOP_DOWN: 758 notify.nt_ncode = NT_LINK_DOWN; 759 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 760 break; 761 case ASYNC_LIP_ERROR: 762 case ASYNC_LIP_F8: 763 case ASYNC_LIP_OCCURRED: 764 case ASYNC_LOOP_RESET: 765 notify.nt_ncode = NT_LIP_RESET; 766 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 767 break; 768 case ASYNC_BUS_RESET: 769 case ASYNC_TIMEOUT_RESET: /* XXX: where does this come from ? */ 770 notify.nt_ncode = NT_BUS_RESET; 771 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 772 break; 773 case ASYNC_DEVICE_RESET: 774 notify.nt_ncode = NT_TARGET_RESET; 775 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 776 break; 777 case ASYNC_CTIO_DONE: 778 { 779 uint8_t storage[QENTRY_LEN]; 780 memset(storage, 0, QENTRY_LEN); 781 if (IS_24XX(isp)) { 782 ct7_entry_t *ct = (ct7_entry_t *) storage; 783 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO7; 784 ct->ct_nphdl = CT7_OK; 785 ct->ct_syshandle = bus; 786 ct->ct_flags = CT7_SENDSTATUS|CT7_FASTPOST; 787 } else if (IS_FC(isp)) { 788 /* This should also suffice for 2K login code */ 789 ct2_entry_t *ct = (ct2_entry_t *) storage; 790 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO2; 791 ct->ct_status = CT_OK; 792 ct->ct_syshandle = bus; 793 ct->ct_flags = CT2_SENDSTATUS|CT2_FASTPOST; 794 } else { 795 ct_entry_t *ct = (ct_entry_t *) storage; 796 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO; 797 ct->ct_status = CT_OK; 798 ct->ct_fwhandle = bus; 799 ct->ct_flags = CT_SENDSTATUS; 800 } 801 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, storage); 802 break; 803 } 804 default: 805 isp_prt(isp, ISP_LOGERR, 806 "isp_target_async: unknown event 0x%x", event); 807 if (isp->isp_state == ISP_RUNSTATE) { 808 isp_notify_ack(isp, NULL); 809 } 810 break; 811 } 812 return (0); 813 } 814 815 816 /* 817 * Process a received message. 818 * The ISP firmware can handle most messages, there are only 819 * a few that we need to deal with: 820 * - abort: clean up the current command 821 * - abort tag and clear queue 822 */ 823 824 static void 825 isp_got_msg(ispsoftc_t *isp, in_entry_t *inp) 826 { 827 tmd_notify_t nt; 828 uint8_t status = inp->in_status & ~QLTM_SVALID; 829 830 MEMZERO(&nt, sizeof (nt)); 831 nt.nt_hba = isp; 832 nt.nt_iid = GET_IID_VAL(inp->in_iid); 833 nt.nt_tgt = inp->in_tgt; 834 nt.nt_lun = inp->in_lun; 835 IN_MAKE_TAGID(nt.nt_tagval, GET_BUS_VAL(inp->in_iid), 0, inp); 836 nt.nt_lreserved = inp; 837 838 if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) { 839 switch (inp->in_msg[0]) { 840 case MSG_ABORT: 841 nt.nt_ncode = NT_ABORT_TASK_SET; 842 break; 843 case MSG_BUS_DEV_RESET: 844 nt.nt_ncode = NT_TARGET_RESET; 845 break; 846 case MSG_ABORT_TAG: 847 nt.nt_ncode = NT_ABORT_TASK; 848 break; 849 case MSG_CLEAR_QUEUE: 850 nt.nt_ncode = NT_CLEAR_TASK_SET; 851 break; 852 case MSG_REL_RECOVERY: 853 nt.nt_ncode = NT_CLEAR_ACA; 854 break; 855 case MSG_TERM_IO_PROC: 856 nt.nt_ncode = NT_ABORT_TASK; 857 break; 858 case MSG_LUN_RESET: 859 nt.nt_ncode = NT_LUN_RESET; 860 break; 861 default: 862 isp_prt(isp, ISP_LOGERR, 863 "unhandled message 0x%x", inp->in_msg[0]); 864 isp_notify_ack(isp, inp); 865 return; 866 } 867 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt); 868 } else { 869 isp_prt(isp, ISP_LOGERR, 870 "unknown immediate notify status 0x%x", inp->in_status); 871 isp_notify_ack(isp, inp); 872 } 873 } 874 875 /* 876 * Synthesize a message from the task management flags in a FCP_CMND_IU. 877 */ 878 static void 879 isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp) 880 { 881 tmd_notify_t nt; 882 static const char f1[] = "%s from N-port handle 0x%x lun %d seq 0x%x"; 883 static const char f2[] = "unknown %s 0x%x lun %d N-Port handle 0x%x " 884 "task flags 0x%x seq 0x%x\n"; 885 uint16_t seqid, loopid; 886 887 MEMZERO(&nt, sizeof (tmd_notify_t)); 888 nt.nt_hba = isp; 889 if (FCPARAM(isp)->isp_2klogin) { 890 nt.nt_iid = ((in_fcentry_e_t *)inp)->in_iid; 891 loopid = ((in_fcentry_e_t *)inp)->in_iid; 892 seqid = ((in_fcentry_e_t *)inp)->in_seqid; 893 } else { 894 nt.nt_iid = inp->in_iid; 895 loopid = inp->in_iid; 896 seqid = inp->in_seqid; 897 } 898 /* nt_tgt set in outer layers */ 899 if (FCPARAM(isp)->isp_sccfw) { 900 nt.nt_lun = inp->in_scclun; 901 } else { 902 nt.nt_lun = inp->in_lun; 903 } 904 IN_FC_MAKE_TAGID(nt.nt_tagval, 0, 0, seqid); 905 nt.nt_need_ack = 1; 906 nt.nt_lreserved = inp; 907 908 if (inp->in_status != IN_MSG_RECEIVED) { 909 isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status", 910 inp->in_status, nt.nt_lun, loopid, inp->in_task_flags, 911 inp->in_seqid); 912 isp_notify_ack(isp, inp); 913 return; 914 } 915 916 if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) { 917 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", 918 loopid, nt.nt_lun, inp->in_seqid); 919 nt.nt_ncode = NT_ABORT_TASK_SET; 920 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) { 921 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", 922 loopid, nt.nt_lun, inp->in_seqid); 923 nt.nt_ncode = NT_CLEAR_TASK_SET; 924 } else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) { 925 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", 926 loopid, nt.nt_lun, inp->in_seqid); 927 nt.nt_ncode = NT_LUN_RESET; 928 } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) { 929 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", 930 loopid, nt.nt_lun, inp->in_seqid); 931 nt.nt_ncode = NT_TARGET_RESET; 932 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) { 933 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", 934 loopid, nt.nt_lun, inp->in_seqid); 935 nt.nt_ncode = NT_CLEAR_ACA; 936 } else { 937 isp_prt(isp, ISP_LOGWARN, f2, "task flag", inp->in_status, 938 nt.nt_lun, loopid, inp->in_task_flags, inp->in_seqid); 939 isp_notify_ack(isp, inp); 940 return; 941 } 942 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt); 943 } 944 945 #define HILO(x) (uint32_t) (x >> 32), (uint32_t) x 946 static void 947 isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep) 948 { 949 tmd_notify_t nt; 950 static const char f1[] = 951 "%s from PortID 0x%06x lun %d seq 0x%08x%08x"; 952 static const char f2[] = 953 "unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%08x%08x"; 954 uint32_t sid; 955 956 MEMZERO(&nt, sizeof (tmd_notify_t)); 957 nt.nt_hba = isp; 958 nt.nt_iid = INI_ANY; 959 nt.nt_lun = 960 (aep->at_cmnd.fcp_cmnd_lun[0] << 8) | 961 (aep->at_cmnd.fcp_cmnd_lun[1]); 962 /* 963 * XXX: VPIDX HAS TO BE DERIVED FROM DESTINATION PORT 964 */ 965 nt.nt_tagval = aep->at_rxid; 966 nt.nt_lreserved = aep; 967 sid = 968 (aep->at_hdr.s_id[0] << 16) | 969 (aep->at_hdr.s_id[1] << 8) | 970 (aep->at_hdr.s_id[2]); 971 972 if (aep->at_cmnd.fcp_cmnd_task_management & 973 FCP_CMND_TMF_ABORT_TASK_SET) { 974 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", 975 sid, nt.nt_lun, HILO(nt.nt_tagval)); 976 nt.nt_ncode = NT_ABORT_TASK_SET; 977 } else if (aep->at_cmnd.fcp_cmnd_task_management & 978 FCP_CMND_TMF_CLEAR_TASK_SET) { 979 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", 980 sid, nt.nt_lun, HILO(nt.nt_tagval)); 981 nt.nt_ncode = NT_CLEAR_TASK_SET; 982 } else if (aep->at_cmnd.fcp_cmnd_task_management & 983 FCP_CMND_TMF_LUN_RESET) { 984 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", 985 sid, nt.nt_lun, HILO(nt.nt_tagval)); 986 nt.nt_ncode = NT_LUN_RESET; 987 } else if (aep->at_cmnd.fcp_cmnd_task_management & 988 FCP_CMND_TMF_TGT_RESET) { 989 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", 990 sid, nt.nt_lun, HILO(nt.nt_tagval)); 991 nt.nt_ncode = NT_TARGET_RESET; 992 nt.nt_lun = LUN_ANY; 993 } else if (aep->at_cmnd.fcp_cmnd_task_management & 994 FCP_CMND_TMF_CLEAR_ACA) { 995 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", 996 sid, nt.nt_lun, HILO(nt.nt_tagval)); 997 nt.nt_ncode = NT_CLEAR_ACA; 998 } else { 999 isp_prt(isp, ISP_LOGWARN, f2, 1000 aep->at_cmnd.fcp_cmnd_task_management, 1001 nt.nt_lun, sid, HILO(nt.nt_tagval)); 1002 isp_endcmd(isp, aep, 0, 0); 1003 return; 1004 } 1005 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt); 1006 } 1007 1008 void 1009 isp_notify_ack(ispsoftc_t *isp, void *arg) 1010 { 1011 char storage[QENTRY_LEN]; 1012 uint32_t nxti, optr; 1013 void *outp; 1014 1015 if (isp_getrqentry(isp, &nxti, &optr, &outp)) { 1016 isp_prt(isp, ISP_LOGWARN, 1017 "Request Queue Overflow For isp_notify_ack"); 1018 return; 1019 } 1020 1021 MEMZERO(storage, QENTRY_LEN); 1022 1023 if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) { 1024 at7_entry_t *aep = arg; 1025 isp_endcmd(isp, aep, 0, 0); 1026 return; 1027 } else if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ABTS_RSP)) { 1028 abts_rsp_t *abts_rsp = (abts_rsp_t *) storage; 1029 /* 1030 * The caller will have set response values as appropriate 1031 * in the ABTS structure just before calling us. 1032 */ 1033 MEMCPY(abts_rsp, arg, QENTRY_LEN); 1034 isp_put_abts_rsp(isp, abts_rsp, (abts_rsp_t *)outp); 1035 } else if (IS_24XX(isp)) { 1036 na_fcentry_24xx_t *na = (na_fcentry_24xx_t *) storage; 1037 if (arg) { 1038 in_fcentry_24xx_t *in = arg; 1039 na->na_nphdl = in->in_nphdl; 1040 na->na_status = in->in_status; 1041 na->na_status_subcode = in->in_status_subcode; 1042 na->na_rxid = in->in_rxid; 1043 na->na_oxid = in->in_oxid; 1044 if (in->in_status == IN24XX_SRR_RCVD) { 1045 na->na_srr_rxid = in->in_srr_rxid; 1046 na->na_srr_reloff_hi = in->in_srr_reloff_hi; 1047 na->na_srr_reloff_lo = in->in_srr_reloff_lo; 1048 na->na_srr_iu = in->in_srr_iu; 1049 na->na_srr_flags = 1; 1050 na->na_srr_reject_vunique = 0; 1051 na->na_srr_reject_explanation = 1; 1052 na->na_srr_reject_code = 1; 1053 } 1054 } 1055 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; 1056 na->na_header.rqs_entry_count = 1; 1057 isp_put_notify_24xx_ack(isp, na, (na_fcentry_24xx_t *)outp); 1058 } else if (IS_FC(isp)) { 1059 na_fcentry_t *na = (na_fcentry_t *) storage; 1060 int iid = 0; 1061 1062 if (arg) { 1063 in_fcentry_t *inp = arg; 1064 MEMCPY(storage, arg, sizeof (isphdr_t)); 1065 if (FCPARAM(isp)->isp_2klogin) { 1066 ((na_fcentry_e_t *)na)->na_iid = 1067 ((in_fcentry_e_t *)inp)->in_iid; 1068 iid = ((na_fcentry_e_t *)na)->na_iid; 1069 } else { 1070 na->na_iid = inp->in_iid; 1071 iid = na->na_iid; 1072 } 1073 na->na_task_flags = 1074 inp->in_task_flags & TASK_FLAGS_RESERVED_MASK; 1075 na->na_seqid = inp->in_seqid; 1076 na->na_flags = NAFC_RCOUNT; 1077 na->na_status = inp->in_status; 1078 if (inp->in_status == IN_RESET) { 1079 na->na_flags |= NAFC_RST_CLRD; 1080 } 1081 if (inp->in_status == IN_MSG_RECEIVED) { 1082 na->na_flags |= NAFC_TVALID; 1083 na->na_response = 0; /* XXX SUCCEEDED XXX */ 1084 } 1085 } else { 1086 na->na_flags = NAFC_RST_CLRD; 1087 } 1088 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; 1089 na->na_header.rqs_entry_count = 1; 1090 if (FCPARAM(isp)->isp_2klogin) { 1091 isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na, 1092 (na_fcentry_e_t *)outp); 1093 } else { 1094 isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp); 1095 } 1096 isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u seqid %x " 1097 "flags %x tflags %x response %x", iid, na->na_seqid, 1098 na->na_flags, na->na_task_flags, na->na_response); 1099 } else { 1100 na_entry_t *na = (na_entry_t *) storage; 1101 if (arg) { 1102 in_entry_t *inp = arg; 1103 MEMCPY(storage, arg, sizeof (isphdr_t)); 1104 na->na_iid = inp->in_iid; 1105 na->na_lun = inp->in_lun; 1106 na->na_tgt = inp->in_tgt; 1107 na->na_seqid = inp->in_seqid; 1108 if (inp->in_status == IN_RESET) { 1109 na->na_event = NA_RST_CLRD; 1110 } 1111 } else { 1112 na->na_event = NA_RST_CLRD; 1113 } 1114 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; 1115 na->na_header.rqs_entry_count = 1; 1116 isp_put_notify_ack(isp, na, (na_entry_t *)outp); 1117 isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u lun %u tgt " 1118 "%u seqid %x event %x", na->na_iid, na->na_lun, na->na_tgt, 1119 na->na_seqid, na->na_event); 1120 } 1121 ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage); 1122 ISP_ADD_REQUEST(isp, nxti); 1123 } 1124 1125 static void 1126 isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep) 1127 { 1128 int lun; 1129 lun = aep->at_lun; 1130 /* 1131 * The firmware status (except for the QLTM_SVALID bit) indicates 1132 * why this ATIO was sent to us. 1133 * 1134 * If QLTM_SVALID is set, the firware has recommended Sense Data. 1135 * 1136 * If the DISCONNECTS DISABLED bit is set in the flags field, 1137 * we're still connected on the SCSI bus - i.e. the initiator 1138 * did not set DiscPriv in the identify message. We don't care 1139 * about this so it's ignored. 1140 */ 1141 1142 switch(aep->at_status & ~QLTM_SVALID) { 1143 case AT_PATH_INVALID: 1144 /* 1145 * ATIO rejected by the firmware due to disabled lun. 1146 */ 1147 isp_prt(isp, ISP_LOGERR, 1148 "rejected ATIO for disabled lun %d", lun); 1149 break; 1150 case AT_NOCAP: 1151 /* 1152 * Requested Capability not available 1153 * We sent an ATIO that overflowed the firmware's 1154 * command resource count. 1155 */ 1156 isp_prt(isp, ISP_LOGERR, 1157 "rejected ATIO for lun %d because of command count" 1158 " overflow", lun); 1159 break; 1160 1161 case AT_BDR_MSG: 1162 /* 1163 * If we send an ATIO to the firmware to increment 1164 * its command resource count, and the firmware is 1165 * recovering from a Bus Device Reset, it returns 1166 * the ATIO with this status. We set the command 1167 * resource count in the Enable Lun entry and do 1168 * not increment it. Therefore we should never get 1169 * this status here. 1170 */ 1171 isp_prt(isp, ISP_LOGERR, atiocope, lun, 1172 GET_BUS_VAL(aep->at_iid)); 1173 break; 1174 1175 case AT_CDB: /* Got a CDB */ 1176 case AT_PHASE_ERROR: /* Bus Phase Sequence Error */ 1177 /* 1178 * Punt to platform specific layer. 1179 */ 1180 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep); 1181 break; 1182 1183 case AT_RESET: 1184 /* 1185 * A bus reset came along and blew away this command. Why 1186 * they do this in addition the async event code stuff, 1187 * I dunno. 1188 * 1189 * Ignore it because the async event will clear things 1190 * up for us. 1191 */ 1192 isp_prt(isp, ISP_LOGWARN, atior, lun, 1193 GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid)); 1194 break; 1195 1196 1197 default: 1198 isp_prt(isp, ISP_LOGERR, 1199 "Unknown ATIO status 0x%x from loopid %d for lun %d", 1200 aep->at_status, aep->at_iid, lun); 1201 (void) isp_target_put_atio(isp, aep); 1202 break; 1203 } 1204 } 1205 1206 static void 1207 isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep) 1208 { 1209 int lun, iid; 1210 1211 if (FCPARAM(isp)->isp_sccfw) { 1212 lun = aep->at_scclun; 1213 } else { 1214 lun = aep->at_lun; 1215 } 1216 1217 if (FCPARAM(isp)->isp_2klogin) { 1218 iid = ((at2e_entry_t *)aep)->at_iid; 1219 } else { 1220 iid = aep->at_iid; 1221 } 1222 1223 /* 1224 * The firmware status (except for the QLTM_SVALID bit) indicates 1225 * why this ATIO was sent to us. 1226 * 1227 * If QLTM_SVALID is set, the firware has recommended Sense Data. 1228 * 1229 * If the DISCONNECTS DISABLED bit is set in the flags field, 1230 * we're still connected on the SCSI bus - i.e. the initiator 1231 * did not set DiscPriv in the identify message. We don't care 1232 * about this so it's ignored. 1233 */ 1234 1235 switch(aep->at_status & ~QLTM_SVALID) { 1236 case AT_PATH_INVALID: 1237 /* 1238 * ATIO rejected by the firmware due to disabled lun. 1239 */ 1240 isp_prt(isp, ISP_LOGERR, 1241 "rejected ATIO2 for disabled lun %d", lun); 1242 break; 1243 case AT_NOCAP: 1244 /* 1245 * Requested Capability not available 1246 * We sent an ATIO that overflowed the firmware's 1247 * command resource count. 1248 */ 1249 isp_prt(isp, ISP_LOGERR, 1250 "rejected ATIO2 for lun %d- command count overflow", lun); 1251 break; 1252 1253 case AT_BDR_MSG: 1254 /* 1255 * If we send an ATIO to the firmware to increment 1256 * its command resource count, and the firmware is 1257 * recovering from a Bus Device Reset, it returns 1258 * the ATIO with this status. We set the command 1259 * resource count in the Enable Lun entry and no 1260 * not increment it. Therefore we should never get 1261 * this status here. 1262 */ 1263 isp_prt(isp, ISP_LOGERR, atiocope, lun, 0); 1264 break; 1265 1266 case AT_CDB: /* Got a CDB */ 1267 /* 1268 * Punt to platform specific layer. 1269 */ 1270 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep); 1271 break; 1272 1273 case AT_RESET: 1274 /* 1275 * A bus reset came along an blew away this command. Why 1276 * they do this in addition the async event code stuff, 1277 * I dunno. 1278 * 1279 * Ignore it because the async event will clear things 1280 * up for us. 1281 */ 1282 isp_prt(isp, ISP_LOGERR, atior, lun, iid, 0); 1283 break; 1284 1285 1286 default: 1287 isp_prt(isp, ISP_LOGERR, 1288 "Unknown ATIO2 status 0x%x from loopid %d for lun %d", 1289 aep->at_status, iid, lun); 1290 (void) isp_target_put_atio(isp, aep); 1291 break; 1292 } 1293 } 1294 1295 static void 1296 isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct) 1297 { 1298 void *xs; 1299 int pl = ISP_LOGTDEBUG2; 1300 char *fmsg = NULL; 1301 1302 if (ct->ct_syshandle) { 1303 xs = isp_find_xs_tgt(isp, ct->ct_syshandle); 1304 if (xs == NULL) { 1305 pl = ISP_LOGALL; 1306 } 1307 } else { 1308 xs = NULL; 1309 } 1310 1311 switch(ct->ct_status & ~QLTM_SVALID) { 1312 case CT_OK: 1313 /* 1314 * There are generally 3 possibilities as to why we'd get 1315 * this condition: 1316 * We disconnected after receiving a CDB. 1317 * We sent or received data. 1318 * We sent status & command complete. 1319 */ 1320 1321 if (ct->ct_flags & CT_SENDSTATUS) { 1322 break; 1323 } else if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) { 1324 /* 1325 * Nothing to do in this case. 1326 */ 1327 isp_prt(isp, pl, "CTIO- iid %d disconnected OK", 1328 ct->ct_iid); 1329 return; 1330 } 1331 break; 1332 1333 case CT_BDR_MSG: 1334 /* 1335 * Bus Device Reset message received or the SCSI Bus has 1336 * been Reset; the firmware has gone to Bus Free. 1337 * 1338 * The firmware generates an async mailbox interupt to 1339 * notify us of this and returns outstanding CTIOs with this 1340 * status. These CTIOs are handled in that same way as 1341 * CT_ABORTED ones, so just fall through here. 1342 */ 1343 fmsg = "Bus Device Reset"; 1344 /*FALLTHROUGH*/ 1345 case CT_RESET: 1346 if (fmsg == NULL) 1347 fmsg = "Bus Reset"; 1348 /*FALLTHROUGH*/ 1349 case CT_ABORTED: 1350 /* 1351 * When an Abort message is received the firmware goes to 1352 * Bus Free and returns all outstanding CTIOs with the status 1353 * set, then sends us an Immediate Notify entry. 1354 */ 1355 if (fmsg == NULL) 1356 fmsg = "ABORT TAG message sent by Initiator"; 1357 1358 isp_prt(isp, ISP_LOGTDEBUG0, "CTIO destroyed by %s", fmsg); 1359 break; 1360 1361 case CT_INVAL: 1362 /* 1363 * CTIO rejected by the firmware due to disabled lun. 1364 * "Cannot Happen". 1365 */ 1366 isp_prt(isp, ISP_LOGERR, 1367 "Firmware rejected CTIO for disabled lun %d", 1368 ct->ct_lun); 1369 break; 1370 1371 case CT_NOPATH: 1372 /* 1373 * CTIO rejected by the firmware due "no path for the 1374 * nondisconnecting nexus specified". This means that 1375 * we tried to access the bus while a non-disconnecting 1376 * command is in process. 1377 */ 1378 isp_prt(isp, ISP_LOGERR, 1379 "Firmware rejected CTIO for bad nexus %d/%d/%d", 1380 ct->ct_iid, ct->ct_tgt, ct->ct_lun); 1381 break; 1382 1383 case CT_RSELTMO: 1384 fmsg = "Reselection"; 1385 /*FALLTHROUGH*/ 1386 case CT_TIMEOUT: 1387 if (fmsg == NULL) 1388 fmsg = "Command"; 1389 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg); 1390 break; 1391 1392 case CT_PANIC: 1393 if (fmsg == NULL) 1394 fmsg = "Unrecoverable Error"; 1395 /*FALLTHROUGH*/ 1396 case CT_ERR: 1397 if (fmsg == NULL) 1398 fmsg = "Completed with Error"; 1399 /*FALLTHROUGH*/ 1400 case CT_PHASE_ERROR: 1401 if (fmsg == NULL) 1402 fmsg = "Phase Sequence Error"; 1403 /*FALLTHROUGH*/ 1404 case CT_TERMINATED: 1405 if (fmsg == NULL) 1406 fmsg = "terminated by TERMINATE TRANSFER"; 1407 /*FALLTHROUGH*/ 1408 case CT_NOACK: 1409 if (fmsg == NULL) 1410 fmsg = "unacknowledged Immediate Notify pending"; 1411 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg); 1412 break; 1413 default: 1414 isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x", 1415 ct->ct_status & ~QLTM_SVALID); 1416 break; 1417 } 1418 1419 if (xs == NULL) { 1420 /* 1421 * There may be more than one CTIO for a data transfer, 1422 * or this may be a status CTIO we're not monitoring. 1423 * 1424 * The assumption is that they'll all be returned in the 1425 * order we got them. 1426 */ 1427 if (ct->ct_syshandle == 0) { 1428 if ((ct->ct_flags & CT_SENDSTATUS) == 0) { 1429 isp_prt(isp, pl, 1430 "intermediate CTIO completed ok"); 1431 } else { 1432 isp_prt(isp, pl, 1433 "unmonitored CTIO completed ok"); 1434 } 1435 } else { 1436 isp_prt(isp, pl, 1437 "NO xs for CTIO (handle 0x%x) status 0x%x", 1438 ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID); 1439 } 1440 } else { 1441 /* 1442 * Final CTIO completed. Release DMA resources and 1443 * notify platform dependent layers. 1444 */ 1445 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) { 1446 ISP_DMAFREE(isp, xs, ct->ct_syshandle); 1447 } 1448 isp_prt(isp, pl, "final CTIO complete"); 1449 /* 1450 * The platform layer will destroy the handle if appropriate. 1451 */ 1452 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct); 1453 } 1454 } 1455 1456 static void 1457 isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct) 1458 { 1459 void *xs; 1460 int pl = ISP_LOGTDEBUG2; 1461 char *fmsg = NULL; 1462 1463 if (ct->ct_syshandle) { 1464 xs = isp_find_xs_tgt(isp, ct->ct_syshandle); 1465 if (xs == NULL) { 1466 pl = ISP_LOGALL; 1467 } 1468 } else { 1469 xs = NULL; 1470 } 1471 1472 switch(ct->ct_status & ~QLTM_SVALID) { 1473 case CT_BUS_ERROR: 1474 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error"); 1475 /* FALL Through */ 1476 case CT_DATA_OVER: 1477 case CT_DATA_UNDER: 1478 case CT_OK: 1479 /* 1480 * There are generally 2 possibilities as to why we'd get 1481 * this condition: 1482 * We sent or received data. 1483 * We sent status & command complete. 1484 */ 1485 1486 break; 1487 1488 case CT_BDR_MSG: 1489 /* 1490 * Target Reset function received. 1491 * 1492 * The firmware generates an async mailbox interupt to 1493 * notify us of this and returns outstanding CTIOs with this 1494 * status. These CTIOs are handled in that same way as 1495 * CT_ABORTED ones, so just fall through here. 1496 */ 1497 fmsg = "TARGET RESET"; 1498 /*FALLTHROUGH*/ 1499 case CT_RESET: 1500 if (fmsg == NULL) 1501 fmsg = "LIP Reset"; 1502 /*FALLTHROUGH*/ 1503 case CT_ABORTED: 1504 /* 1505 * When an Abort message is received the firmware goes to 1506 * Bus Free and returns all outstanding CTIOs with the status 1507 * set, then sends us an Immediate Notify entry. 1508 */ 1509 if (fmsg == NULL) { 1510 fmsg = "ABORT"; 1511 } 1512 1513 isp_prt(isp, ISP_LOGTDEBUG0, 1514 "CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid); 1515 break; 1516 1517 case CT_INVAL: 1518 /* 1519 * CTIO rejected by the firmware - invalid data direction. 1520 */ 1521 isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data direction"); 1522 break; 1523 1524 case CT_RSELTMO: 1525 fmsg = "failure to reconnect to initiator"; 1526 /*FALLTHROUGH*/ 1527 case CT_TIMEOUT: 1528 if (fmsg == NULL) 1529 fmsg = "command"; 1530 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg); 1531 break; 1532 1533 case CT_ERR: 1534 fmsg = "Completed with Error"; 1535 /*FALLTHROUGH*/ 1536 case CT_LOGOUT: 1537 if (fmsg == NULL) 1538 fmsg = "Port Logout"; 1539 /*FALLTHROUGH*/ 1540 case CT_PORTUNAVAIL: 1541 if (fmsg == NULL) 1542 fmsg = "Port not available"; 1543 /*FALLTHROUGH*/ 1544 case CT_PORTCHANGED: 1545 if (fmsg == NULL) 1546 fmsg = "Port Changed"; 1547 /*FALLTHROUGH*/ 1548 case CT_NOACK: 1549 if (fmsg == NULL) 1550 fmsg = "unacknowledged Immediate Notify pending"; 1551 isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg); 1552 break; 1553 1554 case CT_INVRXID: 1555 /* 1556 * CTIO rejected by the firmware because an invalid RX_ID. 1557 * Just print a message. 1558 */ 1559 isp_prt(isp, ISP_LOGWARN, 1560 "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid); 1561 break; 1562 1563 default: 1564 isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x", 1565 ct->ct_status & ~QLTM_SVALID); 1566 break; 1567 } 1568 1569 if (xs == NULL) { 1570 /* 1571 * There may be more than one CTIO for a data transfer, 1572 * or this may be a status CTIO we're not monitoring. 1573 * 1574 * The assumption is that they'll all be returned in the 1575 * order we got them. 1576 */ 1577 if (ct->ct_syshandle == 0) { 1578 if ((ct->ct_flags & CT2_SENDSTATUS) == 0) { 1579 isp_prt(isp, pl, 1580 "intermediate CTIO completed ok"); 1581 } else { 1582 isp_prt(isp, pl, 1583 "unmonitored CTIO completed ok"); 1584 } 1585 } else { 1586 isp_prt(isp, pl, 1587 "NO xs for CTIO (handle 0x%x) status 0x%x", 1588 ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID); 1589 } 1590 } else { 1591 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) { 1592 ISP_DMAFREE(isp, xs, ct->ct_syshandle); 1593 } 1594 if (ct->ct_flags & CT2_SENDSTATUS) { 1595 /* 1596 * Sent status and command complete. 1597 * 1598 * We're now really done with this command, so we 1599 * punt to the platform dependent layers because 1600 * only there can we do the appropriate command 1601 * complete thread synchronization. 1602 */ 1603 isp_prt(isp, pl, "status CTIO complete"); 1604 } else { 1605 /* 1606 * Final CTIO completed. Release DMA resources and 1607 * notify platform dependent layers. 1608 */ 1609 isp_prt(isp, pl, "data CTIO complete"); 1610 } 1611 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct); 1612 /* 1613 * The platform layer will destroy the handle if appropriate. 1614 */ 1615 } 1616 } 1617 1618 static void 1619 isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct) 1620 { 1621 void *xs; 1622 int pl = ISP_LOGTDEBUG2; 1623 char *fmsg = NULL; 1624 1625 if (ct->ct_syshandle) { 1626 xs = isp_find_xs_tgt(isp, ct->ct_syshandle); 1627 if (xs == NULL) { 1628 pl = ISP_LOGALL; 1629 } 1630 } else { 1631 xs = NULL; 1632 } 1633 1634 switch(ct->ct_nphdl) { 1635 case CT7_BUS_ERROR: 1636 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error"); 1637 /* FALL Through */ 1638 case CT7_DATA_OVER: 1639 case CT7_DATA_UNDER: 1640 case CT7_OK: 1641 /* 1642 * There are generally 2 possibilities as to why we'd get 1643 * this condition: 1644 * We sent or received data. 1645 * We sent status & command complete. 1646 */ 1647 1648 break; 1649 1650 case CT7_RESET: 1651 if (fmsg == NULL) { 1652 fmsg = "LIP Reset"; 1653 } 1654 /*FALLTHROUGH*/ 1655 case CT7_ABORTED: 1656 /* 1657 * When an Abort message is received the firmware goes to 1658 * Bus Free and returns all outstanding CTIOs with the status 1659 * set, then sends us an Immediate Notify entry. 1660 */ 1661 if (fmsg == NULL) { 1662 fmsg = "ABORT"; 1663 } 1664 isp_prt(isp, ISP_LOGTDEBUG0, 1665 "CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid); 1666 break; 1667 1668 case CT7_TIMEOUT: 1669 if (fmsg == NULL) { 1670 fmsg = "command"; 1671 } 1672 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg); 1673 break; 1674 1675 case CT7_ERR: 1676 fmsg = "Completed with Error"; 1677 /*FALLTHROUGH*/ 1678 case CT7_LOGOUT: 1679 if (fmsg == NULL) { 1680 fmsg = "Port Logout"; 1681 } 1682 /*FALLTHROUGH*/ 1683 case CT7_PORTUNAVAIL: 1684 if (fmsg == NULL) { 1685 fmsg = "Port not available"; 1686 } 1687 /*FALLTHROUGH*/ 1688 case CT7_PORTCHANGED: 1689 if (fmsg == NULL) { 1690 fmsg = "Port Changed"; 1691 } 1692 isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg); 1693 break; 1694 1695 case CT7_INVRXID: 1696 /* 1697 * CTIO rejected by the firmware because an invalid RX_ID. 1698 * Just print a message. 1699 */ 1700 isp_prt(isp, ISP_LOGWARN, 1701 "CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid); 1702 break; 1703 1704 case CT7_REASSY_ERR: 1705 isp_prt(isp, ISP_LOGWARN, "reassembly error"); 1706 break; 1707 1708 case CT7_SRR: 1709 isp_prt(isp, ISP_LOGWARN, "SRR received"); 1710 break; 1711 1712 default: 1713 isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x", 1714 ct->ct_nphdl); 1715 break; 1716 } 1717 1718 if (xs == NULL) { 1719 /* 1720 * There may be more than one CTIO for a data transfer, 1721 * or this may be a status CTIO we're not monitoring. 1722 * 1723 * The assumption is that they'll all be returned in the 1724 * order we got them. 1725 */ 1726 if (ct->ct_syshandle == 0) { 1727 if (ct->ct_flags & CT7_TERMINATE) { 1728 isp_prt(isp, ISP_LOGINFO, 1729 "termination of 0x%x complete", 1730 ct->ct_rxid); 1731 } else if ((ct->ct_flags & CT7_SENDSTATUS) == 0) { 1732 isp_prt(isp, pl, 1733 "intermediate CTIO completed ok"); 1734 } else { 1735 isp_prt(isp, pl, 1736 "unmonitored CTIO completed ok"); 1737 } 1738 } else { 1739 isp_prt(isp, pl, 1740 "NO xs for CTIO (handle 0x%x) status 0x%x", 1741 ct->ct_syshandle, ct->ct_nphdl); 1742 } 1743 } else { 1744 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) { 1745 ISP_DMAFREE(isp, xs, ct->ct_syshandle); 1746 } 1747 if (ct->ct_flags & CT2_SENDSTATUS) { 1748 /* 1749 * Sent status and command complete. 1750 * 1751 * We're now really done with this command, so we 1752 * punt to the platform dependent layers because 1753 * only there can we do the appropriate command 1754 * complete thread synchronization. 1755 */ 1756 isp_prt(isp, pl, "status CTIO complete"); 1757 } else { 1758 /* 1759 * Final CTIO completed. Release DMA resources and 1760 * notify platform dependent layers. 1761 */ 1762 isp_prt(isp, pl, "data CTIO complete"); 1763 } 1764 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct); 1765 /* 1766 * The platform layer will destroy the handle if appropriate. 1767 */ 1768 } 1769 } 1770 #endif 1771