[coreboot-gerrit] Patch set updated for coreboot: 7ae9403 libpayload: usb: Deep search for endpoint descriptors
Nico Huber (nico.h@gmx.de)
gerrit at coreboot.org
Tue Jul 22 17:47:33 CEST 2014
Nico Huber (nico.h at gmx.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3467
-gerrit
commit 7ae94034ef8e81b41151d8817d2a4cfc4119f995
Author: Anton Kochkov <anton.kochkov at gmail.com>
Date: Fri Jun 14 19:41:48 2013 +0400
libpayload: usb: Deep search for endpoint descriptors
This improves searching for endpoint descriptors
and skipping non-endpoint interface descriptors.
Change-Id: I063c096ab886f9753a9ee59f570fd81ce6f618cb
Signed-off-by: Anton Kochkov <anton.kochkov at gmail.com>
Signed-off-by: Nico Huber <nico.huber at secunet.com>
---
payloads/libpayload/drivers/usb/usb.c | 54 ++++++++++++++++++++++++++++-------
1 file changed, 43 insertions(+), 11 deletions(-)
diff --git a/payloads/libpayload/drivers/usb/usb.c b/payloads/libpayload/drivers/usb/usb.c
index 2d9cbe9..6a1d5bb 100644
--- a/payloads/libpayload/drivers/usb/usb.c
+++ b/payloads/libpayload/drivers/usb/usb.c
@@ -320,6 +320,30 @@ usb_decode_interval(const int speed, const endpoint_type type, const unsigned ch
#undef LOG2
}
+static const endpoint_descriptor_t *
+next_endpoint(const u8 *start, const u8 *const end)
+{
+ for (start += start[0];
+ start < end && start[1] != 0x04 && start[1] != 0x05;
+ start += start[0]);
+ if (start < end && start[1] == 0x05)
+ return (const endpoint_descriptor_t *)start;
+ else
+ return NULL;
+}
+
+static const interface_descriptor_t *
+next_interface(const u8 *start, const u8 *const end)
+{
+ for (start += start[0];
+ start < end && start[1] != 0x04;
+ start += start[0]);
+ if (start < end && start[1] == 0x04)
+ return (const interface_descriptor_t *)start;
+ else
+ return NULL;
+}
+
static int
set_address (hci_t *controller, int speed, int hubport, int hubaddr)
{
@@ -329,6 +353,7 @@ set_address (hci_t *controller, int speed, int hubport, int hubaddr)
return -1;
}
configuration_descriptor_t *cd;
+ const u8 *cd_end;
device_descriptor_t *dd;
usbdev_t *dev = controller->devices[adr];
@@ -356,12 +381,12 @@ set_address (hci_t *controller, int speed, int hubport, int hubaddr)
dev->configuration = get_descriptor (dev, gen_bmRequestType
(device_to_host, standard_type, dev_recp), 2, 0, 0);
cd = (configuration_descriptor_t *) dev->configuration;
+ cd_end = dev->configuration + cd->wTotalLength;
interface_descriptor_t *interface =
(interface_descriptor_t *) (((char *) cd) + cd->bLength);
{
int i;
int num = cd->bNumInterfaces;
- interface_descriptor_t *current = interface;
usb_debug ("device has %x interfaces\n", num);
if (num > 1) {
int interfaces = usb_interface_check(dd->idVendor, dd->idProduct);
@@ -382,17 +407,18 @@ set_address (hci_t *controller, int speed, int hubport, int hubaddr)
num = (num > 1) ? 1 : num;
}
}
+ const interface_descriptor_t *current =
+ (const interface_descriptor_t *)cd;
for (i = 0; i < num; i++) {
+ current = next_interface((const u8 *)current, cd_end);
+ if (!current) {
+ usb_detach_device(controller, adr);
+ return -1;
+ }
+
int j;
usb_debug (" #%x has %x endpoints, interface %x:%x, protocol %x\n",
current->bInterfaceNumber, current->bNumEndpoints, current->bInterfaceClass, current->bInterfaceSubClass, current->bInterfaceProtocol);
- endpoint_descriptor_t *endp =
- (endpoint_descriptor_t *) (((char *) current)
- + current->bLength);
- /* Skip any non-endpoint descriptor */
- if (endp->bDescriptorType != 0x05)
- endp = (endpoint_descriptor_t *)(((char *)endp) + ((char *)endp)[0]);
-
memset (dev->endpoints, 0, sizeof (dev->endpoints));
dev->num_endp = 1; // 0 always exists
dev->endpoints[0].dev = dev;
@@ -400,7 +426,15 @@ set_address (hci_t *controller, int speed, int hubport, int hubaddr)
dev->endpoints[0].direction = SETUP;
dev->endpoints[0].type = CONTROL;
dev->endpoints[0].interval = 0;
+
+ const endpoint_descriptor_t *endp =
+ (const endpoint_descriptor_t *)current;
for (j = 1; j <= current->bNumEndpoints; j++) {
+ endp = next_endpoint((const u8 *)endp, cd_end);
+ if (!endp) {
+ usb_detach_device(controller, adr);
+ return -1;
+ }
#ifdef USB_DEBUG
static const char *transfertypes[4] = {
"control", "isochronous", "bulk", "interrupt"
@@ -418,10 +452,8 @@ set_address (hci_t *controller, int speed, int hubport, int hubaddr)
0) ? OUT : IN;
ep->type = endp->bmAttributes;
ep->interval = usb_decode_interval(dev->speed, ep->type, endp->bInterval);
- endp = (endpoint_descriptor_t
- *) (((char *) endp) + endp->bLength);
}
- current = (interface_descriptor_t *) endp;
+ current = (const interface_descriptor_t *)endp;
}
}
More information about the coreboot-gerrit
mailing list