[SeaBIOS] [PATCH 7/8] Introduce helper functions for finding USB end-points.

Kevin O'Connor kevin at koconnor.net
Thu Feb 18 05:41:34 CET 2010


Introduce findEndPointDesc() and mkendpFromDesc() and refactor usb-hid
code.
---
 src/usb-hid.c |   26 ++++++++------------------
 src/usb.c     |   45 +++++++++++++++++++++++++++++++++++++++++++++
 src/usb.h     |    4 ++++
 3 files changed, 57 insertions(+), 18 deletions(-)

diff --git a/src/usb-hid.c b/src/usb-hid.c
index 48dec8b..ae16686 100644
--- a/src/usb-hid.c
+++ b/src/usb-hid.c
@@ -54,30 +54,20 @@ usb_keyboard_init(u32 endp, struct usb_interface_descriptor *iface, int imax)
         return -1;
     dprintf(2, "usb_keyboard_setup %x\n", endp);
 
-    struct usb_endpoint_descriptor *epdesc = (void*)&iface[1];
-    for (;;) {
-        if ((void*)epdesc >= (void*)iface + imax
-            || epdesc->bDescriptorType == USB_DT_INTERFACE) {
-            dprintf(1, "No keyboard intr in?\n");
-            return -1;
-        }
-        if (epdesc->bDescriptorType == USB_DT_ENDPOINT
-            && (epdesc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN
-            && ((epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-                == USB_ENDPOINT_XFER_INT)
-            && epdesc->wMaxPacketSize == 8)
-            break;
-        epdesc = (void*)epdesc + epdesc->bLength;
+    // Find intr in endpoint.
+    struct usb_endpoint_descriptor *epdesc = findEndPointDesc(
+        iface, imax, USB_ENDPOINT_XFER_INT, USB_DIR_IN);
+    if (!epdesc || epdesc->wMaxPacketSize != 8) {
+        dprintf(1, "No keyboard intr in?\n");
+        return -1;
     }
-    u32 inendp = mkendp(endp2cntl(endp), endp2devaddr(endp)
-                        , epdesc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK
-                        , endp2speed(endp), epdesc->wMaxPacketSize);
+    u32 inendp = mkendpFromDesc(endp, epdesc);
 
     // Enable "boot" protocol.
     int ret = set_protocol(endp, 1);
     if (ret)
         return -1;
-    // Only send reports on a new key event.
+    // Periodically send reports to enable key repeat.
     ret = set_idle(endp, KEYREPEATMS);
     if (ret)
         return -1;
diff --git a/src/usb.c b/src/usb.c
index cb6f391..1ed3c80 100644
--- a/src/usb.c
+++ b/src/usb.c
@@ -18,6 +18,12 @@
 
 struct usb_s USBControllers[16] VAR16VISIBLE;
 
+
+/****************************************************************
+ * Controller function wrappers
+ ****************************************************************/
+
+// Send a message on a control pipe using the default control descriptor.
 static int
 send_control(u32 endp, int dir, const void *cmd, int cmdsize
              , void *data, int datasize)
@@ -63,6 +69,40 @@ usb_poll_intr(struct usb_pipe *pipe, void *data)
     }
 }
 
+
+/****************************************************************
+ * Helper functions
+ ****************************************************************/
+
+// Find the first endpoing of a given type in an interface description.
+struct usb_endpoint_descriptor *
+findEndPointDesc(struct usb_interface_descriptor *iface, int imax
+                 , int type, int dir)
+{
+    struct usb_endpoint_descriptor *epdesc = (void*)&iface[1];
+    for (;;) {
+        if ((void*)epdesc >= (void*)iface + imax
+            || epdesc->bDescriptorType == USB_DT_INTERFACE) {
+            return NULL;
+        }
+        if (epdesc->bDescriptorType == USB_DT_ENDPOINT
+            && (epdesc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == dir
+            && (epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == type)
+            return epdesc;
+        epdesc = (void*)epdesc + epdesc->bLength;
+    }
+}
+
+// Build an encoded "endp" from an endpoint descriptor.
+u32
+mkendpFromDesc(u32 endp, struct usb_endpoint_descriptor *epdesc)
+{
+    return mkendp(endp2cntl(endp), endp2devaddr(endp)
+                  , epdesc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK
+                  , endp2speed(endp), epdesc->wMaxPacketSize);
+}
+
+// Send a message to the default control pipe of a device.
 int
 send_default_control(u32 endp, const struct usb_ctrlrequest *req, void *data)
 {
@@ -144,6 +184,11 @@ set_configuration(u32 endp, u16 val)
     return send_default_control(endp, &req, NULL);
 }
 
+
+/****************************************************************
+ * Initialization and enumeration
+ ****************************************************************/
+
 // Called for every found device - see if a driver is available for
 // this device and do setup if so.
 int
diff --git a/src/usb.h b/src/usb.h
index e4d0a66..925f8ae 100644
--- a/src/usb.h
+++ b/src/usb.h
@@ -39,6 +39,10 @@ int send_default_control(u32 endp, const struct usb_ctrlrequest *req
                          , void *data);
 struct usb_pipe *alloc_intr_pipe(u32 endp, int period);
 int usb_poll_intr(struct usb_pipe *pipe, void *data);
+struct usb_interface_descriptor;
+struct usb_endpoint_descriptor *findEndPointDesc(
+    struct usb_interface_descriptor *iface, int imax, int type, int dir);
+u32 mkendpFromDesc(u32 endp, struct usb_endpoint_descriptor *epdesc);
 
 
 /****************************************************************
-- 
1.6.6




More information about the SeaBIOS mailing list