summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/isp/isp.c310
-rw-r--r--sys/dev/isp/isp_freebsd.c166
-rw-r--r--sys/dev/isp/isp_freebsd.h12
-rw-r--r--sys/dev/isp/isp_pci.c269
-rw-r--r--sys/dev/isp/ispmbox.h45
-rw-r--r--sys/dev/isp/ispreg.h32
-rw-r--r--sys/dev/isp/ispvar.h59
7 files changed, 599 insertions, 294 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 6dd14e03a7cc..783fcea62b94 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -150,12 +150,14 @@ static void isp_parse_nvram_2100 __P((struct ispsoftc *, u_int8_t *));
*
* Locking done elsewhere.
*/
+
void
isp_reset(struct ispsoftc *isp)
{
mbreg_t mbs;
+ u_int16_t code_org;
int loops, i, touched, dodnld = 1;
- char *revname = "????";
+ char *btype = "????";
isp->isp_state = ISP_NILSTATE;
@@ -163,7 +165,8 @@ isp_reset(struct ispsoftc *isp)
/*
* Basic types (SCSI, FibreChannel and PCI or SBus)
* have been set in the MD code. We figure out more
- * here.
+ * here. Possibly more refined types based upon PCI
+ * identification. Chip revision has been gathered.
*
* After we've fired this chip up, zero out the conf1 register
* for SCSI adapters and do other settings for the 2100.
@@ -205,6 +208,14 @@ isp_reset(struct ispsoftc *isp)
}
DISABLE_INTS(isp);
+ /*
+ * Set up default request/response queue in-pointer/out-pointer
+ * register indices.
+ */
+ isp->isp_rqstinrp = INMAILBOX4;
+ isp->isp_rqstoutrp = OUTMAILBOX4;
+ isp->isp_respinrp = OUTMAILBOX5;
+ isp->isp_respoutrp = INMAILBOX5;
/*
* Put the board into PAUSE mode (so we can read the SXP registers
@@ -215,13 +226,17 @@ isp_reset(struct ispsoftc *isp)
if (IS_FC(isp)) {
switch (isp->isp_type) {
case ISP_HA_FC_2100:
- revname = "2100";
+ btype = "2100";
break;
case ISP_HA_FC_2200:
- revname = "2200";
+ btype = "2200";
break;
case ISP_HA_FC_2300:
- revname = "2300";
+ isp->isp_rqstinrp = BIU_REQINP;
+ isp->isp_rqstoutrp = BIU_REQOUTP;
+ isp->isp_respinrp = BIU_RSPINP;
+ isp->isp_respoutrp = BIU_RSPOUTP;
+ btype = "2300";
break;
default:
break;
@@ -236,7 +251,7 @@ isp_reset(struct ispsoftc *isp)
ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
} else if (IS_1240(isp)) {
sdparam *sdp = isp->isp_param;
- revname = "1240";
+ btype = "1240";
isp->isp_clock = 60;
sdp->isp_ultramode = 1;
sdp++;
@@ -252,13 +267,13 @@ isp_reset(struct ispsoftc *isp)
isp->isp_clock = 100;
if (IS_1280(isp))
- revname = "1280";
+ btype = "1280";
else if (IS_1080(isp))
- revname = "1080";
+ btype = "1080";
else if (IS_12160(isp))
- revname = "12160";
+ btype = "12160";
else
- revname = "<UNKLVD>";
+ btype = "<UNKLVD>";
l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
switch (l) {
@@ -313,7 +328,7 @@ isp_reset(struct ispsoftc *isp)
isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
/* FALLTHROUGH */
case 1:
- revname = "1020";
+ btype = "1020";
isp->isp_type = ISP_HA_SCSI_1020;
isp->isp_clock = 40;
break;
@@ -323,27 +338,27 @@ isp_reset(struct ispsoftc *isp)
* run the clock rate up for that unless told to
* do so by the Ultra Capable bits being set.
*/
- revname = "1020A";
+ btype = "1020A";
isp->isp_type = ISP_HA_SCSI_1020A;
isp->isp_clock = 40;
break;
case 3:
- revname = "1040";
+ btype = "1040";
isp->isp_type = ISP_HA_SCSI_1040;
isp->isp_clock = 60;
break;
case 4:
- revname = "1040A";
+ btype = "1040A";
isp->isp_type = ISP_HA_SCSI_1040A;
isp->isp_clock = 60;
break;
case 5:
- revname = "1040B";
+ btype = "1040B";
isp->isp_type = ISP_HA_SCSI_1040B;
isp->isp_clock = 60;
break;
case 6:
- revname = "1040C";
+ btype = "1040C";
isp->isp_type = ISP_HA_SCSI_1040C;
isp->isp_clock = 60;
break;
@@ -593,11 +608,16 @@ again:
dodnld = 0;
}
+ if (IS_2300(isp))
+ code_org = ISP_CODE_ORG_2300;
+ else
+ 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] = ISP_CODE_ORG + i;
+ 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) {
@@ -612,7 +632,7 @@ again:
* Verify that it downloaded correctly.
*/
mbs.param[0] = MBOX_VERIFY_CHECKSUM;
- mbs.param[1] = ISP_CODE_ORG;
+ mbs.param[1] = code_org;
isp_mboxcmd(isp, &mbs, MBLOGNONE);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGERR, "Ram Checksum Failure");
@@ -631,8 +651,9 @@ again:
* we still need to (re)start it.
*/
+
mbs.param[0] = MBOX_EXEC_FIRMWARE;
- mbs.param[1] = ISP_CODE_ORG;
+ mbs.param[1] = code_org;
isp_mboxcmd(isp, &mbs, MBLOGNONE);
/* give it a chance to start */
USEC_SLEEP(isp, 500);
@@ -655,9 +676,9 @@ again:
return;
}
isp_prt(isp, ISP_LOGCONFIG,
- "Board Revision %s, %s F/W Revision %d.%d.%d", revname,
- dodnld? "loaded" : "resident", mbs.param[1], mbs.param[2],
- mbs.param[3]);
+ "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
+ btype, isp->isp_revision, dodnld? "loaded" : "resident",
+ mbs.param[1], mbs.param[2], mbs.param[3]);
if (IS_FC(isp)) {
isp_prt(isp, ISP_LOGCONFIG, "Firmware Attributes = 0x%x",
mbs.param[6]);
@@ -871,8 +892,8 @@ isp_scsi_init(struct ispsoftc *isp)
mbs.param[0] = MBOX_INIT_RES_QUEUE;
mbs.param[1] = RESULT_QUEUE_LEN(isp);
- mbs.param[2] = DMA_MSW(isp->isp_result_dma);
- mbs.param[3] = DMA_LSW(isp->isp_result_dma);
+ mbs.param[2] = DMA_WD1(isp->isp_result_dma);
+ mbs.param[3] = DMA_WD0(isp->isp_result_dma);
mbs.param[4] = 0;
mbs.param[5] = 0;
isp_mboxcmd(isp, &mbs, MBLOGALL);
@@ -883,8 +904,8 @@ isp_scsi_init(struct ispsoftc *isp)
mbs.param[0] = MBOX_INIT_REQ_QUEUE;
mbs.param[1] = RQUEST_QUEUE_LEN(isp);
- mbs.param[2] = DMA_MSW(isp->isp_rquest_dma);
- mbs.param[3] = DMA_LSW(isp->isp_rquest_dma);
+ mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
+ mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
mbs.param[4] = 0;
isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
@@ -1142,6 +1163,8 @@ isp_fibre_init(struct ispsoftc *isp)
/*
* Right now we just set extended options to prefer point-to-point
* over loop based upon some soft config options.
+ *
+ * NB: for the 2300, ICBOPT_EXTENDED is required.
*/
if (IS_2200(isp) || IS_2300(isp)) {
icbp->icb_fwoptions |= ICBOPT_EXTENDED;
@@ -1162,6 +1185,15 @@ isp_fibre_init(struct ispsoftc *isp)
icbp->icb_xfwoptions = ICBXOPT_LOOP_2_PTP;
break;
}
+ if (IS_2300(isp)) {
+ if (isp->isp_revision < 2) {
+ icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
+ }
+ icbp->icb_xfwoptions |= ICBXOPT_RATE_AUTO;
+ }
+ }
+
+ if (IS_2200(isp) || IS_2300(isp)) {
/*
* Turn on LIP F8 async event (1)
* Turn on generate AE 8013 on all LIP Resets (2)
@@ -1173,7 +1205,14 @@ isp_fibre_init(struct ispsoftc *isp)
mbs.param[3] = 0;
isp_mboxcmd(isp, &mbs, MBLOGALL);
}
- icbp->icb_logintime = 60; /* 60 second login timeout */
+ icbp->icb_logintime = 30; /* 30 second login timeout */
+
+ if (IS_2300(isp)) {
+ ISP_WRITE(isp, isp->isp_rqstinrp, 0);
+ ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
+ ISP_WRITE(isp, isp->isp_respinrp, 0);
+ ISP_WRITE(isp, isp->isp_respoutrp, 0);
+ }
nwwn = ISP_NODEWWN(isp);
pwwn = ISP_PORTWWN(isp);
@@ -1193,10 +1232,14 @@ isp_fibre_init(struct ispsoftc *isp)
}
icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
- icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_LSW(isp->isp_rquest_dma);
- icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_MSW(isp->isp_rquest_dma);
- icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_LSW(isp->isp_result_dma);
- icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_MSW(isp->isp_result_dma);
+ icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
+ icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
+ icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
+ icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
+ icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
+ 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_LOGDEBUG1,
"isp_fibre_init: fwoptions 0x%x", fcp->isp_fwoptions);
ISP_SWIZZLE_ICB(isp, icbp);
@@ -1207,12 +1250,12 @@ isp_fibre_init(struct ispsoftc *isp)
*/
mbs.param[0] = MBOX_INIT_FIRMWARE;
mbs.param[1] = 0;
- mbs.param[2] = DMA_MSW(fcp->isp_scdma);
- mbs.param[3] = DMA_LSW(fcp->isp_scdma);
+ mbs.param[2] = DMA_WD1(fcp->isp_scdma);
+ mbs.param[3] = DMA_WD0(fcp->isp_scdma);
mbs.param[4] = 0;
mbs.param[5] = 0;
- mbs.param[6] = 0;
- mbs.param[7] = 0;
+ mbs.param[6] = DMA_WD3(fcp->isp_scdma);
+ mbs.param[7] = DMA_WD2(fcp->isp_scdma);
isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
@@ -1242,8 +1285,8 @@ isp_getmap(struct ispsoftc *isp, fcpos_map_t *map)
mbs.param[0] = MBOX_GET_FC_AL_POSITION_MAP;
mbs.param[1] = 0;
- mbs.param[2] = DMA_MSW(fcp->isp_scdma);
- mbs.param[3] = DMA_LSW(fcp->isp_scdma);
+ mbs.param[2] = DMA_WD1(fcp->isp_scdma);
+ mbs.param[3] = DMA_WD0(fcp->isp_scdma);
/*
* Unneeded. For the 2100, except for initializing f/w, registers
* 4/5 have to not be written to.
@@ -1280,8 +1323,8 @@ isp_getpdb(struct ispsoftc *isp, int id, isp_pdb_t *pdbp)
mbs.param[0] = MBOX_GET_PORT_DB;
mbs.param[1] = id << 8;
- mbs.param[2] = DMA_MSW(fcp->isp_scdma);
- mbs.param[3] = DMA_LSW(fcp->isp_scdma);
+ mbs.param[2] = DMA_WD1(fcp->isp_scdma);
+ mbs.param[3] = DMA_WD0(fcp->isp_scdma);
/*
* Unneeded. For the 2100, except for initializing f/w, registers
* 4/5 have to not be written to.
@@ -1289,8 +1332,8 @@ isp_getpdb(struct ispsoftc *isp, int id, isp_pdb_t *pdbp)
* mbs.param[5] = 0;
*
*/
- mbs.param[6] = 0;
- mbs.param[7] = 0;
+ mbs.param[6] = DMA_WD3(fcp->isp_scdma);
+ mbs.param[7] = DMA_WD2(fcp->isp_scdma);
isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
ISP_UNSWIZZLE_AND_COPY_PDBP(isp, pdbp, fcp->isp_scratch);
@@ -2183,9 +2226,13 @@ isp_scan_fabric(struct ispsoftc *isp)
MEMZERO((void *) reqp, SNS_GAN_REQ_SIZE);
reqp->snscb_rblen = SNS_GAN_RESP_SIZE >> 1;
reqp->snscb_addr[RQRSP_ADDR0015] =
- DMA_LSW(fcp->isp_scdma + 0x100);
+ DMA_WD0(fcp->isp_scdma + 0x100);
reqp->snscb_addr[RQRSP_ADDR1631] =
- DMA_MSW(fcp->isp_scdma + 0x100);
+ DMA_WD1(fcp->isp_scdma + 0x100);
+ reqp->snscb_addr[RQRSP_ADDR3247] =
+ DMA_WD2(fcp->isp_scdma + 0x100);
+ reqp->snscb_addr[RQRSP_ADDR4863] =
+ DMA_WD3(fcp->isp_scdma + 0x100);
reqp->snscb_sblen = 6;
reqp->snscb_data[0] = SNS_GAN;
reqp->snscb_data[4] = portid & 0xffff;
@@ -2193,10 +2240,13 @@ isp_scan_fabric(struct ispsoftc *isp)
ISP_SWIZZLE_SNS_REQ(isp, reqp);
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_GAN_REQ_SIZE >> 1;
- mbs.param[2] = DMA_MSW(fcp->isp_scdma);
- mbs.param[3] = DMA_LSW(fcp->isp_scdma);
- mbs.param[6] = 0;
- mbs.param[7] = 0;
+ mbs.param[2] = DMA_WD1(fcp->isp_scdma);
+ mbs.param[3] = DMA_WD0(fcp->isp_scdma);
+ /*
+ * Leave 4 and 5 alone
+ */
+ mbs.param[6] = DMA_WD3(fcp->isp_scdma);
+ mbs.param[7] = DMA_WD2(fcp->isp_scdma);
isp_mboxcmd(isp, &mbs, MBLOGNONE);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
if (fcp->isp_loopstate == LOOP_SCANNING_FABRIC) {
@@ -2268,8 +2318,10 @@ isp_register_fc4_type(struct ispsoftc *isp)
reqp = (sns_screq_t *) fcp->isp_scratch;
MEMZERO((void *) reqp, SNS_RFT_REQ_SIZE);
reqp->snscb_rblen = SNS_RFT_RESP_SIZE >> 1;
- reqp->snscb_addr[RQRSP_ADDR0015] = DMA_LSW(fcp->isp_scdma + 0x100);
- reqp->snscb_addr[RQRSP_ADDR1631] = DMA_MSW(fcp->isp_scdma + 0x100);
+ reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
+ reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
+ reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
+ reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
reqp->snscb_sblen = 22;
reqp->snscb_data[0] = SNS_RFT;
reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
@@ -2281,10 +2333,13 @@ isp_register_fc4_type(struct ispsoftc *isp)
ISP_SWIZZLE_SNS_REQ(isp, reqp);
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_RFT_REQ_SIZE >> 1;
- mbs.param[2] = DMA_MSW(fcp->isp_scdma);
- mbs.param[3] = DMA_LSW(fcp->isp_scdma);
- mbs.param[6] = 0;
- mbs.param[7] = 0;
+ mbs.param[2] = DMA_WD1(fcp->isp_scdma);
+ mbs.param[3] = DMA_WD0(fcp->isp_scdma);
+ /*
+ * Leave 4 and 5 alone
+ */
+ mbs.param[6] = DMA_WD3(fcp->isp_scdma);
+ mbs.param[7] = DMA_WD2(fcp->isp_scdma);
isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 types succeeded");
@@ -2603,12 +2658,12 @@ isp_start(XS_T *xs)
} else {
/*
* If we don't know what tag to use, use HEAD OF QUEUE
- * for Request Sense or Ordered (for safety's sake).
+ * for Request Sense or Simple.
*/
if (XS_CDBP(xs)[0] == 0x3) /* REQUEST SENSE */
t2reqp->req_flags = REQFLAG_HTAG;
else
- t2reqp->req_flags = REQFLAG_OTAG;
+ t2reqp->req_flags = REQFLAG_STAG;
}
} else {
sdparam *sdp = (sdparam *)isp->isp_param;
@@ -2865,65 +2920,18 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
*/
#define MAX_REQUESTQ_COMPLETIONS 32
-int
-isp_intr(void *arg)
+void
+isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
{
- struct ispsoftc *isp = arg;
XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
- u_int16_t iptr, optr, isr, sema, junk;
+ u_int16_t iptr, optr, junk;
int i, nlooked = 0, ndone = 0;
- if (IS_2100(isp)) {
- i = 0;
- do {
- isr = ISP_READ(isp, BIU_ISR);
- junk = ISP_READ(isp, BIU_ISR);
- } while (isr != junk && ++i < 1000);
- if (isr != junk) {
- isp_prt(isp, ISP_LOGWARN,
- "isr unsteady (%x, %x)", isr, junk);
- }
- i = 0;
- do {
- sema = ISP_READ(isp, BIU_SEMA);
- junk = ISP_READ(isp, BIU_SEMA);
- } while (sema != junk && ++i < 1000);
- if (sema != junk) {
- isp_prt(isp, ISP_LOGWARN,
- "sema unsteady (%x, %x)", sema, junk);
- }
- } else {
- isr = ISP_READ(isp, BIU_ISR);
- sema = ISP_READ(isp, BIU_SEMA);
- }
- isp_prt(isp, ISP_LOGDEBUG3, "isp_intr isr %x sem %x", isr, sema);
- isr &= INT_PENDING_MASK(isp);
- sema &= BIU_SEMA_LOCK;
- isp->isp_intcnt++;
- if (isr == 0 && sema == 0) {
- isp->isp_intbogus++;
- return (0);
- }
-
+ /*
+ * Is this a mailbox related interrupt?
+ * The mailbox semaphore will be nonzero if so.
+ */
if (sema) {
- u_int16_t mbox;
-
- if (IS_2100(isp)) {
- i = 0;
- do {
- mbox = ISP_READ(isp, OUTMAILBOX0);
- junk = ISP_READ(isp, OUTMAILBOX0);;
- } while (junk != mbox && ++i < 1000);
- if (mbox != junk) {
- isp_prt(isp, ISP_LOGWARN,
- "mailbox0 unsteady (%x, %x)", mbox, junk);
- ISP_WRITE(isp, BIU_SEMA, 0);
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- return (1);
- }
- } else {
- mbox = ISP_READ(isp, OUTMAILBOX0);
- }
if (mbox & 0x4000) {
int obits, i = 0;
if ((obits = isp->isp_mboxbsy) != 0) {
@@ -2949,9 +2957,9 @@ isp_intr(void *arg)
}
}
if (IS_FC(isp) || isp->isp_state != ISP_RUNSTATE) {
- ISP_WRITE(isp, BIU_SEMA, 0);
ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- return (1);
+ ISP_WRITE(isp, BIU_SEMA, 0);
+ return;
}
}
@@ -2960,41 +2968,55 @@ isp_intr(void *arg)
*/
if (isp->isp_state != ISP_RUNSTATE) {
isp_prt(isp, ISP_LOGWARN,
- "interrupt (isr=%x, sema=%x) when not ready", isr, sema);
- WRITE_RESPONSE_QUEUE_IN_POINTER(isp,
- READ_RESPONSE_QUEUE_OUT_POINTER(isp));
+ "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
+ /*
+ * Thank you very much! *Burrrp*!
+ */
+ WRITE_RESPONSE_QUEUE_OUT_POINTER(isp,
+ READ_RESPONSE_QUEUE_IN_POINTER(isp));
+
ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
ISP_WRITE(isp, BIU_SEMA, 0);
- return (1);
+ return;
}
/*
- * You *must* read the Response Queue Out Pointer
- * prior to clearing the RISC interrupt.
+ * Get the current Response Queue Out Pointer.
+ *
+ * If we're a 2300, we can ask what hardware what it thinks.
*/
- optr = isp->isp_residx;
+ if (IS_2300(isp)) {
+ optr = ISP_READ(isp, isp->isp_respoutrp);
+ if (isp->isp_residx != optr) {
+ isp_prt(isp, ISP_LOGWARN, "optr %x soft optr %x",
+ optr, isp->isp_residx);
+ }
+ } else {
+ optr = isp->isp_residx;
+ }
- if (IS_2100(isp)) {
+ /*
+ * You *must* read the Response Queue In Pointer
+ * prior to clearing the RISC interrupt.
+ */
+ if (IS_2100(isp) || IS_2300(isp)) {
i = 0;
do {
- iptr = READ_RESPONSE_QUEUE_OUT_POINTER(isp);
- junk = READ_RESPONSE_QUEUE_OUT_POINTER(isp);
+ iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
+ junk = READ_RESPONSE_QUEUE_IN_POINTER(isp);
} while (junk != iptr && ++i < 1000);
if (iptr != junk) {
ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
isp_prt(isp, ISP_LOGWARN,
- "mailbox5 unsteady (%x, %x)", iptr, junk);
- return (1);
+ "Response Queue Out Pointer Unstable (%x, %x)",
+ iptr, junk);
+ return;
}
} else {
- iptr = READ_RESPONSE_QUEUE_OUT_POINTER(isp);
+ iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
}
- if (sema) {
- ISP_WRITE(isp, BIU_SEMA, 0);
- }
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
if (optr == iptr && sema == 0) {
/*
@@ -3005,12 +3027,22 @@ isp_intr(void *arg)
* make sure the old interrupt went away (to avoid 'ringing'
* effects), but that didn't stop this from occurring.
*/
- junk = ISP_READ(isp, BIU_ISR);
- isp_prt(isp, ISP_LOGDEBUG2,
- "bogus intr- isr %x (%x) iptr %x optr %x",
- isr, junk, iptr, optr);
- isp->isp_intbogus++;
+ if (IS_2300(isp)) {
+ USEC_DELAY(100);
+ iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
+ junk = ISP_READ(isp, BIU_R2HSTSLO);
+ } else {
+ junk = ISP_READ(isp, BIU_ISR);
+ }
+ if (optr == iptr) {
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "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);
+ ISP_WRITE(isp, BIU_SEMA, 0);
while (optr != iptr) {
ispstatusreq_t *sp;
@@ -3057,7 +3089,7 @@ isp_intr(void *arg)
if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
isp_prt(isp, ISP_LOGWARN,
"continuation segment");
- WRITE_RESPONSE_QUEUE_IN_POINTER(isp, optr);
+ WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
continue;
}
if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
@@ -3089,7 +3121,7 @@ isp_intr(void *arg)
"bad request handle %d (type 0x%x, flags 0x%x)",
sp->req_handle, sp->req_header.rqs_entry_type,
sp->req_header.rqs_flags);
- WRITE_RESPONSE_QUEUE_IN_POINTER(isp, optr);
+ WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
continue;
}
xs = isp_find_xs(isp, sp->req_handle);
@@ -3098,7 +3130,7 @@ isp_intr(void *arg)
isp_prt(isp, ISP_LOGERR,
"cannot find handle 0x%x in xflist",
sp->req_handle);
- WRITE_RESPONSE_QUEUE_IN_POINTER(isp, optr);
+ WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
continue;
}
isp_destroy_handle(isp, sp->req_handle);
@@ -3233,7 +3265,10 @@ isp_intr(void *arg)
* ISP's notion of what we've seen so far.
*/
if (nlooked) {
- WRITE_RESPONSE_QUEUE_IN_POINTER(isp, optr);
+ WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
+ /*
+ * While we're at it, reqad the requst queue out pointer.
+ */
isp->isp_reqodx = READ_REQUEST_QUEUE_OUT_POINTER(isp);
}
@@ -3244,7 +3279,6 @@ isp_intr(void *arg)
isp_done(xs);
}
}
- return (1);
}
/*
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index a2a53750bd3a..d4bb57fa7b38 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -390,15 +390,16 @@ get_lun_statep(struct ispsoftc *isp, int bus, lun_id_t lun)
tstate_t *tptr;
if (lun == CAM_LUN_WILDCARD) {
- tptr = &isp->isp_osinfo.tsdflt[bus];
- tptr->hold++;
- return (tptr);
+ if (isp->isp_osinfo.tmflags & TM_WILDCARD_ENABLED) {
+ tptr = &isp->isp_osinfo.tsdflt[bus];
+ tptr->hold++;
+ return (tptr);
+ } else {
+ return (NULL);
+ }
} else {
tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(isp, bus, lun)];
}
- if (tptr == NULL) {
- return (NULL);
- }
do {
if (tptr->lun == lun && tptr->bus == bus) {
@@ -546,7 +547,7 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
struct ccb_en_lun *cel = &ccb->cel;
tstate_t *tptr;
u_int16_t rstat;
- int bus, cmd, frozen = 0;
+ int bus, cmd, av, wildcard, frozen = 0;
lun_id_t lun;
target_id_t tgt;
@@ -630,23 +631,23 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
}
}
+ if (lun == CAM_LUN_WILDCARD && tgt == CAM_TARGET_WILDCARD) {
+ wildcard = 1;
+ } else {
+ wildcard = 0;
+ }
/*
* Next check to see whether this is a target/lun wildcard action.
- *
- * If so, we enable/disable target mode but don't do any lun enabling.
+ * If so, we know that we can accept commands and send them
+ * upstream. Otherwise, we have to handle them locally.
*/
- if (lun == CAM_LUN_WILDCARD && tgt == CAM_TARGET_WILDCARD) {
- int av = bus << 31;
+
+ if (wildcard) {
tptr = &isp->isp_osinfo.tsdflt[bus];
if (cel->enable) {
- if (isp->isp_osinfo.tmflags & (1 << bus)) {
+ if (isp->isp_osinfo.tmflags & TM_WILDCARD_ENABLED) {
ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
- if (frozen) {
- ISPLOCK_2_CAMLOCK(isp);
- xpt_release_simq(isp->isp_sim, 1);
- CAMLOCK_2_ISPLOCK(isp);
- }
return;
}
ccb->ccb_h.status =
@@ -664,54 +665,72 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
}
SLIST_INIT(&tptr->atios);
SLIST_INIT(&tptr->inots);
- av |= ENABLE_TARGET_FLAG;
- av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
- if (av) {
- ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
- xpt_free_path(tptr->owner);
- if (frozen) {
- ISPLOCK_2_CAMLOCK(isp);
- xpt_release_simq(isp->isp_sim, 1);
- CAMLOCK_2_ISPLOCK(isp);
- }
- return;
- }
- isp->isp_osinfo.tmflags |= (1 << bus);
+ isp->isp_osinfo.tmflags |= TM_WILDCARD_ENABLED;
} else {
- if ((isp->isp_osinfo.tmflags & (1 << bus)) == 0) {
- ccb->ccb_h.status = CAM_LUN_INVALID;
- if (frozen) {
- ISPLOCK_2_CAMLOCK(isp);
- xpt_release_simq(isp->isp_sim, 1);
- CAMLOCK_2_ISPLOCK(isp);
- }
+ if (!(isp->isp_osinfo.tmflags & TM_WILDCARD_ENABLED)) {
+ ccb->ccb_h.status = CAM_REQ_CMP;
return;
}
- if (are_any_luns_enabled(isp, bus)) {
+ if (tptr->hold) {
ccb->ccb_h.status = CAM_SCSI_BUSY;
- if (frozen) {
- ISPLOCK_2_CAMLOCK(isp);
- xpt_release_simq(isp->isp_sim, 1);
- CAMLOCK_2_ISPLOCK(isp);
- }
return;
}
- av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
- if (av) {
- ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
- if (frozen) {
- ISPLOCK_2_CAMLOCK(isp);
- xpt_release_simq(isp->isp_sim, 1);
- CAMLOCK_2_ISPLOCK(isp);
- }
- return;
+ xpt_free_path(tptr->owner);
+ isp->isp_osinfo.tmflags &= ~TM_WILDCARD_ENABLED;
+ }
+ }
+
+ /*
+ * Now check to see whether this bus needs to be
+ * enabled/disabled with respect to target mode.
+ */
+
+ av = bus << 31;
+ if (cel->enable && (isp->isp_osinfo.tmflags & (1 << bus)) == 0) {
+ av |= ENABLE_TARGET_FLAG;
+ av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
+ if (av) {
+ ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
+ ISPLOCK_2_CAMLOCK(isp);
+ xpt_release_simq(isp->isp_sim, 1);
+ CAMLOCK_2_ISPLOCK(isp);
+ if (wildcard) {
+ isp->isp_osinfo.tmflags &= ~TM_WILDCARD_ENABLED;
+ xpt_free_path(tptr->owner);
}
- isp->isp_osinfo.tmflags &= ~(1 << bus);
- ccb->ccb_h.status = CAM_REQ_CMP;
+ return;
+ }
+ isp_prt(isp, ISP_LOGINFO,
+ "Target Mode enabled on channel %d", bus);
+ } else if (cel->enable == 0 && (isp->isp_osinfo.tmflags & (1 << bus)) &&
+ wildcard) {
+ if (are_any_luns_enabled(isp, bus)) {
+ ccb->ccb_h.status = CAM_SCSI_BUSY;
+ if (frozen) {
+ ISPLOCK_2_CAMLOCK(isp);
+ xpt_release_simq(isp->isp_sim, 1);
+ CAMLOCK_2_ISPLOCK(isp);
+ }
+ return;
}
+ av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
+ if (av) {
+ ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
+ if (frozen) {
+ ISPLOCK_2_CAMLOCK(isp);
+ xpt_release_simq(isp->isp_sim, 1);
+ CAMLOCK_2_ISPLOCK(isp);
+ }
+ return;
+ }
+ isp->isp_osinfo.tmflags &= ~(1 << bus);
+ ccb->ccb_h.status = CAM_REQ_CMP;
xpt_print_path(ccb->ccb_h.path);
- isp_prt(isp, ISP_LOGINFO, "Target Mode %sabled on channel %d",
- (cel->enable) ? "en" : "dis", bus);
+ isp_prt(isp, ISP_LOGINFO,
+ "Target Mode disabled on channel %d", bus);
+ }
+
+ if (wildcard) {
if (frozen) {
ISPLOCK_2_CAMLOCK(isp);
xpt_release_simq(isp->isp_sim, 1);
@@ -850,7 +869,21 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
"DISABLE LUN returned 0x%x", rstat);
goto out;
}
+ if (are_any_luns_enabled(isp, bus) == 0) {
+ av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
+ if (av) {
+ isp_prt(isp, ISP_LOGWARN,
+ "disable target mode on channel %d failed",
+ bus);
+ goto out;
+ }
+ isp->isp_osinfo.tmflags &= ~(1 << bus);
+ xpt_print_path(ccb->ccb_h.path);
+ isp_prt(isp, ISP_LOGINFO,
+ "Target Mode disabled on channel %d", bus);
+ }
}
+
out:
isp_vsema_rqe(isp);
@@ -1571,8 +1604,12 @@ static void
isp_poll(struct cam_sim *sim)
{
struct ispsoftc *isp = cam_sim_softc(sim);
+ u_int16_t isr, sema, mbox;
+
ISP_LOCK(isp);
- (void) isp_intr(isp);
+ if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
+ isp_intr(isp, isr, sema, mbox);
+ }
ISP_UNLOCK(isp);
}
@@ -1609,7 +1646,8 @@ isp_watchdog(void *arg)
ISP_LOCK(isp);
handle = isp_find_handle(isp, xs);
if (handle) {
- u_int16_t r;
+ u_int16_t isr, sema, mbox;
+
if (XS_CMD_DONE_P(xs)) {
isp_prt(isp, ISP_LOGDEBUG1,
@@ -1626,12 +1664,12 @@ isp_watchdog(void *arg)
}
XS_CMD_S_WDOG(xs);
-
- r = ISP_READ(isp, BIU_ISR);
-
- if (INT_PENDING(isp, r) && isp_intr(isp) && XS_CMD_DONE_P(xs)) {
+ if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
+ isp_intr(isp, isr, sema, mbox);
+ }
+ if (XS_CMD_DONE_P(xs)) {
isp_prt(isp, ISP_LOGDEBUG2,
- "watchdog cleanup (%x, %x)", handle, r);
+ "watchdog cleanup for handle 0x%x", handle);
xpt_done((union ccb *) xs);
} else if (XS_CMD_GRACE_P(xs)) {
/*
@@ -1649,7 +1687,7 @@ isp_watchdog(void *arg)
isp_destroy_handle(isp, handle);
xpt_print_path(xs->ccb_h.path);
isp_prt(isp, ISP_LOGWARN,
- "watchdog timeout (%x, %x)", handle, r);
+ "watchdog timeout for handle %x", handle);
XS_SETERR(xs, CAM_CMD_TIMEOUT);
XS_CMD_C_WDOG(xs);
isp_done(xs);
diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h
index 46bec0d5dafb..b3110ce5ff12 100644
--- a/sys/dev/isp/isp_freebsd.h
+++ b/sys/dev/isp/isp_freebsd.h
@@ -103,6 +103,7 @@ struct isposinfo {
#ifdef ISP_TARGET_MODE
#define TM_WANTED 0x80
#define TM_BUSY 0x40
+#define TM_WILDCARD_ENABLED 0x20
#define TM_TMODE_ENABLED 0x03
u_int8_t tmflags;
u_int8_t rstatus;
@@ -328,12 +329,17 @@ isp_mbox_wait_complete(struct ispsoftc *isp)
} else {
int j;
for (j = 0; j < 60 * 10000; j++) {
- if (isp_intr(isp) == 0) {
- USEC_DELAY(500);
- }
+ u_int16_t isr, sema, mbox;
if (isp->isp_mboxbsy == 0) {
break;
}
+ if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
+ isp_intr(isp, isr, sema, mbox);
+ if (isp->isp_mboxbsy == 0) {
+ break;
+ }
+ }
+ USEC_DELAY(500);
}
if (isp->isp_mboxbsy != 0) {
isp_prt(isp, ISP_LOGWARN,
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index 887841c18183..0341b10a21f1 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -45,24 +45,29 @@
#include <dev/isp/isp_freebsd.h>
-static u_int16_t isp_pci_rd_reg __P((struct ispsoftc *, int));
-static void isp_pci_wr_reg __P((struct ispsoftc *, int, u_int16_t));
-static u_int16_t isp_pci_rd_reg_1080 __P((struct ispsoftc *, int));
-static void isp_pci_wr_reg_1080 __P((struct ispsoftc *, int, u_int16_t));
-static int isp_pci_mbxdma __P((struct ispsoftc *));
-static int isp_pci_dmasetup __P((struct ispsoftc *, XS_T *,
- ispreq_t *, u_int16_t *, u_int16_t));
+static u_int16_t isp_pci_rd_reg(struct ispsoftc *, int);
+static void isp_pci_wr_reg(struct ispsoftc *, int, u_int16_t);
+static u_int16_t isp_pci_rd_reg_1080(struct ispsoftc *, int);
+static void isp_pci_wr_reg_1080(struct ispsoftc *, int, u_int16_t);
+static int
+isp_pci_rd_isr(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
+static int
+isp_pci_rd_isr_2300(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
+static int isp_pci_mbxdma(struct ispsoftc *);
+static int
+isp_pci_dmasetup(struct ispsoftc *, XS_T *, ispreq_t *, u_int16_t *, u_int16_t);
static void
-isp_pci_dmateardown __P((struct ispsoftc *, XS_T *, u_int16_t));
+isp_pci_dmateardown(struct ispsoftc *, XS_T *, u_int16_t);
-static void isp_pci_reset1 __P((struct ispsoftc *));
-static void isp_pci_dumpregs __P((struct ispsoftc *, const char *));
+static void isp_pci_reset1(struct ispsoftc *);
+static void isp_pci_dumpregs(struct ispsoftc *, const char *);
#ifndef ISP_CODE_ORG
#define ISP_CODE_ORG 0x1000
#endif
static struct ispmdvec mdvec = {
+ isp_pci_rd_isr,
isp_pci_rd_reg,
isp_pci_wr_reg,
isp_pci_mbxdma,
@@ -76,6 +81,7 @@ static struct ispmdvec mdvec = {
};
static struct ispmdvec mdvec_1080 = {
+ isp_pci_rd_isr,
isp_pci_rd_reg_1080,
isp_pci_wr_reg_1080,
isp_pci_mbxdma,
@@ -89,6 +95,7 @@ static struct ispmdvec mdvec_1080 = {
};
static struct ispmdvec mdvec_12160 = {
+ isp_pci_rd_isr,
isp_pci_rd_reg_1080,
isp_pci_wr_reg_1080,
isp_pci_mbxdma,
@@ -102,6 +109,7 @@ static struct ispmdvec mdvec_12160 = {
};
static struct ispmdvec mdvec_2100 = {
+ isp_pci_rd_isr,
isp_pci_rd_reg,
isp_pci_wr_reg,
isp_pci_mbxdma,
@@ -113,6 +121,19 @@ static struct ispmdvec mdvec_2100 = {
};
static struct ispmdvec mdvec_2200 = {
+ isp_pci_rd_isr,
+ isp_pci_rd_reg,
+ isp_pci_wr_reg,
+ isp_pci_mbxdma,
+ isp_pci_dmasetup,
+ isp_pci_dmateardown,
+ NULL,
+ isp_pci_reset1,
+ isp_pci_dumpregs
+};
+
+static struct ispmdvec mdvec_2300 = {
+ isp_pci_rd_isr_2300,
isp_pci_rd_reg,
isp_pci_wr_reg,
isp_pci_mbxdma,
@@ -184,6 +205,14 @@ static struct ispmdvec mdvec_2200 = {
#define PCI_PRODUCT_QLOGIC_ISP2200 0x2200
#endif
+#ifndef PCI_PRODUCT_QLOGIC_ISP2300
+#define PCI_PRODUCT_QLOGIC_ISP2300 0x2300
+#endif
+
+#ifndef PCI_PRODUCT_QLOGIC_ISP2312
+#define PCI_PRODUCT_QLOGIC_ISP2312 0x2312
+#endif
+
#define PCI_QLOGIC_ISP1020 \
((PCI_PRODUCT_QLOGIC_ISP1020 << 16) | PCI_VENDOR_QLOGIC)
@@ -205,6 +234,12 @@ static struct ispmdvec mdvec_2200 = {
#define PCI_QLOGIC_ISP2200 \
((PCI_PRODUCT_QLOGIC_ISP2200 << 16) | PCI_VENDOR_QLOGIC)
+#define PCI_QLOGIC_ISP2300 \
+ ((PCI_PRODUCT_QLOGIC_ISP2300 << 16) | PCI_VENDOR_QLOGIC)
+
+#define PCI_QLOGIC_ISP2312 \
+ ((PCI_PRODUCT_QLOGIC_ISP2312 << 16) | PCI_VENDOR_QLOGIC)
+
/*
* Odd case for some AMI raid cards... We need to *not* attach to this.
*/
@@ -240,7 +275,7 @@ static device_method_t isp_pci_methods[] = {
DEVMETHOD(device_attach, isp_pci_attach),
{ 0, 0 }
};
-static void isp_pci_intr __P((void *));
+static void isp_pci_intr(void *);
static driver_t isp_pci_driver = {
"isp", isp_pci_methods, sizeof (struct isp_pcisoftc)
@@ -277,6 +312,12 @@ isp_pci_probe(device_t dev)
case PCI_QLOGIC_ISP2200:
device_set_desc(dev, "Qlogic ISP 2200 PCI FC-AL Adapter");
break;
+ case PCI_QLOGIC_ISP2300:
+ device_set_desc(dev, "Qlogic ISP 2300 PCI FC-AL Adapter");
+ break;
+ case PCI_QLOGIC_ISP2312:
+ device_set_desc(dev, "Qlogic ISP 2312 PCI FC-AL Adapter");
+ break;
default:
return (ENXIO);
}
@@ -455,6 +496,14 @@ 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) {
+ mdvp = &mdvec_2300;
+ basetype = ISP_HA_FC_2300;
+ 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) {
@@ -698,68 +747,167 @@ static void
isp_pci_intr(void *arg)
{
struct ispsoftc *isp = arg;
+ u_int16_t isr, sema, mbox;
+
ISP_LOCK(isp);
- (void) isp_intr(isp);
+ isp->isp_intcnt++;
+ if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) {
+ isp->isp_intbogus++;
+ } else {
+ isp_intr(isp, isr, sema, mbox);
+ }
ISP_UNLOCK(isp);
}
+
+#define IspVirt2Off(a, x) \
+ (((struct isp_pcisoftc *)a)->pci_poff[((x) & _BLK_REG_MASK) >> \
+ _BLK_REG_SHFT] + ((x) & 0xff))
+
+#define BXR2(pcs, off) \
+ bus_space_read_2(pcs->pci_st, pcs->pci_sh, off)
+#define BXW2(pcs, off, v) \
+ bus_space_write_2(pcs->pci_st, pcs->pci_sh, off, v)
+
+
+static INLINE int
+isp_pci_rd_debounced(struct ispsoftc *isp, int off, u_int16_t *rp)
+{
+ struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
+ u_int16_t val0, val1;
+ int i = 0;
+
+ do {
+ val0 = BXR2(pcs, IspVirt2Off(isp, off));
+ val1 = BXR2(pcs, IspVirt2Off(isp, off));
+ } while (val0 != val1 && ++i < 1000);
+ if (val0 != val1) {
+ return (1);
+ }
+ *rp = val0;
+ return (0);
+}
+
+static int
+isp_pci_rd_isr(struct ispsoftc *isp, u_int16_t *isrp,
+ u_int16_t *semap, u_int16_t *mbp)
+{
+ struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
+ u_int16_t isr, sema;
+
+ if (IS_2100(isp)) {
+ if (isp_pci_rd_debounced(isp, BIU_ISR, &isr)) {
+ return (0);
+ }
+ if (isp_pci_rd_debounced(isp, BIU_SEMA, &sema)) {
+ return (0);
+ }
+ } else {
+ isr = BXR2(pcs, IspVirt2Off(isp, BIU_ISR));
+ sema = BXR2(pcs, IspVirt2Off(isp, BIU_SEMA));
+ }
+ isp_prt(isp, ISP_LOGDEBUG3, "ISR 0x%x SEMA 0x%x", isr, sema);
+ isr &= INT_PENDING_MASK(isp);
+ sema &= BIU_SEMA_LOCK;
+ if (isr == 0 && sema == 0) {
+ return (0);
+ }
+ *isrp = isr;
+ if ((*semap = sema) != 0) {
+ if (IS_2100(isp)) {
+ if (isp_pci_rd_debounced(isp, OUTMAILBOX0, mbp)) {
+ return (0);
+ }
+ } else {
+ *mbp = BXR2(pcs, IspVirt2Off(isp, OUTMAILBOX0));
+ }
+ }
+ return (1);
+}
+
+static int
+isp_pci_rd_isr_2300(struct ispsoftc *isp, u_int16_t *isrp,
+ u_int16_t *semap, u_int16_t *mbox0p)
+{
+ struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
+ u_int32_t r2hisr;
+
+ r2hisr = bus_space_read_4(pcs->pci_st, pcs->pci_sh,
+ IspVirt2Off(pcs, BIU_R2HSTSLO));
+ isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr);
+ if ((r2hisr & BIU_R2HST_INTR) == 0) {
+ *isrp = 0;
+ return (0);
+ }
+ switch (r2hisr & BIU_R2HST_ISTAT_MASK) {
+ case ISPR2HST_ROM_MBX_OK:
+ case ISPR2HST_ROM_MBX_FAIL:
+ case ISPR2HST_MBX_OK:
+ case ISPR2HST_MBX_FAIL:
+ case ISPR2HST_ASYNC_EVENT:
+ case ISPR2HST_FPOST:
+ case ISPR2HST_FPOST_CTIO:
+ *isrp = r2hisr & 0xffff;
+ *mbox0p = (r2hisr >> 16);
+ *semap = 1;
+ return (1);
+ case ISPR2HST_RSPQ_UPDATE:
+ *isrp = r2hisr & 0xffff;
+ *mbox0p = 0;
+ *semap = 0;
+ return (1);
+ default:
+ return (0);
+ }
+}
+
static u_int16_t
-isp_pci_rd_reg(isp, regoff)
- struct ispsoftc *isp;
- int regoff;
+isp_pci_rd_reg(struct ispsoftc *isp, int regoff)
{
u_int16_t rv;
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
- int offset, oldconf = 0;
+ int oldconf = 0;
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
/*
* We will assume that someone has paused the RISC processor.
*/
- oldconf = isp_pci_rd_reg(isp, BIU_CONF1);
- isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP);
+ oldconf = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
+ BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
+ oldconf | BIU_PCI_CONF1_SXP);
}
- offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
- offset += (regoff & 0xff);
- rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset);
+ rv = BXR2(pcs, IspVirt2Off(isp, regoff));
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
- isp_pci_wr_reg(isp, BIU_CONF1, oldconf);
+ BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oldconf);
}
return (rv);
}
static void
-isp_pci_wr_reg(isp, regoff, val)
- struct ispsoftc *isp;
- int regoff;
- u_int16_t val;
+isp_pci_wr_reg(struct ispsoftc *isp, int regoff, u_int16_t val)
{
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
- int offset, oldconf = 0;
+ int oldconf = 0;
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
/*
* We will assume that someone has paused the RISC processor.
*/
- oldconf = isp_pci_rd_reg(isp, BIU_CONF1);
- isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP);
+ oldconf = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
+ BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
+ oldconf | BIU_PCI_CONF1_SXP);
}
- offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
- offset += (regoff & 0xff);
- bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val);
+ BXW2(pcs, IspVirt2Off(isp, regoff), val);
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
- isp_pci_wr_reg(isp, BIU_CONF1, oldconf);
+ BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oldconf);
}
}
static u_int16_t
-isp_pci_rd_reg_1080(isp, regoff)
- struct ispsoftc *isp;
- int regoff;
+isp_pci_rd_reg_1080(struct ispsoftc *isp, int regoff)
{
u_int16_t rv, oc = 0;
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
- int offset;
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
(regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
@@ -767,34 +915,30 @@ isp_pci_rd_reg_1080(isp, regoff)
/*
* We will assume that someone has paused the RISC processor.
*/
- oc = isp_pci_rd_reg(isp, BIU_CONF1);
+ oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
tc = oc & ~BIU_PCI1080_CONF1_DMA;
if (regoff & SXP_BANK1_SELECT)
tc |= BIU_PCI1080_CONF1_SXP1;
else
tc |= BIU_PCI1080_CONF1_SXP0;
- isp_pci_wr_reg(isp, BIU_CONF1, tc);
+ BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), tc);
} else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
- oc = isp_pci_rd_reg(isp, BIU_CONF1);
- isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA);
+ oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
+ BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
+ oc | BIU_PCI1080_CONF1_DMA);
}
- offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
- offset += (regoff & 0xff);
- rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset);
+ rv = BXR2(pcs, IspVirt2Off(isp, regoff));
if (oc) {
- isp_pci_wr_reg(isp, BIU_CONF1, oc);
+ BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oc);
}
return (rv);
}
static void
-isp_pci_wr_reg_1080(isp, regoff, val)
- struct ispsoftc *isp;
- int regoff;
- u_int16_t val;
+isp_pci_wr_reg_1080(struct ispsoftc *isp, int regoff, u_int16_t val)
{
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
- int offset, oc = 0;
+ int oc = 0;
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
(regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
@@ -802,28 +946,27 @@ isp_pci_wr_reg_1080(isp, regoff, val)
/*
* We will assume that someone has paused the RISC processor.
*/
- oc = isp_pci_rd_reg(isp, BIU_CONF1);
+ oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
tc = oc & ~BIU_PCI1080_CONF1_DMA;
if (regoff & SXP_BANK1_SELECT)
tc |= BIU_PCI1080_CONF1_SXP1;
else
tc |= BIU_PCI1080_CONF1_SXP0;
- isp_pci_wr_reg(isp, BIU_CONF1, tc);
+ BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), tc);
} else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
- oc = isp_pci_rd_reg(isp, BIU_CONF1);
- isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA);
+ oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
+ BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
+ oc | BIU_PCI1080_CONF1_DMA);
}
- offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
- offset += (regoff & 0xff);
- bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val);
+ BXW2(pcs, IspVirt2Off(isp, regoff), val);
if (oc) {
- isp_pci_wr_reg(isp, BIU_CONF1, oc);
+ BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oc);
}
}
-static void isp_map_rquest __P((void *, bus_dma_segment_t *, int, int));
-static void isp_map_result __P((void *, bus_dma_segment_t *, int, int));
-static void isp_map_fcscrt __P((void *, bus_dma_segment_t *, int, int));
+static void isp_map_rquest(void *, bus_dma_segment_t *, int, int);
+static void isp_map_result(void *, bus_dma_segment_t *, int, int);
+static void isp_map_fcscrt(void *, bus_dma_segment_t *, int, int);
struct imush {
struct ispsoftc *isp;
@@ -1552,7 +1695,7 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
}
#endif
-static void dma2 __P((void *, bus_dma_segment_t *, int, int));
+static void dma2(void *, bus_dma_segment_t *, int, int);
static void
dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
@@ -1700,7 +1843,7 @@ isp_pci_dmasetup(struct ispsoftc *isp, struct ccb_scsiio *csio, ispreq_t *rq,
struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
bus_dmamap_t *dp = NULL;
mush_t mush, *mp;
- void (*eptr) __P((void *, bus_dma_segment_t *, int, int));
+ void (*eptr)(void *, bus_dma_segment_t *, int, int);
#ifdef ISP_TARGET_MODE
if (csio->ccb_h.func_code == XPT_CONT_TARGET_IO) {
diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h
index a69a272e7906..5c4b632bc933 100644
--- a/sys/dev/isp/ispmbox.h
+++ b/sys/dev/isp/ispmbox.h
@@ -219,16 +219,16 @@ typedef struct {
*/
#define WRITE_REQUEST_QUEUE_IN_POINTER(isp, value) \
- ISP_WRITE(isp, INMAILBOX4, value)
+ ISP_WRITE(isp, isp->isp_rqstinrp, value)
-#define READ_REQUEST_QUEUE_OUT_POINTER(isp) \
- ISP_READ(isp, OUTMAILBOX4)
+#define READ_REQUEST_QUEUE_OUT_POINTER(isp) \
+ ISP_READ(isp, isp->isp_rqstoutrp)
-#define WRITE_RESPONSE_QUEUE_IN_POINTER(isp, value) \
- ISP_WRITE(isp, INMAILBOX5, value)
+#define READ_RESPONSE_QUEUE_IN_POINTER(isp) \
+ ISP_READ(isp, isp->isp_respinrp)
-#define READ_RESPONSE_QUEUE_OUT_POINTER(isp) \
- ISP_READ(isp, OUTMAILBOX5)
+#define WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, value) \
+ ISP_WRITE(isp, isp->isp_respoutrp, value)
/*
* Command Structure Definitions
@@ -240,7 +240,8 @@ typedef struct {
} ispds_t;
typedef struct {
- u_int64_t ds_base;
+ u_int32_t ds_base;
+ u_int32_t ds_basehi;
u_int32_t ds_count;
} ispds64_t;
@@ -353,7 +354,7 @@ typedef struct {
#define ISP_SBUSIFY_ISPREQ(a, b)
#endif
-#define ISP_RQDSEG_T2 3
+#define ISP_RQDSEG_T2 3
typedef struct {
isphdr_t req_header;
u_int32_t req_handle;
@@ -369,6 +370,22 @@ typedef struct {
ispds_t req_dataseg[ISP_RQDSEG_T2];
} ispreqt2_t;
+#define ISP_RQDSEG_T3 2
+typedef struct {
+ isphdr_t req_header;
+ u_int32_t req_handle;
+ u_int8_t req_lun_trn;
+ u_int8_t req_target;
+ u_int16_t req_scclun;
+ u_int16_t req_flags;
+ u_int16_t _res2;
+ u_int16_t req_time;
+ u_int16_t req_seg_count;
+ u_int32_t req_cdb[4];
+ u_int32_t req_totalcnt;
+ ispds64_t req_dataseg[ISP_RQDSEG_T3];
+} ispreqt3_t;
+
/* req_flag values */
#define REQFLAG_NODISCON 0x0001
#define REQFLAG_HTAG 0x0002
@@ -410,6 +427,12 @@ typedef struct {
ispds_t req_dataseg[ISP_CDSEG];
} ispcontreq_t;
+#define ISP_CDSEG64 5
+typedef struct {
+ isphdr_t req_header;
+ ispds64_t req_dataseg[ISP_CDSEG64];
+} ispcontreq64_t;
+
typedef struct {
isphdr_t req_header;
u_int32_t req_handle;
@@ -630,6 +653,10 @@ typedef struct isp_icb {
#define ICBXOPT_RIO_16BIT_DELAY 3
#define ICBXOPT_RIO_32BIT_DELAY 4
+/* These 3 only apply to the 2300 */
+#define ICBXOPT_RATE_ONEGB (0 << 14)
+#define ICBXOPT_RATE_TWOGB (1 << 14)
+#define ICBXOPT_RATE_AUTO (2 << 14)
#define ICB_MIN_FRMLEN 256
diff --git a/sys/dev/isp/ispreg.h b/sys/dev/isp/ispreg.h
index d50cdf76cb0d..390452553775 100644
--- a/sys/dev/isp/ispreg.h
+++ b/sys/dev/isp/ispreg.h
@@ -63,6 +63,7 @@
#define PCI_MBOX_REGS_OFF 0x70
#define PCI_MBOX_REGS2100_OFF 0x10
+#define PCI_MBOX_REGS2300_OFF 0x40
#define SBUS_MBOX_REGS_OFF 0x80
#define PCI_SXP_REGS_OFF 0x80
@@ -107,6 +108,37 @@
#define BIU_ISR (BIU_BLOCK+0xA) /* R : Bus Interface Status */
#define BIU_SEMA (BIU_BLOCK+0xC) /* RW : Bus Semaphore */
#define BIU_NVRAM (BIU_BLOCK+0xE) /* RW : Bus NVRAM */
+/*
+ * These are specific to the 2300.
+ *
+ * They *claim* you can read BIU_R2HSTSLO with a full 32 bit access
+ * and get both registers, but I'm a bit dubious about that. But the
+ * point here is that the top 16 bits are firmware defined bits that
+ * the RISC processor uses to inform the host about something- usually
+ * something which was nominally in a mailbox register.
+ */
+#define BIU_REQINP (BIU_BLOCK+0x10) /* Request Queue In */
+#define BIU_REQOUTP (BIU_BLOCK+0x12) /* Request Queue Out */
+#define BIU_RSPINP (BIU_BLOCK+0x14) /* Response Queue In */
+#define BIU_RSPOUTP (BIU_BLOCK+0x16) /* Response Queue Out */
+
+#define BIU_R2HSTSLO (BIU_BLOCK+0x18)
+#define BIU_R2HSTSHI (BIU_BLOCK+0x1A)
+
+#define BIU_R2HST_INTR (1 << 15) /* RISC to Host Interrupt */
+#define BIU_R2HST_PAUSED (1 << 8) /* RISC paused */
+#define BIU_R2HST_ISTAT_MASK 0x3f /* intr information && status */
+#define ISPR2HST_ROM_MBX_OK 0x1 /* ROM mailbox cmd done ok */
+#define ISPR2HST_ROM_MBX_FAIL 0x2 /* ROM mailbox cmd done fail */
+#define ISPR2HST_MBX_OK 0x10 /* mailbox cmd done ok */
+#define ISPR2HST_MBX_FAIL 0x11 /* mailbox cmd done fail */
+#define ISPR2HST_ASYNC_EVENT 0x12 /* Async Event */
+#define ISPR2HST_RSPQ_UPDATE 0x13 /* Response Queue Update */
+#define ISPR2HST_RQST_UPDATE 0x14 /* Resquest Queue Update */
+#define ISPR2HST_RIO_16 0x15 /* RIO 1-16 */
+#define ISPR2HST_FPOST 0x16 /* Low 16 bits fast post */
+#define ISPR2HST_FPOST_CTIO 0x17 /* Low 16 bits fast post ctio */
+
#define DFIFO_COMMAND (BIU_BLOCK+0x60) /* RW : Command FIFO Port */
#define RDMA2100_CONTROL DFIFO_COMMAND
#define DFIFO_DATA (BIU_BLOCK+0x62) /* RW : Data FIFO Port */
diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h
index 8526866bff91..833f99ba0912 100644
--- a/sys/dev/isp/ispvar.h
+++ b/sys/dev/isp/ispvar.h
@@ -54,20 +54,22 @@
#endif
#define ISP_CORE_VERSION_MAJOR 2
-#define ISP_CORE_VERSION_MINOR 2
+#define ISP_CORE_VERSION_MINOR 4
/*
* Vector for bus specific code to provide specific services.
*/
struct ispsoftc;
struct ispmdvec {
+ int (*dv_rd_isr)
+ (struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
u_int16_t (*dv_rd_reg) (struct ispsoftc *, int);
void (*dv_wr_reg) (struct ispsoftc *, int, u_int16_t);
int (*dv_mbxdma) (struct ispsoftc *);
int (*dv_dmaset) (struct ispsoftc *,
- XS_T *, ispreq_t *, u_int16_t *, u_int16_t);
+ XS_T *, ispreq_t *, u_int16_t *, u_int16_t);
void (*dv_dmaclr)
- (struct ispsoftc *, XS_T *, u_int16_t);
+ (struct ispsoftc *, XS_T *, u_int16_t);
void (*dv_reset0) (struct ispsoftc *);
void (*dv_reset1) (struct ispsoftc *);
void (*dv_dregs) (struct ispsoftc *, const char *);
@@ -79,16 +81,24 @@ struct ispmdvec {
/*
* Overall parameters
*/
-#define MAX_TARGETS 16
-#define MAX_FC_TARG 256
+#define MAX_TARGETS 16
+#define MAX_FC_TARG 256
#define ISP_MAX_TARGETS(isp) (IS_FC(isp)? MAX_FC_TARG : MAX_TARGETS)
#define ISP_MAX_LUNS(isp) (isp)->isp_maxluns
+/*
+ * 'Types'
+ */
+#ifndef ISP_DMA_ADDR_T
+#define ISP_DMA_ADDR_T u_int32_t
+#endif
/*
* Macros to access ISP registers through bus specific layers-
* mostly wrappers to vector through the mdvec structure.
*/
+#define ISP_READ_ISR(isp, isrp, semap, mbox0p) \
+ (*(isp)->isp_mdvec->dv_rd_isr)(isp, isrp, semap, mbox0p)
#define ISP_READ(isp, reg) \
(*(isp)->isp_mdvec->dv_rd_reg)((isp), (reg))
@@ -152,7 +162,7 @@ struct ispmdvec {
#define ISP_ADD_REQUEST(isp, iptr) \
MEMORYBARRIER(isp, SYNC_REQUEST, iptr, QENTRY_LEN); \
- ISP_WRITE(isp, INMAILBOX4, iptr); \
+ WRITE_REQUEST_QUEUE_IN_POINTER(isp, iptr); \
isp->isp_reqidx = iptr
/*
@@ -284,7 +294,7 @@ typedef struct {
* Scratch DMA mapped in area to fetch Port Database stuff, etc.
*/
caddr_t isp_scratch;
- u_int32_t isp_scdma;
+ ISP_DMA_ADDR_T isp_scdma;
} fcparam;
#define FW_CONFIG_WAIT 0
@@ -350,6 +360,11 @@ typedef struct ispsoftc {
u_int32_t isp_confopts; /* config options */
+ u_int16_t isp_rqstinrp; /* register for REQINP */
+ u_int16_t isp_rqstoutrp; /* register for REQOUTP */
+ u_int16_t isp_respinrp; /* register for RESINP */
+ u_int16_t isp_respoutrp; /* register for RESOUTP */
+
/*
* Instrumentation
*/
@@ -384,8 +399,8 @@ typedef struct ispsoftc {
*/
caddr_t isp_rquest;
caddr_t isp_result;
- u_int32_t isp_rquest_dma;
- u_int32_t isp_result_dma;
+ ISP_DMA_ADDR_T isp_rquest_dma;
+ ISP_DMA_ADDR_T isp_result_dma;
} ispsoftc_t;
#define SDPARAM(isp) ((sdparam *) (isp)->isp_param)
@@ -447,6 +462,7 @@ typedef struct ispsoftc {
* Firmware related defines
*/
#define ISP_CODE_ORG 0x1000 /* default f/w code start */
+#define ISP_CODE_ORG_2300 0x0800 /* ..except for 2300s */
#define ISP_FW_REV(maj, min, mic) ((maj << 24) | (min << 16) | mic)
#define ISP_FW_REVX(xp) ((xp[0]<<24) | (xp[1] << 16) | xp[2])
@@ -490,16 +506,15 @@ typedef struct ispsoftc {
#define IS_FC(isp) ((isp)->isp_type & ISP_HA_FC)
#define IS_2100(isp) ((isp)->isp_type == ISP_HA_FC_2100)
#define IS_2200(isp) ((isp)->isp_type == ISP_HA_FC_2200)
-#define IS_2300(isp) ((isp)->isp_type == ISP_HA_FC_2300)
-
-/* 2300 Support isn't ready yet */
-#define ISP_DISABLE_2300_SUPPORT 1
+#define IS_2300(isp) ((isp)->isp_type >= ISP_HA_FC_2300)
/*
* DMA cookie macros
*/
-#define DMA_MSW(x) (((x) >> 16) & 0xffff)
-#define DMA_LSW(x) (((x) & 0xffff))
+#define DMA_WD3(x) 0
+#define DMA_WD2(x) 0
+#define DMA_WD1(x) (((x) >> 16) & 0xffff)
+#define DMA_WD0(x) (((x) & 0xffff))
/*
* Core System Function Prototypes
@@ -522,9 +537,14 @@ void isp_init(struct ispsoftc *);
void isp_reinit(struct ispsoftc *);
/*
- * Interrupt Service Routine
+ * Internal Interrupt Service Routine
+ *
+ * The outer layers do the spade work to get the appropriate status register,
+ * semaphore register and first mailbox register (if appropriate). This also
+ * means that most spurious/bogus interrupts not for us can be filtered first.
*/
-int isp_intr(void *);
+void isp_intr(struct ispsoftc *, u_int16_t, u_int16_t, u_int16_t);
+
/*
* Command Entry Point- Platform Dependent layers call into this
@@ -689,6 +709,11 @@ void isp_prt(struct ispsoftc *, int level, const char *, ...);
*
* INLINE - platform specific define for 'inline' functions
*
+ * ISP_DMA_ADDR_T - platform specific dma address coookie- basically
+ * the largest integer that can hold the 32 or
+ * 64 bit value appropriate for the QLogic's DMA
+ * addressing. Defaults to u_int32_t.
+ *
* ISP2100_SCRLEN - length for the Fibre Channel scratch DMA area
*
* MEMZERO(dst, src) platform zeroing function