[parisc-linux-cvs] linux willy

Matthew Wilcox matthew@wil.cx
Thu, 12 Apr 2001 15:14:36 +0100


On Wed, Apr 11, 2001 at 10:41:55PM -0600, Ryan Bradetich wrote:
> The memcpy_toio() broke scsi on my C200.  [Note: I was getting
> unaligned data reference traps (28)]  I tracked it to down to
> the memcpy_toio function.  The following patch fixed the
> problem on my C200 for the memcpy_toio(). [Note: I fixed the
> problem in the other two functions as well.]  I have not
> committed this fix, because I'm not sure if it is correct for
> the general case and wanted you to review it.

Yeesh.  I tried scsi on my 712.... I don't understand how it could
have worked though.  Thanks for the debugging work.  I'm going to
commit this:

(the extra casts are so we don't do ++ on a (void *) which is a
fundamentally meaningless thing to do anyway.  The extra brackets in
the if()s  are because gcc warned :-))

Index: arch/parisc/lib/io.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/lib/io.c,v
retrieving revision 1.1
diff -u -p -r1.1 io.c
--- io.c	2001/04/11 19:12:50	1.1
+++ io.c	2001/04/12 13:59:30
@@ -14,20 +14,23 @@
  */
 void memcpy_toio(unsigned long dest, const void *src, int count)
 {
-	if (dest % 3 != (unsigned long)src % 3)
+	if ((dest & 3) != ((unsigned long)src & 3))
 		goto bytecopy;
-	while (dest % 3) {
-		writeb(*(char *)src++, dest++);
+	while (dest & 3) {
+		writeb(*(char *)src, dest++);
+		((char *)src)++;
 		count--;
 	}
 	while (count > 3) {
-		writel(*(u32 *)src++, dest);
+		writel(*(u32 *)src, dest);
+		(unsigned long) src += 4;
 		dest += 4;
 		count -= 4;
 	}
  bytecopy:
 	while (count--) {
-		writeb(*(char *)src++, dest++);
+		writeb(*(char *)src, dest++);
+		((char *)src)++;
 	}
 }
 
@@ -37,9 +40,9 @@ void memcpy_toio(unsigned long dest, con
  */
 void memcpy_fromio(const void *dest, unsigned long src, int count)
 {
-	if ((unsigned long)dest % 3 != src % 3)
+	if (((unsigned long)dest & 3) != (src & 3))
 		goto bytecopy;
-	while (src % 3) {
+	while (src & 3) {
 		*(char *)dest = readb(src++);
 		((char *)dest)++;
 		count--;
@@ -53,6 +56,7 @@ void memcpy_fromio(const void *dest, uns
  bytecopy:
 	while (count--) {
 		*(char *)dest = readb(src++);
+		((char *)dest)++;
 	}
 }
 
@@ -63,7 +67,7 @@ void memcpy_fromio(const void *dest, uns
 void memset_io(unsigned long dest, char fill, int count)
 {
 	u32 fill32 = (fill << 24) | (fill << 16) | (fill << 8) | fill;
-	while (dest % 3) {
+	while (dest & 3) {
 		writeb(fill, dest++);
 		count--;
 	}


-- 
Revolutions do not require corporate support.