aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorScott Long <scottl@FreeBSD.org>2009-09-17 05:27:32 +0000
committerScott Long <scottl@FreeBSD.org>2009-09-17 05:27:32 +0000
commit053351cec37100a3558f948b269f8c891ac9cfce (patch)
tree8f1ac268a9e208e13ec20bccd6598e181aac3ecc /sys/dev
parent6b3c18a020e2a95bc57bbcedd40a932fa8e93663 (diff)
Notes
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ciss/ciss.c26
-rw-r--r--sys/dev/ciss/cissreg.h3
-rw-r--r--sys/dev/ciss/cissvar.h2
3 files changed, 23 insertions, 8 deletions
diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c
index 8c9ef5adb34f..f95b689b7f57 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;
@@ -2559,15 +2567,16 @@ ciss_user_command(struct ciss_softc *sc, IOCTL_Command_struct *ioc)
/*
* Allocate an in-kernel databuffer if required, copy in user data.
*/
+ mtx_unlock(&sc->ciss_mtx);
cr->cr_length = ioc->buf_size;
if (ioc->buf_size > 0) {
if ((cr->cr_data = malloc(ioc->buf_size, CISS_MALLOC_CLASS, M_NOWAIT)) == NULL) {
error = ENOMEM;
- goto out;
+ goto out_unlocked;
}
if ((error = copyin(ioc->buf, cr->cr_data, ioc->buf_size))) {
debug(0, "copyin: bad data buffer %p/%d", ioc->buf, ioc->buf_size);
- goto out;
+ goto out_unlocked;
}
}
@@ -2578,6 +2587,7 @@ ciss_user_command(struct ciss_softc *sc, IOCTL_Command_struct *ioc)
bcopy(&ioc->Request, &cc->cdb, sizeof(cc->cdb));
/* XXX anything else to populate here? */
+ mtx_lock(&sc->ciss_mtx);
/*
* Run the command.
@@ -2598,15 +2608,19 @@ ciss_user_command(struct ciss_softc *sc, IOCTL_Command_struct *ioc)
* Copy the results back to the user.
*/
bcopy(ce, &ioc->error_info, sizeof(*ce));
+ mtx_unlock(&sc->ciss_mtx);
if ((ioc->buf_size > 0) &&
(error = copyout(cr->cr_data, ioc->buf, ioc->buf_size))) {
debug(0, "copyout: bad data buffer %p/%d", ioc->buf, ioc->buf_size);
- goto out;
+ goto out_unlocked;
}
/* done OK */
error = 0;
+out_unlocked:
+ mtx_lock(&sc->ciss_mtx);
+
out:
if ((cr != NULL) && (cr->cr_data != NULL))
free(cr->cr_data, CISS_MALLOC_CLASS);
diff --git a/sys/dev/ciss/cissreg.h b/sys/dev/ciss/cissreg.h
index 196307b6508d..9ed631b4ad72 100644
--- a/sys/dev/ciss/cissreg.h
+++ b/sys/dev/ciss/cissreg.h
@@ -736,7 +736,8 @@ struct ciss_bmic_flush_cache {
#define CISS_TL_PERF_CLEAR_INT(sc) CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_ODC, CISS_TL_SIMPLE_ODC_CLEAR)
#define CISS_CYCLE_MASK 0x00000001
-#define CISS_MSI_COUNT 4
+/* Only need one MSI/MSI-X vector */
+#define CISS_MSI_COUNT 1
#define CISS_TL_SIMPLE_DISABLE_INTERRUPTS(sc) \
CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IMR, \
diff --git a/sys/dev/ciss/cissvar.h b/sys/dev/ciss/cissvar.h
index f9f5c6f10499..98e875fbf30d 100644
--- a/sys/dev/ciss/cissvar.h
+++ b/sys/dev/ciss/cissvar.h
@@ -176,7 +176,7 @@ struct ciss_pdrive
#define CISS_PHYSICAL_SHIFT 5
#define CISS_PHYSICAL_BASE (1 << CISS_PHYSICAL_SHIFT)
-#define CISS_MAX_PHYSTGT 15
+#define CISS_MAX_PHYSTGT 256
#define CISS_IS_PHYSICAL(bus) (bus >= CISS_PHYSICAL_BASE)
#define CISS_CAM_TO_PBUS(bus) (bus - CISS_PHYSICAL_BASE)