summaryrefslogtreecommitdiff
path: root/drivers/usb/host/uhci-q.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2008-09-26 00:59:57 +0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-10-18 01:41:01 +0400
commite58dcebcd83b5902411e747ee7807219dee6bcf2 (patch)
tree2d37312f1514ad992698f642a8e567c1ffc9c359 /drivers/usb/host/uhci-q.c
parent925dff5dee04fb46d2e67c088c54b331f97672ee (diff)
downloadlinux-e58dcebcd83b5902411e747ee7807219dee6bcf2.tar.xz
USB: UHCI: improve scheduling of interrupt URBs
This patch (as1140) adds a little intelligence to the interrupt-URB scheduler in uhci-hcd. Right now the scheduler is stupid; every URB having the same period is assigned to the same slot. Thus a large group of period-N URBs can fill their slot and cause -ENOSPC errors even when all the lower-period slots are empty. With the patch, if an URB doesn't fit in its assigned slot then the scheduler will try using lower-period slots. This will provide greater flexibility. As an example, the driver will be able to handle more than just three or four mice, which the current driver cannot. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/uhci-q.c')
-rw-r--r--drivers/usb/host/uhci-q.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 1f0c2cf26e5d..5631d89c8730 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -1065,13 +1065,18 @@ static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb,
}
if (exponent < 0)
return -EINVAL;
- qh->period = 1 << exponent;
- qh->skel = SKEL_INDEX(exponent);
- /* For now, interrupt phase is fixed by the layout
- * of the QH lists. */
- qh->phase = (qh->period / 2) & (MAX_PHASE - 1);
- ret = uhci_check_bandwidth(uhci, qh);
+ /* If the slot is full, try a lower period */
+ do {
+ qh->period = 1 << exponent;
+ qh->skel = SKEL_INDEX(exponent);
+
+ /* For now, interrupt phase is fixed by the layout
+ * of the QH lists.
+ */
+ qh->phase = (qh->period / 2) & (MAX_PHASE - 1);
+ ret = uhci_check_bandwidth(uhci, qh);
+ } while (ret != 0 && --exponent >= 0);
if (ret)
return ret;
} else if (qh->period > urb->interval)