+#define MAX_INT_QUEUESIZE 8
+
+struct int_queue {
+ int queuesize;
+ int curr_urb;
+ urb_priv_t *urb[MAX_INT_QUEUESIZE];
+};
+
+static struct int_queue *_ohci_create_int_queue(ohci_t *ohci,
+ struct usb_device *udev, unsigned long pipe, int queuesize,
+ int elementsize, void *buffer, int interval)
+{
+ struct int_queue *queue;
+ ohci_dev_t *ohci_dev;
+ int i;
+
+ if (queuesize > MAX_INT_QUEUESIZE)
+ return NULL;
+
+ ohci_dev = ohci_get_ohci_dev(ohci, udev->devnum, 1);
+ if (!ohci_dev)
+ return NULL;
+
+ queue = malloc(sizeof(*queue));
+ if (!queue) {
+ printf("ohci: Error out of memory allocating int queue\n");
+ return NULL;
+ }
+
+ for (i = 0; i < queuesize; i++) {
+ queue->urb[i] = ohci_alloc_urb(udev, pipe,
+ buffer + i * elementsize,
+ elementsize, interval);
+ if (!queue->urb[i])
+ break;
+
+ if (sohci_submit_job(ohci, ohci_dev, queue->urb[i], NULL)) {
+ printf("ohci: Error submitting int queue job\n");
+ urb_free_priv(queue->urb[i]);
+ break;
+ }
+ }
+ if (i == 0) {
+ /* We did not succeed in submitting even 1 urb */
+ free(queue);
+ return NULL;
+ }
+
+ queue->queuesize = i;
+ queue->curr_urb = 0;
+
+ return queue;
+}
+
+static void *_ohci_poll_int_queue(ohci_t *ohci, struct usb_device *udev,
+ struct int_queue *queue)
+{
+ if (queue->curr_urb == queue->queuesize)
+ return NULL; /* Queue depleted */
+
+ if (hc_interrupt(ohci) < 0)
+ return NULL;
+
+ if (queue->urb[queue->curr_urb]->finished) {
+ void *ret = queue->urb[queue->curr_urb]->transfer_buffer;
+ queue->curr_urb++;
+ return ret;
+ }
+
+ return NULL;
+}
+
+static int _ohci_destroy_int_queue(ohci_t *ohci, struct usb_device *dev,
+ struct int_queue *queue)
+{
+ int i;
+
+ for (i = 0; i < queue->queuesize; i++)
+ urb_free_priv(queue->urb[i]);
+
+ free(queue);
+
+ return 0;
+}
+