Index: sys/dev/puc/puc.c =================================================================== --- sys/dev/puc/puc.c (revision 263038) +++ sys/dev/puc/puc.c (working copy) @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -70,6 +71,8 @@ static MALLOC_DEFINE(M_PUC, "PUC", "PUC driver"); +SYSCTL_NODE(_hw, OID_AUTO, puc, CTLFLAG_RD, 0, "puc(9) driver configuration"); + struct puc_bar * puc_get_bar(struct puc_softc *sc, int rid) { @@ -324,7 +327,6 @@ if (bootverbose && sc->sc_ilr != 0) device_printf(dev, "using interrupt latch register\n"); - sc->sc_irid = 0; sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irid, RF_ACTIVE|RF_SHAREABLE); if (sc->sc_ires != NULL) { Index: sys/dev/puc/puc_bfe.h =================================================================== --- sys/dev/puc/puc_bfe.h (revision 263038) +++ sys/dev/puc/puc_bfe.h (working copy) @@ -66,6 +66,7 @@ int sc_fastintr:1; int sc_leaving:1; int sc_polled:1; + int sc_msi:1; int sc_ilr; @@ -94,4 +95,6 @@ driver_filter_t *, driver_intr_t *, void *, void **); int puc_bus_teardown_intr(device_t, device_t, struct resource *, void *); +SYSCTL_DECL(_hw_puc); + #endif /* _DEV_PUC_BFE_H_ */ Index: sys/dev/puc/puc_cfg.c =================================================================== --- sys/dev/puc/puc_cfg.c (revision 263038) +++ sys/dev/puc/puc_cfg.c (working copy) @@ -31,6 +31,7 @@ #include #include #include +#include #include #include Index: sys/dev/puc/puc_pccard.c =================================================================== --- sys/dev/puc/puc_pccard.c (revision 263038) +++ sys/dev/puc/puc_pccard.c (working copy) @@ -34,6 +34,7 @@ #include #include #include +#include #include #include Index: sys/dev/puc/puc_pci.c =================================================================== --- sys/dev/puc/puc_pci.c (revision 263038) +++ sys/dev/puc/puc_pci.c (working copy) @@ -67,6 +67,7 @@ #include #include #include +#include #include #include @@ -78,6 +79,11 @@ #include #include +static int puc_msi_disable; +TUNABLE_INT("hw.puc.msi_disable", &puc_msi_disable); +SYSCTL_INT(_hw_puc, OID_AUTO, msi_disable, CTLFLAG_RD | CTLFLAG_TUN, + &puc_msi_disable, 0, "Disable use of MSI interrupts by puc(9)"); + static const struct puc_cfg * puc_pci_match(device_t dev, const struct puc_cfg *desc) { @@ -120,11 +126,56 @@ return (puc_bfe_probe(dev, desc)); } +static int +puc_pci_attach(device_t dev) +{ + struct puc_softc *sc; + int error, count; + + sc = device_get_softc(dev); + + if (!puc_msi_disable) { + count = 1; + + if (pci_alloc_msi(dev, &count) == 0) { + sc->sc_msi = 1; + sc->sc_irid = 1; + } + } + + error = puc_bfe_attach(dev); + + if (error != 0 && sc->sc_msi) + pci_release_msi(dev); + + return (error); +} + +static int +puc_pci_detach(device_t dev) +{ + struct puc_softc *sc; + int error; + + sc = device_get_softc(dev); + + error = puc_bfe_detach(dev); + + if (error != 0) + return (error); + + if (sc->sc_msi) + error = pci_release_msi(dev); + + return (error); +} + + static device_method_t puc_pci_methods[] = { /* Device interface */ DEVMETHOD(device_probe, puc_pci_probe), - DEVMETHOD(device_attach, puc_bfe_attach), - DEVMETHOD(device_detach, puc_bfe_detach), + DEVMETHOD(device_attach, puc_pci_attach), + DEVMETHOD(device_detach, puc_pci_detach), DEVMETHOD(bus_alloc_resource, puc_bus_alloc_resource), DEVMETHOD(bus_release_resource, puc_bus_release_resource), Index: sys/dev/puc/pucdata.c =================================================================== --- sys/dev/puc/pucdata.c (revision 263038) +++ sys/dev/puc/pucdata.c (working copy) @@ -36,6 +36,7 @@ #include #include #include +#include #include #include