VME: Correct read/write alignment algorithm
authorMartyn Welch <martyn.welch@ge.com>
Fri, 7 Feb 2014 15:48:56 +0000 (15:48 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Feb 2014 16:16:14 +0000 (08:16 -0800)
In order to ensure the correct width cycles on the VME bus, the VME bridge
drivers implement an algorithm to utilise the largest possible width reads and
writes whilst maintaining natural alignment constraints. The algorithm
currently looks at the start address rather than the current read/write address
when determining whether a 16-bit width cycle is required to get to 32-bit
alignment.  This results in incorrect alignment,

Reported-by: Jim Strouth <james.strouth@ge.com>
Tested-by: Jim Strouth <james.strouth@ge.com>
Signed-off-by: Martyn Welch <martyn.welch@ge.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/vme/bridges/vme_ca91cx42.c
drivers/vme/bridges/vme_tsi148.c

index a06edbfa95ca6b894ce1ee01ad6ab10241937e5b..1b5d48c578e19208fbb2ef06f9e4788f93a0f5f5 100644 (file)
@@ -884,7 +884,7 @@ static ssize_t ca91cx42_master_read(struct vme_master_resource *image,
                if (done == count)
                        goto out;
        }
-       if ((uintptr_t)addr & 0x2) {
+       if ((uintptr_t)(addr + done) & 0x2) {
                if ((count - done) < 2) {
                        *(u8 *)(buf + done) = ioread8(addr + done);
                        done += 1;
@@ -938,7 +938,7 @@ static ssize_t ca91cx42_master_write(struct vme_master_resource *image,
                if (done == count)
                        goto out;
        }
-       if ((uintptr_t)addr & 0x2) {
+       if ((uintptr_t)(addr + done) & 0x2) {
                if ((count - done) < 2) {
                        iowrite8(*(u8 *)(buf + done), addr + done);
                        done += 1;
index 16830d8b777cbd8f68e7751dd37729bc2fd681f5..9911cd5fddb58415b56ad23efadef06504b822f3 100644 (file)
@@ -1289,7 +1289,7 @@ static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
                if (done == count)
                        goto out;
        }
-       if ((uintptr_t)addr & 0x2) {
+       if ((uintptr_t)(addr + done) & 0x2) {
                if ((count - done) < 2) {
                        *(u8 *)(buf + done) = ioread8(addr + done);
                        done += 1;
@@ -1371,7 +1371,7 @@ static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
                if (done == count)
                        goto out;
        }
-       if ((uintptr_t)addr & 0x2) {
+       if ((uintptr_t)(addr + done) & 0x2) {
                if ((count - done) < 2) {
                        iowrite8(*(u8 *)(buf + done), addr + done);
                        done += 1;