Patrick Georgi has submitted this change and it was merged. ( https://review.coreboot.org/c/coreboot/+/34227 )
Change subject: libpayload: usbmsc: Factor out usb_msc_force_init() function ......................................................................
libpayload: usbmsc: Factor out usb_msc_force_init() function
We're planning to have a use case with a custom USB device that implements the USB mass storage protocol on its bulk endpoints, but does not have the normal MSC class/protocol interface descriptors and does not support class-specific control requests (Get Max LUN and Bulk-Only Reset). We'd like to identify/enumerate the device via usb_generic_create() in our payload but then reuse all the normal MSC driver code. In order to make that possible, this patch factors a new usb_msc_force_init() function out of usb_msc_init() which will initialize an MSC device without checking its descriptors. It also adds some "quirks" flags that allow devices registered this way to customize behavior of the MSC stack.
Change-Id: I50392128409cb2a879954f234149a5e3b060a229 Signed-off-by: Julius Werner jwerner@chromium.org Reviewed-on: https://review.coreboot.org/c/coreboot/+/34227 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Patrick Georgi pgeorgi@google.com --- M payloads/libpayload/drivers/usb/usbmsc.c M payloads/libpayload/include/usb/usbmsc.h 2 files changed, 35 insertions(+), 10 deletions(-)
Approvals: build bot (Jenkins): Verified Patrick Georgi: Looks good to me, approved
diff --git a/payloads/libpayload/drivers/usb/usbmsc.c b/payloads/libpayload/drivers/usb/usbmsc.c index d793e34..2412e99 100644 --- a/payloads/libpayload/drivers/usb/usbmsc.c +++ b/payloads/libpayload/drivers/usb/usbmsc.c @@ -157,6 +157,9 @@ dr.wIndex = 0; dr.wLength = 0;
+ if (MSC_INST (dev)->quirks & USB_MSC_QUIRK_NO_RESET) + return MSC_COMMAND_FAIL; + /* if any of these fails, detach device, as we are lost */ if (dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0) < 0 || clear_stall (MSC_INST (dev)->bulk_in) || @@ -185,7 +188,8 @@ dr.wValue = 0; dr.wIndex = 0; dr.wLength = 1; - if (dev->controller->control (dev, IN, sizeof (dr), &dr, + if (MSC_INST (dev)->quirks & USB_MSC_QUIRK_NO_LUNS || + dev->controller->control (dev, IN, sizeof (dr), &dr, sizeof (msc->num_luns), &msc->num_luns) < 0) msc->num_luns = 0; /* assume only 1 lun if req fails */ msc->num_luns++; /* Get Max LUN returns number of last LUN */ @@ -600,14 +604,6 @@ void usb_msc_init (usbdev_t *dev) { - int i; - - /* init .data before setting .destroy */ - dev->data = NULL; - - dev->destroy = usb_msc_destroy; - dev->poll = usb_msc_poll; - configuration_descriptor_t *cd = (configuration_descriptor_t *) dev->configuration; interface_descriptor_t *interface = @@ -634,6 +630,19 @@ return; }
+ usb_msc_force_init (dev, 0); +} + +void usb_msc_force_init (usbdev_t *dev, u32 quirks) +{ + int i; + + /* init .data before setting .destroy */ + dev->data = NULL; + + dev->destroy = usb_msc_destroy; + dev->poll = usb_msc_poll; + dev->data = malloc (sizeof (usbmsc_inst_t)); if (!dev->data) fatal("Not enough memory for USB MSC device.\n"); @@ -641,6 +650,7 @@ MSC_INST (dev)->bulk_in = 0; MSC_INST (dev)->bulk_out = 0; MSC_INST (dev)->usbdisk_created = 0; + MSC_INST (dev)->quirks = quirks;
for (i = 1; i <= dev->num_endp; i++) { if (dev->endpoints[i].endpoint == 0) diff --git a/payloads/libpayload/include/usb/usbmsc.h b/payloads/libpayload/include/usb/usbmsc.h index f4562a5..8786586 100644 --- a/payloads/libpayload/include/usb/usbmsc.h +++ b/payloads/libpayload/include/usb/usbmsc.h @@ -34,13 +34,24 @@ unsigned int numblocks; endpoint_t *bulk_in; endpoint_t *bulk_out; - u8 usbdisk_created; + u8 quirks : 7; + u8 usbdisk_created : 1; s8 ready; u8 lun; u8 num_luns; void *data; /* For use by consumers of libpayload. */ } usbmsc_inst_t;
+/* Possible values for quirks field. */ +enum { + /* Don't check for LUNs (force assumption that there's only one LUN). */ + USB_MSC_QUIRK_NO_LUNS = 1 << 0, + /* Never do a BULK_ONLY reset, just continue. This means that the device + cannot recover from phase errors and won't detach automatically for + unrecoverable errors. Do not use unless you have to. */ + USB_MSC_QUIRK_NO_RESET = 1 << 1, +}; + /* Possible values for ready field. */ enum { USB_MSC_DETACHED = -1, /* Disk detached or out to lunch. */ @@ -56,4 +67,8 @@ int readwrite_blocks_512 (usbdev_t *dev, int start, int n, cbw_direction dir, u8 *buf); int readwrite_blocks (usbdev_t *dev, int start, int n, cbw_direction dir, u8 *buf);
+/* Force a device to enumerate as MSC, without checking class/protocol types. + It must still have a bulk endpoint pair and respond to MSC commands. */ +void usb_msc_force_init (usbdev_t *dev, u32 quirks); + #endif