From dcf83ff0e9e93349f750645be4d2b4d28ab05d12 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Sat, 27 Dec 2014 21:50:47 +0000 Subject: [PATCH] Improve/fix interrupt allocation/setup/release: - Simplify MSI allocation to what is actually needed for a single one. - Release the MSI and the corresponding bus resource as appropriate when either the interrupt resource cannot be allocated or setting up the interrupt fails. - Error out when interrupt allocation or setup fails and polling is disabled. - Release the MSI after the corresponding bus resource so the former is not leaked on detach. - Remove a redundant softc member. MFC after: 3 days --- sys/dev/usb/controller/xhci.h | 1 - sys/dev/usb/controller/xhci_pci.c | 45 ++++++++++++++++--------------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/sys/dev/usb/controller/xhci.h b/sys/dev/usb/controller/xhci.h index 7352e9c84ea..a6758558604 100644 --- a/sys/dev/usb/controller/xhci.h +++ b/sys/dev/usb/controller/xhci.h @@ -452,7 +452,6 @@ struct xhci_softc { struct usb_device *sc_devices[XHCI_MAX_DEVICES]; struct resource *sc_io_res; - int sc_irq_rid; struct resource *sc_irq_res; void *sc_intr_hdl; diff --git a/sys/dev/usb/controller/xhci_pci.c b/sys/dev/usb/controller/xhci_pci.c index efa69c2c9a7..c39842c431a 100644 --- a/sys/dev/usb/controller/xhci_pci.c +++ b/sys/dev/usb/controller/xhci_pci.c @@ -203,21 +203,19 @@ xhci_pci_attach(device_t self) usb_callout_init_mtx(&sc->sc_callout, &sc->sc_bus.bus_mtx, 0); - sc->sc_irq_rid = 0; + rid = 0; if (xhci_use_msi) { - count = pci_msi_count(self); - if (count >= 1) { - count = 1; - if (pci_alloc_msi(self, &count) == 0) { - if (bootverbose) - device_printf(self, "MSI enabled\n"); - sc->sc_irq_rid = 1; - } + count = 1; + if (pci_alloc_msi(self, &count) == 0) { + if (bootverbose) + device_printf(self, "MSI enabled\n"); + rid = 1; } } - sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, - &sc->sc_irq_rid, RF_SHAREABLE | RF_ACTIVE); + sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid, + RF_ACTIVE | (rid != 0 ? 0 : RF_SHAREABLE)); if (sc->sc_irq_res == NULL) { + pci_release_msi(self); device_printf(self, "Could not allocate IRQ\n"); /* goto error; FALLTHROUGH - use polling */ } @@ -234,16 +232,22 @@ xhci_pci_attach(device_t self) err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, NULL, (driver_intr_t *)xhci_interrupt, sc, &sc->sc_intr_hdl); if (err != 0) { + bus_release_resource(self, SYS_RES_IRQ, + rman_get_rid(sc->sc_irq_res), sc->sc_irq_res); + sc->sc_irq_res = NULL; + pci_release_msi(self); device_printf(self, "Could not setup IRQ, err=%d\n", err); sc->sc_intr_hdl = NULL; } } - if (sc->sc_irq_res == NULL || sc->sc_intr_hdl == NULL || - xhci_use_polling() != 0) { - device_printf(self, "Interrupt polling at %dHz\n", hz); - USB_BUS_LOCK(&sc->sc_bus); - xhci_interrupt_poll(sc); - USB_BUS_UNLOCK(&sc->sc_bus); + if (sc->sc_irq_res == NULL || sc->sc_intr_hdl == NULL) { + if (xhci_use_polling() != 0) { + device_printf(self, "Interrupt polling at %dHz\n", hz); + USB_BUS_LOCK(&sc->sc_bus); + xhci_interrupt_poll(sc); + USB_BUS_UNLOCK(&sc->sc_bus); + } else + goto error; } /* On Intel chipsets reroute ports from EHCI to XHCI controller. */ @@ -307,11 +311,10 @@ xhci_pci_detach(device_t self) sc->sc_intr_hdl = NULL; } if (sc->sc_irq_res) { - if (sc->sc_irq_rid == 1) - pci_release_msi(self); - bus_release_resource(self, SYS_RES_IRQ, sc->sc_irq_rid, - sc->sc_irq_res); + bus_release_resource(self, SYS_RES_IRQ, + rman_get_rid(sc->sc_irq_res), sc->sc_irq_res); sc->sc_irq_res = NULL; + pci_release_msi(self); } if (sc->sc_io_res) { bus_release_resource(self, SYS_RES_MEMORY, PCI_XHCI_CBMEM,