diff mbox

[3.8.y.z,extended,stable] Patch "USB: OHCI: fix logic for scheduling isochronous URBs" has been added to staging queue

Message ID 1369946087-11497-1-git-send-email-kamal@canonical.com
State New
Headers show

Commit Message

Kamal Mostafa May 30, 2013, 8:34 p.m. UTC
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@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@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
---
 drivers/usb/host/ohci-hcd.c | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

--
1.8.1.2
diff mbox

Patch

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;
 	}