summaryrefslogtreecommitdiffstats
path: root/drivers/vme/bridges/vme_tsi148.c
diff options
context:
space:
mode:
authorMartyn Welch <martyn.welch@ge.com>2014-02-06 14:35:36 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-15 20:53:39 +0100
commita2a720e15f59be60c7ae1c58b5b4ac1003dd5078 (patch)
treecdc8df4e60b7c896fcfbfd664c088edb14a8c1aa /drivers/vme/bridges/vme_tsi148.c
parentTools: hv: vssdaemon: Ignore VFAT mounts during the Freeze operation (diff)
downloadlinux-a2a720e15f59be60c7ae1c58b5b4ac1003dd5078.tar.xz
linux-a2a720e15f59be60c7ae1c58b5b4ac1003dd5078.zip
VME: Stop using memcpy_[to|from]io() due to unwanted behaviour
The ca91cx42 and tsi148 VME bridges use the width of reads and writes on the PCI bus in part to control the width of the cycles on the VME bus. It is important that we can control the width of cycles on the VME bus as some VME hardware requires cycles of a specific width. The memcpy_toio() and memcpy_fromio() functions do not provide sufficient control, so instead loop using ioread functions. Reported-by: Michael Kenney <mfkenney@gmail.com> Signed-off-by: Martyn Welch <martyn.welch@ge.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to '')
-rw-r--r--drivers/vme/bridges/vme_tsi148.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c
index 16830d8b777c..21ac513486f6 100644
--- a/drivers/vme/bridges/vme_tsi148.c
+++ b/drivers/vme/bridges/vme_tsi148.c
@@ -1276,8 +1276,8 @@ static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
spin_lock(&image->lock);
/* The following code handles VME address alignment. We cannot use
- * memcpy_xxx directly here because it may cut small data transfers in
- * to 8-bit cycles, thus making D16 cycle impossible.
+ * memcpy_xxx here because it may cut data transfers in to 8-bit
+ * cycles when D16 or D32 cycles are required on the VME bus.
* On the other hand, the bridge itself assures that the maximum data
* cycle configured for the transfer is used and splits it
* automatically for non-aligned addresses, so we don't want the
@@ -1301,9 +1301,9 @@ static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
}
count32 = (count - done) & ~0x3;
- if (count32 > 0) {
- memcpy_fromio(buf + done, addr + done, count32);
- done += count32;
+ while (done < count32) {
+ *(u32 *)(buf + done) = ioread32(addr + done);
+ done += 4;
}
if ((count - done) & 0x2) {
@@ -1363,7 +1363,7 @@ static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
spin_lock(&image->lock);
/* Here we apply for the same strategy we do in master_read
- * function in order to assure D16 cycle when required.
+ * function in order to assure the correct cycles.
*/
if ((uintptr_t)addr & 0x1) {
iowrite8(*(u8 *)buf, addr);
@@ -1383,9 +1383,9 @@ static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
}
count32 = (count - done) & ~0x3;
- if (count32 > 0) {
- memcpy_toio(addr + done, buf + done, count32);
- done += count32;
+ while (done < count32) {
+ iowrite32(*(u32 *)(buf + done), addr + done);
+ done += 4;
}
if ((count - done) & 0x2) {