linux-uconsole/drivers/usb/core
Guenter Roeck 0a007f74b8 usb: hub: Wait for connection to be reestablished after port reset
commit 22547c4cc4 upstream.

On a system with a defective USB device connected to an USB hub,
an endless sequence of port connect events was observed. The sequence
of events as observed is as follows:

- Port reports connected event (port status=USB_PORT_STAT_CONNECTION).
- Event handler debounces port and resets it by calling hub_port_reset().
- hub_port_reset() calls hub_port_wait_reset() to wait for the reset
  to complete.
- The reset completes, but USB_PORT_STAT_CONNECTION is not immediately
  set in the port status register.
- hub_port_wait_reset() returns -ENOTCONN.
- Port initialization sequence is aborted.
- A few milliseconds later, the port again reports a connected event,
  and the sequence repeats.

This continues either forever or, randomly, stops if the connection
is already re-established when the port status is read. It results in
a high rate of udev events. This in turn destabilizes userspace since
the above sequence holds the device mutex pretty much continuously
and prevents userspace from actually reading the device status.

To prevent the problem from happening, let's wait for the connection
to be re-established after a port reset. If the device was actually
disconnected, the code will still return an error, but it will do so
only after the long reset timeout.

Cc: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-04-18 07:14:37 +02:00
..
buffer.c Usb: core: buffer: fixed the checkpatch warning 2015-05-10 15:44:10 +02:00
config.c usb-core: Add LINEAR_FRAME_INTR_BINTERVAL USB quirk 2017-03-30 09:35:16 +02:00
devices.c usb: define USB_SPEED_SUPER_PLUS speed for SuperSpeedPlus USB3.1 devices 2016-09-07 08:32:39 +02:00
devio.c USB: avoid left shift by -1 2016-09-07 08:32:44 +02:00
driver.c USB: leave LPM alone if possible when binding/unbinding interface drivers 2016-06-01 12:15:51 -07:00
endpoint.c usb: endpoint: convert spaces to tabs 2015-08-14 16:50:36 -07:00
file.c
generic.c staging: usbip: convert usbip-host driver to usb_device_driver 2014-02-07 10:54:30 -08:00
hcd-pci.c usb: define USB_SPEED_SUPER_PLUS speed for SuperSpeedPlus USB3.1 devices 2016-09-07 08:32:39 +02:00
hcd.c USB: fix linked-list corruption in rh_call_control() 2017-04-08 09:53:31 +02:00
hub.c usb: hub: Wait for connection to be reestablished after port reset 2017-04-18 07:14:37 +02:00
hub.h usb: hub: convert khubd into workqueue 2014-09-23 22:33:19 -07:00
Kconfig usb: kconfig: fix warning of select USB_OTG 2015-11-19 16:31:42 -08:00
Makefile USB: core: remove CONFIG_USB_DEBUG usage 2013-12-21 16:01:00 -08:00
message.c usb: message: remove redundant declaration 2015-10-04 10:45:11 +01:00
notify.c
otg_whitelist.h usb: otg_whitelist: remove whitespace 2015-08-14 16:50:36 -07:00
port.c usb: Quiet down false peer failure messages 2015-12-04 08:19:55 -08:00
quirks.c usb-core: Add LINEAR_FRAME_INTR_BINTERVAL USB quirk 2017-03-30 09:35:16 +02:00
sysfs.c usb: core: lpm: fix usb3_hardware_lpm sysfs node 2016-01-31 11:28:58 -08:00
urb.c usb: define USB_SPEED_SUPER_PLUS speed for SuperSpeedPlus USB3.1 devices 2016-09-07 08:32:39 +02:00
usb-acpi.c usb: find internal hub tier mismatch via acpi 2014-05-27 16:38:52 -07:00
usb.c usb: interface authorization: Use a flag for the default device authorization 2015-09-22 12:08:40 -07:00
usb.h usb: define USB_SPEED_SUPER_PLUS speed for SuperSpeedPlus USB3.1 devices 2016-09-07 08:32:39 +02:00