diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/uhci-q.c | 19 |
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 */ |