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>
This commit is contained in:
parent
fcec9bf124
commit
32a9ff9cc5
@ -55,7 +55,11 @@ static unsigned int do_csum(const unsigned char *buff, int len)
|
|||||||
goto out;
|
goto out;
|
||||||
odd = 1 & (unsigned long) buff;
|
odd = 1 & (unsigned long) buff;
|
||||||
if (odd) {
|
if (odd) {
|
||||||
|
#ifdef __LITTLE_ENDIAN
|
||||||
result = *buff;
|
result = *buff;
|
||||||
|
#else
|
||||||
|
result += (*buff << 8);
|
||||||
|
#endif
|
||||||
len--;
|
len--;
|
||||||
buff++;
|
buff++;
|
||||||
}
|
}
|
||||||
@ -71,7 +75,7 @@ static unsigned int do_csum(const unsigned char *buff, int len)
|
|||||||
if (count) {
|
if (count) {
|
||||||
unsigned long carry = 0;
|
unsigned long carry = 0;
|
||||||
do {
|
do {
|
||||||
unsigned long w = *(unsigned long *) buff;
|
unsigned long w = *(unsigned int *) buff;
|
||||||
count--;
|
count--;
|
||||||
buff += 4;
|
buff += 4;
|
||||||
result += carry;
|
result += carry;
|
||||||
@ -87,7 +91,11 @@ static unsigned int do_csum(const unsigned char *buff, int len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (len & 1)
|
if (len & 1)
|
||||||
|
#ifdef __LITTLE_ENDIAN
|
||||||
|
result += *buff;
|
||||||
|
#else
|
||||||
result += (*buff << 8);
|
result += (*buff << 8);
|
||||||
|
#endif
|
||||||
result = from32to16(result);
|
result = from32to16(result);
|
||||||
if (odd)
|
if (odd)
|
||||||
result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
|
result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
|
||||||
|
Loading…
Reference in New Issue
Block a user