summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2014-10-06 11:05:56 +0000
committerhselasky <hselasky@FreeBSD.org>2014-10-06 11:05:56 +0000
commitd2c20c5b927d4e073bb137a63b33f6f18b8835d3 (patch)
treed82edfca1ce9118999fd2f6a8610793ddcadeb23 /sys/dev
parent33b1f8da20360987fca6af2adbd0a46872f0b819 (diff)
downloadFreeBSD-src-d2c20c5b927d4e073bb137a63b33f6f18b8835d3.zip
FreeBSD-src-d2c20c5b927d4e073bb137a63b33f6f18b8835d3.tar.gz
MFC r272349, r272422 and r272479:
- Fix XHCI driver for devices which have more than 15 physical root HUB ports. The current bitmap array was too small to hold more than 16 bits and would at some point toggle the context size, which then would trigger an enumeration fault and cause a fallback to the EHCI companion controller, if any. - Make sure we always set the maximum number of valid contexts. - Set default cycle state in case of early interrupts. Approved by: re, marius
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/controller/xhci.c21
-rw-r--r--sys/dev/usb/controller/xhci.h3
2 files changed, 16 insertions, 8 deletions
diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c
index 6a4d894..82c52fd 100644
--- a/sys/dev/usb/controller/xhci.c
+++ b/sys/dev/usb/controller/xhci.c
@@ -618,6 +618,10 @@ xhci_init(struct xhci_softc *sc, device_t self)
sc->sc_bus.devices = sc->sc_devices;
sc->sc_bus.devices_max = XHCI_MAX_DEVICES;
+ /* set default cycle state in case of early interrupts */
+ sc->sc_event_ccs = 1;
+ sc->sc_command_ccs = 1;
+
/* setup command queue mutex and condition varible */
cv_init(&sc->sc_cmd_cv, "CMDQ");
sx_init(&sc->sc_cmd_sx, "CMDQ lock");
@@ -2271,14 +2275,17 @@ xhci_configure_mask(struct usb_device *udev, uint32_t mask, uint8_t drop)
/* adjust */
x--;
- /* figure out maximum */
- if (x > sc->sc_hw.devs[index].context_num) {
+ /* figure out the maximum number of contexts */
+ if (x > sc->sc_hw.devs[index].context_num)
sc->sc_hw.devs[index].context_num = x;
- temp = xhci_ctx_get_le32(sc, &pinp->ctx_slot.dwSctx0);
- temp &= ~XHCI_SCTX_0_CTX_NUM_SET(31);
- temp |= XHCI_SCTX_0_CTX_NUM_SET(x + 1);
- xhci_ctx_set_le32(sc, &pinp->ctx_slot.dwSctx0, temp);
- }
+ else
+ x = sc->sc_hw.devs[index].context_num;
+
+ /* update number of contexts */
+ temp = xhci_ctx_get_le32(sc, &pinp->ctx_slot.dwSctx0);
+ temp &= ~XHCI_SCTX_0_CTX_NUM_SET(31);
+ temp |= XHCI_SCTX_0_CTX_NUM_SET(x + 1);
+ xhci_ctx_set_le32(sc, &pinp->ctx_slot.dwSctx0, temp);
}
return (0);
}
diff --git a/sys/dev/usb/controller/xhci.h b/sys/dev/usb/controller/xhci.h
index 408b429..7352e9c 100644
--- a/sys/dev/usb/controller/xhci.h
+++ b/sys/dev/usb/controller/xhci.h
@@ -493,7 +493,8 @@ struct xhci_softc {
uint8_t sc_noscratch;
/* root HUB device configuration */
uint8_t sc_conf;
- uint8_t sc_hub_idata[2];
+ /* root HUB port event bitmap, max 256 ports */
+ uint8_t sc_hub_idata[32];
/* size of context */
uint8_t sc_ctx_is_64_byte;
OpenPOWER on IntegriCloud