summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2015-11-29 16:30:49 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2015-11-29 16:30:49 +0000
commitc482ad911426aa4d31e4e1d61d6dcd48f2a99046 (patch)
tree1967243186e440ad1fa9af0c90eefa3c78913fb5 /sys
parent7192f54e449c60f46513e46918507c7d47dfb23b (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.c8
-rw-r--r--sys/dev/usb/xhci.c9
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;