summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2002-02-04 21:04:25 +0000
committermjacob <mjacob@FreeBSD.org>2002-02-04 21:04:25 +0000
commit6d2dbc994419de3783c034893bc621f5c5adb66f (patch)
tree6bc5ce3afd87000d0d3bd51b3708bd7ccb43fbc6 /sys
parent451f832b15e0cbdcd136f1c8cbea2496ca4fa965 (diff)
downloadFreeBSD-src-6d2dbc994419de3783c034893bc621f5c5adb66f.zip
FreeBSD-src-6d2dbc994419de3783c034893bc621f5c5adb66f.tar.gz
+ A variety of 23XX changes:
disable MWI on 2300 based on function code, set an 'isp_port' for the 2312- it's a separate instance, but the NVRAM is shared, and the second port's NVRAM is at offset 256. + Enable RIO operation for LVD SCSI cards. This makes a *big* difference as even under reasonable load we get batched completions of about 30 commands at a time on, say, an ISP1080. + Do 'continuation' mailbox commands- this allows us to specify a work area within the softc and 'continue' repeated mailbox commands. This is more or less on an ad hoc basis and is currently only used for firmware loading (which f/w now loads substantially faster becuase the calling thread is only woken when all the f/w words are loaded- not for each one of the 40000 f/w words that gets loaded). + If we're about to return from isp_intr with a 'bogus interrupt' indication, and we're not a 23XX card, check to see whether the semaphore register is currently *2* (not *1* as it should be) and whether there's an async completion sitting in outgoing mailbox0. This seems to capture cases of lost fast posting and RIO interrupts that the 12160 && 1080 have been known to pump out under extreme load (extreme, as in > 250 active commands). + FC_SCRATCH_ACQUIRE/FC_SCRATCH_RELEASE macros. + Endian correct swizzle/unswizzle of an ATIO2 that has a WWPN in it. MFC after: 1 week
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/isp/isp.c187
-rw-r--r--sys/dev/isp/isp_freebsd.h11
-rw-r--r--sys/dev/isp/isp_inline.h16
-rw-r--r--sys/dev/isp/isp_ioctl.h12
-rw-r--r--sys/dev/isp/isp_pci.c21
-rw-r--r--sys/dev/isp/isp_target.c5
-rw-r--r--sys/dev/isp/isp_target.h5
-rw-r--r--sys/dev/isp/ispmbox.h4
-rw-r--r--sys/dev/isp/ispreg.h3
-rw-r--r--sys/dev/isp/ispvar.h11
10 files changed, 219 insertions, 56 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 094d029..35d6587f 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -115,6 +115,7 @@ static int isp_handle_other_response(struct ispsoftc *, int, isphdr_t *,
static void
isp_parse_status(struct ispsoftc *, ispstatusreq_t *, XS_T *);
static void isp_fastpost_complete(struct ispsoftc *, u_int16_t);
+static int isp_mbox_continue(struct ispsoftc *);
static void isp_scsi_init(struct ispsoftc *);
static void isp_scsi_channel_init(struct ispsoftc *, int);
static void isp_fibre_init(struct ispsoftc *);
@@ -129,6 +130,7 @@ static int isp_scan_loop(struct ispsoftc *);
static int isp_scan_fabric(struct ispsoftc *);
static void isp_register_fc4_type(struct ispsoftc *);
static void isp_fw_state(struct ispsoftc *);
+static void isp_mboxcmd_qnw(struct ispsoftc *, mbreg_t *);
static void isp_mboxcmd(struct ispsoftc *, mbreg_t *, int);
static void isp_update(struct ispsoftc *);
@@ -240,9 +242,11 @@ isp_reset(struct ispsoftc *isp)
btype = "2200";
break;
case ISP_HA_FC_2300:
- case ISP_HA_FC_2312:
btype = "2300";
break;
+ case ISP_HA_FC_2312:
+ btype = "2312";
+ break;
default:
break;
}
@@ -626,20 +630,20 @@ again:
code_org = ISP_CODE_ORG;
if (dodnld) {
- u_int16_t fwlen = isp->isp_mdvec->dv_ispfw[3];
- for (i = 0; i < fwlen; i++) {
- mbs.param[0] = MBOX_WRITE_RAM_WORD;
- mbs.param[1] = code_org + i;
- mbs.param[2] = isp->isp_mdvec->dv_ispfw[i];
- isp_mboxcmd(isp, &mbs, MBLOGNONE);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_prt(isp, ISP_LOGERR,
- "F/W download failed at word %d", i);
- dodnld = 0;
- goto again;
- }
+ isp->isp_mbxworkp = (void *) &isp->isp_mdvec->dv_ispfw[1];
+ isp->isp_mbxwrk0 = isp->isp_mdvec->dv_ispfw[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];
+ isp_mboxcmd(isp, &mbs, MBLOGNONE);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ isp_prt(isp, ISP_LOGERR,
+ "F/W download failed at word %d",
+ isp->isp_mbxwrk1 - code_org);
+ dodnld = 0;
+ goto again;
}
-
/*
* Verify that it downloaded correctly.
*/
@@ -967,8 +971,15 @@ isp_scsi_init(struct ispsoftc *isp)
mbs.param[1] = 0;
if (IS_ULTRA2(isp))
mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
+#ifndef ISP_NO_RIO
+ 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) {
u_int16_t sfeat = mbs.param[1];
isp_mboxcmd(isp, &mbs, MBLOGALL);
@@ -1225,7 +1236,7 @@ isp_fibre_init(struct ispsoftc *isp)
break;
}
if (IS_23XX(isp)) {
- if (!IS_2312(isp) && isp->isp_revision < 2) {
+ if (IS_2300(isp) && isp->isp_revision < 2) {
icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
}
if (isp->isp_confopts & ISP_CFG_ONEGB) {
@@ -1236,9 +1247,13 @@ isp_fibre_init(struct ispsoftc *isp)
icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
}
}
- icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
- icbp->icb_racctimer = 4;
- icbp->icb_idelaytimer = 8;
+#ifndef ISP_NO_RIO_FC
+ if ((isp->isp_role & ISP_ROLE_TARGET) == 0) {
+ icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
+ icbp->icb_racctimer = 4;
+ icbp->icb_idelaytimer = 8;
+ }
+#endif
}
if ((IS_2200(isp) && ISP_FW_REVX(isp->isp_fwrev) >=
@@ -1291,6 +1306,8 @@ isp_fibre_init(struct ispsoftc *isp)
icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
isp_prt(isp, ISP_LOGDEBUG1,
"isp_fibre_init: fwoptions 0x%x", fcp->isp_fwoptions);
+
+ FC_SCRATCH_ACQUIRE(isp);
isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
/*
@@ -1305,6 +1322,7 @@ isp_fibre_init(struct ispsoftc *isp)
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
isp_mboxcmd(isp, &mbs, MBLOGALL);
+ FC_SCRATCH_RELEASE(isp);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
}
@@ -1344,12 +1362,15 @@ isp_getmap(struct ispsoftc *isp, fcpos_map_t *map)
*/
mbs.param[6] = 0;
mbs.param[7] = 0;
+ FC_SCRATCH_ACQUIRE(isp);
isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
MEMCPY(map, fcp->isp_scratch, sizeof (fcpos_map_t));
map->fwmap = mbs.param[1] != 0;
+ FC_SCRATCH_RELEASE(isp);
return (0);
}
+ FC_SCRATCH_RELEASE(isp);
return (-1);
}
@@ -1382,11 +1403,14 @@ isp_getpdb(struct ispsoftc *isp, int id, isp_pdb_t *pdbp)
*/
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
+ FC_SCRATCH_ACQUIRE(isp);
isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
isp_get_pdb(isp, (isp_pdb_t *)fcp->isp_scratch, pdbp);
+ FC_SCRATCH_RELEASE(isp);
return (0);
}
+ FC_SCRATCH_RELEASE(isp);
return (-1);
}
@@ -1611,7 +1635,7 @@ not_on_fabric:
}
}
- isp_prt(isp, ISP_LOGINFO, topology, fcp->isp_loopid, fcp->isp_alpa,
+ isp_prt(isp, ISP_LOGCONFIG, topology, fcp->isp_loopid, fcp->isp_alpa,
fcp->isp_portid, fcp->isp_loopstate, toponames[fcp->isp_topo]);
/*
@@ -1807,7 +1831,7 @@ isp_pdb_sync(struct ispsoftc *isp)
nwwnn == lp->node_wwn && nwwpn == lp->port_wwn &&
lp->roles == nrole && lp->force_logout == 0) {
lp->loggedin = lp->valid = 1;
- isp_prt(isp, ISP_LOGINFO, lretained,
+ isp_prt(isp, ISP_LOGCONFIG, lretained,
(int) (lp - fcp->portdb),
(int) lp->loopid, lp->portid);
continue;
@@ -2282,7 +2306,6 @@ isp_scan_fabric(struct ispsoftc *isp)
first_portid = portid = fcp->isp_portid;
fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
-
for (first_portid_seen = hicap = 0; hicap < 65535; hicap++) {
mbreg_t mbs;
sns_screq_t *rq;
@@ -2300,6 +2323,7 @@ isp_scan_fabric(struct ispsoftc *isp)
rq->snscb_data[0] = SNS_GAN;
rq->snscb_data[4] = portid & 0xffff;
rq->snscb_data[5] = (portid >> 16) & 0xff;
+ FC_SCRATCH_ACQUIRE(isp);
isp_put_sns_request(isp, rq, (sns_screq_t *) fcp->isp_scratch);
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GAN_REQ_SIZE);
mbs.param[0] = MBOX_SEND_SNS;
@@ -2350,12 +2374,14 @@ isp_scan_fabric(struct ispsoftc *isp)
}
if (fcp->isp_fwstate != FW_READY ||
fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
+ FC_SCRATCH_RELEASE(isp);
return (-1);
}
MEMORYBARRIER(isp, SYNC_SFORCPU, 0x100, SNS_GAN_RESP_SIZE);
rs1 = (sns_ganrsp_t *) fcp->isp_scratch;
rs0 = (sns_ganrsp_t *) ((u_int8_t *)fcp->isp_scratch + 0x100);
isp_get_gan_response(isp, rs0, rs1);
+ FC_SCRATCH_RELEASE(isp);
portid = (((u_int32_t) rs1->snscb_port_id[0]) << 16) |
(((u_int32_t) rs1->snscb_port_id[1]) << 8) |
(((u_int32_t) rs1->snscb_port_id[2]));
@@ -2408,6 +2434,7 @@ isp_register_fc4_type(struct ispsoftc *isp)
#if 0
reqp->snscb_data[6] |= 20; /* ISO/IEC 8802-2 LLC/SNAP */
#endif
+ FC_SCRATCH_ACQUIRE(isp);
isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_RFT_REQ_SIZE >> 1;
@@ -2419,6 +2446,7 @@ isp_register_fc4_type(struct ispsoftc *isp)
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
isp_mboxcmd(isp, &mbs, MBLOGALL);
+ FC_SCRATCH_RELEASE(isp);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 types succeeded");
}
@@ -2983,7 +3011,9 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
* Limit our stack depth by sticking with the max likely number
* of completions on a request queue at any one time.
*/
+#ifndef MAX_REQUESTQ_COMPLETIONS
#define MAX_REQUESTQ_COMPLETIONS 64
+#endif
void
isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
@@ -2992,12 +3022,14 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
u_int16_t iptr, optr, junk;
int i, nlooked = 0, ndone = 0;
+again:
/*
* Is this a mailbox related interrupt?
* The mailbox semaphore will be nonzero if so.
*/
if (sema) {
if (mbox & 0x4000) {
+ isp->isp_intmboxc++;
if (isp->isp_mboxbsy) {
int i = 0, obits = isp->isp_obits;
isp->isp_mboxtmp[i++] = mbox;
@@ -3008,13 +3040,17 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
isp->isp_mboxtmp[i] =
ISP_READ(isp, MBOX_OFF(i));
}
+ if (isp->isp_mbxwrk0) {
+ if (isp_mbox_continue(isp) == 0) {
+ return;
+ }
+ }
MBOX_NOTIFY_COMPLETE(isp);
} else {
isp_prt(isp, ISP_LOGWARN,
"Mbox Command Async (0x%x) with no waiters",
mbox);
}
- isp->isp_intmboxc++;
} else if (isp_parse_async(isp, mbox) < 0) {
return;
}
@@ -3049,6 +3085,9 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
*/
if (IS_23XX(isp)) {
optr = ISP_READ(isp, isp->isp_respoutrp);
+ /*
+ * Debug: to be taken out eventually
+ */
if (isp->isp_residx != optr) {
isp_prt(isp, ISP_LOGWARN, "optr %x soft optr %x",
optr, isp->isp_residx);
@@ -3099,10 +3138,19 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
junk = ISP_READ(isp, BIU_ISR);
}
if (optr == iptr) {
- isp_prt(isp, ISP_LOGDEBUG0,
+ if (IS_23XX(isp)) {
+ ;
+ } else {
+ sema = ISP_READ(isp, BIU_SEMA);
+ mbox = ISP_READ(isp, OUTMAILBOX0);
+ if ((sema & 0x3) && (mbox & 0x8000)) {
+ goto again;
+ }
+ }
+ isp->isp_intbogus++;
+ isp_prt(isp, ISP_LOGDEBUG1,
"bogus intr- isr %x (%x) iptr %x optr %x",
isr, junk, iptr, optr);
- isp->isp_intbogus++;
}
}
ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
@@ -3526,13 +3574,13 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
* Bus gets overloaded with the handle. Dual bus
* cards don't put bus# into the handle.
*/
- bus = (ISP_READ(isp, OUTMAILBOX2) << 16) |
- ISP_READ(isp, OUTMAILBOX1);
- isp_target_async(isp, bus, mbox);
+ isp_target_async(isp, ((ISP_READ(isp, OUTMAILBOX2) << 16) |
+ ISP_READ(isp, OUTMAILBOX1)), mbox);
#else
isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
#endif
- break;
+ isp->isp_fphccmplt++; /* count it as a fast posting intr */
+ return (0);
case ASYNC_LIP_F8:
case ASYNC_LIP_OCCURRED:
@@ -3727,6 +3775,7 @@ isp_handle_other_response(struct ispsoftc *isp, int type,
case RQSTYPE_ATIO2:
case RQSTYPE_CTIO2:
case RQSTYPE_CTIO3:
+ isp->isp_rsltccmplt++; /* count as a response completion */
#ifdef ISP_TARGET_MODE
return (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp));
#else
@@ -4120,6 +4169,40 @@ isp_fastpost_complete(struct ispsoftc *isp, u_int16_t fph)
isp_done(xs);
}
+static int
+isp_mbox_continue(struct ispsoftc *isp)
+{
+ mbreg_t mbs;
+ u_int16_t *ptr;
+
+ if (isp->isp_lastmbxcmd != MBOX_WRITE_RAM_WORD) {
+ return (1);
+ }
+ if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
+ isp->isp_mbxwrk0 = 0;
+ return (-1);
+ }
+
+ /*
+ * Clear the previous interrupt.
+ */
+ ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
+ ISP_WRITE(isp, BIU_SEMA, 0);
+
+ /*
+ * Continue with next word.
+ */
+ mbs.param[0] = MBOX_WRITE_RAM_WORD;
+ mbs.param[1] = isp->isp_mbxwrk1++;
+ ptr = isp->isp_mbxworkp;
+ mbs.param[2] = *ptr++;
+ isp->isp_mbxworkp = ptr;
+ isp->isp_mbxwrk0 -= 1;
+ isp_mboxcmd_qnw(isp, &mbs);
+ return (0);
+}
+
+
#define HIBYT(x) ((x) >> 0x8)
#define LOBYT(x) ((x) & 0xff)
#define ISPOPMAP(a, b) (((a) << 8) | (b))
@@ -4582,6 +4665,34 @@ static char *fc_mbcmd_names[] = {
#endif
static void
+isp_mboxcmd_qnw(struct ispsoftc *isp, mbreg_t *mbp)
+{
+ unsigned int lim, ibits, obits, box, opcode;
+ u_int16_t *mcp;
+
+ if (IS_FC(isp)) {
+ mcp = mbpfc;
+ lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
+ } else {
+ mcp = mbpscsi;
+ lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
+ }
+ opcode = mbp->param[0];
+ ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
+ obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
+ for (box = 0; box < MAX_MAILBOX; box++) {
+ if (ibits & (1 << box)) {
+ ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
+ }
+ isp->isp_mboxtmp[box] = mbp->param[box] = 0;
+ }
+ isp->isp_lastmbxcmd = opcode;
+ isp->isp_obits = obits;
+ isp->isp_mboxbsy = 1;
+ ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
+}
+
+static void
isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
{
char *cname, *xname, tname[16], mname[16];
@@ -5218,6 +5329,9 @@ isp_rdnvram_word(struct ispsoftc *isp, int wo, u_int16_t *rp)
if (IS_FC(isp)) {
wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
+ if (IS_2312(isp) && isp->isp_port) {
+ wo += 128;
+ }
rqst = (ISP_NVRAM_READ << 8) | wo;
cbits = 10;
} else if (IS_ULTRA2(isp)) {
@@ -5600,13 +5714,18 @@ isp_parse_nvram_2100(struct ispsoftc *isp, u_int8_t *nvram_data)
}
}
fcp->isp_portwwn = wwn;
- wwn = ISP2100_NVRAM_NODE_NAME(nvram_data);
- if (wwn) {
- isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
- (u_int32_t) (wwn >> 32), (u_int32_t) (wwn & 0xffffffff));
- if ((wwn >> 60) == 0) {
- wwn |= (((u_int64_t) 2)<< 60);
+ if (IS_2200(isp) || IS_23XX(isp)) {
+ wwn = ISP2200_NVRAM_NODE_NAME(nvram_data);
+ if (wwn) {
+ isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
+ (u_int32_t) (wwn >> 32),
+ (u_int32_t) (wwn & 0xffffffff));
+ if ((wwn >> 60) == 0) {
+ wwn |= (((u_int64_t) 2)<< 60);
+ }
}
+ } else {
+ wwn &= ~((u_int64_t) 0xfff << 48);
}
fcp->isp_nodewwn = wwn;
diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h
index fbf9def..1aa6b83 100644
--- a/sys/dev/isp/isp_freebsd.h
+++ b/sys/dev/isp/isp_freebsd.h
@@ -71,7 +71,7 @@
#define HANDLE_LOOPSTATE_IN_OUTER_LAYERS 1
-typedef void ispfwfunc __P((int, int, int, const u_int16_t **));
+typedef void ispfwfunc __P((int, int, int, u_int16_t **));
#ifdef ISP_TARGET_MODE
#define ISP_TARGET_FUNCTIONS 1
@@ -192,6 +192,9 @@ struct isposinfo {
isp->isp_mboxbsy = 0
#define MBOX_RELEASE(isp)
+#define FC_SCRATCH_ACQUIRE(isp)
+#define FC_SCRATCH_RELEASE(isp)
+
#ifndef SCSI_GOOD
#define SCSI_GOOD SCSI_STATUS_OK
#endif
@@ -363,9 +366,10 @@ static INLINE void
isp_mbox_wait_complete(struct ispsoftc *isp)
{
if (isp->isp_osinfo.intsok) {
+ int lim = ((isp->isp_mbxwrk0)? 120 : 20) * hz;
isp->isp_osinfo.mboxwaiting = 1;
(void) msleep(&isp->isp_osinfo.mboxwaiting,
- &isp->isp_lock, PRIBIO, "isp_mboxwaiting", 10 * hz);
+ &isp->isp_lock, PRIBIO, "isp_mboxwaiting", lim);
if (isp->isp_mboxbsy != 0) {
isp_prt(isp, ISP_LOGWARN,
"Interrupting Mailbox Command (0x%x) Timeout",
@@ -374,8 +378,9 @@ isp_mbox_wait_complete(struct ispsoftc *isp)
}
isp->isp_osinfo.mboxwaiting = 0;
} else {
+ int lim = ((isp->isp_mbxwrk0)? 240 : 60) * 10000;
int j;
- for (j = 0; j < 60 * 10000; j++) {
+ for (j = 0; j < lim; j++) {
u_int16_t isr, sema, mbox;
if (isp->isp_mboxbsy == 0) {
break;
diff --git a/sys/dev/isp/isp_inline.h b/sys/dev/isp/isp_inline.h
index 7a90293..f65c365 100644
--- a/sys/dev/isp/isp_inline.h
+++ b/sys/dev/isp/isp_inline.h
@@ -379,7 +379,7 @@ isp_copy_in_hdr(struct ispsoftc *isp, isphdr_t *hpsrc, isphdr_t *hpdst)
static INLINE int
isp_get_response_type(struct ispsoftc *isp, isphdr_t *hp)
{
- uint8_t type;
+ u_int8_t type;
if (ISP_IS_SBUS(isp)) {
ISP_IOXGET_8(isp, &hp->rqs_entry_count, type);
} else {
@@ -856,8 +856,11 @@ isp_put_atio2(struct ispsoftc *isp, at2_entry_t *atsrc, at2_entry_t *atdst)
}
ISP_IOXPUT_32(isp, atsrc->at_datalen, &atdst->at_datalen);
ISP_IOXPUT_16(isp, atsrc->at_scclun, &atdst->at_scclun);
- for (i = 0; i < 10; i++) {
- ISP_IOXPUT_8(isp, atsrc->at_reserved2[i],
+ for (i = 0; i < 4; i++) {
+ ISP_IOXPUT_16(isp, atsrc->at_wwpn[i], &atdst->at_wwpn[i]);
+ }
+ for (i = 0; i < 6; i++) {
+ ISP_IOXPUT_16(isp, atsrc->at_reserved2[i],
&atdst->at_reserved2[i]);
}
ISP_IOXPUT_16(isp, atsrc->at_oxid, &atdst->at_oxid);
@@ -883,8 +886,11 @@ isp_get_atio2(struct ispsoftc *isp, at2_entry_t *atsrc, at2_entry_t *atdst)
}
ISP_IOXGET_32(isp, &atsrc->at_datalen, atdst->at_datalen);
ISP_IOXGET_16(isp, &atsrc->at_scclun, atdst->at_scclun);
- for (i = 0; i < 10; i++) {
- ISP_IOXGET_8(isp, &atsrc->at_reserved2[i],
+ for (i = 0; i < 4; i++) {
+ ISP_IOXGET_16(isp, &atsrc->at_wwpn[i], atdst->at_wwpn[i]);
+ }
+ for (i = 0; i < 6; i++) {
+ ISP_IOXGET_16(isp, &atsrc->at_reserved2[i],
atdst->at_reserved2[i]);
}
ISP_IOXGET_16(isp, &atsrc->at_oxid, atdst->at_oxid);
diff --git a/sys/dev/isp/isp_ioctl.h b/sys/dev/isp/isp_ioctl.h
index b52b2b5..61f921b 100644
--- a/sys/dev/isp/isp_ioctl.h
+++ b/sys/dev/isp/isp_ioctl.h
@@ -79,11 +79,11 @@ struct isp_fc_device {
*/
#define ISP_STATS_VERSION 0
typedef struct {
- uint8_t isp_stat_version;
- uint8_t isp_type; /* (ro) reflects chip type */
- uint8_t isp_revision; /* (ro) reflects chip version */
- uint8_t unused1;
- uint32_t unused2;
+ u_int8_t isp_stat_version;
+ u_int8_t isp_type; /* (ro) reflects chip type */
+ u_int8_t isp_revision; /* (ro) reflects chip version */
+ u_int8_t unused1;
+ u_int32_t unused2;
/*
* Statistics Counters
*/
@@ -96,7 +96,7 @@ typedef struct {
#define ISP_FPHCCMCPLT 5
#define ISP_RSCCHIWAT 6
#define ISP_FPCCHIWAT 7
- uint64_t isp_stats[ISP_NSTATS];
+ u_int64_t isp_stats[ISP_NSTATS];
} isp_stats_t;
#define ISP_GET_STATS _IOR(ISP_IOC, 6, isp_stats_t)
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index 95c40e79..2dfac81 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -496,14 +496,20 @@ isp_pci_attach(device_t dev)
pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
PCI_MBOX_REGS2100_OFF;
}
- if (pci_get_devid(dev) == PCI_QLOGIC_ISP2300 ||
- pci_get_devid(dev) == PCI_QLOGIC_ISP2312) {
+ if (pci_get_devid(dev) == PCI_QLOGIC_ISP2300) {
mdvp = &mdvec_2300;
basetype = ISP_HA_FC_2300;
psize = sizeof (fcparam);
pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
PCI_MBOX_REGS2300_OFF;
}
+ if (pci_get_devid(dev) == PCI_QLOGIC_ISP2312) {
+ mdvp = &mdvec_2300;
+ basetype = ISP_HA_FC_2312;
+ psize = sizeof (fcparam);
+ pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
+ PCI_MBOX_REGS2300_OFF;
+ }
isp = &pcs->pci_isp;
isp->isp_param = malloc(psize, M_DEVBUF, M_NOWAIT | M_ZERO);
if (isp->isp_param == NULL) {
@@ -535,6 +541,9 @@ isp_pci_attach(device_t dev)
*/
cmd |= PCIM_CMD_SEREN | PCIM_CMD_PERRESPEN |
PCIM_CMD_BUSMASTEREN | PCIM_CMD_INVEN;
+ if (IS_2300(isp)) { /* per QLogic errata */
+ cmd &= ~PCIM_CMD_INVEN;
+ }
pci_write_config(dev, PCIR_COMMAND, cmd, 1);
/*
@@ -684,6 +693,13 @@ isp_pci_attach(device_t dev)
isp->isp_dblev |= ISP_LOGCONFIG|ISP_LOGINFO;
/*
+ * Last minute checks...
+ */
+ if (IS_2312(isp)) {
+ isp->isp_port = pci_get_function(dev);
+ }
+
+ /*
* Make sure we're in reset state.
*/
ISP_LOCK(isp);
@@ -852,6 +868,7 @@ isp_pci_rd_isr_2300(struct ispsoftc *isp, u_int16_t *isrp,
case ISPR2HST_MBX_OK:
case ISPR2HST_MBX_FAIL:
case ISPR2HST_ASYNC_EVENT:
+ case ISPR2HST_RIO_16:
case ISPR2HST_FPOST:
case ISPR2HST_FPOST_CTIO:
*isrp = r2hisr & 0xffff;
diff --git a/sys/dev/isp/isp_target.c b/sys/dev/isp/isp_target.c
index a4bcf6f..05a8446 100644
--- a/sys/dev/isp/isp_target.c
+++ b/sys/dev/isp/isp_target.c
@@ -29,6 +29,10 @@
*/
/*
+ * Bug fixes gratefully acknowledged from:
+ * Oded Kedem <oded@kashya.com>
+ */
+/*
* Include header file appropriate for platform we're building on.
*/
@@ -678,6 +682,7 @@ isp_notify_ack(struct ispsoftc *isp, void *arg)
na->na_task_flags = inp->in_task_flags;
na->na_seqid = inp->in_seqid;
na->na_flags = NAFC_RCOUNT;
+ na->na_status = inp->in_status;
if (inp->in_status == IN_RESET) {
na->na_flags |= NAFC_RST_CLRD;
}
diff --git a/sys/dev/isp/isp_target.h b/sys/dev/isp/isp_target.h
index f714f1e..f911a17 100644
--- a/sys/dev/isp/isp_target.h
+++ b/sys/dev/isp/isp_target.h
@@ -280,8 +280,9 @@ typedef struct {
u_int8_t at_execodes;
u_int8_t at_cdb[ATIO2_CDBLEN]; /* received CDB */
u_int32_t at_datalen; /* allocated data len */
- u_int16_t at_scclun; /* SCC Lun or reserved */
- u_int16_t at_reserved2[10];
+ u_int16_t at_scclun; /* SCC Lun or reserved */
+ u_int16_t at_wwpn[4]; /* WWPN of initiator */
+ u_int16_t at_reserved2[6];
u_int16_t at_oxid;
} at2_entry_t;
diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h
index 6204f46..bc4ae54 100644
--- a/sys/dev/isp/ispmbox.h
+++ b/sys/dev/isp/ispmbox.h
@@ -104,8 +104,10 @@
#define MBOX_EXEC_BIOS_IOCB 0x0042
#define MBOX_SET_FW_FEATURES 0x004a
#define MBOX_GET_FW_FEATURES 0x004b
-#define FW_FEATURE_LVD_NOTIFY 0x2
#define FW_FEATURE_FAST_POST 0x1
+#define FW_FEATURE_LVD_NOTIFY 0x2
+#define FW_FEATURE_RIO_32BIT 0x4
+#define FW_FEATURE_RIO_16BIT 0x8
#define MBOX_ENABLE_TARGET_MODE 0x0055
#define ENABLE_TARGET_FLAG 0x8000
diff --git a/sys/dev/isp/ispreg.h b/sys/dev/isp/ispreg.h
index 3904525..7a57b5a 100644
--- a/sys/dev/isp/ispreg.h
+++ b/sys/dev/isp/ispreg.h
@@ -955,7 +955,7 @@
#define ISP2100_NVRAM_HARDLOOPID(c) (c)[26]
-#define ISP2100_NVRAM_NODE_NAME(c) (\
+#define ISP2200_NVRAM_NODE_NAME(c) (\
(((u_int64_t)(c)[30]) << 56) | \
(((u_int64_t)(c)[31]) << 48) | \
(((u_int64_t)(c)[32]) << 40) | \
@@ -985,4 +985,5 @@
#define ISP2100_NVRAM_BOOT_LUN(c) (c)[80]
+#define ISP2200_HBA_FEATURES(c) (c)[232] | ((c)[233] << 8)
#endif /* _ISPREG_H */
diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h
index b0b694d..40d82d1 100644
--- a/sys/dev/isp/ispvar.h
+++ b/sys/dev/isp/ispvar.h
@@ -73,7 +73,7 @@ struct ispmdvec {
void (*dv_reset0) (struct ispsoftc *);
void (*dv_reset1) (struct ispsoftc *);
void (*dv_dregs) (struct ispsoftc *, const char *);
- const u_int16_t *dv_ispfw; /* ptr to f/w */
+ u_int16_t *dv_ispfw; /* ptr to f/w */
u_int16_t dv_conf1;
u_int16_t dv_clock; /* clock frequency */
};
@@ -350,7 +350,8 @@ typedef struct ispsoftc {
u_int32_t isp_maxluns; /* maximum luns supported */
u_int32_t isp_clock : 8, /* input clock */
- : 5,
+ : 4,
+ isp_port : 1, /* 23XX only */
isp_failed : 1, /* board failed */
isp_open : 1, /* opened (ioctl) */
isp_touched : 1, /* board ever seen? */
@@ -395,6 +396,10 @@ typedef struct ispsoftc {
volatile u_int16_t isp_lasthdls; /* last handle seed */
volatile u_int16_t isp_mboxtmp[MAX_MAILBOX];
volatile u_int16_t isp_lastmbxcmd; /* last mbox command sent */
+ volatile u_int16_t isp_mbxwrk0;
+ volatile u_int16_t isp_mbxwrk1;
+ volatile u_int16_t isp_mbxwrk2;
+ void * isp_mbxworkp;
/*
* Active commands are stored here, indexed by handle functions.
@@ -772,6 +777,8 @@ void isp_prt(struct ispsoftc *, int level, const char *, ...);
* MBOX_NOTIFY_COMPLETE(struct ispsoftc *) notification of mbox cmd donee
* MBOX_RELEASE(struct ispsoftc *) release lock on mailbox regs
*
+ * FC_SCRATCH_ACQUIRE(struct ispsoftc *) acquire lock on FC scratch area
+ * FC_SCRATCH_RELEASE(struct ispsoftc *) acquire lock on FC scratch area
*
* SCSI_GOOD SCSI 'Good' Status
* SCSI_CHECK SCSI 'Check Condition' Status
OpenPOWER on IntegriCloud