summaryrefslogtreecommitdiff
path: root/drivers/usb/core/hub.c
diff options
context:
space:
mode:
authorLibor Pechacek <lpechacek@suse.cz>2011-05-20 14:53:25 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-06 16:02:32 -0700
commit3824c1ddaf744be44b170a335332b9d6afe79254 (patch)
tree8e1bef3d7d37276a951d13f7129c823ccdfad09f /drivers/usb/core/hub.c
parent9303961f5b8c8da0b65b897fb6521d2a123ec8a8 (diff)
downloadlinux-3.10-3824c1ddaf744be44b170a335332b9d6afe79254.tar.gz
linux-3.10-3824c1ddaf744be44b170a335332b9d6afe79254.tar.bz2
linux-3.10-3824c1ddaf744be44b170a335332b9d6afe79254.zip
USB: core: Tolerate protocol stall during hub and port status read
Protocol stall should not be fatal while reading port or hub status as it is transient state. Currently hub EP0 STALL during port status read results in failed device enumeration. This has been observed with ST-Ericsson (formerly Philips) USB 2.0 Hub (04cc:1521) after connecting keyboard. Signed-off-by: Libor Pechacek <lpechacek@suse.cz> Acked-by: Alan Stern <stern@rowland.harvard.edu> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r--drivers/usb/core/hub.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 79a58c3a2e2..90ae1753dda 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -339,7 +339,8 @@ static int get_hub_status(struct usb_device *hdev,
{
int i, status = -ETIMEDOUT;
- for (i = 0; i < USB_STS_RETRIES && status == -ETIMEDOUT; i++) {
+ for (i = 0; i < USB_STS_RETRIES &&
+ (status == -ETIMEDOUT || status == -EPIPE); i++) {
status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,
data, sizeof(*data), USB_STS_TIMEOUT);
@@ -355,7 +356,8 @@ static int get_port_status(struct usb_device *hdev, int port1,
{
int i, status = -ETIMEDOUT;
- for (i = 0; i < USB_STS_RETRIES && status == -ETIMEDOUT; i++) {
+ for (i = 0; i < USB_STS_RETRIES &&
+ (status == -ETIMEDOUT || status == -EPIPE); i++) {
status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port1,
data, sizeof(*data), USB_STS_TIMEOUT);