usb: musb: host: unmap the buffer for PIO data transfers
authorMaulik Mankad <x0082077@ti.com>
Fri, 24 Sep 2010 10:44:06 +0000 (13:44 +0300)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 22 Oct 2010 17:21:53 +0000 (10:21 -0700)
The USB stack maps the buffer for DMA if the controller supports DMA.
MUSB controller can perform DMA as well as PIO transfers.
The buffer needs to be unmapped before CPU can perform
PIO data transfers.

Export unmap_urb_for_dma() so that drivers can perform
the DMA unmapping in a sane way.

Signed-off-by: Maulik Mankad <x0082077@ti.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/core/hcd.c
drivers/usb/musb/musb_host.c
include/linux/usb/hcd.h

index 5cca00a6d09d61dfe31859b866463b80091451a3..cb2d894321da7d86424c81731ed3a4bda214cbcb 100644 (file)
@@ -1263,7 +1263,7 @@ static void hcd_free_coherent(struct usb_bus *bus, dma_addr_t *dma_handle,
        *dma_handle = 0;
 }
 
-static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
+void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
 {
        enum dma_data_direction dir;
 
@@ -1307,6 +1307,7 @@ static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
                        URB_DMA_MAP_SG | URB_DMA_MAP_PAGE |
                        URB_DMA_MAP_SINGLE | URB_MAP_LOCAL);
 }
+EXPORT_SYMBOL_GPL(unmap_urb_for_dma);
 
 static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
                           gfp_t mem_flags)
index 9e65c47cc98b95761daba7186dd180550b954def..62e39fc5721143b8934df7dbec05686385db7a90 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"
@@ -1332,6 +1333,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 +1755,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 " : "");
index 3b571f1ffbb3aee4b80881076d6ca6b0042840d9..fe89f7c298aa06ed8f4abe4bbb55c09147671281 100644 (file)
@@ -329,6 +329,7 @@ extern int usb_hcd_submit_urb(struct urb *urb, gfp_t mem_flags);
 extern int usb_hcd_unlink_urb(struct urb *urb, int status);
 extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb,
                int status);
+extern void unmap_urb_for_dma(struct usb_hcd *, struct urb *);
 extern void usb_hcd_flush_endpoint(struct usb_device *udev,
                struct usb_host_endpoint *ep);
 extern void usb_hcd_disable_endpoint(struct usb_device *udev,