diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/isp/isp.c | 261 | ||||
-rw-r--r-- | sys/dev/isp/isp_freebsd.c | 58 | ||||
-rw-r--r-- | sys/dev/isp/isp_pci.c | 173 | ||||
-rw-r--r-- | sys/dev/isp/isp_sbus.c | 32 | ||||
-rw-r--r-- | sys/dev/isp/ispvar.h | 29 |
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 *); /* |