107 lines
3.8 KiB
Diff
107 lines
3.8 KiB
Diff
From 9ebf351bcd28a89a0b1ba8d0496fffbc72421611 Mon Sep 17 00:00:00 2001
|
|
From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
|
|
Date: Tue, 24 Mar 2009 17:22:50 -0700
|
|
Subject: [PATCH] USB: musb: rewrite host periodic endpoint allocation
|
|
|
|
The current MUSB host code doesn't make use of all the available
|
|
FIFOs in for periodic transfers since it wrongly assumes the RX
|
|
and TX sides of any given hw_ep always share one FIFO.
|
|
|
|
Change: use 'in_qh' and 'out_qh' fields of the 'struct musb_hw_ep'
|
|
to check the endpoint's business; get rid of the now-unused 'periodic'
|
|
array in the 'struct musb'. Also optimize a loop induction variable
|
|
in the endpoint lookup code.
|
|
|
|
(Based on a previous patch from Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org>)
|
|
|
|
[ dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org: clarify description and origin
|
|
of this fix; whitespace ]
|
|
|
|
Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
|
|
Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
|
|
Cc: Felipe Balbi <felipe.balbi-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh-l3A5Bk7waGM@public.gmane.org>
|
|
---
|
|
drivers/usb/musb/musb_core.h | 1 -
|
|
drivers/usb/musb/musb_host.c | 28 +++++++++++-----------------
|
|
2 files changed, 11 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
|
|
index 630946a..adf1806 100644
|
|
--- a/drivers/usb/musb/musb_core.h
|
|
+++ b/drivers/usb/musb/musb_core.h
|
|
@@ -331,7 +331,6 @@ struct musb {
|
|
struct list_head control; /* of musb_qh */
|
|
struct list_head in_bulk; /* of musb_qh */
|
|
struct list_head out_bulk; /* of musb_qh */
|
|
- struct musb_qh *periodic[32]; /* tree of interrupt+iso */
|
|
#endif
|
|
|
|
/* called with IRQs blocked; ON/nonzero implies starting a session,
|
|
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
|
|
index bd1d5ae..499c431 100644
|
|
--- a/drivers/usb/musb/musb_host.c
|
|
+++ b/drivers/usb/musb/musb_host.c
|
|
@@ -390,7 +390,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
|
|
* de-allocated if it's tracked and allocated;
|
|
* and where we'd update the schedule tree...
|
|
*/
|
|
- musb->periodic[ep->epnum] = NULL;
|
|
kfree(qh);
|
|
qh = NULL;
|
|
break;
|
|
@@ -1760,31 +1759,27 @@ static int musb_schedule(
|
|
|
|
/* else, periodic transfers get muxed to other endpoints */
|
|
|
|
- /* FIXME this doesn't consider direction, so it can only
|
|
- * work for one half of the endpoint hardware, and assumes
|
|
- * the previous cases handled all non-shared endpoints...
|
|
- */
|
|
-
|
|
- /* we know this qh hasn't been scheduled, so all we need to do
|
|
+ /*
|
|
+ * We know this qh hasn't been scheduled, so all we need to do
|
|
* is choose which hardware endpoint to put it on ...
|
|
*
|
|
* REVISIT what we really want here is a regular schedule tree
|
|
- * like e.g. OHCI uses, but for now musb->periodic is just an
|
|
- * array of the _single_ logical endpoint associated with a
|
|
- * given physical one (identity mapping logical->physical).
|
|
- *
|
|
- * that simplistic approach makes TT scheduling a lot simpler;
|
|
- * there is none, and thus none of its complexity...
|
|
+ * like e.g. OHCI uses.
|
|
*/
|
|
best_diff = 4096;
|
|
best_end = -1;
|
|
|
|
- for (epnum = 1; epnum < musb->nr_endpoints; epnum++) {
|
|
+ for (epnum = 1, hw_ep = musb->endpoints + 1;
|
|
+ epnum < musb->nr_endpoints;
|
|
+ epnum++, hw_ep++) {
|
|
int diff;
|
|
|
|
- if (musb->periodic[epnum])
|
|
+ if (is_in || hw_ep->is_shared_fifo) {
|
|
+ if (hw_ep->in_qh != NULL)
|
|
+ continue;
|
|
+ } else if (hw_ep->out_qh != NULL)
|
|
continue;
|
|
- hw_ep = &musb->endpoints[epnum];
|
|
+
|
|
if (hw_ep == musb->bulk_ep)
|
|
continue;
|
|
|
|
@@ -1824,7 +1819,6 @@ static int musb_schedule(
|
|
idle = 1;
|
|
qh->mux = 0;
|
|
hw_ep = musb->endpoints + best_end;
|
|
- musb->periodic[best_end] = qh;
|
|
DBG(4, "qh %p periodic slot %d\n", qh, best_end);
|
|
success:
|
|
if (head) {
|
|
--
|
|
1.6.0.4
|
|
|