[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