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>
This commit is contained in:
Alan Stern 2007-10-16 11:55:30 -04:00 committed by Greg Kroah-Hartman
parent 6ce073bd8b
commit 7898ffc543

View File

@ -1271,7 +1271,8 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
} else if (qh->period != urb->interval) { } else if (qh->period != urb->interval) {
return -EINVAL; /* Can't change the period */ return -EINVAL; /* Can't change the period */
} else { /* Pick up where the last URB leaves off */ } else {
/* Find the next unused frame */
if (list_empty(&qh->queue)) { if (list_empty(&qh->queue)) {
frame = qh->iso_frame; frame = qh->iso_frame;
} else { } else {
@ -1283,10 +1284,18 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
lurb->number_of_packets * lurb->number_of_packets *
lurb->interval; lurb->interval;
} }
if (urb->transfer_flags & URB_ISO_ASAP) if (urb->transfer_flags & URB_ISO_ASAP) {
urb->start_frame = frame; /* Skip some frames if necessary to insure
else if (urb->start_frame != frame) * the start frame is in the future.
return -EINVAL; */
uhci_get_current_frame_number(uhci);
if (uhci_frame_before_eq(frame, uhci->frame_number)) {
frame = uhci->frame_number + 1;
frame += ((qh->phase - frame) &
(qh->period - 1));
}
} /* Otherwise pick up where the last URB leaves off */
urb->start_frame = frame;
} }
/* Make sure we won't have to go too far into the future */ /* Make sure we won't have to go too far into the future */