libpayload: usb mass storage detect empty media
There is currently a hard-coded 30 sec delay in the mass storage driver while waiting for each device to become ready. However, mass storage card readers that are empty return an error code on the TEST UNIT READY command. A REQUEST SENSE command then needs to be issued and interrogate the data to determine if no media is present. If no media determination is found to be true the USB device is no longer considered a candidate to be a disk. This code does lead to the fact that the media card reader needs to be populated at enumeration time. I suspect this is not an issue as it appears the storage stack in libpayload can't handle removable media coming online later. Booted recovery and dev modes. Noted that removable mass storage devices with no media were ignored without any boot delay. Change-Id: Ida7a45614d97c6e6fbfc9bb099765aad4df550fd Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/57828 Reviewed-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: http://review.coreboot.org/4225 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
parent
2d9d39a704
commit
a967f414df
|
@ -123,6 +123,8 @@ enum {
|
||||||
|
|
||||||
static int
|
static int
|
||||||
request_sense (usbdev_t *dev);
|
request_sense (usbdev_t *dev);
|
||||||
|
static int
|
||||||
|
request_sense_no_media (usbdev_t *dev);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
reset_transport (usbdev_t *dev)
|
reset_transport (usbdev_t *dev)
|
||||||
|
@ -256,6 +258,11 @@ execute_command (usbdev_t *dev, cbw_direction dir, const u8 *cb, int cblen,
|
||||||
if (cb[0] == 0x03)
|
if (cb[0] == 0x03)
|
||||||
/* requesting sense failed, that's bad */
|
/* requesting sense failed, that's bad */
|
||||||
return MSC_COMMAND_FAIL;
|
return MSC_COMMAND_FAIL;
|
||||||
|
else if (cb[0] == 0)
|
||||||
|
/* If command was TEST UNIT READY determine if the
|
||||||
|
* device is of removable type indicating no media
|
||||||
|
* found. */
|
||||||
|
return request_sense_no_media (dev);
|
||||||
/* error "check condition" or reserved error */
|
/* error "check condition" or reserved error */
|
||||||
ret = request_sense (dev);
|
ret = request_sense (dev);
|
||||||
/* return fail or the status of request_sense if it's worse */
|
/* return fail or the status of request_sense if it's worse */
|
||||||
|
@ -350,6 +357,34 @@ request_sense (usbdev_t *dev)
|
||||||
sizeof (cb), buf, 19, 1);
|
sizeof (cb), buf, 19, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int request_sense_no_media(usbdev_t *dev)
|
||||||
|
{
|
||||||
|
u8 buf[19];
|
||||||
|
int ret;
|
||||||
|
cmdblock6_t cb;
|
||||||
|
memset (&cb, 0, sizeof (cb));
|
||||||
|
cb.command = 0x3;
|
||||||
|
|
||||||
|
ret = execute_command (dev, cbw_direction_data_in, (u8 *) &cb,
|
||||||
|
sizeof (cb), buf, 19, 1);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* Check if sense key is set to NOT READY. */
|
||||||
|
if ((buf[2] & 0xf) != 2)
|
||||||
|
return MSC_COMMAND_FAIL;
|
||||||
|
|
||||||
|
/* Check if additional sense code is 0x3a. */
|
||||||
|
if (buf[12] != 0x3a)
|
||||||
|
return MSC_COMMAND_FAIL;
|
||||||
|
|
||||||
|
/* No media is present. Return MSC_COMMAND_DETACHED so as not to use
|
||||||
|
* this device any longer. */
|
||||||
|
usb_debug("Empty media found.\n");
|
||||||
|
return MSC_COMMAND_DETACHED;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
test_unit_ready (usbdev_t *dev)
|
test_unit_ready (usbdev_t *dev)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue