]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/usb/musb/musb_host.c
Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind...
[karo-tx-linux.git] / drivers / usb / musb / musb_host.c
index 9e65c47cc98b95761daba7186dd180550b954def..4d5bcb4e14d24b0c8358ce8f1f66f5a4aac5d384 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/dma-mapping.h>
 
 #include "musb_core.h"
 #include "musb_host.h"
@@ -1119,6 +1120,7 @@ void musb_host_tx(struct musb *musb, u8 epnum)
        u32                     status = 0;
        void __iomem            *mbase = musb->mregs;
        struct dma_channel      *dma;
+       bool                    transfer_pending = false;
 
        musb_ep_select(mbase, epnum);
        tx_csr = musb_readw(epio, MUSB_TXCSR);
@@ -1279,7 +1281,7 @@ void musb_host_tx(struct musb *musb, u8 epnum)
                                offset = d->offset;
                                length = d->length;
                        }
-               } else if (dma) {
+               } else if (dma && urb->transfer_buffer_length == qh->offset) {
                        done = true;
                } else {
                        /* see if we need to send more data, or ZLP */
@@ -1292,6 +1294,7 @@ void musb_host_tx(struct musb *musb, u8 epnum)
                        if (!done) {
                                offset = qh->offset;
                                length = urb->transfer_buffer_length - offset;
+                               transfer_pending = true;
                        }
                }
        }
@@ -1311,7 +1314,7 @@ void musb_host_tx(struct musb *musb, u8 epnum)
                urb->actual_length = qh->offset;
                musb_advance_schedule(musb, urb, hw_ep, USB_DIR_OUT);
                return;
-       } else  if (usb_pipeisoc(pipe) && dma) {
+       } else if ((usb_pipeisoc(pipe) || transfer_pending) && dma) {
                if (musb_tx_dma_program(musb->dma_controller, hw_ep, qh, urb,
                                offset, length)) {
                        if (is_cppi_enabled() || tusb_dma_omap())
@@ -1332,6 +1335,8 @@ void musb_host_tx(struct musb *musb, u8 epnum)
         */
        if (length > qh->maxpacket)
                length = qh->maxpacket;
+       /* Unmap the buffer so that CPU can use it */
+       unmap_urb_for_dma(musb_to_hcd(musb), urb);
        musb_write_fifo(hw_ep, length, urb->transfer_buffer + offset);
        qh->segsize = length;
 
@@ -1752,6 +1757,8 @@ void musb_host_rx(struct musb *musb, u8 epnum)
 #endif /* Mentor DMA */
 
                if (!dma) {
+                       /* Unmap the buffer so that CPU can use it */
+                       unmap_urb_for_dma(musb_to_hcd(musb), urb);
                        done = musb_host_packet_rx(musb, urb,
                                        epnum, iso_err);
                        DBG(6, "read %spacket\n", done ? "last " : "");