diff options
| author | Matt Jacob <mjacob@FreeBSD.org> | 2001-07-04 19:14:22 +0000 |
|---|---|---|
| committer | Matt Jacob <mjacob@FreeBSD.org> | 2001-07-04 19:14:22 +0000 |
| commit | 011b768701e47a206d7645f32606be8811fd8bd3 (patch) | |
| tree | 3cf7efb7c4f62bf30a8fbfa90e0bac092cbf9f34 /sys/dev/isp/isp_target.c | |
| parent | 63ab2cfb65e18033ff845319d8574e362f707ad5 (diff) | |
Notes
Diffstat (limited to 'sys/dev/isp/isp_target.c')
| -rw-r--r-- | sys/dev/isp/isp_target.c | 236 |
1 files changed, 86 insertions, 150 deletions
diff --git a/sys/dev/isp/isp_target.c b/sys/dev/isp/isp_target.c index 51b78fb8fd72..86ab25b36347 100644 --- a/sys/dev/isp/isp_target.c +++ b/sys/dev/isp/isp_target.c @@ -46,14 +46,14 @@ #endif #ifdef ISP_TARGET_MODE -static char *atiocope = +static const char atiocope[] = "ATIO returned for lun %d because it was in the middle of Bus Device Reset"; -static char *atior = +static const char atior[] = "ATIO returned for lun %d from initiator %d because a Bus Reset occurred"; -static void isp_got_msg __P((struct ispsoftc *, int, in_entry_t *)); -static void isp_got_msg_fc __P((struct ispsoftc *, int, in_fcentry_t *)); -static void isp_notify_ack __P((struct ispsoftc *, void *)); +static void isp_got_msg(struct ispsoftc *, int, in_entry_t *); +static void isp_got_msg_fc(struct ispsoftc *, int, in_fcentry_t *); +static void isp_notify_ack(struct ispsoftc *, void *); static void isp_handle_atio(struct ispsoftc *, at_entry_t *); static void isp_handle_atio2(struct ispsoftc *, at2_entry_t *); static void isp_handle_ctio(struct ispsoftc *, ct_entry_t *); @@ -106,10 +106,7 @@ static void isp_handle_ctio2(struct ispsoftc *, ct2_entry_t *); */ int -isp_target_notify(isp, vptr, optrp) - struct ispsoftc *isp; - void *vptr; - u_int16_t *optrp; +isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp) { u_int16_t status, seqid; union { @@ -268,13 +265,8 @@ isp_target_notify(isp, vptr, optrp) * response entry. The caller is responsible for synchronizing this. */ int -isp_lun_cmd(isp, cmd, bus, tgt, lun, opaque) - struct ispsoftc *isp; - int cmd; - int bus; - int tgt; - int lun; - u_int32_t opaque; +isp_lun_cmd(struct ispsoftc *isp, int cmd, int bus, int tgt, int lun, + int cmd_cnt, int inot_cnt, u_int32_t opaque) { lun_entry_t el; u_int16_t iptr, optr; @@ -285,8 +277,8 @@ isp_lun_cmd(isp, cmd, bus, tgt, lun, opaque) if (IS_DUALBUS(isp)) { el.le_rsvd = (bus & 0x1) << 7; } - el.le_cmd_count = DFLT_CMD_CNT; - el.le_in_count = DFLT_INOTIFY; + el.le_cmd_count = cmd_cnt; + el.le_in_count = inot_cnt; if (cmd == RQSTYPE_ENABLE_LUN) { if (IS_SCSI(isp)) { el.le_flags = LUN_TQAE|LUN_DISAD; @@ -312,6 +304,7 @@ isp_lun_cmd(isp, cmd, bus, tgt, lun, opaque) } else if (isp->isp_maxluns <= 16) { el.le_lun = lun; } + el.le_timeout = 2; if (isp_getrqentry(isp, &iptr, &optr, &outp)) { isp_prt(isp, ISP_LOGWARN, @@ -326,9 +319,7 @@ isp_lun_cmd(isp, cmd, bus, tgt, lun, opaque) int -isp_target_put_entry(isp, ap) - struct ispsoftc *isp; - void *ap; +isp_target_put_entry(struct ispsoftc *isp, void *ap) { void *outp; u_int16_t iptr, optr; @@ -365,13 +356,7 @@ isp_target_put_entry(isp, ap) } int -isp_target_put_atio(isp, iid, tgt, lun, ttype, tval) - struct ispsoftc *isp; - int iid; - int tgt; - int lun; - int ttype; - int tval; +isp_target_put_atio(struct ispsoftc *isp, void *arg) { union { at_entry_t _atio; @@ -380,23 +365,27 @@ isp_target_put_atio(isp, iid, tgt, lun, ttype, tval) MEMZERO(&atun, sizeof atun); if (IS_FC(isp)) { + at2_entry_t *aep = arg; atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2; atun._atio2.at_header.rqs_entry_count = 1; if (isp->isp_maxluns > 16) { - atun._atio2.at_scclun = (u_int16_t) lun; + atun._atio2.at_scclun = (u_int16_t) aep->at_scclun; } else { - atun._atio2.at_lun = (u_int8_t) lun; + atun._atio2.at_lun = (u_int8_t) aep->at_scclun; } atun._atio2.at_status = CT_OK; } else { + at_entry_t *aep = arg; atun._atio.at_header.rqs_entry_type = RQSTYPE_ATIO; atun._atio.at_header.rqs_entry_count = 1; - atun._atio.at_iid = iid; - atun._atio.at_tgt = tgt; - atun._atio.at_lun = lun; - atun._atio.at_tag_type = ttype; - atun._atio.at_tag_val = tval; - atun._atio.at_status = CT_OK; + atun._atio.at_handle = aep->at_handle; + atun._atio.at_iid = aep->at_iid; + atun._atio.at_tgt = aep->at_tgt; + atun._atio.at_lun = aep->at_lun; + atun._atio.at_tag_type = aep->at_tag_type; + atun._atio.at_tag_val = aep->at_tag_val; + atun._atio.at_status = (aep->at_flags & AT_TQAE); + atun._atio.at_status |= CT_OK; } return (isp_target_put_entry(isp, &atun)); } @@ -412,7 +401,7 @@ isp_target_put_atio(isp, iid, tgt, lun, ttype, tval) * values. * * NB: the key, asc, ascq, cannot be used for parallel SCSI as it doesn't - * NB: inline SCSI sense reporting. + * NB: inline SCSI sense reporting. As such, we lose this information. XXX. * * For both parallel && fibre channel, we use the feature that does * an automatic resource autoreplenish so we don't have then later do @@ -449,7 +438,7 @@ isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl) } if (aep->at_datalen) { cto->ct_resid = aep->at_datalen; - cto->ct_flags |= CT2_DATA_UNDER; + cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER; } if ((sts & 0xff) == SCSI_CHECK && (sts & ECMD_SVALID)) { cto->rsp.m1.ct_resp[0] = 0xf0; @@ -458,9 +447,9 @@ isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl) cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff; cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff; cto->rsp.m1.ct_senselen = 16; - cto->ct_flags |= CT2_SNSLEN_VALID; + cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID; } - cto->ct_reserved = hdl; + cto->ct_syshandle = hdl; } else { at_entry_t *aep = arg; ct_entry_t *cto = &un._ctio; @@ -473,21 +462,21 @@ isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl) cto->ct_lun = aep->at_lun; cto->ct_tag_type = aep->at_tag_type; cto->ct_tag_val = aep->at_tag_val; + if (aep->at_flags & AT_TQAE) { + cto->ct_flags |= CT_TQAE; + } cto->ct_flags = CT_SENDSTATUS | CT_NO_DATA; if (hdl == 0) { cto->ct_flags |= CT_CCINCR; } cto->ct_scsi_status = sts; - cto->ct_reserved = hdl; + cto->ct_syshandle = hdl; } return (isp_target_put_entry(isp, &un)); } void -isp_target_async(isp, bus, event) - struct ispsoftc *isp; - int bus; - int event; +isp_target_async(struct ispsoftc *isp, int bus, int event) { tmd_event_t evt; tmd_msg_t msg; @@ -550,10 +539,7 @@ isp_target_async(isp, bus, event) */ static void -isp_got_msg(isp, bus, inp) - struct ispsoftc *isp; - int bus; - in_entry_t *inp; +isp_got_msg(struct ispsoftc *isp, int bus, in_entry_t *inp) { u_int8_t status = inp->in_status & ~QLTM_SVALID; @@ -579,13 +565,10 @@ isp_got_msg(isp, bus, inp) * Synthesize a message from the task management flags in a FCP_CMND_IU. */ static void -isp_got_msg_fc(isp, bus, inp) - struct ispsoftc *isp; - int bus; - in_fcentry_t *inp; +isp_got_msg_fc(struct ispsoftc *isp, int bus, in_fcentry_t *inp) { - static char *f1 = "%s from iid %d lun %d seq 0x%x"; - static char *f2 = + static const char f1[] = "%s from iid %d lun %d seq 0x%x"; + static const char f2[] = "unknown %s 0x%x lun %d iid %d task flags 0x%x seq 0x%x\n"; if (inp->in_status != IN_MSG_RECEIVED) { @@ -638,9 +621,7 @@ isp_got_msg_fc(isp, bus, inp) } static void -isp_notify_ack(isp, arg) - struct ispsoftc *isp; - void *arg; +isp_notify_ack(struct ispsoftc *isp, void *arg) { char storage[QENTRY_LEN]; u_int16_t iptr, optr; @@ -701,9 +682,7 @@ isp_notify_ack(isp, arg) } static void -isp_handle_atio(isp, aep) - struct ispsoftc *isp; - at_entry_t *aep; +isp_handle_atio(struct ispsoftc *isp, at_entry_t *aep) { int lun; lun = aep->at_lun; @@ -776,16 +755,13 @@ isp_handle_atio(isp, aep) isp_prt(isp, ISP_LOGERR, "Unknown ATIO status 0x%x from initiator %d for lun %d", aep->at_status, aep->at_iid, lun); - (void) isp_target_put_atio(isp, aep->at_iid, aep->at_tgt, - lun, aep->at_tag_type, aep->at_tag_val); + (void) isp_target_put_atio(isp, aep); break; } } static void -isp_handle_atio2(isp, aep) - struct ispsoftc *isp; - at2_entry_t *aep; +isp_handle_atio2(struct ispsoftc *isp, at2_entry_t *aep) { int lun; @@ -862,26 +838,23 @@ isp_handle_atio2(isp, aep) isp_prt(isp, ISP_LOGERR, "Unknown ATIO2 status 0x%x from initiator %d for lun %d", aep->at_status, aep->at_iid, lun); - (void) isp_target_put_atio(isp, aep->at_iid, 0, lun, 0, 0); + (void) isp_target_put_atio(isp, aep); break; } } static void -isp_handle_ctio(isp, ct) - struct ispsoftc *isp; - ct_entry_t *ct; +isp_handle_ctio(struct ispsoftc *isp, ct_entry_t *ct) { - XS_T *xs; + void *xs; int pl = ISP_LOGTDEBUG2; char *fmsg = NULL; - if (ct->ct_reserved) { - xs = isp_find_xs(isp, ct->ct_reserved); + if (ct->ct_syshandle) { + xs = isp_find_xs(isp, ct->ct_syshandle); if (xs == NULL) pl = ISP_LOGALL; } else { - pl = ISP_LOGTDEBUG1; xs = NULL; } @@ -966,8 +939,13 @@ isp_handle_ctio(isp, ct) isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg); break; + case CT_PANIC: + if (fmsg == NULL) + fmsg = "Unrecoverable Error"; + /*FALLTHROUGH*/ case CT_ERR: - fmsg = "Completed with Error"; + if (fmsg == NULL) + fmsg = "Completed with Error"; /*FALLTHROUGH*/ case CT_PHASE_ERROR: if (fmsg == NULL) @@ -980,16 +958,7 @@ isp_handle_ctio(isp, ct) case CT_NOACK: if (fmsg == NULL) fmsg = "unacknowledged Immediate Notify pending"; - isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg); -#if 0 - if (status & SENSEVALID) { - bcopy((caddr_t) (cep + CTIO_SENSE_OFFSET), - (caddr_t) &cdp->cd_sensedata, - sizeof(scsi_sense_t)); - cdp->cd_flags |= CDF_SENSEVALID; - } -#endif break; default: isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x", @@ -1005,7 +974,7 @@ isp_handle_ctio(isp, ct) * The assumption is that they'll all be returned in the * order we got them. */ - if (ct->ct_reserved == 0) { + if (ct->ct_syshandle == 0) { if ((ct->ct_flags & CT_SENDSTATUS) == 0) { isp_prt(isp, pl, "intermediate CTIO completed ok"); @@ -1016,53 +985,45 @@ isp_handle_ctio(isp, ct) } else { isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", - ct->ct_reserved, ct->ct_status & ~QLTM_SVALID); + ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID); } } else { - if (ct->ct_flags & CT_SENDSTATUS) { - /* - * Sent status and command complete. - * - * We're now really done with this command, so we - * punt to the platform dependent layers because - * only there can we do the appropriate command - * complete thread synchronization. - */ - isp_prt(isp, pl, "status CTIO complete"); - } else { - /* - * Final CTIO completed. Release DMA resources and - * notify platform dependent layers. - */ - isp_prt(isp, pl, "data CTIO complete"); - ISP_DMAFREE(isp, xs, ct->ct_reserved); + /* + * Final CTIO completed. Release DMA resources and + * notify platform dependent layers. + */ + if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) { + ISP_DMAFREE(isp, xs, ct->ct_syshandle); } - (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct); + isp_prt(isp, pl, "final CTIO complete"); /* * The platform layer will destroy the handle if appropriate. */ + (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct); } } static void -isp_handle_ctio2(isp, ct) - struct ispsoftc *isp; - ct2_entry_t *ct; +isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct) { XS_T *xs; int pl = ISP_LOGTDEBUG2; char *fmsg = NULL; - if (ct->ct_reserved) { - xs = isp_find_xs(isp, ct->ct_reserved); + if (ct->ct_syshandle) { + xs = isp_find_xs(isp, ct->ct_syshandle); if (xs == NULL) pl = ISP_LOGALL; } else { - pl = ISP_LOGTDEBUG1; xs = NULL; } switch(ct->ct_status & ~QLTM_SVALID) { + case CT_BUS_ERROR: + isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error"); + /* FALL Through */ + case CT_DATA_OVER: + case CT_DATA_UNDER: case CT_OK: /* * There are generally 2 possibilities as to why we'd get @@ -1075,19 +1036,18 @@ isp_handle_ctio2(isp, ct) case CT_BDR_MSG: /* - * Bus Device Reset message received or the SCSI Bus has - * been Reset; the firmware has gone to Bus Free. + * Target Reset function received. * * The firmware generates an async mailbox interupt to * notify us of this and returns outstanding CTIOs with this * status. These CTIOs are handled in that same way as * CT_ABORTED ones, so just fall through here. */ - fmsg = "Bus Device Reset"; + fmsg = "TARGET RESET Task Management Function Received"; /*FALLTHROUGH*/ case CT_RESET: if (fmsg == NULL) - fmsg = "Bus Reset"; + fmsg = "LIP Reset"; /*FALLTHROUGH*/ case CT_ABORTED: /* @@ -1096,7 +1056,7 @@ isp_handle_ctio2(isp, ct) * set, then sends us an Immediate Notify entry. */ if (fmsg == NULL) - fmsg = "ABORT TASK sent by Initiator"; + fmsg = "ABORT Task Management Function Received"; isp_prt(isp, ISP_LOGERR, "CTIO2 destroyed by %s", fmsg); break; @@ -1108,38 +1068,18 @@ isp_handle_ctio2(isp, ct) isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data directiond"); break; - case CT_NOPATH: - /* - * CTIO rejected by the firmware due "no path for the - * nondisconnecting nexus specified". This means that - * we tried to access the bus while a non-disconnecting - * command is in process. - */ - isp_prt(isp, ISP_LOGERR, - "Firmware rejected CTIO2 for bad nexus %d->%d", - ct->ct_iid, ct->ct_lun); - break; - case CT_RSELTMO: - fmsg = "Reselection"; + fmsg = "failure to reconnect to initiator"; /*FALLTHROUGH*/ case CT_TIMEOUT: if (fmsg == NULL) - fmsg = "Command"; + fmsg = "command"; isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg); break; case CT_ERR: fmsg = "Completed with Error"; /*FALLTHROUGH*/ - case CT_PHASE_ERROR: /* Bus phase sequence error */ - if (fmsg == NULL) - fmsg = "Phase Sequence Error"; - /*FALLTHROUGH*/ - case CT_TERMINATED: - if (fmsg == NULL) - fmsg = "terminated by TERMINATE TRANSFER"; - /*FALLTHROUGH*/ case CT_LOGOUT: if (fmsg == NULL) fmsg = "Port Logout"; @@ -1147,19 +1087,13 @@ isp_handle_ctio2(isp, ct) case CT_PORTNOTAVAIL: if (fmsg == NULL) fmsg = "Port not available"; + case CT_PORTCHANGED: + if (fmsg == NULL) + fmsg = "Port Changed"; case CT_NOACK: if (fmsg == NULL) fmsg = "unacknowledged Immediate Notify pending"; - isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg); -#if 0 - if (status & SENSEVALID) { - bcopy((caddr_t) (cep + CTIO_SENSE_OFFSET), - (caddr_t) &cdp->cd_sensedata, - sizeof(scsi_sense_t)); - cdp->cd_flags |= CDF_SENSEVALID; - } -#endif break; case CT_INVRXID: @@ -1172,7 +1106,7 @@ isp_handle_ctio2(isp, ct) break; default: - isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x", + isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x", ct->ct_status & ~QLTM_SVALID); break; } @@ -1185,7 +1119,7 @@ isp_handle_ctio2(isp, ct) * The assumption is that they'll all be returned in the * order we got them. */ - if (ct->ct_reserved == 0) { + if (ct->ct_syshandle == 0) { if ((ct->ct_flags & CT_SENDSTATUS) == 0) { isp_prt(isp, pl, "intermediate CTIO completed ok"); @@ -1196,9 +1130,12 @@ isp_handle_ctio2(isp, ct) } else { isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", - ct->ct_reserved, ct->ct_status & ~QLTM_SVALID); + ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID); } } else { + if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) { + ISP_DMAFREE(isp, xs, ct->ct_syshandle); + } if (ct->ct_flags & CT_SENDSTATUS) { /* * Sent status and command complete. @@ -1215,7 +1152,6 @@ isp_handle_ctio2(isp, ct) * notify platform dependent layers. */ isp_prt(isp, pl, "data CTIO complete"); - ISP_DMAFREE(isp, xs, ct->ct_reserved); } (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct); /* |
