linux-omap git: add another MUSB fix
authorKoen Kooi <koen@openembedded.org>
Tue, 7 Oct 2008 09:14:11 +0000 (09:14 +0000)
committerKoen Kooi <koen@openembedded.org>
Tue, 7 Oct 2008 09:14:11 +0000 (09:14 +0000)
packages/linux/linux-omap/musb-fix-endpoints.diff [new file with mode: 0644]
packages/linux/linux-omap_git.bb

diff --git a/packages/linux/linux-omap/musb-fix-endpoints.diff b/packages/linux/linux-omap/musb-fix-endpoints.diff
new file mode 100644 (file)
index 0000000..5d1201f
--- /dev/null
@@ -0,0 +1,197 @@
+From: Ajay Kumar Gupta <ajay.gupta@ti.com>
+To: linux-usb@vger.kernel.org
+Cc: linux-omap@vger.kernel.org, david-b@pacbell.net, me@felipebalbi.com,
+        Ajay Kumar Gupta <ajay.gupta@ti.com>
+Subject: [PATCH] MUSB: BULK request on different available endpoints
+Date:  Tue,  7 Oct 2008 11:12:24 +0530
+
+Fixes co-working issue of usb serial device with usb/net devices while
+oter endpoints are free and can be used.This patch implements the policy
+that if endpoint resources are available then different BULK request goes
+to different endpoint otherwise they are multiplexed to one reserved
+endpoint as currently done.
+
+NAK limit scheme has to be added for multiplexed BULK request scenario
+to avoid endpoint starvation due to usb/net devices.
+
+musb->periodic[] flag setting is also updated.It use to set this flag for
+an endpoint even when only rx or tx is used.Now flag setting is done on
+rx/tx basis of an endpoint.
+
+Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com>
+---
+ drivers/usb/musb/musb_host.c |   94 ++++++++++++++++++++++++------------------
+ drivers/usb/musb/musb_host.h |    1 +
+ 2 files changed, 55 insertions(+), 40 deletions(-)
+--- /tmp/musb_host.c   2008-10-07 10:10:49.000000000 +0200
++++ git/drivers/usb/musb/musb_host.c   2008-10-07 10:13:59.000000000 +0200
+@@ -378,27 +378,32 @@
+               switch (qh->type) {
++              case USB_ENDPOINT_XFER_CONTROL:
++              case USB_ENDPOINT_XFER_BULK:
++                      /* fifo policy for these lists, except that NAKing
++                       * should rotate a qh to the end (for fairness).
++                       */
++                      if (qh->mux == 1) {
++                              head = qh->ring.prev;
++                              list_del(&qh->ring);
++                              kfree(qh);
++                              qh = first_qh(head);
++                              break;
++                      }
+               case USB_ENDPOINT_XFER_ISOC:
+               case USB_ENDPOINT_XFER_INT:
+                       /* this is where periodic bandwidth should be
+                        * de-allocated if it's tracked and allocated;
+                        * and where we'd update the schedule tree...
+                        */
+-                      musb->periodic[ep->epnum] = NULL;
++                      if (is_in)
++                              musb->periodic[2 * ep->epnum - 2] = NULL;
++                      else
++                              musb->periodic[2 * ep->epnum - 1] = NULL;
+                       kfree(qh);
+                       qh = NULL;
+                       break;
+-              case USB_ENDPOINT_XFER_CONTROL:
+-              case USB_ENDPOINT_XFER_BULK:
+-                      /* fifo policy for these lists, except that NAKing
+-                       * should rotate a qh to the end (for fairness).
+-                       */
+-                      head = qh->ring.prev;
+-                      list_del(&qh->ring);
+-                      kfree(qh);
+-                      qh = first_qh(head);
+-                      break;
+               }
+       }
+       return qh;
+@@ -1728,22 +1733,9 @@
+       u16                     maxpacket;
+       /* use fixed hardware for control and bulk */
+-      switch (qh->type) {
+-      case USB_ENDPOINT_XFER_CONTROL:
++      if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
+               head = &musb->control;
+               hw_ep = musb->control_ep;
+-              break;
+-      case USB_ENDPOINT_XFER_BULK:
+-              hw_ep = musb->bulk_ep;
+-              if (is_in)
+-                      head = &musb->in_bulk;
+-              else
+-                      head = &musb->out_bulk;
+-              break;
+-      }
+-      if (head) {
+-              idle = list_empty(head);
+-              list_add_tail(&qh->ring, head);
+               goto success;
+       }
+@@ -1778,7 +1770,8 @@
+       for (epnum = 1; epnum < musb->nr_endpoints; epnum++) {
+               int     diff;
+-              if (musb->periodic[epnum])
++              if ((is_in && musb->periodic[2 * epnum - 2]) ||
++                      (!is_in && musb->periodic[2 * epnum - 1]))
+                       continue;
+               hw_ep = &musb->endpoints[epnum];
+               if (hw_ep == musb->bulk_ep)
+@@ -1789,19 +1782,36 @@
+               else
+                       diff = hw_ep->max_packet_sz_tx - maxpacket;
+-              if (diff > 0 && best_diff > diff) {
++              if (diff >= 0 && best_diff > diff) {
+                       best_diff = diff;
+                       best_end = epnum;
+               }
+       }
+-      if (best_end < 0)
++      /* use bulk reserved ep1 if no other ep is free*/
++      if (best_end < 0 && qh->type == USB_ENDPOINT_XFER_BULK) {
++              hw_ep = musb->bulk_ep;
++              if (is_in)
++                      head = &musb->in_bulk;
++              else
++                      head = &musb->out_bulk;
++              goto success;
++      } else if (best_end < 0)
+               return -ENOSPC;
+       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);
++      if (is_in)
++              musb->periodic[2 * best_end - 2] = qh;
++      else
++              musb->periodic[2 * best_end - 1] = qh;
++      DBG(4, "qh %p periodic slot %d%s\n", qh, best_end, is_in ? "Rx" : "Tx");
+ success:
++      if (head) {
++              idle = list_empty(head);
++              list_add_tail(&qh->ring, head);
++              qh->mux = 1;
++      }
+       qh->hw_ep = hw_ep;
+       qh->hep->hcpriv = qh;
+       if (idle)
+@@ -2065,11 +2075,13 @@
+                       sched = &musb->control;
+                       break;
+               case USB_ENDPOINT_XFER_BULK:
+-                      if (usb_pipein(urb->pipe))
+-                              sched = &musb->in_bulk;
+-                      else
+-                              sched = &musb->out_bulk;
+-                      break;
++                      if (qh->mux == 1) {
++                              if (usb_pipein(urb->pipe))
++                                      sched = &musb->in_bulk;
++                              else
++                                      sched = &musb->out_bulk;
++                              break;
++                      }
+               default:
+                       /* REVISIT when we get a schedule tree, periodic
+                        * transfers won't always be at the head of a
+@@ -2131,11 +2143,13 @@
+               sched = &musb->control;
+               break;
+       case USB_ENDPOINT_XFER_BULK:
+-              if (is_in)
+-                      sched = &musb->in_bulk;
+-              else
+-                      sched = &musb->out_bulk;
+-              break;
++              if (qh->mux == 1) {
++                      if (is_in)
++                              sched = &musb->in_bulk;
++                      else
++                              sched = &musb->out_bulk;
++                      break;
++              }
+       case USB_ENDPOINT_XFER_ISOC:
+       case USB_ENDPOINT_XFER_INT:
+               for (i = 0; i < musb->nr_endpoints; i++) {
+--- /tmp/musb_host.h   2008-10-07 08:59:38.000000000 +0200
++++ git/drivers/usb/musb/musb_host.h   2008-10-07 10:10:54.000000000 +0200
+@@ -53,7 +53,8 @@
+       struct list_head        ring;           /* of musb_qh */
+       /* struct musb_qh               *next; */       /* for periodic tree */
+-
++      u8          mux;        /* qh multiplexed to hw_ep */
++      
+       unsigned                offset;         /* in urb->transfer_buffer */
+       unsigned                segsize;        /* current xfer fragment */
index b005727..290d900 100644 (file)
@@ -9,7 +9,7 @@ COMPATIBLE_MACHINE = "omap5912osk|omap1710h3|omap2430sdp|omap2420h4|beagleboard|
 SRCREV = "e1c49d7d22af768188e2a54c167ed79919361e55"
 
 PV = "2.6.26+2.6.27-rc7+${PR}+git${SRCREV}"
-PR = "r11"
+PR = "r12"
 
 SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git;protocol=git \
           file://defconfig"
@@ -33,6 +33,7 @@ SRC_URI_append = " \
            file://musb-fix-ISO-in-unlink.diff;patch=1 \
            file://musb-fix-multiple-bulk-transfers.diff;patch=1 \
            file://mru-256MB.diff;patch=1 \
+           file://musb-fix-endpoints.diff;patch=1 \
 "