summaryrefslogtreecommitdiff
path: root/drivers/usb/core/hub.h
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2014-05-29 12:58:46 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-07-09 15:43:12 -0700
commit3cd12f91514da6893954de479dc60b16d3b381f4 (patch)
tree3209b05551050ac2e1da7f79ca96bc49298f9ac9 /drivers/usb/core/hub.h
parent51df62ff74b371866c1006dee887a8e42838c1f2 (diff)
usb: force warm reset to break link re-connect livelock
Resuming a powered down port sometimes results in the port state being stuck in the training sequence. hub 3-0:1.0: debounce: port 1: total 2000ms stable 0ms status 0x2e0 port1: can't get reconnection after setting port power on, status -110 hub 3-0:1.0: port 1 status 0000.02e0 after resume, -19 usb 3-1: can't resume, status -19 hub 3-0:1.0: logical disconnect on port 1 In the case above we wait for the port re-connect timeout of 2 seconds and observe that the port status is USB_SS_PORT_LS_POLLING (although it is likely toggling between this state and USB_SS_PORT_LS_RX_DETECT). This is indicative of a case where the device is failing to progress the link training state machine. It is resolved by issuing a warm reset to get the hub and device link state machines back in sync. hub 3-0:1.0: debounce: port 1: total 2000ms stable 0ms status 0x2e0 usb usb3: port1 usb_port_runtime_resume requires warm reset hub 3-0:1.0: port 1 not warm reset yet, waiting 50ms usb 3-1: reset SuperSpeed USB device number 2 using xhci_hcd After a reconnect timeout when we expect the device to be present, force a warm reset of the device. Note that we can not simply look at the link status to determine if a warm reset is required as any of the training states USB_SS_PORT_LS_POLLING, USB_SS_PORT_LS_RX_DETECT, or USB_SS_PORT_LS_COMP_MOD are valid states that do not indicate the need for warm reset by themselves. Cc: Alan Stern <stern@rowland.harvard.edu> Cc: Kukjin Kim <kgene.kim@samsung.com> Cc: Vincent Palatin <vpalatin@chromium.org> Cc: Lan Tianyu <tianyu.lan@intel.com> Cc: Ksenia Ragiadakou <burzalodowa@gmail.com> Cc: Vivek Gautam <gautam.vivek@samsung.com> Cc: Douglas Anderson <dianders@chromium.org> Cc: Felipe Balbi <balbi@ti.com> Cc: Sunil Joshi <joshi@samsung.com> Cc: Hans de Goede <hdegoede@redhat.com> Acked-by: Julius Werner <jwerner@chromium.org> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/core/hub.h')
-rw-r--r--drivers/usb/core/hub.h2
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index 326308e53961..c77d8778af4b 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -52,6 +52,8 @@ struct usb_hub {
unsigned long power_bits[1]; /* ports that are powered */
unsigned long child_usage_bits[1]; /* ports powered on for
children */
+ unsigned long warm_reset_bits[1]; /* ports requesting warm
+ reset recovery */
#if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */
#error event_bits[] is too short!
#endif