summaryrefslogtreecommitdiff
path: root/sys/dev/isp
diff options
context:
space:
mode:
authorMatt Jacob <mjacob@FreeBSD.org>1999-08-16 20:00:26 +0000
committerMatt Jacob <mjacob@FreeBSD.org>1999-08-16 20:00:26 +0000
commit603d05ee27640ac33fd6e48d6a5dbcd8a581f14b (patch)
treeea6bb62b2c1f448e37dc9876edacb406c64d5384 /sys/dev/isp
parent3b975e00a0780f6c93d4c9b444cf23c0fea653b1 (diff)
Notes
Diffstat (limited to 'sys/dev/isp')
-rw-r--r--sys/dev/isp/isp.c248
1 files changed, 157 insertions, 91 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 2fef146351a8..beda7b92f4ae 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -1,5 +1,4 @@
-/* $Id: isp.c,v 1.11.2.2 1999/07/03 01:47:13 mjacob Exp $ */
-/* release_6_5_99 */
+/* $Id: isp.c,v 1.11.2.3 1999/07/05 20:43:11 mjacob Exp $ */
/*
* Machine and OS Independent (well, as best as possible)
* code for the Qlogic ISP SCSI adapters.
@@ -205,8 +204,8 @@ isp_reset(isp)
case ISP_HA_FC_2200:
revname[1] = '2';
/*
- * Resident firmware for the 2200 appears to have
- * SCCLUN enabled.
+ * Resident firmware for the 2200 appears
+ * to have SCCLUN enabled.
*/
#ifndef ISP2100_SCCLUN
if (isp->isp_mdvec->dv_fwlen == 0) {
@@ -395,7 +394,7 @@ again:
*/
loops = MBOX_DELAY_COUNT;
for (;;) {
- if (isp->isp_type & ISP_HA_SCSI) {
+ if (IS_SCSI(isp)) {
if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET))
break;
} else {
@@ -585,7 +584,7 @@ again:
mbs.param[1] = 0x1000;
isp_mboxcmd(isp, &mbs);
- if (isp->isp_type & ISP_HA_SCSI) {
+ if (IS_SCSI(isp)) {
/*
* Set CLOCK RATE, but only if asked to.
*/
@@ -859,8 +858,8 @@ isp_scsi_channel_init(isp, channel)
u_int16_t sdf;
if (sdp->isp_devparam[tgt].dev_enable == 0) {
- PRINTF("%s: skipping settings for target %d bus %d\n",
- isp->isp_name, tgt, channel);
+ IDPRINTF(1, ("%s: skipping target %d bus %d settings\n",
+ isp->isp_name, tgt, channel));
continue;
}
@@ -996,31 +995,24 @@ isp_fibre_init(isp)
icbp->icb_version = ICB_VERSION1;
#ifdef ISP_TARGET_MODE
- fcp->isp_fwoptions = ICBOPT_TGT_ENABLE|ICBOPT_INI_TGTTYPE;
+ fcp->isp_fwoptions = ICBOPT_TGT_ENABLE;
#else
fcp->isp_fwoptions = 0;
#endif
fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
-#ifdef ISP2100_FABRIC
-#if 0
- /*
- * Do not use FULL LOGIN- it resets the loop too much.
- */
- fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
-#endif
-#endif
-#if 0
/*
- * Don't use this either
+ * We have to use FULL LOGIN even though it resets the loop too much
+ * because otherwise port database entries don't get updated after
+ * a LIP- this is a known f/w bug.
*/
- fcp->isp_fwoptions |= ICBOPT_INI_ADISC;
-#endif
+ if (ISP_FW_REVX(isp->isp_fwrev) < ISP_FW_REV(1, 17, 0)) {
+ fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
+ }
#ifndef ISP_NO_FASTPOST_FC
fcp->isp_fwoptions |= ICBOPT_FAST_POST;
#endif
-
if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
@@ -1052,6 +1044,7 @@ isp_fibre_init(isp)
icbp->icb_retry_delay = fcp->isp_retry_delay;
icbp->icb_retry_count = fcp->isp_retry_count;
icbp->icb_hardaddr = loopid;
+ icbp->icb_logintime = 30; /* 30 second login timeout */
if (fcp->isp_nodewwn) {
u_int64_t pn;
@@ -1077,7 +1070,6 @@ isp_fibre_init(isp)
} else {
fcp->isp_fwoptions &= ~(ICBOPT_USE_PORTNAME|ICBOPT_FULL_LOGIN);
}
-
icbp->icb_rqstqlen = RQUEST_QUEUE_LEN;
icbp->icb_rsltqlen = RESULT_QUEUE_LEN;
icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_LSW(isp->isp_rquest_dma);
@@ -1086,6 +1078,14 @@ isp_fibre_init(isp)
icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_MSW(isp->isp_result_dma);
MemoryBarrier();
+
+ /*
+ * Do this *before* initializing the firmware.
+ */
+ isp_mark_getpdb_all(isp);
+ fcp->isp_fwstate = FW_CONFIG_WAIT;
+ fcp->isp_loopstate = LOOP_NIL;
+
for (;;) {
mbs.param[0] = MBOX_INIT_FIRMWARE;
mbs.param[1] = 0;
@@ -1099,7 +1099,7 @@ isp_fibre_init(isp)
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
PRINTF("%s: INIT FIRMWARE failed (code 0x%x)\n",
isp->isp_name, mbs.param[0]);
- if (mbs.param[0] & 0xc000) {
+ if (mbs.param[0] & 0x8000) {
SYS_DELAY(1000);
continue;
}
@@ -1116,9 +1116,6 @@ isp_fibre_init(isp)
* Whatever happens, we're now committed to being here.
*/
isp->isp_state = ISP_INITSTATE;
- fcp->isp_fwstate = FW_CONFIG_WAIT;
-
- isp_mark_getpdb_all(isp);
#ifdef ISP_TARGET_MODE
if (isp_modify_lun(isp, 0, 1, 1)) {
@@ -1277,6 +1274,7 @@ isp_fclink_test(isp, waitdelay)
*/
fcp->isp_alpa = mbs.param[2];
#if defined(ISP2100_FABRIC)
+ fcp->isp_onfabric = 0;
if (isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
fcp->isp_portid = mbs.param[2] | (((int)mbs.param[3]) << 16);
fcp->isp_onfabric = 1;
@@ -1344,8 +1342,6 @@ isp_pdb_sync(isp, target)
isp_pdb_t pdb;
int loopid, lim;
-target = target;
-
#ifdef ISP2100_FABRIC
/*
* XXX: If we do this *after* building up our local port database,
@@ -1357,6 +1353,8 @@ target = target;
if (fcp->isp_onfabric)
(void) isp_scan_fabric(isp);
#endif
+
+
/*
* Run through the local loop ports and get port database info
* for each loop ID.
@@ -1365,13 +1363,12 @@ target = target;
* the wrong database entity- if that happens, just restart (up to
* FL_PORT_ID times).
*/
+ MEMZERO((void *) tport, sizeof (tport));
for (lim = loopid = 0; loopid < FL_PORT_ID; loopid++) {
/*
* make sure the temp port database is clean...
*/
lp = &tport[loopid];
- MEMZERO((void *) lp, sizeof (*lp));
-
lp->node_wwn = isp_get_portname(isp, loopid, 1);
if (lp->node_wwn == 0)
continue;
@@ -1380,12 +1377,14 @@ target = target;
lp->node_wwn = 0;
continue;
}
+
/*
* Get an entry....
*/
if (isp_getpdb(isp, loopid, &pdb) != 0) {
continue;
}
+
/*
* If the returned database element doesn't match what we
* asked for, restart the process entirely (up to a point...).
@@ -1401,6 +1400,7 @@ target = target;
"database\n", isp->isp_name);
return (-1);
}
+
/*
* Save the pertinent info locally.
*/
@@ -1447,6 +1447,13 @@ target = target;
fcp->isp_loopstate = LOOP_READY;
/*
+ * Mark all of the permanent local loop database entries as invalid.
+ */
+ for (loopid = 0; loopid < FL_PORT_ID; loopid++) {
+ fcp->portdb[loopid].valid = 0;
+ }
+
+ /*
* Now merge our local copy of the port database into our saved copy.
* Notify the outer layers of new devices arriving.
*/
@@ -1454,12 +1461,6 @@ target = target;
int i;
/*
- * While we're at it, clear the valid bit for the saved entry
- * that coincidentally is at this same index.
- */
- fcp->portdb[loopid].valid = 0;
-
- /*
* If we don't have a non-zero Port WWN, we're not here.
*/
if (tport[loopid].port_wwn == 0) {
@@ -1469,12 +1470,10 @@ target = target;
/*
* If we've already marked our tmp copy as valid,
* this means that we've decided that it's the
- * same as our saved data base. This does not include
- * the 'valid' marking though so we have to turn it
- * back on.
+ * same as our saved data base. This didn't include
+ * the 'valid' marking so we have set that here.
*/
if (tport[loopid].valid) {
-IDPRINTF(0, ("%s: loopid %d already valid\n", isp->isp_name, loopid));
fcp->portdb[loopid].valid = 1;
continue;
}
@@ -1502,12 +1501,19 @@ IDPRINTF(0, ("%s: loopid %d already valid\n", isp->isp_name, loopid));
* just change the actual loop ID we'd use.
*/
if (fcp->portdb[i].loopid != loopid) {
- PRINTF("%s: Target ID %d (0x%x) was loopid 0x%x"
- " and is now loopid 0x%x\n", isp->isp_name,
- i, i, fcp->portdb[i].loopid, loopid);
+ PRINTF("%s: Target ID %d Loop 0x%x (Port 0x%x) "
+ "=> Loop 0x%x (Port 0x%x) \n",
+ isp->isp_name, i, fcp->portdb[i].loopid,
+ fcp->portdb[i].portid, loopid,
+ tport[loopid].portid);
}
+ fcp->portdb[i].portid = tport[loopid].portid;
fcp->portdb[i].loopid = loopid;
fcp->portdb[i].valid = 1;
+ /*
+ * XXX: Should we also propagate roles in case they
+ * XXX: changed?
+ */
/*
* Now make sure this Port WWN doesn't exist elsewhere
@@ -1616,7 +1622,7 @@ IDPRINTF(0, ("%s: loopid %d already valid\n", isp->isp_name, loopid));
/*
* Force a logout.
*/
- lp->loopid = lp - fcp->portdb;
+ lp->loopid = loopid = lp - fcp->portdb;
mbs.param[0] = MBOX_FABRIC_LOGOUT;
mbs.param[1] = lp->loopid << 8;
mbs.param[2] = 0;
@@ -1632,10 +1638,46 @@ IDPRINTF(0, ("%s: loopid %d already valid\n", isp->isp_name, loopid));
mbs.param[3] = lp->portid & 0xffff;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
- continue;
lp->valid = 1;
lp->fabdev = 1;
- lp->roles = (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT);
+ if (isp_getpdb(isp, loopid, &pdb) != 0) {
+ /*
+ * Be kind...
+ */
+ lp->roles = (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT);
+ PRINTF("%s: Faked PortID 0x%x into LoopID %d\n",
+ isp->isp_name, lp->portid, lp->loopid);
+ } else if (pdb.pdb_loopid != lp->loopid) {
+ lp->roles = (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT);
+ PRINTF("%s: Wanked PortID 0x%x to LoopID %d\n",
+ isp->isp_name, lp->portid, lp->loopid);
+ } else {
+ lp->roles =
+ (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >>
+ SVC3_ROLE_SHIFT;
+ lp->portid = BITS2WORD(pdb.pdb_portid_bits);
+ lp->loopid = pdb.pdb_loopid;
+ lp->node_wwn =
+ (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
+ (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
+ (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
+ (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
+ (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
+ (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
+ (((u_int64_t)pdb.pdb_nodename[6]) << 8) |
+ (((u_int64_t)pdb.pdb_nodename[7]));
+ lp->port_wwn =
+ (((u_int64_t)pdb.pdb_portname[0]) << 56) |
+ (((u_int64_t)pdb.pdb_portname[1]) << 48) |
+ (((u_int64_t)pdb.pdb_portname[2]) << 40) |
+ (((u_int64_t)pdb.pdb_portname[3]) << 32) |
+ (((u_int64_t)pdb.pdb_portname[4]) << 24) |
+ (((u_int64_t)pdb.pdb_portname[5]) << 16) |
+ (((u_int64_t)pdb.pdb_portname[6]) << 8) |
+ (((u_int64_t)pdb.pdb_portname[7]));
+ (void) isp_async(isp, ISPASYNC_PDB_CHANGED,
+ &loopid);
+ }
}
}
#endif
@@ -1747,7 +1789,6 @@ ispscsicmd(xs)
if (IS_FC(isp)) {
fcparam *fcp = isp->isp_param;
struct lportdb *lp;
-
#if defined(ISP2100_FABRIC)
if (target >= FL_PORT_ID) {
/*
@@ -1761,7 +1802,6 @@ ispscsicmd(xs)
}
}
#endif
-
/*
* Check for f/w being in ready state. If the f/w
* isn't in ready state, then we don't know our
@@ -1778,7 +1818,7 @@ ispscsicmd(xs)
if (isp_fclink_test(isp, FC_FW_READY_DELAY)) {
XS_SETERR(xs, HBA_SELTIMEOUT);
if (fcp->loop_seen_once) {
- return (CMD_EAGAIN);
+ return (CMD_RQLATER);
} else {
return (CMD_COMPLETE);
}
@@ -1793,7 +1833,7 @@ ispscsicmd(xs)
*/
if (fcp->isp_loopstate < LOOP_PDB_RCVD) {
XS_SETERR(xs, HBA_SELTIMEOUT);
- return (CMD_EAGAIN);
+ return (CMD_RQLATER);
}
/*
@@ -1812,16 +1852,16 @@ ispscsicmd(xs)
* Now check whether we should even think about pursuing this.
*/
lp = &fcp->portdb[target];
-if ( target < 0x80) {
if (lp->valid == 0) {
XS_SETERR(xs, HBA_SELTIMEOUT);
return (CMD_COMPLETE);
}
if ((lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) == 0) {
+ IDPRINTF(3, ("%s: target %d is not a target\n",
+ isp->isp_name, target));
XS_SETERR(xs, HBA_SELTIMEOUT);
return (CMD_COMPLETE);
}
-}
/*
* Now turn target into what the actual loop ID is.
*/
@@ -1842,7 +1882,7 @@ if ( target < 0x80) {
reqp = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, iptr);
iptr = ISP_NXT_QENTRY(iptr, RQUEST_QUEUE_LEN);
if (iptr == optr) {
- IDPRINTF(2, ("%s: Request Queue Overflow\n", isp->isp_name));
+ IDPRINTF(0, ("%s: Request Queue Overflow\n", isp->isp_name));
XS_SETERR(xs, HBA_BOTCH);
return (CMD_EAGAIN);
}
@@ -1877,7 +1917,7 @@ if ( target < 0x80) {
niptr = ISP_NXT_QENTRY(iptr, RQUEST_QUEUE_LEN);
if (niptr == optr) {
- IDPRINTF(2, ("%s: Request Queue Overflow+\n",
+ IDPRINTF(0, ("%s: Request Queue Overflow+\n",
isp->isp_name));
XS_SETERR(xs, HBA_BOTCH);
return (CMD_EAGAIN);
@@ -1890,7 +1930,7 @@ if ( target < 0x80) {
MEMZERO((void *) reqp, UZSIZE);
reqp->req_header.rqs_entry_count = 1;
- if (isp->isp_type & ISP_HA_FC) {
+ if (IS_FC(isp)) {
reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
} else {
reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
@@ -1904,7 +1944,7 @@ if ( target < 0x80) {
break;
}
if (rqidx == RQUEST_QUEUE_LEN) {
- IDPRINTF(2, ("%s: out of xflist pointers\n", isp->isp_name));
+ IDPRINTF(0, ("%s: out of xflist pointers\n", isp->isp_name));
XS_SETERR(xs, HBA_BOTCH);
return (CMD_EAGAIN);
} else {
@@ -1916,7 +1956,7 @@ if ( target < 0x80) {
reqp->req_handle = rqidx+1;
}
- if (isp->isp_type & ISP_HA_FC) {
+ if (IS_FC(isp)) {
/*
* See comment in isp_intr
*/
@@ -1944,7 +1984,7 @@ if ( target < 0x80) {
}
}
reqp->req_target = target | (XS_CHANNEL(xs) << 7);
- if (isp->isp_type & ISP_HA_SCSI) {
+ if (IS_SCSI(isp)) {
reqp->req_lun_trn = XS_LUN(xs);
reqp->req_cdblen = XS_CDBLEN(xs);
} else {
@@ -2022,19 +2062,18 @@ isp_control(isp, ctl, arg)
* Issue a bus reset.
*/
mbs.param[0] = MBOX_BUS_RESET;
- if (isp->isp_type & ISP_HA_SCSI) {
+ if (IS_SCSI(isp)) {
mbs.param[1] =
((sdparam *) isp->isp_param)->isp_bus_reset_delay;
if (mbs.param[1] < 2)
mbs.param[1] = 2;
+ bus = *((int *) arg);
+ mbs.param[2] = bus;
} else {
- /*
- * Unparameterized.
- */
- mbs.param[1] = 5;
+ /* Unparameterized. */
+ mbs.param[1] = 10;
+ bus = 0;
}
- bus = *((int *) arg);
- mbs.param[2] = bus;
isp->isp_sendmarker = 1 << bus;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
@@ -2075,7 +2114,7 @@ isp_control(isp, ctl, arg)
}
mbs.param[0] = MBOX_ABORT;
#ifdef ISP2100_SCCLUN
- if (isp->isp_type & ISP_HA_FC) {
+ if (IS_FC(isp)) {
mbs.param[1] = XS_TGT(xs) << 8;
mbs.param[4] = 0;
mbs.param[5] = 0;
@@ -2125,14 +2164,17 @@ isp_intr(arg)
ISP_SCSI_XFER_T *complist[RESULT_QUEUE_LEN], *xs;
struct ispsoftc *isp = arg;
u_int8_t iptr, optr;
- u_int16_t isr, sema;
+ u_int16_t isr, isrb, sema;
int i, nlooked = 0, ndone = 0;
/*
* Well, if we've disabled interrupts, we may get a case where
- * isr isn't set, but sema is.
+ * isr isn't set, but sema is. In any case, debounce Isr reads.
*/
- isr = ISP_READ(isp, BIU_ISR);
+ do {
+ isr = ISP_READ(isp, BIU_ISR);
+ isrb = ISP_READ(isp, BIU_ISR);
+ } while (isr != isrb);
sema = ISP_READ(isp, BIU_SEMA) & 0x1;
IDPRINTF(5, ("%s: isp_intr isr %x sem %x\n", isp->isp_name, isr, sema));
if (IS_FC(isp)) {
@@ -2347,7 +2389,7 @@ isp_intr(arg)
XS_SETERR(xs, HBA_BOTCH);
}
}
- if (isp->isp_type & ISP_HA_SCSI) {
+ if (IS_SCSI(isp)) {
XS_RESID(xs) = sp->req_resid;
} else if (sp->req_scsi_status & RQCS_RU) {
XS_RESID(xs) = sp->req_resid;
@@ -2553,7 +2595,7 @@ isp_parse_async(isp, mbox)
((fcparam *) isp->isp_param)->isp_loopstate = LOOP_LIP_RCVD;
isp->isp_sendmarker = 1;
isp_mark_getpdb_all(isp);
- PRINTF("%s: LIP occurred\n", isp->isp_name);
+ IDPRINTF(1, ("%s: LIP occurred\n", isp->isp_name));
break;
case ASYNC_LOOP_UP:
@@ -2587,10 +2629,16 @@ isp_parse_async(isp, mbox)
isp->isp_sendmarker = 1;
((fcparam *) isp->isp_param)->isp_loopstate = LOOP_PDB_RCVD;
isp_mark_getpdb_all(isp);
- IDPRINTF(3, ("%s: Port Database Changed\n", isp->isp_name));
+ IDPRINTF(2, ("%s: Port Database Changed\n", isp->isp_name));
break;
case ASYNC_CHANGE_NOTIFY:
+ isp_mark_getpdb_all(isp);
+ /*
+ * Not correct, but it will force us to rescan the loop.
+ */
+ ((fcparam *) isp->isp_param)->isp_loopstate = LOOP_PDB_RCVD;
+ isp_async(isp, ISPASYNC_CHANGE_NOTIFY, NULL);
break;
default:
@@ -2647,7 +2695,7 @@ isp_handle_other_response(isp, sp, optrp)
/*
* The ISP is acknowleding our ack of an Immediate Notify.
*/
- if (isp->isp_type & ISP_HA_FC) {
+ if (IS_FC(isp)) {
PRINTF(f, isp->isp_name,
nack_fc->na-status, nack_fc->na_seqid);
} else {
@@ -2665,7 +2713,7 @@ isp_handle_other_response(isp, sp, optrp)
* or some other out of band condition (e.g., Port Logout)
* or it is returning an Immediate Notify entry we sent.
*/
- if (isp->isp_type & ISP_HA_FC) {
+ if (IS_FC(isp)) {
status = inot_fc->status;
seqid = inot_fc->in_seqid;
} else {
@@ -2950,7 +2998,7 @@ isp_modify_lun(isp, lun, icnt, ccnt)
ip->req_header.rqs_entry_count = 1;
ip->req_header.rqs_seqno = isp->isp_seqno++;
ip->req_handle = RQSTYPE_ENABLE_LUN;
- if (isp->isp_type & ISP_HA_SCSI) {
+ if (IS_SCSI(isp)) {
ip->req_lun = lun;
}
ip->req_cmdcount = ccnt;
@@ -2977,7 +3025,7 @@ isp_notify_ack(isp, ptrp)
un._nas.na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
un._nas.na_header.rqs_entry_count = 1;
- if (isp->isp_type & ISP_HA_FC) {
+ if (IS_FC(isp)) {
na_fcentry_t *na = &un._nas;
if (ptrp) {
in_fcentry_t *inp = ptrp;
@@ -3279,7 +3327,7 @@ isp_parse_status(isp, sp, xs)
return;
case RQCS_DATA_OVERRUN:
- if (isp->isp_type & ISP_HA_FC) {
+ if (IS_FC(isp)) {
XS_RESID(xs) = sp->req_resid;
break;
}
@@ -3354,7 +3402,7 @@ isp_parse_status(isp, sp, xs)
break;
case RQCS_DATA_UNDERRUN:
- if (isp->isp_type & ISP_HA_FC) {
+ if (IS_FC(isp)) {
XS_RESID(xs) = sp->req_resid;
/* an UNDERRUN is not a botch ??? */
}
@@ -3661,7 +3709,7 @@ isp_mboxcmd(isp, mbp)
* Check for variants
*/
#ifdef ISP2100_SCCLUN
- if (isp->isp_type & ISP_HA_FC) {
+ if (IS_FC(isp)) {
switch (mbp->param[0]) {
case MBOX_ABORT:
inparam = 7;
@@ -3674,6 +3722,9 @@ isp_mboxcmd(isp, mbp)
case MBOX_GET_DEV_QUEUE_STATUS:
inparam = 3;
break;
+ case MBOX_BUS_RESET:
+ inparam = 2;
+ break;
default:
break;
}
@@ -3688,6 +3739,12 @@ command_known:
ISP_WRITE(isp, BIU_SEMA, 1);
/*
+ * Qlogic Errata for the ISP2100 says that there is a necessary
+ * debounce between between writing the semaphore register
+ * and reading a mailbox register. I believe we're okay here.
+ */
+
+ /*
* Make sure we can send some words.
* Check to see if there's an async mbox event pending.
*/
@@ -4022,7 +4079,7 @@ isp_dumpregs(isp, msg)
const char *msg;
{
PRINTF("%s: %s\n", isp->isp_name, msg);
- if (isp->isp_type & ISP_HA_SCSI)
+ if (IS_SCSI(isp))
PRINTF(" biu_conf1=%x", ISP_READ(isp, BIU_CONF1));
else
PRINTF(" biu_csr=%x", ISP_READ(isp, BIU2100_CSR));
@@ -4031,7 +4088,7 @@ isp_dumpregs(isp, msg)
PRINTF("risc_hccr=%x\n", ISP_READ(isp, HCCR));
- if (isp->isp_type & ISP_HA_SCSI) {
+ if (IS_SCSI(isp)) {
ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
PRINTF(" cdma_conf=%x cdma_sts=%x cdma_fifostat=%x\n",
ISP_READ(isp, CDMA_CONF), ISP_READ(isp, CDMA_STATUS),
@@ -4078,7 +4135,7 @@ isp_fw_state(isp)
struct ispsoftc *isp;
{
mbreg_t mbs;
- if (isp->isp_type & ISP_HA_FC) {
+ if (IS_FC(isp)) {
int once = 0;
fcparam *fcp = isp->isp_param;
again:
@@ -4145,7 +4202,7 @@ isp_update_bus(isp, bus)
mbreg_t mbs;
sdparam *sdp;
- if (isp->isp_type & ISP_HA_FC) {
+ if (IS_FC(isp)) {
return;
}
@@ -4157,8 +4214,8 @@ isp_update_bus(isp, bus)
int get;
if (sdp->isp_devparam[tgt].dev_enable == 0) {
- PRINTF("%s: skipping update of target %d on bus %d\n",
- isp->isp_name, tgt, bus);
+ IDPRINTF(1, ("%s: skipping target %d bus %d update\n",
+ isp->isp_name, tgt, bus));
continue;
}
@@ -4800,14 +4857,24 @@ isp_read_nvram(isp)
u_int32_t lo32;
u_int32_t hi32;
#endif
- } wds;
+ } wd;
u_int64_t full64;
} wwnstore;
wwnstore.full64 = ISP2100_NVRAM_NODE_NAME(nvram_data);
- PRINTF("%s: Adapter WWN 0x%08x%08x\n", isp->isp_name,
- wwnstore.wds.hi32, wwnstore.wds.lo32);
+ /*
+ * Broken PTI cards with nothing in the top nibble. Pah.
+ */
+ if ((wwnstore.wd.hi32 >> 28) == 0) {
+ wwnstore.wd.hi32 |= (2 << 28);
+ PRINTF("%s: (corrected) Adapter WWN 0x%08x%08x\n",
+ isp->isp_name, wwnstore.wd.hi32, wwnstore.wd.lo32);
+ } else {
+ PRINTF("%s: Adapter WWN 0x%08x%08x\n", isp->isp_name,
+ wwnstore.wd.hi32, wwnstore.wd.lo32);
+ }
fcp->isp_nodewwn = wwnstore.full64;
+
/*
* If the Node WWN has 2 in the top nibble, we can
* authoritatively construct a Port WWN by adding
@@ -4824,8 +4891,7 @@ isp_read_nvram(isp)
wwnstore.full64 = ISP2100_NVRAM_BOOT_NODE_NAME(nvram_data);
if (wwnstore.full64 != 0) {
PRINTF("%s: BOOT DEVICE WWN 0x%08x%08x\n",
- isp->isp_name, wwnstore.wds.hi32,
- wwnstore.wds.lo32);
+ isp->isp_name, wwnstore.wd.hi32, wwnstore.wd.lo32);
}
fcp->isp_maxalloc =
ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);