summaryrefslogtreecommitdiffstats
path: root/sys/dev/ciss/ciss.c
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2009-09-16 23:10:10 +0000
committerscottl <scottl@FreeBSD.org>2009-09-16 23:10:10 +0000
commit7780e2c81f386e967efdc0944036426a38d5631c (patch)
tree8a3a29a21d65f17163c499149bd66f07cf867f36 /sys/dev/ciss/ciss.c
parented3e2dff4b8015f6b024c7e85202510ca35c93cd (diff)
downloadFreeBSD-src-7780e2c81f386e967efdc0944036426a38d5631c.zip
FreeBSD-src-7780e2c81f386e967efdc0944036426a38d5631c.tar.gz
Make MSI and PERFORMANT interrupts work correctly. Only require the minimum
number of MSIX interrupts that are needed, and don't strictly check for 4. Enable enough interrupt mask bits so that the controller will generate interrupts in PERFORMANT mode. This fixes the hang-on-boot issues that people were seeing with newer controllers.
Diffstat (limited to 'sys/dev/ciss/ciss.c')
-rw-r--r--sys/dev/ciss/ciss.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c
index 8c9ef5a..b09575e 100644
--- a/sys/dev/ciss/ciss.c
+++ b/sys/dev/ciss/ciss.c
@@ -736,11 +736,16 @@ setup:
ciss_printf(sc, "PERFORMANT Transport\n");
if ((ciss_force_interrupt != 1) && (ciss_setup_msix(sc) == 0)) {
intr = ciss_perf_msi_intr;
- sc->ciss_interrupt_mask = CISS_TL_PERF_INTR_MSI;
} else {
intr = ciss_perf_intr;
- sc->ciss_interrupt_mask = CISS_TL_PERF_INTR_OPQ;
}
+ /* XXX The docs say that the 0x01 bit is only for SAS controllers.
+ * Unfortunately, there is no good way to know if this is a SAS
+ * controller. Hopefully enabling this bit universally will work OK.
+ * It seems to work fine for SA6i controllers.
+ */
+ sc->ciss_interrupt_mask = CISS_TL_PERF_INTR_OPQ | CISS_TL_PERF_INTR_MSI;
+
} else {
ciss_printf(sc, "SIMPLE Transport\n");
/* MSIX doesn't seem to work in SIMPLE mode, only enable if it forced */
@@ -834,7 +839,10 @@ ciss_setup_msix(struct ciss_softc *sc)
return (EINVAL);
val = pci_msix_count(sc->ciss_dev);
- if ((val != CISS_MSI_COUNT) || (pci_alloc_msix(sc->ciss_dev, &val) != 0))
+ if (val < CISS_MSI_COUNT)
+ return (EINVAL);
+ val = MIN(val, CISS_MSI_COUNT);
+ if (pci_alloc_msix(sc->ciss_dev, &val) != 0)
return (EINVAL);
sc->ciss_msi = val;
OpenPOWER on IntegriCloud