summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandrew <andrew@FreeBSD.org>2015-12-24 09:40:29 +0000
committerandrew <andrew@FreeBSD.org>2015-12-24 09:40:29 +0000
commit5badcaaa0f325d543c4a79c30c6c91b0e88163fd (patch)
treef9f93225673952f7b60b7ebda1d05a47b89d0f7f
parentdea196cd0987efddd0de054962cd6f8b403787d4 (diff)
downloadFreeBSD-src-5badcaaa0f325d543c4a79c30c6c91b0e88163fd.zip
FreeBSD-src-5badcaaa0f325d543c4a79c30c6c91b0e88163fd.tar.gz
Ads support to the xhci pci attachment to use MSI-X interrupts when
available. As with MSI interrupts these can be disabled by setting hw.usb.xhci.msix to 0 in the loader. MSI-X interrupts are needed on some hardware, for example the Cavium ThunderX only supports them, and with this we don't fall back to polling. PR: 204378 Reviewed by: hselasky, jhb MFC after: 1 week (after r292669) Sponsored by: ABT Systems Ltd Differential Revision: https://reviews.freebsd.org/D4698
-rw-r--r--sys/dev/usb/controller/xhci.h1
-rw-r--r--sys/dev/usb/controller/xhci_pci.c31
2 files changed, 30 insertions, 2 deletions
diff --git a/sys/dev/usb/controller/xhci.h b/sys/dev/usb/controller/xhci.h
index ac21c0f..4857450 100644
--- a/sys/dev/usb/controller/xhci.h
+++ b/sys/dev/usb/controller/xhci.h
@@ -465,6 +465,7 @@ struct xhci_softc {
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;
diff --git a/sys/dev/usb/controller/xhci_pci.c b/sys/dev/usb/controller/xhci_pci.c
index e6f937f..0a8a95b 100644
--- a/sys/dev/usb/controller/xhci_pci.c
+++ b/sys/dev/usb/controller/xhci_pci.c
@@ -148,6 +148,8 @@ xhci_pci_probe(device_t self)
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 @@ static int
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 @@ xhci_pci_attach(device_t self)
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 @@ xhci_pci_detach(device_t self)
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);
OpenPOWER on IntegriCloud