[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