1 /*- 2 * Copyright (c) 1997-2009 by Matthew Jacob 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 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 <dev/ic/isp_netbsd.h> 41 #endif 42 #ifdef __FreeBSD__ 43 #include <sys/cdefs.h> 44 __FBSDID("$FreeBSD$"); 45 #include <dev/isp/isp_freebsd.h> 46 #endif 47 #ifdef __OpenBSD__ 48 #include <dev/ic/isp_openbsd.h> 49 #endif 50 #ifdef __linux__ 51 #include "isp_linux.h" 52 #endif 53 54 #ifdef ISP_TARGET_MODE 55 static const char atiocope[] = "ATIO returned for LUN %x because it was in the middle of Bus Device Reset on bus %d"; 56 static const char atior[] = "ATIO returned for LUN %x from handle 0x%x because a Bus Reset occurred on bus %d"; 57 static const char rqo[] = "%s: Request Queue Overflow"; 58 59 static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *); 60 static void isp_got_tmf_24xx(ispsoftc_t *, at7_entry_t *); 61 static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *); 62 static void isp_handle_ctio2(ispsoftc_t *, ct2_entry_t *); 63 static void isp_handle_ctio7(ispsoftc_t *, ct7_entry_t *); 64 static void isp_handle_24xx_inotify(ispsoftc_t *, in_fcentry_24xx_t *); 65 66 /* 67 * The Qlogic driver gets an interrupt to look at response queue entries. 68 * Some of these are status completions for initiatior mode commands, but 69 * if target mode is enabled, we get a whole wad of response queue entries 70 * to be handled here. 71 * 72 * Basically the split into 3 main groups: Lun Enable/Modification responses, 73 * SCSI Command processing, and Immediate Notification events. 74 * 75 * You start by writing a request queue entry to enable target mode (and 76 * establish some resource limitations which you can modify later). 77 * The f/w responds with a LUN ENABLE or LUN MODIFY response with 78 * the status of this action. If the enable was successful, you can expect... 79 * 80 * Response queue entries with SCSI commands encapsulate show up in an ATIO 81 * (Accept Target IO) type- sometimes with enough info to stop the command at 82 * this level. Ultimately the driver has to feed back to the f/w's request 83 * queue a sequence of CTIOs (continue target I/O) that describe data to 84 * be moved and/or status to be sent) and finally finishing with sending 85 * to the f/w's response queue an ATIO which then completes the handshake 86 * with the f/w for that command. There's a lot of variations on this theme, 87 * including flags you can set in the CTIO for the Qlogic 2X00 fibre channel 88 * cards that 'auto-replenish' the f/w's ATIO count, but this is the basic 89 * gist of it. 90 * 91 * The third group that can show up in the response queue are Immediate 92 * Notification events. These include things like notifications of SCSI bus 93 * resets, or Bus Device Reset messages or other messages received. This 94 * a classic oddbins area. It can get a little weird because you then turn 95 * around and acknowledge the Immediate Notify by writing an entry onto the 96 * request queue and then the f/w turns around and gives you an acknowledgement 97 * to *your* acknowledgement on the response queue (the idea being to let 98 * the f/w tell you when the event is *really* over I guess). 99 * 100 */ 101 102 103 /* 104 * A new response queue entry has arrived. The interrupt service code 105 * has already swizzled it into the platform dependent from canonical form. 106 * 107 * Because of the way this driver is designed, unfortunately most of the 108 * actual synchronization work has to be done in the platform specific 109 * code- we have no synchroniation primitives in the common code. 110 */ 111 112 int 113 isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp) 114 { 115 uint16_t status; 116 uint32_t seqid; 117 union { 118 at2_entry_t *at2iop; 119 at2e_entry_t *at2eiop; 120 at7_entry_t *at7iop; 121 ct2_entry_t *ct2iop; 122 ct2e_entry_t *ct2eiop; 123 ct7_entry_t *ct7iop; 124 lun_entry_t *lunenp; 125 in_fcentry_t *inot_fcp; 126 in_fcentry_e_t *inote_fcp; 127 in_fcentry_24xx_t *inot_24xx; 128 na_fcentry_t *nack_fcp; 129 na_fcentry_e_t *nacke_fcp; 130 na_fcentry_24xx_t *nack_24xx; 131 isphdr_t *hp; 132 abts_t *abts; 133 abts_rsp_t *abts_rsp; 134 els_t *els; 135 void * *vp; 136 #define at2iop unp.at2iop 137 #define at2eiop unp.at2eiop 138 #define at7iop unp.at7iop 139 #define ct2iop unp.ct2iop 140 #define ct2eiop unp.ct2eiop 141 #define ct7iop unp.ct7iop 142 #define lunenp unp.lunenp 143 #define inot_fcp unp.inot_fcp 144 #define inote_fcp unp.inote_fcp 145 #define inot_24xx unp.inot_24xx 146 #define nack_fcp unp.nack_fcp 147 #define nacke_fcp unp.nacke_fcp 148 #define nack_24xx unp.nack_24xx 149 #define abts unp.abts 150 #define abts_rsp unp.abts_rsp 151 #define els unp.els 152 #define hdrp unp.hp 153 } unp; 154 uint8_t local[QENTRY_LEN]; 155 uint16_t iid; 156 int bus, type, len, level, rval = 1; 157 isp_notify_t notify; 158 159 type = isp_get_response_type(isp, (isphdr_t *)vptr); 160 unp.vp = vptr; 161 162 ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr); 163 164 switch (type) { 165 case RQSTYPE_ATIO: 166 isp_get_atio7(isp, at7iop, (at7_entry_t *) local); 167 at7iop = (at7_entry_t *) local; 168 /* 169 * Check for and do something with commands whose 170 * IULEN extends past a single queue entry. 171 */ 172 len = at7iop->at_ta_len & 0x0fff; 173 if (len > (QENTRY_LEN - 8)) { 174 len -= (QENTRY_LEN - 8); 175 isp_prt(isp, ISP_LOGINFO, "long IU length (%d) ignored", len); 176 while (len > 0) { 177 *optrp = ISP_NXT_QENTRY(*optrp, RESULT_QUEUE_LEN(isp)); 178 len -= QENTRY_LEN; 179 } 180 } 181 /* 182 * Check for a task management function 183 */ 184 if (at7iop->at_cmnd.fcp_cmnd_task_management) { 185 isp_got_tmf_24xx(isp, at7iop); 186 break; 187 } 188 /* 189 * Just go straight to outer layer for this one. 190 */ 191 isp_async(isp, ISPASYNC_TARGET_ACTION, local); 192 break; 193 194 case RQSTYPE_ATIO2: 195 if (ISP_CAP_2KLOGIN(isp)) { 196 isp_get_atio2e(isp, at2eiop, (at2e_entry_t *) local); 197 } else { 198 isp_get_atio2(isp, at2iop, (at2_entry_t *) local); 199 } 200 isp_handle_atio2(isp, (at2_entry_t *) local); 201 break; 202 203 case RQSTYPE_CTIO3: 204 case RQSTYPE_CTIO2: 205 if (ISP_CAP_2KLOGIN(isp)) { 206 isp_get_ctio2e(isp, ct2eiop, (ct2e_entry_t *) local); 207 } else { 208 isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local); 209 } 210 isp_handle_ctio2(isp, (ct2_entry_t *) local); 211 break; 212 213 case RQSTYPE_CTIO7: 214 isp_get_ctio7(isp, ct7iop, (ct7_entry_t *) local); 215 isp_handle_ctio7(isp, (ct7_entry_t *) local); 216 break; 217 218 case RQSTYPE_NOTIFY: 219 bus = 0; 220 if (IS_24XX(isp)) { 221 isp_get_notify_24xx(isp, inot_24xx, (in_fcentry_24xx_t *)local); 222 inot_24xx = (in_fcentry_24xx_t *) local; 223 isp_handle_24xx_inotify(isp, inot_24xx); 224 break; 225 } else { 226 if (ISP_CAP_2KLOGIN(isp)) { 227 in_fcentry_e_t *ecp = (in_fcentry_e_t *)local; 228 isp_get_notify_fc_e(isp, inote_fcp, ecp); 229 iid = ecp->in_iid; 230 status = ecp->in_status; 231 seqid = ecp->in_seqid; 232 } else { 233 in_fcentry_t *fcp = (in_fcentry_t *)local; 234 isp_get_notify_fc(isp, inot_fcp, fcp); 235 iid = fcp->in_iid; 236 status = fcp->in_status; 237 seqid = fcp->in_seqid; 238 } 239 } 240 241 isp_prt(isp, ISP_LOGTDEBUG0, "Immediate Notify On Bus %d, status=0x%x seqid=0x%x", bus, status, seqid); 242 243 switch (status) { 244 case IN_MSG_RECEIVED: 245 case IN_IDE_RECEIVED: 246 isp_got_msg_fc(isp, (in_fcentry_t *)local); 247 break; 248 case IN_RSRC_UNAVAIL: 249 isp_prt(isp, ISP_LOGINFO, "Firmware out of ATIOs"); 250 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, local); 251 break; 252 253 case IN_RESET: 254 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 255 notify.nt_hba = isp; 256 notify.nt_wwn = INI_ANY; 257 notify.nt_tgt = TGT_ANY; 258 notify.nt_nphdl = iid; 259 notify.nt_sid = PORT_ANY; 260 notify.nt_did = PORT_ANY; 261 notify.nt_lun = LUN_ANY; 262 notify.nt_tagval = TAG_ANY; 263 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); 264 notify.nt_ncode = NT_BUS_RESET; 265 notify.nt_need_ack = 1; 266 notify.nt_lreserved = local; 267 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 268 break; 269 270 case IN_PORT_LOGOUT: 271 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 272 notify.nt_hba = isp; 273 notify.nt_wwn = INI_ANY; 274 notify.nt_nphdl = iid; 275 notify.nt_sid = PORT_ANY; 276 notify.nt_did = PORT_ANY; 277 notify.nt_ncode = NT_LOGOUT; 278 notify.nt_need_ack = 1; 279 notify.nt_lreserved = local; 280 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 281 break; 282 283 case IN_ABORT_TASK: 284 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 285 notify.nt_hba = isp; 286 notify.nt_wwn = INI_ANY; 287 notify.nt_nphdl = iid; 288 notify.nt_sid = PORT_ANY; 289 notify.nt_did = PORT_ANY; 290 notify.nt_ncode = NT_ABORT_TASK; 291 notify.nt_need_ack = 1; 292 notify.nt_lreserved = local; 293 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 294 break; 295 296 case IN_GLOBAL_LOGO: 297 isp_prt(isp, ISP_LOGTINFO, "%s: all ports logged out", __func__); 298 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 299 notify.nt_hba = isp; 300 notify.nt_wwn = INI_ANY; 301 notify.nt_nphdl = NIL_HANDLE; 302 notify.nt_sid = PORT_ANY; 303 notify.nt_did = PORT_ANY; 304 notify.nt_ncode = NT_GLOBAL_LOGOUT; 305 notify.nt_need_ack = 1; 306 notify.nt_lreserved = local; 307 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 308 break; 309 310 case IN_PORT_CHANGED: 311 isp_prt(isp, ISP_LOGTINFO, "%s: port changed", __func__); 312 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 313 notify.nt_hba = isp; 314 notify.nt_wwn = INI_ANY; 315 notify.nt_nphdl = NIL_HANDLE; 316 notify.nt_sid = PORT_ANY; 317 notify.nt_did = PORT_ANY; 318 notify.nt_ncode = NT_CHANGED; 319 notify.nt_need_ack = 1; 320 notify.nt_lreserved = local; 321 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 322 break; 323 324 default: 325 ISP_SNPRINTF(local, sizeof local, "%s: unknown status to RQSTYPE_NOTIFY (0x%x)", __func__, status); 326 isp_print_bytes(isp, local, QENTRY_LEN, vptr); 327 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, local); 328 break; 329 } 330 break; 331 332 case RQSTYPE_NOTIFY_ACK: 333 /* 334 * The ISP is acknowledging our acknowledgement of an 335 * Immediate Notify entry for some asynchronous event. 336 */ 337 if (IS_24XX(isp)) { 338 isp_get_notify_ack_24xx(isp, nack_24xx, (na_fcentry_24xx_t *) local); 339 nack_24xx = (na_fcentry_24xx_t *) local; 340 if (nack_24xx->na_status != NA_OK) { 341 level = ISP_LOGINFO; 342 } else { 343 level = ISP_LOGTDEBUG1; 344 } 345 isp_prt(isp, level, "Notify Ack Status=0x%x; Subcode 0x%x seqid=0x%x", nack_24xx->na_status, nack_24xx->na_status_subcode, nack_24xx->na_rxid); 346 } else { 347 if (ISP_CAP_2KLOGIN(isp)) { 348 isp_get_notify_ack_fc_e(isp, nacke_fcp, (na_fcentry_e_t *)local); 349 } else { 350 isp_get_notify_ack_fc(isp, nack_fcp, (na_fcentry_t *)local); 351 } 352 nack_fcp = (na_fcentry_t *)local; 353 if (nack_fcp->na_status != NA_OK) { 354 level = ISP_LOGINFO; 355 } else { 356 level = ISP_LOGTDEBUG1; 357 } 358 isp_prt(isp, level, "Notify Ack Status=0x%x seqid 0x%x", nack_fcp->na_status, nack_fcp->na_seqid); 359 } 360 break; 361 362 case RQSTYPE_ABTS_RCVD: 363 isp_get_abts(isp, abts, (abts_t *)local); 364 isp_async(isp, ISPASYNC_TARGET_ACTION, &local); 365 break; 366 case RQSTYPE_ABTS_RSP: 367 isp_get_abts_rsp(isp, abts_rsp, (abts_rsp_t *)local); 368 abts_rsp = (abts_rsp_t *) local; 369 if (abts_rsp->abts_rsp_status) { 370 level = ISP_LOGINFO; 371 } else { 372 level = ISP_LOGTDEBUG0; 373 } 374 isp_prt(isp, level, "ABTS RSP response[0x%x]: status=0x%x sub=(0x%x 0x%x)", abts_rsp->abts_rsp_rxid_task, abts_rsp->abts_rsp_status, 375 abts_rsp->abts_rsp_payload.rsp.subcode1, abts_rsp->abts_rsp_payload.rsp.subcode2); 376 break; 377 default: 378 isp_prt(isp, ISP_LOGERR, "%s: unknown entry type 0x%x", __func__, type); 379 rval = 0; 380 break; 381 } 382 #undef atiop 383 #undef at2iop 384 #undef at2eiop 385 #undef at7iop 386 #undef ctiop 387 #undef ct2iop 388 #undef ct2eiop 389 #undef ct7iop 390 #undef lunenp 391 #undef inotp 392 #undef inot_fcp 393 #undef inote_fcp 394 #undef inot_24xx 395 #undef nackp 396 #undef nack_fcp 397 #undef nacke_fcp 398 #undef hack_24xx 399 #undef abts 400 #undef abts_rsp 401 #undef els 402 #undef hdrp 403 return (rval); 404 } 405 406 int 407 isp_target_put_entry(ispsoftc_t *isp, void *ap) 408 { 409 void *outp; 410 uint8_t etype = ((isphdr_t *) ap)->rqs_entry_type; 411 412 outp = isp_getrqentry(isp); 413 if (outp == NULL) { 414 isp_prt(isp, ISP_LOGWARN, rqo, __func__); 415 return (-1); 416 } 417 switch (etype) { 418 case RQSTYPE_NOTIFY_ACK: 419 if (IS_24XX(isp)) 420 isp_put_notify_24xx_ack(isp, (na_fcentry_24xx_t *)ap, 421 (na_fcentry_24xx_t *)outp); 422 else if (ISP_CAP_2KLOGIN(isp)) 423 isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *)ap, 424 (na_fcentry_e_t *)outp); 425 else 426 isp_put_notify_ack_fc(isp, ap, (na_fcentry_t *)outp); 427 break; 428 case RQSTYPE_ATIO2: 429 if (ISP_CAP_2KLOGIN(isp)) 430 isp_put_atio2e(isp, (at2e_entry_t *)ap, 431 (at2e_entry_t *)outp); 432 else 433 isp_put_atio2(isp, (at2_entry_t *)ap, 434 (at2_entry_t *)outp); 435 break; 436 case RQSTYPE_CTIO2: 437 if (ISP_CAP_2KLOGIN(isp)) 438 isp_put_ctio2e(isp, (ct2e_entry_t *)ap, 439 (ct2e_entry_t *)outp); 440 else 441 isp_put_ctio2(isp, (ct2_entry_t *)ap, 442 (ct2_entry_t *)outp); 443 break; 444 case RQSTYPE_CTIO7: 445 isp_put_ctio7(isp, (ct7_entry_t *)ap, (ct7_entry_t *)outp); 446 break; 447 case RQSTYPE_ABTS_RSP: 448 isp_put_abts_rsp(isp, (abts_rsp_t *)ap, (abts_rsp_t *)outp); 449 break; 450 default: 451 isp_prt(isp, ISP_LOGERR, "%s: Unknown type 0x%x", __func__, etype); 452 return (-1); 453 } 454 ISP_TDQE(isp, __func__, isp->isp_reqidx, ap); 455 ISP_SYNC_REQUEST(isp); 456 return (0); 457 } 458 459 int 460 isp_target_put_atio(ispsoftc_t *isp, void *arg) 461 { 462 at2_entry_t *aep = arg; 463 union { 464 at2_entry_t _atio2; 465 at2e_entry_t _atio2e; 466 } atun; 467 468 ISP_MEMZERO(&atun, sizeof atun); 469 atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2; 470 atun._atio2.at_header.rqs_entry_count = 1; 471 if (ISP_CAP_SCCFW(isp)) { 472 atun._atio2.at_scclun = aep->at_scclun; 473 } else { 474 atun._atio2.at_lun = (uint8_t) aep->at_lun; 475 } 476 if (ISP_CAP_2KLOGIN(isp)) { 477 atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid; 478 } else { 479 atun._atio2.at_iid = aep->at_iid; 480 } 481 atun._atio2.at_rxid = aep->at_rxid; 482 atun._atio2.at_status = CT_OK; 483 return (isp_target_put_entry(isp, &atun)); 484 } 485 486 /* 487 * Command completion- both for handling cases of no resources or 488 * no blackhole driver, or other cases where we have to, inline, 489 * finish the command sanely, or for normal command completion. 490 * 491 * The 'completion' code value has the scsi status byte in the low 8 bits. 492 * If status is a CHECK CONDITION and bit 8 is nonzero, then bits 12..15 have 493 * the sense key and bits 16..23 have the ASCQ and bits 24..31 have the ASC 494 * values. 495 * 496 * NB: the key, asc, ascq, cannot be used for parallel SCSI as it doesn't 497 * NB: inline SCSI sense reporting. As such, we lose this information. XXX. 498 * 499 * For both parallel && fibre channel, we use the feature that does 500 * an automatic resource autoreplenish so we don't have then later do 501 * put of an atio to replenish the f/w's resource count. 502 */ 503 504 int 505 isp_endcmd(ispsoftc_t *isp, ...) 506 { 507 uint32_t code, hdl; 508 uint8_t sts; 509 union { 510 ct2_entry_t _ctio2; 511 ct2e_entry_t _ctio2e; 512 ct7_entry_t _ctio7; 513 } un; 514 va_list ap; 515 int vpidx, nphdl; 516 517 ISP_MEMZERO(&un, sizeof un); 518 519 if (IS_24XX(isp)) { 520 at7_entry_t *aep; 521 ct7_entry_t *cto = &un._ctio7; 522 523 va_start(ap, isp); 524 aep = va_arg(ap, at7_entry_t *); 525 nphdl = va_arg(ap, int); 526 /* 527 * Note that vpidx may equal 0xff (unknown) here 528 */ 529 vpidx = va_arg(ap, int); 530 code = va_arg(ap, uint32_t); 531 hdl = va_arg(ap, uint32_t); 532 va_end(ap); 533 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] chan %d code %x", __func__, aep->at_rxid, vpidx, code); 534 535 sts = code & 0xff; 536 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; 537 cto->ct_header.rqs_entry_count = 1; 538 cto->ct_nphdl = nphdl; 539 cto->ct_rxid = aep->at_rxid; 540 cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2]; 541 cto->ct_iid_hi = aep->at_hdr.s_id[0]; 542 cto->ct_oxid = aep->at_hdr.ox_id; 543 cto->ct_scsi_status = sts; 544 cto->ct_vpidx = vpidx; 545 cto->ct_flags = CT7_NOACK; 546 if (code & ECMD_TERMINATE) { 547 cto->ct_flags |= CT7_TERMINATE; 548 } else if (code & ECMD_SVALID) { 549 cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS; 550 cto->ct_scsi_status |= (FCP_SNSLEN_VALID << 8); 551 cto->ct_senselen = min(16, MAXRESPLEN_24XX); 552 ISP_MEMZERO(cto->rsp.m1.ct_resp, sizeof (cto->rsp.m1.ct_resp)); 553 cto->rsp.m1.ct_resp[0] = 0xf0; 554 cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf; 555 cto->rsp.m1.ct_resp[7] = 8; 556 cto->rsp.m1.ct_resp[12] = (code >> 16) & 0xff; 557 cto->rsp.m1.ct_resp[13] = (code >> 24) & 0xff; 558 } else if (code & ECMD_RVALID) { 559 cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS; 560 cto->ct_scsi_status |= (FCP_RSPLEN_VALID << 8); 561 cto->rsp.m1.ct_resplen = 4; 562 ISP_MEMZERO(cto->rsp.m1.ct_resp, sizeof (cto->rsp.m1.ct_resp)); 563 cto->rsp.m1.ct_resp[0] = (code >> 12) & 0xf; 564 cto->rsp.m1.ct_resp[1] = (code >> 16) & 0xff; 565 cto->rsp.m1.ct_resp[2] = (code >> 24) & 0xff; 566 cto->rsp.m1.ct_resp[3] = 0; 567 } else { 568 cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS; 569 } 570 if (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl != 0) { 571 cto->ct_resid = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl; 572 cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8); 573 } 574 cto->ct_syshandle = hdl; 575 } else { 576 at2_entry_t *aep; 577 ct2_entry_t *cto = &un._ctio2; 578 579 va_start(ap, isp); 580 aep = va_arg(ap, at2_entry_t *); 581 /* nphdl and vpidx are unused here. */ 582 nphdl = va_arg(ap, int); 583 vpidx = va_arg(ap, int); 584 code = va_arg(ap, uint32_t); 585 hdl = va_arg(ap, uint32_t); 586 va_end(ap); 587 588 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] code %x", __func__, aep->at_rxid, code); 589 590 sts = code & 0xff; 591 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2; 592 cto->ct_header.rqs_entry_count = 1; 593 if (ISP_CAP_SCCFW(isp) == 0) { 594 cto->ct_lun = aep->at_lun; 595 } 596 if (ISP_CAP_2KLOGIN(isp)) { 597 un._ctio2e.ct_iid = ((at2e_entry_t *)aep)->at_iid; 598 } else { 599 cto->ct_iid = aep->at_iid; 600 } 601 cto->ct_rxid = aep->at_rxid; 602 cto->rsp.m1.ct_scsi_status = sts; 603 cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1; 604 if (hdl == 0) { 605 cto->ct_flags |= CT2_CCINCR; 606 } 607 if (aep->at_datalen) { 608 cto->ct_resid = aep->at_datalen; 609 cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER; 610 } 611 if (sts == SCSI_CHECK && (code & ECMD_SVALID)) { 612 cto->rsp.m1.ct_resp[0] = 0xf0; 613 cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf; 614 cto->rsp.m1.ct_resp[7] = 8; 615 cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff; 616 cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff; 617 cto->rsp.m1.ct_senselen = 16; 618 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID; 619 } 620 cto->ct_syshandle = hdl; 621 } 622 return (isp_target_put_entry(isp, &un)); 623 } 624 625 /* 626 * These are either broadcast events or specifically CTIO fast completion 627 */ 628 629 void 630 isp_target_async(ispsoftc_t *isp, int bus, int event) 631 { 632 isp_notify_t notify; 633 634 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 635 notify.nt_hba = isp; 636 notify.nt_wwn = INI_ANY; 637 notify.nt_nphdl = NIL_HANDLE; 638 notify.nt_sid = PORT_ANY; 639 notify.nt_did = PORT_ANY; 640 notify.nt_tgt = TGT_ANY; 641 notify.nt_channel = bus; 642 notify.nt_lun = LUN_ANY; 643 notify.nt_tagval = TAG_ANY; 644 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); 645 646 switch (event) { 647 case ASYNC_LOOP_UP: 648 case ASYNC_PTPMODE: 649 isp_prt(isp, ISP_LOGTDEBUG0, "%s: LOOP UP", __func__); 650 notify.nt_ncode = NT_LINK_UP; 651 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 652 break; 653 case ASYNC_LOOP_DOWN: 654 isp_prt(isp, ISP_LOGTDEBUG0, "%s: LOOP DOWN", __func__); 655 notify.nt_ncode = NT_LINK_DOWN; 656 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 657 break; 658 case ASYNC_LIP_ERROR: 659 case ASYNC_LIP_NOS_OLS_RECV: 660 case ASYNC_LIP_OCCURRED: 661 case ASYNC_LOOP_RESET: 662 isp_prt(isp, ISP_LOGTDEBUG0, "%s: LIP RESET", __func__); 663 notify.nt_ncode = NT_LIP_RESET; 664 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 665 break; 666 case ASYNC_BUS_RESET: 667 case ASYNC_TIMEOUT_RESET: /* XXX: where does this come from ? */ 668 isp_prt(isp, ISP_LOGTDEBUG0, "%s: BUS RESET", __func__); 669 notify.nt_ncode = NT_BUS_RESET; 670 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 671 break; 672 case ASYNC_DEVICE_RESET: 673 isp_prt(isp, ISP_LOGTDEBUG0, "%s: DEVICE RESET", __func__); 674 notify.nt_ncode = NT_TARGET_RESET; 675 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 676 break; 677 case ASYNC_CTIO_DONE: 678 { 679 uint8_t storage[QENTRY_LEN]; 680 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO DONE", __func__); 681 memset(storage, 0, QENTRY_LEN); 682 if (IS_24XX(isp)) { 683 ct7_entry_t *ct = (ct7_entry_t *) storage; 684 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO7; 685 ct->ct_nphdl = CT7_OK; 686 ct->ct_syshandle = bus; 687 ct->ct_flags = CT7_SENDSTATUS; 688 } else { 689 /* This should also suffice for 2K login code */ 690 ct2_entry_t *ct = (ct2_entry_t *) storage; 691 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO2; 692 ct->ct_status = CT_OK; 693 ct->ct_syshandle = bus; 694 ct->ct_flags = CT2_SENDSTATUS|CT2_FASTPOST; 695 } 696 isp_async(isp, ISPASYNC_TARGET_ACTION, storage); 697 break; 698 } 699 default: 700 isp_prt(isp, ISP_LOGERR, "%s: unknown event 0x%x", __func__, event); 701 break; 702 } 703 } 704 705 /* 706 * Synthesize a message from the task management flags in a FCP_CMND_IU. 707 */ 708 static void 709 isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp) 710 { 711 isp_notify_t notify; 712 static const char f1[] = "%s from N-port handle 0x%x lun %x seq 0x%x"; 713 static const char f2[] = "unknown %s 0x%x lun %x N-Port handle 0x%x task flags 0x%x seq 0x%x\n"; 714 uint16_t seqid, nphdl; 715 716 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 717 notify.nt_hba = isp; 718 notify.nt_wwn = INI_ANY; 719 if (ISP_CAP_2KLOGIN(isp)) { 720 notify.nt_nphdl = ((in_fcentry_e_t *)inp)->in_iid; 721 nphdl = ((in_fcentry_e_t *)inp)->in_iid; 722 seqid = ((in_fcentry_e_t *)inp)->in_seqid; 723 } else { 724 notify.nt_nphdl = inp->in_iid; 725 nphdl = inp->in_iid; 726 seqid = inp->in_seqid; 727 } 728 notify.nt_sid = PORT_ANY; 729 notify.nt_did = PORT_ANY; 730 731 /* nt_tgt set in outer layers */ 732 if (ISP_CAP_SCCFW(isp)) { 733 notify.nt_lun = inp->in_scclun; 734 } else { 735 notify.nt_lun = inp->in_lun; 736 } 737 notify.nt_tagval = seqid; 738 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); 739 notify.nt_need_ack = 1; 740 notify.nt_lreserved = inp; 741 742 if (inp->in_status != IN_MSG_RECEIVED) { 743 isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status", inp->in_status, notify.nt_lun, nphdl, inp->in_task_flags, inp->in_seqid); 744 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inp); 745 return; 746 } 747 748 if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) { 749 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", nphdl, notify.nt_lun, inp->in_seqid); 750 notify.nt_ncode = NT_ABORT_TASK_SET; 751 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) { 752 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", nphdl, notify.nt_lun, inp->in_seqid); 753 notify.nt_ncode = NT_CLEAR_TASK_SET; 754 } else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) { 755 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", nphdl, notify.nt_lun, inp->in_seqid); 756 notify.nt_ncode = NT_LUN_RESET; 757 } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) { 758 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", nphdl, notify.nt_lun, inp->in_seqid); 759 notify.nt_ncode = NT_TARGET_RESET; 760 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) { 761 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", nphdl, notify.nt_lun, inp->in_seqid); 762 notify.nt_ncode = NT_CLEAR_ACA; 763 } else { 764 isp_prt(isp, ISP_LOGWARN, f2, "task flag", inp->in_status, notify.nt_lun, nphdl, inp->in_task_flags, inp->in_seqid); 765 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inp); 766 return; 767 } 768 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 769 } 770 771 static void 772 isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep) 773 { 774 isp_notify_t notify; 775 static const char f1[] = "%s from PortID 0x%06x lun %x seq 0x%08x"; 776 static const char f2[] = "unknown Task Flag 0x%x lun %x PortID 0x%x tag 0x%08x"; 777 fcportdb_t *lp; 778 uint16_t chan; 779 uint32_t sid, did; 780 781 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 782 notify.nt_hba = isp; 783 notify.nt_wwn = INI_ANY; 784 notify.nt_lun = (aep->at_cmnd.fcp_cmnd_lun[0] << 8) | (aep->at_cmnd.fcp_cmnd_lun[1]); 785 notify.nt_tagval = aep->at_rxid; 786 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); 787 notify.nt_lreserved = aep; 788 sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2]; 789 did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2]; 790 if (ISP_CAP_MULTI_ID(isp) && isp->isp_nchan > 1) { 791 /* Channel has to be derived from D_ID */ 792 isp_find_chan_by_did(isp, did, &chan); 793 if (chan == ISP_NOCHAN) { 794 isp_prt(isp, ISP_LOGWARN, "%s: D_ID 0x%x not found on any channel", __func__, did); 795 isp_endcmd(isp, aep, NIL_HANDLE, ISP_NOCHAN, ECMD_TERMINATE, 0); 796 return; 797 } 798 } else { 799 chan = 0; 800 } 801 if (isp_find_pdb_by_portid(isp, chan, sid, &lp)) 802 notify.nt_nphdl = lp->handle; 803 else 804 notify.nt_nphdl = NIL_HANDLE; 805 notify.nt_sid = sid; 806 notify.nt_did = did; 807 notify.nt_channel = chan; 808 if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_QUERY_TASK_SET) { 809 isp_prt(isp, ISP_LOGINFO, f1, "QUERY TASK SET", sid, notify.nt_lun, aep->at_rxid); 810 notify.nt_ncode = NT_QUERY_TASK_SET; 811 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_ABORT_TASK_SET) { 812 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", sid, notify.nt_lun, aep->at_rxid); 813 notify.nt_ncode = NT_ABORT_TASK_SET; 814 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_CLEAR_TASK_SET) { 815 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", sid, notify.nt_lun, aep->at_rxid); 816 notify.nt_ncode = NT_CLEAR_TASK_SET; 817 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_QUERY_ASYNC_EVENT) { 818 isp_prt(isp, ISP_LOGINFO, f1, "QUERY ASYNC EVENT", sid, notify.nt_lun, aep->at_rxid); 819 notify.nt_ncode = NT_QUERY_ASYNC_EVENT; 820 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_LUN_RESET) { 821 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", sid, notify.nt_lun, aep->at_rxid); 822 notify.nt_ncode = NT_LUN_RESET; 823 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_TGT_RESET) { 824 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", sid, notify.nt_lun, aep->at_rxid); 825 notify.nt_ncode = NT_TARGET_RESET; 826 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_CLEAR_ACA) { 827 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", sid, notify.nt_lun, aep->at_rxid); 828 notify.nt_ncode = NT_CLEAR_ACA; 829 } else { 830 isp_prt(isp, ISP_LOGWARN, f2, aep->at_cmnd.fcp_cmnd_task_management, notify.nt_lun, sid, aep->at_rxid); 831 notify.nt_ncode = NT_UNKNOWN; 832 isp_endcmd(isp, aep, notify.nt_nphdl, chan, ECMD_RVALID | (0x4 << 12), 0); 833 return; 834 } 835 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 836 } 837 838 int 839 isp_notify_ack(ispsoftc_t *isp, void *arg) 840 { 841 char storage[QENTRY_LEN]; 842 843 /* 844 * This is in case a Task Management Function ends up here. 845 */ 846 if (IS_24XX(isp) && ((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO) { 847 at7_entry_t *aep = arg; 848 return (isp_endcmd(isp, aep, NIL_HANDLE, 0, 0, 0)); 849 } 850 851 ISP_MEMZERO(storage, QENTRY_LEN); 852 if (IS_24XX(isp)) { 853 in_fcentry_24xx_t *in = arg; 854 na_fcentry_24xx_t *na = (na_fcentry_24xx_t *) storage; 855 856 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; 857 na->na_header.rqs_entry_count = 1; 858 na->na_nphdl = in->in_nphdl; 859 na->na_flags = in->in_flags; 860 na->na_status = in->in_status; 861 na->na_status_subcode = in->in_status_subcode; 862 na->na_fwhandle = in->in_fwhandle; 863 na->na_rxid = in->in_rxid; 864 na->na_oxid = in->in_oxid; 865 na->na_vpidx = in->in_vpidx; 866 if (in->in_status == IN24XX_SRR_RCVD) { 867 na->na_srr_rxid = in->in_srr_rxid; 868 na->na_srr_reloff_hi = in->in_srr_reloff_hi; 869 na->na_srr_reloff_lo = in->in_srr_reloff_lo; 870 na->na_srr_iu = in->in_srr_iu; 871 /* 872 * Whether we're accepting the SRR or rejecting 873 * it is determined by looking at the in_reserved 874 * field in the original notify structure. 875 */ 876 if (in->in_reserved) { 877 na->na_srr_flags = 1; 878 na->na_srr_reject_vunique = 0; 879 /* Unable to perform this command at this time. */ 880 na->na_srr_reject_code = 9; 881 /* Unable to supply the requested data. */ 882 na->na_srr_reject_explanation = 0x2a; 883 } 884 } 885 } else { 886 in_fcentry_t *in = arg; 887 na_fcentry_t *na = (na_fcentry_t *) storage; 888 int iid; 889 890 ISP_MEMCPY(storage, arg, sizeof (isphdr_t)); 891 if (ISP_CAP_2KLOGIN(isp)) { 892 iid = ((in_fcentry_e_t *)in)->in_iid; 893 ((na_fcentry_e_t *)na)->na_iid = iid; 894 } else { 895 iid = in->in_iid; 896 na->na_iid = iid; 897 } 898 na->na_task_flags = in->in_task_flags & TASK_FLAGS_RESERVED_MASK; 899 na->na_seqid = in->in_seqid; 900 na->na_status = in->in_status; 901 na->na_flags = NAFC_RCOUNT; 902 /* We do not modify resource counts for LIP resets */ 903 if (in->in_status == IN_RESET) 904 na->na_flags = NAFC_RST_CLRD; 905 if (in->in_status == IN_MSG_RECEIVED) { 906 na->na_flags |= NAFC_TVALID; 907 na->na_response = 0; /* XXX SUCCEEDED XXX */ 908 } 909 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; 910 na->na_header.rqs_entry_count = 1; 911 isp_prt(isp, ISP_LOGTDEBUG0, "notify ack handle %x seqid %x flags %x tflags %x response %x", iid, na->na_seqid, 912 na->na_flags, na->na_task_flags, na->na_response); 913 } 914 return (isp_target_put_entry(isp, &storage)); 915 } 916 917 int 918 isp_acknak_abts(ispsoftc_t *isp, void *arg, int errno) 919 { 920 char storage[QENTRY_LEN]; 921 uint16_t tmpw; 922 uint8_t tmpb; 923 abts_t *abts = arg; 924 abts_rsp_t *rsp = (abts_rsp_t *) storage; 925 926 if (!IS_24XX(isp)) { 927 isp_prt(isp, ISP_LOGERR, "%s: called for non-24XX card", __func__); 928 return (0); 929 } 930 931 if (abts->abts_header.rqs_entry_type != RQSTYPE_ABTS_RCVD) { 932 isp_prt(isp, ISP_LOGERR, "%s: called for non-ABTS entry (0x%x)", __func__, abts->abts_header.rqs_entry_type); 933 return (0); 934 } 935 936 ISP_MEMCPY(rsp, abts, QENTRY_LEN); 937 rsp->abts_rsp_header.rqs_entry_type = RQSTYPE_ABTS_RSP; 938 939 /* 940 * Swap destination and source for response. 941 */ 942 rsp->abts_rsp_r_ctl = BA_ACC; 943 tmpw = rsp->abts_rsp_did_lo; 944 tmpb = rsp->abts_rsp_did_hi; 945 rsp->abts_rsp_did_lo = rsp->abts_rsp_sid_lo; 946 rsp->abts_rsp_did_hi = rsp->abts_rsp_sid_hi; 947 rsp->abts_rsp_sid_lo = tmpw; 948 rsp->abts_rsp_sid_hi = tmpb; 949 950 rsp->abts_rsp_f_ctl_hi ^= 0x80; /* invert Exchange Context */ 951 rsp->abts_rsp_f_ctl_hi &= ~0x7f; /* clear Sequence Initiator and other bits */ 952 rsp->abts_rsp_f_ctl_hi |= 0x10; /* abort the whole exchange */ 953 rsp->abts_rsp_f_ctl_hi |= 0x8; /* last data frame of sequence */ 954 rsp->abts_rsp_f_ctl_hi |= 0x1; /* transfer Sequence Initiative */ 955 rsp->abts_rsp_f_ctl_lo = 0; 956 957 if (errno == 0) { 958 uint16_t rx_id, ox_id; 959 960 rx_id = rsp->abts_rsp_rx_id; 961 ox_id = rsp->abts_rsp_ox_id; 962 ISP_MEMZERO(&rsp->abts_rsp_payload.ba_acc, sizeof (rsp->abts_rsp_payload.ba_acc)); 963 isp_prt(isp, ISP_LOGTINFO, "[0x%x] ABTS of 0x%x being BA_ACC'd", rsp->abts_rsp_rxid_abts, rsp->abts_rsp_rxid_task); 964 rsp->abts_rsp_payload.ba_acc.aborted_rx_id = rx_id; 965 rsp->abts_rsp_payload.ba_acc.aborted_ox_id = ox_id; 966 rsp->abts_rsp_payload.ba_acc.high_seq_cnt = 0xffff; 967 } else { 968 ISP_MEMZERO(&rsp->abts_rsp_payload.ba_rjt, sizeof (rsp->abts_rsp_payload.ba_acc)); 969 switch (errno) { 970 case ENOMEM: 971 rsp->abts_rsp_payload.ba_rjt.reason = 5; /* Logical Unit Busy */ 972 break; 973 default: 974 rsp->abts_rsp_payload.ba_rjt.reason = 9; /* Unable to perform command request */ 975 break; 976 } 977 } 978 return (isp_target_put_entry(isp, rsp)); 979 } 980 981 static void 982 isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep) 983 { 984 int lun, iid; 985 986 if (ISP_CAP_SCCFW(isp)) { 987 lun = aep->at_scclun; 988 } else { 989 lun = aep->at_lun; 990 } 991 992 if (ISP_CAP_2KLOGIN(isp)) { 993 iid = ((at2e_entry_t *)aep)->at_iid; 994 } else { 995 iid = aep->at_iid; 996 } 997 998 /* 999 * The firmware status (except for the QLTM_SVALID bit) indicates 1000 * why this ATIO was sent to us. 1001 * 1002 * If QLTM_SVALID is set, the firware has recommended Sense Data. 1003 * 1004 * If the DISCONNECTS DISABLED bit is set in the flags field, 1005 * we're still connected on the SCSI bus - i.e. the initiator 1006 * did not set DiscPriv in the identify message. We don't care 1007 * about this so it's ignored. 1008 */ 1009 1010 switch (aep->at_status & ~QLTM_SVALID) { 1011 case AT_PATH_INVALID: 1012 /* 1013 * ATIO rejected by the firmware due to disabled lun. 1014 */ 1015 isp_prt(isp, ISP_LOGERR, "rejected ATIO2 for disabled lun %x", lun); 1016 break; 1017 case AT_NOCAP: 1018 /* 1019 * Requested Capability not available 1020 * We sent an ATIO that overflowed the firmware's 1021 * command resource count. 1022 */ 1023 isp_prt(isp, ISP_LOGERR, "rejected ATIO2 for lun %x- command count overflow", lun); 1024 break; 1025 1026 case AT_BDR_MSG: 1027 /* 1028 * If we send an ATIO to the firmware to increment 1029 * its command resource count, and the firmware is 1030 * recovering from a Bus Device Reset, it returns 1031 * the ATIO with this status. We set the command 1032 * resource count in the Enable Lun entry and no 1033 * not increment it. Therefore we should never get 1034 * this status here. 1035 */ 1036 isp_prt(isp, ISP_LOGERR, atiocope, lun, 0); 1037 break; 1038 1039 case AT_CDB: /* Got a CDB */ 1040 /* 1041 * Punt to platform specific layer. 1042 */ 1043 isp_async(isp, ISPASYNC_TARGET_ACTION, aep); 1044 break; 1045 1046 case AT_RESET: 1047 /* 1048 * A bus reset came along an blew away this command. Why 1049 * they do this in addition the async event code stuff, 1050 * I dunno. 1051 * 1052 * Ignore it because the async event will clear things 1053 * up for us. 1054 */ 1055 isp_prt(isp, ISP_LOGERR, atior, lun, iid, 0); 1056 break; 1057 1058 1059 default: 1060 isp_prt(isp, ISP_LOGERR, "Unknown ATIO2 status 0x%x from handle %d for lun %x", aep->at_status, iid, lun); 1061 (void) isp_target_put_atio(isp, aep); 1062 break; 1063 } 1064 } 1065 1066 static void 1067 isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct) 1068 { 1069 void *xs; 1070 int pl = ISP_LOGTDEBUG2; 1071 char *fmsg = NULL; 1072 1073 if (ct->ct_syshandle) { 1074 xs = isp_find_xs(isp, ct->ct_syshandle); 1075 if (xs == NULL) { 1076 pl = ISP_LOGALL; 1077 } 1078 } else { 1079 xs = NULL; 1080 } 1081 1082 switch (ct->ct_status & ~QLTM_SVALID) { 1083 case CT_BUS_ERROR: 1084 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error"); 1085 /* FALL Through */ 1086 case CT_DATA_OVER: 1087 case CT_DATA_UNDER: 1088 case CT_OK: 1089 /* 1090 * There are generally 2 possibilities as to why we'd get 1091 * this condition: 1092 * We sent or received data. 1093 * We sent status & command complete. 1094 */ 1095 1096 break; 1097 1098 case CT_BDR_MSG: 1099 /* 1100 * Target Reset function received. 1101 * 1102 * The firmware generates an async mailbox interrupt to 1103 * notify us of this and returns outstanding CTIOs with this 1104 * status. These CTIOs are handled in that same way as 1105 * CT_ABORTED ones, so just fall through here. 1106 */ 1107 fmsg = "TARGET RESET"; 1108 /*FALLTHROUGH*/ 1109 case CT_RESET: 1110 if (fmsg == NULL) 1111 fmsg = "LIP Reset"; 1112 /*FALLTHROUGH*/ 1113 case CT_ABORTED: 1114 /* 1115 * When an Abort message is received the firmware goes to 1116 * Bus Free and returns all outstanding CTIOs with the status 1117 * set, then sends us an Immediate Notify entry. 1118 */ 1119 if (fmsg == NULL) { 1120 fmsg = "ABORT"; 1121 } 1122 1123 isp_prt(isp, ISP_LOGTDEBUG0, "CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid); 1124 break; 1125 1126 case CT_INVAL: 1127 /* 1128 * CTIO rejected by the firmware - invalid data direction. 1129 */ 1130 isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data direction"); 1131 break; 1132 1133 case CT_RSELTMO: 1134 fmsg = "failure to reconnect to initiator"; 1135 /*FALLTHROUGH*/ 1136 case CT_TIMEOUT: 1137 if (fmsg == NULL) 1138 fmsg = "command"; 1139 isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg); 1140 break; 1141 1142 case CT_ERR: 1143 fmsg = "Completed with Error"; 1144 /*FALLTHROUGH*/ 1145 case CT_LOGOUT: 1146 if (fmsg == NULL) 1147 fmsg = "Port Logout"; 1148 /*FALLTHROUGH*/ 1149 case CT_PORTUNAVAIL: 1150 if (fmsg == NULL) 1151 fmsg = "Port not available"; 1152 /*FALLTHROUGH*/ 1153 case CT_PORTCHANGED: 1154 if (fmsg == NULL) 1155 fmsg = "Port Changed"; 1156 /*FALLTHROUGH*/ 1157 case CT_NOACK: 1158 if (fmsg == NULL) 1159 fmsg = "unacknowledged Immediate Notify pending"; 1160 isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg); 1161 break; 1162 1163 case CT_INVRXID: 1164 /* 1165 * CTIO rejected by the firmware because an invalid RX_ID. 1166 * Just print a message. 1167 */ 1168 isp_prt(isp, ISP_LOGWARN, "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid); 1169 break; 1170 1171 default: 1172 isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x", ct->ct_status & ~QLTM_SVALID); 1173 break; 1174 } 1175 1176 if (xs == NULL) { 1177 /* 1178 * There may be more than one CTIO for a data transfer, 1179 * or this may be a status CTIO we're not monitoring. 1180 * 1181 * The assumption is that they'll all be returned in the 1182 * order we got them. 1183 */ 1184 if (ct->ct_syshandle == 0) { 1185 if ((ct->ct_flags & CT2_SENDSTATUS) == 0) { 1186 isp_prt(isp, pl, "intermediate CTIO completed ok"); 1187 } else { 1188 isp_prt(isp, pl, "unmonitored CTIO completed ok"); 1189 } 1190 } else { 1191 isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID); 1192 } 1193 } else { 1194 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) { 1195 ISP_DMAFREE(isp, xs, ct->ct_syshandle); 1196 } 1197 if (ct->ct_flags & CT2_SENDSTATUS) { 1198 /* 1199 * Sent status and command complete. 1200 * 1201 * We're now really done with this command, so we 1202 * punt to the platform dependent layers because 1203 * only there can we do the appropriate command 1204 * complete thread synchronization. 1205 */ 1206 isp_prt(isp, pl, "status CTIO complete"); 1207 } else { 1208 /* 1209 * Final CTIO completed. Release DMA resources and 1210 * notify platform dependent layers. 1211 */ 1212 isp_prt(isp, pl, "data CTIO complete"); 1213 } 1214 isp_async(isp, ISPASYNC_TARGET_ACTION, ct); 1215 /* 1216 * The platform layer will destroy the handle if appropriate. 1217 */ 1218 } 1219 } 1220 1221 static void 1222 isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct) 1223 { 1224 void *xs; 1225 int pl = ISP_LOGTDEBUG2; 1226 char *fmsg = NULL; 1227 1228 if (ct->ct_syshandle) { 1229 xs = isp_find_xs(isp, ct->ct_syshandle); 1230 if (xs == NULL) { 1231 pl = ISP_LOGALL; 1232 } 1233 } else { 1234 xs = NULL; 1235 } 1236 1237 switch (ct->ct_nphdl) { 1238 case CT7_BUS_ERROR: 1239 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error"); 1240 /* FALL Through */ 1241 case CT7_DATA_OVER: 1242 case CT7_DATA_UNDER: 1243 case CT7_OK: 1244 /* 1245 * There are generally 2 possibilities as to why we'd get 1246 * this condition: 1247 * We sent or received data. 1248 * We sent status & command complete. 1249 */ 1250 1251 break; 1252 1253 case CT7_RESET: 1254 if (fmsg == NULL) { 1255 fmsg = "LIP Reset"; 1256 } 1257 /*FALLTHROUGH*/ 1258 case CT7_ABORTED: 1259 /* 1260 * When an Abort message is received the firmware goes to 1261 * Bus Free and returns all outstanding CTIOs with the status 1262 * set, then sends us an Immediate Notify entry. 1263 */ 1264 if (fmsg == NULL) { 1265 fmsg = "ABORT"; 1266 } 1267 isp_prt(isp, ISP_LOGTDEBUG0, "CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid); 1268 break; 1269 1270 case CT7_TIMEOUT: 1271 if (fmsg == NULL) { 1272 fmsg = "command"; 1273 } 1274 isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg); 1275 break; 1276 1277 case CT7_ERR: 1278 fmsg = "Completed with Error"; 1279 /*FALLTHROUGH*/ 1280 case CT7_LOGOUT: 1281 if (fmsg == NULL) { 1282 fmsg = "Port Logout"; 1283 } 1284 /*FALLTHROUGH*/ 1285 case CT7_PORTUNAVAIL: 1286 if (fmsg == NULL) { 1287 fmsg = "Port not available"; 1288 } 1289 /*FALLTHROUGH*/ 1290 case CT7_PORTCHANGED: 1291 if (fmsg == NULL) { 1292 fmsg = "Port Changed"; 1293 } 1294 isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg); 1295 break; 1296 1297 case CT7_INVRXID: 1298 /* 1299 * CTIO rejected by the firmware because an invalid RX_ID. 1300 * Just print a message. 1301 */ 1302 isp_prt(isp, ISP_LOGWARN, "CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid); 1303 break; 1304 1305 case CT7_REASSY_ERR: 1306 isp_prt(isp, ISP_LOGWARN, "reassembly error"); 1307 break; 1308 1309 case CT7_SRR: 1310 isp_prt(isp, ISP_LOGTDEBUG0, "SRR received"); 1311 break; 1312 1313 default: 1314 isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x", ct->ct_nphdl); 1315 break; 1316 } 1317 1318 if (xs == NULL) { 1319 /* 1320 * There may be more than one CTIO for a data transfer, 1321 * or this may be a status CTIO we're not monitoring. 1322 * 1323 * The assumption is that they'll all be returned in the 1324 * order we got them. 1325 */ 1326 if (ct->ct_syshandle == 0) { 1327 if (ct->ct_flags & CT7_TERMINATE) { 1328 isp_prt(isp, ISP_LOGINFO, "termination of [RX_ID 0x%x] complete", ct->ct_rxid); 1329 } else if ((ct->ct_flags & CT7_SENDSTATUS) == 0) { 1330 isp_prt(isp, pl, "intermediate CTIO completed ok"); 1331 } else { 1332 isp_prt(isp, pl, "unmonitored CTIO completed ok"); 1333 } 1334 } else { 1335 isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_nphdl); 1336 } 1337 } else { 1338 if ((ct->ct_flags & CT7_DATAMASK) != CT7_NO_DATA) { 1339 ISP_DMAFREE(isp, xs, ct->ct_syshandle); 1340 } 1341 if (ct->ct_flags & CT7_SENDSTATUS) { 1342 /* 1343 * Sent status and command complete. 1344 * 1345 * We're now really done with this command, so we 1346 * punt to the platform dependent layers because 1347 * only there can we do the appropriate command 1348 * complete thread synchronization. 1349 */ 1350 isp_prt(isp, pl, "status CTIO complete"); 1351 } else { 1352 /* 1353 * Final CTIO completed. Release DMA resources and 1354 * notify platform dependent layers. 1355 */ 1356 isp_prt(isp, pl, "data CTIO complete"); 1357 } 1358 isp_async(isp, ISPASYNC_TARGET_ACTION, ct); 1359 /* 1360 * The platform layer will destroy the handle if appropriate. 1361 */ 1362 } 1363 } 1364 1365 static void 1366 isp_handle_24xx_inotify(ispsoftc_t *isp, in_fcentry_24xx_t *inot_24xx) 1367 { 1368 uint8_t ochan, chan, lochan, hichan; 1369 1370 /* 1371 * Check to see whether we got a wildcard channel. 1372 * If so, we have to iterate over all channels. 1373 */ 1374 ochan = chan = ISP_GET_VPIDX(isp, inot_24xx->in_vpidx); 1375 if (chan == 0xff) { 1376 lochan = 0; 1377 hichan = isp->isp_nchan; 1378 } else { 1379 if (chan >= isp->isp_nchan) { 1380 char buf[64]; 1381 ISP_SNPRINTF(buf, sizeof buf, "%s: bad channel %d for status 0x%x", __func__, chan, inot_24xx->in_status); 1382 isp_print_bytes(isp, buf, QENTRY_LEN, inot_24xx); 1383 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot_24xx); 1384 return; 1385 } 1386 lochan = chan; 1387 hichan = chan + 1; 1388 } 1389 isp_prt(isp, ISP_LOGTDEBUG1, "%s: Immediate Notify Channels %d..%d status=0x%x seqid=0x%x", __func__, lochan, hichan-1, inot_24xx->in_status, inot_24xx->in_rxid); 1390 switch (inot_24xx->in_status) { 1391 case IN24XX_LIP_RESET: 1392 case IN24XX_LINK_RESET: 1393 case IN24XX_PORT_LOGOUT: 1394 case IN24XX_PORT_CHANGED: 1395 case IN24XX_LINK_FAILED: 1396 case IN24XX_SRR_RCVD: 1397 case IN24XX_ELS_RCVD: 1398 for (chan = lochan; chan < hichan; chan++) { 1399 if (FCPARAM(isp, chan)->role == ISP_ROLE_NONE) 1400 continue; 1401 inot_24xx->in_reserved = 0; /* clear this for later usage */ 1402 inot_24xx->in_vpidx = chan; 1403 isp_async(isp, ISPASYNC_TARGET_ACTION, inot_24xx); 1404 } 1405 inot_24xx->in_vpidx = ochan; 1406 break; 1407 default: 1408 isp_prt(isp, ISP_LOGINFO, "%s: unhandled status (0x%x) for chan %d", 1409 __func__, inot_24xx->in_status, chan); 1410 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot_24xx); 1411 break; 1412 } 1413 } 1414 #endif 1415