summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Howard <ghoward@sgi.com>2005-08-15 22:00:00 +0200
committerTony Luck <tony.luck@intel.com>2005-08-15 23:17:49 +0200
commit1a402aaca51b7d56e62348f50a426c531b6bc29e (patch)
treef11678902e54db1205bad348e2a6cdb2017ccfbe
parentRevert PCIBIOS_MIN_IO changes for 2.6.13 (diff)
downloadlinux-1a402aaca51b7d56e62348f50a426c531b6bc29e.tar.xz
linux-1a402aaca51b7d56e62348f50a426c531b6bc29e.zip
[IA64-SGI] fix unaligned memory access in snsc_event.c
It's been pointed out that environmental events from the system controllers on Altix machines cause the kernel to complain about unaligned memory accesses. This turns out to be because "be32_to_cpup()" didn't do everything I thought/hoped it did. I've added calls to pull the offending integers out of the buffers using get_unaligned() before feeding them to be32_to_cpup(). Signed-off-by: Greg Howard <ghoward@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r--drivers/char/snsc_event.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
index d692af57213a..baaa365285fa 100644
--- a/drivers/char/snsc_event.c
+++ b/drivers/char/snsc_event.c
@@ -19,6 +19,7 @@
#include <linux/sched.h>
#include <linux/byteorder/generic.h>
#include <asm/sn/sn_sal.h>
+#include <asm/unaligned.h>
#include "snsc.h"
static struct subch_data_s *event_sd;
@@ -62,13 +63,16 @@ static int
scdrv_parse_event(char *event, int *src, int *code, int *esp_code, char *desc)
{
char *desc_end;
+ __be32 from_buf;
/* record event source address */
- *src = be32_to_cpup((__be32 *)event);
+ from_buf = get_unaligned((__be32 *)event);
+ *src = be32_to_cpup(&from_buf);
event += 4; /* move on to event code */
/* record the system controller's event code */
- *code = be32_to_cpup((__be32 *)event);
+ from_buf = get_unaligned((__be32 *)event);
+ *code = be32_to_cpup(&from_buf);
event += 4; /* move on to event arguments */
/* how many arguments are in the packet? */
@@ -82,7 +86,8 @@ scdrv_parse_event(char *event, int *src, int *code, int *esp_code, char *desc)
/* not an integer argument, so give up */
return -1;
}
- *esp_code = be32_to_cpup((__be32 *)event);
+ from_buf = get_unaligned((__be32 *)event);
+ *esp_code = be32_to_cpup(&from_buf);
event += 4;
/* parse out the event description */