From f80ccb40c7d311f812a7d9fb8547e2786fc4b147 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Thu, 9 Oct 2014 06:24:06 +0000 Subject: [PATCH] Refine support for disabling USB enumeration to allow device detach and suspend and resume of existing devices. MFC after: 2 weeks --- sys/dev/usb/controller/usb_controller.c | 11 +-------- sys/dev/usb/usb_hub.c | 31 +++++++++++++++---------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c index 1d202dd4634..dc10591513a 100644 --- a/sys/dev/usb/controller/usb_controller.c +++ b/sys/dev/usb/controller/usb_controller.c @@ -102,14 +102,6 @@ static int usb_no_shutdown_wait = 0; SYSCTL_INT(_hw_usb, OID_AUTO, no_shutdown_wait, CTLFLAG_RWTUN, &usb_no_shutdown_wait, 0, "No USB device waiting at system shutdown."); -#if USB_HAVE_DISABLE_ENUM -static int usb_disable_enumeration = 0; -SYSCTL_INT(_hw_usb, OID_AUTO, disable_enumeration, CTLFLAG_RWTUN, - &usb_disable_enumeration, 0, "Set to disable all USB device enumeration."); -#else -#define usb_disable_enumeration 0 -#endif - static devclass_t usb_devclass; static device_method_t usb_methods[] = { @@ -379,8 +371,7 @@ usb_bus_explore(struct usb_proc_msg *pm) USB_BUS_LOCK(bus); } - if (usb_disable_enumeration == 0 && - udev != NULL && udev->hub != NULL) { + if (udev != NULL && udev->hub != NULL) { if (bus->do_probe) { bus->do_probe = 0; diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index 3385d9acff4..e9280bc2426 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -97,6 +97,12 @@ SYSCTL_INT(_hw_usb, OID_AUTO, power_timeout, CTLFLAG_RW, &usb_power_timeout, 0, "USB power timeout"); #endif +#if USB_HAVE_DISABLE_ENUM +static int usb_disable_enumeration = 0; +SYSCTL_INT(_hw_usb, OID_AUTO, disable_enumeration, CTLFLAG_RWTUN, + &usb_disable_enumeration, 0, "Set to disable all USB device enumeration."); +#endif + struct uhub_current_state { uint16_t port_change; uint16_t port_status; @@ -621,9 +627,9 @@ uhub_reattach_port(struct uhub_softc *sc, uint8_t portno) err = usbd_req_clear_port_feature(udev, NULL, portno, UHF_C_PORT_CONNECTION); - if (err) { + if (err) goto error; - } + /* check if there is a child */ if (child != NULL) { @@ -636,14 +642,22 @@ uhub_reattach_port(struct uhub_softc *sc, uint8_t portno) /* get fresh status */ err = uhub_read_port_status(sc, portno); - if (err) { + if (err) + goto error; + +#if USB_HAVE_DISABLE_ENUM + /* check if we should skip enumeration from this USB HUB */ + if (usb_disable_enumeration != 0 || + sc->sc_disable_enumeration != 0) { + DPRINTF("Enumeration is disabled!\n"); goto error; } +#endif /* check if nothing is connected to the port */ - if (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS)) { + if (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS)) goto error; - } + /* check if there is no power on the port and print a warning */ switch (udev->speed) { @@ -996,13 +1010,6 @@ uhub_explore(struct usb_device *udev) DPRINTFN(11, "udev=%p addr=%d\n", udev, udev->address); -#if USB_HAVE_DISABLE_ENUM - /* check if we should skip enumeration from this USB HUB */ - if (sc->sc_disable_enumeration != 0) { - DPRINTF("Enumeration is disabled!\n"); - return (0); - } -#endif /* ignore devices that are too deep */ if (uhub_is_too_deep(udev)) return (USB_ERR_TOO_DEEP); -- 2.45.2