From 68335e816a92411649955a9903b1f30c388ea322 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 22 May 2009 17:02:33 -0400 Subject: USB: EHCI: stagger frames for interrupt transfers This patch (as1243) tries to improve ehci-hcd's scheduling of interrupt transfers. Instead of trying to cram all transfers with the same period into the same frame, the new code will spread the transfers out among lots of different frames. This should reduce the periodic schedule load in any one frame -- some host controllers have trouble when there's too much work to do. A more thorough approach would stagger the uframe values as well. But this is enough to make a big improvement. Signed-off-by: Alan Stern Tested-by: Dwayne Fontenot Cc: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sched.c | 8 +++++--- drivers/usb/host/ehci.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 556d0ec0c1f8..9d1babc7ff65 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -760,8 +760,10 @@ static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh) if (status) { /* "normal" case, uframing flexible except with splits */ if (qh->period) { - frame = qh->period - 1; - do { + int i; + + for (i = qh->period; status && i > 0; --i) { + frame = ++ehci->random_frame % qh->period; for (uframe = 0; uframe < 8; uframe++) { status = check_intr_schedule (ehci, frame, uframe, qh, @@ -769,7 +771,7 @@ static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh) if (status == 0) break; } - } while (status && frame--); + } /* qh->period == 0 means every uframe */ } else { diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 6cff195e1a36..90ad3395bb21 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -116,6 +116,7 @@ struct ehci_hcd { /* one per controller */ struct timer_list watchdog; unsigned long actions; unsigned stamp; + unsigned random_frame; unsigned long next_statechange; u32 command; -- cgit v1.2.3