summaryrefslogtreecommitdiff
path: root/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0003-USB-musb-NAK-timeout-scheme-on-bulk-RX-endpoint.patch
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0003-USB-musb-NAK-timeout-scheme-on-bulk-RX-endpoint.patch
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadopenembedded-core-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
openembedded-core-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.bz2
openembedded-core-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.xz
openembedded-core-29d6678fd546377459ef75cf54abeef5b969b5cf.zip
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0003-USB-musb-NAK-timeout-scheme-on-bulk-RX-endpoint.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0003-USB-musb-NAK-timeout-scheme-on-bulk-RX-endpoint.patch218
1 files changed, 218 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0003-USB-musb-NAK-timeout-scheme-on-bulk-RX-endpoint.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0003-USB-musb-NAK-timeout-scheme-on-bulk-RX-endpoint.patch
new file mode 100644
index 000000000..fadad9e44
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0003-USB-musb-NAK-timeout-scheme-on-bulk-RX-endpoint.patch
@@ -0,0 +1,218 @@
+From ba7b26e69f4bb41f10be444c5fded853330f82b5 Mon Sep 17 00:00:00 2001
+From: Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org>
+Date: Tue, 24 Mar 2009 17:22:51 -0700
+Subject: [PATCH] USB: musb: NAK timeout scheme on bulk RX endpoint
+
+Fixes endpoint starvation issue when more than one bulk QH is
+multiplexed on the reserved bulk RX endpoint, which is normal
+for cases like serial and ethernet adapters.
+
+This patch sets the NAK timeout interval for such QHs, and when
+a timeout triggers the next QH will be scheduled. (This resembles
+the bulk scheduling done in hardware by EHCI, OHCI, and UHCI.)
+
+This scheme doesn't work for devices which are connected to a
+high to full speed tree (transaction translator) as there is
+no NAK timeout interrupt from the musb controller from such
+devices.
+
+Tested with PIO, Inventra DMA, CPPI DMA.
+
+[ dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org: fold in start_urb() update;
+ clarify only for bulk RX; don't accidentally clear WZC bits ]
+
+Signed-off-by: Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org>
+Cc: Felipe Balbi <felipe.balbi-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
+Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh-l3A5Bk7waGM@public.gmane.org>
+---
+ drivers/usb/musb/musb_host.c | 112 ++++++++++++++++++++++++++++++++----------
+ 1 files changed, 85 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
+index 6dbbd07..bd1d5ae 100644
+--- a/drivers/usb/musb/musb_host.c
++++ b/drivers/usb/musb/musb_host.c
+@@ -64,11 +64,8 @@
+ *
+ * - DMA (Mentor/OMAP) ...has at least toggle update problems
+ *
+- * - Still no traffic scheduling code to make NAKing for bulk or control
+- * transfers unable to starve other requests; or to make efficient use
+- * of hardware with periodic transfers. (Note that network drivers
+- * commonly post bulk reads that stay pending for a long time; these
+- * would make very visible trouble.)
++ * - [23-feb-2009] minimal traffic scheduling to avoid bulk RX packet
++ * starvation ... nothing yet for TX, interrupt, or bulk.
+ *
+ * - Not tested with HNP, but some SRP paths seem to behave.
+ *
+@@ -88,11 +85,8 @@
+ *
+ * CONTROL transfers all go through ep0. BULK ones go through dedicated IN
+ * and OUT endpoints ... hardware is dedicated for those "async" queue(s).
+- *
+ * (Yes, bulk _could_ use more of the endpoints than that, and would even
+- * benefit from it ... one remote device may easily be NAKing while others
+- * need to perform transfers in that same direction. The same thing could
+- * be done in software though, assuming dma cooperates.)
++ * benefit from it.)
+ *
+ * INTERUPPT and ISOCHRONOUS transfers are scheduled to the other endpoints.
+ * So far that scheduling is both dumb and optimistic: the endpoint will be
+@@ -201,8 +195,9 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
+ len = urb->iso_frame_desc[0].length;
+ break;
+ default: /* bulk, interrupt */
+- buf = urb->transfer_buffer;
+- len = urb->transfer_buffer_length;
++ /* actual_length may be nonzero on retry paths */
++ buf = urb->transfer_buffer + urb->actual_length;
++ len = urb->transfer_buffer_length - urb->actual_length;
+ }
+
+ DBG(4, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n",
+@@ -1045,7 +1040,8 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb)
+
+ /* NOTE: this code path would be a good place to PAUSE a
+ * control transfer, if another one is queued, so that
+- * ep0 is more likely to stay busy.
++ * ep0 is more likely to stay busy. That's already done
++ * for bulk RX transfers.
+ *
+ * if (qh->ring.next != &musb->control), then
+ * we have a candidate... NAKing is *NOT* an error
+@@ -1197,6 +1193,7 @@ void musb_host_tx(struct musb *musb, u8 epnum)
+ /* NOTE: this code path would be a good place to PAUSE a
+ * transfer, if there's some other (nonperiodic) tx urb
+ * that could use this fifo. (dma complicates it...)
++ * That's already done for bulk RX transfers.
+ *
+ * if (bulk && qh->ring.next != &musb->out_bulk), then
+ * we have a candidate... NAKing is *NOT* an error
+@@ -1358,6 +1355,50 @@ finish:
+
+ #endif
+
++/* Schedule next QH from musb->in_bulk and move the current qh to
++ * the end; avoids starvation for other endpoints.
++ */
++static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep)
++{
++ struct dma_channel *dma;
++ struct urb *urb;
++ void __iomem *mbase = musb->mregs;
++ void __iomem *epio = ep->regs;
++ struct musb_qh *cur_qh, *next_qh;
++ u16 rx_csr;
++
++ musb_ep_select(mbase, ep->epnum);
++ dma = is_dma_capable() ? ep->rx_channel : NULL;
++
++ /* clear nak timeout bit */
++ rx_csr = musb_readw(epio, MUSB_RXCSR);
++ rx_csr |= MUSB_RXCSR_H_WZC_BITS;
++ rx_csr &= ~MUSB_RXCSR_DATAERROR;
++ musb_writew(epio, MUSB_RXCSR, rx_csr);
++
++ cur_qh = first_qh(&musb->in_bulk);
++ if (cur_qh) {
++ urb = next_urb(cur_qh);
++ if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
++ dma->status = MUSB_DMA_STATUS_CORE_ABORT;
++ musb->dma_controller->channel_abort(dma);
++ urb->actual_length += dma->actual_len;
++ dma->actual_len = 0L;
++ }
++ musb_save_toggle(ep, 1, urb);
++
++ /* move cur_qh to end of queue */
++ list_move_tail(&cur_qh->ring, &musb->in_bulk);
++
++ /* get the next qh from musb->in_bulk */
++ next_qh = first_qh(&musb->in_bulk);
++
++ /* set rx_reinit and schedule the next qh */
++ ep->rx_reinit = 1;
++ musb_start_urb(musb, 1, next_qh);
++ }
++}
++
+ /*
+ * Service an RX interrupt for the given IN endpoint; docs cover bulk, iso,
+ * and high-bandwidth IN transfer cases.
+@@ -1421,18 +1462,26 @@ void musb_host_rx(struct musb *musb, u8 epnum)
+ } else if (rx_csr & MUSB_RXCSR_DATAERROR) {
+
+ if (USB_ENDPOINT_XFER_ISOC != qh->type) {
+- /* NOTE this code path would be a good place to PAUSE a
+- * transfer, if there's some other (nonperiodic) rx urb
+- * that could use this fifo. (dma complicates it...)
++ DBG(6, "RX end %d NAK timeout\n", epnum);
++
++ /* NOTE: NAKing is *NOT* an error, so we want to
++ * continue. Except ... if there's a request for
++ * another QH, use that instead of starving it.
+ *
+- * if (bulk && qh->ring.next != &musb->in_bulk), then
+- * we have a candidate... NAKing is *NOT* an error
++ * Devices like Ethernet and serial adapters keep
++ * reads posted at all times, which will starve
++ * other devices without this logic.
+ */
+- DBG(6, "RX end %d NAK timeout\n", epnum);
++ if (usb_pipebulk(urb->pipe)
++ && qh->mux == 1
++ && !list_is_singular(&musb->in_bulk)) {
++ musb_bulk_rx_nak_timeout(musb, hw_ep);
++ return;
++ }
+ musb_ep_select(mbase, epnum);
+- musb_writew(epio, MUSB_RXCSR,
+- MUSB_RXCSR_H_WZC_BITS
+- | MUSB_RXCSR_H_REQPKT);
++ rx_csr |= MUSB_RXCSR_H_WZC_BITS;
++ rx_csr &= ~MUSB_RXCSR_DATAERROR;
++ musb_writew(epio, MUSB_RXCSR, rx_csr);
+
+ goto finish;
+ } else {
+@@ -1756,6 +1805,17 @@ static int musb_schedule(
+ head = &musb->in_bulk;
+ else
+ head = &musb->out_bulk;
++
++ /* Enable bulk RX NAK timeout scheme when bulk requests are
++ * multiplexed. This scheme doen't work in high speed to full
++ * speed scenario as NAK interrupts are not coming from a
++ * full speed device connected to a high speed device.
++ * NAK timeout interval is 8 (128 uframe or 16ms) for HS and
++ * 4 (8 frame or 8ms) for FS device.
++ */
++ if (is_in && qh->dev)
++ qh->intv_reg =
++ (USB_SPEED_HIGH == qh->dev->speed) ? 8 : 4;
+ goto success;
+ } else if (best_end < 0) {
+ return -ENOSPC;
+@@ -1888,13 +1948,11 @@ static int musb_urb_enqueue(
+ *
+ * The downside of disabling this is that transfer scheduling
+ * gets VERY unfair for nonperiodic transfers; a misbehaving
+- * peripheral could make that hurt. Or for reads, one that's
+- * perfectly normal: network and other drivers keep reads
+- * posted at all times, having one pending for a week should
+- * be perfectly safe.
++ * peripheral could make that hurt. That's perfectly normal
++ * for reads from network or serial adapters ... so we have
++ * partial NAKlimit support for bulk RX.
+ *
+- * The upside of disabling it is avoidng transfer scheduling
+- * code to put this aside for while.
++ * The upside of disabling it is simpler transfer scheduling.
+ */
+ interval = 0;
+ }
+--
+1.6.0.4
+