diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2015-09-24 14:45:10 -0700 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2015-10-27 15:00:16 +0100 |
commit | ff5d0b251830bdb4595972f2b2824ec780a09dca (patch) | |
tree | b76c2286363bdbc22fb1313028aeb63ece444921 /payloads/libpayload/drivers | |
parent | d1adafec0507109629fa4d1005e510a3234e04fb (diff) | |
download | coreboot-ff5d0b251830bdb4595972f2b2824ec780a09dca.tar.xz |
libpayload: usb: Retry get_descriptor() on failure
Certain Lexar USB disks may fail during the first calls to
get_descriptor(..., DT_CFG, ...) for unknown reasons. Therefore, make
several attempts before giving up.
BUG=chromium:466758
TEST=Manual on Samus. Go to recovery mode, verify that Lexar LJDS70 USB
stick is bootable.
BRANCH=None
Change-Id: I476ac22f9c4f844c60ebc6e53af8c144d70bb9d4
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 93a0570b343479dd22506ad4d7961f0ea4251f8c
Original-Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Original-Change-Id: Ie581c7c71c53816065c7f59202581888a79e445e
Original-Reviewed-on: https://chromium-review.googlesource.com/302403
Original-Commit-Ready: Shawn N <shawnn@chromium.org>
Original-Tested-by: Shawn N <shawnn@chromium.org>
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: http://review.coreboot.org/12133
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Diffstat (limited to 'payloads/libpayload/drivers')
-rw-r--r-- | payloads/libpayload/drivers/usb/usb.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/payloads/libpayload/drivers/usb/usb.c b/payloads/libpayload/drivers/usb/usb.c index ffbe005e84..e87e397061 100644 --- a/payloads/libpayload/drivers/usb/usb.c +++ b/payloads/libpayload/drivers/usb/usb.c @@ -149,19 +149,36 @@ get_status (usbdev_t *dev, int intf, int rtype, int len, void *data) return dev->controller->control (dev, IN, sizeof (dr), &dr, len, data); } +/* + * Certain Lexar / Micron USB 2.0 disks will fail the get_descriptor(DT_CFG) + * call due to timing issues. Work around this by making extra attempts on + * failure. + */ +#define GET_DESCRIPTOR_TRIES 3 + int -get_descriptor (usbdev_t *dev, int rtype, int descType, int descIdx, +get_descriptor(usbdev_t *dev, int rtype, int desc_type, int desc_idx, void *data, size_t len) { dev_req_t dr; - - dr.bmRequestType = rtype; - dr.bRequest = GET_DESCRIPTOR; - dr.wValue = descType << 8 | descIdx; - dr.wIndex = 0; - dr.wLength = len; - - return dev->controller->control (dev, IN, sizeof (dr), &dr, len, data); + int fail_tries = 0; + int ret = 0; + + while (fail_tries++ < GET_DESCRIPTOR_TRIES) { + dr.bmRequestType = rtype; + dr.bRequest = GET_DESCRIPTOR; + dr.wValue = desc_type << 8 | desc_idx; + dr.wIndex = 0; + dr.wLength = len; + + ret = dev->controller->control(dev, IN, + sizeof(dr), &dr, len, data); + if (ret) + udelay(10); + else + return 0; + } + return ret; } int |