aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartyn Welch <martyn.welch@ge.com>2014-02-06 08:35:36 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-15 14:53:39 -0500
commita2a720e15f59be60c7ae1c58b5b4ac1003dd5078 (patch)
treecdc8df4e60b7c896fcfbfd664c088edb14a8c1aa
parentf33b215549938f89aebf862b942366d2aa41c191 (diff)
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>
-rw-r--r--drivers/vme/bridges/vme_ca91cx42.c29
-rw-r--r--drivers/vme/bridges/vme_tsi148.c18
2 files changed, 23 insertions, 24 deletions
diff --git a/drivers/vme/bridges/vme_ca91cx42.c b/drivers/vme/bridges/vme_ca91cx42.c
index a06edbfa95ca..92b5719cd99b 100644
--- a/drivers/vme/bridges/vme_ca91cx42.c
+++ b/drivers/vme/bridges/vme_ca91cx42.c
@@ -869,14 +869,13 @@ static ssize_t ca91cx42_master_read(struct vme_master_resource *image,
869 869
870 spin_lock(&image->lock); 870 spin_lock(&image->lock);
871 871
872 /* The following code handles VME address alignment problem 872 /* The following code handles VME address alignment. We cannot use
873 * in order to assure the maximal data width cycle. 873 * memcpy_xxx here because it may cut data transfers in to 8-bit
874 * We cannot use memcpy_xxx directly here because it 874 * cycles when D16 or D32 cycles are required on the VME bus.
875 * may cut data transfer in 8-bits cycles, thus making 875 * On the other hand, the bridge itself assures that the maximum data
876 * D16 cycle impossible. 876 * cycle configured for the transfer is used and splits it
877 * From the other hand, the bridge itself assures that 877 * automatically for non-aligned addresses, so we don't want the
878 * maximal configured data cycle is used and splits it 878 * overhead of needlessly forcing small transfers for the entire cycle.
879 * automatically for non-aligned addresses.
880 */ 879 */
881 if ((uintptr_t)addr & 0x1) { 880 if ((uintptr_t)addr & 0x1) {
882 *(u8 *)buf = ioread8(addr); 881 *(u8 *)buf = ioread8(addr);
@@ -896,9 +895,9 @@ static ssize_t ca91cx42_master_read(struct vme_master_resource *image,
896 } 895 }
897 896
898 count32 = (count - done) & ~0x3; 897 count32 = (count - done) & ~0x3;
899 if (count32 > 0) { 898 while (done < count32) {
900 memcpy_fromio(buf + done, addr + done, (unsigned int)count); 899 *(u32 *)(buf + done) = ioread32(addr + done);
901 done += count32; 900 done += 4;
902 } 901 }
903 902
904 if ((count - done) & 0x2) { 903 if ((count - done) & 0x2) {
@@ -930,7 +929,7 @@ static ssize_t ca91cx42_master_write(struct vme_master_resource *image,
930 spin_lock(&image->lock); 929 spin_lock(&image->lock);
931 930
932 /* Here we apply for the same strategy we do in master_read 931 /* Here we apply for the same strategy we do in master_read
933 * function in order to assure D16 cycle when required. 932 * function in order to assure the correct cycles.
934 */ 933 */
935 if ((uintptr_t)addr & 0x1) { 934 if ((uintptr_t)addr & 0x1) {
936 iowrite8(*(u8 *)buf, addr); 935 iowrite8(*(u8 *)buf, addr);
@@ -950,9 +949,9 @@ static ssize_t ca91cx42_master_write(struct vme_master_resource *image,
950 } 949 }
951 950
952 count32 = (count - done) & ~0x3; 951 count32 = (count - done) & ~0x3;
953 if (count32 > 0) { 952 while (done < count32) {
954 memcpy_toio(addr + done, buf + done, count32); 953 iowrite32(*(u32 *)(buf + done), addr + done);
955 done += count32; 954 done += 4;
956 } 955 }
957 956
958 if ((count - done) & 0x2) { 957 if ((count - done) & 0x2) {
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,
1276 spin_lock(&image->lock); 1276 spin_lock(&image->lock);
1277 1277
1278 /* The following code handles VME address alignment. We cannot use 1278 /* The following code handles VME address alignment. We cannot use
1279 * memcpy_xxx directly here because it may cut small data transfers in 1279 * memcpy_xxx here because it may cut data transfers in to 8-bit
1280 * to 8-bit cycles, thus making D16 cycle impossible. 1280 * cycles when D16 or D32 cycles are required on the VME bus.
1281 * On the other hand, the bridge itself assures that the maximum data 1281 * On the other hand, the bridge itself assures that the maximum data
1282 * cycle configured for the transfer is used and splits it 1282 * cycle configured for the transfer is used and splits it
1283 * automatically for non-aligned addresses, so we don't want the 1283 * 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,
1301 } 1301 }
1302 1302
1303 count32 = (count - done) & ~0x3; 1303 count32 = (count - done) & ~0x3;
1304 if (count32 > 0) { 1304 while (done < count32) {
1305 memcpy_fromio(buf + done, addr + done, count32); 1305 *(u32 *)(buf + done) = ioread32(addr + done);
1306 done += count32; 1306 done += 4;
1307 } 1307 }
1308 1308
1309 if ((count - done) & 0x2) { 1309 if ((count - done) & 0x2) {
@@ -1363,7 +1363,7 @@ static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
1363 spin_lock(&image->lock); 1363 spin_lock(&image->lock);
1364 1364
1365 /* Here we apply for the same strategy we do in master_read 1365 /* Here we apply for the same strategy we do in master_read
1366 * function in order to assure D16 cycle when required. 1366 * function in order to assure the correct cycles.
1367 */ 1367 */
1368 if ((uintptr_t)addr & 0x1) { 1368 if ((uintptr_t)addr & 0x1) {
1369 iowrite8(*(u8 *)buf, addr); 1369 iowrite8(*(u8 *)buf, addr);
@@ -1383,9 +1383,9 @@ static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
1383 } 1383 }
1384 1384
1385 count32 = (count - done) & ~0x3; 1385 count32 = (count - done) & ~0x3;
1386 if (count32 > 0) { 1386 while (done < count32) {
1387 memcpy_toio(addr + done, buf + done, count32); 1387 iowrite32(*(u32 *)(buf + done), addr + done);
1388 done += count32; 1388 done += 4;
1389 } 1389 }
1390 1390
1391 if ((count - done) & 0x2) { 1391 if ((count - done) & 0x2) {