[coreboot-gerrit] New patch to review for coreboot: 155090a libpayload: usb: Add interval attribute to endpoints

Nico Huber (nico.huber@secunet.com) gerrit at coreboot.org
Thu Jun 13 14:46:32 CEST 2013


Nico Huber (nico.huber at secunet.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3449

-gerrit

commit 155090a29f9bc93f058f78e92275aa29a76fe2a3
Author: Nico Huber <nico.huber at secunet.com>
Date:   Thu Jun 6 10:20:35 2013 +0200

    libpayload: usb: Add interval attribute to endpoints
    
    Read bInterval from endpoint descriptors and store it in our endpoint_t
    struct. The interval is encoded dependently on the device' speed and the
    endpoint's type. Therefore, it will be normalized to the binary logarithm
    of the number of microframes, i.e.
      t = 125us * 2^interval
    
    The interval attribute will be used in the xHCI driver.
    
    Change-Id: I65a8eda6145faf34666800789f0292e640a8141b
    Signed-off-by: Nico Huber <nico.huber at secunet.com>
---
 payloads/libpayload/drivers/usb/usb.c | 44 +++++++++++++++++++++++++++++++++++
 payloads/libpayload/include/usb/usb.h |  2 ++
 2 files changed, 46 insertions(+)

diff --git a/payloads/libpayload/drivers/usb/usb.c b/payloads/libpayload/drivers/usb/usb.c
index 54a5935..47f8eb6 100644
--- a/payloads/libpayload/drivers/usb/usb.c
+++ b/payloads/libpayload/drivers/usb/usb.c
@@ -278,6 +278,48 @@ generic_set_address (hci_t *controller, int speed, int hubport, int hubaddr)
 	return adr;
 }
 
+/* Normalize bInterval to log2 of microframes */
+static int
+usb_decode_interval(const int speed, const endpoint_type type, const unsigned char bInterval)
+{
+#define LOG2(a) ((sizeof(unsigned) << 3) - __builtin_clz(a) - 1)
+	switch (speed) {
+	case LOW_SPEED:
+		switch (type) {
+		case ISOCHRONOUS: case INTERRUPT:
+			return LOG2(bInterval) + 3;
+		default:
+			return 0;
+		}
+	case FULL_SPEED:
+		switch (type) {
+		case ISOCHRONOUS:
+			return (bInterval - 1) + 3;
+		case INTERRUPT:
+			return LOG2(bInterval) + 3;
+		default:
+			return 0;
+		}
+	case HIGH_SPEED:
+		switch (type) {
+		case ISOCHRONOUS: case INTERRUPT:
+			return bInterval - 1;
+		default:
+			return LOG2(bInterval);
+		}
+	case SUPER_SPEED:
+		switch (type) {
+		case ISOCHRONOUS: case INTERRUPT:
+			return bInterval - 1;
+		default:
+			return 0;
+		}
+	default:
+		return 0;
+	}
+#undef LOG2
+}
+
 static int
 set_address (hci_t *controller, int speed, int hubport, int hubaddr)
 {
@@ -357,6 +399,7 @@ set_address (hci_t *controller, int speed, int hubport, int hubaddr)
 			dev->endpoints[0].maxpacketsize = dd->bMaxPacketSize0;
 			dev->endpoints[0].direction = SETUP;
 			dev->endpoints[0].type = CONTROL;
+			dev->endpoints[0].interval = usb_decode_interval(dev->speed, CONTROL, endp->bInterval);
 			for (j = 1; j <= current->bNumEndpoints; j++) {
 #ifdef USB_DEBUG
 				static const char *transfertypes[4] = {
@@ -374,6 +417,7 @@ set_address (hci_t *controller, int speed, int hubport, int hubaddr)
 					((endp->bEndpointAddress & 0x80) ==
 					 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);
 			}
diff --git a/payloads/libpayload/include/usb/usb.h b/payloads/libpayload/include/usb/usb.h
index 3aac2ae..ab45708 100644
--- a/payloads/libpayload/include/usb/usb.h
+++ b/payloads/libpayload/include/usb/usb.h
@@ -91,6 +91,8 @@ typedef struct {
 	int toggle;
 	int maxpacketsize;
 	endpoint_type type;
+	int interval; /* expressed as binary logarithm of the number
+			 of microframes (i.e. t = 125us * 2^interval) */
 } endpoint_t;
 
 enum { FULL_SPEED = 0, LOW_SPEED = 1, HIGH_SPEED = 2, SUPER_SPEED = 3 };



More information about the coreboot-gerrit mailing list