MFC of 204397: fix problems with fast posting handles

This commit is contained in:
mjacob 2010-03-01 17:36:45 +00:00
parent 11a4464b0f
commit ac5ac1cdf2
8 changed files with 245 additions and 256 deletions

View File

@ -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
@ -4860,7 +4852,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;
@ -4880,10 +4872,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;
}
}
@ -5065,9 +5060,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);
}
@ -5079,6 +5074,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
@ -5391,40 +5390,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);
@ -5432,10 +5426,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.
@ -5450,7 +5440,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:
@ -5462,17 +5452,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
@ -5482,82 +5461,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;
@ -5590,70 +5532,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 */
break;
case ASYNC_RIO4:
pattern = 0x4e; /* outgoing mailbox regs 1-3, 6 */
break;
case ASYNC_RIO3:
pattern = 0x0e; /* outgoing mailbox regs 1-3 */
break;
case ASYNC_RIO2:
pattern = 0x06; /* outgoing mailbox regs 1-2 */
break;
case ASYNC_RIO1:
case ASYNC_CMD_CMPLT:
pattern = 0x02; /* outgoing mailbox regs 1 */
break;
case ASYNC_RIO_RESP:
return (rval);
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");
case ASYNC_RIO32_1:
if (!IS_ULTRA3(isp)) {
isp_prt(isp, ISP_LOGERR, "unexpected fast posting completion");
break;
}
handle =
(ISP_READ(isp, OUTMAILBOX2) << 16) |
(ISP_READ(isp, OUTMAILBOX1));
if (isp_target_async(isp, handle, mbox)) {
rval = -1;
/* 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_RQS_XFER_ERR:
isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
break;
case ASYNC_RSP_XFER_ERR:
isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
break;
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_CMD_CMPLT:
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_RIOZIO_STALL:
break;
case ASYNC_CTIO_DONE:
#ifdef ISP_TARGET_MODE
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.
@ -5673,7 +5687,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
/*
@ -5708,11 +5722,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.
@ -5732,18 +5741,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.
@ -5762,18 +5766,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.
@ -5792,7 +5791,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
}
@ -5801,11 +5800,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
@ -5828,8 +5822,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;
}
@ -5837,11 +5830,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;
@ -5863,8 +5851,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;
}
@ -5874,8 +5861,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;
@ -5909,8 +5895,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;
@ -5920,8 +5905,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 */
@ -5937,29 +5921,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);
}
/*
@ -6591,7 +6556,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;
@ -7679,7 +7644,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;
}

View File

@ -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)) {

View File

@ -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;
}
@ -1131,18 +1131,37 @@ 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);
}

View File

@ -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 *);

View File

@ -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));

View File

@ -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);

View File

@ -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 {

View File

@ -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