diff options
Diffstat (limited to 'usb/usb-ehci-simplify-remainder-computations.patch')
| -rw-r--r-- | usb/usb-ehci-simplify-remainder-computations.patch | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/usb/usb-ehci-simplify-remainder-computations.patch b/usb/usb-ehci-simplify-remainder-computations.patch new file mode 100644 index 00000000000000..d49e13986c755d --- /dev/null +++ b/usb/usb-ehci-simplify-remainder-computations.patch @@ -0,0 +1,148 @@ +From linux-usb-owner@vger.kernel.org Thu Jul 22 15:51:42 2010 +Date: Wed, 14 Jul 2010 11:03:36 -0400 (EDT) +From: Alan Stern <stern@rowland.harvard.edu> +To: Greg KH <greg@kroah.com> +cc: David Brownell <david-b@pacbell.net>, + USB list <linux-usb@vger.kernel.org> +Subject: USB: EHCI: simplify remainder computations +Message-ID: <Pine.LNX.4.44L0.1007141055270.1634-100000@iolanthe.rowland.org> + +This patch (as1406) adds a micro-optimization to ehci-hcd's scheduling +code. Instead of computing remainders with respect to the schedule +length, use bitwise-and (which is quicker). We know that the schedule +length will always be a power of two, but the compiler doesn't have +this information. + +Signed-off-by: Alan Stern <stern@rowland.harvard.edu> +CC: David Brownell <david-b@pacbell.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/host/ehci-sched.c | 29 +++++++++++++++-------------- + 1 file changed, 15 insertions(+), 14 deletions(-) + +--- a/drivers/usb/host/ehci-sched.c ++++ b/drivers/usb/host/ehci-sched.c +@@ -1417,7 +1417,7 @@ iso_stream_schedule ( + if (!stream->highspeed) + period <<= 3; + +- now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; ++ now = ehci_readl(ehci, &ehci->regs->frame_index) & (mod - 1); + + /* Typical case: reuse current schedule, stream is still active. + * Hopefully there are no gaps from the host falling behind +@@ -1461,7 +1461,7 @@ iso_stream_schedule ( + * jump until after the queue is primed. + */ + start = SCHEDULE_SLOP + (now & ~0x07); +- start %= mod; ++ start &= mod - 1; + stream->next_uframe = start; + + /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ +@@ -1483,7 +1483,7 @@ iso_stream_schedule ( + + /* schedule it here if there's enough bandwidth */ + if (enough_space) { +- stream->next_uframe = start % mod; ++ stream->next_uframe = start & (mod - 1); + goto ready; + } + } +@@ -1599,7 +1599,7 @@ itd_link_urb ( + struct ehci_iso_sched *iso_sched = urb->hcpriv; + struct ehci_itd *itd; + +- next_uframe = stream->next_uframe % mod; ++ next_uframe = stream->next_uframe & (mod - 1); + + if (unlikely (list_empty(&stream->td_list))) { + ehci_to_hcd(ehci)->self.bandwidth_allocated +@@ -1637,13 +1637,13 @@ itd_link_urb ( + + next_uframe += stream->interval; + stream->depth += stream->interval; +- next_uframe %= mod; ++ next_uframe &= mod - 1; + packet++; + + /* link completed itds into the schedule */ + if (((next_uframe >> 3) != frame) + || packet == urb->number_of_packets) { +- itd_link (ehci, frame % ehci->periodic_size, itd); ++ itd_link(ehci, frame & (ehci->periodic_size - 1), itd); + itd = NULL; + } + } +@@ -2020,7 +2020,7 @@ sitd_link_urb ( + "sched devp %s ep%d%s-iso [%d] %dms/%04x\n", + urb->dev->devpath, stream->bEndpointAddress & 0x0f, + (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out", +- (next_uframe >> 3) % ehci->periodic_size, ++ (next_uframe >> 3) & (ehci->periodic_size - 1), + stream->interval, hc32_to_cpu(ehci, stream->splits)); + stream->start = jiffies; + } +@@ -2043,13 +2043,13 @@ sitd_link_urb ( + sitd->urb = urb; + + sitd_patch(ehci, stream, sitd, sched, packet); +- sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size, ++ sitd_link(ehci, (next_uframe >> 3) & (ehci->periodic_size - 1), + sitd); + + next_uframe += stream->interval << 3; + stream->depth += stream->interval << 3; + } +- stream->next_uframe = next_uframe % mod; ++ stream->next_uframe = next_uframe & (mod - 1); + + /* don't need that schedule data any more */ + iso_sched_free (stream, sched); +@@ -2258,7 +2258,7 @@ scan_periodic (struct ehci_hcd *ehci) + now_uframe = ehci->next_uframe; + if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { + clock = ehci_readl(ehci, &ehci->regs->frame_index); +- clock_frame = (clock >> 3) % ehci->periodic_size; ++ clock_frame = (clock >> 3) & (ehci->periodic_size - 1); + } else { + clock = now_uframe + mod - 1; + clock_frame = -1; +@@ -2267,7 +2267,7 @@ scan_periodic (struct ehci_hcd *ehci) + free_cached_lists(ehci); + ehci->clock_frame = clock_frame; + } +- clock %= mod; ++ clock &= mod - 1; + clock_frame = clock >> 3; + + for (;;) { +@@ -2356,7 +2356,7 @@ restart: + * frame is current. + */ + if (((frame == clock_frame) || +- (((frame + 1) % ehci->periodic_size) ++ (((frame + 1) & (ehci->periodic_size - 1)) + == clock_frame)) + && live + && (q.sitd->hw_results & +@@ -2423,7 +2423,8 @@ restart: + || ehci->periodic_sched == 0) + break; + ehci->next_uframe = now_uframe; +- now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; ++ now = ehci_readl(ehci, &ehci->regs->frame_index) & ++ (mod - 1); + if (now_uframe == now) + break; + +@@ -2436,7 +2437,7 @@ restart: + } + } else { + now_uframe++; +- now_uframe %= mod; ++ now_uframe &= mod - 1; + } + } + } |
