summaryrefslogtreecommitdiff
path: root/sys/dev/ic/isp.c
diff options
context:
space:
mode:
authormjacob <mjacob@cvs.openbsd.org>2000-02-20 21:22:42 +0000
committermjacob <mjacob@cvs.openbsd.org>2000-02-20 21:22:42 +0000
commit843be39a687253a9894847550ed56ea58510c179 (patch)
tree5ba8385712451adffcce024f1c84487e320e5d2d /sys/dev/ic/isp.c
parent507037610dbda92ebe936b00eda0be017503a7d8 (diff)
Add 12160 (Ultra3) support. Add files and changes for target mode support.
Do some SNS fabric suppor tchanges. Roll revision levels. Tested on GENERIC i386 && sparc.
Diffstat (limited to 'sys/dev/ic/isp.c')
-rw-r--r--sys/dev/ic/isp.c1184
1 files changed, 735 insertions, 449 deletions
diff --git a/sys/dev/ic/isp.c b/sys/dev/ic/isp.c
index e5eaeb54805..c7303a59778 100644
--- a/sys/dev/ic/isp.c
+++ b/sys/dev/ic/isp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isp.c,v 1.12 2000/01/09 22:44:27 mjacob Exp $ */
+/* $OpenBSD: isp.c,v 1.13 2000/02/20 21:22:40 mjacob Exp $ */
/*
* Machine and OS Independent (well, as best as possible)
* code for the Qlogic ISP SCSI adapters.
@@ -95,6 +95,11 @@ static void isp_update_bus __P((struct ispsoftc *, int));
static void isp_setdfltparm __P((struct ispsoftc *, int));
static int isp_read_nvram __P((struct ispsoftc *));
static void isp_rdnvram_word __P((struct ispsoftc *, int, u_int16_t *));
+static void isp_parse_nvram_1020 __P((struct ispsoftc *, u_int8_t *));
+static void isp_parse_nvram_1080 __P((struct ispsoftc *, int, u_int8_t *));
+static void isp_parse_nvram_12160 __P((struct ispsoftc *, int, u_int8_t *));
+static void isp_parse_nvram_2100 __P((struct ispsoftc *, u_int8_t *));
+
/*
* Reset Hardware.
@@ -188,7 +193,15 @@ isp_reset(isp)
isp->isp_clock = 100;
- revname = "1080";
+ if (IS_1280(isp))
+ revname = "1280";
+ else if (IS_1080(isp))
+ revname = "1080";
+ else if (IS_12160(isp))
+ revname = "12160";
+ else
+ revname = "<UNKLVD>";
+
l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
switch (l) {
case ISP1080_LVD_MODE:
@@ -209,9 +222,8 @@ isp_reset(isp)
break;
}
- if (IS_1280(isp)) {
+ if (IS_DUALBUS(isp)) {
sdp++;
- revname[1] = '2';
l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
l &= ISP1080_MODE_MASK;
switch(l) {
@@ -793,22 +805,16 @@ isp_scsi_init(isp)
*
* Ultra2 F/W always has had fast posting (and LVD transitions)
*
- * Ultra and older (i.e., SBus) cards may not. Assume SBus cards
- * do not, and only guess that 4.55.0 <= x < 5.0.0 (initiator
- * only) and x >= 7.55 (initiator/target) has fast posting.
+ * Ultra and older (i.e., SBus) cards may not. It's just safer
+ * to assume not for them.
*/
mbs.param[0] = MBOX_SET_FW_FEATURES;
mbs.param[1] = 0;
if (IS_ULTRA2(isp))
mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
-#ifndef ISP_NO_FASTPOST_SCSI
- if ((ISP_FW_REVX(isp->isp_fwrev) >= 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_REV(7, 55, 0))) {
+ if (IS_ULTRA2(isp) || IS_1240(isp))
mbs.param[1] |= FW_FEATURE_FAST_POST;
- }
-#endif
if (mbs.param[1] != 0) {
u_int16_t sfeat = mbs.param[1];
isp_mboxcmd(isp, &mbs);
@@ -1007,7 +1013,6 @@ isp_fibre_init(isp)
#else
fcp->isp_fwoptions = 0;
#endif
-
fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
/*
* If this is a 2100 < revision 5, we have to turn off FAIRNESS.
@@ -1059,7 +1064,19 @@ 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 */
+#ifdef PRET_A_PORTE
+ if (IS_2200(isp)) {
+ icbp->icb_fwoptions |= ICBOPT_EXTENDED;
+ /*
+ * Prefer or force Point-To-Point instead Loop?
+ */
+ if (isp->isp_confopts & ISP_CFG_NPORT)
+ icbp->icb_xfwoptions = ICBXOPT_PTP_2_LOOP;
+ else
+ icbp->icb_xfwoptions = ICBXOPT_LOOP_2_PTP;
+ }
+#endif
+ icbp->icb_logintime = 60; /* 60 second login timeout */
if (fcp->isp_nodewwn) {
u_int64_t pn;
@@ -1238,7 +1255,6 @@ isp_fclink_test(isp, waitdelay)
"N-Port to N-Port",
"F Port"
};
- char *tname;
mbreg_t mbs;
int count, topo = -1;
u_int8_t lwfs;
@@ -1283,19 +1299,13 @@ isp_fclink_test(isp, waitdelay)
return (-1);
}
fcp->isp_loopid = mbs.param[1];
- if (isp->isp_type == ISP_HA_FC_2200) {
- if (ISP_FW_REVX(isp->isp_fwrev) >= ISP_FW_REV(2, 0, 14)) {
- topo = (int) mbs.param[6];
- }
- } else if (isp->isp_type == ISP_HA_FC_2100) {
- if (ISP_FW_REVX(isp->isp_fwrev) >= ISP_FW_REV(1, 17, 26)) {
- topo = (int) mbs.param[6];
- }
+ if (IS_2200(isp)) {
+ topo = (int) mbs.param[6];
+ if (topo < 0 || topo > 3)
+ topo = 0;
+ } else {
+ topo = 0;
}
- if (topo < 0 || topo > 3)
- tname = "unknown";
- else
- tname = toponames[topo];
/*
* If we're not on a fabric, the low 8 bits will be our AL_PA.
@@ -1305,11 +1315,16 @@ isp_fclink_test(isp, waitdelay)
#if defined(ISP2100_FABRIC)
fcp->isp_onfabric = 0;
if (isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
+
+ if (IS_2100(isp))
+ topo = 1;
+
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, tname);
+ "0x%x topology '%s'\n", isp->isp_name, fcp->isp_loopid,
+ fcp->isp_alpa, fcp->isp_portid, fcp->isp_loopstate,
+ toponames[topo]);
/*
* Make sure we're logged out of all fabric devices.
@@ -1329,10 +1344,9 @@ isp_fclink_test(isp, waitdelay)
}
} else
#endif
- CFGPRINTF("%s: Loop ID %d, ALPA 0x%x Loop State 0x%x topology %s\n",
+ 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,
- tname);
- fcp->loop_seen_once = 1;
+ toponames[topo]);
return (0);
}
@@ -1394,6 +1408,7 @@ isp_pdb_sync(isp, target)
* FL_PORT_ID times).
*/
tport = fcp->tport;
+
/*
* make sure the temp port database is clean...
*/
@@ -1466,7 +1481,7 @@ isp_pdb_sync(isp, target)
* use) and then compare it to our saved database which
* never shifts.
*/
- if (isp_same_lportdb(lp, &fcp->portdb[target])) {
+ if (target >= 0 && isp_same_lportdb(lp, &fcp->portdb[target])) {
lp->valid = 1;
}
}
@@ -1635,8 +1650,9 @@ isp_pdb_sync(isp, target)
/*
* Now log in any fabric devices
*/
- for (lp = &fcp->portdb[FC_SNS_ID+1];
+ for (lim = FC_SNS_ID+1, lp = &fcp->portdb[FC_SNS_ID+1];
lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
+ u_int32_t portid;
mbreg_t mbs;
/*
@@ -1644,67 +1660,77 @@ isp_pdb_sync(isp, target)
*/
if (lp->port_wwn == 0)
continue;
+
/*
* Don't try to log into yourself.
*/
- if (lp->portid == fcp->isp_portid)
+ if ((portid = lp->portid) == fcp->isp_portid)
continue;
/*
- * Force a logout.
+ * Force a logout if we were logged in.
*/
- lp->loopid = loopid = lp - fcp->portdb;
- mbs.param[0] = MBOX_FABRIC_LOGOUT;
- mbs.param[1] = lp->loopid << 8;
- mbs.param[2] = 0;
- mbs.param[3] = 0;
- isp_mboxcmd(isp, &mbs);
+ if (lp->valid) {
+ 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;
+ }
/*
* And log in....
*/
- mbs.param[0] = MBOX_FABRIC_LOGIN;
- mbs.param[1] = lp->loopid << 8;
- mbs.param[2] = lp->portid >> 16;
- mbs.param[3] = lp->portid & 0xffff;
- isp_mboxcmd(isp, &mbs);
- switch (mbs.param[0]) {
- case MBOX_COMMAND_COMPLETE:
- break;
- case MBOX_COMMAND_ERROR:
- switch (mbs.param[1]) {
- case 1:
- PRINTF("%s: no loop\n", isp->isp_name);
- break;
- case 2:
- PRINTF("%s: IOCB buffer could not be alloced\n",
- isp->isp_name);
- break;
- case 3:
- PRINTF("%s: could not alloc xchange resource\n",
- isp->isp_name);
- break;
- case 4:
- PRINTF("%s: ELS timeout\n", isp->isp_name);
- break;
- case 5:
- PRINTF("%s: no fabric port\n", isp->isp_name);
+ loopid = lp - fcp->portdb;
+ lp->loopid = 0;
+ lim = 0;
+ do {
+ mbs.param[0] = MBOX_FABRIC_LOGIN;
+ mbs.param[1] = loopid << 8;
+ 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:
+ /*
+ * Try the next available loop id.
+ */
+ loopid++;
break;
- case 6:
- PRINTF("%s: remote device cannot be a target\n",
- isp->isp_name);
+ case MBOX_PORT_ID_USED:
+ /*
+ * This port is already logged in.
+ * Snaffle the loop id it's using.
+ */
+ if ((loopid = mbs.param[1]) == 0) {
+ lim = -1;
+ }
+ /* FALLTHROUGH */
+ case MBOX_COMMAND_COMPLETE:
+ 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]);
+ /* FALLTHROUGH */
+ case MBOX_ALL_IDS_USED: /* We're outta IDs */
default:
+ lim = -1;
break;
}
+ } while (lim == 0 && loopid < MAX_FC_TARG);
+ if (lim < 0)
continue;
- default:
- continue;
- }
lp->valid = 1;
lp->fabdev = 1;
- if (isp_getpdb(isp, loopid, &pdb) != 0) {
+ if (isp_getpdb(isp, lp->loopid, &pdb) != 0) {
/*
* Be kind...
*/
@@ -1722,7 +1748,6 @@ isp_pdb_sync(isp, target)
lp->roles =
(pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
lp->portid = BITS2WORD(pdb.pdb_portid_bits);
- lp->loopid = loopid;
lp->node_wwn =
(((u_int64_t)pdb.pdb_nodename[0]) << 56) |
(((u_int64_t)pdb.pdb_nodename[1]) << 48) |
@@ -1745,6 +1770,7 @@ isp_pdb_sync(isp, target)
* Check to make sure this all makes sense.
*/
if (lp->node_wwn && lp->port_wwn) {
+ loopid = lp - fcp->portdb;
(void) isp_async(isp, ISPASYNC_PDB_CHANGED, &loopid);
continue;
}
@@ -1758,6 +1784,12 @@ isp_pdb_sync(isp, target)
isp_mboxcmd(isp, &mbs);
}
#endif
+ /*
+ * If we get here, we've for sure seen not only a valid loop
+ * but know what is or isn't on it, so mark this for usage
+ * in ispscsicmd.
+ */
+ fcp->loop_seen_once = 1;
return (0);
}
@@ -1798,6 +1830,8 @@ isp_scan_fabric(isp)
MemoryBarrier();
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ IDPRINTF(1, ("%s: SNS failed (0x%x)\n", isp->isp_name,
+ mbs.param[0]));
return (-1);
}
ISP_UNSWIZZLE_SNS_RSP(isp, resp, SNS_GAN_RESP_SIZE >> 1);
@@ -1849,13 +1883,15 @@ ispscsicmd(xs)
}
/*
- * We *could* do the different sequence type that has close
- * to the whole Queue Entry for the command...
+ * Check command CDB length, etc.. We really are limited to 16 bytes
+ * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
+ * but probably only if we're running fairly new firmware (we'll
+ * let the old f/w choke on an extended command queue entry).
*/
- if (XS_CDBLEN(xs) > (IS_FC(isp) ? 16 : 12) || XS_CDBLEN(xs) == 0) {
+ if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
PRINTF("%s: unsupported cdb length (%d, CDB[0]=0x%x)\n",
- isp->isp_name, XS_CDBLEN(xs), XS_CDBP(xs)[0]);
+ isp->isp_name, XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
XS_SETERR(xs, HBA_BOTCH);
return (CMD_COMPLETE);
}
@@ -1908,11 +1944,17 @@ ispscsicmd(xs)
* If our loop state is such that we haven't yet received
* a "Port Database Changed" notification (after a LIP or
* a Loop Reset or firmware initialization), then defer
- * sending commands for a little while.
+ * sending commands for a little while, but only if we've
+ * seen a valid loop at one point (otherwise we can get
+ * stuck at initialization time).
*/
if (fcp->isp_loopstate < LOOP_PDB_RCVD) {
XS_SETERR(xs, HBA_SELTIMEOUT);
- return (CMD_RQLATER);
+ if (fcp->loop_seen_once) {
+ return (CMD_RQLATER);
+ } else {
+ return (CMD_COMPLETE);
+ }
}
/*
@@ -1999,7 +2041,10 @@ ispscsicmd(xs)
if (IS_FC(isp)) {
reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
} else {
- reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
+ if (XS_CDBLEN(xs) > 12)
+ reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
+ else
+ reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
}
reqp->req_header.rqs_flags = 0;
reqp->req_header.rqs_seqno = 0;
@@ -2112,16 +2157,17 @@ isp_control(isp, ctl, arg)
* Issue a bus reset.
*/
mbs.param[0] = MBOX_BUS_RESET;
+ mbs.param[2] = 0;
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;
+ if (IS_DUALBUS(isp))
+ mbs.param[2] = bus;
} else {
mbs.param[1] = 10;
- mbs.param[2] = 0;
bus = 0;
}
isp->isp_sendmarker = 1 << bus;
@@ -2174,8 +2220,8 @@ isp_control(isp, ctl, arg)
mbs.param[1] =
(bus << 15) | (XS_TGT(xs) << 8) | XS_LUN(xs);
}
- mbs.param[2] = handle >> 16;
- mbs.param[3] = handle & 0xffff;
+ 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",
@@ -2192,12 +2238,25 @@ isp_control(isp, ctl, arg)
case ISPCTL_FCLINK_TEST:
return (isp_fclink_test(isp, FC_FW_READY_DELAY));
-#ifdef ISP_TARGET_MODE
- case ISPCTL_ENABLE_LUN:
- return (isp_modify_lun, 1, arg));
- case ISPCTL_MODIFY_LUN:
- return (isp_modify_lun, 0, arg));
+ case ISPCTL_PDB_SYNC:
+ return (isp_pdb_sync(isp, -1));
+
+#ifdef ISP_TARGET_MODE
+ case ISPCTL_TOGGLE_TMODE:
+ if (IS_SCSI(isp)) {
+ int ena = *(int *)arg;
+ mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
+ mbs.param[1] = (ena)? ENABLE_TARGET_FLAG : 0;
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ PRINTF("%s: cannot %sable target mode (0x%x)\n",
+ isp->isp_name, ena? "en" : "dis",
+ mbs.param[0]);
+ break;
+ }
+ }
+ return (0);
#endif
}
return (-1);
@@ -2289,12 +2348,12 @@ isp_intr(arg)
MemoryBarrier();
/*
* Do any appropriate unswizzling of what the Qlogic f/w has
- * written into memory so it makes sense to us.
+ * written into memory so it makes sense to us. This is a
+ * per-platform thing.
*/
ISP_UNSWIZZLE_RESPONSE(isp, sp);
if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) {
if (isp_handle_other_response(isp, sp, &optr) == 0) {
- ISP_WRITE(isp, INMAILBOX5, optr);
continue;
}
/*
@@ -2303,7 +2362,6 @@ isp_intr(arg)
* not, something bad has happened.
*/
if (sp->req_header.rqs_entry_type != RQSTYPE_REQUEST) {
- ISP_WRITE(isp, INMAILBOX5, optr);
PRINTF("%s: not RESPONSE in RESPONSE Queue "
"(type 0x%x) @ idx %d (next %d)\n",
isp->isp_name,
@@ -2384,11 +2442,14 @@ isp_intr(arg)
isp->isp_update |= (1 << XS_CHANNEL(xs));
}
} else {
- if (XS_STS(xs) == SCSI_CHECK) {
+ if (sp->req_scsi_status & RQCS_SV) {
+ int amt = min(XS_SNSLEN(xs), sp->req_sense_len);
+ MEMCPY(XS_SNSP(xs), sp->req_sense_data, amt);
XS_SNS_IS_VALID(xs);
- MEMCPY(XS_SNSP(xs), sp->req_sense_data,
- XS_SNSLEN(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));
}
}
if (XS_NOERR(xs) && XS_STS(xs) == SCSI_BUSY) {
@@ -2431,6 +2492,10 @@ isp_intr(arg)
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
@@ -2443,6 +2508,7 @@ isp_intr(arg)
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",
@@ -2506,7 +2572,7 @@ isp_parse_async(isp, mbox)
case ASYNC_BUS_RESET:
isp->isp_sendmarker = (1 << bus);
#ifdef ISP_TARGET_MODE
- isp_target_async(isp, bus, ASYNC_BUS_RESET);
+ isp_target_async(isp, bus, mbox);
#endif
isp_async(isp, ISPASYNC_BUS_RESET, &bus);
break;
@@ -2540,7 +2606,7 @@ isp_parse_async(isp, mbox)
isp->isp_name, bus);
isp->isp_sendmarker = (1 << bus);
#ifdef ISP_TARGET_MODE
- isp_target_async(isp, bus, ASYNC_TIMEOUT_RESET);
+ isp_target_async(isp, bus, mbox);
#endif
break;
@@ -2548,7 +2614,7 @@ isp_parse_async(isp, mbox)
PRINTF("%s: device reset on bus %d\n", isp->isp_name, bus);
isp->isp_sendmarker = 1 << bus;
#ifdef ISP_TARGET_MODE
- isp_target_async(isp, bus, ASYNC_DEVICE_RESET);
+ isp_target_async(isp, bus, mbox);
#endif
break;
@@ -2626,6 +2692,9 @@ isp_parse_async(isp, mbox)
isp->isp_sendmarker = 1;
isp_mark_getpdb_all(isp);
IDPRINTF(1, ("%s: LIP occurred\n", isp->isp_name));
+#ifdef ISP_TARGET_MODE
+ isp_target_async(isp, bus, mbox);
+#endif
break;
case ASYNC_LOOP_UP:
@@ -2634,6 +2703,9 @@ isp_parse_async(isp, mbox)
((fcparam *) isp->isp_param)->isp_loopstate = LOOP_LIP_RCVD;
isp_mark_getpdb_all(isp);
isp_async(isp, ISPASYNC_LOOP_UP, NULL);
+#ifdef ISP_TARGET_MODE
+ isp_target_async(isp, bus, mbox);
+#endif
break;
case ASYNC_LOOP_DOWN:
@@ -2642,6 +2714,9 @@ isp_parse_async(isp, mbox)
((fcparam *) isp->isp_param)->isp_loopstate = LOOP_NIL;
isp_mark_getpdb_all(isp);
isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
+#ifdef ISP_TARGET_MODE
+ isp_target_async(isp, bus, mbox);
+#endif
break;
case ASYNC_LOOP_RESET:
@@ -2651,7 +2726,7 @@ isp_parse_async(isp, mbox)
isp_mark_getpdb_all(isp);
PRINTF("%s: Loop RESET\n", isp->isp_name);
#ifdef ISP_TARGET_MODE
- isp_target_async(isp, bus, ASYNC_LOOP_RESET);
+ isp_target_async(isp, bus, mbox);
#endif
break;
@@ -2671,6 +2746,37 @@ isp_parse_async(isp, mbox)
isp_async(isp, ISPASYNC_CHANGE_NOTIFY, NULL);
break;
+ case ASYNC_PTPMODE:
+ PRINTF("%s: Point-to-Point mode\n", isp->isp_name);
+ break;
+
+ case ASYNC_CONNMODE:
+ mbox = ISP_READ(isp, OUTMAILBOX1);
+ switch (mbox) {
+ case ISP_CONN_LOOP:
+ PRINTF("%s: Point-to-Point -> Loop mode\n",
+ isp->isp_name);
+ break;
+ case ISP_CONN_PTP:
+ PRINTF("%s: Loop -> Point-to-Point mode\n",
+ isp->isp_name);
+ break;
+ case ISP_CONN_BADLIP:
+ PRINTF("%s: Point-to-Point -> Loop mode (1)\n",
+ isp->isp_name);
+ break;
+ case ISP_CONN_FATAL:
+ PRINTF("%s: FATAL CONNECTION ERROR\n", isp->isp_name);
+ isp_restart(isp);
+ /* no point continuing after this */
+ return (-1);
+
+ case ISP_CONN_LOOPBACK:
+ PRINTF("%s: Looped Back in Point-to-Point mode\n",
+ isp->isp_name);
+ }
+ break;
+
default:
PRINTF("%s: unknown async code 0x%x\n", isp->isp_name, mbox);
break;
@@ -2692,7 +2798,7 @@ isp_handle_other_response(isp, sp, optrp)
{
switch (sp->req_header.rqs_entry_type) {
case RQSTYPE_ATIO:
- case RQSTYPE_CTIO0:
+ case RQSTYPE_CTIO:
case RQSTYPE_ENABLE_LUN:
case RQSTYPE_MODIFY_LUN:
case RQSTYPE_NOTIFY:
@@ -2702,7 +2808,7 @@ isp_handle_other_response(isp, sp, optrp)
case RQSTYPE_CTIO2:
case RQSTYPE_CTIO3:
#ifdef ISP_TARGET_MODE
- return (isp_target_entry(isp, sp));
+ return (isp_target_notify(isp, sp, optrp));
#else
/* FALLTHROUGH */
#endif
@@ -3094,7 +3200,7 @@ static u_int8_t mbpcnt[] = {
MAKNIB(0, 0), /* 0x52: */
MAKNIB(0, 0), /* 0x53: */
MAKNIB(8, 0), /* 0x54: MBOX_EXEC_COMMAND_IOCB_A64 */
- MAKNIB(0, 0), /* 0x55: */
+ MAKNIB(2, 1), /* 0x55: MBOX_ENABLE_TARGET_MODE */
MAKNIB(0, 0), /* 0x56: */
MAKNIB(0, 0), /* 0x57: */
MAKNIB(0, 0), /* 0x58: */
@@ -3403,6 +3509,12 @@ command_known:
}
}
+ if (IS_2200(isp)) {
+ if (opcode == MBOX_GET_LOOP_ID) {
+ mbp->param[6] = ISP_READ(isp, OUTMAILBOX6);
+ }
+ }
+
switch (outparam) {
case 8: mbp->param[7] = ISP_READ(isp, OUTMAILBOX7);
case 7: mbp->param[6] = ISP_READ(isp, OUTMAILBOX6);
@@ -3459,6 +3571,12 @@ command_known:
}
break;
+ case MBOX_LOOP_ID_USED:
+ case MBOX_PORT_ID_USED:
+ case MBOX_ALL_IDS_USED:
+ break;
+
+
/*
* Be silent about these...
*/
@@ -3826,7 +3944,14 @@ isp_setdfltparm(isp, channel)
sdp->isp_devparam[tgt].cur_period = 0;
sdp->isp_devparam[tgt].dev_flags = DPARM_DEFAULT;
sdp->isp_devparam[tgt].cur_dflags = 0;
- if (isp->isp_type < ISP_HA_SCSI_1040 ||
+ /*
+ * We default to Wide/Fast for versions less than a 1040
+ * (unless it's SBus).
+ */
+ if ((isp->isp_bustype == ISP_BT_SBUS &&
+ 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)) {
sdp->isp_devparam[tgt].sync_offset =
ISP_10M_SYNCPARMS >> 8;
@@ -3891,7 +4016,7 @@ isp_setdfltparm(isp, channel)
IDPRINTF(3, ("%s: bus %d tgt %d flags %x offset %x period %x\n",
isp->isp_name, channel, tgt,
sdp->isp_devparam[tgt].dev_flags,
- sdp->isp_devparam[tgt].sync_period,
+ sdp->isp_devparam[tgt].sync_offset,
sdp->isp_devparam[tgt].sync_period));
}
@@ -3971,13 +4096,10 @@ isp_restart(isp)
/*
* NVRAM Routines
*/
-
static int
isp_read_nvram(isp)
struct ispsoftc *isp;
{
- static char *tru = "true";
- static char *not = "false";
int i, amt;
u_int8_t csum, minversion;
union {
@@ -4030,349 +4152,23 @@ isp_read_nvram(isp)
return (-1);
}
- if (IS_ULTRA2(isp)) {
- int bus;
- sdparam *sdp = (sdparam *) isp->isp_param;
- for (bus = 0; bus < (IS_DUALBUS(isp)? 2 : 1); bus++, sdp++) {
- sdp->isp_fifo_threshold =
- ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
-
- sdp->isp_initiator_id =
- ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
-
- sdp->isp_bus_reset_delay =
- ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
-
- sdp->isp_retry_count =
- ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
-
- sdp->isp_retry_delay =
- ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
-
- sdp->isp_async_data_setup =
- ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data,
- bus);
-
- sdp->isp_req_ack_active_neg =
- ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data,
- bus);
-
- sdp->isp_data_line_active_neg =
- ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data,
- bus);
-
- sdp->isp_data_dma_burst_enabl =
- ISP1080_NVRAM_BURST_ENABLE(nvram_data);
-
- sdp->isp_cmd_dma_burst_enable =
- ISP1080_NVRAM_BURST_ENABLE(nvram_data);
-
- sdp->isp_selection_timeout =
- ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
-
- sdp->isp_max_queue_depth =
- ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
-
- if (isp->isp_dblev >= 3) {
- PRINTF("%s: ISP1080 bus %d NVRAM values:\n",
- isp->isp_name, bus);
- PRINTF(" Initiator ID = %d\n",
- sdp->isp_initiator_id);
- PRINTF(" Fifo Threshold = 0x%x\n",
- sdp->isp_fifo_threshold);
- PRINTF(" Bus Reset Delay = %d\n",
- sdp->isp_bus_reset_delay);
- PRINTF(" Retry Count = %d\n",
- sdp->isp_retry_count);
- PRINTF(" Retry Delay = %d\n",
- sdp->isp_retry_delay);
- PRINTF(" Tag Age Limit = %d\n",
- sdp->isp_tag_aging);
- PRINTF(" Selection Timeout = %d\n",
- sdp->isp_selection_timeout);
- PRINTF(" Max Queue Depth = %d\n",
- sdp->isp_max_queue_depth);
- PRINTF(" Async Data Setup = 0x%x\n",
- sdp->isp_async_data_setup);
- PRINTF(" REQ/ACK Active Negation = %s\n",
- sdp->isp_req_ack_active_neg? tru : not);
- PRINTF(" Data Line Active Negation = %s\n",
- sdp->isp_data_line_active_neg? tru : not);
- PRINTF(" Cmd DMA Burst Enable = %s\n",
- sdp->isp_cmd_dma_burst_enable? tru : not);
- }
- for (i = 0; i < MAX_TARGETS; i++) {
- sdp->isp_devparam[i].dev_enable =
- ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i, bus);
- sdp->isp_devparam[i].exc_throttle =
- ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, i, bus);
- sdp->isp_devparam[i].sync_offset =
- ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, i, bus);
- sdp->isp_devparam[i].sync_period =
- ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, i, bus);
- sdp->isp_devparam[i].dev_flags = 0;
- if (ISP1080_NVRAM_TGT_RENEG(nvram_data, i, bus))
- sdp->isp_devparam[i].dev_flags |= DPARM_RENEG;
- if (ISP1080_NVRAM_TGT_QFRZ(nvram_data, i, bus)) {
- PRINTF("%s: not supporting QFRZ option "
- "for target %d bus %d\n",
- isp->isp_name, i, bus);
- }
- sdp->isp_devparam[i].dev_flags |= DPARM_ARQ;
- if (ISP1080_NVRAM_TGT_ARQ(nvram_data, i, bus) == 0) {
- PRINTF("%s: not disabling ARQ option "
- "for target %d bus %d\n",
- isp->isp_name, i, bus);
- }
- if (ISP1080_NVRAM_TGT_TQING(nvram_data, i, bus))
- sdp->isp_devparam[i].dev_flags |= DPARM_TQING;
- if (ISP1080_NVRAM_TGT_SYNC(nvram_data, i, bus))
- sdp->isp_devparam[i].dev_flags |= DPARM_SYNC;
- if (ISP1080_NVRAM_TGT_WIDE(nvram_data, i, bus))
- sdp->isp_devparam[i].dev_flags |= DPARM_WIDE;
- if (ISP1080_NVRAM_TGT_PARITY(nvram_data, i, bus))
- sdp->isp_devparam[i].dev_flags |= DPARM_PARITY;
- if (ISP1080_NVRAM_TGT_DISC(nvram_data, i, bus))
- sdp->isp_devparam[i].dev_flags |= DPARM_DISC;
- sdp->isp_devparam[i].cur_dflags = 0;
- if (isp->isp_dblev >= 3) {
- PRINTF(" Target %d: Ena %d Throttle "
- "%d Offset %d Period %d Flags "
- "0x%x\n", i,
- sdp->isp_devparam[i].dev_enable,
- sdp->isp_devparam[i].exc_throttle,
- sdp->isp_devparam[i].sync_offset,
- sdp->isp_devparam[i].sync_period,
- sdp->isp_devparam[i].dev_flags);
- }
- }
- }
+ if (IS_ULTRA3(isp)) {
+ isp_parse_nvram_12160(isp, 0, nvram_data);
+ isp_parse_nvram_12160(isp, 1, nvram_data);
+ } else if (IS_1080(isp)) {
+ isp_parse_nvram_1080(isp, 0, nvram_data);
+ } else if (IS_1280(isp) || IS_1240(isp)) {
+ isp_parse_nvram_1080(isp, 0, nvram_data);
+ isp_parse_nvram_1080(isp, 1, nvram_data);
} else if (IS_SCSI(isp)) {
- sdparam *sdp = (sdparam *) isp->isp_param;
-
- sdp->isp_fifo_threshold =
- ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
- (ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
-
- sdp->isp_initiator_id =
- ISP_NVRAM_INITIATOR_ID(nvram_data);
-
- sdp->isp_bus_reset_delay =
- ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
-
- sdp->isp_retry_count =
- ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
-
- sdp->isp_retry_delay =
- ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
-
- sdp->isp_async_data_setup =
- ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
-
- if (isp->isp_type >= ISP_HA_SCSI_1040) {
- if (sdp->isp_async_data_setup < 9) {
- sdp->isp_async_data_setup = 9;
- }
- } else {
- if (sdp->isp_async_data_setup != 6) {
- sdp->isp_async_data_setup = 6;
- }
- }
-
- sdp->isp_req_ack_active_neg =
- ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
-
- sdp->isp_data_line_active_neg =
- ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
-
- sdp->isp_data_dma_burst_enabl =
- ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
-
- sdp->isp_cmd_dma_burst_enable =
- ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
-
- sdp->isp_tag_aging =
- ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
-
- sdp->isp_selection_timeout =
- ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
-
- sdp->isp_max_queue_depth =
- ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
-
- isp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
- if (isp->isp_dblev > 2) {
- PRINTF("%s: NVRAM values:\n", isp->isp_name);
- PRINTF(" Fifo Threshold = 0x%x\n",
- sdp->isp_fifo_threshold);
- PRINTF(" Bus Reset Delay = %d\n",
- sdp->isp_bus_reset_delay);
- PRINTF(" Retry Count = %d\n",
- sdp->isp_retry_count);
- PRINTF(" Retry Delay = %d\n",
- sdp->isp_retry_delay);
- PRINTF(" Tag Age Limit = %d\n",
- sdp->isp_tag_aging);
- PRINTF(" Selection Timeout = %d\n",
- sdp->isp_selection_timeout);
- PRINTF(" Max Queue Depth = %d\n",
- sdp->isp_max_queue_depth);
- PRINTF(" Async Data Setup = 0x%x\n",
- sdp->isp_async_data_setup);
- PRINTF(" REQ/ACK Active Negation = %s\n",
- sdp->isp_req_ack_active_neg? tru : not);
- PRINTF(" Data Line Active Negation = %s\n",
- sdp->isp_data_line_active_neg? tru : not);
- PRINTF(" Data DMA Burst Enable = %s\n",
- sdp->isp_data_dma_burst_enabl? tru : not);
- PRINTF(" Cmd DMA Burst Enable = %s\n",
- sdp->isp_cmd_dma_burst_enable? tru : not);
- PRINTF(" Fast MTTR = %s\n",
- isp->isp_fast_mttr? tru : not);
- }
- for (i = 0; i < MAX_TARGETS; i++) {
- sdp->isp_devparam[i].dev_enable =
- ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i);
- sdp->isp_devparam[i].exc_throttle =
- ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, i);
- sdp->isp_devparam[i].sync_offset =
- ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, i);
- sdp->isp_devparam[i].sync_period =
- ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, i);
-
- if (isp->isp_type < ISP_HA_SCSI_1040) {
- /*
- * If we're not ultra, we can't possibly
- * be a shorter period than this.
- */
- if (sdp->isp_devparam[i].sync_period < 0x19) {
- sdp->isp_devparam[i].sync_period =
- 0x19;
- }
- if (sdp->isp_devparam[i].sync_offset > 0xc) {
- sdp->isp_devparam[i].sync_offset =
- 0x0c;
- }
- } else {
- if (sdp->isp_devparam[i].sync_offset > 0x8) {
- sdp->isp_devparam[i].sync_offset = 0x8;
- }
- }
- sdp->isp_devparam[i].dev_flags = 0;
- if (ISP_NVRAM_TGT_RENEG(nvram_data, i))
- sdp->isp_devparam[i].dev_flags |= DPARM_RENEG;
- if (ISP_NVRAM_TGT_QFRZ(nvram_data, i)) {
- PRINTF("%s: not supporting QFRZ option for "
- "target %d\n", isp->isp_name, i);
- }
- sdp->isp_devparam[i].dev_flags |= DPARM_ARQ;
- if (ISP_NVRAM_TGT_ARQ(nvram_data, i) == 0) {
- PRINTF("%s: not disabling ARQ option for "
- "target %d\n", isp->isp_name, i);
- }
- if (ISP_NVRAM_TGT_TQING(nvram_data, i))
- sdp->isp_devparam[i].dev_flags |= DPARM_TQING;
- if (ISP_NVRAM_TGT_SYNC(nvram_data, i))
- sdp->isp_devparam[i].dev_flags |= DPARM_SYNC;
- if (ISP_NVRAM_TGT_WIDE(nvram_data, i))
- sdp->isp_devparam[i].dev_flags |= DPARM_WIDE;
- if (ISP_NVRAM_TGT_PARITY(nvram_data, i))
- sdp->isp_devparam[i].dev_flags |= DPARM_PARITY;
- if (ISP_NVRAM_TGT_DISC(nvram_data, i))
- sdp->isp_devparam[i].dev_flags |= DPARM_DISC;
- sdp->isp_devparam[i].cur_dflags = 0; /* we don't know */
- if (isp->isp_dblev > 2) {
- PRINTF(" Target %d: Enabled %d Throttle %d "
- "Offset %d Period %d Flags 0x%x\n", i,
- sdp->isp_devparam[i].dev_enable,
- sdp->isp_devparam[i].exc_throttle,
- sdp->isp_devparam[i].sync_offset,
- sdp->isp_devparam[i].sync_period,
- sdp->isp_devparam[i].dev_flags);
- }
- }
+ isp_parse_nvram_1020(isp, nvram_data);
} else {
- fcparam *fcp = (fcparam *) isp->isp_param;
- union {
- struct {
-#if BYTE_ORDER == BIG_ENDIAN
- u_int32_t hi32;
- u_int32_t lo32;
-#else
- u_int32_t lo32;
- u_int32_t hi32;
-#endif
- } wd;
- u_int64_t full64;
- } wwnstore;
-
- wwnstore.full64 = ISP2100_NVRAM_NODE_NAME(nvram_data);
- /*
- * Broken PTI cards with nothing in the top nibble. Pah.
- */
- 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);
- }
- fcp->isp_maxalloc =
- ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
- fcp->isp_maxfrmlen =
- ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
- fcp->isp_retry_delay =
- ISP2100_NVRAM_RETRY_DELAY(nvram_data);
- fcp->isp_retry_count =
- ISP2100_NVRAM_RETRY_COUNT(nvram_data);
- fcp->isp_loopid =
- ISP2100_NVRAM_HARDLOOPID(nvram_data);
- fcp->isp_execthrottle =
- ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
- fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
- if (isp->isp_dblev > 2) {
- PRINTF("%s: NVRAM values:\n", isp->isp_name);
- PRINTF(" Max IOCB Allocation = %d\n",
- fcp->isp_maxalloc);
- PRINTF(" Max Frame Length = %d\n",
- fcp->isp_maxfrmlen);
- PRINTF(" Execution Throttle = %d\n",
- fcp->isp_execthrottle);
- PRINTF(" Retry Count = %d\n",
- fcp->isp_retry_count);
- PRINTF(" Retry Delay = %d\n",
- fcp->isp_retry_delay);
- PRINTF(" Hard Loop ID = %d\n",
- fcp->isp_loopid);
- PRINTF(" Options = 0x%x\n",
- fcp->isp_fwoptions);
- PRINTF(" HBA Options = 0x%x\n",
- ISP2100_NVRAM_HBA_OPTIONS(nvram_data));
- }
+ isp_parse_nvram_2100(isp, nvram_data);
}
IDPRINTF(3, ("%s: NVRAM is valid\n", isp->isp_name));
return (0);
+#undef nvram_data
+#undef nvram_words
}
static void
@@ -4442,3 +4238,493 @@ isp_rdnvram_word(isp, wo, rp)
*rp = ((*rp >> 8) | ((*rp & 0xff) << 8));
#endif
}
+
+static void
+isp_parse_nvram_1020(isp, nvram_data)
+ struct ispsoftc *isp;
+ u_int8_t *nvram_data;
+{
+ int i;
+ static char *tru = "true";
+ static char *not = "false";
+ sdparam *sdp = (sdparam *) isp->isp_param;
+
+ sdp->isp_fifo_threshold =
+ ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
+ (ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
+
+ sdp->isp_initiator_id =
+ ISP_NVRAM_INITIATOR_ID(nvram_data);
+
+ sdp->isp_bus_reset_delay =
+ ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
+
+ sdp->isp_retry_count =
+ ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
+
+ sdp->isp_retry_delay =
+ ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
+
+ sdp->isp_async_data_setup =
+ ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
+
+ if (isp->isp_type >= ISP_HA_SCSI_1040) {
+ if (sdp->isp_async_data_setup < 9) {
+ sdp->isp_async_data_setup = 9;
+ }
+ } else {
+ if (sdp->isp_async_data_setup != 6) {
+ sdp->isp_async_data_setup = 6;
+ }
+ }
+
+ sdp->isp_req_ack_active_neg =
+ ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
+
+ sdp->isp_data_line_active_neg =
+ ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
+
+ sdp->isp_data_dma_burst_enabl =
+ ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
+
+ sdp->isp_cmd_dma_burst_enable =
+ ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
+
+ sdp->isp_tag_aging =
+ ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
+
+ sdp->isp_selection_timeout =
+ ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
+
+ sdp->isp_max_queue_depth =
+ ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
+
+ isp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
+ if (isp->isp_dblev > 2) {
+ PRINTF("%s: NVRAM values:\n", isp->isp_name);
+ PRINTF(" Fifo Threshold = 0x%x\n",
+ sdp->isp_fifo_threshold);
+ PRINTF(" Bus Reset Delay = %d\n",
+ sdp->isp_bus_reset_delay);
+ PRINTF(" Retry Count = %d\n",
+ sdp->isp_retry_count);
+ PRINTF(" Retry Delay = %d\n",
+ sdp->isp_retry_delay);
+ PRINTF(" Tag Age Limit = %d\n",
+ sdp->isp_tag_aging);
+ PRINTF(" Selection Timeout = %d\n",
+ sdp->isp_selection_timeout);
+ PRINTF(" Max Queue Depth = %d\n",
+ sdp->isp_max_queue_depth);
+ PRINTF(" Async Data Setup = 0x%x\n",
+ sdp->isp_async_data_setup);
+ PRINTF(" REQ/ACK Active Negation = %s\n",
+ sdp->isp_req_ack_active_neg? tru : not);
+ PRINTF(" Data Line Active Negation = %s\n",
+ sdp->isp_data_line_active_neg? tru : not);
+ PRINTF(" Data DMA Burst Enable = %s\n",
+ sdp->isp_data_dma_burst_enabl? tru : not);
+ PRINTF(" Cmd DMA Burst Enable = %s\n",
+ sdp->isp_cmd_dma_burst_enable? tru : not);
+ PRINTF(" Fast MTTR = %s\n",
+ isp->isp_fast_mttr? tru : not);
+ }
+ for (i = 0; i < MAX_TARGETS; i++) {
+ sdp->isp_devparam[i].dev_enable =
+ ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i);
+ sdp->isp_devparam[i].exc_throttle =
+ ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, i);
+ sdp->isp_devparam[i].sync_offset =
+ ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, i);
+ sdp->isp_devparam[i].sync_period =
+ ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, i);
+
+ if (isp->isp_type < ISP_HA_SCSI_1040) {
+ /*
+ * If we're not ultra, we can't possibly
+ * be a shorter period than this.
+ */
+ if (sdp->isp_devparam[i].sync_period < 0x19) {
+ sdp->isp_devparam[i].sync_period =
+ 0x19;
+ }
+ if (sdp->isp_devparam[i].sync_offset > 0xc) {
+ sdp->isp_devparam[i].sync_offset =
+ 0x0c;
+ }
+ } else {
+ if (sdp->isp_devparam[i].sync_offset > 0x8) {
+ sdp->isp_devparam[i].sync_offset = 0x8;
+ }
+ }
+ sdp->isp_devparam[i].dev_flags = 0;
+ if (ISP_NVRAM_TGT_RENEG(nvram_data, i))
+ sdp->isp_devparam[i].dev_flags |= DPARM_RENEG;
+ if (ISP_NVRAM_TGT_QFRZ(nvram_data, i)) {
+ PRINTF("%s: not supporting QFRZ option for "
+ "target %d\n", isp->isp_name, i);
+ }
+ sdp->isp_devparam[i].dev_flags |= DPARM_ARQ;
+ if (ISP_NVRAM_TGT_ARQ(nvram_data, i) == 0) {
+ PRINTF("%s: not disabling ARQ option for "
+ "target %d\n", isp->isp_name, i);
+ }
+ if (ISP_NVRAM_TGT_TQING(nvram_data, i))
+ sdp->isp_devparam[i].dev_flags |= DPARM_TQING;
+ if (ISP_NVRAM_TGT_SYNC(nvram_data, i))
+ sdp->isp_devparam[i].dev_flags |= DPARM_SYNC;
+ if (ISP_NVRAM_TGT_WIDE(nvram_data, i))
+ sdp->isp_devparam[i].dev_flags |= DPARM_WIDE;
+ if (ISP_NVRAM_TGT_PARITY(nvram_data, i))
+ sdp->isp_devparam[i].dev_flags |= DPARM_PARITY;
+ if (ISP_NVRAM_TGT_DISC(nvram_data, i))
+ sdp->isp_devparam[i].dev_flags |= DPARM_DISC;
+ sdp->isp_devparam[i].cur_dflags = 0; /* we don't know */
+ if (isp->isp_dblev > 2) {
+ PRINTF(" Target %d: Enabled %d Throttle %d "
+ "Offset %d Period %d Flags 0x%x\n", i,
+ sdp->isp_devparam[i].dev_enable,
+ sdp->isp_devparam[i].exc_throttle,
+ sdp->isp_devparam[i].sync_offset,
+ sdp->isp_devparam[i].sync_period,
+ sdp->isp_devparam[i].dev_flags);
+ }
+ }
+}
+
+static void
+isp_parse_nvram_1080(isp, bus, nvram_data)
+ struct ispsoftc *isp;
+ int bus;
+ u_int8_t *nvram_data;
+{
+ static char *tru = "true";
+ static char *not = "false";
+ int i;
+ sdparam *sdp = (sdparam *) isp->isp_param;
+ sdp += bus;
+
+ sdp->isp_fifo_threshold =
+ ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
+
+ sdp->isp_initiator_id =
+ ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
+
+ sdp->isp_bus_reset_delay =
+ ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
+
+ sdp->isp_retry_count =
+ ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
+
+ sdp->isp_retry_delay =
+ ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
+
+ sdp->isp_async_data_setup =
+ ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data,
+ bus);
+
+ sdp->isp_req_ack_active_neg =
+ ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data,
+ bus);
+
+ sdp->isp_data_line_active_neg =
+ ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data,
+ bus);
+
+ sdp->isp_data_dma_burst_enabl =
+ ISP1080_NVRAM_BURST_ENABLE(nvram_data);
+
+ sdp->isp_cmd_dma_burst_enable =
+ ISP1080_NVRAM_BURST_ENABLE(nvram_data);
+
+ sdp->isp_selection_timeout =
+ ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
+
+ sdp->isp_max_queue_depth =
+ ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
+
+ if (isp->isp_dblev >= 3) {
+ PRINTF("%s: ISP1080 bus %d NVRAM values:\n",
+ isp->isp_name, bus);
+ PRINTF(" Initiator ID = %d\n",
+ sdp->isp_initiator_id);
+ PRINTF(" Fifo Threshold = 0x%x\n",
+ sdp->isp_fifo_threshold);
+ PRINTF(" Bus Reset Delay = %d\n",
+ sdp->isp_bus_reset_delay);
+ PRINTF(" Retry Count = %d\n",
+ sdp->isp_retry_count);
+ PRINTF(" Retry Delay = %d\n",
+ sdp->isp_retry_delay);
+ PRINTF(" Tag Age Limit = %d\n",
+ sdp->isp_tag_aging);
+ PRINTF(" Selection Timeout = %d\n",
+ sdp->isp_selection_timeout);
+ PRINTF(" Max Queue Depth = %d\n",
+ sdp->isp_max_queue_depth);
+ PRINTF(" Async Data Setup = 0x%x\n",
+ sdp->isp_async_data_setup);
+ PRINTF(" REQ/ACK Active Negation = %s\n",
+ sdp->isp_req_ack_active_neg? tru : not);
+ PRINTF(" Data Line Active Negation = %s\n",
+ sdp->isp_data_line_active_neg? tru : not);
+ PRINTF(" Cmd DMA Burst Enable = %s\n",
+ sdp->isp_cmd_dma_burst_enable? tru : not);
+ }
+ for (i = 0; i < MAX_TARGETS; i++) {
+ sdp->isp_devparam[i].dev_enable =
+ ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i, bus);
+ sdp->isp_devparam[i].exc_throttle =
+ ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, i, bus);
+ sdp->isp_devparam[i].sync_offset =
+ ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, i, bus);
+ sdp->isp_devparam[i].sync_period =
+ ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, i, bus);
+ sdp->isp_devparam[i].dev_flags = 0;
+ if (ISP1080_NVRAM_TGT_RENEG(nvram_data, i, bus))
+ sdp->isp_devparam[i].dev_flags |= DPARM_RENEG;
+ if (ISP1080_NVRAM_TGT_QFRZ(nvram_data, i, bus)) {
+ PRINTF("%s: not supporting QFRZ option "
+ "for target %d bus %d\n",
+ isp->isp_name, i, bus);
+ }
+ sdp->isp_devparam[i].dev_flags |= DPARM_ARQ;
+ if (ISP1080_NVRAM_TGT_ARQ(nvram_data, i, bus) == 0) {
+ PRINTF("%s: not disabling ARQ option "
+ "for target %d bus %d\n",
+ isp->isp_name, i, bus);
+ }
+ if (ISP1080_NVRAM_TGT_TQING(nvram_data, i, bus))
+ sdp->isp_devparam[i].dev_flags |= DPARM_TQING;
+ if (ISP1080_NVRAM_TGT_SYNC(nvram_data, i, bus))
+ sdp->isp_devparam[i].dev_flags |= DPARM_SYNC;
+ if (ISP1080_NVRAM_TGT_WIDE(nvram_data, i, bus))
+ sdp->isp_devparam[i].dev_flags |= DPARM_WIDE;
+ if (ISP1080_NVRAM_TGT_PARITY(nvram_data, i, bus))
+ sdp->isp_devparam[i].dev_flags |= DPARM_PARITY;
+ if (ISP1080_NVRAM_TGT_DISC(nvram_data, i, bus))
+ sdp->isp_devparam[i].dev_flags |= DPARM_DISC;
+ sdp->isp_devparam[i].cur_dflags = 0;
+ if (isp->isp_dblev >= 3) {
+ PRINTF(" Target %d: Ena %d Throttle "
+ "%d Offset %d Period %d Flags "
+ "0x%x\n", i,
+ sdp->isp_devparam[i].dev_enable,
+ sdp->isp_devparam[i].exc_throttle,
+ sdp->isp_devparam[i].sync_offset,
+ sdp->isp_devparam[i].sync_period,
+ sdp->isp_devparam[i].dev_flags);
+ }
+ }
+}
+
+static void
+isp_parse_nvram_12160(isp, bus, nvram_data)
+ struct ispsoftc *isp;
+ int bus;
+ u_int8_t *nvram_data;
+{
+ static char *tru = "true";
+ static char *not = "false";
+ sdparam *sdp = (sdparam *) isp->isp_param;
+ int i;
+
+ sdp += bus;
+
+ sdp->isp_fifo_threshold =
+ ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
+
+ sdp->isp_initiator_id =
+ ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
+
+ sdp->isp_bus_reset_delay =
+ ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
+
+ sdp->isp_retry_count =
+ ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
+
+ sdp->isp_retry_delay =
+ ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
+
+ sdp->isp_async_data_setup =
+ ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data,
+ bus);
+
+ sdp->isp_req_ack_active_neg =
+ ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data,
+ bus);
+
+ sdp->isp_data_line_active_neg =
+ ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data,
+ bus);
+
+ sdp->isp_data_dma_burst_enabl =
+ ISP12160_NVRAM_BURST_ENABLE(nvram_data);
+
+ sdp->isp_cmd_dma_burst_enable =
+ ISP12160_NVRAM_BURST_ENABLE(nvram_data);
+
+ sdp->isp_selection_timeout =
+ ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
+
+ sdp->isp_max_queue_depth =
+ ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
+
+ if (isp->isp_dblev >= 3) {
+ PRINTF("%s: ISP12160 bus %d NVRAM values:\n",
+ isp->isp_name, bus);
+ PRINTF(" Initiator ID = %d\n",
+ sdp->isp_initiator_id);
+ PRINTF(" Fifo Threshold = 0x%x\n",
+ sdp->isp_fifo_threshold);
+ PRINTF(" Bus Reset Delay = %d\n",
+ sdp->isp_bus_reset_delay);
+ PRINTF(" Retry Count = %d\n",
+ sdp->isp_retry_count);
+ PRINTF(" Retry Delay = %d\n",
+ sdp->isp_retry_delay);
+ PRINTF(" Tag Age Limit = %d\n",
+ sdp->isp_tag_aging);
+ PRINTF(" Selection Timeout = %d\n",
+ sdp->isp_selection_timeout);
+ PRINTF(" Max Queue Depth = %d\n",
+ sdp->isp_max_queue_depth);
+ PRINTF(" Async Data Setup = 0x%x\n",
+ sdp->isp_async_data_setup);
+ PRINTF(" REQ/ACK Active Negation = %s\n",
+ sdp->isp_req_ack_active_neg? tru : not);
+ PRINTF(" Data Line Active Negation = %s\n",
+ sdp->isp_data_line_active_neg? tru : not);
+ PRINTF(" Cmd DMA Burst Enable = %s\n",
+ sdp->isp_cmd_dma_burst_enable? tru : not);
+ }
+
+ for (i = 0; i < MAX_TARGETS; i++) {
+ sdp->isp_devparam[i].dev_enable =
+ ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i, bus);
+ sdp->isp_devparam[i].exc_throttle =
+ ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, i, bus);
+ sdp->isp_devparam[i].sync_offset =
+ ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, i, bus);
+ sdp->isp_devparam[i].sync_period =
+ ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, i, bus);
+ sdp->isp_devparam[i].dev_flags = 0;
+ if (ISP12160_NVRAM_TGT_RENEG(nvram_data, i, bus))
+ sdp->isp_devparam[i].dev_flags |= DPARM_RENEG;
+ if (ISP12160_NVRAM_TGT_QFRZ(nvram_data, i, bus)) {
+ PRINTF("%s: not supporting QFRZ option "
+ "for target %d bus %d\n", isp->isp_name, i, bus);
+ }
+ sdp->isp_devparam[i].dev_flags |= DPARM_ARQ;
+ if (ISP12160_NVRAM_TGT_ARQ(nvram_data, i, bus) == 0) {
+ PRINTF("%s: not disabling ARQ option "
+ "for target %d bus %d\n", isp->isp_name, i, bus);
+ }
+ if (ISP12160_NVRAM_TGT_TQING(nvram_data, i, bus))
+ sdp->isp_devparam[i].dev_flags |= DPARM_TQING;
+ if (ISP12160_NVRAM_TGT_SYNC(nvram_data, i, bus))
+ sdp->isp_devparam[i].dev_flags |= DPARM_SYNC;
+ if (ISP12160_NVRAM_TGT_WIDE(nvram_data, i, bus))
+ sdp->isp_devparam[i].dev_flags |= DPARM_WIDE;
+ if (ISP12160_NVRAM_TGT_PARITY(nvram_data, i, bus))
+ sdp->isp_devparam[i].dev_flags |= DPARM_PARITY;
+ if (ISP12160_NVRAM_TGT_DISC(nvram_data, i, bus))
+ sdp->isp_devparam[i].dev_flags |= DPARM_DISC;
+ sdp->isp_devparam[i].cur_dflags = 0;
+ if (isp->isp_dblev >= 3) {
+ PRINTF(" Target %d: Ena %d Throttle %d Offset %d "
+ "Period %d Flags 0x%x\n", i,
+ sdp->isp_devparam[i].dev_enable,
+ sdp->isp_devparam[i].exc_throttle,
+ sdp->isp_devparam[i].sync_offset,
+ sdp->isp_devparam[i].sync_period,
+ sdp->isp_devparam[i].dev_flags);
+ }
+ }
+}
+
+static void
+isp_parse_nvram_2100(isp, nvram_data)
+ struct ispsoftc *isp;
+ u_int8_t *nvram_data;
+{
+ fcparam *fcp = (fcparam *) isp->isp_param;
+ union {
+ struct {
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int32_t hi32;
+ u_int32_t lo32;
+#else
+ u_int32_t lo32;
+ u_int32_t hi32;
+#endif
+ } wd;
+ u_int64_t full64;
+ } wwnstore;
+
+ wwnstore.full64 = ISP2100_NVRAM_NODE_NAME(nvram_data);
+
+ /*
+ * Broken PTI cards with nothing in the top nibble. Pah.
+ */
+ 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);
+ }
+ fcp->isp_maxalloc =
+ ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
+ fcp->isp_maxfrmlen =
+ ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
+ fcp->isp_retry_delay =
+ ISP2100_NVRAM_RETRY_DELAY(nvram_data);
+ fcp->isp_retry_count =
+ ISP2100_NVRAM_RETRY_COUNT(nvram_data);
+ fcp->isp_loopid =
+ ISP2100_NVRAM_HARDLOOPID(nvram_data);
+ fcp->isp_execthrottle =
+ ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
+ fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
+ if (isp->isp_dblev > 2) {
+ PRINTF("%s: NVRAM values:\n", isp->isp_name);
+ PRINTF(" Max IOCB Allocation = %d\n",
+ fcp->isp_maxalloc);
+ PRINTF(" Max Frame Length = %d\n",
+ fcp->isp_maxfrmlen);
+ PRINTF(" Execution Throttle = %d\n",
+ fcp->isp_execthrottle);
+ PRINTF(" Retry Count = %d\n",
+ fcp->isp_retry_count);
+ PRINTF(" Retry Delay = %d\n",
+ fcp->isp_retry_delay);
+ PRINTF(" Hard Loop ID = %d\n",
+ fcp->isp_loopid);
+ PRINTF(" Options = 0x%x\n",
+ fcp->isp_fwoptions);
+ PRINTF(" HBA Options = 0x%x\n",
+ ISP2100_NVRAM_HBA_OPTIONS(nvram_data));
+ }
+}