summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp/isp.c
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2006-07-03 08:24:09 +0000
committermjacob <mjacob@FreeBSD.org>2006-07-03 08:24:09 +0000
commitfa2514423bf205fcd4d5d552ebe38852f9457594 (patch)
tree58604d0a86cb16b7926e21a19d97952de8549f42 /sys/dev/isp/isp.c
parent617ea887dfddbc7da18e9cf29e731789481560ed (diff)
downloadFreeBSD-src-fa2514423bf205fcd4d5d552ebe38852f9457594.zip
FreeBSD-src-fa2514423bf205fcd4d5d552ebe38852f9457594.tar.gz
Do various fixes to support firmware loading for the 2322
(and by extension, the 2422). One peculiar thing I've found with the 2322 is that if you don't force it to do Hard LoopID acquisition, the firmware crashes. This took a while to figure out. While we're at it, fix various bugs having to do with NVRAM reading and option setting with respect to pieces of NVRAM.
Diffstat (limited to 'sys/dev/isp/isp.c')
-rw-r--r--sys/dev/isp/isp.c351
1 files changed, 227 insertions, 124 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 8fcb134..99c52db 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -100,7 +100,7 @@ static const char topology[] =
static const char swrej[] =
"Fabric Nameserver rejected %s (Reason=0x%x Expl=0x%x) for Port ID 0x%x";
static const char finmsg[] =
- "(%d.%d.%d): FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x";
+ "%d.%d.%d: FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x";
static const char sc0[] =
"%s CHAN %d FTHRSH %d IID %d RESETD %d RETRYC %d RETRYD %d ASD 0x%x";
static const char sc1[] =
@@ -129,7 +129,7 @@ static int isp_getmap(ispsoftc_t *, fcpos_map_t *);
static int isp_getpdb(ispsoftc_t *, int, isp_pdb_t *);
static uint64_t isp_get_portname(ispsoftc_t *, int, int);
static int isp_fclink_test(ispsoftc_t *, int);
-static char *isp2100_fw_statename(int);
+static const char *isp2100_fw_statename(int);
static int isp_pdb_sync(ispsoftc_t *);
static int isp_scan_loop(ispsoftc_t *);
static int isp_fabric_mbox_cmd(ispsoftc_t *, mbreg_t *);
@@ -639,18 +639,20 @@ again:
dodnld = 0;
}
- if (IS_23XX(isp))
+ if (IS_23XX(isp)) {
code_org = ISP_CODE_ORG_2300;
- else
+ } else {
code_org = ISP_CODE_ORG;
-
+ }
if (dodnld) {
- isp->isp_mbxworkp = (void *) &isp->isp_mdvec->dv_ispfw[1];
- isp->isp_mbxwrk0 = isp->isp_mdvec->dv_ispfw[3] - 1;
+ uint16_t *ptr = isp->isp_mdvec->dv_ispfw;
+
+ isp->isp_mbxworkp = &ptr[1];
+ isp->isp_mbxwrk0 = ptr[3] - 1;
isp->isp_mbxwrk1 = code_org + 1;
mbs.param[0] = MBOX_WRITE_RAM_WORD;
mbs.param[1] = code_org;
- mbs.param[2] = isp->isp_mdvec->dv_ispfw[0];
+ mbs.param[2] = ptr[0];
isp_mboxcmd(isp, &mbs, MBLOGNONE);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGERR,
@@ -659,6 +661,7 @@ again:
dodnld = 0;
goto again;
}
+
/*
* Verify that it downloaded correctly.
*/
@@ -669,6 +672,49 @@ again:
isp_prt(isp, ISP_LOGERR, "Ram Checksum Failure");
return;
}
+
+ /*
+ * If we're a 2322 or 2422, the firmware actually comes
+ * in three chunks. We loaded the first at the code_org
+ * address. The other two chunks, which follow right
+ * after each other in memory here, get loaded at addresses
+ * specfied at offset 0x9..0xB.
+ */
+ if (IS_2322(isp)) {
+
+ ptr = &ptr[ptr[3]];
+ isp->isp_mbxworkp = &ptr[1];
+ isp->isp_mbxwrk0 = ptr[3] - 1;
+ isp->isp_mbxwrk1 = ptr[5] + 1;
+ isp->isp_mbxwrk8 = ptr[4];
+ mbs.param[0] = MBOX_WRITE_RAM_WORD_EXTENDED;
+ mbs.param[8] = ptr[4];
+ mbs.param[1] = ptr[5];
+ mbs.param[2] = ptr[0];
+ isp_mboxcmd(isp, &mbs, MBLOGNONE);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ isp_prt(isp, ISP_LOGERR,
+ "Receive Sequencer F/W Load Failed");
+ return;
+ }
+
+ ptr = &ptr[ptr[3]];
+ isp->isp_mbxworkp = &ptr[1];
+ isp->isp_mbxwrk0 = ptr[3] - 1;
+ isp->isp_mbxwrk1 = ptr[5] + 1;
+ isp->isp_mbxwrk8 = ptr[4];
+ mbs.param[0] = MBOX_WRITE_RAM_WORD_EXTENDED;
+ mbs.param[8] = ptr[4];
+ mbs.param[1] = ptr[5];
+ mbs.param[2] = ptr[0];
+ isp_mboxcmd(isp, &mbs, MBLOGNONE);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ isp_prt(isp, ISP_LOGERR,
+ "Transmit Sequencer F/W Load Failed");
+ return;
+ }
+ }
+
isp->isp_loaded_fw = 1;
} else {
isp->isp_loaded_fw = 0;
@@ -687,9 +733,9 @@ again:
mbs.param[1] = code_org;
if (IS_2322(isp) || IS_24XX(isp)) {
if (isp->isp_loaded_fw) {
- mbs.param[2] = 1;
- } else {
mbs.param[2] = 0;
+ } else {
+ mbs.param[2] = 1;
}
mbs.obits |= 2;
}
@@ -1032,11 +1078,9 @@ isp_scsi_init(ispsoftc_t *isp)
if (IS_ULTRA2(isp) || IS_1240(isp))
mbs.param[1] |= FW_FEATURE_RIO_16BIT;
#else
-#ifndef ISP_NO_FASTPOST
if (IS_ULTRA2(isp) || IS_1240(isp))
mbs.param[1] |= FW_FEATURE_FAST_POST;
#endif
-#endif
if (mbs.param[1] != 0) {
uint16_t sfeat = mbs.param[1];
isp_mboxcmd(isp, &mbs, MBLOGALL);
@@ -1273,7 +1317,7 @@ isp_fibre_init(ispsoftc_t *isp)
icbp->icb_retry_delay = fcp->isp_retry_delay;
icbp->icb_retry_count = fcp->isp_retry_count;
icbp->icb_hardaddr = loopid;
- if (icbp->icb_hardaddr >= 125) {
+ if (icbp->icb_hardaddr > 125) {
/*
* We end up with these Loop IDs for F-Port topologies
*/
@@ -1284,6 +1328,11 @@ isp_fibre_init(ispsoftc_t *isp)
}
icbp->icb_hardaddr = 0;
}
+
+ if (IS_2322(isp) || IS_24XX(isp)) {
+ icbp->icb_fwoptions |= ICBOPT_HARD_ADDRESS;
+ }
+
/*
* Right now we just set extended options to prefer point-to-point
* over loop based upon some soft config options.
@@ -1309,38 +1358,26 @@ isp_fibre_init(ispsoftc_t *isp)
icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
break;
}
- if (IS_23XX(isp)) {
+ if (IS_2200(isp)) {
+ if (ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
+ icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
+ icbp->icb_racctimer = 4;
+ icbp->icb_idelaytimer = 8;
+ }
+ icbp->icb_fwoptions |= ICBOPT_FAST_POST;
+ } else {
/*
* QLogic recommends that FAST Posting be turned
* off for 23XX cards and instead allow the HBA
* to write response queue entries and interrupt
* after a delay (ZIO).
- *
- * If we set ZIO, it will disable fast posting,
- * so we don't need to clear it in fwoptions.
- *
- * Depending on the role we're selecting, we
- * chose fast posting or not as it still is
- * a win for target mode.
*/
-#ifndef ISP_NO_ZIO
- if (isp->isp_role == ISP_ROLE_TARGET) {
- icbp->icb_fwoptions |= ICBOPT_FAST_POST;
- } else {
+ icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
+ if ((fcp->isp_xfwoptions & ICBXOPT_TIMER_MASK) ==
+ ICBXOPT_ZIO) {
icbp->icb_xfwoptions |= ICBXOPT_ZIO;
+ icbp->icb_idelaytimer = 10;
}
-#else
- icbp->icb_fwoptions |= ICBOPT_FAST_POST;
-#endif
-#if 0
- /*
- * Values, in 100us increments. The default
- * is 2 (200us) if a value 0 (default) is
- * selected.
- */
- icbp->icb_idelaytimer = 2;
-#endif
-
if (isp->isp_confopts & ISP_CFG_ONEGB) {
icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
} else if (isp->isp_confopts & ISP_CFG_TWOGB) {
@@ -1348,30 +1385,12 @@ isp_fibre_init(ispsoftc_t *isp)
} else {
icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
}
+ if (fcp->isp_zfwoptions & ICBZOPT_50_OHM) {
+ icbp->icb_zfwoptions |= ICBZOPT_50_OHM;
+ }
}
}
-#ifndef ISP_NO_RIO_FC
- /*
- * RIO seems to be enabled in 2100s for fw >= 1.17.0.
- *
- * I've had some questionable problems with RIO on 2200.
- * More specifically, on a 2204 I had problems with RIO
- * on a Linux system where I was dropping commands right
- * and left. It's not clear to me what the actual problem
- * was.
- *
- * 23XX Cards do not support RIO. Instead they support ZIO.
- */
-#if 0
- if (!IS_23XX(isp) && ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
- icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
- icbp->icb_racctimer = 4;
- icbp->icb_idelaytimer = 8;
- }
-#endif
-#endif
-
MEMZERO(&mbs, sizeof (mbs));
/*
@@ -1432,6 +1451,7 @@ isp_fibre_init(ispsoftc_t *isp)
icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
+
isp_prt(isp, ISP_LOGDEBUG0,
"isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
@@ -1560,18 +1580,20 @@ isp_get_portname(ispsoftc_t *isp, int loopid, int nodename)
mbs.param[0] = MBOX_GET_PORT_NAME;
if (IS_2KLOGIN(isp)) {
mbs.param[1] = loopid;
- if (nodename)
- mbs.param[10] = 1;
mbs.obits |= (1 << 10);
+ if (nodename) {
+ mbs.param[10] = 1;
+ }
} else {
mbs.param[1] = loopid << 8;
- if (nodename)
+ if (nodename) {
mbs.param[1] |= 1;
+ }
}
isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
wwn =
- (((uint64_t)(mbs.param[2] & 0xff)) << 56) |
+ (((uint64_t)(mbs.param[2] & 0xff)) << 56) |
(((uint64_t)(mbs.param[2] >> 8)) << 48) |
(((uint64_t)(mbs.param[3] & 0xff)) << 40) |
(((uint64_t)(mbs.param[3] >> 8)) << 32) |
@@ -1606,6 +1628,8 @@ isp_fclink_test(ispsoftc_t *isp, int usdelay)
fcp = isp->isp_param;
+ isp_prt(isp, ISP_LOGDEBUG0, "FC Link Test Entry");
+
/*
* XXX: Here is where we would start a 'loop dead' timeout
*/
@@ -1689,7 +1713,11 @@ isp_fclink_test(ispsoftc_t *isp, int usdelay)
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return (-1);
}
- fcp->isp_loopid = mbs.param[1];
+ if (IS_2KLOGIN(isp)) {
+ fcp->isp_loopid = mbs.param[1];
+ } else {
+ fcp->isp_loopid = mbs.param[1] & 0xff;
+ }
if (fcp->isp_loopid == 0xffff) { /* happens with 2k login f/w */
fcp->isp_loopid = MAX_FC_TARG-1;
} else if (fcp->isp_loopid >= MAX_FC_TARG) {
@@ -1840,10 +1868,11 @@ not_on_fabric:
lp->loggedin = lp->valid = 1;
count = fcp->isp_iid;
(void) isp_async(isp, ISPASYNC_PROMENADE, &count);
+ isp_prt(isp, ISP_LOGDEBUG0, "FC Link Test Complete");
return (0);
}
-static char *
+static const char *
isp2100_fw_statename(int state)
{
switch(state) {
@@ -2209,11 +2238,15 @@ isp_scan_loop(ispsoftc_t *isp)
hival = FC_PORT_ID;
break;
default:
+ isp_prt(isp, ISP_LOGDEBUG0, "no loop scasn\n");
fcp->isp_loopstate = LOOP_LSCAN_DONE;
return (0);
}
fcp->isp_loopstate = LOOP_SCANNING_LOOP;
+ isp_prt(isp, ISP_LOGDEBUG0, "scanning local loop 0..%d", hival);
+
+
/*
* make sure the temp port database is clean...
*/
@@ -2233,30 +2266,30 @@ isp_scan_loop(ispsoftc_t *isp)
/*
* Don't even try for ourselves...
*/
- if (loopid == fcp->isp_loopid)
+ if (loopid == fcp->isp_loopid) {
continue;
+ }
- lp->node_wwn = isp_get_portname(isp, loopid, 1);
- if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
- return (-1);
- if (lp->node_wwn == 0)
- continue;
- lp->port_wwn = isp_get_portname(isp, loopid, 0);
- if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
- return (-1);
- if (lp->port_wwn == 0) {
- lp->node_wwn = 0;
- continue;
+ if (IS_2100(isp) || IS_2200(isp)) {
+ lp->node_wwn = isp_get_portname(isp, loopid, 1);
+ if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
+ return (-1);
+ }
+ if (lp->node_wwn == 0) {
+ continue;
+ }
}
/*
* Get an entry....
*/
if (isp_getpdb(isp, loopid, &pdb) != 0) {
- if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
+ if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
return (-1);
+ }
continue;
}
+
if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
return (-1);
}
@@ -2523,6 +2556,8 @@ isp_scan_fabric(ispsoftc_t *isp, int ftype)
return (0);
}
+ isp_prt(isp, ISP_LOGDEBUG0, "scanning fabric (GA_NXT)");
+
FC_SCRATCH_ACQUIRE(isp);
/*
@@ -2689,6 +2724,8 @@ isp_scan_fabric(ispsoftc_t *isp, int ftype)
return (0);
}
+ isp_prt(isp, ISP_LOGDEBUG0, "scanning fabric (GID_FT)");
+
FC_SCRATCH_ACQUIRE(isp);
fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
@@ -3425,11 +3462,13 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg)
if (IS_SCSI(isp)) {
mbs.param[1] =
((sdparam *) isp->isp_param)->isp_bus_reset_delay;
- if (mbs.param[1] < 2)
+ if (mbs.param[1] < 2) {
mbs.param[1] = 2;
+ }
bus = *((int *) arg);
- if (IS_DUALBUS(isp))
+ if (IS_DUALBUS(isp)) {
mbs.param[2] = bus;
+ }
} else {
mbs.param[1] = 10;
bus = 0;
@@ -3549,6 +3588,9 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg)
if (IS_FC(isp)) {
mbs.param[0] = MBOX_INIT_LIP;
+ if (IS_2KLOGIN(isp)) {
+ mbs.obits |= (1 << 10);
+ }
isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
return (0);
@@ -3966,8 +4008,9 @@ again:
}
}
isp_prt(isp, ISP_LOGDEBUG2,
- "asked for %ld got resid %ld", (long) XS_XFRLEN(xs),
- (long) sp->req_resid);
+ "asked for %ld got raw resid %ld settled for %ld",
+ (long) XS_XFRLEN(xs), (long) sp->req_resid,
+ (long) XS_RESID(xs));
break;
case RQSTYPE_REQUEST:
if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
@@ -4085,6 +4128,20 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
isp_async(isp, ISPASYNC_BUS_RESET, &bus);
break;
case ASYNC_SYSTEM_ERROR:
+ isp->isp_state = ISP_CRASHED;
+ if (IS_FC(isp)) {
+ FCPARAM(isp)->isp_loopstate = LOOP_NIL;
+ FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
+ }
+ /*
+ * Were we waiting for a mailbox command to complete?
+ * If so, it's dead, so wake up the waiter.
+ */
+ if (isp->isp_mboxbsy) {
+ isp->isp_obits = 1;
+ isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
+ MBOX_NOTIFY_COMPLETE(isp);
+ }
#ifdef ISP_FW_CRASH_DUMP
/*
* If we have crash dumps enabled, it's up to the handler
@@ -4810,6 +4867,9 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs)
mbreg_t mbs;
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_INIT_LIP;
+ if (IS_2KLOGIN(isp)) {
+ mbs.obits |= (1 << 10);
+ }
isp_mboxcmd_qnw(isp, &mbs, 1);
}
@@ -4893,6 +4953,7 @@ isp_mbox_continue(ispsoftc_t *isp)
switch (isp->isp_lastmbxcmd) {
case MBOX_WRITE_RAM_WORD:
case MBOX_READ_RAM_WORD:
+ case MBOX_WRITE_RAM_WORD_EXTENDED:
case MBOX_READ_RAM_WORD_EXTENDED:
break;
default:
@@ -4919,10 +4980,25 @@ isp_mbox_continue(ispsoftc_t *isp)
mbs.param[2] = *ptr++;
mbs.param[1] = isp->isp_mbxwrk1++;
break;
+ case MBOX_WRITE_RAM_WORD_EXTENDED:
+ mbs.param[2] = *ptr++;
+ mbs.param[1] = isp->isp_mbxwrk1++;
+ if (isp->isp_mbxwrk1 == 0) {
+ isp->isp_mbxwrk8++;
+ }
+ mbs.param[8] = isp->isp_mbxwrk8;
+ break;
case MBOX_READ_RAM_WORD:
+ *ptr++ = isp->isp_mboxtmp[2];
+ mbs.param[1] = isp->isp_mbxwrk1++;
+ break;
case MBOX_READ_RAM_WORD_EXTENDED:
*ptr++ = isp->isp_mboxtmp[2];
mbs.param[1] = isp->isp_mbxwrk1++;
+ if (isp->isp_mbxwrk1 == 0) {
+ isp->isp_mbxwrk8++;
+ }
+ mbs.param[8] = isp->isp_mbxwrk8;
break;
}
isp->isp_mbxworkp = ptr;
@@ -5146,9 +5222,9 @@ static const uint32_t mbpfc[] = {
ISPOPMAP(0xdf, 0x01), /* 0x0a: DUMP RAM */
ISPOPMAP(0x00, 0x00), /* 0x0b: */
ISPOPMAP(0x00, 0x00), /* 0x0c: */
- ISPOPMAP(0x00, 0x00), /* 0x0d: */
+ ISPOPMAP(0x13, 0x01), /* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED) */
ISPOPMAP(0x01, 0x05), /* 0x0e: MBOX_CHECK_FIRMWARE */
- ISPOPMAP(0x03, 0x07), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED(1) */
+ ISPOPMAP(0x13, 0x05), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
ISPOPMAP(0x1f, 0x11), /* 0x10: MBOX_INIT_REQ_QUEUE */
ISPOPMAP(0x2f, 0x21), /* 0x11: MBOX_INIT_RES_QUEUE */
ISPOPMAP(0x0f, 0x01), /* 0x12: MBOX_EXECUTE_IOCB */
@@ -5266,7 +5342,8 @@ static const uint32_t mbpfc[] = {
*
* (1): this sets bits 21..16 in mailbox register #8, which we nominally
* do not access at this time in the core driver. The caller is
- * responsible for setting this register first (Gross!).
+ * responsible for setting this register first (Gross!). The assumption
+ * is that we won't overflow.
*/
#ifndef ISP_STRIPPED
@@ -5282,7 +5359,7 @@ static char *fc_mbcmd_names[] = {
"ABOUT FIRMWARE",
"LOAD RAM",
"DUMP RAM",
- NULL,
+ "WRITE RAM WORD EXTENDED",
NULL,
"READ RAM WORD EXTENDED",
"CHECK FIRMWARE",
@@ -5342,7 +5419,7 @@ static char *fc_mbcmd_names[] = {
NULL,
NULL,
NULL,
- "GET PORT DATABASE,, ENHANCED",
+ "GET PORT DATABASE ENHANCED",
NULL,
NULL,
NULL,
@@ -5465,6 +5542,9 @@ isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp, int logmask)
ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
+ /*
+ * Pick up any additional bits that the caller might have set.
+ */
ibits |= mbp->ibits;
obits |= mbp->obits;
@@ -5504,10 +5584,10 @@ isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp, int logmask)
*/
MBOX_WAIT_COMPLETE(isp);
+ /*
+ * Did the command time out?
+ */
if (isp->isp_mboxbsy) {
- /*
- * Command timed out.
- */
isp->isp_mboxbsy = 0;
MBOX_RELEASE(isp);
return;
@@ -5773,9 +5853,7 @@ isp_setdfltparm(ispsoftc_t *isp, int channel)
fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
-#ifndef ISP_NO_FASTPOST_FC
fcp->isp_fwoptions |= ICBOPT_FAST_POST;
-#endif
if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
@@ -5791,8 +5869,9 @@ isp_setdfltparm(ispsoftc_t *isp, int channel)
*/
if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
nvfail = isp_read_nvram(isp);
- if (nvfail)
+ if (nvfail) {
isp->isp_confopts |= ISP_CFG_NONVRAM;
+ }
} else {
nvfail = 1;
}
@@ -5816,6 +5895,11 @@ isp_setdfltparm(ispsoftc_t *isp, int channel)
* from NVRAM or our platform default.
*/
ISP_NODEWWN(isp) = fcp->isp_nodewwn;
+ if (fcp->isp_nodewwn == 0) {
+ isp_prt(isp, ISP_LOGCONFIG,
+ "bad WWNN- using default\n");
+ ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
+ }
}
if (isp->isp_confopts & ISP_CFG_OWNWWPN) {
isp_prt(isp, ISP_LOGCONFIG, "Using Port WWN 0x%08x%08x",
@@ -5828,6 +5912,11 @@ isp_setdfltparm(ispsoftc_t *isp, int channel)
* from NVRAM or our platform default.
*/
ISP_PORTWWN(isp) = fcp->isp_portwwn;
+ if (fcp->isp_portwwn == 0) {
+ isp_prt(isp, ISP_LOGCONFIG,
+ "bad WWPN- using default\n");
+ ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
+ }
}
return;
}
@@ -6019,7 +6108,7 @@ isp_reinit(ispsoftc_t *isp)
static int
isp_read_nvram(ispsoftc_t *isp)
{
- int i, amt;
+ int i, amt, retval;
uint8_t csum, minversion;
union {
uint8_t _x[ISP2100_NVRAM_SIZE];
@@ -6053,7 +6142,8 @@ isp_read_nvram(ispsoftc_t *isp)
isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x",
nvram_data[0], nvram_data[1], nvram_data[2]);
}
- return (-1);
+ retval = -1;
+ goto out;
}
for (i = 2; i < amt>>1; i++) {
isp_rdnvram_word(isp, i, &nvram_words[i]);
@@ -6063,12 +6153,14 @@ isp_read_nvram(ispsoftc_t *isp)
}
if (csum != 0) {
isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
- return (-1);
+ retval = -1;
+ goto out;
}
if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
ISP_NVRAM_VERSION(nvram_data));
- return (-1);
+ retval = -1;
+ goto out;
}
if (IS_ULTRA3(isp)) {
@@ -6085,7 +6177,9 @@ isp_read_nvram(ispsoftc_t *isp)
} else {
isp_parse_nvram_2100(isp, nvram_data);
}
- return (0);
+ retval = 0;
+out:
+ return (retval);
#undef nvram_data
#undef nvram_words
}
@@ -6094,15 +6188,15 @@ static void
isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
{
int i, cbits;
- uint16_t bit, rqst;
+ uint16_t bit, rqst, junk;
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
- USEC_DELAY(2);
+ USEC_DELAY(10);
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
- USEC_DELAY(2);
+ USEC_DELAY(10);
if (IS_FC(isp)) {
- wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
+ wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
if (IS_2312(isp) && isp->isp_port) {
wo += 128;
}
@@ -6128,11 +6222,14 @@ isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
bit = BIU_NVRAM_SELECT;
}
ISP_WRITE(isp, BIU_NVRAM, bit);
- USEC_DELAY(2);
+ USEC_DELAY(10);
+ junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
- USEC_DELAY(2);
+ USEC_DELAY(10);
+ junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
ISP_WRITE(isp, BIU_NVRAM, bit);
- USEC_DELAY(2);
+ USEC_DELAY(10);
+ junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
}
/*
* Now read the result back in (bits come back in MSB format).
@@ -6142,17 +6239,19 @@ isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
uint16_t rv;
*rp <<= 1;
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
- USEC_DELAY(2);
+ USEC_DELAY(10);
rv = ISP_READ(isp, BIU_NVRAM);
if (rv & BIU_NVRAM_DATAIN) {
*rp |= 1;
}
- USEC_DELAY(2);
+ USEC_DELAY(10);
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
- USEC_DELAY(2);
+ USEC_DELAY(10);
+ junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
}
ISP_WRITE(isp, BIU_NVRAM, 0);
- USEC_DELAY(2);
+ USEC_DELAY(10);
+ junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
ISP_SWIZZLE_NVRAM_WORD(isp, rp);
}
@@ -6492,7 +6591,7 @@ isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
}
fcp->isp_portwwn = wwn;
if (IS_2200(isp) || IS_23XX(isp)) {
- wwn = ISP2200_NVRAM_NODE_NAME(nvram_data);
+ wwn = ISP2100_NVRAM_NODE_NAME(nvram_data);
if (wwn) {
isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
(uint32_t) (wwn >> 32),
@@ -6532,13 +6631,6 @@ isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
}
}
- isp_prt(isp, ISP_LOGDEBUG0,
- "NVRAM: maxfrmlen %d execthrottle %d fwoptions 0x%x loopid %x",
- ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data),
- ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
- ISP2100_NVRAM_OPTIONS(nvram_data),
- ISP2100_NVRAM_HARDLOOPID(nvram_data));
-
fcp->isp_maxalloc =
ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0)
@@ -6555,6 +6647,23 @@ isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
fcp->isp_execthrottle =
ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d",
+ (uint32_t) (fcp->isp_nodewwn >> 32), (uint32_t) fcp->isp_nodewwn,
+ (uint32_t) (fcp->isp_portwwn >> 32), (uint32_t) fcp->isp_portwwn,
+ ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data),
+ ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data));
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "execthrottle %d fwoptions 0x%x hardloop %d tov %d",
+ ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
+ ISP2100_NVRAM_OPTIONS(nvram_data),
+ ISP2100_NVRAM_HARDLOOPID(nvram_data),
+ ISP2100_NVRAM_TOV(nvram_data));
+ fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data);
+ fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data);
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "xfwoptions 0x%x zfw options 0x%x",
+ ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data));
}
#ifdef ISP_FW_CRASH_DUMP
@@ -6844,19 +6953,13 @@ isp2300_fw_dump(ispsoftc_t *isp)
}
ptr = isp->isp_mbxworkp; /* finish fetch of final word */
*ptr++ = isp->isp_mboxtmp[2];
-
- /*
- * We don't have access to mailbox registers 8.. onward
- * in our 'common' device model- so we have to set it
- * here and hope it stays the same!
- */
- ISP_WRITE(isp, PCI_MBOX_REGS2300_OFF + (8 << 1), 0x1);
-
mbs.param[0] = MBOX_READ_RAM_WORD_EXTENDED;
mbs.param[1] = 0;
+ mbs.param[8] = 1;
isp->isp_mbxworkp = (void *) ptr;
isp->isp_mbxwrk0 = 0xffff; /* continuation count */
isp->isp_mbxwrk1 = 0x1; /* next SRAM address */
+ isp->isp_mbxwrk8 = 0x1;
isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGWARN,
OpenPOWER on IntegriCloud