summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp/isp_target.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/isp/isp_target.c')
-rw-r--r--sys/dev/isp/isp_target.c947
1 files changed, 526 insertions, 421 deletions
diff --git a/sys/dev/isp/isp_target.c b/sys/dev/isp/isp_target.c
index 531f64b..68c42b4 100644
--- a/sys/dev/isp/isp_target.c
+++ b/sys/dev/isp/isp_target.c
@@ -1,17 +1,17 @@
/*-
- * Copyright (c) 1997-2007 by Matthew Jacob
+ * Copyright (c) 1997-2009 by Matthew Jacob
* All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -23,6 +23,7 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
*/
/*
* Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters.
@@ -51,12 +52,9 @@ __FBSDID("$FreeBSD$");
#endif
#ifdef ISP_TARGET_MODE
-static const char atiocope[] =
- "ATIO returned for lun %d because it was in the middle of Bus Device Reset "
- "on bus %d";
-static const char atior[] =
- "ATIO returned on for lun %d on from loopid %d because a Bus Reset "
- "occurred on bus %d";
+static const char atiocope[] = "ATIO returned for lun %d because it was in the middle of Bus Device Reset on bus %d";
+static const char atior[] = "ATIO returned on for lun %d on from loopid %d because a Bus Reset occurred on bus %d";
+static const char rqo[] = "%s: Request Queue Overflow";
static void isp_got_msg(ispsoftc_t *, in_entry_t *);
static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *);
@@ -66,6 +64,7 @@ static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *);
static void isp_handle_ctio(ispsoftc_t *, ct_entry_t *);
static void isp_handle_ctio2(ispsoftc_t *, ct2_entry_t *);
static void isp_handle_ctio7(ispsoftc_t *, ct7_entry_t *);
+static void isp_handle_24xx_inotify(ispsoftc_t *, in_fcentry_24xx_t *);
/*
* The Qlogic driver gets an interrupt to look at response queue entries.
@@ -164,14 +163,16 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
#define hdrp unp.hp
} unp;
uint8_t local[QENTRY_LEN];
+ uint16_t iid;
int bus, type, level, rval = 1;
+ isp_notify_t notify;
type = isp_get_response_type(isp, (isphdr_t *)vptr);
unp.vp = vptr;
ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr);
- switch(type) {
+ switch (type) {
case RQSTYPE_ATIO:
if (IS_24XX(isp)) {
int len;
@@ -179,17 +180,15 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
isp_get_atio7(isp, at7iop, (at7_entry_t *) local);
at7iop = (at7_entry_t *) local;
/*
- * Check for and do something with commands whose IULEN
- * extends past a singel queue entry.
+ * Check for and do something with commands whose
+ * IULEN extends past a single queue entry.
*/
len = at7iop->at_ta_len & 0xfffff;
if (len > (QENTRY_LEN - 8)) {
len -= (QENTRY_LEN - 8);
- isp_prt(isp, ISP_LOGINFO,
- "long IU length (%d) ignored", len);
+ isp_prt(isp, ISP_LOGINFO, "long IU length (%d) ignored", len);
while (len > 0) {
- *optrp = ISP_NXT_QENTRY(*optrp,
- RESULT_QUEUE_LEN(isp));
+ *optrp = ISP_NXT_QENTRY(*optrp, RESULT_QUEUE_LEN(isp));
len -= QENTRY_LEN;
}
}
@@ -203,7 +202,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
/*
* Just go straight to outer layer for this one.
*/
- (void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
+ isp_async(isp, ISPASYNC_TARGET_ACTION, local);
} else {
isp_get_atio(isp, atiop, (at_entry_t *) local);
isp_handle_atio(isp, (at_entry_t *) local);
@@ -216,7 +215,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
break;
case RQSTYPE_ATIO2:
- if (FCPARAM(isp)->isp_2klogin) {
+ if (ISP_CAP_2KLOGIN(isp)) {
isp_get_atio2e(isp, at2eiop, (at2e_entry_t *) local);
} else {
isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
@@ -226,7 +225,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
case RQSTYPE_CTIO3:
case RQSTYPE_CTIO2:
- if (FCPARAM(isp)->isp_2klogin) {
+ if (ISP_CAP_2KLOGIN(isp)) {
isp_get_ctio2e(isp, ct2eiop, (ct2e_entry_t *) local);
} else {
isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
@@ -242,71 +241,44 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
case RQSTYPE_ENABLE_LUN:
case RQSTYPE_MODIFY_LUN:
isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local);
- (void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
+ isp_async(isp, ISPASYNC_TARGET_ACTION, local);
break;
case RQSTYPE_NOTIFY:
- /*
- * Either the ISP received a SCSI message it can't
- * handle, or it's returning an Immed. Notify entry
- * we sent. We can send Immed. Notify entries to
- * increment the firmware's resource count for them
- * (we set this initially in the Enable Lun entry).
- */
bus = 0;
if (IS_24XX(isp)) {
- isp_get_notify_24xx(isp, inot_24xx,
- (in_fcentry_24xx_t *)local);
+ isp_get_notify_24xx(isp, inot_24xx, (in_fcentry_24xx_t *)local);
inot_24xx = (in_fcentry_24xx_t *) local;
- status = inot_24xx->in_status;
- seqid = inot_24xx->in_rxid;
- isp_prt(isp, ISP_LOGTDEBUG0,
- "Immediate Notify status=0x%x seqid=0x%x",
- status, seqid);
- switch (status) {
- case IN24XX_LIP_RESET:
- case IN24XX_LINK_RESET:
- case IN24XX_PORT_LOGOUT:
- case IN24XX_PORT_CHANGED:
- case IN24XX_LINK_FAILED:
- case IN24XX_SRR_RCVD:
- case IN24XX_ELS_RCVD:
- (void) isp_async(isp, ISPASYNC_TARGET_ACTION,
- &local);
- break;
- default:
- isp_prt(isp, ISP_LOGINFO,
- "isp_target_notify: unknown status (0x%x)",
- status);
- isp_notify_ack(isp, local);
- break;
- }
+ isp_handle_24xx_inotify(isp, inot_24xx);
break;
- } else if (IS_FC(isp)) {
- if (FCPARAM(isp)->isp_2klogin) {
- isp_get_notify_fc_e(isp, inote_fcp,
- (in_fcentry_e_t *)local);
+ }
+ if (IS_FC(isp)) {
+ if (ISP_CAP_2KLOGIN(isp)) {
+ in_fcentry_e_t *ecp = (in_fcentry_e_t *)local;
+ isp_get_notify_fc_e(isp, inote_fcp, ecp);
+ iid = ecp->in_iid;
+ status = ecp->in_status;
+ seqid = ecp->in_seqid;
} else {
- isp_get_notify_fc(isp, inot_fcp,
- (in_fcentry_t *)local);
+ in_fcentry_t *fcp = (in_fcentry_t *)local;
+ isp_get_notify_fc(isp, inot_fcp, fcp);
+ iid = fcp->in_iid;
+ status = fcp->in_status;
+ seqid = fcp->in_seqid;
}
- inot_fcp = (in_fcentry_t *) local;
- status = inot_fcp->in_status;
- seqid = inot_fcp->in_seqid;
} else {
- isp_get_notify(isp, inotp, (in_entry_t *)local);
- inotp = (in_entry_t *) local;
- status = inotp->in_status & 0xff;
- seqid = inotp->in_seqid;
+ in_entry_t *inp = (in_entry_t *)local;
+ isp_get_notify(isp, inotp, inp);
+ status = inp->in_status & 0xff;
+ seqid = inp->in_seqid;
+ iid = inp->in_iid;
if (IS_DUALBUS(isp)) {
- bus = GET_BUS_VAL(inotp->in_iid);
- SET_BUS_VAL(inotp->in_iid, 0);
+ bus = GET_BUS_VAL(inp->in_iid);
+ SET_BUS_VAL(inp->in_iid, 0);
}
}
- isp_prt(isp, ISP_LOGTDEBUG0,
- "Immediate Notify On Bus %d, status=0x%x seqid=0x%x",
- bus, status, seqid);
+ isp_prt(isp, ISP_LOGTDEBUG0, "Immediate Notify On Bus %d, status=0x%x seqid=0x%x", bus, status, seqid);
switch (status) {
case IN_MSG_RECEIVED:
@@ -319,38 +291,74 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
break;
case IN_RSRC_UNAVAIL:
isp_prt(isp, ISP_LOGINFO, "Firmware out of ATIOs");
- isp_notify_ack(isp, local);
+ (void) isp_notify_ack(isp, local);
break;
- case IN_RESET:
- {
- /*
- * We form the notify structure here because we need
- * to mark it as needing a NOTIFY ACK on return.
- */
- tmd_notify_t notify;
- MEMZERO(&notify, sizeof (tmd_notify_t));
+ case IN_RESET:
+ ISP_MEMZERO(&notify, sizeof (isp_notify_t));
notify.nt_hba = isp;
- notify.nt_iid = INI_ANY;
- /* nt_tgt set in outer layers */
+ notify.nt_wwn = INI_ANY;
+ notify.nt_tgt = TGT_ANY;
+ notify.nt_nphdl = iid;
+ notify.nt_sid = PORT_ANY;
+ notify.nt_did = PORT_ANY;
notify.nt_lun = LUN_ANY;
notify.nt_tagval = TAG_ANY;
+ notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32);
notify.nt_ncode = NT_BUS_RESET;
notify.nt_need_ack = 1;
- (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ notify.nt_lreserved = local;
+ isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
break;
- }
+
case IN_PORT_LOGOUT:
+ ISP_MEMZERO(&notify, sizeof (isp_notify_t));
+ notify.nt_hba = isp;
+ notify.nt_wwn = INI_ANY;
+ notify.nt_nphdl = iid;
+ notify.nt_sid = PORT_ANY;
+ notify.nt_did = PORT_ANY;
+ notify.nt_ncode = NT_LOGOUT;
+ notify.nt_need_ack = 1;
+ notify.nt_lreserved = local;
+ isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ break;
+
case IN_ABORT_TASK:
- case IN_PORT_CHANGED:
+ ISP_MEMZERO(&notify, sizeof (isp_notify_t));
+ notify.nt_hba = isp;
+ notify.nt_wwn = INI_ANY;
+ notify.nt_nphdl = iid;
+ notify.nt_sid = PORT_ANY;
+ notify.nt_did = PORT_ANY;
+ notify.nt_ncode = NT_ABORT_TASK;
+ notify.nt_need_ack = 1;
+ notify.nt_lreserved = local;
+ isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ break;
+
case IN_GLOBAL_LOGO:
- (void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
+ isp_prt(isp, ISP_LOGTINFO, "%s: all ports logged out", __func__);
+ ISP_MEMZERO(&notify, sizeof (isp_notify_t));
+ notify.nt_hba = isp;
+ notify.nt_wwn = INI_ANY;
+ notify.nt_nphdl = NIL_HANDLE;
+ notify.nt_sid = PORT_ANY;
+ notify.nt_did = PORT_ANY;
+ notify.nt_ncode = NT_GLOBAL_LOGOUT;
+ isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ (void) isp_notify_ack(isp, local);
+ break;
+
+ case IN_PORT_CHANGED:
+ isp_prt(isp, ISP_LOGTINFO, "%s: port changed", __func__);
+ (void) isp_notify_ack(isp, local);
break;
+
default:
- isp_prt(isp, ISP_LOGINFO,
- "isp_target_notify: unknown status (0x%x)",
- status);
- isp_notify_ack(isp, local);
+ ISP_SNPRINTF(local, sizeof local, "%s: unknown status to RQSTYPE_NOTIFY (0x%x)", __func__, status);
+ isp_print_bytes(isp, local, QENTRY_LEN, vptr);
+ (void) isp_notify_ack(isp, local);
break;
}
break;
@@ -361,25 +369,19 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
* Immediate Notify entry for some asynchronous event.
*/
if (IS_24XX(isp)) {
- isp_get_notify_ack_24xx(isp, nack_24xx,
- (na_fcentry_24xx_t *) local);
+ isp_get_notify_ack_24xx(isp, nack_24xx, (na_fcentry_24xx_t *) local);
nack_24xx = (na_fcentry_24xx_t *) local;
if (nack_24xx->na_status != NA_OK) {
level = ISP_LOGINFO;
} else {
level = ISP_LOGTDEBUG1;
}
- 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);
+ 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);
} else if (IS_FC(isp)) {
- if (FCPARAM(isp)->isp_2klogin) {
- isp_get_notify_ack_fc_e(isp, nacke_fcp,
- (na_fcentry_e_t *)local);
+ if (ISP_CAP_2KLOGIN(isp)) {
+ isp_get_notify_ack_fc_e(isp, nacke_fcp, (na_fcentry_e_t *)local);
} else {
- isp_get_notify_ack_fc(isp, nack_fcp,
- (na_fcentry_t *)local);
+ isp_get_notify_ack_fc(isp, nack_fcp, (na_fcentry_t *)local);
}
nack_fcp = (na_fcentry_t *)local;
if (nack_fcp->na_status != NA_OK) {
@@ -387,9 +389,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
} else {
level = ISP_LOGTDEBUG1;
}
- isp_prt(isp, level,
- "Notify Ack Status=0x%x seqid 0x%x",
- nack_fcp->na_status, nack_fcp->na_seqid);
+ isp_prt(isp, level, "Notify Ack Status=0x%x seqid 0x%x", nack_fcp->na_status, nack_fcp->na_seqid);
} else {
isp_get_notify_ack(isp, nackp, (na_entry_t *)local);
nackp = (na_entry_t *)local;
@@ -398,15 +398,13 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
} else {
level = ISP_LOGTDEBUG1;
}
- isp_prt(isp, level,
- "Notify Ack event 0x%x status=0x%x seqid 0x%x",
- nackp->na_event, nackp->na_status, nackp->na_seqid);
+ isp_prt(isp, level, "Notify Ack event 0x%x status=0x%x seqid 0x%x", nackp->na_event, nackp->na_status, nackp->na_seqid);
}
break;
case RQSTYPE_ABTS_RCVD:
isp_get_abts(isp, abts, (abts_t *)local);
- (void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
+ isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
break;
case RQSTYPE_ABTS_RSP:
isp_get_abts_rsp(isp, abts_rsp, (abts_rsp_t *)local);
@@ -416,15 +414,11 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
} else {
level = ISP_LOGTDEBUG0;
}
- 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,
- abts_rsp->abts_rsp_payload.rsp.subcode1,
- abts_rsp->abts_rsp_payload.rsp.subcode2);
+ 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,
+ abts_rsp->abts_rsp_payload.rsp.subcode1, abts_rsp->abts_rsp_payload.rsp.subcode2);
break;
default:
- isp_prt(isp, ISP_LOGERR,
- "Unknown entry type 0x%x in isp_target_notify", type);
+ isp_prt(isp, ISP_LOGERR, "%s: unknown entry type 0x%x", __func__, type);
rval = 0;
break;
}
@@ -452,26 +446,23 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
return (rval);
}
-
+
/*
- * Toggle (on/off) target mode for bus/target/lun
+ * Toggle (on/off) target mode for bus/target/lun.
*
* The caller has checked for overlap and legality.
*
* Note that not all of bus, target or lun can be paid attention to.
* Note also that this action will not be complete until the f/w writes
- * response entry. The caller is responsible for synchronizing this.
+ * a response entry. The caller is responsible for synchronizing with this.
*/
int
-isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int tgt, int lun,
- int cmd_cnt, int inot_cnt, uint32_t opaque)
+isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int lun, int cmd_cnt, int inot_cnt)
{
lun_entry_t el;
- uint32_t nxti, optr;
void *outp;
-
- MEMZERO(&el, sizeof (el));
+ ISP_MEMZERO(&el, sizeof (el));
if (IS_DUALBUS(isp)) {
el.le_rsvd = (bus & 0x1) << 7;
}
@@ -495,37 +486,34 @@ isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int tgt, int lun,
}
el.le_header.rqs_entry_type = cmd;
el.le_header.rqs_entry_count = 1;
- el.le_reserved = opaque;
if (IS_SCSI(isp)) {
- el.le_tgt = tgt;
+ el.le_tgt = SDPARAM(isp, bus)->isp_initiator_id;
el.le_lun = lun;
- } else if (FCPARAM(isp)->isp_sccfw == 0) {
+ } else if (ISP_CAP_SCCFW(isp) == 0) {
el.le_lun = lun;
}
el.le_timeout = 30;
- if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
- isp_prt(isp, ISP_LOGERR,
- "Request Queue Overflow in isp_lun_cmd");
+ outp = isp_getrqentry(isp);
+ if (outp == NULL) {
+ isp_prt(isp, ISP_LOGERR, rqo, __func__);
return (-1);
}
- ISP_TDQE(isp, "isp_lun_cmd", (int) optr, &el);
isp_put_enable_lun(isp, &el, outp);
- ISP_ADD_REQUEST(isp, nxti);
+ ISP_TDQE(isp, "isp_lun_cmd", isp->isp_reqidx, &el);
+ ISP_SYNC_REQUEST(isp);
return (0);
}
-
int
isp_target_put_entry(ispsoftc_t *isp, void *ap)
{
void *outp;
- uint32_t nxti, optr;
uint8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
- if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
- isp_prt(isp, ISP_LOGWARN,
- "Request Queue Overflow in isp_target_put_entry");
+ outp = isp_getrqentry(isp);
+ if (outp == NULL) {
+ isp_prt(isp, ISP_LOGWARN, rqo, __func__);
return (-1);
}
switch (etype) {
@@ -533,36 +521,31 @@ isp_target_put_entry(ispsoftc_t *isp, void *ap)
isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp);
break;
case RQSTYPE_ATIO2:
- if (FCPARAM(isp)->isp_2klogin) {
- isp_put_atio2e(isp, (at2e_entry_t *) ap,
- (at2e_entry_t *) outp);
+ if (ISP_CAP_2KLOGIN(isp)) {
+ isp_put_atio2e(isp, (at2e_entry_t *) ap, (at2e_entry_t *) outp);
} else {
- isp_put_atio2(isp, (at2_entry_t *) ap,
- (at2_entry_t *) outp);
+ isp_put_atio2(isp, (at2_entry_t *) ap, (at2_entry_t *) outp);
}
break;
case RQSTYPE_CTIO:
isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp);
break;
case RQSTYPE_CTIO2:
- if (FCPARAM(isp)->isp_2klogin) {
- isp_put_ctio2e(isp, (ct2e_entry_t *) ap,
- (ct2e_entry_t *) outp);
+ if (ISP_CAP_2KLOGIN(isp)) {
+ isp_put_ctio2e(isp, (ct2e_entry_t *) ap, (ct2e_entry_t *) outp);
} else {
- isp_put_ctio2(isp, (ct2_entry_t *) ap,
- (ct2_entry_t *) outp);
+ isp_put_ctio2(isp, (ct2_entry_t *) ap, (ct2_entry_t *) outp);
}
break;
case RQSTYPE_CTIO7:
isp_put_ctio7(isp, (ct7_entry_t *) ap, (ct7_entry_t *) outp);
break;
default:
- isp_prt(isp, ISP_LOGERR,
- "Unknown type 0x%x in isp_put_entry", etype);
+ isp_prt(isp, ISP_LOGERR, "%s: Unknown type 0x%x", __func__, etype);
return (-1);
}
- ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);
- ISP_ADD_REQUEST(isp, nxti);
+ ISP_TDQE(isp, __func__, isp->isp_reqidx, ap);
+ ISP_SYNC_REQUEST(isp);
return (0);
}
@@ -575,17 +558,17 @@ isp_target_put_atio(ispsoftc_t *isp, void *arg)
at2e_entry_t _atio2e;
} atun;
- MEMZERO(&atun, sizeof atun);
+ ISP_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 (FCPARAM(isp)->isp_sccfw) {
+ if (ISP_CAP_SCCFW(isp)) {
atun._atio2.at_scclun = aep->at_scclun;
} else {
atun._atio2.at_lun = (uint8_t) aep->at_lun;
}
- if (FCPARAM(isp)->isp_2klogin) {
+ if (ISP_CAP_2KLOGIN(isp)) {
atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid;
} else {
atun._atio2.at_iid = aep->at_iid;
@@ -627,56 +610,91 @@ isp_target_put_atio(ispsoftc_t *isp, void *arg)
*/
int
-isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint32_t hdl)
+isp_endcmd(ispsoftc_t *isp, ...)
{
- int sts;
+ uint32_t code, hdl;
+ uint8_t sts;
union {
ct_entry_t _ctio;
ct2_entry_t _ctio2;
ct2e_entry_t _ctio2e;
ct7_entry_t _ctio7;
} un;
+ va_list ap;
- MEMZERO(&un, sizeof un);
- sts = code & 0xff;
+ ISP_MEMZERO(&un, sizeof un);
if (IS_24XX(isp)) {
- at7_entry_t *aep = arg;
+ int vpidx, nphdl;
+ at7_entry_t *aep;
ct7_entry_t *cto = &un._ctio7;
+ va_start(ap, isp);
+ aep = va_arg(ap, at7_entry_t *);
+ nphdl = va_arg(ap, int);
+ /*
+ * Note that vpidx may equal 0xff (unknown) here
+ */
+ vpidx = va_arg(ap, int);
+ code = va_arg(ap, uint32_t);
+ hdl = va_arg(ap, uint32_t);
+ va_end(ap);
+ isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] chan %d code %x", __func__, aep->at_rxid, vpidx, code);
+
+ sts = code & 0xff;
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
cto->ct_header.rqs_entry_count = 1;
-/* XXXX */ cto->ct_nphdl = aep->at_hdr.seq_id;
+ cto->ct_nphdl = nphdl;
cto->ct_rxid = aep->at_rxid;
- cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) |
- aep->at_hdr.s_id[2];
+ cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2];
cto->ct_iid_hi = aep->at_hdr.s_id[0];
cto->ct_oxid = aep->at_hdr.ox_id;
cto->ct_scsi_status = sts;
- cto->ct_flags = CT7_FLAG_MODE1 | CT7_NO_DATA | CT7_SENDSTATUS;
- if (sts == SCSI_CHECK && (code & ECMD_SVALID)) {
- cto->rsp.m1.ct_resplen = 16;
+ cto->ct_vpidx = vpidx;
+ cto->ct_flags = CT7_NOACK;
+ if (code & ECMD_TERMINATE) {
+ cto->ct_flags |= CT7_TERMINATE;
+ } else if (code & ECMD_SVALID) {
+ cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS;
+ cto->ct_scsi_status |= (FCP_SNSLEN_VALID << 8);
+ cto->rsp.m1.ct_resplen = cto->ct_senselen = min(16, MAXRESPLEN_24XX);
+ ISP_MEMZERO(cto->rsp.m1.ct_resp, sizeof (cto->rsp.m1.ct_resp));
cto->rsp.m1.ct_resp[0] = 0xf0;
cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
cto->rsp.m1.ct_resp[7] = 8;
cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
+ } else {
+ cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS;
}
if (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl) {
cto->ct_resid = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl;
- cto->ct_scsi_status |= CT2_DATA_UNDER;
+ if (cto->ct_resid < 0) {
+ cto->ct_scsi_status |= (FCP_RESID_OVERFLOW << 8);
+ } else if (cto->ct_resid > 0) {
+ cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8);
+ }
}
cto->ct_syshandle = hdl;
} else if (IS_FC(isp)) {
- at2_entry_t *aep = arg;
+ at2_entry_t *aep;
ct2_entry_t *cto = &un._ctio2;
+ va_start(ap, isp);
+ aep = va_arg(ap, at2_entry_t *);
+ code = va_arg(ap, uint32_t);
+ hdl = va_arg(ap, uint32_t);
+ va_end(ap);
+
+ isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] code %x", __func__, aep->at_rxid, code);
+
+ sts = code & 0xff;
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
cto->ct_header.rqs_entry_count = 1;
- if (FCPARAM(isp)->isp_sccfw == 0) {
+ if (ISP_CAP_SCCFW(isp) == 0) {
cto->ct_lun = aep->at_lun;
}
- if (FCPARAM(isp)->isp_2klogin) {
+ if (ISP_CAP_2KLOGIN(isp)) {
un._ctio2e.ct_iid = ((at2e_entry_t *)aep)->at_iid;
} else {
cto->ct_iid = aep->at_iid;
@@ -702,9 +720,17 @@ isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint32_t hdl)
}
cto->ct_syshandle = hdl;
} else {
- at_entry_t *aep = arg;
+ at_entry_t *aep;
ct_entry_t *cto = &un._ctio;
+ va_start(ap, isp);
+ aep = va_arg(ap, at_entry_t *);
+ code = va_arg(ap, uint32_t);
+ hdl = va_arg(ap, uint32_t);
+ va_end(ap);
+ isp_prt(isp, ISP_LOGTDEBUG0, "%s: [IID %d] code %x", __func__, aep->at_iid, code);
+ sts = code;
+
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
cto->ct_header.rqs_entry_count = 1;
cto->ct_fwhandle = aep->at_handle;
@@ -729,58 +755,66 @@ isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint32_t hdl)
/*
* These are either broadcast events or specifically CTIO fast completion
*/
+
int
isp_target_async(ispsoftc_t *isp, int bus, int event)
{
- tmd_notify_t notify;
+ isp_notify_t notify;
- MEMZERO(&notify, sizeof (tmd_notify_t));
+ ISP_MEMZERO(&notify, sizeof (isp_notify_t));
notify.nt_hba = isp;
- notify.nt_iid = INI_ANY;
- /* nt_tgt set in outer layers */
+ notify.nt_wwn = INI_ANY;
+ notify.nt_nphdl = NIL_HANDLE;
+ notify.nt_sid = PORT_ANY;
+ notify.nt_did = PORT_ANY;
+ notify.nt_tgt = TGT_ANY;
+ notify.nt_channel = bus;
notify.nt_lun = LUN_ANY;
notify.nt_tagval = TAG_ANY;
-
- if (IS_SCSI(isp)) {
- TAG_INSERT_BUS(notify.nt_tagval, bus);
- }
+ notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32);
switch (event) {
case ASYNC_LOOP_UP:
case ASYNC_PTPMODE:
+ isp_prt(isp, ISP_LOGTDEBUG0, "%s: LOOP UP", __func__);
notify.nt_ncode = NT_LINK_UP;
- (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
break;
case ASYNC_LOOP_DOWN:
+ isp_prt(isp, ISP_LOGTDEBUG0, "%s: LOOP DOWN", __func__);
notify.nt_ncode = NT_LINK_DOWN;
- (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
break;
case ASYNC_LIP_ERROR:
case ASYNC_LIP_F8:
case ASYNC_LIP_OCCURRED:
case ASYNC_LOOP_RESET:
+ isp_prt(isp, ISP_LOGTDEBUG0, "%s: LIP RESET", __func__);
notify.nt_ncode = NT_LIP_RESET;
- (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
break;
case ASYNC_BUS_RESET:
case ASYNC_TIMEOUT_RESET: /* XXX: where does this come from ? */
+ isp_prt(isp, ISP_LOGTDEBUG0, "%s: BUS RESET", __func__);
notify.nt_ncode = NT_BUS_RESET;
- (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
break;
case ASYNC_DEVICE_RESET:
+ isp_prt(isp, ISP_LOGTDEBUG0, "%s: DEVICE RESET", __func__);
notify.nt_ncode = NT_TARGET_RESET;
- (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
break;
case ASYNC_CTIO_DONE:
{
uint8_t storage[QENTRY_LEN];
+ isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO DONE", __func__);
memset(storage, 0, QENTRY_LEN);
if (IS_24XX(isp)) {
ct7_entry_t *ct = (ct7_entry_t *) storage;
ct->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
ct->ct_nphdl = CT7_OK;
ct->ct_syshandle = bus;
- ct->ct_flags = CT7_SENDSTATUS|CT7_FASTPOST;
+ ct->ct_flags = CT7_SENDSTATUS;
} else if (IS_FC(isp)) {
/* This should also suffice for 2K login code */
ct2_entry_t *ct = (ct2_entry_t *) storage;
@@ -795,14 +829,13 @@ isp_target_async(ispsoftc_t *isp, int bus, int event)
ct->ct_fwhandle = bus;
ct->ct_flags = CT_SENDSTATUS;
}
- (void) isp_async(isp, ISPASYNC_TARGET_ACTION, storage);
+ isp_async(isp, ISPASYNC_TARGET_ACTION, storage);
break;
}
default:
- isp_prt(isp, ISP_LOGERR,
- "isp_target_async: unknown event 0x%x", event);
+ isp_prt(isp, ISP_LOGERR, "%s: unknown event 0x%x", __func__, event);
if (isp->isp_state == ISP_RUNSTATE) {
- isp_notify_ack(isp, NULL);
+ (void) isp_notify_ack(isp, NULL);
}
break;
}
@@ -821,51 +854,54 @@ isp_target_async(ispsoftc_t *isp, int bus, int event)
static void
isp_got_msg(ispsoftc_t *isp, in_entry_t *inp)
{
- tmd_notify_t nt;
+ isp_notify_t notify;
uint8_t status = inp->in_status & ~QLTM_SVALID;
- MEMZERO(&nt, sizeof (nt));
- nt.nt_hba = isp;
- nt.nt_iid = GET_IID_VAL(inp->in_iid);
- nt.nt_tgt = inp->in_tgt;
- nt.nt_lun = inp->in_lun;
- IN_MAKE_TAGID(nt.nt_tagval, GET_BUS_VAL(inp->in_iid), 0, inp);
- nt.nt_lreserved = inp;
+ ISP_MEMZERO(&notify, sizeof (notify));
+ notify.nt_hba = isp;
+ notify.nt_wwn = INI_ANY;
+ notify.nt_nphdl = GET_IID_VAL(inp->in_iid);
+ notify.nt_sid = PORT_ANY;
+ notify.nt_did = PORT_ANY;
+ notify.nt_channel = GET_BUS_VAL(inp->in_iid);
+ notify.nt_tgt = inp->in_tgt;
+ notify.nt_lun = inp->in_lun;
+ IN_MAKE_TAGID(notify.nt_tagval, inp);
+ notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32);
+ notify.nt_lreserved = inp;
if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) {
switch (inp->in_msg[0]) {
case MSG_ABORT:
- nt.nt_ncode = NT_ABORT_TASK_SET;
+ notify.nt_ncode = NT_ABORT_TASK_SET;
break;
case MSG_BUS_DEV_RESET:
- nt.nt_ncode = NT_TARGET_RESET;
+ notify.nt_ncode = NT_TARGET_RESET;
break;
case MSG_ABORT_TAG:
- nt.nt_ncode = NT_ABORT_TASK;
+ notify.nt_ncode = NT_ABORT_TASK;
break;
case MSG_CLEAR_QUEUE:
- nt.nt_ncode = NT_CLEAR_TASK_SET;
+ notify.nt_ncode = NT_CLEAR_TASK_SET;
break;
case MSG_REL_RECOVERY:
- nt.nt_ncode = NT_CLEAR_ACA;
+ notify.nt_ncode = NT_CLEAR_ACA;
break;
case MSG_TERM_IO_PROC:
- nt.nt_ncode = NT_ABORT_TASK;
+ notify.nt_ncode = NT_ABORT_TASK;
break;
case MSG_LUN_RESET:
- nt.nt_ncode = NT_LUN_RESET;
+ notify.nt_ncode = NT_LUN_RESET;
break;
default:
- isp_prt(isp, ISP_LOGERR,
- "unhandled message 0x%x", inp->in_msg[0]);
- isp_notify_ack(isp, inp);
+ isp_prt(isp, ISP_LOGERR, "%s: unhandled message 0x%x", __func__, inp->in_msg[0]);
+ (void) isp_notify_ack(isp, inp);
return;
}
- (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
+ isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
} else {
- isp_prt(isp, ISP_LOGERR,
- "unknown immediate notify status 0x%x", inp->in_status);
- isp_notify_ack(isp, inp);
+ isp_prt(isp, ISP_LOGERR, "%s: unknown immediate notify status 0x%x", __func__, inp->in_status);
+ (void) isp_notify_ack(isp, inp);
}
}
@@ -875,169 +911,156 @@ isp_got_msg(ispsoftc_t *isp, in_entry_t *inp)
static void
isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp)
{
- tmd_notify_t nt;
+ isp_notify_t notify;
static const char f1[] = "%s from N-port handle 0x%x lun %d seq 0x%x";
- static const char f2[] = "unknown %s 0x%x lun %d N-Port handle 0x%x "
- "task flags 0x%x seq 0x%x\n";
+ static const char f2[] = "unknown %s 0x%x lun %d N-Port handle 0x%x task flags 0x%x seq 0x%x\n";
uint16_t seqid, loopid;
- MEMZERO(&nt, sizeof (tmd_notify_t));
- nt.nt_hba = isp;
- if (FCPARAM(isp)->isp_2klogin) {
- nt.nt_iid = ((in_fcentry_e_t *)inp)->in_iid;
+ ISP_MEMZERO(&notify, sizeof (isp_notify_t));
+ notify.nt_hba = isp;
+ notify.nt_wwn = INI_ANY;
+ if (ISP_CAP_2KLOGIN(isp)) {
+ notify.nt_nphdl = ((in_fcentry_e_t *)inp)->in_iid;
loopid = ((in_fcentry_e_t *)inp)->in_iid;
seqid = ((in_fcentry_e_t *)inp)->in_seqid;
} else {
- nt.nt_iid = inp->in_iid;
+ notify.nt_nphdl = inp->in_iid;
loopid = inp->in_iid;
seqid = inp->in_seqid;
}
+ notify.nt_sid = PORT_ANY;
+ notify.nt_did = PORT_ANY;
+
/* nt_tgt set in outer layers */
- if (FCPARAM(isp)->isp_sccfw) {
- nt.nt_lun = inp->in_scclun;
+ if (ISP_CAP_SCCFW(isp)) {
+ notify.nt_lun = inp->in_scclun;
} else {
- nt.nt_lun = inp->in_lun;
+ notify.nt_lun = inp->in_lun;
}
- IN_FC_MAKE_TAGID(nt.nt_tagval, 0, 0, seqid);
- nt.nt_need_ack = 1;
- nt.nt_lreserved = inp;
+ notify.nt_tagval = seqid;
+ notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32);
+ notify.nt_need_ack = 1;
+ notify.nt_lreserved = inp;
if (inp->in_status != IN_MSG_RECEIVED) {
- isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status",
- inp->in_status, nt.nt_lun, loopid, inp->in_task_flags,
- inp->in_seqid);
- isp_notify_ack(isp, inp);
+ isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status", inp->in_status, notify.nt_lun, loopid, inp->in_task_flags, inp->in_seqid);
+ (void) isp_notify_ack(isp, inp);
return;
}
if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) {
- isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
- loopid, nt.nt_lun, inp->in_seqid);
- nt.nt_ncode = NT_ABORT_TASK_SET;
+ isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", loopid, notify.nt_lun, inp->in_seqid);
+ notify.nt_ncode = NT_ABORT_TASK_SET;
} else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
- isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
- loopid, nt.nt_lun, inp->in_seqid);
- nt.nt_ncode = NT_CLEAR_TASK_SET;
+ isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", loopid, notify.nt_lun, inp->in_seqid);
+ notify.nt_ncode = NT_CLEAR_TASK_SET;
} else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) {
- isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET",
- loopid, nt.nt_lun, inp->in_seqid);
- nt.nt_ncode = NT_LUN_RESET;
+ isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", loopid, notify.nt_lun, inp->in_seqid);
+ notify.nt_ncode = NT_LUN_RESET;
} else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
- isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
- loopid, nt.nt_lun, inp->in_seqid);
- nt.nt_ncode = NT_TARGET_RESET;
+ isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", loopid, notify.nt_lun, inp->in_seqid);
+ notify.nt_ncode = NT_TARGET_RESET;
} else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
- isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
- loopid, nt.nt_lun, inp->in_seqid);
- nt.nt_ncode = NT_CLEAR_ACA;
+ isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", loopid, notify.nt_lun, inp->in_seqid);
+ notify.nt_ncode = NT_CLEAR_ACA;
} else {
- isp_prt(isp, ISP_LOGWARN, f2, "task flag", inp->in_status,
- nt.nt_lun, loopid, inp->in_task_flags, inp->in_seqid);
- isp_notify_ack(isp, inp);
+ isp_prt(isp, ISP_LOGWARN, f2, "task flag", inp->in_status, notify.nt_lun, loopid, inp->in_task_flags, inp->in_seqid);
+ (void) isp_notify_ack(isp, inp);
return;
}
- (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
+ isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
}
-#define HILO(x) (uint32_t) (x >> 32), (uint32_t) x
static void
isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep)
{
- tmd_notify_t nt;
- static const char f1[] =
- "%s from PortID 0x%06x lun %d seq 0x%08x%08x";
- static const char f2[] =
- "unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%08x%08x";
- uint32_t sid;
-
- MEMZERO(&nt, sizeof (tmd_notify_t));
- nt.nt_hba = isp;
- nt.nt_iid = INI_ANY;
- nt.nt_lun =
- (aep->at_cmnd.fcp_cmnd_lun[0] << 8) |
- (aep->at_cmnd.fcp_cmnd_lun[1]);
- /*
- * XXX: VPIDX HAS TO BE DERIVED FROM DESTINATION PORT
- */
- nt.nt_tagval = aep->at_rxid;
- nt.nt_lreserved = aep;
- sid =
- (aep->at_hdr.s_id[0] << 16) |
- (aep->at_hdr.s_id[1] << 8) |
- (aep->at_hdr.s_id[2]);
-
- if (aep->at_cmnd.fcp_cmnd_task_management &
- FCP_CMND_TMF_ABORT_TASK_SET) {
- isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
- sid, nt.nt_lun, HILO(nt.nt_tagval));
- nt.nt_ncode = NT_ABORT_TASK_SET;
- } else if (aep->at_cmnd.fcp_cmnd_task_management &
- FCP_CMND_TMF_CLEAR_TASK_SET) {
- isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
- sid, nt.nt_lun, HILO(nt.nt_tagval));
- nt.nt_ncode = NT_CLEAR_TASK_SET;
- } else if (aep->at_cmnd.fcp_cmnd_task_management &
- FCP_CMND_TMF_LUN_RESET) {
- isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET",
- sid, nt.nt_lun, HILO(nt.nt_tagval));
- nt.nt_ncode = NT_LUN_RESET;
- } else if (aep->at_cmnd.fcp_cmnd_task_management &
- FCP_CMND_TMF_TGT_RESET) {
- isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
- sid, nt.nt_lun, HILO(nt.nt_tagval));
- nt.nt_ncode = NT_TARGET_RESET;
- nt.nt_lun = LUN_ANY;
- } else if (aep->at_cmnd.fcp_cmnd_task_management &
- FCP_CMND_TMF_CLEAR_ACA) {
- isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
- sid, nt.nt_lun, HILO(nt.nt_tagval));
- nt.nt_ncode = NT_CLEAR_ACA;
+ isp_notify_t notify;
+ static const char f1[] = "%s from PortID 0x%06x lun %d seq 0x%08x";
+ static const char f2[] = "unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%08x";
+ uint16_t chan;
+ uint32_t sid, did;
+
+ ISP_MEMZERO(&notify, sizeof (isp_notify_t));
+ notify.nt_hba = isp;
+ notify.nt_wwn = INI_ANY;
+ notify.nt_lun = (aep->at_cmnd.fcp_cmnd_lun[0] << 8) | (aep->at_cmnd.fcp_cmnd_lun[1]);
+ notify.nt_tagval = aep->at_rxid;
+ notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32);
+ notify.nt_lreserved = aep;
+ sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | (aep->at_hdr.s_id[2]);
+
+ /* Channel has to derived from D_ID */
+ did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2];
+ for (chan = 0; chan < isp->isp_nchan; chan++) {
+ if (FCPARAM(isp, chan)->isp_portid == did) {
+ break;
+ }
+ }
+ if (chan == isp->isp_nchan) {
+ isp_prt(isp, ISP_LOGWARN, "%s: D_ID 0x%x not found on any channel", __func__, did);
+ /* just drop on the floor */
+ return;
+ }
+ notify.nt_nphdl = NIL_HANDLE; /* unknown here */
+ notify.nt_sid = sid;
+ notify.nt_did = did;
+ notify.nt_channel = chan;
+ if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_ABORT_TASK_SET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", sid, notify.nt_lun, aep->at_rxid);
+ notify.nt_ncode = NT_ABORT_TASK_SET;
+ } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_CLEAR_TASK_SET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", sid, notify.nt_lun, aep->at_rxid);
+ notify.nt_ncode = NT_CLEAR_TASK_SET;
+ } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_LUN_RESET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", sid, notify.nt_lun, aep->at_rxid);
+ notify.nt_ncode = NT_LUN_RESET;
+ } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_TGT_RESET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", sid, notify.nt_lun, aep->at_rxid);
+ notify.nt_ncode = NT_TARGET_RESET;
+ } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_CLEAR_ACA) {
+ isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", sid, notify.nt_lun, aep->at_rxid);
+ notify.nt_ncode = NT_CLEAR_ACA;
} else {
- isp_prt(isp, ISP_LOGWARN, f2,
- aep->at_cmnd.fcp_cmnd_task_management,
- nt.nt_lun, sid, HILO(nt.nt_tagval));
- isp_endcmd(isp, aep, 0, 0);
+ isp_prt(isp, ISP_LOGWARN, f2, aep->at_cmnd.fcp_cmnd_task_management, notify.nt_lun, sid, aep->at_rxid);
+ notify.nt_ncode = NT_UNKNOWN;
return;
}
- (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
+ isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
}
-void
+int
isp_notify_ack(ispsoftc_t *isp, void *arg)
{
char storage[QENTRY_LEN];
- uint32_t nxti, optr;
void *outp;
- if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
- isp_prt(isp, ISP_LOGWARN,
- "Request Queue Overflow For isp_notify_ack");
- return;
+ /*
+ * This is in case a Task Management Function ends up here.
+ */
+ if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) {
+ at7_entry_t *aep = arg;
+ return (isp_endcmd(isp, aep, NIL_HANDLE, 0, 0, 0));
}
- MEMZERO(storage, QENTRY_LEN);
+ outp = isp_getrqentry(isp);
+ if (outp == NULL) {
+ isp_prt(isp, ISP_LOGWARN, rqo, __func__);
+ return (1);
+ }
- if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) {
- at7_entry_t *aep = arg;
- isp_endcmd(isp, aep, 0, 0);
- return;
- } else if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ABTS_RSP)) {
- abts_rsp_t *abts_rsp = (abts_rsp_t *) storage;
- /*
- * The caller will have set response values as appropriate
- * in the ABTS structure just before calling us.
- */
- MEMCPY(abts_rsp, arg, QENTRY_LEN);
- isp_put_abts_rsp(isp, abts_rsp, (abts_rsp_t *)outp);
- } else if (IS_24XX(isp)) {
+ ISP_MEMZERO(storage, QENTRY_LEN);
+
+ if (IS_24XX(isp)) {
na_fcentry_24xx_t *na = (na_fcentry_24xx_t *) storage;
if (arg) {
in_fcentry_24xx_t *in = arg;
na->na_nphdl = in->in_nphdl;
+ na->na_flags = in->in_flags & IN24XX_FLAG_PUREX_IOCB;
na->na_status = in->in_status;
na->na_status_subcode = in->in_status_subcode;
na->na_rxid = in->in_rxid;
na->na_oxid = in->in_oxid;
+ na->na_vpidx = in->in_vpidx;
if (in->in_status == IN24XX_SRR_RCVD) {
na->na_srr_rxid = in->in_srr_rxid;
na->na_srr_reloff_hi = in->in_srr_reloff_hi;
@@ -1058,17 +1081,15 @@ isp_notify_ack(ispsoftc_t *isp, void *arg)
if (arg) {
in_fcentry_t *inp = arg;
- MEMCPY(storage, arg, sizeof (isphdr_t));
- if (FCPARAM(isp)->isp_2klogin) {
- ((na_fcentry_e_t *)na)->na_iid =
- ((in_fcentry_e_t *)inp)->in_iid;
+ ISP_MEMCPY(storage, arg, sizeof (isphdr_t));
+ if (ISP_CAP_2KLOGIN(isp)) {
+ ((na_fcentry_e_t *)na)->na_iid = ((in_fcentry_e_t *)inp)->in_iid;
iid = ((na_fcentry_e_t *)na)->na_iid;
} else {
na->na_iid = inp->in_iid;
iid = na->na_iid;
}
- na->na_task_flags =
- inp->in_task_flags & TASK_FLAGS_RESERVED_MASK;
+ na->na_task_flags = inp->in_task_flags & TASK_FLAGS_RESERVED_MASK;
na->na_seqid = inp->in_seqid;
na->na_flags = NAFC_RCOUNT;
na->na_status = inp->in_status;
@@ -1084,20 +1105,18 @@ isp_notify_ack(ispsoftc_t *isp, void *arg)
}
na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
na->na_header.rqs_entry_count = 1;
- if (FCPARAM(isp)->isp_2klogin) {
- isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na,
- (na_fcentry_e_t *)outp);
+ if (ISP_CAP_2KLOGIN(isp)) {
+ isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na, (na_fcentry_e_t *)outp);
} else {
isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
}
- isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u seqid %x "
- "flags %x tflags %x response %x", iid, na->na_seqid,
+ isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u seqid %x flags %x tflags %x response %x", iid, na->na_seqid,
na->na_flags, na->na_task_flags, na->na_response);
} else {
na_entry_t *na = (na_entry_t *) storage;
if (arg) {
in_entry_t *inp = arg;
- MEMCPY(storage, arg, sizeof (isphdr_t));
+ ISP_MEMCPY(storage, arg, sizeof (isphdr_t));
na->na_iid = inp->in_iid;
na->na_lun = inp->in_lun;
na->na_tgt = inp->in_tgt;
@@ -1111,12 +1130,90 @@ isp_notify_ack(ispsoftc_t *isp, void *arg)
na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
na->na_header.rqs_entry_count = 1;
isp_put_notify_ack(isp, na, (na_entry_t *)outp);
- isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u lun %u tgt "
- "%u seqid %x event %x", na->na_iid, na->na_lun, na->na_tgt,
- na->na_seqid, na->na_event);
+ isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u lun %u tgt %u seqid %x event %x", na->na_iid, na->na_lun, na->na_tgt, na->na_seqid, na->na_event);
+ }
+ ISP_TDQE(isp, "isp_notify_ack", isp->isp_reqidx, storage);
+ ISP_SYNC_REQUEST(isp);
+ return (0);
+}
+
+int
+isp_acknak_abts(ispsoftc_t *isp, void *arg, int errno)
+{
+ char storage[QENTRY_LEN];
+ uint16_t tmpw;
+ uint8_t tmpb;
+ abts_t *abts = arg;
+ abts_rsp_t *rsp = (abts_rsp_t *) storage;
+ void *outp;
+
+ if (!IS_24XX(isp)) {
+ isp_prt(isp, ISP_LOGERR, "%s: called for non-24XX card", __func__);
+ return (0);
+ }
+
+ if (abts->abts_header.rqs_entry_type != RQSTYPE_ABTS_RCVD) {
+ isp_prt(isp, ISP_LOGERR, "%s: called for non-ABTS entry (0x%x)", __func__, abts->abts_header.rqs_entry_type);
+ return (0);
+ }
+
+ outp = isp_getrqentry(isp);
+ if (outp == NULL) {
+ isp_prt(isp, ISP_LOGWARN, rqo, __func__);
+ return (1);
+ }
+
+ ISP_MEMCPY(rsp, abts, QENTRY_LEN);
+ rsp->abts_rsp_header.rqs_entry_type = RQSTYPE_ABTS_RSP;
+
+ /*
+ * Swap destination and source for response.
+ */
+ rsp->abts_rsp_r_ctl = BA_ACC;
+ tmpw = rsp->abts_rsp_did_lo;
+ tmpb = rsp->abts_rsp_did_hi;
+ rsp->abts_rsp_did_lo = rsp->abts_rsp_sid_lo;
+ rsp->abts_rsp_did_hi = rsp->abts_rsp_sid_hi;
+ rsp->abts_rsp_sid_lo = tmpw;
+ rsp->abts_rsp_sid_hi = tmpb;
+
+ rsp->abts_rsp_f_ctl_hi ^= 0x80; /* invert Exchange Context */
+ rsp->abts_rsp_f_ctl_hi &= ~0x7f; /* clear Sequence Initiator and other bits */
+ rsp->abts_rsp_f_ctl_hi |= 0x10; /* abort the whole exchange */
+ rsp->abts_rsp_f_ctl_hi |= 0x8; /* last data frame of sequence */
+ rsp->abts_rsp_f_ctl_hi |= 0x1; /* transfer Sequence Initiative */
+ rsp->abts_rsp_f_ctl_lo = 0;
+
+ if (errno == 0) {
+ uint16_t rx_id, ox_id;
+
+ rx_id = rsp->abts_rsp_rx_id;
+ ox_id = rsp->abts_rsp_ox_id;
+ ISP_MEMZERO(&rsp->abts_rsp_payload.ba_acc, sizeof (rsp->abts_rsp_payload.ba_acc));
+ 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);
+ rsp->abts_rsp_payload.ba_acc.aborted_rx_id = rx_id;
+ rsp->abts_rsp_payload.ba_acc.aborted_ox_id = ox_id;
+ rsp->abts_rsp_payload.ba_acc.high_seq_cnt = 0xffff;
+ } else {
+ ISP_MEMZERO(&rsp->abts_rsp_payload.ba_rjt, sizeof (rsp->abts_rsp_payload.ba_acc));
+ switch (errno) {
+ case ENOMEM:
+ rsp->abts_rsp_payload.ba_rjt.reason = 5; /* Logical Busy */
+ break;
+ default:
+ rsp->abts_rsp_payload.ba_rjt.reason = 9; /* Unable to perform command request */
+ break;
+ }
}
- ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage);
- ISP_ADD_REQUEST(isp, nxti);
+
+ /*
+ * The caller will have set response values as appropriate
+ * in the ABTS structure just before calling us.
+ */
+ isp_put_abts_rsp(isp, rsp, (abts_rsp_t *)outp);
+ ISP_TDQE(isp, "isp_acknak_abts", isp->isp_reqidx, storage);
+ ISP_SYNC_REQUEST(isp);
+ return (0);
}
static void
@@ -1136,13 +1233,12 @@ isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep)
* about this so it's ignored.
*/
- switch(aep->at_status & ~QLTM_SVALID) {
+ switch (aep->at_status & ~QLTM_SVALID) {
case AT_PATH_INVALID:
/*
* ATIO rejected by the firmware due to disabled lun.
*/
- isp_prt(isp, ISP_LOGERR,
- "rejected ATIO for disabled lun %d", lun);
+ isp_prt(isp, ISP_LOGERR, "rejected ATIO for disabled lun %d", lun);
break;
case AT_NOCAP:
/*
@@ -1150,9 +1246,7 @@ isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep)
* We sent an ATIO that overflowed the firmware's
* command resource count.
*/
- isp_prt(isp, ISP_LOGERR,
- "rejected ATIO for lun %d because of command count"
- " overflow", lun);
+ isp_prt(isp, ISP_LOGERR, "rejected ATIO for lun %d because of command count overflow", lun);
break;
case AT_BDR_MSG:
@@ -1165,8 +1259,7 @@ isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep)
* not increment it. Therefore we should never get
* this status here.
*/
- isp_prt(isp, ISP_LOGERR, atiocope, lun,
- GET_BUS_VAL(aep->at_iid));
+ isp_prt(isp, ISP_LOGERR, atiocope, lun, GET_BUS_VAL(aep->at_iid));
break;
case AT_CDB: /* Got a CDB */
@@ -1174,7 +1267,7 @@ isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep)
/*
* Punt to platform specific layer.
*/
- (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
+ isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
break;
case AT_RESET:
@@ -1186,15 +1279,12 @@ isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep)
* Ignore it because the async event will clear things
* up for us.
*/
- isp_prt(isp, ISP_LOGWARN, atior, lun,
- GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid));
+ isp_prt(isp, ISP_LOGWARN, atior, lun, GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid));
break;
default:
- isp_prt(isp, ISP_LOGERR,
- "Unknown ATIO status 0x%x from loopid %d for lun %d",
- aep->at_status, aep->at_iid, lun);
+ isp_prt(isp, ISP_LOGERR, "Unknown ATIO status 0x%x from loopid %d for lun %d", aep->at_status, aep->at_iid, lun);
(void) isp_target_put_atio(isp, aep);
break;
}
@@ -1205,13 +1295,13 @@ isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep)
{
int lun, iid;
- if (FCPARAM(isp)->isp_sccfw) {
+ if (ISP_CAP_SCCFW(isp)) {
lun = aep->at_scclun;
} else {
lun = aep->at_lun;
}
- if (FCPARAM(isp)->isp_2klogin) {
+ if (ISP_CAP_2KLOGIN(isp)) {
iid = ((at2e_entry_t *)aep)->at_iid;
} else {
iid = aep->at_iid;
@@ -1229,13 +1319,12 @@ isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep)
* about this so it's ignored.
*/
- switch(aep->at_status & ~QLTM_SVALID) {
+ switch (aep->at_status & ~QLTM_SVALID) {
case AT_PATH_INVALID:
/*
* ATIO rejected by the firmware due to disabled lun.
*/
- isp_prt(isp, ISP_LOGERR,
- "rejected ATIO2 for disabled lun %d", lun);
+ isp_prt(isp, ISP_LOGERR, "rejected ATIO2 for disabled lun %d", lun);
break;
case AT_NOCAP:
/*
@@ -1243,8 +1332,7 @@ isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep)
* We sent an ATIO that overflowed the firmware's
* command resource count.
*/
- isp_prt(isp, ISP_LOGERR,
- "rejected ATIO2 for lun %d- command count overflow", lun);
+ isp_prt(isp, ISP_LOGERR, "rejected ATIO2 for lun %d- command count overflow", lun);
break;
case AT_BDR_MSG:
@@ -1264,7 +1352,7 @@ isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep)
/*
* Punt to platform specific layer.
*/
- (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
+ isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
break;
case AT_RESET:
@@ -1281,9 +1369,7 @@ isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep)
default:
- isp_prt(isp, ISP_LOGERR,
- "Unknown ATIO2 status 0x%x from loopid %d for lun %d",
- aep->at_status, iid, lun);
+ isp_prt(isp, ISP_LOGERR, "Unknown ATIO2 status 0x%x from loopid %d for lun %d", aep->at_status, iid, lun);
(void) isp_target_put_atio(isp, aep);
break;
}
@@ -1305,7 +1391,7 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
xs = NULL;
}
- switch(ct->ct_status & ~QLTM_SVALID) {
+ switch (ct->ct_status & ~QLTM_SVALID) {
case CT_OK:
/*
* There are generally 3 possibilities as to why we'd get
@@ -1321,8 +1407,7 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
/*
* Nothing to do in this case.
*/
- isp_prt(isp, pl, "CTIO- iid %d disconnected OK",
- ct->ct_iid);
+ isp_prt(isp, pl, "CTIO- iid %d disconnected OK", ct->ct_iid);
return;
}
break;
@@ -1351,7 +1436,6 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
*/
if (fmsg == NULL)
fmsg = "ABORT TAG message sent by Initiator";
-
isp_prt(isp, ISP_LOGTDEBUG0, "CTIO destroyed by %s", fmsg);
break;
@@ -1360,9 +1444,7 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
* CTIO rejected by the firmware due to disabled lun.
* "Cannot Happen".
*/
- isp_prt(isp, ISP_LOGERR,
- "Firmware rejected CTIO for disabled lun %d",
- ct->ct_lun);
+ isp_prt(isp, ISP_LOGERR, "Firmware rejected CTIO for disabled lun %d", ct->ct_lun);
break;
case CT_NOPATH:
@@ -1372,9 +1454,7 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
* we tried to access the bus while a non-disconnecting
* command is in process.
*/
- isp_prt(isp, ISP_LOGERR,
- "Firmware rejected CTIO for bad nexus %d/%d/%d",
- ct->ct_iid, ct->ct_tgt, ct->ct_lun);
+ isp_prt(isp, ISP_LOGERR, "Firmware rejected CTIO for bad nexus %d/%d/%d", ct->ct_iid, ct->ct_tgt, ct->ct_lun);
break;
case CT_RSELTMO:
@@ -1383,7 +1463,7 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
case CT_TIMEOUT:
if (fmsg == NULL)
fmsg = "Command";
- isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
+ isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg);
break;
case CT_PANIC:
@@ -1408,8 +1488,7 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
break;
default:
- isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
- ct->ct_status & ~QLTM_SVALID);
+ isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x", ct->ct_status & ~QLTM_SVALID);
break;
}
@@ -1423,16 +1502,12 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
*/
if (ct->ct_syshandle == 0) {
if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
- isp_prt(isp, pl,
- "intermediate CTIO completed ok");
+ isp_prt(isp, pl, "intermediate CTIO completed ok");
} else {
- isp_prt(isp, pl,
- "unmonitored CTIO completed ok");
+ isp_prt(isp, pl, "unmonitored CTIO completed ok");
}
} else {
- isp_prt(isp, pl,
- "NO xs for CTIO (handle 0x%x) status 0x%x",
- ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
+ isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
}
} else {
/*
@@ -1446,7 +1521,7 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
/*
* The platform layer will destroy the handle if appropriate.
*/
- (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
+ isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
}
}
@@ -1466,7 +1541,7 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
xs = NULL;
}
- switch(ct->ct_status & ~QLTM_SVALID) {
+ switch (ct->ct_status & ~QLTM_SVALID) {
case CT_BUS_ERROR:
isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
/* FALL Through */
@@ -1507,8 +1582,7 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
fmsg = "ABORT";
}
- isp_prt(isp, ISP_LOGTDEBUG0,
- "CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
+ isp_prt(isp, ISP_LOGTDEBUG0, "CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
break;
case CT_INVAL:
@@ -1524,7 +1598,7 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
case CT_TIMEOUT:
if (fmsg == NULL)
fmsg = "command";
- isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
+ isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg);
break;
case CT_ERR:
@@ -1553,13 +1627,11 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
* CTIO rejected by the firmware because an invalid RX_ID.
* Just print a message.
*/
- isp_prt(isp, ISP_LOGWARN,
- "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
+ isp_prt(isp, ISP_LOGWARN, "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
break;
default:
- isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x",
- ct->ct_status & ~QLTM_SVALID);
+ isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x", ct->ct_status & ~QLTM_SVALID);
break;
}
@@ -1573,16 +1645,12 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
*/
if (ct->ct_syshandle == 0) {
if ((ct->ct_flags & CT2_SENDSTATUS) == 0) {
- isp_prt(isp, pl,
- "intermediate CTIO completed ok");
+ isp_prt(isp, pl, "intermediate CTIO completed ok");
} else {
- isp_prt(isp, pl,
- "unmonitored CTIO completed ok");
+ isp_prt(isp, pl, "unmonitored CTIO completed ok");
}
} else {
- isp_prt(isp, pl,
- "NO xs for CTIO (handle 0x%x) status 0x%x",
- ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
+ isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
}
} else {
if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
@@ -1605,7 +1673,7 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
*/
isp_prt(isp, pl, "data CTIO complete");
}
- (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
+ isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
/*
* The platform layer will destroy the handle if appropriate.
*/
@@ -1628,7 +1696,7 @@ isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct)
xs = NULL;
}
- switch(ct->ct_nphdl) {
+ switch (ct->ct_nphdl) {
case CT7_BUS_ERROR:
isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
/* FALL Through */
@@ -1658,15 +1726,14 @@ isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct)
if (fmsg == NULL) {
fmsg = "ABORT";
}
- isp_prt(isp, ISP_LOGTDEBUG0,
- "CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
+ isp_prt(isp, ISP_LOGTDEBUG0, "CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
break;
case CT7_TIMEOUT:
if (fmsg == NULL) {
fmsg = "command";
}
- isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
+ isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg);
break;
case CT7_ERR:
@@ -1694,8 +1761,7 @@ isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct)
* CTIO rejected by the firmware because an invalid RX_ID.
* Just print a message.
*/
- isp_prt(isp, ISP_LOGWARN,
- "CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
+ isp_prt(isp, ISP_LOGWARN, "CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
break;
case CT7_REASSY_ERR:
@@ -1707,8 +1773,7 @@ isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct)
break;
default:
- isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x",
- ct->ct_nphdl);
+ isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x", ct->ct_nphdl);
break;
}
@@ -1722,26 +1787,20 @@ isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct)
*/
if (ct->ct_syshandle == 0) {
if (ct->ct_flags & CT7_TERMINATE) {
- isp_prt(isp, ISP_LOGINFO,
- "termination of 0x%x complete",
- ct->ct_rxid);
+ isp_prt(isp, ISP_LOGINFO, "termination of 0x%x complete", ct->ct_rxid);
} else if ((ct->ct_flags & CT7_SENDSTATUS) == 0) {
- isp_prt(isp, pl,
- "intermediate CTIO completed ok");
+ isp_prt(isp, pl, "intermediate CTIO completed ok");
} else {
- isp_prt(isp, pl,
- "unmonitored CTIO completed ok");
+ isp_prt(isp, pl, "unmonitored CTIO completed ok");
}
} else {
- isp_prt(isp, pl,
- "NO xs for CTIO (handle 0x%x) status 0x%x",
- ct->ct_syshandle, ct->ct_nphdl);
+ isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_nphdl);
}
} else {
- if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
+ if ((ct->ct_flags & CT7_DATAMASK) != CT7_NO_DATA) {
ISP_DMAFREE(isp, xs, ct->ct_syshandle);
}
- if (ct->ct_flags & CT2_SENDSTATUS) {
+ if (ct->ct_flags & CT7_SENDSTATUS) {
/*
* Sent status and command complete.
*
@@ -1758,10 +1817,56 @@ isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct)
*/
isp_prt(isp, pl, "data CTIO complete");
}
- (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
+ isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
/*
* The platform layer will destroy the handle if appropriate.
*/
}
}
+
+static void
+isp_handle_24xx_inotify(ispsoftc_t *isp, in_fcentry_24xx_t *inot_24xx)
+{
+ uint8_t ochan, chan, lochan, hichan;
+
+ /*
+ * Check to see whether we got a wildcard channel.
+ * If so, we have to iterate over all channels.
+ */
+ ochan = chan = ISP_GET_VPIDX(isp, inot_24xx->in_vpidx);
+ if (chan == 0xff) {
+ lochan = 0;
+ hichan = isp->isp_nchan;
+ } else {
+ if (chan >= isp->isp_nchan) {
+ char buf[64];
+ ISP_SNPRINTF(buf, sizeof buf, "%s: bad channel %d for status 0x%x", __func__, chan, inot_24xx->in_status);
+ isp_print_bytes(isp, buf, QENTRY_LEN, inot_24xx);
+ (void) isp_notify_ack(isp, inot_24xx);
+ return;
+ }
+ lochan = chan;
+ hichan = chan + 1;
+ }
+ 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);
+ for (chan = lochan; chan < hichan; chan++) {
+ switch (inot_24xx->in_status) {
+ case IN24XX_LIP_RESET:
+ case IN24XX_LINK_RESET:
+ case IN24XX_PORT_LOGOUT:
+ case IN24XX_PORT_CHANGED:
+ case IN24XX_LINK_FAILED:
+ case IN24XX_SRR_RCVD:
+ case IN24XX_ELS_RCVD:
+ inot_24xx->in_vpidx = chan;
+ isp_async(isp, ISPASYNC_TARGET_ACTION, inot_24xx);
+ break;
+ default:
+ isp_prt(isp, ISP_LOGINFO, "%s: unhandled status (0x%x) for chan %d", __func__, inot_24xx->in_status, chan);
+ (void) isp_notify_ack(isp, inot_24xx);
+ break;
+ }
+ }
+ inot_24xx->in_vpidx = ochan;
+}
#endif
OpenPOWER on IntegriCloud