diff options
Diffstat (limited to 'sys/dev/puc/puc_pci.c')
-rw-r--r-- | sys/dev/puc/puc_pci.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/sys/dev/puc/puc_pci.c b/sys/dev/puc/puc_pci.c index 4ad1e3a..d6d5509 100644 --- a/sys/dev/puc/puc_pci.c +++ b/sys/dev/puc/puc_pci.c @@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$"); #include <sys/bus.h> #include <sys/conf.h> #include <sys/malloc.h> +#include <sys/sysctl.h> #include <machine/bus.h> #include <machine/resource.h> @@ -78,6 +79,11 @@ __FBSDID("$FreeBSD$"); #include <dev/puc/puc_cfg.h> #include <dev/puc/puc_bfe.h> +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 @@ puc_pci_probe(device_t dev) 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), |