]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
[PATCH] ARM: OMAP: USB peripheral DMA update'
authorDavid Brownell <dbrownell@users.sourceforge.net>
Fri, 14 Oct 2005 19:31:56 +0000 (22:31 +0300)
committerTony Lindgren <tony@atomide.com>
Fri, 14 Oct 2005 19:31:56 +0000 (22:31 +0300)
The change to make DMA work two bytes at a time omitted an important
tweak that affects the file_storage gadget:  it needs to recognize when
the host writes an odd number of bytes.  (The change was made to get
past a controller lockup that seemed to be caused by byte-at-a-time DMA
using too much bandwidth on one of the I/O busses during network stress
testing.  The network layer ignores such extra bytes.)

This patch resolves that issue by checking the relevant bit and adjusting
the rx byte count, so that for example a legal 13 byte request doesn't
morph into an illegal 14 byte one any more.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Tony Lindgren <tony@atomide.com>
drivers/usb/gadget/omap_udc.c

index ff5533e6956047fd25688d3fd37af3f23421b38f..d1b797bff9c1cf955cb2948ed24e5dc16551615d 100644 (file)
@@ -691,7 +691,7 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req)
 }
 
 static void
-finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status)
+finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status, int one)
 {
        u16     count;
 
@@ -699,6 +699,8 @@ finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status)
                ep->dma_counter = (u16) (req->req.dma + req->req.actual);
        count = dma_dest_len(ep, req->req.dma + req->req.actual);
        count += req->req.actual;
+       if (one)
+               count--;
        if (count <= req->req.length)
                req->req.actual = count;
 
@@ -747,7 +749,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src)
                if (!list_empty(&ep->queue)) {
                        req = container_of(ep->queue.next,
                                        struct omap_req, queue);
-                       finish_out_dma(ep, req, 0);
+                       finish_out_dma(ep, req, 0, dman_stat & UDC_DMA_RX_SB);
                }
                UDC_IRQ_SRC_REG = UDC_RXN_EOT;
 
@@ -925,7 +927,7 @@ static void dma_channel_release(struct omap_ep *ep)
                while (UDC_RXDMA_CFG_REG & mask)
                        udelay(10);
                if (req)
-                       finish_out_dma(ep, req, -ECONNRESET);
+                       finish_out_dma(ep, req, -ECONNRESET, 0);
        }
        omap_free_dma(ep->lch);
        ep->dma_channel = 0;