summaryrefslogtreecommitdiff
path: root/sys/dev/ic/isp.c
diff options
context:
space:
mode:
authormjacob <mjacob@cvs.openbsd.org>2000-07-06 05:31:50 +0000
committermjacob <mjacob@cvs.openbsd.org>2000-07-06 05:31:50 +0000
commit31aac79a59ca445d1cf6c71e52787efe67800919 (patch)
treedf9cb3676c3dcd5f0bcfe507da8441f709ab1d21 /sys/dev/ic/isp.c
parent6e19cd57aab2214eed0c07bd2f244840f212184b (diff)
Resync with FreeBSD/NetBSD. Salient features are that the mailbox command
routines are not necessarily polled now- this should cut down on some of the spurious lost commands that have occurred. Also, we now watchdog each command and make sure that command constipation doesn't occur (which it has been documented to do on the QLA2100 cards).
Diffstat (limited to 'sys/dev/ic/isp.c')
-rw-r--r--sys/dev/ic/isp.c1337
1 files changed, 701 insertions, 636 deletions
diff --git a/sys/dev/ic/isp.c b/sys/dev/ic/isp.c
index e7daced056f..23e0c6af910 100644
--- a/sys/dev/ic/isp.c
+++ b/sys/dev/ic/isp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isp.c,v 1.15 2000/04/06 05:50:43 mjacob Exp $ */
+/* $OpenBSD: isp.c,v 1.16 2000/07/06 05:31:48 mjacob Exp $ */
/*
* Machine and OS Independent (well, as best as possible)
* code for the Qlogic ISP SCSI adapters.
@@ -113,7 +113,7 @@ isp_reset(isp)
struct ispsoftc *isp;
{
mbreg_t mbs;
- int loops, i, dodnld = 1;
+ int loops, i, touched, dodnld = 1;
char *revname;
isp->isp_state = ISP_NILSTATE;
@@ -138,7 +138,7 @@ isp_reset(isp)
* case, we don't really use this yet, but we may in
* the future.
*/
- if (isp->isp_touched == 0) {
+ if ((touched = isp->isp_touched) == 0) {
/*
* Just in case it was paused...
*/
@@ -576,6 +576,8 @@ again:
else
mbs.param[1] = 0x1000;
isp_mboxcmd(isp, &mbs);
+ /* give it a chance to start */
+ SYS_DELAY(500);
if (IS_SCSI(isp)) {
/*
@@ -636,6 +638,46 @@ again:
return;
}
isp->isp_state = ISP_RESETSTATE;
+
+ /*
+ * Okay- now that we have new firmware running, we now (re)set our
+ * notion of how many luns we support. This is somewhat tricky because
+ * if we haven't loaded firmware, we don't have an easy way of telling
+ * how many luns we support.
+ *
+ * We'll make a simplifying assumption- if we loaded firmware, we
+ * are running with expanded lun firmware, otherwise not.
+ *
+ * Expanded lun firmware gives you 32 luns for SCSI cards and
+ * 65536 luns for Fibre Channel cards.
+ *
+ * Because the lun is in a a different position in the Request Queue
+ * Entry structure for Fibre Channel with expanded lun firmware, we
+ * can only support one lun (lun zero) when we don't know what kind
+ * of firmware we're running.
+ *
+ * Note that we only do this once (the first time thru isp_reset)
+ * because we may be called again after firmware has been loaded once
+ * and released.
+ */
+ if (touched == 0) {
+ if (dodnld) {
+ if (IS_SCSI(isp)) {
+ isp->isp_maxluns = 32;
+ } else {
+ isp->isp_maxluns = 65536;
+ }
+ } else {
+ if (IS_SCSI(isp)) {
+ isp->isp_maxluns = 8;
+ } else {
+ PRINTF("%s: WARNING- cannot determine Expanded "
+ "LUN capability- limiting to one LUN\n",
+ isp->isp_name);
+ isp->isp_maxluns = 1;
+ }
+ }
+ }
}
/*
@@ -861,11 +903,11 @@ isp_scsi_channel_init(isp, channel)
* Set current per-target parameters to a safe minimum.
*/
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
- int maxlun, lun;
+ int lun;
u_int16_t sdf;
if (sdp->isp_devparam[tgt].dev_enable == 0) {
- IDPRINTF(1, ("%s: skipping target %d bus %d settings\n",
+ IDPRINTF(2, ("%s: skipping target %d bus %d settings\n",
isp->isp_name, tgt, channel));
continue;
}
@@ -952,13 +994,7 @@ isp_scsi_channel_init(isp, channel)
* seen yet.
*/
sdp->isp_devparam[tgt].cur_dflags &= ~DPARM_TQING;
- if ((ISP_FW_REV(4, 55, 0) <= ISP_FW_REVX(isp->isp_fwrev) &&
- (ISP_FW_REV(5, 0, 0) > ISP_FW_REVX(isp->isp_fwrev))) ||
- (ISP_FW_REVX(isp->isp_fwrev) >= ISP_FW_REV(7, 55, 0)))
- maxlun = 32;
- else
- maxlun = 8;
- for (lun = 0; lun < maxlun; lun++) {
+ for (lun = 0; lun < isp->isp_maxluns; lun++) {
mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
mbs.param[1] = (channel << 15) | (tgt << 8) | lun;
mbs.param[2] = sdp->isp_max_queue_depth;
@@ -1025,7 +1061,7 @@ isp_fibre_init(isp)
/*
* 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.
+ * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
*/
if (ISP_FW_REVX(isp->isp_fwrev) < ISP_FW_REV(1, 17, 0)) {
fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
@@ -1079,26 +1115,8 @@ isp_fibre_init(isp)
icbp->icb_logintime = 60; /* 60 second login timeout */
if (fcp->isp_nodewwn) {
- u_int64_t pn;
MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_nodewwn);
- if (fcp->isp_portwwn) {
- pn = fcp->isp_portwwn;
- } else {
- pn = fcp->isp_nodewwn |
- (((u_int64_t)(isp->isp_unit+1)) << 56);
- }
- /*
- * If the top nibble is 2, we can construct a port name
- * from the node name by setting a nonzero instance in
- * bits 56..59. Otherwise, we need to make it identical
- * to Node name...
- */
- if ((fcp->isp_nodewwn >> 60) == 2) {
- MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pn);
- } else {
- MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname,
- fcp->isp_nodewwn);
- }
+ MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_portwwn);
} else {
fcp->isp_fwoptions &= ~(ICBOPT_USE_PORTNAME|ICBOPT_FULL_LOGIN);
}
@@ -1253,7 +1271,8 @@ isp_fclink_test(isp, waitdelay)
"Private Loop",
"FL Port",
"N-Port to N-Port",
- "F Port"
+ "F Port",
+ "F Port (no FLOGI_ACC response)"
};
mbreg_t mbs;
int count;
@@ -1300,54 +1319,74 @@ isp_fclink_test(isp, waitdelay)
}
fcp->isp_loopid = mbs.param[1];
if (IS_2200(isp)) {
- count = (int) mbs.param[6];
- if (count < TOPO_NL_PORT || count > TOPO_PTP_STUB)
- count = TOPO_PTP_STUB;
- fcp->isp_topo = count;
+ int topo = (int) mbs.param[6];
+ if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
+ topo = TOPO_PTP_STUB;
+ fcp->isp_topo = topo;
} else {
fcp->isp_topo = TOPO_NL_PORT;
}
-
- /*
- * If we're not on a fabric, the low 8 bits will be our AL_PA.
- * If we're on a fabric, the low 8 bits will still be our AL_PA.
- */
fcp->isp_alpa = mbs.param[2];
+
#if defined(ISP2100_FABRIC)
fcp->isp_onfabric = 0;
- if (isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
-
- if (IS_2100(isp))
+ if (fcp->isp_topo != TOPO_N_PORT &&
+ isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
+ struct lportdb *lp;
+ if (IS_2100(isp)) {
fcp->isp_topo = TOPO_FL_PORT;
-
+ }
fcp->isp_portid = mbs.param[2] | (((int)mbs.param[3]) << 16);
fcp->isp_onfabric = 1;
- CFGPRINTF("%s: Loop ID %d, AL_PA 0x%x, Port ID 0x%x Loop State "
- "0x%x topology '%s'\n", isp->isp_name, fcp->isp_loopid,
- fcp->isp_alpa, fcp->isp_portid, fcp->isp_loopstate,
- toponames[fcp->isp_topo]);
/*
- * Make sure we're logged out of all fabric devices.
+ * Save the Fabric controller's port database entry.
*/
- for (count = FC_SNS_ID+1; count < MAX_FC_TARG; count++) {
- struct lportdb *lp = &fcp->portdb[count];
- if (lp->valid == 0 || lp->fabdev == 0)
- continue;
- PRINTF("%s: logging out target %d at Loop ID %d "
- "(port id 0x%x)\n", isp->isp_name, count,
- lp->loopid, lp->portid);
- mbs.param[0] = MBOX_FABRIC_LOGOUT;
- mbs.param[1] = lp->loopid << 8;
- mbs.param[2] = 0;
- mbs.param[3] = 0;
- isp_mboxcmd(isp, &mbs);
+ lp = &fcp->portdb[FL_PORT_ID];
+ 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]));
+ 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->loggedin = lp->valid = 1;
+#if 0
+ if (isp->isp_rfabric == 0) {
+ isp_i_register_fc4_type(isp);
}
+#endif
} else
#endif
- CFGPRINTF("%s: Loop ID %d, ALPA 0x%x Loop State 0x%x topology '%s'\n",
- isp->isp_name, fcp->isp_loopid, fcp->isp_alpa, fcp->isp_loopstate,
+ {
+ fcp->isp_portid = mbs.param[2];
+ fcp->isp_onfabric = 0;
+#if 0
+ isp->isp_rfabric = 0;
+#endif
+ fcp->portdb[FL_PORT_ID].valid = 0;
+ }
+
+ CFGPRINTF("%s: Loop ID %d, AL_PA 0x%x, Port ID 0x%x Loop State "
+ "0x%x topology '%s'\n", isp->isp_name, fcp->isp_loopid,
+ fcp->isp_alpa, fcp->isp_portid, fcp->isp_loopstate,
toponames[fcp->isp_topo]);
+
return (0);
}
@@ -1365,7 +1404,7 @@ isp_same_lportdb(a, b)
*/
if (a->port_wwn == 0 || a->port_wwn != b->port_wwn ||
- a->loopid != b->loopid) {
+ a->loopid != b->loopid || a->roles != b->roles) {
return (0);
} else {
return (1);
@@ -1385,7 +1424,7 @@ isp_pdb_sync(isp, target)
struct lportdb *lp, *tport;
fcparam *fcp = isp->isp_param;
isp_pdb_t pdb;
- int loopid, lim;
+ int loopid, prange, lim;
#ifdef ISP2100_FABRIC
/*
@@ -1400,6 +1439,19 @@ isp_pdb_sync(isp, target)
#endif
+ switch (fcp->isp_topo) {
+ case TOPO_F_PORT:
+ case TOPO_PTP_STUB:
+ prange = 0;
+ break;
+ case TOPO_N_PORT:
+ prange = 2;
+ break;
+ default:
+ prange = FL_PORT_ID;
+ break;
+ }
+
/*
* Run through the local loop ports and get port database info
* for each loop ID.
@@ -1414,12 +1466,17 @@ isp_pdb_sync(isp, target)
* make sure the temp port database is clean...
*/
MEMZERO((void *) tport, sizeof (tport));
- for (lim = loopid = 0; loopid < FL_PORT_ID; loopid++) {
+
+ for (lim = loopid = 0; loopid < prange; loopid++) {
lp = &tport[loopid];
lp->node_wwn = isp_get_portname(isp, loopid, 1);
+ if (fcp->isp_loopstate < LOOP_PDB_RCVD)
+ return (-1);
if (lp->node_wwn == 0)
continue;
lp->port_wwn = isp_get_portname(isp, loopid, 0);
+ if (fcp->isp_loopstate < LOOP_PDB_RCVD)
+ return (-1);
if (lp->port_wwn == 0) {
lp->node_wwn = 0;
continue;
@@ -1429,16 +1486,19 @@ isp_pdb_sync(isp, target)
* Get an entry....
*/
if (isp_getpdb(isp, loopid, &pdb) != 0) {
+ if (fcp->isp_loopstate < LOOP_PDB_RCVD)
+ return (-1);
continue;
}
+ if (fcp->isp_loopstate < LOOP_PDB_RCVD)
+ return (-1);
+
/*
* If the returned database element doesn't match what we
* asked for, restart the process entirely (up to a point...).
*/
if (pdb.pdb_loopid != loopid) {
- IDPRINTF(1, ("%s: wankage (%d != %d)\n",
- isp->isp_name, pdb.pdb_loopid, loopid));
loopid = 0;
if (lim++ < FL_PORT_ID) {
continue;
@@ -1504,7 +1564,7 @@ isp_pdb_sync(isp, target)
* Now merge our local copy of the port database into our saved copy.
* Notify the outer layers of new devices arriving.
*/
- for (loopid = 0; loopid < FL_PORT_ID; loopid++) {
+ for (loopid = 0; loopid < prange; loopid++) {
int i;
/*
@@ -1557,10 +1617,7 @@ isp_pdb_sync(isp, target)
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?
- */
+ fcp->portdb[i].roles = tport[loopid].roles;
/*
* Now make sure this Port WWN doesn't exist elsewhere
@@ -1635,7 +1692,7 @@ isp_pdb_sync(isp, target)
* Now find all previously used targets that are now invalid and
* notify the outer layers that they're gone.
*/
- for (lp = fcp->portdb; lp < &fcp->portdb[FL_PORT_ID]; lp++) {
+ for (lp = fcp->portdb; lp < &fcp->portdb[prange]; lp++) {
if (lp->valid || lp->port_wwn == 0)
continue;
@@ -1651,13 +1708,13 @@ isp_pdb_sync(isp, target)
/*
* Now log in any fabric devices
*/
- for (lim = FC_SNS_ID+1, lp = &fcp->portdb[FC_SNS_ID+1];
+ for (lp = &fcp->portdb[FC_SNS_ID+1];
lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
u_int32_t portid;
mbreg_t mbs;
/*
- * Nothing here?
+ * Anything here?
*/
if (lp->port_wwn == 0)
continue;
@@ -1668,16 +1725,61 @@ isp_pdb_sync(isp, target)
if ((portid = lp->portid) == fcp->isp_portid)
continue;
+
+ /*
+ * If we'd been logged in- see if we still are and we haven't
+ * changed. If so, no need to log ourselves out, etc..
+ */
+ if (lp->loggedin &&
+ isp_getpdb(isp, lp->loopid, &pdb) == 0) {
+ int nrole;
+ u_int64_t nwwnn, nwwpn;
+ nwwnn =
+ (((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]));
+ nwwpn =
+ (((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]));
+ nrole = (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >>
+ SVC3_ROLE_SHIFT;
+ if (pdb.pdb_loopid == lp->loopid && lp->portid ==
+ (u_int32_t) BITS2WORD(pdb.pdb_portid_bits) &&
+ nwwnn == lp->node_wwn && nwwpn == lp->port_wwn &&
+ lp->roles == nrole) {
+ lp->loggedin = lp->valid = 1;
+ IDPRINTF(1, ("%s: retained login of Target %d "
+ "(Loop 0x%x) Port ID 0x%x\n",
+ isp->isp_name, (int) (lp - fcp->portdb),
+ (int) lp->loopid, lp->portid));
+ continue;
+ }
+ }
+
/*
* Force a logout if we were logged in.
*/
- if (lp->valid) {
+ if (lp->loggedin) {
mbs.param[0] = MBOX_FABRIC_LOGOUT;
mbs.param[1] = lp->loopid << 8;
mbs.param[2] = 0;
mbs.param[3] = 0;
isp_mboxcmd(isp, &mbs);
- lp->valid = 0;
+ lp->loggedin = 0;
+ IDPRINTF(1, ("%s: Logging out target %d at Loop ID %d "
+ "(port id 0x%x)\n", isp->isp_name,
+ (int) (lp - fcp->portdb), lp->loopid, lp->portid));
}
/*
@@ -1685,16 +1787,15 @@ isp_pdb_sync(isp, target)
*/
loopid = lp - fcp->portdb;
lp->loopid = 0;
- lim = 0;
do {
mbs.param[0] = MBOX_FABRIC_LOGIN;
mbs.param[1] = loopid << 8;
+ mbs.param[2] = portid >> 16;
+ mbs.param[3] = portid & 0xffff;
if (IS_2200(isp)) {
/* only issue a PLOGI if not logged in */
mbs.param[1] |= 0x1;
}
- mbs.param[2] = portid >> 16;
- mbs.param[3] = portid & 0xffff;
isp_mboxcmd(isp, &mbs);
switch (mbs.param[0]) {
case MBOX_LOOP_ID_USED:
@@ -1706,49 +1807,71 @@ isp_pdb_sync(isp, target)
case MBOX_PORT_ID_USED:
/*
* This port is already logged in.
- * Snaffle the loop id it's using.
+ * Snaffle the loop id it's using if it's
+ * nonzero, otherwise we're hosed.
*/
- if ((loopid = mbs.param[1]) == 0) {
- lim = -1;
+ if (mbs.param[1] != 0) {
+ loopid = mbs.param[1];
+ IDPRINTF(1, ("%s: Retaining loopid 0x%x"
+ " for Target %d (port id 0x%x)\n",
+ isp->isp_name, loopid,
+ (int) (lp - fcp->portdb),
+ lp->portid));
+ } else {
+ loopid = MAX_FC_TARG;
+ break;
}
/* FALLTHROUGH */
case MBOX_COMMAND_COMPLETE:
+ lp->loggedin = 1;
lp->loopid = loopid;
- lim = 1;
break;
case MBOX_COMMAND_ERROR:
- PRINTF("%s: command error in PLOGI (0x%x)\n",
- isp->isp_name, mbs.param[1]);
+ PRINTF("%s: command error in PLOGI for port "
+ " 0x%x (0x%x)\n", isp->isp_name, portid,
+ mbs.param[1]);
/* FALLTHROUGH */
case MBOX_ALL_IDS_USED: /* We're outta IDs */
default:
- lim = -1;
+ loopid = MAX_FC_TARG;
break;
}
- } while (lim == 0 && loopid < MAX_FC_TARG);
- if (lim < 0)
+ } while (lp->loopid == 0 && loopid < MAX_FC_TARG);
+
+ /*
+ * If we get here and we haven't set a Loop ID,
+ * we failed to log into this device.
+ */
+
+ if (lp->loopid == 0) {
continue;
+ }
- lp->valid = 1;
- lp->fabdev = 1;
+ /*
+ * Make sure we can get the approriate port information.
+ */
if (isp_getpdb(isp, lp->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);
- continue;
+ PRINTF("%s: could not get PDB for device@port 0x%x\n",
+ isp->isp_name, lp->portid);
+ goto dump_em;
}
+
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);
- continue;
+ PRINTF("%s: PDB loopid info for device@port 0x%x does "
+ "not match up (0x%x)\n", isp->isp_name, lp->portid,
+ pdb.pdb_loopid);
+ goto dump_em;
}
+
+ if (lp->portid != (u_int32_t) BITS2WORD(pdb.pdb_portid_bits)) {
+ PRINTF("%s: PDB port info for device@port 0x%x does "
+ "not match up (0x%x)\n", isp->isp_name, lp->portid,
+ BITS2WORD(pdb.pdb_portid_bits));
+ goto dump_em;
+ }
+
lp->roles =
(pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
- lp->portid = BITS2WORD(pdb.pdb_portid_bits);
lp->node_wwn =
(((u_int64_t)pdb.pdb_nodename[0]) << 56) |
(((u_int64_t)pdb.pdb_nodename[1]) << 48) |
@@ -1771,13 +1894,15 @@ isp_pdb_sync(isp, target)
* Check to make sure this all makes sense.
*/
if (lp->node_wwn && lp->port_wwn) {
+ lp->valid = 1;
loopid = lp - fcp->portdb;
(void) isp_async(isp, ISPASYNC_PDB_CHANGED, &loopid);
continue;
}
- lp->fabdev = lp->valid = 0;
- PRINTF("%s: Target %d (Loop 0x%x) Port ID 0x%x lost its WWN\n",
- isp->isp_name, loopid, lp->loopid, lp->portid);
+dump_em:
+ lp->valid = 0;
+ PRINTF("%s: Target %d (Loop 0x%x) Port ID 0x%x dumped after "
+ "login\n", isp->isp_name, loopid, lp->loopid, lp->portid);
mbs.param[0] = MBOX_FABRIC_LOGOUT;
mbs.param[1] = lp->loopid << 8;
mbs.param[2] = 0;
@@ -2011,7 +2136,7 @@ ispscsicmd(xs)
}
if (isp_getrqentry(isp, &iptr, &optr, (void **) &reqp)) {
- IDPRINTF(1, ("%s: Request Queue Overflow\n", isp->isp_name));
+ IDPRINTF(2, ("%s: Request Queue Overflow\n", isp->isp_name));
XS_SETERR(xs, HBA_BOTCH);
return (CMD_EAGAIN);
}
@@ -2040,7 +2165,7 @@ ispscsicmd(xs)
ISP_ADD_REQUEST(isp, iptr);
if (isp_getrqentry(isp, &iptr, &optr, (void **)&reqp)) {
- IDPRINTF(1, ("%s: Request Queue Overflow+\n",
+ IDPRINTF(2, ("%s: Request Queue Overflow+\n",
isp->isp_name));
XS_SETERR(xs, HBA_BOTCH);
return (CMD_EAGAIN);
@@ -2091,11 +2216,10 @@ ispscsicmd(xs)
reqp->req_lun_trn = XS_LUN(xs);
reqp->req_cdblen = XS_CDBLEN(xs);
} else {
-#ifdef ISP2100_SCCLUN
- t2reqp->req_scclun = XS_LUN(xs);
-#else
- t2reqp->req_lun_trn = XS_LUN(xs);
-#endif
+ if (isp->isp_maxluns > 16)
+ t2reqp->req_scclun = XS_LUN(xs);
+ else
+ t2reqp->req_lun_trn = XS_LUN(xs);
}
MEMCPY(reqp->req_cdb, XS_CDBP(xs), XS_CDBLEN(xs));
@@ -2211,6 +2335,7 @@ isp_control(isp, ctl, arg)
case ISPCTL_ABORT_CMD:
xs = (ISP_SCSI_XFER_T *) arg;
+ tgt = XS_TGT(xs);
handle = isp_find_handle(isp, xs);
if (handle == 0) {
PRINTF("%s: isp_control- cannot find command to abort "
@@ -2220,14 +2345,14 @@ isp_control(isp, ctl, arg)
bus = XS_CHANNEL(xs);
mbs.param[0] = MBOX_ABORT;
if (IS_FC(isp)) {
-#ifdef ISP2100_SCCLUN
- mbs.param[1] = XS_TGT(xs) << 8;
- mbs.param[4] = 0;
- mbs.param[5] = 0;
- mbs.param[6] = XS_LUN(xs);
-#else
- mbs.param[1] = XS_TGT(xs) << 8 | XS_LUN(xs);
-#endif
+ if (isp->isp_maxluns > 16) {
+ mbs.param[1] = tgt << 8;
+ mbs.param[4] = 0;
+ mbs.param[5] = 0;
+ mbs.param[6] = XS_LUN(xs);
+ } else {
+ mbs.param[1] = tgt << 8 | XS_LUN(xs);
+ }
} else {
mbs.param[1] =
(bus << 15) | (XS_TGT(xs) << 8) | XS_LUN(xs);
@@ -2235,13 +2360,19 @@ isp_control(isp, ctl, arg)
mbs.param[3] = handle >> 16;
mbs.param[2] = handle & 0xffff;
isp_mboxcmd(isp, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: isp_control MBOX_ABORT failure (code %x)\n",
- isp->isp_name, mbs.param[0]);
+ switch (mbs.param[0]) {
+ case MBOX_COMMAND_COMPLETE:
+ IDPRINTF(1,
+ ("%s: command (handle 0x%x) for %d.%d.%d aborted\n",
+ isp->isp_name, handle, bus, tgt, XS_LUN(xs)));
+ /* FALLTHROUGH */
+ case MBOX_COMMAND_ERROR:
+ break;
+ default:
+ PRINTF("%s: command (handle 0x%x) abort failed (%x)\n",
+ isp->isp_name, handle, mbs.param[0]);
break;
}
- PRINTF("%s: command for target %d lun %d was aborted\n",
- isp->isp_name, XS_TGT(xs), XS_LUN(xs));
return (0);
case ISPCTL_UPDATE_PARAMS:
@@ -2249,10 +2380,16 @@ isp_control(isp, ctl, arg)
return (0);
case ISPCTL_FCLINK_TEST:
- return (isp_fclink_test(isp, FC_FW_READY_DELAY));
+ if (IS_FC(isp)) {
+ return (isp_fclink_test(isp, FC_FW_READY_DELAY));
+ }
+ break;
case ISPCTL_PDB_SYNC:
- return (isp_pdb_sync(isp, -1));
+ if (IS_FC(isp)) {
+ return (isp_pdb_sync(isp, -1));
+ }
+ break;
#ifdef ISP_TARGET_MODE
case ISPCTL_TOGGLE_TMODE:
@@ -2287,42 +2424,74 @@ isp_intr(arg)
{
ISP_SCSI_XFER_T *complist[RESULT_QUEUE_LEN], *xs;
struct ispsoftc *isp = arg;
- u_int16_t iptr, optr;
- u_int16_t isr, isrb, sema;
+ u_int16_t iptr, optr, isr, sema, junk;
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. In any case, debounce isr reads.
- */
- do {
+ if (IS_2100(isp)) {
+ i = 0;
+ do {
+ isr = ISP_READ(isp, BIU_ISR);
+ junk = ISP_READ(isp, BIU_ISR);
+ } while (isr != junk && ++i < 1000);
+ if (isr != junk) {
+ PRINTF("%s: isr unsteady (%x, %x)\n",
+ isp->isp_name, isr, junk);
+ }
+ i = 0;
+ do {
+ sema = ISP_READ(isp, BIU_SEMA);
+ junk = ISP_READ(isp, BIU_SEMA);
+ } while (sema != junk && ++i < 1000);
+ if (sema != junk) {
+ PRINTF("%s: sema unsteady (%x, %x)\n",
+ isp->isp_name, sema, junk);
+ }
+ } else {
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 (isr == 0) {
- return (0);
+ sema = ISP_READ(isp, BIU_SEMA);
}
- if (!INT_PENDING(isp, isr)) {
- IDPRINTF(4, ("%s: isp_intr isr=%x\n", isp->isp_name, isr));
+ IDPRINTF(5, ("%s: isp_intr isr %x sem %x\n", isp->isp_name, isr, sema));
+ isr &= INT_PENDING_MASK(isp);
+ sema &= BIU_SEMA_LOCK;
+ if (isr == 0 && sema == 0) {
return (0);
}
- if (isp->isp_state != ISP_RUNSTATE) {
- IDPRINTF(3, ("%s: interrupt (isr=%x,sema=%x) when not ready\n",
- isp->isp_name, isr, sema));
- ISP_WRITE(isp, INMAILBOX5, ISP_READ(isp, OUTMAILBOX5));
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- ISP_WRITE(isp, BIU_SEMA, 0);
- ENABLE_INTS(isp);
- return (1);
- }
if (sema) {
- u_int16_t mbox = ISP_READ(isp, OUTMAILBOX0);
+ u_int16_t mbox;
+
+ if (IS_2100(isp)) {
+ i = 0;
+ do {
+ mbox = ISP_READ(isp, OUTMAILBOX0);
+ junk = ISP_READ(isp, OUTMAILBOX0);;
+ } while (junk != mbox && ++i < 1000);
+ if (mbox != junk) {
+ PRINTF("%s: mailbox0 unsteady (%x, %x)\n",
+ isp->isp_name, mbox, junk);
+ ISP_WRITE(isp, BIU_SEMA, 0);
+ ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
+ return (1);
+ }
+ } else {
+ mbox = ISP_READ(isp, OUTMAILBOX0);
+ }
if (mbox & 0x4000) {
- IDPRINTF(4, ("%s: Command Mbox 0x%x\n",
- isp->isp_name, mbox));
+ int obits, i = 0;
+ if ((obits = isp->isp_mboxbsy) != 0) {
+ isp->isp_mboxtmp[i++] = mbox;
+ for (i = 1; i < 8; i++) {
+ if ((obits & (1 << i)) == 0) {
+ continue;
+ }
+ isp->isp_mboxtmp[i] =
+ ISP_READ(isp, MBOX_OFF(i));
+ }
+ MBOX_NOTIFY_COMPLETE(isp);
+ } else {
+ PRINTF("%s: Command Mbox 0x%x\n",
+ isp->isp_name, mbox);
+ }
} else {
u_int32_t fhandle = isp_parse_async(isp, (int) mbox);
IDPRINTF(4, ("%s: Async Mbox 0x%x\n",
@@ -2331,9 +2500,22 @@ isp_intr(arg)
isp_fastpost_complete(isp, fhandle);
}
}
- ISP_WRITE(isp, BIU_SEMA, 0);
+ if (IS_FC(isp) || isp->isp_state != ISP_RUNSTATE) {
+ ISP_WRITE(isp, BIU_SEMA, 0);
+ ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
+ return (1);
+ }
+ }
+
+ /*
+ * We can't be getting this now.
+ */
+ if (isp->isp_state != ISP_RUNSTATE) {
+ PRINTF("%s: interrupt (isr=%x, sema=%x) when not ready\n",
+ isp->isp_name, isr, sema);
+ ISP_WRITE(isp, INMAILBOX5, ISP_READ(isp, OUTMAILBOX5));
ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- ENABLE_INTS(isp);
+ ISP_WRITE(isp, BIU_SEMA, 0);
return (1);
}
@@ -2341,11 +2523,41 @@ isp_intr(arg)
* You *must* read OUTMAILBOX5 prior to clearing the RISC interrupt.
*/
optr = isp->isp_residx;
- iptr = ISP_READ(isp, OUTMAILBOX5);
+
+ if (IS_2100(isp)) {
+ i = 0;
+ do {
+ iptr = ISP_READ(isp, OUTMAILBOX5);
+ junk = ISP_READ(isp, OUTMAILBOX5);
+ } while (junk != iptr && ++i < 1000);
+
+ if (iptr != junk) {
+ ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
+ PRINTF("%s: mailbox5 unsteady (%x, %x)\n",
+ isp->isp_name, iptr, junk);
+ return (1);
+ }
+ } else {
+ iptr = ISP_READ(isp, OUTMAILBOX5);
+ }
+
+ if (sema) {
+ ISP_WRITE(isp, BIU_SEMA, 0);
+ }
ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- if (optr == iptr) {
- IDPRINTF(4, ("why intr? isr %x iptr %x optr %x\n",
- isr, optr, iptr));
+
+ if (optr == iptr && sema == 0) {
+ /*
+ * There are a lot of these- reasons unknown- mostly on
+ * faster Alpha machines.
+ *
+ * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
+ * make sure the old interrupt went away (to avoid 'ringing'
+ * effects), but that didn't stop this from occurring.
+ */
+ junk = ISP_READ(isp, BIU_ISR);
+ IDPRINTF(2, ("%s: null intr- isr %x (%x) iptr %x optr %x\n",
+ isp->isp_name, isr, junk, iptr, optr));
}
while (optr != iptr) {
@@ -2460,8 +2672,9 @@ isp_intr(arg)
XS_SNS_IS_VALID(xs);
sp->req_state_flags |= RQSF_GOT_SENSE;
} else if (XS_STS(xs) == SCSI_CHECK) {
- IDPRINTF(1, ("%s: check condition with no sense"
- " data\n", isp->isp_name));
+ IDPRINTF(2,
+ ("%s: check condition with no sense data\n",
+ isp->isp_name));
}
}
if (XS_NOERR(xs) && XS_STS(xs) == SCSI_BUSY) {
@@ -2503,24 +2716,6 @@ isp_intr(arg)
if (XS_XFRLEN(xs)) {
ISP_DMAFREE(isp, xs, sp->req_handle);
}
- /*
- * Let the platforms cope.
- */
-#if 0
- /*
- * XXX: If we have a check condition, but no Sense Data,
- * XXX: mark it as an error (ARQ failed). We need to
- * XXX: to do a more distinct job because there may
- * XXX: cases where ARQ is disabled.
- */
- if (XS_STS(xs) == SCSI_CHECK && !(XS_IS_SNS_VALID(xs))) {
- if (XS_NOERR(xs)) {
- PRINTF("%s: ARQ failure for target %d lun %d\n",
- isp->isp_name, XS_TGT(xs), XS_LUN(xs));
- XS_SETERR(xs, HBA_ARQFAIL);
- }
- }
-#endif
if ((isp->isp_dblev >= 5) ||
(isp->isp_dblev > 2 && !XS_NOERR(xs))) {
PRINTF("%s(%d.%d): FIN dl%d resid%d STS %x",
@@ -2549,6 +2744,7 @@ isp_intr(arg)
ISP_WRITE(isp, INMAILBOX5, optr);
isp->isp_reqodx = ISP_READ(isp, OUTMAILBOX4);
}
+
isp->isp_residx = optr;
for (i = 0; i < ndone; i++) {
xs = complist[i];
@@ -2556,7 +2752,6 @@ isp_intr(arg)
XS_CMD_DONE(xs);
}
}
- ENABLE_INTS(isp);
return (1);
}
@@ -2746,7 +2941,7 @@ isp_parse_async(isp, mbox)
isp->isp_sendmarker = 1;
((fcparam *) isp->isp_param)->isp_loopstate = LOOP_PDB_RCVD;
isp_mark_getpdb_all(isp);
- IDPRINTF(2, ("%s: Port Database Changed\n", isp->isp_name));
+ IDPRINTF(1, ("%s: Port Database Changed\n", isp->isp_name));
break;
case ASYNC_CHANGE_NOTIFY:
@@ -2759,6 +2954,17 @@ isp_parse_async(isp, mbox)
break;
case ASYNC_PTPMODE:
+ if (((fcparam *) isp->isp_param)->isp_onfabric)
+ ((fcparam *) isp->isp_param)->isp_topo = TOPO_N_PORT;
+ else
+ ((fcparam *) isp->isp_param)->isp_topo = TOPO_F_PORT;
+ isp_mark_getpdb_all(isp);
+ isp->isp_sendmarker = 1;
+ ((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
+ ((fcparam *) isp->isp_param)->isp_loopstate = LOOP_LIP_RCVD;
+#ifdef ISP_TARGET_MODE
+ isp_target_async(isp, bus, mbox);
+#endif
PRINTF("%s: Point-to-Point mode\n", isp->isp_name);
break;
@@ -3013,7 +3219,7 @@ isp_parse_status(isp, sp, xs)
case RQCS_ARQS_FAILED:
PRINTF("%s: Auto Request Sense failed for %d.%d.%d\n",
- isp->isp_name, XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
+ isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
return;
case RQCS_WIDE_FAILED:
@@ -3117,309 +3323,279 @@ isp_fastpost_complete(isp, fph)
isp->isp_nactive--;
}
-#define HINIB(x) ((x) >> 0x4)
-#define LONIB(x) ((x) & 0xf)
-#define MAKNIB(a, b) (((a) << 4) | (b))
-static u_int8_t mbpcnt[] = {
- MAKNIB(1, 1), /* 0x00: MBOX_NO_OP */
- MAKNIB(5, 5), /* 0x01: MBOX_LOAD_RAM */
- MAKNIB(2, 0), /* 0x02: MBOX_EXEC_FIRMWARE */
- MAKNIB(5, 5), /* 0x03: MBOX_DUMP_RAM */
- MAKNIB(3, 3), /* 0x04: MBOX_WRITE_RAM_WORD */
- MAKNIB(2, 3), /* 0x05: MBOX_READ_RAM_WORD */
- MAKNIB(6, 6), /* 0x06: MBOX_MAILBOX_REG_TEST */
- MAKNIB(2, 3), /* 0x07: MBOX_VERIFY_CHECKSUM */
- MAKNIB(1, 4), /* 0x08: MBOX_ABOUT_FIRMWARE */
- MAKNIB(0, 0), /* 0x09: */
- MAKNIB(0, 0), /* 0x0a: */
- MAKNIB(0, 0), /* 0x0b: */
- MAKNIB(0, 0), /* 0x0c: */
- MAKNIB(0, 0), /* 0x0d: */
- MAKNIB(1, 2), /* 0x0e: MBOX_CHECK_FIRMWARE */
- MAKNIB(0, 0), /* 0x0f: */
- MAKNIB(5, 5), /* 0x10: MBOX_INIT_REQ_QUEUE */
- MAKNIB(6, 6), /* 0x11: MBOX_INIT_RES_QUEUE */
- MAKNIB(4, 4), /* 0x12: MBOX_EXECUTE_IOCB */
- MAKNIB(2, 2), /* 0x13: MBOX_WAKE_UP */
- MAKNIB(1, 6), /* 0x14: MBOX_STOP_FIRMWARE */
- MAKNIB(4, 4), /* 0x15: MBOX_ABORT */
- MAKNIB(2, 2), /* 0x16: MBOX_ABORT_DEVICE */
- MAKNIB(3, 3), /* 0x17: MBOX_ABORT_TARGET */
- MAKNIB(3, 1), /* 0x18: MBOX_BUS_RESET */
- MAKNIB(2, 3), /* 0x19: MBOX_STOP_QUEUE */
- MAKNIB(2, 3), /* 0x1a: MBOX_START_QUEUE */
- MAKNIB(2, 3), /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
- MAKNIB(2, 3), /* 0x1c: MBOX_ABORT_QUEUE */
- MAKNIB(2, 4), /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
- MAKNIB(0, 0), /* 0x1e: */
- MAKNIB(1, 3), /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
- MAKNIB(1, 4), /* 0x20: MBOX_GET_INIT_SCSI_ID, MBOX_GET_LOOP_ID */
- MAKNIB(1, 3), /* 0x21: MBOX_GET_SELECT_TIMEOUT */
- MAKNIB(1, 3), /* 0x22: MBOX_GET_RETRY_COUNT */
- MAKNIB(1, 2), /* 0x23: MBOX_GET_TAG_AGE_LIMIT */
- MAKNIB(1, 2), /* 0x24: MBOX_GET_CLOCK_RATE */
- MAKNIB(1, 2), /* 0x25: MBOX_GET_ACT_NEG_STATE */
- MAKNIB(1, 2), /* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
- MAKNIB(1, 3), /* 0x27: MBOX_GET_PCI_PARAMS */
- MAKNIB(2, 4), /* 0x28: MBOX_GET_TARGET_PARAMS */
- MAKNIB(2, 4), /* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
- MAKNIB(1, 2), /* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
- MAKNIB(0, 0), /* 0x2b: */
- MAKNIB(0, 0), /* 0x2c: */
- MAKNIB(0, 0), /* 0x2d: */
- MAKNIB(0, 0), /* 0x2e: */
- MAKNIB(0, 0), /* 0x2f: */
- MAKNIB(2, 2), /* 0x30: MBOX_SET_INIT_SCSI_ID */
- MAKNIB(2, 3), /* 0x31: MBOX_SET_SELECT_TIMEOUT */
- MAKNIB(3, 3), /* 0x32: MBOX_SET_RETRY_COUNT */
- MAKNIB(2, 2), /* 0x33: MBOX_SET_TAG_AGE_LIMIT */
- MAKNIB(2, 2), /* 0x34: MBOX_SET_CLOCK_RATE */
- MAKNIB(2, 2), /* 0x35: MBOX_SET_ACT_NEG_STATE */
- MAKNIB(2, 2), /* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
- MAKNIB(3, 3), /* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
- MAKNIB(4, 4), /* 0x38: MBOX_SET_TARGET_PARAMS */
- MAKNIB(4, 4), /* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
- MAKNIB(1, 2), /* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
- MAKNIB(0, 0), /* 0x3b: */
- MAKNIB(0, 0), /* 0x3c: */
- MAKNIB(0, 0), /* 0x3d: */
- MAKNIB(0, 0), /* 0x3e: */
- MAKNIB(0, 0), /* 0x3f: */
- MAKNIB(1, 2), /* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
- MAKNIB(6, 1), /* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
- MAKNIB(2, 3), /* 0x42: MBOX_EXEC_BIOS_IOCB */
- MAKNIB(0, 0), /* 0x43: */
- MAKNIB(0, 0), /* 0x44: */
- MAKNIB(0, 0), /* 0x45: */
- MAKNIB(0, 0), /* 0x46: */
- MAKNIB(0, 0), /* 0x47: */
- MAKNIB(0, 0), /* 0x48: */
- MAKNIB(0, 0), /* 0x49: */
- MAKNIB(2, 1), /* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
- MAKNIB(1, 2), /* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
- MAKNIB(0, 0), /* 0x4c: */
- MAKNIB(0, 0), /* 0x4d: */
- MAKNIB(0, 0), /* 0x4e: */
- MAKNIB(0, 0), /* 0x4f: */
- MAKNIB(0, 0), /* 0x50: */
- MAKNIB(0, 0), /* 0x51: */
- MAKNIB(0, 0), /* 0x52: */
- MAKNIB(0, 0), /* 0x53: */
- MAKNIB(8, 0), /* 0x54: MBOX_EXEC_COMMAND_IOCB_A64 */
- MAKNIB(2, 1), /* 0x55: MBOX_ENABLE_TARGET_MODE */
- MAKNIB(0, 0), /* 0x56: */
- MAKNIB(0, 0), /* 0x57: */
- MAKNIB(0, 0), /* 0x58: */
- MAKNIB(0, 0), /* 0x59: */
- MAKNIB(0, 0), /* 0x5a: */
- MAKNIB(0, 0), /* 0x5b: */
- MAKNIB(0, 0), /* 0x5c: */
- MAKNIB(0, 0), /* 0x5d: */
- MAKNIB(0, 0), /* 0x5e: */
- MAKNIB(0, 0), /* 0x5f: */
- MAKNIB(8, 6), /* 0x60: MBOX_INIT_FIRMWARE */
- MAKNIB(0, 0), /* 0x61: */
- MAKNIB(2, 1), /* 0x62: MBOX_INIT_LIP */
- MAKNIB(8, 1), /* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
- MAKNIB(8, 1), /* 0x64: MBOX_GET_PORT_DB */
- MAKNIB(3, 1), /* 0x65: MBOX_CLEAR_ACA */
- MAKNIB(3, 1), /* 0x66: MBOX_TARGET_RESET */
- MAKNIB(3, 1), /* 0x67: MBOX_CLEAR_TASK_SET */
- MAKNIB(3, 1), /* 0x68: MBOX_ABORT_TASK_SET */
- MAKNIB(1, 2), /* 0x69: MBOX_GET_FW_STATE */
- MAKNIB(2, 8), /* 0x6a: MBOX_GET_PORT_NAME */
- MAKNIB(8, 1), /* 0x6b: MBOX_GET_LINK_STATUS */
- MAKNIB(4, 4), /* 0x6c: MBOX_INIT_LIP_RESET */
- MAKNIB(0, 0), /* 0x6d: */
- MAKNIB(8, 2), /* 0x6e: MBOX_SEND_SNS */
- MAKNIB(4, 3), /* 0x6f: MBOX_FABRIC_LOGIN */
- MAKNIB(2, 1), /* 0x70: MBOX_SEND_CHANGE_REQUEST */
- MAKNIB(2, 1), /* 0x71: MBOX_FABRIC_LOGOUT */
- MAKNIB(4, 1) /* 0x72: MBOX_INIT_LIP_LOGIN */
+#define HIBYT(x) ((x) >> 0x8)
+#define LOBYT(x) ((x) & 0xff)
+#define ISPOPMAP(a, b) (((a) << 8) | (b))
+static u_int16_t mbpscsi[] = {
+ ISPOPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */
+ ISPOPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */
+ ISPOPMAP(0x03, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */
+ ISPOPMAP(0x1f, 0x01), /* 0x03: MBOX_DUMP_RAM */
+ ISPOPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */
+ ISPOPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */
+ ISPOPMAP(0x3f, 0x3f), /* 0x06: MBOX_MAILBOX_REG_TEST */
+ ISPOPMAP(0x03, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */
+ ISPOPMAP(0x01, 0x0f), /* 0x08: MBOX_ABOUT_FIRMWARE */
+ ISPOPMAP(0x00, 0x00), /* 0x09: */
+ ISPOPMAP(0x00, 0x00), /* 0x0a: */
+ ISPOPMAP(0x00, 0x00), /* 0x0b: */
+ ISPOPMAP(0x00, 0x00), /* 0x0c: */
+ ISPOPMAP(0x00, 0x00), /* 0x0d: */
+ ISPOPMAP(0x01, 0x05), /* 0x0e: MBOX_CHECK_FIRMWARE */
+ ISPOPMAP(0x00, 0x00), /* 0x0f: */
+ ISPOPMAP(0x1f, 0x1f), /* 0x10: MBOX_INIT_REQ_QUEUE */
+ ISPOPMAP(0x3f, 0x3f), /* 0x11: MBOX_INIT_RES_QUEUE */
+ ISPOPMAP(0x0f, 0x0f), /* 0x12: MBOX_EXECUTE_IOCB */
+ ISPOPMAP(0x03, 0x03), /* 0x13: MBOX_WAKE_UP */
+ ISPOPMAP(0x01, 0x3f), /* 0x14: MBOX_STOP_FIRMWARE */
+ ISPOPMAP(0x0f, 0x0f), /* 0x15: MBOX_ABORT */
+ ISPOPMAP(0x03, 0x03), /* 0x16: MBOX_ABORT_DEVICE */
+ ISPOPMAP(0x07, 0x07), /* 0x17: MBOX_ABORT_TARGET */
+ ISPOPMAP(0x07, 0x07), /* 0x18: MBOX_BUS_RESET */
+ ISPOPMAP(0x03, 0x07), /* 0x19: MBOX_STOP_QUEUE */
+ ISPOPMAP(0x03, 0x07), /* 0x1a: MBOX_START_QUEUE */
+ ISPOPMAP(0x03, 0x07), /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
+ ISPOPMAP(0x03, 0x07), /* 0x1c: MBOX_ABORT_QUEUE */
+ ISPOPMAP(0x03, 0x4f), /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
+ ISPOPMAP(0x00, 0x00), /* 0x1e: */
+ ISPOPMAP(0x01, 0x07), /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
+ ISPOPMAP(0x01, 0x07), /* 0x20: MBOX_GET_INIT_SCSI_ID */
+ ISPOPMAP(0x01, 0x07), /* 0x21: MBOX_GET_SELECT_TIMEOUT */
+ ISPOPMAP(0x01, 0xc7), /* 0x22: MBOX_GET_RETRY_COUNT */
+ ISPOPMAP(0x01, 0x07), /* 0x23: MBOX_GET_TAG_AGE_LIMIT */
+ ISPOPMAP(0x01, 0x03), /* 0x24: MBOX_GET_CLOCK_RATE */
+ ISPOPMAP(0x01, 0x07), /* 0x25: MBOX_GET_ACT_NEG_STATE */
+ ISPOPMAP(0x01, 0x07), /* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
+ ISPOPMAP(0x01, 0x07), /* 0x27: MBOX_GET_PCI_PARAMS */
+ ISPOPMAP(0x03, 0x4f), /* 0x28: MBOX_GET_TARGET_PARAMS */
+ ISPOPMAP(0x03, 0x0f), /* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
+ ISPOPMAP(0x01, 0x07), /* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
+ ISPOPMAP(0x00, 0x00), /* 0x2b: */
+ ISPOPMAP(0x00, 0x00), /* 0x2c: */
+ ISPOPMAP(0x00, 0x00), /* 0x2d: */
+ ISPOPMAP(0x00, 0x00), /* 0x2e: */
+ ISPOPMAP(0x00, 0x00), /* 0x2f: */
+ ISPOPMAP(0x03, 0x03), /* 0x30: MBOX_SET_INIT_SCSI_ID */
+ ISPOPMAP(0x07, 0x07), /* 0x31: MBOX_SET_SELECT_TIMEOUT */
+ ISPOPMAP(0xc7, 0xc7), /* 0x32: MBOX_SET_RETRY_COUNT */
+ ISPOPMAP(0x07, 0x07), /* 0x33: MBOX_SET_TAG_AGE_LIMIT */
+ ISPOPMAP(0x03, 0x03), /* 0x34: MBOX_SET_CLOCK_RATE */
+ ISPOPMAP(0x07, 0x07), /* 0x35: MBOX_SET_ACT_NEG_STATE */
+ ISPOPMAP(0x07, 0x07), /* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
+ ISPOPMAP(0x07, 0x07), /* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
+ ISPOPMAP(0x4f, 0x4f), /* 0x38: MBOX_SET_TARGET_PARAMS */
+ ISPOPMAP(0x0f, 0x0f), /* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
+ ISPOPMAP(0x07, 0x07), /* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
+ ISPOPMAP(0x00, 0x00), /* 0x3b: */
+ ISPOPMAP(0x00, 0x00), /* 0x3c: */
+ ISPOPMAP(0x00, 0x00), /* 0x3d: */
+ ISPOPMAP(0x00, 0x00), /* 0x3e: */
+ ISPOPMAP(0x00, 0x00), /* 0x3f: */
+ ISPOPMAP(0x01, 0x03), /* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
+ ISPOPMAP(0x3f, 0x01), /* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
+ ISPOPMAP(0x03, 0x07), /* 0x42: MBOX_EXEC_BIOS_IOCB */
+ ISPOPMAP(0x00, 0x00), /* 0x43: */
+ ISPOPMAP(0x00, 0x00), /* 0x44: */
+ ISPOPMAP(0x03, 0x03), /* 0x45: SET SYSTEM PARAMETER */
+ ISPOPMAP(0x01, 0x03), /* 0x46: GET SYSTEM PARAMETER */
+ ISPOPMAP(0x00, 0x00), /* 0x47: */
+ ISPOPMAP(0x01, 0xcf), /* 0x48: GET SCAM CONFIGURATION */
+ ISPOPMAP(0xcf, 0xcf), /* 0x49: SET SCAM CONFIGURATION */
+ ISPOPMAP(0x03, 0x03), /* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
+ ISPOPMAP(0x01, 0x03), /* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
+ ISPOPMAP(0x00, 0x00), /* 0x4c: */
+ ISPOPMAP(0x00, 0x00), /* 0x4d: */
+ ISPOPMAP(0x00, 0x00), /* 0x4e: */
+ ISPOPMAP(0x00, 0x00), /* 0x4f: */
+ ISPOPMAP(0xdf, 0xdf), /* 0x50: LOAD RAM A64 */
+ ISPOPMAP(0xdf, 0xdf), /* 0x51: DUMP RAM A64 */
+ ISPOPMAP(0xdf, 0xdf), /* 0x52: INITIALIZE REQUEST QUEUE A64 */
+ ISPOPMAP(0xff, 0xff), /* 0x53: INITIALIZE RESPONSE QUEUE A64 */
+ ISPOPMAP(0xcf, 0xff), /* 0x54: EXECUTE IOCB A64 */
+ ISPOPMAP(0x03, 0x01), /* 0x55: ENABLE TARGET MODE */
+ ISPOPMAP(0x00, 0x00), /* 0x56: */
+ ISPOPMAP(0x00, 0x00), /* 0x57: */
+ ISPOPMAP(0x00, 0x00), /* 0x58: */
+ ISPOPMAP(0x00, 0x00), /* 0x59: */
+ ISPOPMAP(0x03, 0x03), /* 0x5a: SET DATA OVERRUN RECOVERY MODE */
+ ISPOPMAP(0x01, 0x03), /* 0x5b: GET DATA OVERRUN RECOVERY MODE */
+ ISPOPMAP(0x0f, 0x0f), /* 0x5c: SET HOST DATA */
+ ISPOPMAP(0x01, 0x01) /* 0x5d: GET NOST DATA */
+};
+
+static u_int16_t mbpfc[] = {
+ ISPOPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */
+ ISPOPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */
+ ISPOPMAP(0x03, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */
+ ISPOPMAP(0x1f, 0x01), /* 0x03: MBOX_DUMP_RAM */
+ ISPOPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */
+ ISPOPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */
+ ISPOPMAP(0xff, 0xff), /* 0x06: MBOX_MAILBOX_REG_TEST */
+ ISPOPMAP(0x03, 0x05), /* 0x07: MBOX_VERIFY_CHECKSUM */
+ ISPOPMAP(0x01, 0x0f), /* 0x08: MBOX_ABOUT_FIRMWARE */
+ ISPOPMAP(0xdf, 0x01), /* 0x09: LOAD RAM */
+ ISPOPMAP(0xdf, 0x01), /* 0x0a: DUMP RAM */
+ ISPOPMAP(0x00, 0x00), /* 0x0b: */
+ ISPOPMAP(0x00, 0x00), /* 0x0c: */
+ ISPOPMAP(0x00, 0x00), /* 0x0d: */
+ ISPOPMAP(0x01, 0x05), /* 0x0e: MBOX_CHECK_FIRMWARE */
+ ISPOPMAP(0x00, 0x00), /* 0x0f: */
+ ISPOPMAP(0x1f, 0x11), /* 0x10: MBOX_INIT_REQ_QUEUE */
+ ISPOPMAP(0x2f, 0x21), /* 0x11: MBOX_INIT_RES_QUEUE */
+ ISPOPMAP(0x0f, 0x01), /* 0x12: MBOX_EXECUTE_IOCB */
+ ISPOPMAP(0x03, 0x03), /* 0x13: MBOX_WAKE_UP */
+ ISPOPMAP(0x01, 0xff), /* 0x14: MBOX_STOP_FIRMWARE */
+ ISPOPMAP(0x4f, 0x01), /* 0x15: MBOX_ABORT */
+ ISPOPMAP(0x07, 0x01), /* 0x16: MBOX_ABORT_DEVICE */
+ ISPOPMAP(0x07, 0x01), /* 0x17: MBOX_ABORT_TARGET */
+ ISPOPMAP(0x03, 0x03), /* 0x18: MBOX_BUS_RESET */
+ ISPOPMAP(0x07, 0x05), /* 0x19: MBOX_STOP_QUEUE */
+ ISPOPMAP(0x07, 0x05), /* 0x1a: MBOX_START_QUEUE */
+ ISPOPMAP(0x07, 0x05), /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
+ ISPOPMAP(0x07, 0x05), /* 0x1c: MBOX_ABORT_QUEUE */
+ ISPOPMAP(0x07, 0x03), /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
+ ISPOPMAP(0x00, 0x00), /* 0x1e: */
+ ISPOPMAP(0x01, 0x07), /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
+ ISPOPMAP(0x01, 0x4f), /* 0x20: MBOX_GET_LOOP_ID */
+ ISPOPMAP(0x00, 0x00), /* 0x21: */
+ ISPOPMAP(0x01, 0x07), /* 0x22: MBOX_GET_RETRY_COUNT */
+ ISPOPMAP(0x00, 0x00), /* 0x23: */
+ ISPOPMAP(0x00, 0x00), /* 0x24: */
+ ISPOPMAP(0x00, 0x00), /* 0x25: */
+ ISPOPMAP(0x00, 0x00), /* 0x26: */
+ ISPOPMAP(0x00, 0x00), /* 0x27: */
+ ISPOPMAP(0x0f, 0x1), /* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
+ ISPOPMAP(0x03, 0x07), /* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
+ ISPOPMAP(0x00, 0x00), /* 0x2a: */
+ ISPOPMAP(0x00, 0x00), /* 0x2b: */
+ ISPOPMAP(0x00, 0x00), /* 0x2c: */
+ ISPOPMAP(0x00, 0x00), /* 0x2d: */
+ ISPOPMAP(0x00, 0x00), /* 0x2e: */
+ ISPOPMAP(0x00, 0x00), /* 0x2f: */
+ ISPOPMAP(0x00, 0x00), /* 0x30: */
+ ISPOPMAP(0x00, 0x00), /* 0x31: */
+ ISPOPMAP(0x07, 0x07), /* 0x32: MBOX_SET_RETRY_COUNT */
+ ISPOPMAP(0x00, 0x00), /* 0x33: */
+ ISPOPMAP(0x00, 0x00), /* 0x34: */
+ ISPOPMAP(0x00, 0x00), /* 0x35: */
+ ISPOPMAP(0x00, 0x00), /* 0x36: */
+ ISPOPMAP(0x00, 0x00), /* 0x37: */
+ ISPOPMAP(0x0f, 0x01), /* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
+ ISPOPMAP(0x0f, 0x07), /* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
+ ISPOPMAP(0x00, 0x00), /* 0x3a: */
+ ISPOPMAP(0x00, 0x00), /* 0x3b: */
+ ISPOPMAP(0x00, 0x00), /* 0x3c: */
+ ISPOPMAP(0x00, 0x00), /* 0x3d: */
+ ISPOPMAP(0x00, 0x00), /* 0x3e: */
+ ISPOPMAP(0x00, 0x00), /* 0x3f: */
+ ISPOPMAP(0x03, 0x01), /* 0x40: MBOX_LOOP_PORT_BYPASS */
+ ISPOPMAP(0x03, 0x01), /* 0x41: MBOX_LOOP_PORT_ENABLE */
+ ISPOPMAP(0x03, 0x07), /* 0x42: MBOX_GET_RESOURCE_COUNTS */
+ ISPOPMAP(0x01, 0x01), /* 0x43: MBOX_REQUEST_NON_PARTICIPATING_MODE */
+ ISPOPMAP(0x00, 0x00), /* 0x44: */
+ ISPOPMAP(0x00, 0x00), /* 0x45: */
+ ISPOPMAP(0x00, 0x00), /* 0x46: */
+ ISPOPMAP(0xcf, 0x03), /* 0x47: GET PORT_DATABASE ENHANCED */
+ ISPOPMAP(0x00, 0x00), /* 0x48: */
+ ISPOPMAP(0x00, 0x00), /* 0x49: */
+ ISPOPMAP(0x00, 0x00), /* 0x4a: */
+ ISPOPMAP(0x00, 0x00), /* 0x4b: */
+ ISPOPMAP(0x00, 0x00), /* 0x4c: */
+ ISPOPMAP(0x00, 0x00), /* 0x4d: */
+ ISPOPMAP(0x00, 0x00), /* 0x4e: */
+ ISPOPMAP(0x00, 0x00), /* 0x4f: */
+ ISPOPMAP(0x00, 0x00), /* 0x50: */
+ ISPOPMAP(0x00, 0x00), /* 0x51: */
+ ISPOPMAP(0x00, 0x00), /* 0x52: */
+ ISPOPMAP(0x00, 0x00), /* 0x53: */
+ ISPOPMAP(0xcf, 0x01), /* 0x54: EXECUTE IOCB A64 */
+ ISPOPMAP(0x00, 0x00), /* 0x55: */
+ ISPOPMAP(0x00, 0x00), /* 0x56: */
+ ISPOPMAP(0x00, 0x00), /* 0x57: */
+ ISPOPMAP(0x00, 0x00), /* 0x58: */
+ ISPOPMAP(0x00, 0x00), /* 0x59: */
+ ISPOPMAP(0x00, 0x00), /* 0x5a: */
+ ISPOPMAP(0x00, 0x00), /* 0x5b: */
+ ISPOPMAP(0x00, 0x00), /* 0x5c: */
+ ISPOPMAP(0x00, 0x00), /* 0x5d: */
+ ISPOPMAP(0x00, 0x00), /* 0x5e: */
+ ISPOPMAP(0x00, 0x00), /* 0x5f: */
+ ISPOPMAP(0xfd, 0x31), /* 0x60: MBOX_INIT_FIRMWARE */
+ ISPOPMAP(0x00, 0x00), /* 0x61: */
+ ISPOPMAP(0x01, 0x01), /* 0x62: MBOX_INIT_LIP */
+ ISPOPMAP(0xcd, 0x03), /* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
+ ISPOPMAP(0xcf, 0x01), /* 0x64: MBOX_GET_PORT_DB */
+ ISPOPMAP(0x07, 0x01), /* 0x65: MBOX_CLEAR_ACA */
+ ISPOPMAP(0x07, 0x01), /* 0x66: MBOX_TARGET_RESET */
+ ISPOPMAP(0x07, 0x01), /* 0x67: MBOX_CLEAR_TASK_SET */
+ ISPOPMAP(0x07, 0x01), /* 0x68: MBOX_ABORT_TASK_SET */
+ ISPOPMAP(0x01, 0x07), /* 0x69: MBOX_GET_FW_STATE */
+ ISPOPMAP(0x03, 0xcf), /* 0x6a: MBOX_GET_PORT_NAME */
+ ISPOPMAP(0xcf, 0x01), /* 0x6b: MBOX_GET_LINK_STATUS */
+ ISPOPMAP(0x0f, 0x01), /* 0x6c: MBOX_INIT_LIP_RESET */
+ ISPOPMAP(0x00, 0x00), /* 0x6d: */
+ ISPOPMAP(0xcf, 0x03), /* 0x6e: MBOX_SEND_SNS */
+ ISPOPMAP(0x0f, 0x07), /* 0x6f: MBOX_FABRIC_LOGIN */
+ ISPOPMAP(0x03, 0x01), /* 0x70: MBOX_SEND_CHANGE_REQUEST */
+ ISPOPMAP(0x03, 0x03), /* 0x71: MBOX_FABRIC_LOGOUT */
+ ISPOPMAP(0x0f, 0x0f), /* 0x72: MBOX_INIT_LIP_LOGIN */
+ ISPOPMAP(0x00, 0x00), /* 0x73: */
+ ISPOPMAP(0x07, 0x01), /* 0x74: LOGIN LOOP PORT */
+ ISPOPMAP(0xcf, 0x03), /* 0x75: GET PORT/NODE NAME LIST */
+ ISPOPMAP(0x4f, 0x01), /* 0x76: SET VENDOR ID */
+ ISPOPMAP(0xcd, 0x01), /* 0x77: INITIALIZE IP MAILBOX */
+ ISPOPMAP(0x00, 0x00), /* 0x78: */
+ ISPOPMAP(0x00, 0x00), /* 0x79: */
+ ISPOPMAP(0x00, 0x00), /* 0x7a: */
+ ISPOPMAP(0x00, 0x00), /* 0x7b: */
+ ISPOPMAP(0x4f, 0x03), /* 0x7c: Get ID List */
+ ISPOPMAP(0xcf, 0x01), /* 0x7d: SEND LFA */
+ ISPOPMAP(0x07, 0x01) /* 0x7e: Lun RESET */
};
-#define NMBCOM (sizeof (mbpcnt) / sizeof (mbpcnt[0]))
static void
isp_mboxcmd(isp, mbp)
struct ispsoftc *isp;
mbreg_t *mbp;
{
- int outparam, inparam;
- int loops, dld = 0;
- u_int8_t opcode;
-
- if (mbp->param[0] == ISP2100_SET_PCI_PARAM) {
- opcode = mbp->param[0] = MBOX_SET_PCI_PARAMETERS;
- inparam = 4;
- outparam = 4;
- goto command_known;
- } else if (mbp->param[0] > NMBCOM) {
- PRINTF("%s: bad command %x\n", isp->isp_name, mbp->param[0]);
- return;
- }
-
- opcode = mbp->param[0];
- inparam = HINIB(mbpcnt[mbp->param[0]]);
- outparam = LONIB(mbpcnt[mbp->param[0]]);
+ unsigned int lim, ibits, obits, box, opcode;
+ u_int16_t *mcp;
- if (inparam == 0 && outparam == 0) {
- PRINTF("%s: no parameters for %x\n", isp->isp_name,
- mbp->param[0]);
- return;
- }
-
-
- /*
- * Check for variants
- */
-#ifdef ISP2100_SCCLUN
if (IS_FC(isp)) {
- switch (mbp->param[0]) {
- case MBOX_ABORT:
- inparam = 7;
- break;
- case MBOX_ABORT_DEVICE:
- case MBOX_START_QUEUE:
- case MBOX_STOP_QUEUE:
- case MBOX_SINGLE_STEP_QUEUE:
- case MBOX_ABORT_QUEUE:
- case MBOX_GET_DEV_QUEUE_STATUS:
- inparam = 3;
- break;
- case MBOX_BUS_RESET:
- inparam = 2;
- break;
- default:
- break;
- }
+ mcp = mbpfc;
+ lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
+ } else {
+ mcp = mbpscsi;
+ lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
}
-#endif
-
-command_known:
-
- /*
- * Set semaphore on mailbox registers to win any races to acquire them.
- */
- 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.
- */
+ if ((opcode = mbp->param[0]) >= lim) {
+ mbp->param[0] = MBOX_INVALID_COMMAND;
+ PRINTF("%s: unknown command 0x%x\n", isp->isp_name, opcode);
+ return;
+ }
- /*
- * Make sure we can send some words.
- * Check to see if there's an async mbox event pending.
- */
+ ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
+ obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
- loops = MBOX_DELAY_COUNT;
- while ((ISP_READ(isp, HCCR) & HCCR_HOST_INT) != 0) {
- if (ISP_READ(isp, BIU_SEMA) & 1) {
- int fph;
- u_int16_t mbox = ISP_READ(isp, OUTMAILBOX0);
- /*
- * We have a pending MBOX async event.
- */
- if (mbox & 0x8000) {
- fph = isp_parse_async(isp, (int) mbox);
- IDPRINTF(5, ("%s: line %d, fph %d\n",
- isp->isp_name, __LINE__, fph));
- ISP_WRITE(isp, BIU_SEMA, 0);
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- if (fph < 0) {
- return;
- } else if (fph > 0) {
- isp_fastpost_complete(isp, fph);
- }
- SYS_DELAY(100);
- goto command_known;
- }
- /*
- * We have a pending MBOX completion? Might be
- * from a previous command. We can't (sometimes)
- * just clear HOST INTERRUPT, so we'll just silently
- * eat this here.
- */
- if (mbox & 0x4000) {
- IDPRINTF(5, ("%s: line %d, mbox 0x%x\n",
- isp->isp_name, __LINE__, mbox));
- ISP_WRITE(isp, BIU_SEMA, 0);
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- SYS_DELAY(100);
- goto command_known;
- }
- }
- SYS_DELAY(100);
- if (--loops < 0) {
- if (dld++ > 10) {
- PRINTF("%s: isp_mboxcmd could not get command "
- "started\n", isp->isp_name);
- return;
- }
- ISP_WRITE(isp, BIU_SEMA, 0);
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- goto command_known;
- }
+ if (ibits == 0 && obits == 0) {
+ mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
+ PRINTF("%s: no parameters for opcode 0x%x\n", isp->isp_name,
+ opcode);
+ return;
}
- /*
- * Write input parameters.
- *
- * Special case some of the setups for the dual port SCSI cards.
- * XXX Eventually will be fixed by converting register write/read
- * XXX counts to bitmasks.
- */
- if (IS_DUALBUS(isp)) {
- switch (opcode) {
- case MBOX_GET_RETRY_COUNT:
- case MBOX_SET_RETRY_COUNT:
- ISP_WRITE(isp, INMAILBOX7, mbp->param[7]);
- mbp->param[7] = 0;
- ISP_WRITE(isp, INMAILBOX6, mbp->param[6]);
- mbp->param[6] = 0;
- break;
- case MBOX_SET_ASYNC_DATA_SETUP_TIME:
- case MBOX_SET_ACT_NEG_STATE:
- case MBOX_SET_TAG_AGE_LIMIT:
- case MBOX_SET_SELECT_TIMEOUT:
- ISP_WRITE(isp, INMAILBOX2, mbp->param[2]);
- mbp->param[2] = 0;
- break;
+ for (box = 0; box < MAX_MAILBOX; box++) {
+ if (ibits & (1 << box)) {
+ ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
}
- }
-
- switch (inparam) {
- case 8: ISP_WRITE(isp, INMAILBOX7, mbp->param[7]); mbp->param[7] = 0;
- case 7: ISP_WRITE(isp, INMAILBOX6, mbp->param[6]); mbp->param[6] = 0;
- case 6:
- /*
- * The Qlogic 2100 cannot have registers 4 and 5 written to
- * after initialization or BAD THINGS HAPPEN (tm).
- */
- if (IS_SCSI(isp) || mbp->param[0] == MBOX_INIT_FIRMWARE)
- ISP_WRITE(isp, INMAILBOX5, mbp->param[5]);
- mbp->param[5] = 0;
- case 5:
- if (IS_SCSI(isp) || mbp->param[0] == MBOX_INIT_FIRMWARE)
- ISP_WRITE(isp, INMAILBOX4, mbp->param[4]);
- mbp->param[4] = 0;
- case 4: ISP_WRITE(isp, INMAILBOX3, mbp->param[3]); mbp->param[3] = 0;
- case 3: ISP_WRITE(isp, INMAILBOX2, mbp->param[2]); mbp->param[2] = 0;
- case 2: ISP_WRITE(isp, INMAILBOX1, mbp->param[1]); mbp->param[1] = 0;
- case 1: ISP_WRITE(isp, INMAILBOX0, mbp->param[0]); mbp->param[0] = 0;
+ isp->isp_mboxtmp[box] = mbp->param[box] = 0;
}
/*
- * Clear RISC int condition.
+ * We assume that we can't overwrite a previous command.
*/
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
-
- /*
- * Clear semaphore on mailbox registers so that the Qlogic
- * may update outgoing registers.
- */
- ISP_WRITE(isp, BIU_SEMA, 0);
+ isp->isp_mboxbsy = obits;
/*
* Set Host Interrupt condition so that RISC will pick up mailbox regs.
@@ -3427,121 +3603,25 @@ command_known:
ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
/*
- * Wait until HOST INT has gone away (meaning that the Qlogic
- * has picked up the mailbox command. Wait a long time.
+ * Give the f/w a chance to pick this up.
*/
- loops = MBOX_DELAY_COUNT * 5;
- while ((ISP_READ(isp, HCCR) & HCCR_CMD_CLEAR_RISC_INT) != 0) {
- SYS_DELAY(100);
- if (--loops < 0) {
- PRINTF("%s: isp_mboxcmd timeout #2\n", isp->isp_name);
- return;
- }
- }
+ SYS_DELAY(250);
- /*
- * While the Semaphore registers isn't set, wait for the Qlogic
- * to process the mailbox command. Again- wait a long time.
- */
- loops = MBOX_DELAY_COUNT * 5;
- while ((ISP_READ(isp, BIU_SEMA) & 1) == 0) {
- SYS_DELAY(100);
- /*
- * Wierd- I've seen the case where the semaphore register
- * isn't getting set- sort of a violation of the protocol..
- */
- if (ISP_READ(isp, OUTMAILBOX0) & 0x4000)
- break;
- if (--loops < 0) {
- PRINTF("%s: isp_mboxcmd timeout #3\n", isp->isp_name);
- return;
- }
- }
/*
- * Make sure that the MBOX_BUSY has gone away
+ * While we haven't finished the command, spin our wheels here.
*/
- loops = MBOX_DELAY_COUNT;
- for (;;) {
- u_int16_t mbox = ISP_READ(isp, OUTMAILBOX0);
- if (mbox == MBOX_BUSY) {
- if (--loops < 0) {
- PRINTF("%s: isp_mboxcmd timeout #4\n",
- isp->isp_name);
- return;
- }
- SYS_DELAY(100);
- continue;
- }
- /*
- * We have a pending MBOX async event.
- */
- if (mbox & 0x8000) {
- int fph = isp_parse_async(isp, (int) mbox);
- ISP_WRITE(isp, BIU_SEMA, 0);
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- if (fph < 0) {
- return;
- } else if (fph > 0) {
- isp_fastpost_complete(isp, fph);
- }
- SYS_DELAY(100);
- continue;
- }
- break;
- }
+ MBOX_WAIT_COMPLETE(isp);
/*
- * Pick up output parameters. Special case some of the readbacks
- * for the dual port SCSI cards.
+ * Copy back output registers.
*/
- if (IS_DUALBUS(isp)) {
- switch (opcode) {
- case MBOX_GET_RETRY_COUNT:
- case MBOX_SET_RETRY_COUNT:
- mbp->param[7] = ISP_READ(isp, OUTMAILBOX7);
- mbp->param[6] = ISP_READ(isp, OUTMAILBOX6);
- break;
- case MBOX_GET_TAG_AGE_LIMIT:
- case MBOX_SET_TAG_AGE_LIMIT:
- case MBOX_GET_ACT_NEG_STATE:
- case MBOX_SET_ACT_NEG_STATE:
- case MBOX_SET_ASYNC_DATA_SETUP_TIME:
- case MBOX_GET_ASYNC_DATA_SETUP_TIME:
- case MBOX_GET_RESET_DELAY_PARAMS:
- case MBOX_SET_RESET_DELAY_PARAMS:
- mbp->param[2] = ISP_READ(isp, OUTMAILBOX2);
- break;
- }
- }
-
- if (IS_2200(isp)) {
- if (opcode == MBOX_GET_LOOP_ID) {
- mbp->param[6] = ISP_READ(isp, OUTMAILBOX6);
+ for (box = 0; box < MAX_MAILBOX; box++) {
+ if (obits & (1 << box)) {
+ mbp->param[box] = isp->isp_mboxtmp[box];
}
}
- switch (outparam) {
- case 8: mbp->param[7] = ISP_READ(isp, OUTMAILBOX7);
- case 7: mbp->param[6] = ISP_READ(isp, OUTMAILBOX6);
- case 6: mbp->param[5] = ISP_READ(isp, OUTMAILBOX5);
- case 5: mbp->param[4] = ISP_READ(isp, OUTMAILBOX4);
- case 4: mbp->param[3] = ISP_READ(isp, OUTMAILBOX3);
- case 3: mbp->param[2] = ISP_READ(isp, OUTMAILBOX2);
- case 2: mbp->param[1] = ISP_READ(isp, OUTMAILBOX1);
- case 1: mbp->param[0] = ISP_READ(isp, OUTMAILBOX0);
- }
-
- /*
- * Clear RISC int.
- */
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
-
- /*
- * Release semaphore on mailbox registers
- */
- ISP_WRITE(isp, BIU_SEMA, 0);
-
/*
* Just to be chatty here...
*/
@@ -3582,30 +3662,6 @@ command_known:
case MBOX_ALL_IDS_USED:
break;
-
- /*
- * Be silent about these...
- */
- case ASYNC_PDB_CHANGED:
- ((fcparam *) isp->isp_param)->isp_loopstate = LOOP_PDB_RCVD;
- break;
-
- case ASYNC_LIP_OCCURRED:
- ((fcparam *) isp->isp_param)->isp_lipseq = mbp->param[1];
- /* FALLTHROUGH */
- case ASYNC_LOOP_UP:
- ((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
- ((fcparam *) isp->isp_param)->isp_loopstate = LOOP_LIP_RCVD;
- break;
-
- case ASYNC_LOOP_DOWN:
- case ASYNC_LOOP_RESET:
- ((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
- ((fcparam *) isp->isp_param)->isp_loopstate = LOOP_NIL;
- /* FALLTHROUGH */
- case ASYNC_CHANGE_NOTIFY:
- break;
-
default:
/*
* The expected return of EXEC_FIRMWARE is zero.
@@ -3778,7 +3834,7 @@ isp_update_bus(isp, bus)
int get;
if (sdp->isp_devparam[tgt].dev_enable == 0) {
- IDPRINTF(1, ("%s: skipping target %d bus %d update\n",
+ IDPRINTF(2, ("%s: skipping target %d bus %d update\n",
isp->isp_name, tgt, bus));
continue;
}
@@ -3877,15 +3933,23 @@ isp_setdfltparm(isp, channel)
/* Platform specific.... */
fcp->isp_loopid = DEFAULT_LOOPID(isp);
fcp->isp_nodewwn = DEFAULT_WWN(isp);
- fcp->isp_portwwn = 0;
+ if ((fcp->isp_nodewwn >> 60) == 2) {
+ fcp->isp_nodewwn &= ~((u_int64_t) 0xfff << 48);
+ fcp->isp_portwwn = fcp->isp_nodewwn |
+ (((u_int64_t)(isp->isp_unit+1)) << 48);
+ } else {
+ fcp->isp_portwwn = fcp->isp_nodewwn;
+ }
/*
* Now try and read NVRAM
*/
if ((isp->isp_confopts & (ISP_CFG_NONVRAM|ISP_CFG_OWNWWN)) ||
(isp_read_nvram(isp))) {
- PRINTF("%s: using Node WWN 0x%08x%08x\n",
- isp->isp_name, (u_int32_t)(fcp->isp_nodewwn >> 32),
- (u_int32_t)(fcp->isp_nodewwn & 0xffffffff));
+ PRINTF("%s: Node WWN 0x%08x%08x, Port WWN 0x%08x%08x\n",
+ isp->isp_name, (u_int32_t) (fcp->isp_nodewwn >> 32),
+ (u_int32_t) (fcp->isp_nodewwn & 0xffffffff),
+ (u_int32_t) (fcp->isp_portwwn >> 32),
+ (u_int32_t) (fcp->isp_portwwn & 0xffffffff));
}
return;
}
@@ -3958,7 +4022,8 @@ isp_setdfltparm(isp, channel)
isp->isp_type < ISP_HA_SCSI_1020A) ||
(isp->isp_bustype == ISP_BT_PCI &&
isp->isp_type < ISP_HA_SCSI_1040) ||
- (isp->isp_clock && isp->isp_clock < 60)) {
+ (isp->isp_clock && isp->isp_clock < 60) ||
+ (sdp->isp_ultramode == 0)) {
sdp->isp_devparam[tgt].sync_offset =
ISP_10M_SYNCPARMS >> 8;
sdp->isp_devparam[tgt].sync_period =
@@ -4067,9 +4132,6 @@ isp_restart(isp)
ISP_SCSI_XFER_T *xs;
u_int32_t handle;
-#if 0
- isp->isp_gotdparms = 0;
-#endif
isp_reset(isp);
if (isp->isp_state == ISP_RESETSTATE) {
isp_init(isp);
@@ -4668,39 +4730,42 @@ isp_parse_nvram_2100(isp, nvram_data)
u_int64_t full64;
} wwnstore;
- wwnstore.full64 = ISP2100_NVRAM_NODE_NAME(nvram_data);
-
/*
- * Broken PTI cards with nothing in the top nibble. Pah.
+ * There is supposed to be WWNN storage as distinct
+ * from WWPN storage in NVRAM, but it doesn't appear
+ * to be used sanely.
*/
- if ((wwnstore.wd.hi32 >> 28) == 0) {
- wwnstore.wd.hi32 |= (2 << 28);
- CFGPRINTF("%s: (corrected) Adapter WWN 0x%08x%08x\n",
- isp->isp_name, wwnstore.wd.hi32, wwnstore.wd.lo32);
- } else {
- CFGPRINTF("%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
- * our unit number (plus one to make it nonzero) and
- * putting it into bits 59..56. If the top nibble isn't
- * 2, then we just set them identically.
- */
- if ((fcp->isp_nodewwn >> 60) == 2) {
- fcp->isp_portwwn = fcp->isp_nodewwn |
- (((u_int64_t)(isp->isp_unit+1)) << 56);
- } else {
- fcp->isp_portwwn = fcp->isp_nodewwn;
- }
- 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.wd.hi32, wwnstore.wd.lo32);
+ wwnstore.full64 = ISP2100_NVRAM_PORT_NAME(nvram_data);
+ if (wwnstore.full64 != 0LL) {
+ switch ((int) (wwnstore.full64 >> 60)) {
+ case 0:
+ /*
+ * Broken cards with nothing in the top nibble.
+ * Pah.
+ */
+ wwnstore.full64 |= (2LL << 60);
+ /* FALLTHROUGH */
+ case 2:
+ fcp->isp_portwwn = wwnstore.full64;
+ fcp->isp_nodewwn = wwnstore.full64;
+ fcp->isp_nodewwn &= ~((0xfffLL) << 48);
+ if (fcp->isp_nodewwn == fcp->isp_portwwn) {
+ fcp->isp_portwwn |=
+ (((u_int64_t)(isp->isp_unit+1)) << 48);
+ }
+ break;
+ default:
+ fcp->isp_portwwn = wwnstore.full64;
+ fcp->isp_nodewwn = wwnstore.full64;
+ }
}
+ CFGPRINTF("%s: Node WWN 0x%08x%08x, Port WWN 0x%08x%08x\n",
+ isp->isp_name, (u_int32_t) (fcp->isp_nodewwn >> 32),
+ (u_int32_t) (fcp->isp_nodewwn & 0xffffffff),
+ (u_int32_t) (fcp->isp_portwwn >> 32),
+ (u_int32_t) (fcp->isp_portwwn & 0xffffffff));
+
fcp->isp_maxalloc =
ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
fcp->isp_maxfrmlen =