isp_target.c revision 55385
1/* $FreeBSD: head/sys/dev/isp/isp_target.c 55385 2000-01-04 03:43:03Z mjacob $ */ 2/* 3 * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters. 4 * 5 * Copyright (c) 1999 by Matthew Jacob 6 * All rights reserved. 7 * mjacob@feral.com 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice immediately at the beginning of the file, without modification, 14 * this list of conditions, and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34/* 35 * Include header file appropriate for platform we're building on. 36 */ 37 38#ifdef __NetBSD__ 39#include <dev/ic/isp_netbsd.h> 40#endif 41#ifdef __FreeBSD__ 42#include <dev/isp/isp_freebsd.h> 43#endif 44#ifdef __OpenBSD__ 45#include <dev/ic/isp_openbsd.h> 46#endif 47#ifdef __linux__ 48#include "isp_linux.h" 49#endif 50 51#ifdef ISP_TARGET_MODE 52int isp_tdebug = 0; 53 54static void isp_got_msg __P((struct ispsoftc *, int, in_entry_t *)); 55static void isp_got_msg_fc __P((struct ispsoftc *, int, in_fcentry_t *)); 56static void isp_notify_ack __P((struct ispsoftc *, void *)); 57static void isp_handle_atio(struct ispsoftc *, at_entry_t *); 58static void isp_handle_atio2(struct ispsoftc *, at2_entry_t *); 59static void isp_handle_ctio(struct ispsoftc *, ct_entry_t *); 60static void isp_handle_ctio2(struct ispsoftc *, ct2_entry_t *); 61 62/* 63 * The Qlogic driver gets an interrupt to look at response queue entries. 64 * Some of these are status completions for initiatior mode commands, but 65 * if target mode is enabled, we get a whole wad of response queue entries 66 * to be handled here. 67 * 68 * Basically the split into 3 main groups: Lun Enable/Modification responses, 69 * SCSI Command processing, and Immediate Notification events. 70 * 71 * You start by writing a request queue entry to enable target mode (and 72 * establish some resource limitations which you can modify later). 73 * The f/w responds with a LUN ENABLE or LUN MODIFY response with 74 * the status of this action. If the enable was successful, you can expect... 75 * 76 * Response queue entries with SCSI commands encapsulate show up in an ATIO 77 * (Accept Target IO) type- sometimes with enough info to stop the command at 78 * this level. Ultimately the driver has to feed back to the f/w's request 79 * queue a sequence of CTIOs (continue target I/O) that describe data to 80 * be moved and/or status to be sent) and finally finishing with sending 81 * to the f/w's response queue an ATIO which then completes the handshake 82 * with the f/w for that command. There's a lot of variations on this theme, 83 * including flags you can set in the CTIO for the Qlogic 2X00 fibre channel 84 * cards that 'auto-replenish' the f/w's ATIO count, but this is the basic 85 * gist of it. 86 * 87 * The third group that can show up in the response queue are Immediate 88 * Notification events. These include things like notifications of SCSI bus 89 * resets, or Bus Device Reset messages or other messages received. This 90 * a classic oddbins area. It can get a little wierd because you then turn 91 * around and acknowledge the Immediate Notify by writing an entry onto the 92 * request queue and then the f/w turns around and gives you an acknowledgement 93 * to *your* acknowledgement on the response queue (the idea being to let 94 * the f/w tell you when the event is *really* over I guess). 95 * 96 */ 97 98 99/* 100 * A new response queue entry has arrived. The interrupt service code 101 * has already swizzled it into the platform dependent from canonical form. 102 * 103 * Because of the way this driver is designed, unfortunately most of the 104 * actual synchronization work has to be done in the platform specific 105 * code- we have no synchroniation primitives in the common code. 106 */ 107 108int 109isp_target_notify(isp, vptr, optrp) 110 struct ispsoftc *isp; 111 void *vptr; 112 u_int16_t *optrp; 113{ 114 u_int16_t status, seqid; 115 union { 116 at_entry_t *atiop; 117 at2_entry_t *at2iop; 118 ct_entry_t *ctiop; 119 ct2_entry_t *ct2iop; 120 lun_entry_t *lunenp; 121 in_entry_t *inotp; 122 in_fcentry_t *inot_fcp; 123 na_entry_t *nackp; 124 na_fcentry_t *nack_fcp; 125 isphdr_t *hp; 126 void * *vp; 127#define atiop unp.atiop 128#define at2iop unp.at2iop 129#define ctiop unp.ctiop 130#define ct2iop unp.ct2iop 131#define lunenp unp.lunenp 132#define inotp unp.inotp 133#define inot_fcp unp.inot_fcp 134#define nackp unp.nackp 135#define nack_fcp unp.nack_fcp 136#define hdrp unp.hp 137 } unp; 138 int bus, rval = 0; 139 140 unp.vp = vptr; 141 142 ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr); 143 144 switch(hdrp->rqs_entry_type) { 145 case RQSTYPE_ATIO: 146 isp_handle_atio(isp, atiop); 147 break; 148 case RQSTYPE_CTIO: 149 isp_handle_ctio(isp, ctiop); 150 break; 151 case RQSTYPE_ATIO2: 152 isp_handle_atio2(isp, at2iop); 153 break; 154 case RQSTYPE_CTIO2: 155 isp_handle_ctio2(isp, ct2iop); 156 break; 157 case RQSTYPE_ENABLE_LUN: 158 case RQSTYPE_MODIFY_LUN: 159 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, vptr); 160 break; 161 162 case RQSTYPE_NOTIFY: 163 /* 164 * Either the ISP received a SCSI message it can't 165 * handle, or it's returning an Immed. Notify entry 166 * we sent. We can send Immed. Notify entries to 167 * increment the firmware's resource count for them 168 * (we set this initially in the Enable Lun entry). 169 */ 170 if (IS_FC(isp)) { 171 status = inot_fcp->in_status; 172 seqid = inot_fcp->in_seqid; 173 } else { 174 status = inotp->in_status & 0xff; 175 seqid = inotp->in_seqid; 176 } 177 bus = 0; /* XXX: Which Channel? */ 178 ITDEBUG(2, ("isp_target_notify: Immediate Notify, " 179 "status=0x%x seqid=0x%x\n", status, seqid)); 180 switch (status) { 181 case IN_RESET: 182 (void) isp_async(isp, ISPASYNC_BUS_RESET, &bus); 183 break; 184 case IN_MSG_RECEIVED: 185 case IN_IDE_RECEIVED: 186 if (IS_FC(isp)) { 187 isp_got_msg_fc(isp, bus, vptr); 188 } else { 189 isp_got_msg(isp, bus, vptr); 190 } 191 break; 192 case IN_RSRC_UNAVAIL: 193 PRINTF("%s: Firmware out of ATIOs\n", isp->isp_name); 194 break; 195 case IN_ABORT_TASK: 196 PRINTF("%s: Abort Task for Initiator %d RX_ID 0x%x\n", 197 isp->isp_name, inot_fcp->in_iid, seqid); 198 break; 199 case IN_PORT_LOGOUT: 200 PRINTF("%s: Port Logout for Initiator %d RX_ID 0x%x\n", 201 isp->isp_name, inot_fcp->in_iid, seqid); 202 break; 203 case IN_PORT_CHANGED: 204 PRINTF("%s: Port Changed for Initiator %d RX_ID 0x%x\n", 205 isp->isp_name, inot_fcp->in_iid, seqid); 206 break; 207 case IN_GLOBAL_LOGO: 208 PRINTF("%s: All ports logged out\n", isp->isp_name); 209 break; 210 default: 211 PRINTF("%s: bad status (0x%x) in isp_target_notify\n", 212 isp->isp_name, status); 213 break; 214 } 215 isp_notify_ack(isp, vptr); 216 break; 217 218 case RQSTYPE_NOTIFY_ACK: 219 /* 220 * The ISP is acknowledging our acknowledgement of an 221 * Immediate Notify entry for some asynchronous event. 222 */ 223 if (IS_FC(isp)) { 224 ITDEBUG(2, ("%s: Notify Ack status=0x%x seqid 0x%x\n", 225 isp->isp_name, nack_fcp->na_status, 226 nack_fcp->na_seqid)); 227 } else { 228 ITDEBUG(2, ("%s: Notify Ack event 0x%x status=0x%x " 229 "seqid 0x%x\n", isp->isp_name, nackp->na_event, 230 nackp->na_status, nackp->na_seqid)); 231 } 232 break; 233 default: 234 PRINTF("%s: Unknown entry type 0x%x in isp_target_notify", 235 isp->isp_name, hdrp->rqs_entry_type); 236 rval = -1; 237 break; 238 } 239#undef atiop 240#undef at2iop 241#undef ctiop 242#undef ct2iop 243#undef lunenp 244#undef inotp 245#undef inot_fcp 246#undef nackp 247#undef nack_fcp 248#undef hdrp 249 return (rval); 250} 251 252 253/* 254 * Toggle (on/off) target mode for bus/target/lun 255 * 256 * The caller has checked for overlap and legality. 257 * 258 * Note that not all of bus, target or lun can be paid attention to. 259 * Note also that this action will not be complete until the f/w writes 260 * response entry. The caller is responsible for synchronizing this. 261 */ 262int 263isp_lun_cmd(isp, cmd, bus, tgt, lun, opaque) 264 struct ispsoftc *isp; 265 int cmd; 266 int bus; 267 int tgt; 268 int lun; 269 u_int32_t opaque; 270{ 271 lun_entry_t el; 272 u_int16_t iptr, optr; 273 void *outp; 274 275 bus = bus; /* XXX */ 276 277 MEMZERO(&el, sizeof (el)); 278 el.le_cmd_count = DFLT_CMD_CNT; 279 el.le_in_count = DFLT_INOTIFY; 280 if (cmd == RQSTYPE_ENABLE_LUN) { 281 if (IS_SCSI(isp)) { 282 el.le_flags = LUN_TQAE; 283 el.le_cdb6len = 12; 284 el.le_cdb7len = 12; 285 } 286 } else if (cmd == -RQSTYPE_ENABLE_LUN) { 287 cmd = RQSTYPE_ENABLE_LUN; 288 el.le_cmd_count = 0; 289 el.le_in_count = 0; 290 } else if (cmd == -RQSTYPE_MODIFY_LUN) { 291 cmd = RQSTYPE_MODIFY_LUN; 292 el.le_ops = LUN_CCDECR | LUN_INDECR; 293 } else { 294 el.le_ops = LUN_CCINCR | LUN_ININCR; 295 } 296 el.le_header.rqs_entry_type = cmd; 297 el.le_header.rqs_entry_count = 1; 298 el.le_reserved = opaque; 299 if (IS_SCSI(isp)) { 300 el.le_tgt = tgt; 301 el.le_lun = lun; 302#ifndef ISP2100_SCCLUN 303 } else { 304 el.le_lun = lun; 305#endif 306 } 307 308 if (isp_getrqentry(isp, &iptr, &optr, &outp)) { 309 PRINTF("%s: Request Queue Overflow in isp_lun_cmd\n", 310 isp->isp_name); 311 return (-1); 312 } 313 ISP_SWIZ_ENABLE_LUN(isp, outp, &el); 314 ISP_TDQE(isp, "isp_lun_cmd", (int) optr, &el); 315 ISP_ADD_REQUEST(isp, iptr); 316 return (0); 317} 318 319 320int 321isp_target_put_entry(isp, ap) 322 struct ispsoftc *isp; 323 void *ap; 324{ 325 void *outp; 326 u_int16_t iptr, optr; 327 u_int8_t etype = ((isphdr_t *) ap)->rqs_entry_type; 328 int s = splcam(); 329 330 if (isp_getrqentry(isp, &iptr, &optr, &outp)) { 331 splx(s); 332 PRINTF("%s: Request Queue Overflow in isp_target_put_entry " 333 "for type 0x%x\n", isp->isp_name, etype); 334 return (-1); 335 } 336 switch (etype) { 337 case RQSTYPE_ATIO: 338 ISP_SWIZ_ATIO(isp, outp, ap); 339 break; 340 case RQSTYPE_ATIO2: 341 ISP_SWIZ_ATIO2(isp, outp, ap); 342 break; 343 case RQSTYPE_CTIO: 344 ISP_SWIZ_CTIO(isp, outp, ap); 345 break; 346 case RQSTYPE_CTIO2: 347 ISP_SWIZ_CTIO2(isp, outp, ap); 348 break; 349 default: 350 splx(s); 351 PRINTF("%s: Unknown type 0x%x in isp_put_entry\n", 352 isp->isp_name, etype); 353 return (-1); 354 } 355 356 ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);; 357 358 ISP_ADD_REQUEST(isp, iptr); 359 splx(s); 360 return (0); 361} 362 363int 364isp_target_put_atio(isp, iid, tgt, lun, ttype, tval) 365 struct ispsoftc *isp; 366 int iid; 367 int tgt; 368 int lun; 369 int ttype; 370 int tval; 371{ 372 union { 373 at_entry_t _atio; 374 at2_entry_t _atio2; 375 } atun; 376 377 MEMZERO(&atun, sizeof atun); 378 if (IS_FC(isp)) { 379 atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2; 380 atun._atio2.at_header.rqs_entry_count = 1; 381#ifdef ISP2100_SCCLUN 382 atun._atio2.at_scclun = (uint16_t) lun; 383#else 384 atun._atio2.at_lun = (uint8_t) lun; 385#endif 386 atun._atio2.at_status = CT_OK; 387 } else { 388 atun._atio.at_header.rqs_entry_type = RQSTYPE_ATIO; 389 atun._atio.at_header.rqs_entry_count = 1; 390 atun._atio.at_iid = iid; 391 atun._atio.at_tgt = tgt; 392 atun._atio.at_lun = lun; 393 atun._atio.at_tag_type = ttype; 394 atun._atio.at_tag_val = tval; 395 atun._atio.at_status = CT_OK; 396 } 397 return (isp_target_put_entry(isp, &atun)); 398} 399 400/* 401 * Command completion- both for handling cases of no resources or 402 * no blackhole driver, or other cases where we have to, inline, 403 * finish the command sanely, or for normal command completion. 404 * 405 * The 'completion' code value has the scsi status byte in the low 8 bits. 406 * If status is a CHECK CONDITION and bit 8 is nonzero, then bits 12..15 have 407 * the sense key and bits 16..23 have the ASCQ and bits 24..31 have the ASC 408 * values. 409 * 410 * NB: the key, asc, ascq, cannot be used for parallel SCSI as it doesn't 411 * NB: inline SCSI sense reporting. 412 * 413 * For both parallel && fibre channel, we use the feature that does 414 * an automatic resource autoreplenish so we don't have then later do 415 * put of an atio to replenish the f/w's resource count. 416 */ 417 418int 419isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int32_t hdl) 420{ 421 int sts; 422 union { 423 ct_entry_t _ctio; 424 ct2_entry_t _ctio2; 425 } un; 426 427 MEMZERO(&un, sizeof un); 428 sts = code & 0xff; 429 430 if (IS_FC(isp)) { 431 at2_entry_t *aep = arg; 432 ct2_entry_t *cto = &un._ctio2; 433 434 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2; 435 cto->ct_header.rqs_entry_count = 1; 436 cto->ct_iid = aep->at_iid; 437#ifndef ISP2100_SCCLUN 438 cto->ct_lun = aep->at_lun; 439#endif 440 cto->ct_rxid = aep->at_rxid; 441 cto->rsp.m1.ct_scsi_status = sts; 442 cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1; 443 if (hdl == 0) { 444 cto->ct_flags |= CT2_CCINCR; 445 } 446 if (aep->at_datalen) { 447 cto->ct_resid = aep->at_datalen; 448 cto->ct_flags |= CT2_DATA_UNDER; 449 } 450 if (sts == SCSI_CHECK && (sts & 0x100)) { 451 cto->rsp.m1.ct_resp[0] = 0xf0; 452 cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf; 453 cto->rsp.m1.ct_resp[7] = 8; 454 cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff; 455 cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff; 456 cto->rsp.m1.ct_senselen = 16; 457 cto->ct_flags |= CT2_SNSLEN_VALID; 458 } 459 cto->ct_reserved = hdl; 460 } else { 461 at_entry_t *aep = arg; 462 ct_entry_t *cto = &un._ctio; 463 464 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO; 465 cto->ct_header.rqs_entry_count = 1; 466 cto->ct_iid = aep->at_iid; 467 cto->ct_tgt = aep->at_tgt; 468 cto->ct_lun = aep->at_lun; 469 cto->ct_tag_type = aep->at_tag_type; 470 cto->ct_tag_val = aep->at_tag_val; 471 cto->ct_flags = CT_SENDSTATUS | CT_NO_DATA; 472 if (hdl == 0) { 473 cto->ct_flags |= CT_CCINCR; 474 } 475 cto->ct_scsi_status = sts; 476 cto->ct_reserved = hdl; 477 } 478 return (isp_target_put_entry(isp, &un)); 479} 480 481void 482isp_target_async(isp, bus, event) 483 struct ispsoftc *isp; 484 int bus; 485 int event; 486{ 487 tmd_event_t evt; 488 tmd_msg_t msg; 489 490 switch (event) { 491 /* 492 * These three we handle here to propagate an effective bus reset 493 * upstream, but these do not require any immediate notify actions 494 * so we return when done. 495 */ 496 case ASYNC_LIP_OCCURRED: 497 case ASYNC_LOOP_UP: 498 case ASYNC_LOOP_DOWN: 499 evt.ev_bus = bus; 500 evt.ev_event = event; 501 (void) isp_async(isp, ISPASYNC_TARGET_EVENT, &evt); 502 return; 503 504 case ASYNC_LOOP_RESET: 505 case ASYNC_BUS_RESET: 506 case ASYNC_TIMEOUT_RESET: 507 if (IS_FC(isp)) { 508 return; /* we'll be getting an inotify instead */ 509 } 510 evt.ev_bus = bus; 511 evt.ev_event = event; 512 (void) isp_async(isp, ISPASYNC_TARGET_EVENT, &evt); 513 break; 514 case ASYNC_DEVICE_RESET: 515 /* 516 * Bus Device Reset resets a specific target, so 517 * we pass this as a synthesized message. 518 */ 519 MEMZERO(&msg, sizeof msg); 520 if (IS_FC(isp)) { 521 msg.nt_iid = 522 ((fcparam *)isp->isp_param)->isp_loopid; 523 } else { 524 msg.nt_iid = 525 ((sdparam *)isp->isp_param)->isp_initiator_id; 526 } 527 msg.nt_bus = bus; 528 msg.nt_msg[0] = MSG_BUS_DEV_RESET; 529 (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg); 530 break; 531 default: 532 PRINTF("%s: isp_target_async: unknown event 0x%x\n", 533 isp->isp_name, event); 534 break; 535 } 536 isp_notify_ack(isp, NULL); 537} 538 539 540/* 541 * Process a received message. 542 * The ISP firmware can handle most messages, there are only 543 * a few that we need to deal with: 544 * - abort: clean up the current command 545 * - abort tag and clear queue 546 */ 547 548static void 549isp_got_msg(isp, bus, inp) 550 struct ispsoftc *isp; 551 int bus; 552 in_entry_t *inp; 553{ 554 u_int8_t status = inp->in_status & ~QLTM_SVALID; 555 556 if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) { 557 tmd_msg_t msg; 558 559 MEMZERO(&msg, sizeof (msg)); 560 msg.nt_bus = bus; 561 msg.nt_iid = inp->in_iid; 562 msg.nt_tgt = inp->in_tgt; 563 msg.nt_lun = inp->in_lun; 564 msg.nt_tagtype = inp->in_tag_type; 565 msg.nt_tagval = inp->in_tag_val; 566 MEMCPY(msg.nt_msg, inp->in_msg, IN_MSGLEN); 567 (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg); 568 } else { 569 PRINTF("%s: unknown immediate notify status 0x%x\n", 570 isp->isp_name, inp->in_status); 571 } 572} 573 574/* 575 * Synthesize a message from the task management flags in a FCP_CMND_IU. 576 */ 577static void 578isp_got_msg_fc(isp, bus, inp) 579 struct ispsoftc *isp; 580 int bus; 581 in_fcentry_t *inp; 582{ 583 static char *f1 = "%s: %s from iid %d lun %d seq 0x%x\n"; 584 static char *f2 = 585 "%s: unknown %s 0x%x lun %d iid %d task flags 0x%x seq 0x%x\n"; 586 587 if (inp->in_status != IN_MSG_RECEIVED) { 588 PRINTF(f2, isp->isp_name, "immediate notify status", 589 inp->in_status, inp->in_lun, inp->in_iid, 590 inp->in_task_flags, inp->in_seqid); 591 } else { 592 tmd_msg_t msg; 593 594 MEMZERO(&msg, sizeof (msg)); 595 msg.nt_bus = bus; 596 msg.nt_iid = inp->in_iid; 597#ifdef ISP2100_SCCLUN 598 msg.nt_lun = inp->in_scclun; 599#else 600 msg.nt_lun = inp->in_lun; 601#endif 602 msg.nt_tagval = inp->in_seqid; 603 604 if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK) { 605 PRINTF(f1, isp->isp_name, "ABORT TASK", 606 inp->in_iid, inp->in_lun, inp->in_seqid); 607 msg.nt_msg[0] = MSG_ABORT_TAG; 608 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) { 609 PRINTF(f1, isp->isp_name, "CLEAR TASK SET", 610 inp->in_iid, inp->in_lun, inp->in_seqid); 611 msg.nt_msg[0] = MSG_CLEAR_QUEUE; 612 } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) { 613 PRINTF(f1, isp->isp_name, "TARGET RESET", 614 inp->in_iid, inp->in_lun, inp->in_seqid); 615 msg.nt_msg[0] = MSG_BUS_DEV_RESET; 616 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) { 617 PRINTF(f1, isp->isp_name, "CLEAR ACA", 618 inp->in_iid, inp->in_lun, inp->in_seqid); 619 /* ???? */ 620 msg.nt_msg[0] = MSG_REL_RECOVERY; 621 } else if (inp->in_task_flags & TASK_FLAGS_TERMINATE_TASK) { 622 PRINTF(f1, isp->isp_name, "TERMINATE TASK", 623 inp->in_iid, inp->in_lun, inp->in_seqid); 624 msg.nt_msg[0] = MSG_TERM_IO_PROC; 625 } else { 626 PRINTF(f2, isp->isp_name, "task flag", 627 inp->in_status, inp->in_lun, inp->in_iid, 628 inp->in_task_flags, inp->in_seqid); 629 } 630 if (msg.nt_msg[0]) { 631 (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg); 632 } 633 } 634} 635 636static void 637isp_notify_ack(isp, arg) 638 struct ispsoftc *isp; 639 void *arg; 640{ 641 char storage[QENTRY_LEN]; 642 u_int16_t iptr, optr; 643 void *outp; 644 645 if (isp_getrqentry(isp, &iptr, &optr, &outp)) { 646 PRINTF("%s: Request Queue Overflow For isp_notify_ack\n", 647 isp->isp_name); 648 return; 649 } 650 651 MEMCPY(storage, arg, sizeof (isphdr_t)); 652 MEMZERO(&storage[sizeof (isphdr_t)], QENTRY_LEN - sizeof (isphdr_t)); 653 654 if (IS_FC(isp)) { 655 na_fcentry_t *na = (na_fcentry_t *) storage; 656 if (arg) { 657 in_fcentry_t *inp = arg; 658 na->na_iid = inp->in_iid; 659#ifdef ISP2100_SCCLUN 660 na->na_lun = inp->in_scclun; 661#else 662 na->na_lun = inp->in_lun; 663#endif 664 na->na_task_flags = inp->in_task_flags; 665 na->na_seqid = inp->in_seqid; 666 na->na_flags = NAFC_RCOUNT; 667 if (inp->in_status == IN_RESET) { 668 na->na_flags |= NAFC_RST_CLRD; 669 } 670 } else { 671 na->na_flags = NAFC_RST_CLRD; 672 } 673 ISP_SWIZ_NOT_ACK_FC(isp, outp, na); 674 } else { 675 na_entry_t *na = (na_entry_t *) storage; 676 if (arg) { 677 in_entry_t *inp = arg; 678 na->na_iid = inp->in_iid; 679 na->na_lun = inp->in_lun; 680 na->na_tgt = inp->in_tgt; 681 na->na_seqid = inp->in_seqid; 682 if (inp->in_status == IN_RESET) { 683 na->na_flags = NA_RST_CLRD; 684 } 685 } else { 686 na->na_flags = NA_RST_CLRD; 687 } 688 ISP_SWIZ_NOT_ACK(isp, outp, na); 689 } 690 ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage); 691 ISP_ADD_REQUEST(isp, iptr); 692} 693 694static void 695isp_handle_atio(isp, aep) 696 struct ispsoftc *isp; 697 at_entry_t *aep; 698{ 699 int lun; 700 lun = aep->at_lun; 701 /* 702 * The firmware status (except for the QLTM_SVALID bit) indicates 703 * why this ATIO was sent to us. 704 * 705 * If QLTM_SVALID is set, the firware has recommended Sense Data. 706 * 707 * If the DISCONNECTS DISABLED bit is set in the flags field, 708 * we're still connected on the SCSI bus - i.e. the initiator 709 * did not set DiscPriv in the identify message. We don't care 710 * about this so it's ignored. 711 */ 712 713 switch(aep->at_status & ~QLTM_SVALID) { 714 case AT_PATH_INVALID: 715 /* 716 * ATIO rejected by the firmware due to disabled lun. 717 */ 718 printf("%s: rejected ATIO for disabled lun %d\n", 719 isp->isp_name, lun); 720 break; 721 case AT_NOCAP: 722 /* 723 * Requested Capability not available 724 * We sent an ATIO that overflowed the firmware's 725 * command resource count. 726 */ 727 PRINTF("%s: rejected ATIO for lun %d because of command count" 728 " overflow\n", isp->isp_name, lun); 729 break; 730 731 case AT_BDR_MSG: 732 /* 733 * If we send an ATIO to the firmware to increment 734 * its command resource count, and the firmware is 735 * recovering from a Bus Device Reset, it returns 736 * the ATIO with this status. We set the command 737 * resource count in the Enable Lun entry and no 738 * not increment it. Therefore we should never get 739 * this status here. 740 */ 741 printf("%s: ATIO returned for lun %d because it was in the " 742 " middle of coping with a Bus Device Reset\n", 743 isp->isp_name, lun); 744 break; 745 746 case AT_CDB: /* Got a CDB */ 747 case AT_PHASE_ERROR: /* Bus Phase Sequence Error */ 748 /* 749 * Punt to platform specific layer. 750 */ 751 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep); 752 break; 753 754 case AT_RESET: 755 /* 756 * A bus reset came along an blew away this command. Why 757 * they do this in addition the async event code stuff, 758 * I dunno. 759 * 760 * Ignore it because the async event will clear things 761 * up for us. 762 */ 763 PRINTF("%s: ATIO returned for lun %d from initiator %d because" 764 " a Bus Reset occurred\n", isp->isp_name, lun, 765 aep->at_iid); 766 break; 767 768 769 default: 770 PRINTF("%s: Unknown ATIO status 0x%x from initiator %d for lun" 771 " %d\n", isp->isp_name, aep->at_status, aep->at_iid, lun); 772 (void) isp_target_put_atio(isp, aep->at_iid, aep->at_tgt, 773 lun, aep->at_tag_type, aep->at_tag_val); 774 break; 775 } 776} 777 778static void 779isp_handle_atio2(isp, aep) 780 struct ispsoftc *isp; 781 at2_entry_t *aep; 782{ 783 int lun; 784#ifdef ISP2100_SCCLUN 785 lun = aep->at_scclun; 786#else 787 lun = aep->at_lun; 788#endif 789 /* 790 * The firmware status (except for the QLTM_SVALID bit) indicates 791 * why this ATIO was sent to us. 792 * 793 * If QLTM_SVALID is set, the firware has recommended Sense Data. 794 * 795 * If the DISCONNECTS DISABLED bit is set in the flags field, 796 * we're still connected on the SCSI bus - i.e. the initiator 797 * did not set DiscPriv in the identify message. We don't care 798 * about this so it's ignored. 799 */ 800 801 switch(aep->at_status & ~QLTM_SVALID) { 802 case AT_PATH_INVALID: 803 /* 804 * ATIO rejected by the firmware due to disabled lun. 805 */ 806 printf("%s: rejected ATIO2 for disabled lun %d\n", 807 isp->isp_name, lun); 808 break; 809 case AT_NOCAP: 810 /* 811 * Requested Capability not available 812 * We sent an ATIO that overflowed the firmware's 813 * command resource count. 814 */ 815 PRINTF("%s: rejected ATIO2 for lun %d because of command count" 816 " overflow\n", isp->isp_name, lun); 817 break; 818 819 case AT_BDR_MSG: 820 /* 821 * If we send an ATIO to the firmware to increment 822 * its command resource count, and the firmware is 823 * recovering from a Bus Device Reset, it returns 824 * the ATIO with this status. We set the command 825 * resource count in the Enable Lun entry and no 826 * not increment it. Therefore we should never get 827 * this status here. 828 */ 829 printf("%s: ATIO2 returned for lun %d because it was in the " 830 " middle of coping with a Bus Device Reset\n", 831 isp->isp_name, lun); 832 break; 833 834 case AT_CDB: /* Got a CDB */ 835 /* 836 * Punt to platform specific layer. 837 */ 838 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep); 839 break; 840 841 case AT_RESET: 842 /* 843 * A bus reset came along an blew away this command. Why 844 * they do this in addition the async event code stuff, 845 * I dunno. 846 * 847 * Ignore it because the async event will clear things 848 * up for us. 849 */ 850 PRINTF("%s: ATIO2 returned for lun %d from initiator %d because" 851 " a Bus Reset occurred\n", isp->isp_name, lun, 852 aep->at_iid); 853 break; 854 855 856 default: 857 PRINTF("%s: Unknown ATIO2 status 0x%x from initiator %d for lun" 858 " %d\n", isp->isp_name, aep->at_status, aep->at_iid, lun); 859 (void) isp_target_put_atio(isp, aep->at_iid, 0, lun, 0, 0); 860 break; 861 } 862} 863 864static void 865isp_handle_ctio(isp, ct) 866 struct ispsoftc *isp; 867 ct_entry_t *ct; 868{ 869 ISP_SCSI_XFER_T *xs; 870 int pl = 0; 871 char *fmsg = NULL; 872 873 if (ct->ct_reserved) { 874 xs = isp_find_xs(isp, ct->ct_reserved); 875 if (xs == NULL) 876 pl = 0; 877 } else { 878 pl = 2; 879 xs = NULL; 880 } 881 882 switch(ct->ct_status & ~QLTM_SVALID) { 883 case CT_OK: 884 /* 885 * There are generally 3 possibilities as to why we'd get 886 * this condition: 887 * We disconnected after receiving a CDB. 888 * We sent or received data. 889 * We sent status & command complete. 890 */ 891 892 if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) { 893 /* 894 * Nothing to do in this case. 895 */ 896 IDPRINTF(pl, ("%s: CTIO- initiator disconnected OK\n", 897 isp->isp_name)); 898 return; 899 } 900 break; 901 902 case CT_BDR_MSG: 903 /* 904 * Bus Device Reset message received or the SCSI Bus has 905 * been Reset; the firmware has gone to Bus Free. 906 * 907 * The firmware generates an async mailbox interupt to 908 * notify us of this and returns outstanding CTIOs with this 909 * status. These CTIOs are handled in that same way as 910 * CT_ABORTED ones, so just fall through here. 911 */ 912 fmsg = "Bus Device Reset"; 913 /*FALLTHROUGH*/ 914 case CT_RESET: 915 if (fmsg == NULL) 916 fmsg = "Bus Reset"; 917 /*FALLTHROUGH*/ 918 case CT_ABORTED: 919 /* 920 * When an Abort message is received the firmware goes to 921 * Bus Free and returns all outstanding CTIOs with the status 922 * set, then sends us an Immediate Notify entry. 923 */ 924 if (fmsg == NULL) 925 fmsg = "ABORT TASK sent by Initiator"; 926 927 PRINTF("%s: CTIO destroyed by %s\n", isp->isp_name, fmsg); 928 break; 929 930 case CT_INVAL: 931 /* 932 * CTIO rejected by the firmware due to disabled lun. 933 * "Cannot Happen". 934 */ 935 PRINTF("%s: Firmware rejected CTIO for disabled lun %d\n", 936 isp->isp_name, ct->ct_lun); 937 break; 938 939 case CT_NOPATH: 940 /* 941 * CTIO rejected by the firmware due "no path for the 942 * nondisconnecting nexus specified". This means that 943 * we tried to access the bus while a non-disconnecting 944 * command is in process. 945 */ 946 PRINTF("%s: Firmware rejected CTIO for bad nexus %d/%d/%d\n", 947 isp->isp_name, ct->ct_iid, ct->ct_tgt, ct->ct_lun); 948 break; 949 950 case CT_RSELTMO: 951 fmsg = "Reselection"; 952 /*FALLTHROUGH*/ 953 case CT_TIMEOUT: 954 if (fmsg == NULL) 955 fmsg = "Command"; 956 PRINTF("%s: Firmware timed out on %s\n", isp->isp_name, fmsg); 957 break; 958 959 case CT_ERR: 960 fmsg = "Completed with Error"; 961 /*FALLTHROUGH*/ 962 case CT_PHASE_ERROR: 963 if (fmsg == NULL) 964 fmsg = "Phase Sequence Error"; 965 /*FALLTHROUGH*/ 966 case CT_TERMINATED: 967 if (fmsg == NULL) 968 fmsg = "terminated by TERMINATE TRANSFER"; 969 /*FALLTHROUGH*/ 970 case CT_NOACK: 971 if (fmsg == NULL) 972 fmsg = "unacknowledged Immediate Notify pending"; 973 974 PRINTF("%s: CTIO returned by f/w- %s\n", isp->isp_name, fmsg); 975#if 0 976 if (status & SENSEVALID) { 977 bcopy((caddr_t) (cep + CTIO_SENSE_OFFSET), 978 (caddr_t) &cdp->cd_sensedata, 979 sizeof(scsi_sense_t)); 980 cdp->cd_flags |= CDF_SENSEVALID; 981 } 982#endif 983 break; 984 default: 985 PRINTF("%s: Unknown CTIO status 0x%x\n", isp->isp_name, 986 ct->ct_status & ~QLTM_SVALID); 987 break; 988 } 989 990 if (xs == NULL) { 991 /* 992 * There may be more than one CTIO for a data transfer, 993 * or this may be a status CTIO we're not monitoring. 994 * 995 * The assumption is that they'll all be returned in the 996 * order we got them. 997 */ 998 if (ct->ct_reserved == 0) { 999 if ((ct->ct_flags & CT_SENDSTATUS) == 0) { 1000 IDPRINTF(pl, 1001 ("%s: intermediate CTIO completed ok\n", 1002 isp->isp_name)); 1003 } else { 1004 IDPRINTF(pl, 1005 ("%s: unmonitored CTIO completed ok\n", 1006 isp->isp_name)); 1007 } 1008 } else { 1009 IDPRINTF(pl, 1010 ("%s: NO xs for CTIO (handle 0x%x) status 0x%x\n", 1011 isp->isp_name, ct->ct_reserved, 1012 ct->ct_status & ~QLTM_SVALID)); 1013 } 1014 } else { 1015 if (ct->ct_flags & CT_SENDSTATUS) { 1016 /* 1017 * Sent status and command complete. 1018 * 1019 * We're now really done with this command, so we 1020 * punt to the platform dependent layers because 1021 * only there can we do the appropriate command 1022 * complete thread synchronization. 1023 */ 1024 IDPRINTF(pl, 1025 ("%s: status CTIO complete\n", isp->isp_name)); 1026 } else { 1027 /* 1028 * Final CTIO completed. Release DMA resources and 1029 * notify platform dependent layers. 1030 */ 1031 IDPRINTF(pl, 1032 ("%s: data CTIO complete\n", isp->isp_name)); 1033 ISP_DMAFREE(isp, xs, ct->ct_reserved); 1034 } 1035 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct); 1036 /* 1037 * The platform layer will destroy the handle if appropriate. 1038 */ 1039 } 1040} 1041 1042static void 1043isp_handle_ctio2(isp, ct) 1044 struct ispsoftc *isp; 1045 ct2_entry_t *ct; 1046{ 1047 ISP_SCSI_XFER_T *xs; 1048 int pl = 3; 1049 char *fmsg = NULL; 1050 1051 if (ct->ct_reserved) { 1052 xs = isp_find_xs(isp, ct->ct_reserved); 1053 if (xs == NULL) 1054 pl = 0; 1055 } else { 1056 pl = 2; 1057 xs = NULL; 1058 } 1059 1060 switch(ct->ct_status & ~QLTM_SVALID) { 1061 case CT_OK: 1062 /* 1063 * There are generally 2 possibilities as to why we'd get 1064 * this condition: 1065 * We sent or received data. 1066 * We sent status & command complete. 1067 */ 1068 1069 break; 1070 1071 case CT_BDR_MSG: 1072 /* 1073 * Bus Device Reset message received or the SCSI Bus has 1074 * been Reset; the firmware has gone to Bus Free. 1075 * 1076 * The firmware generates an async mailbox interupt to 1077 * notify us of this and returns outstanding CTIOs with this 1078 * status. These CTIOs are handled in that same way as 1079 * CT_ABORTED ones, so just fall through here. 1080 */ 1081 fmsg = "Bus Device Reset"; 1082 /*FALLTHROUGH*/ 1083 case CT_RESET: 1084 if (fmsg == NULL) 1085 fmsg = "Bus Reset"; 1086 /*FALLTHROUGH*/ 1087 case CT_ABORTED: 1088 /* 1089 * When an Abort message is received the firmware goes to 1090 * Bus Free and returns all outstanding CTIOs with the status 1091 * set, then sends us an Immediate Notify entry. 1092 */ 1093 if (fmsg == NULL) 1094 fmsg = "ABORT TASK sent by Initiator"; 1095 1096 PRINTF("%s: CTIO2 destroyed by %s\n", isp->isp_name, fmsg); 1097 break; 1098 1099 case CT_INVAL: 1100 /* 1101 * CTIO rejected by the firmware due to disabled lun. 1102 * "Cannot Happen". 1103 */ 1104 PRINTF("%s: Firmware rejected CTIO2 for disabled lun %d\n", 1105 isp->isp_name, ct->ct_lun); 1106 break; 1107 1108 case CT_NOPATH: 1109 /* 1110 * CTIO rejected by the firmware due "no path for the 1111 * nondisconnecting nexus specified". This means that 1112 * we tried to access the bus while a non-disconnecting 1113 * command is in process. 1114 */ 1115 PRINTF("%s: Firmware rejected CTIO2 for bad nexus %d->%d\n", 1116 isp->isp_name, ct->ct_iid, ct->ct_lun); 1117 break; 1118 1119 case CT_RSELTMO: 1120 fmsg = "Reselection"; 1121 /*FALLTHROUGH*/ 1122 case CT_TIMEOUT: 1123 if (fmsg == NULL) 1124 fmsg = "Command"; 1125 PRINTF("%s: Firmware timed out on %s\n", isp->isp_name, fmsg); 1126 break; 1127 1128 case CT_ERR: 1129 fmsg = "Completed with Error"; 1130 /*FALLTHROUGH*/ 1131 case CT_PHASE_ERROR: /* Bus phase sequence error */ 1132 if (fmsg == NULL) 1133 fmsg = "Phase Sequence Error"; 1134 /*FALLTHROUGH*/ 1135 case CT_TERMINATED: 1136 if (fmsg == NULL) 1137 fmsg = "terminated by TERMINATE TRANSFER"; 1138 /*FALLTHROUGH*/ 1139 case CT_LOGOUT: 1140 if (fmsg == NULL) 1141 fmsg = "Port Logout"; 1142 /*FALLTHROUGH*/ 1143 case CT_PORTNOTAVAIL: 1144 if (fmsg == NULL) 1145 fmsg = "Port not available"; 1146 case CT_NOACK: 1147 if (fmsg == NULL) 1148 fmsg = "unacknowledged Immediate Notify pending"; 1149 1150 PRINTF("%s: CTIO returned by f/w- %s\n", isp->isp_name, fmsg); 1151#if 0 1152 if (status & SENSEVALID) { 1153 bcopy((caddr_t) (cep + CTIO_SENSE_OFFSET), 1154 (caddr_t) &cdp->cd_sensedata, 1155 sizeof(scsi_sense_t)); 1156 cdp->cd_flags |= CDF_SENSEVALID; 1157 } 1158#endif 1159 break; 1160 1161 case CT_INVRXID: 1162 /* 1163 * CTIO rejected by the firmware because an invalid RX_ID. 1164 * Just print a message. 1165 */ 1166 PRINTF("%s: CTIO2 completed with Invalid RX_ID 0x%x", 1167 isp->isp_name, ct->ct_rxid); 1168 break; 1169 1170 default: 1171 IDPRINTF(pl, ("%s: Unknown CTIO status 0x%x\n", isp->isp_name, 1172 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_reserved == 0) { 1185 if ((ct->ct_flags & CT_SENDSTATUS) == 0) { 1186 IDPRINTF(pl, 1187 ("%s: intermediate CTIO completed ok\n", 1188 isp->isp_name)); 1189 } else { 1190 IDPRINTF(pl, 1191 ("%s: unmonitored CTIO completed ok\n", 1192 isp->isp_name)); 1193 } 1194 } else { 1195 IDPRINTF(pl, 1196 ("%s: NO xs for CTIO (handle 0x%x) status 0x%x\n", 1197 isp->isp_name, ct->ct_reserved, 1198 ct->ct_status & ~QLTM_SVALID)); 1199 } 1200 } else { 1201 if (ct->ct_flags & CT_SENDSTATUS) { 1202 /* 1203 * Sent status and command complete. 1204 * 1205 * We're now really done with this command, so we 1206 * punt to the platform dependent layers because 1207 * only there can we do the appropriate command 1208 * complete thread synchronization. 1209 */ 1210 IDPRINTF(pl, 1211 ("%s: status CTIO complete\n", isp->isp_name)); 1212 } else { 1213 /* 1214 * Final CTIO completed. Release DMA resources and 1215 * notify platform dependent layers. 1216 */ 1217 IDPRINTF(pl, 1218 ("%s: data CTIO complete\n", isp->isp_name)); 1219 ISP_DMAFREE(isp, xs, ct->ct_reserved); 1220 } 1221 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct); 1222 /* 1223 * The platform layer will destroy the handle if appropriate. 1224 */ 1225 } 1226} 1227#endif 1228