]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
USB: musb: rewrite host periodic endpoint allocation
authorSergei Shtylyov <sshtylyov@ru.mvista.com>
Tue, 24 Feb 2009 23:23:34 +0000 (15:23 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 24 Mar 2009 23:20:35 +0000 (16:20 -0700)
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@ti.com>)

[ dbrownell@users.sourceforge.net: clarify description and origin
  of this fix; whitespace ]

Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Felipe Balbi <felipe.balbi@nokia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_host.c

index 630946a2d9fce2db69bd9a7cd2ab68d513ade60f..adf1806007ffe58c027726008b95daebf15588ce 100644 (file)
@@ -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,
index 6dbbd0786a6a0955877dca888f107b641d50eec0..9489c859868601351d61595996e970ef88aa9807 100644 (file)
@@ -395,7 +395,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;
@@ -1711,31 +1710,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;
 
@@ -1764,7 +1759,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) {