diff options
Diffstat (limited to 'lib/crc32.c')
| -rw-r--r-- | lib/crc32.c | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/lib/crc32.c b/lib/crc32.c index 02e3b31b3a79..4855995fcde9 100644 --- a/lib/crc32.c +++ b/lib/crc32.c | |||
| @@ -25,16 +25,19 @@ | |||
| 25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| 26 | #include <linux/compiler.h> | 26 | #include <linux/compiler.h> |
| 27 | #include <linux/types.h> | 27 | #include <linux/types.h> |
| 28 | #include <linux/slab.h> | ||
| 29 | #include <linux/init.h> | 28 | #include <linux/init.h> |
| 30 | #include <asm/atomic.h> | 29 | #include <asm/atomic.h> |
| 31 | #include "crc32defs.h" | 30 | #include "crc32defs.h" |
| 32 | #if CRC_LE_BITS == 8 | 31 | #if CRC_LE_BITS == 8 |
| 33 | #define tole(x) __constant_cpu_to_le32(x) | 32 | # define tole(x) __constant_cpu_to_le32(x) |
| 34 | #define tobe(x) __constant_cpu_to_be32(x) | ||
| 35 | #else | 33 | #else |
| 36 | #define tole(x) (x) | 34 | # define tole(x) (x) |
| 37 | #define tobe(x) (x) | 35 | #endif |
| 36 | |||
| 37 | #if CRC_BE_BITS == 8 | ||
| 38 | # define tobe(x) __constant_cpu_to_be32(x) | ||
| 39 | #else | ||
| 40 | # define tobe(x) (x) | ||
| 38 | #endif | 41 | #endif |
| 39 | #include "crc32table.h" | 42 | #include "crc32table.h" |
| 40 | 43 | ||
| @@ -45,33 +48,37 @@ MODULE_LICENSE("GPL"); | |||
| 45 | #if CRC_LE_BITS == 8 || CRC_BE_BITS == 8 | 48 | #if CRC_LE_BITS == 8 || CRC_BE_BITS == 8 |
| 46 | 49 | ||
| 47 | static inline u32 | 50 | static inline u32 |
| 48 | crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 *tab) | 51 | crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256]) |
| 49 | { | 52 | { |
| 50 | # ifdef __LITTLE_ENDIAN | 53 | # ifdef __LITTLE_ENDIAN |
| 51 | # define DO_CRC(x) crc = tab[(crc ^ (x)) & 255 ] ^ (crc >> 8) | 54 | # define DO_CRC(x) crc = tab[0][(crc ^ (x)) & 255] ^ (crc >> 8) |
| 55 | # define DO_CRC4 crc = tab[3][(crc) & 255] ^ \ | ||
| 56 | tab[2][(crc >> 8) & 255] ^ \ | ||
| 57 | tab[1][(crc >> 16) & 255] ^ \ | ||
| 58 | tab[0][(crc >> 24) & 255] | ||
| 52 | # else | 59 | # else |
| 53 | # define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc << 8) | 60 | # define DO_CRC(x) crc = tab[0][((crc >> 24) ^ (x)) & 255] ^ (crc << 8) |
| 61 | # define DO_CRC4 crc = tab[0][(crc) & 255] ^ \ | ||
| 62 | tab[1][(crc >> 8) & 255] ^ \ | ||
| 63 | tab[2][(crc >> 16) & 255] ^ \ | ||
| 64 | tab[3][(crc >> 24) & 255] | ||
| 54 | # endif | 65 | # endif |
| 55 | const u32 *b = (const u32 *)buf; | 66 | const u32 *b; |
| 56 | size_t rem_len; | 67 | size_t rem_len; |
| 57 | 68 | ||
| 58 | /* Align it */ | 69 | /* Align it */ |
| 59 | if (unlikely((long)b & 3 && len)) { | 70 | if (unlikely((long)buf & 3 && len)) { |
| 60 | u8 *p = (u8 *)b; | ||
| 61 | do { | 71 | do { |
| 62 | DO_CRC(*p++); | 72 | DO_CRC(*buf++); |
| 63 | } while ((--len) && ((long)p)&3); | 73 | } while ((--len) && ((long)buf)&3); |
| 64 | b = (u32 *)p; | ||
| 65 | } | 74 | } |
| 66 | rem_len = len & 3; | 75 | rem_len = len & 3; |
| 67 | /* load data 32 bits wide, xor data 32 bits wide. */ | 76 | /* load data 32 bits wide, xor data 32 bits wide. */ |
| 68 | len = len >> 2; | 77 | len = len >> 2; |
| 78 | b = (const u32 *)buf; | ||
| 69 | for (--b; len; --len) { | 79 | for (--b; len; --len) { |
| 70 | crc ^= *++b; /* use pre increment for speed */ | 80 | crc ^= *++b; /* use pre increment for speed */ |
| 71 | DO_CRC(0); | 81 | DO_CRC4; |
| 72 | DO_CRC(0); | ||
| 73 | DO_CRC(0); | ||
| 74 | DO_CRC(0); | ||
| 75 | } | 82 | } |
| 76 | len = rem_len; | 83 | len = rem_len; |
| 77 | /* And the last few bytes */ | 84 | /* And the last few bytes */ |
| @@ -82,6 +89,8 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 *tab) | |||
| 82 | } while (--len); | 89 | } while (--len); |
| 83 | } | 90 | } |
| 84 | return crc; | 91 | return crc; |
| 92 | #undef DO_CRC | ||
| 93 | #undef DO_CRC4 | ||
| 85 | } | 94 | } |
| 86 | #endif | 95 | #endif |
| 87 | /** | 96 | /** |
| @@ -114,14 +123,11 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) | |||
| 114 | u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) | 123 | u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) |
| 115 | { | 124 | { |
| 116 | # if CRC_LE_BITS == 8 | 125 | # if CRC_LE_BITS == 8 |
| 117 | const u32 *tab = crc32table_le; | 126 | const u32 (*tab)[] = crc32table_le; |
| 118 | 127 | ||
| 119 | crc = __cpu_to_le32(crc); | 128 | crc = __cpu_to_le32(crc); |
| 120 | crc = crc32_body(crc, p, len, tab); | 129 | crc = crc32_body(crc, p, len, tab); |
| 121 | return __le32_to_cpu(crc); | 130 | return __le32_to_cpu(crc); |
| 122 | #undef ENDIAN_SHIFT | ||
| 123 | #undef DO_CRC | ||
| 124 | |||
| 125 | # elif CRC_LE_BITS == 4 | 131 | # elif CRC_LE_BITS == 4 |
| 126 | while (len--) { | 132 | while (len--) { |
| 127 | crc ^= *p++; | 133 | crc ^= *p++; |
| @@ -174,14 +180,11 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) | |||
| 174 | u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) | 180 | u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) |
| 175 | { | 181 | { |
| 176 | # if CRC_BE_BITS == 8 | 182 | # if CRC_BE_BITS == 8 |
| 177 | const u32 *tab = crc32table_be; | 183 | const u32 (*tab)[] = crc32table_be; |
| 178 | 184 | ||
| 179 | crc = __cpu_to_be32(crc); | 185 | crc = __cpu_to_be32(crc); |
| 180 | crc = crc32_body(crc, p, len, tab); | 186 | crc = crc32_body(crc, p, len, tab); |
| 181 | return __be32_to_cpu(crc); | 187 | return __be32_to_cpu(crc); |
| 182 | #undef ENDIAN_SHIFT | ||
| 183 | #undef DO_CRC | ||
| 184 | |||
| 185 | # elif CRC_BE_BITS == 4 | 188 | # elif CRC_BE_BITS == 4 |
| 186 | while (len--) { | 189 | while (len--) { |
| 187 | crc ^= *p++ << 24; | 190 | crc ^= *p++ << 24; |
