aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/mpr/mpr_pci.c
diff options
context:
space:
mode:
authorScott Long <scottl@FreeBSD.org>2017-07-30 06:53:58 +0000
committerScott Long <scottl@FreeBSD.org>2017-07-30 06:53:58 +0000
commit252b2b4f4fb7f7749f90c83e5e01ba68b5424ffa (patch)
tree39d65e8a960f9ea32511ca4f88f2d057f32c21a5 /sys/dev/mpr/mpr_pci.c
parent7f25cd53b5b0f9ff6c32aa76f8f2d7788f11be48 (diff)
Notes
Diffstat (limited to 'sys/dev/mpr/mpr_pci.c')
-rw-r--r--sys/dev/mpr/mpr_pci.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/sys/dev/mpr/mpr_pci.c b/sys/dev/mpr/mpr_pci.c
index 4b9f0aaa1513..ce7e56c807d5 100644
--- a/sys/dev/mpr/mpr_pci.c
+++ b/sys/dev/mpr/mpr_pci.c
@@ -69,6 +69,7 @@ static int mpr_pci_resume(device_t);
static void mpr_pci_free(struct mpr_softc *);
static int mpr_alloc_msix(struct mpr_softc *sc, int msgs);
static int mpr_alloc_msi(struct mpr_softc *sc, int msgs);
+static int mpr_pci_alloc_interrupts(struct mpr_softc *sc);
static device_method_t mpr_methods[] = {
DEVMETHOD(device_probe, mpr_pci_probe),
@@ -191,6 +192,8 @@ mpr_pci_attach(device_t dev)
m = mpr_find_ident(dev);
sc->mpr_flags = m->flags;
+ mpr_get_tunables(sc);
+
/* Twiddle basic PCI config bits for a sanity check */
pci_enable_busmaster(dev);
@@ -240,28 +243,51 @@ mpr_pci_attach(device_t dev)
return (ENOMEM);
}
- if ((error = mpr_attach(sc)) != 0)
+ if (((error = mpr_pci_alloc_interrupts(sc)) != 0) ||
+ ((error = mpr_attach(sc)) != 0))
mpr_pci_free(sc);
return (error);
}
+/*
+ * Allocate, but don't assign interrupts early. Doing it before requesting
+ * the IOCFacts message informs the firmware that we want to do MSI-X
+ * multiqueue. We might not use all of the available messages, but there's
+ * no reason to re-alloc if we don't.
+ */
int
-mpr_pci_setup_interrupts(struct mpr_softc *sc)
+mpr_pci_alloc_interrupts(struct mpr_softc *sc)
{
device_t dev;
- int i, error, msgs;
+ int error, msgs;
dev = sc->mpr_dev;
- error = ENXIO;
+ error = 0;
+
if ((sc->disable_msix == 0) &&
((msgs = pci_msix_count(dev)) >= MPR_MSI_COUNT))
error = mpr_alloc_msix(sc, MPR_MSI_COUNT);
if ((error != 0) && (sc->disable_msi == 0) &&
((msgs = pci_msi_count(dev)) >= MPR_MSI_COUNT))
error = mpr_alloc_msi(sc, MPR_MSI_COUNT);
+ else
+ msgs = 0;
+
+ sc->msi_msgs = msgs;
+ return (error);
+}
+
+int
+mpr_pci_setup_interrupts(struct mpr_softc *sc)
+{
+ device_t dev;
+ int i, error;
+
+ dev = sc->mpr_dev;
+ error = ENXIO;
- if (error != 0) {
+ if (sc->msi_msgs == 0) {
sc->mpr_flags |= MPR_FLAGS_INTX;
sc->mpr_irq_rid[0] = 0;
sc->mpr_irq[0] = bus_alloc_resource_any(dev, SYS_RES_IRQ,