summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/isp/isp.c396
-rw-r--r--sys/dev/isp/isp_freebsd.c3
-rw-r--r--sys/dev/isp/isp_library.c35
-rw-r--r--sys/dev/isp/isp_library.h1
-rw-r--r--sys/dev/isp/isp_pci.c18
-rw-r--r--sys/dev/isp/isp_target.c4
-rw-r--r--sys/dev/isp/ispmbox.h18
-rw-r--r--sys/dev/isp/ispreg.h4
8 files changed, 234 insertions, 245 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 33ba5ec..65e5d86 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -108,10 +108,11 @@ static const uint8_t alpa_map[] = {
* Local function prototypes.
*/
static int isp_parse_async(ispsoftc_t *, uint16_t);
+static int isp_parse_async_fc(ispsoftc_t *, uint16_t);
static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *);
static void isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *); static void
isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *);
-static void isp_fastpost_complete(ispsoftc_t *, uint16_t);
+static void isp_fastpost_complete(ispsoftc_t *, uint32_t);
static int isp_mbox_continue(ispsoftc_t *);
static void isp_scsi_init(ispsoftc_t *);
static void isp_scsi_channel_init(ispsoftc_t *, int);
@@ -1334,23 +1335,24 @@ isp_scsi_init(ispsoftc_t *isp)
}
/*
- * Turn on Fast Posting, LVD transitions
+ * Turn on LVD transitions for ULTRA2 or better and other features
*
- * Ultra2 F/W always has had fast posting (and LVD transitions)
- *
- * Ultra and older (i.e., SBus) cards may not. It's just safer
- * to assume not for them.
+ * Now that we have 32 bit handles, don't do any fast posting
+ * any more. For Ultra2/Ultra3 cards, we can turn on 32 bit RIO
+ * operation or use fast posting. To be conservative, we'll only
+ * do this for Ultra3 cards now because the other cards are so
+ * rare for this author to find and test with.
*/
MBSINIT(&mbs, MBOX_SET_FW_FEATURES, MBLOGALL, 0);
if (IS_ULTRA2(isp))
mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
-#ifndef ISP_NO_RIO
- if (IS_ULTRA2(isp) || IS_1240(isp))
- mbs.param[1] |= FW_FEATURE_RIO_16BIT;
-#else
- if (IS_ULTRA2(isp) || IS_1240(isp))
+#ifdef ISP_NO_RIO
+ if (IS_ULTRA3(isp))
mbs.param[1] |= FW_FEATURE_FAST_POST;
+#else
+ if (IS_ULTRA3(isp))
+ mbs.param[1] |= FW_FEATURE_RIO_32BIT;
#endif
if (mbs.param[1] != 0) {
uint16_t sfeat = mbs.param[1];
@@ -1604,25 +1606,15 @@ isp_fibre_init(ispsoftc_t *isp)
}
if (IS_2200(isp)) {
/*
- * There seems to just be too much breakage here
- * with RIO and Fast Posting- it probably actually
- * works okay but this driver is messing it up.
- * This card is really ancient by now, so let's
- * just opt for safety and not use the feature.
+ * We can't have Fast Posting any more- we now
+ * have 32 bit handles.
+ *
+ * RIO seemed to have to much breakage.
+ *
+ * Just opt for safety.
*/
-#if 0
- if (ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
- icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
- icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
- icbp->icb_racctimer = 4;
- icbp->icb_idelaytimer = 8;
- } else {
- icbp->icb_fwoptions |= ICBOPT_FAST_POST;
- }
-#else
icbp->icb_xfwoptions &= ~ICBXOPT_RIO_16BIT;
icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
-#endif
} else {
/*
* QLogic recommends that FAST Posting be turned
@@ -4863,7 +4855,7 @@ again:
*/
if (sema) {
fmbox:
- if (mbox & 0x4000) {
+ if (mbox & MBOX_COMMAND_COMPLETE) {
isp->isp_intmboxc++;
if (isp->isp_mboxbsy) {
int obits = isp->isp_obits;
@@ -4883,10 +4875,13 @@ again:
} else {
isp_prt(isp, ISP_LOGWARN, "mailbox cmd (0x%x) with no waiters", mbox);
}
- } else if (isp_parse_async(isp, mbox) < 0) {
- return;
+ } else {
+ i = IS_FC(isp)? isp_parse_async_fc(isp, mbox) : isp_parse_async(isp, mbox);
+ if (i < 0) {
+ return;
+ }
}
- if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) || isp->isp_state != ISP_RUNSTATE) {
+ if ((IS_FC(isp) && mbox != ASYNC_RIOZIO_STALL) || isp->isp_state != ISP_RUNSTATE) {
goto out;
}
}
@@ -5068,9 +5063,9 @@ again:
req_status_flags = sp->req_status_flags;
req_state_flags = sp->req_state_flags;
resid = sp->req_resid;
- } else if (etype == RQSTYPE_RIO2) {
- isp_rio2_t *rio = (isp_rio2_t *)qe;
- isp_get_rio2(isp, (isp_rio2_t *) hp, rio);
+ } else if (etype == RQSTYPE_RIO1) {
+ isp_rio1_t *rio = (isp_rio1_t *) qe;
+ isp_get_rio1(isp, (isp_rio1_t *) hp, rio);
if (isp->isp_dblev & ISP_LOGDEBUG1) {
isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, rio);
}
@@ -5082,6 +5077,10 @@ again:
}
ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
continue;
+ } else if (etype == RQSTYPE_RIO2) {
+ isp_prt(isp, ISP_LOGERR, "dropping RIO2 response\n");
+ ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
+ continue;
} else {
/*
* Somebody reachable via isp_handle_other_response
@@ -5394,40 +5393,35 @@ out:
* Support routines.
*/
-#define GET_24XX_BUS(isp, chan, msg) \
- if (IS_24XX(isp)) { \
- chan = ISP_READ(isp, OUTMAILBOX3) & 0xff; \
- if (chan >= isp->isp_nchan) { \
- isp_prt(isp, ISP_LOGERR, "bogus channel %u for %s at line %d", chan, msg, __LINE__); \
- break; \
- } \
- }
-
+/*
+ * Parse an ASYNC mailbox complete
+ *
+ * Return non-zero if the event has been acknowledged.
+ */
static int
isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
{
- int rval = 0;
- int pattern = 0;
- uint16_t chan;
+ int acked = 0;
+ uint32_t h1 = 0, h2 = 0;
+ uint16_t chan = 0;
- if (IS_DUALBUS(isp)) {
- chan = ISP_READ(isp, OUTMAILBOX6);
- } else {
- chan = 0;
+ /*
+ * Pick up the channel, but not if this is a ASYNC_RIO32_2,
+ * where Mailboxes 6/7 have the second handle.
+ */
+ if (mbox != ASYNC_RIO32_2) {
+ if (IS_DUALBUS(isp)) {
+ chan = ISP_READ(isp, OUTMAILBOX6);
+ }
}
isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
switch (mbox) {
case ASYNC_BUS_RESET:
- if (IS_FC(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "ILLEGAL ASYNC_BUS_RESET for FC card");
- break;
- }
ISP_SET_SENDMARKER(isp, chan, 1);
#ifdef ISP_TARGET_MODE
if (isp_target_async(isp, chan, mbox)) {
- rval = -1;
+ acked = 1;
}
#endif
isp_async(isp, ISPASYNC_BUS_RESET, chan);
@@ -5435,10 +5429,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
case ASYNC_SYSTEM_ERROR:
isp->isp_dead = 1;
isp->isp_state = ISP_CRASHED;
- if (IS_FC(isp)) {
- FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
- FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
- }
/*
* Were we waiting for a mailbox command to complete?
* If so, it's dead, so wake up the waiter.
@@ -5453,7 +5443,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
* restart the firmware
*/
isp_async(isp, ISPASYNC_FW_CRASH);
- rval = -1;
+ acked = 1;
break;
case ASYNC_RQS_XFER_ERR:
@@ -5465,17 +5455,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
break;
case ASYNC_QWAKEUP:
-#ifdef ISP_TARGET_MODE
- if (IS_24XX(isp)) {
- isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
- break;
- }
-#endif
- if (IS_FC(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "ILLEGAL ASYNC_QWAKEUP for FC card");
- break;
- }
/*
* We've just been notified that the Queue has woken up.
* We don't need to be chatty about this- just unlatch things
@@ -5485,82 +5464,45 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
break;
case ASYNC_TIMEOUT_RESET:
- if (IS_FC(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "ILLEGAL ASYNC_TIMEOUT_RESET for FC card");
- break;
- }
- isp_prt(isp, ISP_LOGWARN,
- "timeout initiated SCSI bus reset of chan %d", chan);
+ isp_prt(isp, ISP_LOGWARN, "timeout initiated SCSI bus reset of chan %d", chan);
ISP_SET_SENDMARKER(isp, chan, 1);
#ifdef ISP_TARGET_MODE
if (isp_target_async(isp, chan, mbox)) {
- rval = -1;
+ acked = 1;
}
#endif
break;
case ASYNC_DEVICE_RESET:
- if (IS_FC(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "ILLEGAL DEVICE_RESET for FC card");
- break;
- }
isp_prt(isp, ISP_LOGINFO, "device reset on chan %d", chan);
ISP_SET_SENDMARKER(isp, chan, 1);
#ifdef ISP_TARGET_MODE
if (isp_target_async(isp, chan, mbox)) {
- rval = -1;
+ acked = 1;
}
#endif
break;
case ASYNC_EXTMSG_UNDERRUN:
- if (IS_FC(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "ILLEGAL ASYNC_EXTMSG_UNDERRUN for FC card");
- break;
- }
isp_prt(isp, ISP_LOGWARN, "extended message underrun");
break;
case ASYNC_SCAM_INT:
- if (IS_FC(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "ILLEGAL ASYNC_SCAM_INT for FC card");
- break;
- }
isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
break;
case ASYNC_HUNG_SCSI:
- if (IS_FC(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "ILLEGAL ASYNC_HUNG_SCSI for FC card");
- break;
- }
- isp_prt(isp, ISP_LOGERR,
- "stalled SCSI Bus after DATA Overrun");
+ isp_prt(isp, ISP_LOGERR, "stalled SCSI Bus after DATA Overrun");
/* XXX: Need to issue SCSI reset at this point */
break;
case ASYNC_KILLED_BUS:
- if (IS_FC(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "ILLEGAL ASYNC_KILLED_BUS for FC card");
- break;
- }
isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
break;
case ASYNC_BUS_TRANSIT:
- if (IS_FC(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "ILLEGAL ASYNC_BUS_TRANSIT for FC card");
- break;
- }
mbox = ISP_READ(isp, OUTMAILBOX2);
- switch (mbox & 0x1c00) {
+ switch (mbox & SXP_PINS_MODE_MASK) {
case SXP_PINS_LVD_MODE:
isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
SDPARAM(isp, chan)->isp_diffmode = 0;
@@ -5593,70 +5535,142 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
ISP_SET_SENDMARKER(isp, chan, 1);
break;
- case ASYNC_RIO5:
- pattern = 0xce; /* outgoing mailbox regs 1-3, 6-7 */
+ case ASYNC_CMD_CMPLT:
+ case ASYNC_RIO32_1:
+ if (!IS_ULTRA3(isp)) {
+ isp_prt(isp, ISP_LOGERR, "unexpected fast posting completion");
+ break;
+ }
+ /* FALLTHROUGH */
+ h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1);
+ break;
+
+ case ASYNC_RIO32_2:
+ h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1);
+ h2 = (ISP_READ(isp, OUTMAILBOX7) << 16) | ISP_READ(isp, OUTMAILBOX6);
+ break;
+
+ case ASYNC_RIO16_5:
+ case ASYNC_RIO16_4:
+ case ASYNC_RIO16_3:
+ case ASYNC_RIO16_2:
+ case ASYNC_RIO16_1:
+ isp_prt(isp, ISP_LOGERR, "unexpected 16 bit RIO handle");
+ break;
+ default:
+ isp_prt(isp, ISP_LOGWARN, "%s: unhandled async code 0x%x", __func__, mbox);
+ break;
+ }
+
+ if (h1 || h2) {
+ isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h1);
+ isp_fastpost_complete(isp, h1);
+ if (h2) {
+ isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h2);
+ isp_fastpost_complete(isp, h2);
+ if (isp->isp_fpcchiwater < 2) {
+ isp->isp_fpcchiwater = 2;
+ }
+ } else {
+ if (isp->isp_fpcchiwater < 1) {
+ isp->isp_fpcchiwater = 1;
+ }
+ }
+ } else {
+ isp->isp_intoasync++;
+ }
+ return (acked);
+}
+
+#define GET_24XX_BUS(isp, chan, msg) \
+ if (IS_24XX(isp)) { \
+ chan = ISP_READ(isp, OUTMAILBOX3) & 0xff; \
+ if (chan >= isp->isp_nchan) { \
+ isp_prt(isp, ISP_LOGERR, "bogus channel %u for %s at line %d", chan, msg, __LINE__); \
+ break; \
+ } \
+ }
+
+
+static int
+isp_parse_async_fc(ispsoftc_t *isp, uint16_t mbox)
+{
+ int acked = 0;
+ uint16_t chan;
+
+ if (IS_DUALBUS(isp)) {
+ chan = ISP_READ(isp, OUTMAILBOX6);
+ } else {
+ chan = 0;
+ }
+ isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
+
+ switch (mbox) {
+ case ASYNC_SYSTEM_ERROR:
+ isp->isp_dead = 1;
+ isp->isp_state = ISP_CRASHED;
+ FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
+ FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
+ /*
+ * Were we waiting for a mailbox command to complete?
+ * If so, it's dead, so wake up the waiter.
+ */
+ if (isp->isp_mboxbsy) {
+ isp->isp_obits = 1;
+ isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
+ MBOX_NOTIFY_COMPLETE(isp);
+ }
+ /*
+ * It's up to the handler for isp_async to reinit stuff and
+ * restart the firmware
+ */
+ isp_async(isp, ISPASYNC_FW_CRASH);
+ acked = 1;
break;
- case ASYNC_RIO4:
- pattern = 0x4e; /* outgoing mailbox regs 1-3, 6 */
+ case ASYNC_RQS_XFER_ERR:
+ isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
break;
- case ASYNC_RIO3:
- pattern = 0x0e; /* outgoing mailbox regs 1-3 */
+ case ASYNC_RSP_XFER_ERR:
+ isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
break;
- case ASYNC_RIO2:
- pattern = 0x06; /* outgoing mailbox regs 1-2 */
+ case ASYNC_QWAKEUP:
+#ifdef ISP_TARGET_MODE
+ if (IS_24XX(isp)) {
+ isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
+ break;
+ }
+#endif
+ isp_prt(isp, ISP_LOGERR, "%s: unexpected ASYNC_QWAKEUP code", __func__);
break;
- case ASYNC_RIO1:
case ASYNC_CMD_CMPLT:
- pattern = 0x02; /* outgoing mailbox regs 1 */
+ isp_fastpost_complete(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1));
+ if (isp->isp_fpcchiwater < 1) {
+ isp->isp_fpcchiwater = 1;
+ }
break;
- case ASYNC_RIO_RESP:
- return (rval);
+ case ASYNC_RIOZIO_STALL:
+ break;
case ASYNC_CTIO_DONE:
- {
#ifdef ISP_TARGET_MODE
- int handle;
- if (IS_SCSI(isp) || IS_24XX(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "bad ASYNC_CTIO_DONE for %s cards",
- IS_SCSI(isp)? "SCSI" : "24XX");
- break;
- }
- handle =
- (ISP_READ(isp, OUTMAILBOX2) << 16) |
- (ISP_READ(isp, OUTMAILBOX1));
- if (isp_target_async(isp, handle, mbox)) {
- rval = -1;
+ if (isp_target_async(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1), mbox)) {
+ acked = 1;
} else {
- /* count it as a fast posting intr */
isp->isp_fphccmplt++;
}
#else
- if (IS_SCSI(isp) || IS_24XX(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "bad ASYNC_CTIO_DONE for %s cards",
- IS_SCSI(isp)? "SCSI" : "24XX");
- break;
- }
- isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
- isp->isp_fphccmplt++; /* count it as a fast posting intr */
+ isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC CTIO done");
#endif
break;
- }
case ASYNC_LIP_ERROR:
case ASYNC_LIP_F8:
case ASYNC_LIP_OCCURRED:
case ASYNC_PTPMODE:
- if (IS_SCSI(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "bad LIP event for SCSI cards");
- break;
- }
/*
* These are broadcast events that have to be sent across
* all active channels.
@@ -5676,7 +5690,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
isp_async(isp, ISPASYNC_LIP, chan);
#ifdef ISP_TARGET_MODE
if (isp_target_async(isp, chan, mbox)) {
- rval = -1;
+ acked = 1;
}
#endif
/*
@@ -5711,11 +5725,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
break;
case ASYNC_LOOP_UP:
- if (IS_SCSI(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "bad LOOP UP event for SCSI cards");
- break;
- }
/*
* This is a broadcast event that has to be sent across
* all active channels.
@@ -5735,18 +5744,13 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
isp_async(isp, ISPASYNC_LOOP_UP, chan);
#ifdef ISP_TARGET_MODE
if (isp_target_async(isp, chan, mbox)) {
- rval = -1;
+ acked = 1;
}
#endif
}
break;
case ASYNC_LOOP_DOWN:
- if (IS_SCSI(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "bad LOOP DOWN event for SCSI cards");
- break;
- }
/*
* This is a broadcast event that has to be sent across
* all active channels.
@@ -5765,18 +5769,13 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
#ifdef ISP_TARGET_MODE
if (isp_target_async(isp, chan, mbox)) {
- rval = -1;
+ acked = 1;
}
#endif
}
break;
case ASYNC_LOOP_RESET:
- if (IS_SCSI(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "bad LIP RESET event for SCSI cards");
- break;
- }
/*
* This is a broadcast event that has to be sent across
* all active channels.
@@ -5795,7 +5794,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
isp_async(isp, ISPASYNC_LOOP_RESET, chan);
#ifdef ISP_TARGET_MODE
if (isp_target_async(isp, chan, mbox)) {
- rval = -1;
+ acked = 1;
}
#endif
}
@@ -5804,11 +5803,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
case ASYNC_PDB_CHANGED:
{
int nphdl, nlstate, reason;
- if (IS_SCSI(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "bad PDB CHANGED event for SCSI cards");
- break;
- }
/*
* We *should* get a channel out of the 24XX, but we don't seem
* to get more than a PDB CHANGED on channel 0, so turn it into
@@ -5831,8 +5825,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
ISP_SET_SENDMARKER(isp, chan, 1);
fcp->isp_loopstate = LOOP_PDB_RCVD;
ISP_MARK_PORTDB(isp, chan, 1);
- isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
- ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
+ isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
}
break;
}
@@ -5840,11 +5833,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
{
int lochan, hichan;
- if (IS_SCSI(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "bad CHANGE NOTIFY event for SCSI cards");
- break;
- }
if (ISP_FW_NEWER_THAN(isp, 4, 0, 25) && ISP_CAP_MULTI_ID(isp)) {
GET_24XX_BUS(isp, chan, "ASYNC_CHANGE_NOTIFY");
lochan = chan;
@@ -5866,8 +5854,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
fcp->isp_loopstate = LOOP_PDB_RCVD;
}
ISP_MARK_PORTDB(isp, chan, 1);
- isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
- ISPASYNC_CHANGE_SNS);
+ isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_SNS);
}
break;
}
@@ -5877,8 +5864,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
* This only applies to 2100 amd 2200 cards
*/
if (!IS_2200(isp) && !IS_2100(isp)) {
- isp_prt(isp, ISP_LOGWARN,
- "bad card for ASYNC_CONNMODE event");
+ isp_prt(isp, ISP_LOGWARN, "bad card for ASYNC_CONNMODE event");
break;
}
chan = 0;
@@ -5912,8 +5898,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
"Unknown connection mode (0x%x)", mbox);
break;
}
- isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
- ISPASYNC_CHANGE_OTHER);
+ isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_OTHER);
FCPARAM(isp, chan)->sendmarker = 1;
FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
FCPARAM(isp, chan)->isp_loopstate = LOOP_LIP_RCVD;
@@ -5923,8 +5908,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
if (IS_24XX(isp)) {
isp_prt(isp, ISP_LOGWARN, "Receive Error");
} else {
- isp_prt(isp, ISP_LOGWARN,
- "Unknown Async Code 0x%x", mbox);
+ isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC_RCV_ERR");
}
break;
case ASYNC_RJT_SENT: /* same as ASYNC_QFULL_SENT */
@@ -5940,29 +5924,10 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
break;
}
-
- if (pattern) {
- int i, nh;
- uint16_t handles[16];
-
- for (nh = 0, i = 1; i < MAX_MAILBOX(isp); i++) {
- if ((pattern & (1 << i)) == 0) {
- continue;
- }
- handles[nh++] = ISP_READ(isp, MBOX_OFF(i));
- }
- for (i = 0; i < nh; i++) {
- isp_fastpost_complete(isp, handles[i]);
- isp_prt(isp, ISP_LOGDEBUG3,
- "fast post completion of %u", handles[i]);
- }
- if (isp->isp_fpcchiwater < nh) {
- isp->isp_fpcchiwater = nh;
- }
- } else {
+ if (mbox != ASYNC_CTIO_DONE && mbox != ASYNC_CMD_CMPLT) {
isp->isp_intoasync++;
}
- return (rval);
+ return (acked);
}
/*
@@ -6594,7 +6559,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
}
static void
-isp_fastpost_complete(ispsoftc_t *isp, uint16_t fph)
+isp_fastpost_complete(ispsoftc_t *isp, uint32_t fph)
{
XS_T *xs;
@@ -7682,7 +7647,6 @@ isp_setdfltfcparm(ispsoftc_t *isp, int chan)
fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
- fcp->isp_fwoptions |= ICBOPT_FAST_POST;
if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
}
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 515e637..902c827 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -2304,7 +2304,8 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
uint32_t tval, handle;
/*
- * CTIO, CTIO2 and CTIO7 are close enough....
+ * CTIO handles are 16 bits.
+ * CTIO2 and CTIO7 are 32 bits.
*/
if (IS_SCSI(isp)) {
diff --git a/sys/dev/isp/isp_library.c b/sys/dev/isp/isp_library.c
index 57b8400..43c161d 100644
--- a/sys/dev/isp/isp_library.c
+++ b/sys/dev/isp/isp_library.c
@@ -668,7 +668,7 @@ isp_clear_commands(ispsoftc_t *isp)
ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
} else {
ct_entry_t *ctio = (ct_entry_t *) local;
- ctio->ct_syshandle = hdp->handle & 0xffff;
+ ctio->ct_syshandle = hdp->handle;
ctio->ct_status = CT_HBA_RESET & 0xff;
ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO;
}
@@ -1132,17 +1132,36 @@ isp_get_24xx_abrt(ispsoftc_t *isp, isp24xx_abrt_t *src, isp24xx_abrt_t *dst)
void
+isp_get_rio1(ispsoftc_t *isp, isp_rio1_t *r1src, isp_rio1_t *r1dst)
+{
+ const int lim = sizeof (r1dst->req_handles) / sizeof (r1dst->req_handles[0]);
+ int i;
+ isp_get_hdr(isp, &r1src->req_header, &r1dst->req_header);
+ if (r1dst->req_header.rqs_seqno > lim) {
+ r1dst->req_header.rqs_seqno = lim;
+ }
+ for (i = 0; i < r1dst->req_header.rqs_seqno; i++) {
+ ISP_IOXGET_32(isp, &r1src->req_handles[i], r1dst->req_handles[i]);
+ }
+ while (i < lim) {
+ r1dst->req_handles[i++] = 0;
+ }
+}
+
+void
isp_get_rio2(ispsoftc_t *isp, isp_rio2_t *r2src, isp_rio2_t *r2dst)
{
+ const int lim = sizeof (r2dst->req_handles) / sizeof (r2dst->req_handles[0]);
int i;
+
isp_get_hdr(isp, &r2src->req_header, &r2dst->req_header);
- if (r2dst->req_header.rqs_seqno > 30) {
- r2dst->req_header.rqs_seqno = 30;
+ if (r2dst->req_header.rqs_seqno > lim) {
+ r2dst->req_header.rqs_seqno = lim;
}
for (i = 0; i < r2dst->req_header.rqs_seqno; i++) {
ISP_IOXGET_16(isp, &r2src->req_handles[i], r2dst->req_handles[i]);
}
- while (i < 30) {
+ while (i < lim) {
r2dst->req_handles[i++] = 0;
}
}
@@ -2240,7 +2259,13 @@ isp_allocate_xs_tgt(ispsoftc_t *isp, void *xs, uint32_t *handlep)
hdp->cmd = xs;
hdp->handle = (hdp - isp->isp_tgtlist);
hdp->handle |= (ISP_HANDLE_TARGET << ISP_HANDLE_USAGE_SHIFT);
- hdp->handle |= (isp->isp_seqno++ << ISP_HANDLE_SEQ_SHIFT);
+ /*
+ * Target handles for SCSI cards are only 16 bits, so
+ * sequence number protection will be ommitted.
+ */
+ if (IS_FC(isp)) {
+ hdp->handle |= (isp->isp_seqno++ << ISP_HANDLE_SEQ_SHIFT);
+ }
*handlep = hdp->handle;
return (0);
}
diff --git a/sys/dev/isp/isp_library.h b/sys/dev/isp/isp_library.h
index b055dd8..4e0c7f8 100644
--- a/sys/dev/isp/isp_library.h
+++ b/sys/dev/isp/isp_library.h
@@ -108,6 +108,7 @@ void isp_put_cont64_req(ispsoftc_t *, ispcontreq64_t *, ispcontreq64_t *);
void isp_get_response(ispsoftc_t *, ispstatusreq_t *, ispstatusreq_t *);
void isp_get_24xx_response(ispsoftc_t *, isp24xx_statusreq_t *, isp24xx_statusreq_t *);
void isp_get_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *);
+void isp_get_rio1(ispsoftc_t *, isp_rio1_t *, isp_rio1_t *);
void isp_get_rio2(ispsoftc_t *, isp_rio2_t *, isp_rio2_t *);
void isp_put_icb(ispsoftc_t *, isp_icb_t *, isp_icb_t *);
void isp_put_icb_2400(ispsoftc_t *, isp_icb_2400_t *, isp_icb_2400_t *);
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index 257dd2c..547f48e 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -1068,8 +1068,7 @@ isp_pci_rd_isr(ispsoftc_t *isp, uint32_t *isrp, uint16_t *semap, uint16_t *mbp)
}
static int
-isp_pci_rd_isr_2300(ispsoftc_t *isp, uint32_t *isrp,
- uint16_t *semap, uint16_t *mbox0p)
+isp_pci_rd_isr_2300(ispsoftc_t *isp, uint32_t *isrp, uint16_t *semap, uint16_t *mbox0p)
{
uint32_t hccr;
uint32_t r2hisr;
@@ -1096,7 +1095,7 @@ isp_pci_rd_isr_2300(ispsoftc_t *isp, uint32_t *isrp,
return (1);
case ISPR2HST_RIO_16:
*isrp = r2hisr & 0xffff;
- *mbox0p = ASYNC_RIO1;
+ *mbox0p = ASYNC_RIO16_1;
*semap = 1;
return (1);
case ISPR2HST_FPOST:
@@ -1118,21 +1117,17 @@ isp_pci_rd_isr_2300(ispsoftc_t *isp, uint32_t *isrp,
hccr = ISP_READ(isp, HCCR);
if (hccr & HCCR_PAUSE) {
ISP_WRITE(isp, HCCR, HCCR_RESET);
- isp_prt(isp, ISP_LOGERR,
- "RISC paused at interrupt (%x->%x)", hccr,
- ISP_READ(isp, HCCR));
+ isp_prt(isp, ISP_LOGERR, "RISC paused at interrupt (%x->%x)", hccr, ISP_READ(isp, HCCR));
ISP_WRITE(isp, BIU_ICR, 0);
} else {
- isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n",
- r2hisr);
+ isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n", r2hisr);
}
return (0);
}
}
static int
-isp_pci_rd_isr_2400(ispsoftc_t *isp, uint32_t *isrp,
- uint16_t *semap, uint16_t *mbox0p)
+isp_pci_rd_isr_2400(ispsoftc_t *isp, uint32_t *isrp, uint16_t *semap, uint16_t *mbox0p)
{
uint32_t r2hisr;
@@ -1177,8 +1172,7 @@ isp_pci_rd_reg(ispsoftc_t *isp, int regoff)
* We will assume that someone has paused the RISC processor.
*/
oldconf = BXR2(isp, IspVirt2Off(isp, BIU_CONF1));
- BXW2(isp, IspVirt2Off(isp, BIU_CONF1),
- oldconf | BIU_PCI_CONF1_SXP);
+ BXW2(isp, IspVirt2Off(isp, BIU_CONF1), oldconf | BIU_PCI_CONF1_SXP);
MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, BIU_CONF1), 2);
}
rv = BXR2(isp, IspVirt2Off(isp, regoff));
diff --git a/sys/dev/isp/isp_target.c b/sys/dev/isp/isp_target.c
index 68c42b4..8707961 100644
--- a/sys/dev/isp/isp_target.c
+++ b/sys/dev/isp/isp_target.c
@@ -826,7 +826,9 @@ isp_target_async(ispsoftc_t *isp, int bus, int event)
ct_entry_t *ct = (ct_entry_t *) storage;
ct->ct_header.rqs_entry_type = RQSTYPE_CTIO;
ct->ct_status = CT_OK;
- ct->ct_fwhandle = bus;
+ ct->ct_syshandle = bus;
+ /* we skip fwhandle here */
+ ct->ct_fwhandle = 0;
ct->ct_flags = CT_SENDSTATUS;
}
isp_async(isp, ISPASYNC_TARGET_ACTION, storage);
diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h
index eb3ab63..36a7391 100644
--- a/sys/dev/isp/ispmbox.h
+++ b/sys/dev/isp/ispmbox.h
@@ -223,6 +223,8 @@
#define ASYNC_SECURITY_UPDATE 0x801B
#define ASYNC_CMD_CMPLT 0x8020
#define ASYNC_CTIO_DONE 0x8021
+#define ASYNC_RIO32_1 0x8021
+#define ASYNC_RIO32_2 0x8022
#define ASYNC_IP_XMIT_DONE 0x8022
#define ASYNC_IP_RECV_DONE 0x8023
#define ASYNC_IP_BROADCAST 0x8024
@@ -230,19 +232,19 @@
#define ASYNC_IP_RCVQ_EMPTY 0x8026
#define ASYNC_IP_RECV_DONE_ALIGNED 0x8027
#define ASYNC_PTPMODE 0x8030
-#define ASYNC_RIO1 0x8031
-#define ASYNC_RIO2 0x8032
-#define ASYNC_RIO3 0x8033
-#define ASYNC_RIO4 0x8034
-#define ASYNC_RIO5 0x8035
+#define ASYNC_RIO16_1 0x8031
+#define ASYNC_RIO16_2 0x8032
+#define ASYNC_RIO16_3 0x8033
+#define ASYNC_RIO16_4 0x8034
+#define ASYNC_RIO16_5 0x8035
#define ASYNC_CONNMODE 0x8036
#define ISP_CONN_LOOP 1
#define ISP_CONN_PTP 2
#define ISP_CONN_BADLIP 3
#define ISP_CONN_FATAL 4
#define ISP_CONN_LOOPBACK 5
-#define ASYNC_RIO_RESP 0x8040
-#define ASYNC_RIO_COMP 0x8042
+#define ASYNC_RIOZIO_STALL 0x8040 /* there's a RIO/ZIO entry that hasn't been serviced */
+#define ASYNC_RIO32_2_2200 0x8042 /* same as ASYNC_RIO32_2, but for 2100/2200 */
#define ASYNC_RCV_ERR 0x8048
/*
@@ -860,7 +862,7 @@ typedef struct {
(ISP_CAP_MULTI_ID(isp) ? tag : 0)
/*
- * Reduced Interrupt Operation Response Queue Entreis
+ * Reduced Interrupt Operation Response Queue Entries
*/
typedef struct {
diff --git a/sys/dev/isp/ispreg.h b/sys/dev/isp/ispreg.h
index 08df337..2d616ae 100644
--- a/sys/dev/isp/ispreg.h
+++ b/sys/dev/isp/ispreg.h
@@ -677,13 +677,13 @@ typedef struct {
#define SXP_PINS_LVD_MODE 0x1000
#define SXP_PINS_HVD_MODE 0x0800
#define SXP_PINS_SE_MODE 0x0400
+#define SXP_PINS_MODE_MASK (SXP_PINS_LVD_MODE|SXP_PINS_HVD_MODE|SXP_PINS_SE_MODE)
/* The above have to be put together with the DIFFM pin to make sense */
#define ISP1080_LVD_MODE (SXP_PINS_LVD_MODE)
#define ISP1080_HVD_MODE (SXP_PINS_HVD_MODE|SXP_PINS_DIFF_MODE)
#define ISP1080_SE_MODE (SXP_PINS_SE_MODE)
-#define ISP1080_MODE_MASK \
- (SXP_PINS_LVD_MODE|SXP_PINS_HVD_MODE|SXP_PINS_SE_MODE|SXP_PINS_DIFF_MODE)
+#define ISP1080_MODE_MASK (SXP_PINS_MODE_MASK|SXP_PINS_DIFF_MODE)
/*
* RISC and Host Command and Control Block Register Offsets
OpenPOWER on IntegriCloud