+int noinline
+usb_poll_intr(struct usb_pipe *pipe_fl, void *data)
+{
+ switch (GET_FLATPTR(pipe_fl->type)) {
+ default:
+ case USB_TYPE_UHCI:
+ return uhci_poll_intr(pipe_fl, data);
+ case USB_TYPE_OHCI:
+ return ohci_poll_intr(pipe_fl, data);
+ case USB_TYPE_EHCI:
+ return ehci_poll_intr(pipe_fl, 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;
+ }
+}
+
+// Send a message to the default control pipe of a device.