summaryrefslogtreecommitdiff
path: root/payloads/libpayload/drivers/usb/usb.c
diff options
context:
space:
mode:
authorNico Huber <nico.huber@secunet.com>2012-06-01 09:50:11 +0200
committerNico Huber <nico.huber@secunet.com>2012-06-21 11:54:23 +0200
commit79e1f2fa010173a81b891044085bf6a0a3a672fb (patch)
treeb8cf4e92909dae9c7937694a7986c3e72f760d32 /payloads/libpayload/drivers/usb/usb.c
parent3ca35cae354305003bcc5d14549a247247726e61 (diff)
downloadcoreboot-79e1f2fa010173a81b891044085bf6a0a3a672fb.tar.xz
libpayload: Detach unresponsive usb mass storage devices
This enables logical detachment of unresponsive usb devices (i.e. devices not responding to control transfers) in the usb mass storage driver. Without the detection of unresponsive devices we wait way too long for the device to become ready. Change-Id: I8b8cf327f49dde25afaca4d3066f16ea86b99d3d Signed-off-by: Nico Huber <nico.huber@secunet.com> Reviewed-on: http://review.coreboot.org/1121 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'payloads/libpayload/drivers/usb/usb.c')
-rw-r--r--payloads/libpayload/drivers/usb/usb.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/payloads/libpayload/drivers/usb/usb.c b/payloads/libpayload/drivers/usb/usb.c
index 42c73f345e..99b65e03f2 100644
--- a/payloads/libpayload/drivers/usb/usb.c
+++ b/payloads/libpayload/drivers/usb/usb.c
@@ -206,7 +206,7 @@ set_configuration (usbdev_t *dev)
dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0);
}
-void
+int
clear_feature (usbdev_t *dev, int endp, int feature, int rtype)
{
dev_req_t dr;
@@ -217,7 +217,7 @@ clear_feature (usbdev_t *dev, int endp, int feature, int rtype)
dr.wValue = feature;
dr.wIndex = endp;
dr.wLength = 0;
- dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0);
+ return dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0);
}
int
@@ -228,9 +228,9 @@ clear_stall (endpoint_t *ep)
int rtype = gen_bmRequestType (host_to_device, standard_type,
endp ? endp_recp : dev_recp);
- clear_feature (dev, endp, ENDPOINT_HALT, rtype);
+ int ret = clear_feature (dev, endp, ENDPOINT_HALT, rtype);
ep->toggle = 0;
- return 0;
+ return ret;
}
/* returns free address or -1 */
@@ -459,12 +459,21 @@ set_address (hci_t *controller, int speed, int hubport, int hubaddr)
return adr;
}
+/*
+ * Should be called by the hub drivers whenever a physical detach occurs
+ * and can be called by usb class drivers if they are unsatisfied with a
+ * malfunctioning device.
+ */
void
usb_detach_device(hci_t *controller, int devno)
{
- controller->devices[devno]->destroy (controller->devices[devno]);
- free(controller->devices[devno]);
- controller->devices[devno] = 0;
+ /* check if device exists, as we may have
+ been called yet by the usb class driver */
+ if (controller->devices[devno]) {
+ controller->devices[devno]->destroy (controller->devices[devno]);
+ free(controller->devices[devno]);
+ controller->devices[devno] = NULL;
+ }
}
int