[ 3.8.y.z extended stable ] Patch "USB: OHCI: fix logic for scheduling isochronous URBs" has been added to staging queue
Kamal Mostafa
kamal at canonical.com
Thu May 30 20:34:47 UTC 2013
This is a note to let you know that I have just added a patch titled
USB: OHCI: fix logic for scheduling isochronous URBs
to the linux-3.8.y-queue branch of the 3.8.y.z extended stable tree
which can be found at:
http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.8.y-queue
This patch is scheduled to be released in version 3.8.13.2.
If you, or anyone else, feels it should not be added to this tree, please
reply to this email.
For more information about the 3.8.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable
Thanks.
-Kamal
------
>From df6fb1bb9c9a8612b2e77fbf0d3a9d2478ef17cc Mon Sep 17 00:00:00 2001
From: Alan Stern <stern at rowland.harvard.edu>
Date: Tue, 14 May 2013 13:57:51 -0400
Subject: USB: OHCI: fix logic for scheduling isochronous URBs
commit 815fa7b917614261748d1ecd9600ff27f99508e5 upstream.
The isochronous scheduling logic in ohci-hcd has a bug. The
calculation for skipping TDs that are too late should be carried out
only in the !URB_ISO_ASAP case. When URB_ISO_ASAP is set, the URB is
pushed back so that none of the TDs are too late, which would cause
the calculation to overflow.
The patch also fixes the calculation to avoid overflow in the case
where the frame value wraps around.
This should be applied to -stable kernels going back to 3.8.
Signed-off-by: Alan Stern <stern at rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Kamal Mostafa <kamal at canonical.com>
---
drivers/usb/host/ohci-hcd.c | 32 ++++++++++++++++++--------------
1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 4b6d1c8..007137f 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -240,7 +240,7 @@ static int ohci_urb_enqueue (
if (unlikely(tick_before(frame, next))) {
/* USB_ISO_ASAP: Round up to the first available slot */
- if (urb->transfer_flags & URB_ISO_ASAP)
+ if (urb->transfer_flags & URB_ISO_ASAP) {
frame += (next - frame + ed->interval - 1) &
-ed->interval;
@@ -248,21 +248,25 @@ static int ohci_urb_enqueue (
* Not ASAP: Use the next slot in the stream. If
* the entire URB falls before the threshold, fail.
*/
- else if (tick_before(frame + ed->interval *
+ } else {
+ if (tick_before(frame + ed->interval *
(urb->number_of_packets - 1), next)) {
- retval = -EXDEV;
- usb_hcd_unlink_urb_from_ep(hcd, urb);
- goto fail;
- }
+ retval = -EXDEV;
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
+ goto fail;
+ }
- /*
- * Some OHCI hardware doesn't handle late TDs
- * correctly. After retiring them it proceeds to
- * the next ED instead of the next TD. Therefore
- * we have to omit the late TDs entirely.
- */
- urb_priv->td_cnt = DIV_ROUND_UP(next - frame,
- ed->interval);
+ /*
+ * Some OHCI hardware doesn't handle late TDs
+ * correctly. After retiring them it proceeds
+ * to the next ED instead of the next TD.
+ * Therefore we have to omit the late TDs
+ * entirely.
+ */
+ urb_priv->td_cnt = DIV_ROUND_UP(
+ (u16) (next - frame),
+ ed->interval);
+ }
}
urb->start_frame = frame;
}
--
1.8.1.2
More information about the kernel-team
mailing list