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;
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)
}
}
+
+/****************************************************************
+ * 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)
{
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
, 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);
/****************************************************************