USB: isp1760: Flush the D-cache for the pipe-in transfer buffers
authorCatalin Marinas <catalin.marinas@arm.com>
Tue, 2 Feb 2010 15:31:02 +0000 (15:31 +0000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 2 Mar 2010 22:54:53 +0000 (14:54 -0800)
When the HDC driver writes the data to the transfer buffers it pollutes
the D-cache (unlike DMA drivers where the device writes the data). If
the corresponding pages get mapped into user space, there are no
additional cache flushing operations performed and this causes random
user space faults on architectures with separate I and D caches
(Harvard) or those with aliasing D-cache.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Matthew Dharm <mdharm-kernel@one-eyed-alien.net>
Cc: Greg KH <greg@kroah.com>
Cc: Sebastian Siewior <bigeasy@linutronix.de>
Cc: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/host/isp1760-hcd.c

index 27b8f7cb4471e8399f8262feaca409388b11957f..9f01293600b0559e9d30ca6a11ae2244e102189b 100644 (file)
@@ -17,7 +17,9 @@
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/mm.h>
 #include <asm/unaligned.h>
+#include <asm/cacheflush.h>
 
 #include "../core/hcd.h"
 #include "isp1760-hcd.h"
@@ -904,6 +906,14 @@ __acquires(priv->lock)
                        status = 0;
        }
 
+       if (usb_pipein(urb->pipe) && usb_pipetype(urb->pipe) != PIPE_CONTROL) {
+               void *ptr;
+               for (ptr = urb->transfer_buffer;
+                    ptr < urb->transfer_buffer + urb->transfer_buffer_length;
+                    ptr += PAGE_SIZE)
+                       flush_dcache_page(virt_to_page(ptr));
+       }
+
        /* complete() can reenter this HCD */
        usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb);
        spin_unlock(&priv->lock);