summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp/isp_pci.c
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2017-03-29 15:42:35 +0000
committermav <mav@FreeBSD.org>2017-03-29 15:42:35 +0000
commit9b846bc013c221df1c2d0d1c3069fea8c3891732 (patch)
treebe0683aea33432b84807d14ecd0690a29f052c31 /sys/dev/isp/isp_pci.c
parent117e948538efaf610e8329f34db6cbf8656f1dda (diff)
downloadFreeBSD-src-9b846bc013c221df1c2d0d1c3069fea8c3891732.zip
FreeBSD-src-9b846bc013c221df1c2d0d1c3069fea8c3891732.tar.gz
MFC r315307: Refactor interrupt handling.
Instead of single isp_intr() function doing all possible magic, introduce four different functions to handle mailbox operation completions, async events, response and ATIO queues. The goal is to isolate different code paths to make code more readable, and to make easier support for multiple interrupt vectors. Even oldest hardware in many cases can identify what code path it should run on interrupt. Contemporary hardware can assign them to different interrupt vectors.
Diffstat (limited to 'sys/dev/isp/isp_pci.c')
-rw-r--r--sys/dev/isp/isp_pci.c173
1 files changed, 87 insertions, 86 deletions
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
OpenPOWER on IntegriCloud