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);
/****************************************************************