diff options
author | hselasky <hselasky@FreeBSD.org> | 2011-10-26 17:43:27 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2011-10-26 17:43:27 +0000 |
commit | d16be1d43585dd21b7cefb1b2d1c7d65968ee7cb (patch) | |
tree | 61cae9efa2e722177b98d8b8f0321329ef7db193 /sys/dev/usb/controller/xhci.c | |
parent | 6ae1a53eda68ab65a69718a023f2b6cd2b3dce28 (diff) | |
download | FreeBSD-src-d16be1d43585dd21b7cefb1b2d1c7d65968ee7cb.zip FreeBSD-src-d16be1d43585dd21b7cefb1b2d1c7d65968ee7cb.tar.gz |
Fix suspend and resume of FULL and HIGH speed USB devices
in the generic XHCI driver. There appears to be some minor
logic missing for this feature to work.
MFC after: 3 days
Diffstat (limited to 'sys/dev/usb/controller/xhci.c')
-rw-r--r-- | sys/dev/usb/controller/xhci.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c index f6c8c0e..0df4c4d 100644 --- a/sys/dev/usb/controller/xhci.c +++ b/sys/dev/usb/controller/xhci.c @@ -3048,7 +3048,9 @@ xhci_roothub_exec(struct usb_device *udev, } port = XHCI_PORTSC(index); - v = XREAD4(sc, oper, port) & ~XHCI_PS_CLEAR; + v = XREAD4(sc, oper, port); + i = XHCI_PS_PLS_GET(v); + v &= ~XHCI_PS_CLEAR; switch (value) { case UHF_C_BH_PORT_RESET: @@ -3082,6 +3084,17 @@ xhci_roothub_exec(struct usb_device *udev, XWRITE4(sc, oper, port, v & ~XHCI_PS_PIC_SET(3)); break; case UHF_PORT_SUSPEND: + + /* U3 -> U15 */ + if (i == 3) { + XWRITE4(sc, oper, port, v | + XHCI_PS_PLS_SET(0xF) | XHCI_PS_LWS); + } + + /* wait 20ms for resume sequence to complete */ + usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 50); + + /* U0 */ XWRITE4(sc, oper, port, v | XHCI_PS_PLS_SET(0) | XHCI_PS_LWS); break; |