Index: head/sys/dev/usb/controller/xhci.h =================================================================== --- head/sys/dev/usb/controller/xhci.h +++ head/sys/dev/usb/controller/xhci.h @@ -465,6 +465,7 @@ struct usb_device *sc_devices[XHCI_MAX_DEVICES]; struct resource *sc_io_res; struct resource *sc_irq_res; + struct resource *sc_msix_res; void *sc_intr_hdl; bus_size_t sc_io_size; Index: head/sys/dev/usb/controller/xhci_pci.c =================================================================== --- head/sys/dev/usb/controller/xhci_pci.c +++ head/sys/dev/usb/controller/xhci_pci.c @@ -148,6 +148,8 @@ static int xhci_use_msi = 1; TUNABLE_INT("hw.usb.xhci.msi", &xhci_use_msi); +static int xhci_use_msix = 1; +TUNABLE_INT("hw.usb.xhci.msix", &xhci_use_msix); static void xhci_interrupt_poll(void *_sc) @@ -188,7 +190,7 @@ xhci_pci_attach(device_t self) { struct xhci_softc *sc = device_get_softc(self); - int count, err, rid; + int count, err, msix_table, rid; uint8_t usemsi = 1; uint8_t usedma32 = 0; @@ -240,7 +242,27 @@ usb_callout_init_mtx(&sc->sc_callout, &sc->sc_bus.bus_mtx, 0); rid = 0; - if (xhci_use_msi && usemsi) { + if (xhci_use_msix && (msix_table = pci_msix_table_bar(self)) >= 0) { + sc->sc_msix_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, + &msix_table, RF_ACTIVE); + if (sc->sc_msix_res == NULL) { + /* May not be enabled */ + device_printf(self, + "Unable to map MSI-X table \n"); + } else { + count = 1; + if (pci_alloc_msix(self, &count) == 0) { + if (bootverbose) + device_printf(self, "MSI-X enabled\n"); + rid = 1; + } else { + bus_release_resource(self, SYS_RES_MEMORY, + msix_table, sc->sc_msix_res); + sc->sc_msix_res = NULL; + } + } + } + if (rid == 0 && xhci_use_msi && usemsi) { count = 1; if (pci_alloc_msi(self, &count) == 0) { if (bootverbose) @@ -341,6 +363,11 @@ sc->sc_io_res); sc->sc_io_res = NULL; } + if (sc->sc_msix_res) { + bus_release_resource(self, SYS_RES_MEMORY, + rman_get_rid(sc->sc_msix_res), sc->sc_msix_res); + sc->sc_msix_res = NULL; + } xhci_uninit(sc);