MFC of 204397: fix problems with fast posting handles
This commit is contained in:
parent
11a4464b0f
commit
ac5ac1cdf2
@ -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;
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user