summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2010-02-02 15:31:02 +0000
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-02 14:54:53 -0800
commitdb8516f61b481e82cec398474ed716d926de7f94 (patch)
tree845a2c53e10bd6716ef51f0d675050b6c5c544d7 /drivers/usb/host
parent9714080d20f2ec4b671a06ce69367d91fa9e227e (diff)
downloadop-kernel-dev-db8516f61b481e82cec398474ed716d926de7f94.zip
op-kernel-dev-db8516f61b481e82cec398474ed716d926de7f94.tar.gz
USB: isp1760: Flush the D-cache for the pipe-in transfer buffers
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>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/isp1760-hcd.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index 27b8f7c..9f01293 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -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);
OpenPOWER on IntegriCloud