summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/isp/isp.c261
-rw-r--r--sys/dev/isp/isp_freebsd.c58
-rw-r--r--sys/dev/isp/isp_pci.c173
-rw-r--r--sys/dev/isp/isp_sbus.c32
-rw-r--r--sys/dev/isp/ispvar.h29
5 files changed, 198 insertions, 355 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 510117c..ca95801 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -416,11 +416,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
}
/*
- * Clear instrumentation
- */
- isp->isp_intcnt = isp->isp_intbogus = 0;
-
- /*
* Hit the chip over the head with hammer,
* and give it a chance to recover.
*/
@@ -4404,7 +4399,7 @@ isp_start(XS_T *xs)
((ispreqt7_t *)reqp)->req_task_attribute = ttype;
} else if (IS_FC(isp)) {
/*
- * See comment in isp_intr
+ * See comment in isp_intr_respq
*/
/* XS_SET_RESID(xs, 0); */
@@ -4911,6 +4906,70 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
* and the locking will be held throughout this function.
*/
+#ifdef ISP_TARGET_MODE
+void
+isp_intr_atioq(ispsoftc_t *isp)
+{
+ uint8_t qe[QENTRY_LEN];
+ isphdr_t *hp;
+ void *addr;
+ uint32_t iptr, optr, oop;
+
+ iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
+ optr = isp->isp_atioodx;
+ while (optr != iptr) {
+ oop = optr;
+ MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1);
+ addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
+ isp_get_hdr(isp, addr, (isphdr_t *)qe);
+ hp = (isphdr_t *)qe;
+ switch (hp->rqs_entry_type) {
+ case RQSTYPE_NOTIFY:
+ case RQSTYPE_ATIO:
+ (void) isp_target_notify(isp, addr, &oop);
+ break;
+ default:
+ isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
+ break;
+ }
+ optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
+ }
+ if (isp->isp_atioodx != optr) {
+ ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
+ isp->isp_atioodx = optr;
+ }
+}
+#endif
+
+void
+isp_intr_async(ispsoftc_t *isp, uint16_t event)
+{
+
+ if (IS_FC(isp))
+ isp_parse_async_fc(isp, event);
+ else
+ isp_parse_async(isp, event);
+}
+
+void
+isp_intr_mbox(ispsoftc_t *isp, uint16_t mbox0)
+{
+ int i, obits;
+
+ if (!isp->isp_mboxbsy) {
+ isp_prt(isp, ISP_LOGWARN, "mailbox 0x%x with no waiters", mbox0);
+ return;
+ }
+ obits = isp->isp_obits;
+ isp->isp_mboxtmp[0] = mbox0;
+ for (i = 1; i < ISP_NMBOX(isp); i++) {
+ if ((obits & (1 << i)) == 0)
+ continue;
+ isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
+ }
+ MBOX_NOTIFY_COMPLETE(isp);
+}
+
/*
* Limit our stack depth by sticking with the max likely number
* of completions on a request queue at any one time.
@@ -4920,165 +4979,32 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
#endif
void
-isp_intr(ispsoftc_t *isp, uint16_t isr, uint16_t sema, uint16_t info)
+isp_intr_respq(ispsoftc_t *isp)
{
XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
uint32_t iptr, optr, junk;
int i, nlooked = 0, ndone = 0, continuations_expected = 0;
int etype, last_etype = 0;
-again:
- /*
- * Is this a mailbox related interrupt?
- * The mailbox semaphore will be nonzero if so.
- */
- if (sema) {
- fmbox:
- if (info & MBOX_COMMAND_COMPLETE) {
- isp->isp_intmboxc++;
- if (isp->isp_mboxbsy) {
- int obits = isp->isp_obits;
- isp->isp_mboxtmp[0] = info;
- for (i = 1; i < ISP_NMBOX(isp); i++) {
- if ((obits & (1 << i)) == 0) {
- continue;
- }
- isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
- }
- MBOX_NOTIFY_COMPLETE(isp);
- } else {
- isp_prt(isp, ISP_LOGWARN, "mailbox cmd (0x%x) with no waiters", info);
- }
- } else {
- if (IS_FC(isp))
- isp_parse_async_fc(isp, info);
- else
- isp_parse_async(isp, info);
- }
- if ((IS_FC(isp) && info != ASYNC_RIOZIO_STALL) || isp->isp_state != ISP_RUNSTATE) {
- goto out;
- }
- }
-
/*
* We can't be getting this now.
*/
if (isp->isp_state != ISP_RUNSTATE) {
- /*
- * This seems to happen to 23XX and 24XX cards- don't know why.
- */
- if (isp->isp_mboxbsy && isp->isp_lastmbxcmd == MBOX_ABOUT_FIRMWARE) {
- goto fmbox;
- }
- isp_prt(isp, ISP_LOGINFO, "interrupt (ISR=%x SEMA=%x INFO=%x) "
- "when not ready", isr, sema, info);
- /*
- * Thank you very much! *Burrrp*!
- */
- isp->isp_residx = ISP_READ(isp, isp->isp_respinrp);
- isp->isp_resodx = isp->isp_residx;
- ISP_WRITE(isp, isp->isp_respoutrp, isp->isp_resodx);
- if (IS_24XX(isp)) {
- ISP_DISABLE_INTS(isp);
- }
- goto out;
- }
-
-#ifdef ISP_TARGET_MODE
- /*
- * Check for ATIO Queue entries.
- */
- if (IS_24XX(isp) &&
- (isr == ISPR2HST_ATIO_UPDATE || isr == ISPR2HST_ATIO_RSPQ_UPDATE ||
- isr == ISPR2HST_ATIO_UPDATE2)) {
- iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
- optr = isp->isp_atioodx;
-
- while (optr != iptr) {
- uint8_t qe[QENTRY_LEN];
- isphdr_t *hp;
- uint32_t oop;
- void *addr;
-
- oop = optr;
- MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1);
- addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
- isp_get_hdr(isp, addr, (isphdr_t *)qe);
- hp = (isphdr_t *)qe;
- switch (hp->rqs_entry_type) {
- case RQSTYPE_NOTIFY:
- case RQSTYPE_ATIO:
- (void) isp_target_notify(isp, addr, &oop);
- break;
- default:
- isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
- break;
- }
- optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
- }
- if (isp->isp_atioodx != optr) {
- ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
- isp->isp_atioodx = optr;
- }
+ isp_prt(isp, ISP_LOGINFO, "respq interrupt when not ready");
+ return;
}
-#endif
- /*
- * You *must* read the Response Queue In Pointer
- * prior to clearing the RISC interrupt.
- *
- * Debounce the 2300 if revision less than 2.
- */
+ iptr = ISP_READ(isp, isp->isp_respinrp);
+ /* Debounce the 2300 if revision less than 2. */
if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
- i = 0;
do {
+ junk = iptr;
iptr = ISP_READ(isp, isp->isp_respinrp);
- junk = ISP_READ(isp, isp->isp_respinrp);
- } while (junk != iptr && ++i < 1000);
-
- if (iptr != junk) {
- isp_prt(isp, ISP_LOGWARN, "Response Queue Out Pointer Unstable (%x, %x)", iptr, junk);
- goto out;
- }
- } else {
- iptr = ISP_READ(isp, isp->isp_respinrp);
- }
-
- optr = isp->isp_resodx;
- if (optr == iptr && sema == 0) {
- /*
- * There are a lot of these- reasons unknown- mostly on
- * faster Alpha machines.
- *
- * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
- * make sure the old interrupt went away (to avoid 'ringing'
- * effects), but that didn't stop this from occurring.
- */
- if (IS_24XX(isp)) {
- junk = 0;
- } else if (IS_23XX(isp)) {
- ISP_DELAY(100);
- iptr = ISP_READ(isp, isp->isp_respinrp);
- junk = ISP_READ(isp, BIU_R2HSTSLO);
- } else {
- junk = ISP_READ(isp, BIU_ISR);
- }
- if (optr == iptr) {
- if (IS_23XX(isp) || IS_24XX(isp)) {
- ;
- } else {
- sema = ISP_READ(isp, BIU_SEMA);
- info = ISP_READ(isp, OUTMAILBOX0);
- if ((sema & 0x3) && (info & 0x8000)) {
- goto again;
- }
- }
- isp->isp_intbogus++;
- isp_prt(isp, ISP_LOGDEBUG1, "bogus intr- isr %x (%x) iptr %x optr %x", isr, junk, iptr, optr);
- }
+ } while (junk != iptr);
}
isp->isp_residx = iptr;
+ optr = isp->isp_resodx;
while (optr != iptr) {
uint8_t qe[QENTRY_LEN];
ispstatusreq_t *sp = (ispstatusreq_t *) qe;
@@ -5130,9 +5056,6 @@ again:
for (i = 0; i < rio->req_header.rqs_seqno; i++) {
isp_fastpost_complete(isp, rio->req_handles[i]);
}
- if (isp->isp_fpcchiwater < rio->req_header.rqs_seqno) {
- isp->isp_fpcchiwater = rio->req_header.rqs_seqno;
- }
ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
last_etype = etype;
continue;
@@ -5377,10 +5300,8 @@ again:
if (ndone > (MAX_REQUESTQ_COMPLETIONS - continuations_expected - 1)) {
/* we'll lose some stats, but that's a small price to pay */
for (i = 0; i < ndone; i++) {
- if (complist[i]) {
- isp->isp_rsltccmplt++;
+ if (complist[i])
isp_done(complist[i]);
- }
}
ndone = 0;
}
@@ -5453,17 +5374,6 @@ again:
if (nlooked) {
ISP_WRITE(isp, isp->isp_respoutrp, optr);
isp->isp_resodx = optr;
- if (isp->isp_rscchiwater < ndone)
- isp->isp_rscchiwater = ndone;
- }
-
-out:
-
- if (IS_24XX(isp)) {
- ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
- } else {
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- ISP_WRITE(isp, BIU_SEMA, 0);
}
for (i = 0; i < ndone; i++) {
@@ -5473,7 +5383,6 @@ out:
((isp->isp_dblev & (ISP_LOGDEBUG0|ISP_LOG_CWARN) && ((!XS_NOERR(xs)) || (*XS_STSP(xs) != SCSI_GOOD))))) {
isp_prt_endcmd(isp, xs);
}
- isp->isp_rsltccmplt++;
isp_done(xs);
}
}
@@ -5666,16 +5575,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
if (h2) {
isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h2);
isp_fastpost_complete(isp, h2);
- if (isp->isp_fpcchiwater < 2) {
- isp->isp_fpcchiwater = 2;
- }
- } else {
- if (isp->isp_fpcchiwater < 1) {
- isp->isp_fpcchiwater = 1;
- }
}
- } else {
- isp->isp_intoasync++;
}
}
@@ -5733,19 +5633,16 @@ isp_parse_async_fc(ispsoftc_t *isp, uint16_t mbox)
case ASYNC_CMD_CMPLT:
isp_fastpost_complete(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1));
- if (isp->isp_fpcchiwater < 1) {
- isp->isp_fpcchiwater = 1;
- }
break;
case ASYNC_RIOZIO_STALL:
+ isp_intr_respq(isp);
break;
case ASYNC_CTIO_DONE:
#ifdef ISP_TARGET_MODE
isp_target_async(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) |
ISP_READ(isp, OUTMAILBOX1), mbox);
- isp->isp_fphccmplt++;
#else
isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC CTIO done");
#endif
@@ -6017,9 +5914,6 @@ isp_parse_async_fc(ispsoftc_t *isp, uint16_t mbox)
isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
break;
}
- if (mbox != ASYNC_CTIO_DONE && mbox != ASYNC_CMD_CMPLT) {
- isp->isp_intoasync++;
- }
}
/*
@@ -6106,11 +6000,9 @@ isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *opt
case RQSTYPE_CTIO7:
case RQSTYPE_ABTS_RCVD:
case RQSTYPE_ABTS_RSP:
- isp->isp_rsltccmplt++; /* count as a response completion */
#ifdef ISP_TARGET_MODE
- if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
+ if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp))
return (1);
- }
#endif
/* FALLTHROUGH */
case RQSTYPE_REQUEST:
@@ -6649,7 +6541,6 @@ isp_fastpost_complete(ispsoftc_t *isp, uint32_t fph)
if (isp->isp_nactive) {
isp->isp_nactive--;
}
- isp->isp_fphccmplt++;
isp_done(xs);
}
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 7c01ea0..d04813f 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -512,40 +512,6 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
}
break;
}
- case ISP_GET_STATS:
- {
- isp_stats_t *sp = (isp_stats_t *) addr;
-
- ISP_MEMZERO(sp, sizeof (*sp));
- sp->isp_stat_version = ISP_STATS_VERSION;
- sp->isp_type = isp->isp_type;
- sp->isp_revision = isp->isp_revision;
- ISP_LOCK(isp);
- sp->isp_stats[ISP_INTCNT] = isp->isp_intcnt;
- sp->isp_stats[ISP_INTBOGUS] = isp->isp_intbogus;
- sp->isp_stats[ISP_INTMBOXC] = isp->isp_intmboxc;
- sp->isp_stats[ISP_INGOASYNC] = isp->isp_intoasync;
- sp->isp_stats[ISP_RSLTCCMPLT] = isp->isp_rsltccmplt;
- sp->isp_stats[ISP_FPHCCMCPLT] = isp->isp_fphccmplt;
- sp->isp_stats[ISP_RSCCHIWAT] = isp->isp_rscchiwater;
- sp->isp_stats[ISP_FPCCHIWAT] = isp->isp_fpcchiwater;
- ISP_UNLOCK(isp);
- retval = 0;
- break;
- }
- case ISP_CLR_STATS:
- ISP_LOCK(isp);
- isp->isp_intcnt = 0;
- isp->isp_intbogus = 0;
- isp->isp_intmboxc = 0;
- isp->isp_intoasync = 0;
- isp->isp_rsltccmplt = 0;
- isp->isp_fphccmplt = 0;
- isp->isp_rscchiwater = 0;
- isp->isp_fpcchiwater = 0;
- ISP_UNLOCK(isp);
- retval = 0;
- break;
case ISP_FC_GETHINFO:
{
struct isp_hba_device *hba = (struct isp_hba_device *) addr;
@@ -2829,10 +2795,8 @@ static void
isp_poll(struct cam_sim *sim)
{
ispsoftc_t *isp = cam_sim_softc(sim);
- uint16_t isr, sema, info;
- if (ISP_READ_ISR(isp, &isr, &sema, &info))
- isp_intr(isp, isr, sema, info);
+ ISP_RUN_ISR(isp);
}
@@ -2851,9 +2815,7 @@ isp_watchdog(void *arg)
* Hand crank the interrupt code just to be sure the command isn't stuck somewhere.
*/
if (handle != ISP_HANDLE_FREE) {
- uint16_t isr, sema, info;
- if (ISP_READ_ISR(isp, &isr, &sema, &info) != 0)
- isp_intr(isp, isr, sema, info);
+ ISP_RUN_ISR(isp);
ohandle = handle;
handle = isp_find_handle(isp, xs);
}
@@ -4428,14 +4390,11 @@ isp_mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
isp->isp_osinfo.mbox_sleeping = 0;
} else {
for (t = 0; t < to; t += 100) {
- uint16_t isr, sema, info;
if (isp->isp_osinfo.mboxcmd_done)
break;
- if (ISP_READ_ISR(isp, &isr, &sema, &info)) {
- isp_intr(isp, isr, sema, info);
- if (isp->isp_osinfo.mboxcmd_done)
- break;
- }
+ ISP_RUN_ISR(isp);
+ if (isp->isp_osinfo.mboxcmd_done)
+ break;
ISP_DELAY(100);
}
}
@@ -4495,14 +4454,9 @@ void
isp_platform_intr(void *arg)
{
ispsoftc_t *isp = arg;
- uint16_t isr, sema, info;
ISP_LOCK(isp);
- isp->isp_intcnt++;
- if (ISP_READ_ISR(isp, &isr, &sema, &info))
- isp_intr(isp, isr, sema, info);
- else
- isp->isp_intbogus++;
+ ISP_RUN_ISR(isp);
ISP_UNLOCK(isp);
}
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index f4641e6..887dd42 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -61,9 +61,9 @@ static uint32_t isp_pci_rd_reg_2400(ispsoftc_t *, int);
static void isp_pci_wr_reg_2400(ispsoftc_t *, int, uint32_t);
static uint32_t isp_pci_rd_reg_2600(ispsoftc_t *, int);
static void isp_pci_wr_reg_2600(ispsoftc_t *, int, uint32_t);
-static int isp_pci_rd_isr(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
-static int isp_pci_rd_isr_2300(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
-static int isp_pci_rd_isr_2400(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
+static void isp_pci_run_isr(ispsoftc_t *);
+static void isp_pci_run_isr_2300(ispsoftc_t *);
+static void isp_pci_run_isr_2400(ispsoftc_t *);
static int isp_pci_mbxdma(ispsoftc_t *);
static void isp_pci_mbxdmafree(ispsoftc_t *);
static int isp_pci_dmasetup(ispsoftc_t *, XS_T *, void *);
@@ -71,7 +71,7 @@ static int isp_pci_irqsetup(ispsoftc_t *);
static void isp_pci_dumpregs(ispsoftc_t *, const char *);
static struct ispmdvec mdvec = {
- isp_pci_rd_isr,
+ isp_pci_run_isr,
isp_pci_rd_reg,
isp_pci_wr_reg,
isp_pci_mbxdma,
@@ -84,7 +84,7 @@ static struct ispmdvec mdvec = {
};
static struct ispmdvec mdvec_1080 = {
- isp_pci_rd_isr,
+ isp_pci_run_isr,
isp_pci_rd_reg_1080,
isp_pci_wr_reg_1080,
isp_pci_mbxdma,
@@ -97,7 +97,7 @@ static struct ispmdvec mdvec_1080 = {
};
static struct ispmdvec mdvec_12160 = {
- isp_pci_rd_isr,
+ isp_pci_run_isr,
isp_pci_rd_reg_1080,
isp_pci_wr_reg_1080,
isp_pci_mbxdma,
@@ -110,7 +110,7 @@ static struct ispmdvec mdvec_12160 = {
};
static struct ispmdvec mdvec_2100 = {
- isp_pci_rd_isr,
+ isp_pci_run_isr,
isp_pci_rd_reg,
isp_pci_wr_reg,
isp_pci_mbxdma,
@@ -121,7 +121,7 @@ static struct ispmdvec mdvec_2100 = {
};
static struct ispmdvec mdvec_2200 = {
- isp_pci_rd_isr,
+ isp_pci_run_isr,
isp_pci_rd_reg,
isp_pci_wr_reg,
isp_pci_mbxdma,
@@ -132,7 +132,7 @@ static struct ispmdvec mdvec_2200 = {
};
static struct ispmdvec mdvec_2300 = {
- isp_pci_rd_isr_2300,
+ isp_pci_run_isr_2300,
isp_pci_rd_reg,
isp_pci_wr_reg,
isp_pci_mbxdma,
@@ -143,7 +143,7 @@ static struct ispmdvec mdvec_2300 = {
};
static struct ispmdvec mdvec_2400 = {
- isp_pci_rd_isr_2400,
+ isp_pci_run_isr_2400,
isp_pci_rd_reg_2400,
isp_pci_wr_reg_2400,
isp_pci_mbxdma,
@@ -154,7 +154,7 @@ static struct ispmdvec mdvec_2400 = {
};
static struct ispmdvec mdvec_2500 = {
- isp_pci_rd_isr_2400,
+ isp_pci_run_isr_2400,
isp_pci_rd_reg_2400,
isp_pci_wr_reg_2400,
isp_pci_mbxdma,
@@ -165,7 +165,7 @@ static struct ispmdvec mdvec_2500 = {
};
static struct ispmdvec mdvec_2600 = {
- isp_pci_rd_isr_2400,
+ isp_pci_run_isr_2400,
isp_pci_rd_reg_2600,
isp_pci_wr_reg_2600,
isp_pci_mbxdma,
@@ -1066,35 +1066,27 @@ isp_pci_detach(device_t dev)
#define B2R4(isp, off) bus_read_4((isp)->isp_regs2, (off))
#define B2W4(isp, off, v) bus_write_4((isp)->isp_regs2, (off), (v))
-static ISP_INLINE int
-isp_pci_rd_debounced(ispsoftc_t *isp, int off, uint16_t *rp)
+static ISP_INLINE uint16_t
+isp_pci_rd_debounced(ispsoftc_t *isp, int off)
{
- uint32_t val0, val1;
- int i = 0;
+ uint16_t val, prev;
+ val = BXR2(isp, IspVirt2Off(isp, off));
do {
- val0 = BXR2(isp, IspVirt2Off(isp, off));
- val1 = BXR2(isp, IspVirt2Off(isp, off));
- } while (val0 != val1 && ++i < 1000);
- if (val0 != val1) {
- return (1);
- }
- *rp = val0;
- return (0);
+ prev = val;
+ val = BXR2(isp, IspVirt2Off(isp, off));
+ } while (val != prev);
+ return (val);
}
-static int
-isp_pci_rd_isr(ispsoftc_t *isp, uint16_t *isrp, uint16_t *semap, uint16_t *info)
+static void
+isp_pci_run_isr(ispsoftc_t *isp)
{
- uint16_t isr, sema;
+ uint16_t isr, sema, info;
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);
- }
+ isr = isp_pci_rd_debounced(isp, BIU_ISR);
+ sema = isp_pci_rd_debounced(isp, BIU_SEMA);
} else {
isr = BXR2(isp, IspVirt2Off(isp, BIU_ISR));
sema = BXR2(isp, IspVirt2Off(isp, BIU_SEMA));
@@ -1102,59 +1094,61 @@ isp_pci_rd_isr(ispsoftc_t *isp, uint16_t *isrp, uint16_t *semap, uint16_t *info)
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, info)) {
- return (0);
- }
- } else {
- *info = BXR2(isp, IspVirt2Off(isp, OUTMAILBOX0));
- }
- }
- return (1);
+ if (isr == 0 && sema == 0)
+ return;
+ if (sema != 0) {
+ if (IS_2100(isp))
+ info = isp_pci_rd_debounced(isp, OUTMAILBOX0);
+ else
+ info = BXR2(isp, IspVirt2Off(isp, OUTMAILBOX0));
+ if (info & MBOX_COMMAND_COMPLETE)
+ isp_intr_mbox(isp, info);
+ else
+ isp_intr_async(isp, info);
+ if (!IS_FC(isp) && isp->isp_state == ISP_RUNSTATE)
+ isp_intr_respq(isp);
+ } else
+ isp_intr_respq(isp);
+ ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
+ if (sema)
+ ISP_WRITE(isp, BIU_SEMA, 0);
}
-static int
-isp_pci_rd_isr_2300(ispsoftc_t *isp, uint16_t *isrp, uint16_t *semap, uint16_t *info)
+static void
+isp_pci_run_isr_2300(ispsoftc_t *isp)
{
uint32_t hccr, r2hisr;
+ uint16_t isr, info;
- if ((BXR2(isp, IspVirt2Off(isp, BIU_ISR)) & BIU2100_ISR_RISC_INT) == 0) {
- *isrp = 0;
- return (0);
- }
+ if ((BXR2(isp, IspVirt2Off(isp, BIU_ISR)) & BIU2100_ISR_RISC_INT) == 0)
+ return;
r2hisr = BXR4(isp, IspVirt2Off(isp, BIU_R2HSTSLO));
isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr);
- if ((r2hisr & BIU_R2HST_INTR) == 0) {
- *isrp = 0;
- return (0);
- }
- switch ((*isrp = r2hisr & BIU_R2HST_ISTAT_MASK)) {
+ if ((r2hisr & BIU_R2HST_INTR) == 0)
+ return;
+ isr = r2hisr & BIU_R2HST_ISTAT_MASK;
+ info = r2hisr >> 16;
+ switch (isr) {
case ISPR2HST_ROM_MBX_OK:
case ISPR2HST_ROM_MBX_FAIL:
case ISPR2HST_MBX_OK:
case ISPR2HST_MBX_FAIL:
+ isp_intr_mbox(isp, info);
+ break;
case ISPR2HST_ASYNC_EVENT:
- *semap = 1;
+ isp_intr_async(isp, info);
break;
case ISPR2HST_RIO_16:
- *info = ASYNC_RIO16_1;
- *semap = 1;
- return (1);
+ isp_intr_async(isp, ASYNC_RIO16_1);
+ break;
case ISPR2HST_FPOST:
- *info = ASYNC_CMD_CMPLT;
- *semap = 1;
- return (1);
+ isp_intr_async(isp, ASYNC_CMD_CMPLT);
+ break;
case ISPR2HST_FPOST_CTIO:
- *info = ASYNC_CTIO_DONE;
- *semap = 1;
- return (1);
+ isp_intr_async(isp, ASYNC_CTIO_DONE);
+ break;
case ISPR2HST_RSPQ_UPDATE:
- *semap = 0;
+ isp_intr_respq(isp);
break;
default:
hccr = ISP_READ(isp, HCCR);
@@ -1165,45 +1159,52 @@ isp_pci_rd_isr_2300(ispsoftc_t *isp, uint16_t *isrp, uint16_t *semap, uint16_t *
} else {
isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n", r2hisr);
}
- return (0);
}
- *info = (r2hisr >> 16);
- return (1);
+ ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
+ ISP_WRITE(isp, BIU_SEMA, 0);
}
-static int
-isp_pci_rd_isr_2400(ispsoftc_t *isp, uint16_t *isrp, uint16_t *semap, uint16_t *info)
+static void
+isp_pci_run_isr_2400(ispsoftc_t *isp)
{
uint32_t r2hisr;
+ uint16_t isr, info;
r2hisr = BXR4(isp, IspVirt2Off(isp, BIU2400_R2HSTSLO));
isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr);
- if ((r2hisr & BIU_R2HST_INTR) == 0) {
- *isrp = 0;
- return (0);
- }
- switch ((*isrp = r2hisr & BIU_R2HST_ISTAT_MASK)) {
+ if ((r2hisr & BIU_R2HST_INTR) == 0)
+ return;
+ isr = r2hisr & BIU_R2HST_ISTAT_MASK;
+ info = (r2hisr >> 16);
+ switch (isr) {
case ISPR2HST_ROM_MBX_OK:
case ISPR2HST_ROM_MBX_FAIL:
case ISPR2HST_MBX_OK:
case ISPR2HST_MBX_FAIL:
+ isp_intr_mbox(isp, info);
+ break;
case ISPR2HST_ASYNC_EVENT:
- *semap = 1;
+ isp_intr_async(isp, info);
break;
case ISPR2HST_RSPQ_UPDATE:
+ isp_intr_respq(isp);
+ break;
case ISPR2HST_RSPQ_UPDATE2:
- case ISPR2HST_ATIO_UPDATE:
+#ifdef ISP_TARGET_MODE
case ISPR2HST_ATIO_RSPQ_UPDATE:
+#endif
+ isp_intr_respq(isp);
+ /* FALLTHROUGH */
+#ifdef ISP_TARGET_MODE
+ case ISPR2HST_ATIO_UPDATE:
case ISPR2HST_ATIO_UPDATE2:
- *semap = 0;
+ isp_intr_atioq(isp);
+#endif
break;
default:
- ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n", r2hisr);
- return (0);
}
- *info = (r2hisr >> 16);
- return (1);
+ ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
}
static uint32_t
diff --git a/sys/dev/isp/isp_sbus.c b/sys/dev/isp/isp_sbus.c
index 65c5ee5..e161045 100644
--- a/sys/dev/isp/isp_sbus.c
+++ b/sys/dev/isp/isp_sbus.c
@@ -53,14 +53,14 @@ __FBSDID("$FreeBSD$");
static uint32_t isp_sbus_rd_reg(ispsoftc_t *, int);
static void isp_sbus_wr_reg(ispsoftc_t *, int, uint32_t);
-static int isp_sbus_rd_isr(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
+static void isp_sbus_run_isr(ispsoftc_t *);
static int isp_sbus_mbxdma(ispsoftc_t *);
static void isp_sbus_mbxdmafree(ispsoftc_t *);
static int isp_sbus_dmasetup(ispsoftc_t *, XS_T *, void *);
static void isp_sbus_dumpregs(ispsoftc_t *, const char *);
static struct ispmdvec mdvec = {
- isp_sbus_rd_isr,
+ isp_sbus_run_isr,
isp_sbus_rd_reg,
isp_sbus_wr_reg,
isp_sbus_mbxdma,
@@ -344,23 +344,31 @@ isp_sbus_detach(device_t dev)
#define BXR2(isp, off) bus_read_2((isp)->isp_regs, (off))
-static int
-isp_sbus_rd_isr(ispsoftc_t *isp, uint16_t *isrp, uint16_t *semap, uint16_t *info)
+static void
+isp_sbus_run_isr(ispsoftc_t *isp)
{
- uint16_t isr, sema;
+ uint16_t isr, sema, info;
isr = BXR2(isp, IspVirt2Off(isp, BIU_ISR));
sema = BXR2(isp, 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)
- *info = BXR2(isp, IspVirt2Off(isp, OUTMAILBOX0));
- return (1);
+ if (isr == 0 && sema == 0)
+ return;
+ if (sema != 0) {
+ info = BXR2(isp, IspVirt2Off(isp, OUTMAILBOX0));
+ if (info & MBOX_COMMAND_COMPLETE)
+ isp_intr_mbox(isp, info);
+ else
+ isp_intr_async(isp, info);
+ if (isp->isp_state == ISP_RUNSTATE)
+ isp_intr_respq(isp);
+ } else
+ isp_intr_respq(isp);
+ ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
+ if (sema)
+ ISP_WRITE(isp, BIU_SEMA, 0);
}
static uint32_t
diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h
index 8f9bfc0..3af7a7c 100644
--- a/sys/dev/isp/ispvar.h
+++ b/sys/dev/isp/ispvar.h
@@ -58,7 +58,7 @@
*/
typedef struct ispsoftc ispsoftc_t;
struct ispmdvec {
- int (*dv_rd_isr) (ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
+ void (*dv_run_isr) (ispsoftc_t *);
uint32_t (*dv_rd_reg) (ispsoftc_t *, int);
void (*dv_wr_reg) (ispsoftc_t *, int, uint32_t);
int (*dv_mbxdma) (ispsoftc_t *);
@@ -85,8 +85,8 @@ struct ispmdvec {
* Macros to access ISP registers through bus specific layers-
* mostly wrappers to vector through the mdvec structure.
*/
-#define ISP_READ_ISR(isp, isrp, semap, info) \
- (*(isp)->isp_mdvec->dv_rd_isr)(isp, isrp, semap, info)
+#define ISP_RUN_ISR(isp) \
+ (*(isp)->isp_mdvec->dv_run_isr)(isp)
#define ISP_READ(isp, reg) \
(*(isp)->isp_mdvec->dv_rd_reg)((isp), (reg))
@@ -544,18 +544,6 @@ struct ispsoftc {
uint32_t isp_rqstoutrp; /* register for REQOUTP */
uint32_t isp_respinrp; /* register for RESINP */
uint32_t isp_respoutrp; /* register for RESOUTP */
-
- /*
- * Instrumentation
- */
- uint64_t isp_intcnt; /* total int count */
- uint64_t isp_intbogus; /* spurious int count */
- uint64_t isp_intmboxc; /* mbox completions */
- uint64_t isp_intoasync; /* other async */
- uint64_t isp_rsltccmplt; /* CMDs on result q */
- uint64_t isp_fphccmplt; /* CMDs via fastpost */
- uint16_t isp_rscchiwater;
- uint16_t isp_fpcchiwater;
NANOTIME_T isp_init_time; /* time were last initialized */
/*
@@ -813,12 +801,13 @@ void isp_shutdown(ispsoftc_t *);
/*
* 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.
*/
-void isp_intr(ispsoftc_t *, uint16_t, uint16_t, uint16_t);
+#ifdef ISP_TARGET_MODE
+void isp_intr_atioq(ispsoftc_t *);
+#endif
+void isp_intr_async(ispsoftc_t *, uint16_t event);
+void isp_intr_mbox(ispsoftc_t *, uint16_t mbox0);
+void isp_intr_respq(ispsoftc_t *);
/*
OpenPOWER on IntegriCloud