[IA64] Fix __{in,out}s{w,l} to handle unaligned data
authorJames Bottomley <James.Bottomley@HansenPartnership.com>
Fri, 22 Aug 2008 21:15:22 +0000 (16:15 -0500)
committerTony Luck <tony.luck@intel.com>
Mon, 25 Aug 2008 18:23:13 +0000 (11:23 -0700)
Some ia64 systems produce several repeats of kernel messages like this:

 kernel unaligned access to 0xe000000644220466, ip=0xa000000100516fa1

This was tracked to ide code using the __cmd[] field in "struct request"
via the __outsw() function.  __cmd[] is a char array, so is not guaranteed
to be properly aligned when accessed as words.

Tested-by: Nishanth Aravamudan <nacc@us.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
arch/ia64/include/asm/io.h

index 260a85ac9d6a6bc4a1784520522e94a686283574..7f257507cd86f3b0a301bc69b9db51fb7cf6d2fa 100644 (file)
@@ -19,6 +19,8 @@
  * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
  */
 
+#include <asm/unaligned.h>
+
 /* We don't use IO slowdowns on the ia64, but.. */
 #define __SLOW_DOWN_IO do { } while (0)
 #define SLOW_DOWN_IO   do { } while (0)
@@ -241,7 +243,7 @@ __insw (unsigned long port, void *dst, unsigned long count)
        unsigned short *dp = dst;
 
        while (count--)
-               *dp++ = platform_inw(port);
+               put_unaligned(platform_inw(port), dp++);
 }
 
 static inline void
@@ -250,7 +252,7 @@ __insl (unsigned long port, void *dst, unsigned long count)
        unsigned int *dp = dst;
 
        while (count--)
-               *dp++ = platform_inl(port);
+               put_unaligned(platform_inl(port), dp++);
 }
 
 static inline void
@@ -268,7 +270,7 @@ __outsw (unsigned long port, const void *src, unsigned long count)
        const unsigned short *sp = src;
 
        while (count--)
-               platform_outw(*sp++, port);
+               platform_outw(get_unaligned(sp++), port);
 }
 
 static inline void
@@ -277,7 +279,7 @@ __outsl (unsigned long port, const void *src, unsigned long count)
        const unsigned int *sp = src;
 
        while (count--)
-               platform_outl(*sp++, port);
+               platform_outl(get_unaligned(sp++), port);
 }
 
 /*