diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-11-29 16:30:49 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-11-29 16:30:49 +0000 |
commit | c482ad911426aa4d31e4e1d61d6dcd48f2a99046 (patch) | |
tree | 1967243186e440ad1fa9af0c90eefa3c78913fb5 /sys | |
parent | 7192f54e449c60f46513e46918507c7d47dfb23b (diff) |
Unconnected xhci(4) super speed ports may come up with the XHCI_PS_WRC,
indicating a warm reset has happened. Communicate this as UPS_C_BH_PORT_RESET
to the upper layers and make uhub(4) clear this bit such that we receive
further connection status change notifications. Make sure we only do this
for super speed (USB 3.0) hubs as high speed (USB 2.0) hubs use the same bit
for UPS_C_PORT_L1.
Make hotplugging USB 3.0 devices work on my MacBookPro12,1.
ok mpi@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/usb/uhub.c | 8 | ||||
-rw-r--r-- | sys/dev/usb/xhci.c | 9 |
2 files changed, 15 insertions, 2 deletions
diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c index 8dac9465acd..b73a15dfb1a 100644 --- a/sys/dev/usb/uhub.c +++ b/sys/dev/usb/uhub.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uhub.c,v 1.87 2015/11/29 16:16:35 kettenis Exp $ */ +/* $OpenBSD: uhub.c,v 1.88 2015/11/29 16:30:48 kettenis Exp $ */ /* $NetBSD: uhub.c,v 1.64 2003/02/08 03:32:51 ichiro Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhub.c,v 1.18 1999/11/17 22:33:43 n_hibma Exp $ */ @@ -425,6 +425,12 @@ uhub_explore(struct usbd_device *dev) change |= UPS_C_CONNECT_STATUS; } + if (change & UPS_C_BH_PORT_RESET && + sc->sc_hub->speed == USB_SPEED_SUPER) { + usbd_clear_port_feature(sc->sc_hub, port, + UHF_C_BH_PORT_RESET); + } + if (change & UPS_C_CONNECT_STATUS) { if (uhub_port_connect(sc, port, status, change)) continue; diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index a48d83140ae..e4e54bc20f7 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xhci.c,v 1.64 2015/11/02 14:53:10 mpi Exp $ */ +/* $OpenBSD: xhci.c,v 1.65 2015/11/29 16:30:48 kettenis Exp $ */ /* * Copyright (c) 2014-2015 Martin Pieuchot @@ -2194,6 +2194,9 @@ xhci_root_ctrl_start(struct usbd_xfer *xfer) case UHF_C_PORT_RESET: XOWRITE4(sc, port, v | XHCI_PS_PRC); break; + case UHF_C_BH_PORT_RESET: + XOWRITE4(sc, port, v | XHCI_PS_WRC); + break; default: err = USBD_IOERROR; goto ret; @@ -2277,6 +2280,7 @@ xhci_root_ctrl_start(struct usbd_xfer *xfer) if (v & XHCI_PS_PEC) i |= UPS_C_PORT_ENABLED; if (v & XHCI_PS_OCC) i |= UPS_C_OVERCURRENT_INDICATOR; if (v & XHCI_PS_PRC) i |= UPS_C_PORT_RESET; + if (v & XHCI_PS_WRC) i |= UPS_C_BH_PORT_RESET; if (v & XHCI_PS_PLC) i |= UPS_C_PORT_LINK_STATE; if (v & XHCI_PS_CEC) i |= UPS_C_PORT_CONFIG_ERROR; USETW(ps.wPortChange, i); @@ -2333,6 +2337,9 @@ xhci_root_ctrl_start(struct usbd_xfer *xfer) case UHF_C_PORT_RESET: XOWRITE4(sc, port, v | XHCI_PS_PRC); break; + case UHF_C_BH_PORT_RESET: + XOWRITE4(sc, port, v | XHCI_PS_WRC); + break; default: err = USBD_IOERROR; goto ret; |