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>
This commit is contained in:
Nico Huber
2012-06-01 09:50:11 +02:00
parent 3ca35cae35
commit 79e1f2fa01
3 changed files with 116 additions and 60 deletions

View File

@@ -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