aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-10-16 11:55:30 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-10-25 15:18:43 -0400
commit7898ffc543566a9c4a1b4ff39f43857d2d84a51c (patch)
treef69b2c37ef58f3e850205c2036b01e420f2fbb53 /drivers/usb/host
parent6ce073bd8be0a741440944fed892a136a1d24bbe (diff)
USB: fix scheduling of Iso URBs in uhci-hcd
This patch (as1003) changes uhci-hcd to treat the URB_ISO_ASAP flag the same as other host controller drivers, namely, to schedule an Iso URB for the first available time slot that hasn't already expired. URBs in which the flag isn't set will be scheduled for the first slot following the last URB, even if it has expired. This fixes a problem reported by Martin Bachem. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/uhci-q.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index e5d60d5b105a..60379b17bbc1 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -1271,7 +1271,8 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
1271 } else if (qh->period != urb->interval) { 1271 } else if (qh->period != urb->interval) {
1272 return -EINVAL; /* Can't change the period */ 1272 return -EINVAL; /* Can't change the period */
1273 1273
1274 } else { /* Pick up where the last URB leaves off */ 1274 } else {
1275 /* Find the next unused frame */
1275 if (list_empty(&qh->queue)) { 1276 if (list_empty(&qh->queue)) {
1276 frame = qh->iso_frame; 1277 frame = qh->iso_frame;
1277 } else { 1278 } else {
@@ -1283,10 +1284,18 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
1283 lurb->number_of_packets * 1284 lurb->number_of_packets *
1284 lurb->interval; 1285 lurb->interval;
1285 } 1286 }
1286 if (urb->transfer_flags & URB_ISO_ASAP) 1287 if (urb->transfer_flags & URB_ISO_ASAP) {
1287 urb->start_frame = frame; 1288 /* Skip some frames if necessary to insure
1288 else if (urb->start_frame != frame) 1289 * the start frame is in the future.
1289 return -EINVAL; 1290 */
1291 uhci_get_current_frame_number(uhci);
1292 if (uhci_frame_before_eq(frame, uhci->frame_number)) {
1293 frame = uhci->frame_number + 1;
1294 frame += ((qh->phase - frame) &
1295 (qh->period - 1));
1296 }
1297 } /* Otherwise pick up where the last URB leaves off */
1298 urb->start_frame = frame;
1290 } 1299 }
1291 1300
1292 /* Make sure we won't have to go too far into the future */ 1301 /* Make sure we won't have to go too far into the future */