From 2d0bc3aa8861bc948883418cb9302dd920535b18 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 7 Apr 2004 02:51:28 -0700 Subject: [PATCH] [PATCH] USB: retry some descriptor fetches This helps Linux handle certain enumeration problems better, by retrying most stalled descriptor fetches; on some devices, those indicate temporary problems. This match makes at least one such (old) device enumerate reliably. --- drivers/usb/core/message.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index cdf9a29d3f1fe..fad1c2243ca68 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -572,13 +572,16 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char memset(buf,0,size); // Make sure we parse really received data while (i--) { - /* retries if the returned length was 0; flakey device */ + /* retry on length 0 or stall; some devices are flakey */ if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, (type << 8) + index, 0, buf, size, HZ * USB_CTRL_GET_TIMEOUT)) > 0 - || result == -EPIPE) + || result != -EPIPE) break; + + dev_dbg (&dev->dev, "RETRY descriptor, result %d\n", result); + result = -ENOMSG; } return result; } @@ -1244,7 +1247,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) /* get langid for strings if it's not yet known */ if (!dev->have_langid) { - err = usb_get_string(dev, 0, 0, tbuf, 4); + err = usb_get_descriptor(dev, USB_DT_STRING, 0, tbuf, 4); if (err < 0) { dev_err (&dev->dev, "string descriptor 0 read error: %d\n", @@ -1268,11 +1271,19 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) */ err = usb_get_string(dev, dev->string_langid, index, tbuf, 2); + if (err == -EPIPE) { + dev_dbg(&dev->dev, "RETRY string %d read/%d\n", index, 2); + err = usb_get_string(dev, dev->string_langid, index, tbuf, 2); + } if(err<2) goto errout; len=tbuf[0]; err = usb_get_string(dev, dev->string_langid, index, tbuf, len); + if (err == -EPIPE) { + dev_dbg(&dev->dev, "RETRY string %d read/%d\n", index, len); + err = usb_get_string(dev, dev->string_langid, index, tbuf, len); + } if (err < 0) goto errout; -- 2.53.0