aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMatt Jacob <mjacob@FreeBSD.org>2006-07-03 08:24:09 +0000
committerMatt Jacob <mjacob@FreeBSD.org>2006-07-03 08:24:09 +0000
commit8a97c03a7a480077305129a8e1c0fcf004c28f92 (patch)
tree58604d0a86cb16b7926e21a19d97952de8549f42 /sys
parentfb372900796f639bf269bf44651ef67f0eb17095 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/isp/isp.c351
-rw-r--r--sys/dev/isp/isp_pci.c24
-rw-r--r--sys/dev/isp/ispmbox.h4
-rw-r--r--sys/dev/isp/ispreg.h25
-rw-r--r--sys/dev/isp/ispvar.h18
5 files changed, 280 insertions, 142 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 8fcb134e57f51..99c52db1bb67e 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,
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index 09e05bb1d94f8..1186cced37a6c 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -165,6 +165,9 @@ static struct ispmdvec mdvec_2300 = {
#ifndef PCIM_CMD_SEREN
#define PCIM_CMD_SEREN 0x0100
#endif
+#ifndef PCIM_CMD_INTX_DISABLE
+#define PCIM_CMD_INTX_DISABLE 0x0400
+#endif
#ifndef PCIR_COMMAND
#define PCIR_COMMAND 0x04
@@ -874,10 +877,7 @@ isp_pci_attach(device_t dev)
* Try and find firmware for this device.
*/
- /*
- * Don't even attempt to get firmware for the 2322/2422 (yet)
- */
- if (IS_2322(isp) == 0 && IS_24XX(isp) == 0 && isp_get_firmware_p) {
+ if (isp_get_firmware_p) {
int device = (int) pci_get_device(dev);
#ifdef ISP_TARGET_MODE
(*isp_get_firmware_p)(0, 1, device, &mdvp->dv_ispfw);
@@ -902,6 +902,11 @@ isp_pci_attach(device_t dev)
isp->isp_touched = 1;
}
+
+ if (IS_2322(isp) || pci_get_devid(dev) == PCI_QLOGIC_ISP6312) {
+ cmd &= ~PCIM_CMD_INTX_DISABLE;
+ }
+
pci_write_config(dev, PCIR_COMMAND, cmd, 2);
/*
@@ -1114,6 +1119,7 @@ isp_pci_rd_isr_2300(ispsoftc_t *isp, uint16_t *isrp,
uint16_t *semap, uint16_t *mbox0p)
{
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
+ uint16_t hccr;
uint32_t r2hisr;
if (!(BXR2(pcs, IspVirt2Off(isp, BIU_ISR) & BIU2100_ISR_RISC_INT))) {
@@ -1158,6 +1164,16 @@ isp_pci_rd_isr_2300(ispsoftc_t *isp, uint16_t *isrp,
*semap = 0;
return (1);
default:
+ hccr = ISP_READ(isp, HCCR);
+ if (hccr & HCCR_PAUSE) {
+ ISP_WRITE(isp, HCCR, HCCR_RESET);
+ isp_prt(isp, ISP_LOGERR,
+ "RISC paused at interrupt (%x->%x\n", hccr,
+ ISP_READ(isp, HCCR));
+ } else {
+ isp_prt(isp, ISP_LOGERR, "unknown interrerupt 0x%x\n",
+ r2hisr);
+ }
return (0);
}
}
diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h
index e79efa232ca7d..2ef8d51e42d7b 100644
--- a/sys/dev/isp/ispmbox.h
+++ b/sys/dev/isp/ispmbox.h
@@ -46,7 +46,7 @@
/* a */
/* b */
/* c */
- /* d */
+#define MBOX_WRITE_RAM_WORD_EXTENDED 0x000d
#define MBOX_CHECK_FIRMWARE 0x000e
#define MBOX_READ_RAM_WORD_EXTENDED 0x000f
#define MBOX_INIT_REQ_QUEUE 0x0010
@@ -691,9 +691,11 @@ typedef struct isp_icb {
#define ICBXOPT_RIO_16BIT_IOCB 3
#define ICBXOPT_RIO_32BIT_IOCB 4
#define ICBXOPT_ZIO 5
+#define ICBXOPT_TIMER_MASK 0x7
#define ICBZOPT_ENA_RDXFR_RDY 0x01
#define ICBZOPT_ENA_OOF (1 << 6) /* out of order frame handling */
+#define ICBZOPT_50_OHM 0x0200
/* These 3 only apply to the 2300 */
#define ICBZOPT_RATE_ONEGB (MBGSD_ONEGB << 14)
#define ICBZOPT_RATE_TWOGB (MBGSD_TWOGB << 14)
diff --git a/sys/dev/isp/ispreg.h b/sys/dev/isp/ispreg.h
index a53751fc57b98..8c5e5d413ee28 100644
--- a/sys/dev/isp/ispreg.h
+++ b/sys/dev/isp/ispreg.h
@@ -204,7 +204,8 @@
#define BIU2100_FB_REGS (1 << 4) /* FrameBuffer Regs */
#define BIU2100_FPM0_REGS (2 << 4) /* FPM 0 Regs */
#define BIU2100_FPM1_REGS (3 << 4) /* FPM 1 Regs */
-#define BIU2100_PCI64 0x04 /* R: 64 Bit PCI slot */
+#define BIU2100_NVRAM_OFFSET (1 << 14)
+#define BIU2100_FLASH_UPPER_64K 0x04 /* RW: Upper 64K Bank Select */
#define BIU2100_FLASH_ENABLE 0x02 /* RW: Enable Flash RAM */
#define BIU2100_SOFT_RESET 0x01
/* SOFT RESET FOR ISP2100 is same bit, but in this register, not ICR */
@@ -268,6 +269,7 @@
#define BIU_NVRAM_SELECT 0x0002
#define BIU_NVRAM_DATAOUT 0x0004
#define BIU_NVRAM_DATAIN 0x0008
+#define BIU_NVRAM_BUSY 0x0080 /* 2322/24xx only */
#define ISP_NVRAM_READ 6
/* COMNMAND && DATA DMA CONFIGURATION REGISTER */
@@ -947,7 +949,7 @@ typedef struct {
#define ISP2100_NVRAM_SIZE 256
/* ISP_NVRAM_VERSION is in same overall place */
#define ISP2100_NVRAM_RISCVER(c) (c)[6]
-#define ISP2100_NVRAM_OPTIONS(c) (c)[8]
+#define ISP2100_NVRAM_OPTIONS(c) ((c)[8] | ((c)[9] << 8))
#define ISP2100_NVRAM_MAXFRAMELENGTH(c) (((c)[10]) | ((c)[11] << 8))
#define ISP2100_NVRAM_MAXIOCBALLOCATION(c) (((c)[12]) | ((c)[13] << 8))
#define ISP2100_NVRAM_EXECUTION_THROTTLE(c) (((c)[14]) | ((c)[15] << 8))
@@ -964,9 +966,10 @@ typedef struct {
(((uint64_t)(c)[24]) << 8) | \
(((uint64_t)(c)[25]) << 0))
-#define ISP2100_NVRAM_HARDLOOPID(c) (c)[26]
+#define ISP2100_NVRAM_HARDLOOPID(c) ((c)[26] | ((c)[27] << 8))
+#define ISP2100_NVRAM_TOV(c) ((c)[29])
-#define ISP2200_NVRAM_NODE_NAME(c) (\
+#define ISP2100_NVRAM_NODE_NAME(c) (\
(((uint64_t)(c)[30]) << 56) | \
(((uint64_t)(c)[31]) << 48) | \
(((uint64_t)(c)[32]) << 40) | \
@@ -976,7 +979,16 @@ typedef struct {
(((uint64_t)(c)[36]) << 8) | \
(((uint64_t)(c)[37]) << 0))
-#define ISP2100_NVRAM_HBA_OPTIONS(c) (c)[70]
+#define ISP2100_XFW_OPTIONS(c) ((c)[38] | ((c)[39] << 8))
+
+#define ISP2100_RACC_TIMER(c) (c)[40]
+#define ISP2100_IDELAY_TIMER(c) (c)[41]
+
+#define ISP2100_ZFW_OPTIONS(c) ((c)[42] | ((c)[43] << 8))
+
+#define ISP2100_SERIAL_LINK(c) ((c)[68] | ((c)[69] << 8))
+
+#define ISP2100_NVRAM_HBA_OPTIONS(c) ((c)[70] | ((c)[71] << 8))
#define ISP2100_NVRAM_HBA_DISABLE(c) ISPBSMX(c, 70, 0, 0x01)
#define ISP2100_NVRAM_BIOS_DISABLE(c) ISPBSMX(c, 70, 1, 0x01)
#define ISP2100_NVRAM_LUN_DISABLE(c) ISPBSMX(c, 70, 2, 0x01)
@@ -995,8 +1007,9 @@ typedef struct {
(((uint64_t)(c)[79]) << 0))
#define ISP2100_NVRAM_BOOT_LUN(c) (c)[80]
+#define ISP2100_RESET_DELAY(c) (c)[81]
-#define ISP2200_HBA_FEATURES(c) (c)[232] | ((c)[233] << 8)
+#define ISP2100_HBA_FEATURES(c) ((c)[232] | ((c)[233] << 8))
/*
* Firmware Crash Dump
diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h
index 3b0ef8dabeef8..59a7cd0d670c4 100644
--- a/sys/dev/isp/ispvar.h
+++ b/sys/dev/isp/ispvar.h
@@ -234,17 +234,19 @@ typedef struct {
typedef struct {
uint32_t : 13,
isp_gbspeed : 3,
- : 2,
+ : 1,
isp_iid_set : 1,
loop_seen_once : 1,
isp_loopstate : 4, /* Current Loop State */
- isp_fwstate : 3, /* ISP F/W state */
+ isp_fwstate : 4, /* ISP F/W state */
isp_gotdparms : 1,
isp_topo : 3,
isp_onfabric : 1;
uint32_t : 8,
isp_portid : 24; /* S_ID */
uint16_t isp_fwoptions;
+ uint16_t isp_xfwoptions;
+ uint16_t isp_zfwoptions;
uint16_t isp_iid; /* 'initiator' id */
uint16_t isp_loopid; /* hard loop id */
uint16_t isp_fwattr; /* firmware attributes */
@@ -380,8 +382,7 @@ struct ispsoftc {
* Volatile state
*/
- volatile uint32_t
- isp_obits : 8, /* mailbox command output */
+ volatile uint32_t : 8,
isp_mboxbsy : 1, /* mailbox command active */
isp_state : 3,
isp_sendmarker : 2, /* send a marker entry */
@@ -393,11 +394,13 @@ struct ispsoftc {
volatile uint16_t isp_resodx; /* index of next result */
volatile uint16_t isp_rspbsy;
volatile uint16_t isp_lasthdls; /* last handle seed */
+ volatile uint16_t isp_obits; /* mailbox command output */
volatile uint16_t isp_mboxtmp[MAILBOX_STORAGE];
volatile uint16_t isp_lastmbxcmd; /* last mbox command sent */
volatile uint16_t isp_mbxwrk0;
volatile uint16_t isp_mbxwrk1;
volatile uint16_t isp_mbxwrk2;
+ volatile uint16_t isp_mbxwrk8;
void * isp_mbxworkp;
/*
@@ -428,9 +431,10 @@ struct ispsoftc {
* ISP Driver Run States
*/
#define ISP_NILSTATE 0
-#define ISP_RESETSTATE 1
-#define ISP_INITSTATE 2
-#define ISP_RUNSTATE 3
+#define ISP_CRASHED 1
+#define ISP_RESETSTATE 2
+#define ISP_INITSTATE 3
+#define ISP_RUNSTATE 4
/*
* ISP Configuration Options