diff options
author | hselasky <hselasky@FreeBSD.org> | 2012-01-12 21:21:20 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2012-01-12 21:21:20 +0000 |
commit | 6c85604246f379ee4bb4d0701a1f85b5b1cdf10f (patch) | |
tree | 38f3d90c8fddf434631d370481d287f6ba079ccb /sys/dev/usb/controller | |
parent | 0238379b18c22577e791b322bb2f68d9447a5b12 (diff) | |
download | FreeBSD-src-6c85604246f379ee4bb4d0701a1f85b5b1cdf10f.zip FreeBSD-src-6c85604246f379ee4bb4d0701a1f85b5b1cdf10f.tar.gz |
- Try to fix support for USB 3.0 HUBs.
- Try to fix support for USB 3.0 suspend and resume.
MFC after: 1 week
Diffstat (limited to 'sys/dev/usb/controller')
-rw-r--r-- | sys/dev/usb/controller/xhci.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c index c20e3bd..7e2f05b 100644 --- a/sys/dev/usb/controller/xhci.c +++ b/sys/dev/usb/controller/xhci.c @@ -2211,9 +2211,10 @@ xhci_configure_device(struct usb_device *udev) struct usb_device *hubdev; uint32_t temp; uint32_t route; + uint32_t rh_port; uint8_t is_hub; uint8_t index; - uint8_t rh_port; + uint8_t depth; index = udev->controller_slot_id; @@ -2235,6 +2236,8 @@ xhci_configure_device(struct usb_device *udev) if (hubdev->parent_hub == NULL) break; + depth = hubdev->parent_hub->depth; + /* * NOTE: HS/FS/LS devices and the SS root HUB can have * more than 15 ports @@ -2242,17 +2245,18 @@ xhci_configure_device(struct usb_device *udev) rh_port = hubdev->port_no; - if (hubdev->parent_hub->parent_hub == NULL) + if (depth == 0) break; - route *= 16; - if (rh_port > 15) - route |= 15; - else - route |= rh_port; + rh_port = 15; + + if (depth < 6) + route |= rh_port << (4 * (depth - 1)); } + DPRINTF("Route=0x%08x\n", route); + temp = XHCI_SCTX_0_ROUTE_SET(route); switch (sc->sc_hw.devs[index].state) { @@ -3063,6 +3067,7 @@ xhci_roothub_exec(struct usb_device *udev, case UHF_C_PORT_CONFIG_ERROR: XWRITE4(sc, oper, port, v | XHCI_PS_CEC); break; + case UHF_C_PORT_SUSPEND: case UHF_C_PORT_LINK_STATE: XWRITE4(sc, oper, port, v | XHCI_PS_PLC); break; @@ -3190,7 +3195,7 @@ xhci_roothub_exec(struct usb_device *udev, if (v & XHCI_PS_PR) i |= UPS_RESET; if (v & XHCI_PS_PP) - i |= UPS_PORT_POWER; + i |= UPS_PORT_POWER_SS; USETW(sc->sc_hub_desc.ps.wPortStatus, i); i = 0; |