diff options
author | Arnd Bergmann <arnd@arndb.de> | 2009-06-19 04:41:19 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2009-06-19 08:58:13 -0400 |
commit | 32a9ff9cc55b42543a84bca90b070df92af72671 (patch) | |
tree | ce4d38741f8b78f5e4f193f5032846743e76b183 /lib/checksum.c | |
parent | fcec9bf12442d0cd50d6cee125d168cfc3f37c5e (diff) |
lib/checksum.c: fix endianess bug
The new generic checksum code has a small dependency on endianess and
worked only on big-endian systems. I could not find a nice efficient
way to express this, so I added an #ifdef. Using
'result += le16_to_cpu(*buff);' would have worked as well, but
would be slightly less efficient on big-endian systems and IMHO
would not be clearer.
Also fix a bug that prevents this from working on 64-bit machines.
If you have a 64-bit CPU and want to use the generic checksum
code, you should probably do some more optimizations anyway, but
at least the code should not break.
Reported-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'lib/checksum.c')
-rw-r--r-- | lib/checksum.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/lib/checksum.c b/lib/checksum.c index 12e5a1c91cda..b2e2fd468461 100644 --- a/lib/checksum.c +++ b/lib/checksum.c | |||
@@ -55,7 +55,11 @@ static unsigned int do_csum(const unsigned char *buff, int len) | |||
55 | goto out; | 55 | goto out; |
56 | odd = 1 & (unsigned long) buff; | 56 | odd = 1 & (unsigned long) buff; |
57 | if (odd) { | 57 | if (odd) { |
58 | #ifdef __LITTLE_ENDIAN | ||
58 | result = *buff; | 59 | result = *buff; |
60 | #else | ||
61 | result += (*buff << 8); | ||
62 | #endif | ||
59 | len--; | 63 | len--; |
60 | buff++; | 64 | buff++; |
61 | } | 65 | } |
@@ -71,7 +75,7 @@ static unsigned int do_csum(const unsigned char *buff, int len) | |||
71 | if (count) { | 75 | if (count) { |
72 | unsigned long carry = 0; | 76 | unsigned long carry = 0; |
73 | do { | 77 | do { |
74 | unsigned long w = *(unsigned long *) buff; | 78 | unsigned long w = *(unsigned int *) buff; |
75 | count--; | 79 | count--; |
76 | buff += 4; | 80 | buff += 4; |
77 | result += carry; | 81 | result += carry; |
@@ -87,7 +91,11 @@ static unsigned int do_csum(const unsigned char *buff, int len) | |||
87 | } | 91 | } |
88 | } | 92 | } |
89 | if (len & 1) | 93 | if (len & 1) |
94 | #ifdef __LITTLE_ENDIAN | ||
95 | result += *buff; | ||
96 | #else | ||
90 | result += (*buff << 8); | 97 | result += (*buff << 8); |
98 | #endif | ||
91 | result = from32to16(result); | 99 | result = from32to16(result); |
92 | if (odd) | 100 | if (odd) |
93 | result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); | 101 | result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); |