Commit 4005ad43 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

EHCI: implement new semantics for URB_ISO_ASAP

This patch (as1612) updates the isochronous scheduling and processing
in ehci-hcd to match the new semantics for URB_ISO_ASAP.  It also adds
a missing "unlikely" in sitd_complete() to match the corresponding
statement in itd_complete(), and it increments urb->error_count in a
couple of places that had been overlooked.
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a03bede5
...@@ -1386,8 +1386,8 @@ iso_stream_schedule ( ...@@ -1386,8 +1386,8 @@ iso_stream_schedule (
/* Typical case: reuse current schedule, stream is still active. /* Typical case: reuse current schedule, stream is still active.
* Hopefully there are no gaps from the host falling behind * Hopefully there are no gaps from the host falling behind
* (irq delays etc), but if there are we'll take the next * (irq delays etc). If there are, the behavior depends on
* slot in the schedule, implicitly assuming URB_ISO_ASAP. * whether URB_ISO_ASAP is set.
*/ */
if (likely (!list_empty (&stream->td_list))) { if (likely (!list_empty (&stream->td_list))) {
...@@ -1414,9 +1414,25 @@ iso_stream_schedule ( ...@@ -1414,9 +1414,25 @@ iso_stream_schedule (
goto fail; goto fail;
} }
/* Behind the scheduling threshold? Assume URB_ISO_ASAP. */ /* Behind the scheduling threshold? */
if (unlikely(start < next)) if (unlikely(start < next)) {
start += (next - start + period - 1) & (- period);
/* USB_ISO_ASAP: Round up to the first available slot */
if (urb->transfer_flags & URB_ISO_ASAP)
start += (next - start + period - 1) & -period;
/*
* Not ASAP: Use the next slot in the stream. If
* the entire URB falls before the threshold, fail.
*/
else if (start + span - period < next) {
ehci_dbg(ehci, "iso urb late %p (%u+%u < %u)\n",
urb, start + base,
span - period, next + base);
status = -EXDEV;
goto fail;
}
}
start += base; start += base;
} }
...@@ -1699,7 +1715,7 @@ static bool itd_complete(struct ehci_hcd *ehci, struct ehci_itd *itd) ...@@ -1699,7 +1715,7 @@ static bool itd_complete(struct ehci_hcd *ehci, struct ehci_itd *itd)
urb->actual_length += desc->actual_length; urb->actual_length += desc->actual_length;
} else { } else {
/* URB was too late */ /* URB was too late */
desc->status = -EXDEV; urb->error_count++;
} }
} }
...@@ -2072,7 +2088,7 @@ static bool sitd_complete(struct ehci_hcd *ehci, struct ehci_sitd *sitd) ...@@ -2072,7 +2088,7 @@ static bool sitd_complete(struct ehci_hcd *ehci, struct ehci_sitd *sitd)
t = hc32_to_cpup(ehci, &sitd->hw_results); t = hc32_to_cpup(ehci, &sitd->hw_results);
/* report transfer status */ /* report transfer status */
if (t & SITD_ERRS) { if (unlikely(t & SITD_ERRS)) {
urb->error_count++; urb->error_count++;
if (t & SITD_STS_DBE) if (t & SITD_STS_DBE)
desc->status = usb_pipein (urb->pipe) desc->status = usb_pipein (urb->pipe)
...@@ -2082,6 +2098,9 @@ static bool sitd_complete(struct ehci_hcd *ehci, struct ehci_sitd *sitd) ...@@ -2082,6 +2098,9 @@ static bool sitd_complete(struct ehci_hcd *ehci, struct ehci_sitd *sitd)
desc->status = -EOVERFLOW; desc->status = -EOVERFLOW;
else /* XACT, MMF, etc */ else /* XACT, MMF, etc */
desc->status = -EPROTO; desc->status = -EPROTO;
} else if (unlikely(t & SITD_STS_ACTIVE)) {
/* URB was too late */
urb->error_count++;
} else { } else {
desc->status = 0; desc->status = 0;
desc->actual_length = desc->length - SITD_LENGTH(t); desc->actual_length = desc->length - SITD_LENGTH(t);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment