diff options
| author | Scott Long <scottl@FreeBSD.org> | 2017-09-08 20:20:35 +0000 |
|---|---|---|
| committer | Scott Long <scottl@FreeBSD.org> | 2017-09-08 20:20:35 +0000 |
| commit | 3d96cd787356d6b2d6085de134ec8f9bfeb91192 (patch) | |
| tree | 46b142533070bb92c1a0331db8917b6a4ace9c03 /sys/dev/mps | |
| parent | 2e2baf2ec37b52e5fa4464f857dce1106456fa9a (diff) | |
Notes
Diffstat (limited to 'sys/dev/mps')
| -rw-r--r-- | sys/dev/mps/mps_pci.c | 103 |
1 files changed, 53 insertions, 50 deletions
diff --git a/sys/dev/mps/mps_pci.c b/sys/dev/mps/mps_pci.c index bfa71cc6c95a..2e95b42cc22d 100644 --- a/sys/dev/mps/mps_pci.c +++ b/sys/dev/mps/mps_pci.c @@ -253,10 +253,21 @@ mps_pci_alloc_interrupts(struct mps_softc *sc) if ((error != 0) && (sc->disable_msi == 0) && ((msgs = pci_msi_count(dev)) >= MPS_MSI_COUNT)) error = mps_alloc_msi(sc, MPS_MSI_COUNT); - if (error != 0) - msgs = 0; + if (error != 0) { + /* + * If neither MSI or MSI-X are avaiable, assume legacy INTx. + * This also implies that there will be only 1 queue. + */ + sc->mps_flags |= MPS_FLAGS_INTX; + msgs = 1; + } else { + sc->mps_flags |= MPS_FLAGS_MSI; + msgs = 1; /* XXX */ + } sc->msi_msgs = msgs; + mps_dprint(sc, MPS_INIT, "Allocated %d interrupts\n", msgs); + return (error); } @@ -264,47 +275,46 @@ int mps_pci_setup_interrupts(struct mps_softc *sc) { device_t dev; - int i, error; + void *ihandler; + int i, error, rid, initial_rid; dev = sc->mps_dev; error = ENXIO; - if (sc->msi_msgs == 0) { - sc->mps_flags |= MPS_FLAGS_INTX; - sc->mps_irq_rid[0] = 0; - sc->mps_irq[0] = bus_alloc_resource_any(dev, SYS_RES_IRQ, - &sc->mps_irq_rid[0], RF_SHAREABLE | RF_ACTIVE); - if (sc->mps_irq[0] == NULL) { - mps_printf(sc, "Cannot allocate INTx interrupt\n"); - return (ENXIO); - } - error = bus_setup_intr(dev, sc->mps_irq[0], - INTR_TYPE_BIO | INTR_MPSAFE, NULL, mps_intr, sc, - &sc->mps_intrhand[0]); - if (error) - mps_printf(sc, "Cannot setup INTx interrupt\n"); + if (sc->mps_flags & MPS_FLAGS_INTX) { + initial_rid = 0; + ihandler = mps_intr; + } else if (sc->mps_flags & MPS_FLAGS_MSI) { + initial_rid = 1; + ihandler = mps_intr_msi; } else { - sc->mps_flags |= MPS_FLAGS_MSI; - for (i = 0; i < MPS_MSI_COUNT; i++) { - sc->mps_irq_rid[i] = i + 1; - sc->mps_irq[i] = bus_alloc_resource_any(dev, - SYS_RES_IRQ, &sc->mps_irq_rid[i], RF_ACTIVE); - if (sc->mps_irq[i] == NULL) { - mps_printf(sc, - "Cannot allocate MSI interrupt\n"); - return (ENXIO); - } - error = bus_setup_intr(dev, sc->mps_irq[i], - INTR_TYPE_BIO | INTR_MPSAFE, NULL, mps_intr_msi, - sc, &sc->mps_intrhand[i]); - if (error) { - mps_printf(sc, - "Cannot setup MSI interrupt %d\n", i); - break; - } + mps_dprint(sc, MPS_ERROR|MPS_INIT, + "Unable to set up interrupts\n"); + return (EINVAL); + } + + for (i = 0; i < sc->msi_msgs; i++) { + rid = i + initial_rid; + sc->mps_irq_rid[i] = rid; + sc->mps_irq[i] = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &sc->mps_irq_rid[i], RF_ACTIVE); + if (sc->mps_irq[i] == NULL) { + mps_dprint(sc, MPS_ERROR|MPS_INIT, + "Cannot allocate interrupt RID%d\n", rid); + break; + } + error = bus_setup_intr(dev, sc->mps_irq[i], + INTR_TYPE_BIO | INTR_MPSAFE, NULL, ihandler, + sc, &sc->mps_intrhand[i]); + if (error) { + mps_dprint(sc, MPS_ERROR|MPS_INIT, + "Cannot setup interrupt RID %d\n", rid); + break; } } + mps_dprint(sc, MPS_INIT, "Set up %d interrupts\n", sc->msi_msgs); + return (error); } @@ -332,24 +342,17 @@ mps_pci_free(struct mps_softc *sc) bus_dma_tag_destroy(sc->mps_parent_dmat); } - if (sc->mps_flags & MPS_FLAGS_MSI) { - for (i = 0; i < MPS_MSI_COUNT; i++) { - if (sc->mps_irq[i] != NULL) { - bus_teardown_intr(sc->mps_dev, sc->mps_irq[i], - sc->mps_intrhand[i]); - bus_release_resource(sc->mps_dev, SYS_RES_IRQ, - sc->mps_irq_rid[i], sc->mps_irq[i]); - } + for (i = 0; i < sc->msi_msgs; i++) { + if (sc->mps_irq[i] != NULL) { + bus_teardown_intr(sc->mps_dev, sc->mps_irq[i], + sc->mps_intrhand[i]); + bus_release_resource(sc->mps_dev, SYS_RES_IRQ, + sc->mps_irq_rid[i], sc->mps_irq[i]); } - pci_release_msi(sc->mps_dev); } - if (sc->mps_flags & MPS_FLAGS_INTX) { - bus_teardown_intr(sc->mps_dev, sc->mps_irq[0], - sc->mps_intrhand[0]); - bus_release_resource(sc->mps_dev, SYS_RES_IRQ, - sc->mps_irq_rid[0], sc->mps_irq[0]); - } + if (sc->mps_flags & MPS_FLAGS_MSI) + pci_release_msi(sc->mps_dev); if (sc->mps_regs_resource != NULL) { bus_release_resource(sc->mps_dev, SYS_RES_MEMORY, |
