diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /lib/crc32.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'lib/crc32.c')
-rw-r--r-- | lib/crc32.c | 140 |
1 files changed, 52 insertions, 88 deletions
diff --git a/lib/crc32.c b/lib/crc32.c index 49d1c9e3ce38..bc5b936e9142 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 | ||
@@ -42,6 +45,48 @@ MODULE_AUTHOR("Matt Domsch <Matt_Domsch@dell.com>"); | |||
42 | MODULE_DESCRIPTION("Ethernet CRC32 calculations"); | 45 | MODULE_DESCRIPTION("Ethernet CRC32 calculations"); |
43 | MODULE_LICENSE("GPL"); | 46 | MODULE_LICENSE("GPL"); |
44 | 47 | ||
48 | #if CRC_LE_BITS == 8 || CRC_BE_BITS == 8 | ||
49 | |||
50 | static inline u32 | ||
51 | crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 *tab) | ||
52 | { | ||
53 | # ifdef __LITTLE_ENDIAN | ||
54 | # define DO_CRC(x) crc = tab[(crc ^ (x)) & 255 ] ^ (crc >> 8) | ||
55 | # else | ||
56 | # define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc << 8) | ||
57 | # endif | ||
58 | const u32 *b; | ||
59 | size_t rem_len; | ||
60 | |||
61 | /* Align it */ | ||
62 | if (unlikely((long)buf & 3 && len)) { | ||
63 | do { | ||
64 | DO_CRC(*buf++); | ||
65 | } while ((--len) && ((long)buf)&3); | ||
66 | } | ||
67 | rem_len = len & 3; | ||
68 | /* load data 32 bits wide, xor data 32 bits wide. */ | ||
69 | len = len >> 2; | ||
70 | b = (const u32 *)buf; | ||
71 | for (--b; len; --len) { | ||
72 | crc ^= *++b; /* use pre increment for speed */ | ||
73 | DO_CRC(0); | ||
74 | DO_CRC(0); | ||
75 | DO_CRC(0); | ||
76 | DO_CRC(0); | ||
77 | } | ||
78 | len = rem_len; | ||
79 | /* And the last few bytes */ | ||
80 | if (len) { | ||
81 | u8 *p = (u8 *)(b + 1) - 1; | ||
82 | do { | ||
83 | DO_CRC(*++p); /* use pre increment for speed */ | ||
84 | } while (--len); | ||
85 | } | ||
86 | return crc; | ||
87 | #undef DO_CRC | ||
88 | } | ||
89 | #endif | ||
45 | /** | 90 | /** |
46 | * crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32 | 91 | * crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32 |
47 | * @crc: seed value for computation. ~0 for Ethernet, sometimes 0 for | 92 | * @crc: seed value for computation. ~0 for Ethernet, sometimes 0 for |
@@ -72,52 +117,11 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) | |||
72 | u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) | 117 | u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) |
73 | { | 118 | { |
74 | # if CRC_LE_BITS == 8 | 119 | # if CRC_LE_BITS == 8 |
75 | const u32 *b =(u32 *)p; | ||
76 | const u32 *tab = crc32table_le; | 120 | const u32 *tab = crc32table_le; |
77 | 121 | ||
78 | # ifdef __LITTLE_ENDIAN | ||
79 | # define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8) | ||
80 | # else | ||
81 | # define DO_CRC(x) crc = tab[ ((crc >> 24) ^ (x)) & 255] ^ (crc<<8) | ||
82 | # endif | ||
83 | |||
84 | crc = __cpu_to_le32(crc); | 122 | crc = __cpu_to_le32(crc); |
85 | /* Align it */ | 123 | crc = crc32_body(crc, p, len, tab); |
86 | if(unlikely(((long)b)&3 && len)){ | ||
87 | do { | ||
88 | u8 *p = (u8 *)b; | ||
89 | DO_CRC(*p++); | ||
90 | b = (void *)p; | ||
91 | } while ((--len) && ((long)b)&3 ); | ||
92 | } | ||
93 | if(likely(len >= 4)){ | ||
94 | /* load data 32 bits wide, xor data 32 bits wide. */ | ||
95 | size_t save_len = len & 3; | ||
96 | len = len >> 2; | ||
97 | --b; /* use pre increment below(*++b) for speed */ | ||
98 | do { | ||
99 | crc ^= *++b; | ||
100 | DO_CRC(0); | ||
101 | DO_CRC(0); | ||
102 | DO_CRC(0); | ||
103 | DO_CRC(0); | ||
104 | } while (--len); | ||
105 | b++; /* point to next byte(s) */ | ||
106 | len = save_len; | ||
107 | } | ||
108 | /* And the last few bytes */ | ||
109 | if(len){ | ||
110 | do { | ||
111 | u8 *p = (u8 *)b; | ||
112 | DO_CRC(*p++); | ||
113 | b = (void *)p; | ||
114 | } while (--len); | ||
115 | } | ||
116 | |||
117 | return __le32_to_cpu(crc); | 124 | return __le32_to_cpu(crc); |
118 | #undef ENDIAN_SHIFT | ||
119 | #undef DO_CRC | ||
120 | |||
121 | # elif CRC_LE_BITS == 4 | 125 | # elif CRC_LE_BITS == 4 |
122 | while (len--) { | 126 | while (len--) { |
123 | crc ^= *p++; | 127 | crc ^= *p++; |
@@ -170,51 +174,11 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) | |||
170 | 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) |
171 | { | 175 | { |
172 | # if CRC_BE_BITS == 8 | 176 | # if CRC_BE_BITS == 8 |
173 | const u32 *b =(u32 *)p; | ||
174 | const u32 *tab = crc32table_be; | 177 | const u32 *tab = crc32table_be; |
175 | 178 | ||
176 | # ifdef __LITTLE_ENDIAN | ||
177 | # define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8) | ||
178 | # else | ||
179 | # define DO_CRC(x) crc = tab[ ((crc >> 24) ^ (x)) & 255] ^ (crc<<8) | ||
180 | # endif | ||
181 | |||
182 | crc = __cpu_to_be32(crc); | 179 | crc = __cpu_to_be32(crc); |
183 | /* Align it */ | 180 | crc = crc32_body(crc, p, len, tab); |
184 | if(unlikely(((long)b)&3 && len)){ | ||
185 | do { | ||
186 | u8 *p = (u8 *)b; | ||
187 | DO_CRC(*p++); | ||
188 | b = (u32 *)p; | ||
189 | } while ((--len) && ((long)b)&3 ); | ||
190 | } | ||
191 | if(likely(len >= 4)){ | ||
192 | /* load data 32 bits wide, xor data 32 bits wide. */ | ||
193 | size_t save_len = len & 3; | ||
194 | len = len >> 2; | ||
195 | --b; /* use pre increment below(*++b) for speed */ | ||
196 | do { | ||
197 | crc ^= *++b; | ||
198 | DO_CRC(0); | ||
199 | DO_CRC(0); | ||
200 | DO_CRC(0); | ||
201 | DO_CRC(0); | ||
202 | } while (--len); | ||
203 | b++; /* point to next byte(s) */ | ||
204 | len = save_len; | ||
205 | } | ||
206 | /* And the last few bytes */ | ||
207 | if(len){ | ||
208 | do { | ||
209 | u8 *p = (u8 *)b; | ||
210 | DO_CRC(*p++); | ||
211 | b = (void *)p; | ||
212 | } while (--len); | ||
213 | } | ||
214 | return __be32_to_cpu(crc); | 181 | return __be32_to_cpu(crc); |
215 | #undef ENDIAN_SHIFT | ||
216 | #undef DO_CRC | ||
217 | |||
218 | # elif CRC_BE_BITS == 4 | 182 | # elif CRC_BE_BITS == 4 |
219 | while (len--) { | 183 | while (len--) { |
220 | crc ^= *p++ << 24; | 184 | crc ^= *p++ << 24; |