Warning, cross-references for /kernel/util/crc32.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 #include <kernel.h>
0043 #include <util/crc32.h>
0044 #include <arch/i386.h>
0045
0046
0047
0048
0049
0050
0051 #define CRCPOLY_LE 0xedb88320
0052 #define CRCPOLY_BE 0x04c11db7
0053
0054
0055
0056 #ifndef CRC_LE_BITS
0057 # define CRC_LE_BITS 8
0058 #endif
0059 #ifndef CRC_BE_BITS
0060 # define CRC_BE_BITS 8
0061 #endif
0062
0063
0064
0065
0066
0067 #if CRC_LE_BITS > 8 || CRC_LE_BITS < 1 || CRC_LE_BITS & CRC_LE_BITS-1
0068 # error CRC_LE_BITS must be a power of 2 between 1 and 8
0069 #endif
0070
0071
0072
0073
0074
0075 #if CRC_BE_BITS > 8 || CRC_BE_BITS < 1 || CRC_BE_BITS & CRC_BE_BITS-1
0076 # error CRC_BE_BITS must be a power of 2 between 1 and 8
0077 #endif
0078
0079
0080 #if CRC_LE_BITS == 8
0081 #define tole(x) __constant_cpu_to_le32(x)
0082 #define tobe(x) __constant_cpu_to_be32(x)
0083 #else
0084 #define tole(x) (x)
0085 #define tobe(x) (x)
0086 #endif
0087
0088
0089 static const u32 crc32table_le[] = {
0090 tole(0x00000000L), tole(0x77073096L), tole(0xee0e612cL), tole(0x990951baL),
0091 tole(0x076dc419L), tole(0x706af48fL), tole(0xe963a535L), tole(0x9e6495a3L),
0092 tole(0x0edb8832L), tole(0x79dcb8a4L), tole(0xe0d5e91eL), tole(0x97d2d988L),
0093 tole(0x09b64c2bL), tole(0x7eb17cbdL), tole(0xe7b82d07L), tole(0x90bf1d91L),
0094 tole(0x1db71064L), tole(0x6ab020f2L), tole(0xf3b97148L), tole(0x84be41deL),
0095 tole(0x1adad47dL), tole(0x6ddde4ebL), tole(0xf4d4b551L), tole(0x83d385c7L),
0096 tole(0x136c9856L), tole(0x646ba8c0L), tole(0xfd62f97aL), tole(0x8a65c9ecL),
0097 tole(0x14015c4fL), tole(0x63066cd9L), tole(0xfa0f3d63L), tole(0x8d080df5L),
0098 tole(0x3b6e20c8L), tole(0x4c69105eL), tole(0xd56041e4L), tole(0xa2677172L),
0099 tole(0x3c03e4d1L), tole(0x4b04d447L), tole(0xd20d85fdL), tole(0xa50ab56bL),
0100 tole(0x35b5a8faL), tole(0x42b2986cL), tole(0xdbbbc9d6L), tole(0xacbcf940L),
0101 tole(0x32d86ce3L), tole(0x45df5c75L), tole(0xdcd60dcfL), tole(0xabd13d59L),
0102 tole(0x26d930acL), tole(0x51de003aL), tole(0xc8d75180L), tole(0xbfd06116L),
0103 tole(0x21b4f4b5L), tole(0x56b3c423L), tole(0xcfba9599L), tole(0xb8bda50fL),
0104 tole(0x2802b89eL), tole(0x5f058808L), tole(0xc60cd9b2L), tole(0xb10be924L),
0105 tole(0x2f6f7c87L), tole(0x58684c11L), tole(0xc1611dabL), tole(0xb6662d3dL),
0106 tole(0x76dc4190L), tole(0x01db7106L), tole(0x98d220bcL), tole(0xefd5102aL),
0107 tole(0x71b18589L), tole(0x06b6b51fL), tole(0x9fbfe4a5L), tole(0xe8b8d433L),
0108 tole(0x7807c9a2L), tole(0x0f00f934L), tole(0x9609a88eL), tole(0xe10e9818L),
0109 tole(0x7f6a0dbbL), tole(0x086d3d2dL), tole(0x91646c97L), tole(0xe6635c01L),
0110 tole(0x6b6b51f4L), tole(0x1c6c6162L), tole(0x856530d8L), tole(0xf262004eL),
0111 tole(0x6c0695edL), tole(0x1b01a57bL), tole(0x8208f4c1L), tole(0xf50fc457L),
0112 tole(0x65b0d9c6L), tole(0x12b7e950L), tole(0x8bbeb8eaL), tole(0xfcb9887cL),
0113 tole(0x62dd1ddfL), tole(0x15da2d49L), tole(0x8cd37cf3L), tole(0xfbd44c65L),
0114 tole(0x4db26158L), tole(0x3ab551ceL), tole(0xa3bc0074L), tole(0xd4bb30e2L),
0115 tole(0x4adfa541L), tole(0x3dd895d7L), tole(0xa4d1c46dL), tole(0xd3d6f4fbL),
0116 tole(0x4369e96aL), tole(0x346ed9fcL), tole(0xad678846L), tole(0xda60b8d0L),
0117 tole(0x44042d73L), tole(0x33031de5L), tole(0xaa0a4c5fL), tole(0xdd0d7cc9L),
0118 tole(0x5005713cL), tole(0x270241aaL), tole(0xbe0b1010L), tole(0xc90c2086L),
0119 tole(0x5768b525L), tole(0x206f85b3L), tole(0xb966d409L), tole(0xce61e49fL),
0120 tole(0x5edef90eL), tole(0x29d9c998L), tole(0xb0d09822L), tole(0xc7d7a8b4L),
0121 tole(0x59b33d17L), tole(0x2eb40d81L), tole(0xb7bd5c3bL), tole(0xc0ba6cadL),
0122 tole(0xedb88320L), tole(0x9abfb3b6L), tole(0x03b6e20cL), tole(0x74b1d29aL),
0123 tole(0xead54739L), tole(0x9dd277afL), tole(0x04db2615L), tole(0x73dc1683L),
0124 tole(0xe3630b12L), tole(0x94643b84L), tole(0x0d6d6a3eL), tole(0x7a6a5aa8L),
0125 tole(0xe40ecf0bL), tole(0x9309ff9dL), tole(0x0a00ae27L), tole(0x7d079eb1L),
0126 tole(0xf00f9344L), tole(0x8708a3d2L), tole(0x1e01f268L), tole(0x6906c2feL),
0127 tole(0xf762575dL), tole(0x806567cbL), tole(0x196c3671L), tole(0x6e6b06e7L),
0128 tole(0xfed41b76L), tole(0x89d32be0L), tole(0x10da7a5aL), tole(0x67dd4accL),
0129 tole(0xf9b9df6fL), tole(0x8ebeeff9L), tole(0x17b7be43L), tole(0x60b08ed5L),
0130 tole(0xd6d6a3e8L), tole(0xa1d1937eL), tole(0x38d8c2c4L), tole(0x4fdff252L),
0131 tole(0xd1bb67f1L), tole(0xa6bc5767L), tole(0x3fb506ddL), tole(0x48b2364bL),
0132 tole(0xd80d2bdaL), tole(0xaf0a1b4cL), tole(0x36034af6L), tole(0x41047a60L),
0133 tole(0xdf60efc3L), tole(0xa867df55L), tole(0x316e8eefL), tole(0x4669be79L),
0134 tole(0xcb61b38cL), tole(0xbc66831aL), tole(0x256fd2a0L), tole(0x5268e236L),
0135 tole(0xcc0c7795L), tole(0xbb0b4703L), tole(0x220216b9L), tole(0x5505262fL),
0136 tole(0xc5ba3bbeL), tole(0xb2bd0b28L), tole(0x2bb45a92L), tole(0x5cb36a04L),
0137 tole(0xc2d7ffa7L), tole(0xb5d0cf31L), tole(0x2cd99e8bL), tole(0x5bdeae1dL),
0138 tole(0x9b64c2b0L), tole(0xec63f226L), tole(0x756aa39cL), tole(0x026d930aL),
0139 tole(0x9c0906a9L), tole(0xeb0e363fL), tole(0x72076785L), tole(0x05005713L),
0140 tole(0x95bf4a82L), tole(0xe2b87a14L), tole(0x7bb12baeL), tole(0x0cb61b38L),
0141 tole(0x92d28e9bL), tole(0xe5d5be0dL), tole(0x7cdcefb7L), tole(0x0bdbdf21L),
0142 tole(0x86d3d2d4L), tole(0xf1d4e242L), tole(0x68ddb3f8L), tole(0x1fda836eL),
0143 tole(0x81be16cdL), tole(0xf6b9265bL), tole(0x6fb077e1L), tole(0x18b74777L),
0144 tole(0x88085ae6L), tole(0xff0f6a70L), tole(0x66063bcaL), tole(0x11010b5cL),
0145 tole(0x8f659effL), tole(0xf862ae69L), tole(0x616bffd3L), tole(0x166ccf45L),
0146 tole(0xa00ae278L), tole(0xd70dd2eeL), tole(0x4e048354L), tole(0x3903b3c2L),
0147 tole(0xa7672661L), tole(0xd06016f7L), tole(0x4969474dL), tole(0x3e6e77dbL),
0148 tole(0xaed16a4aL), tole(0xd9d65adcL), tole(0x40df0b66L), tole(0x37d83bf0L),
0149 tole(0xa9bcae53L), tole(0xdebb9ec5L), tole(0x47b2cf7fL), tole(0x30b5ffe9L),
0150 tole(0xbdbdf21cL), tole(0xcabac28aL), tole(0x53b39330L), tole(0x24b4a3a6L),
0151 tole(0xbad03605L), tole(0xcdd70693L), tole(0x54de5729L), tole(0x23d967bfL),
0152 tole(0xb3667a2eL), tole(0xc4614ab8L), tole(0x5d681b02L), tole(0x2a6f2b94L),
0153 tole(0xb40bbe37L), tole(0xc30c8ea1L), tole(0x5a05df1bL), tole(0x2d02ef8dL)
0154 };
0155
0156 static const u32 crc32table_be[] = {
0157 tobe(0x00000000L), tobe(0x04c11db7L), tobe(0x09823b6eL), tobe(0x0d4326d9L),
0158 tobe(0x130476dcL), tobe(0x17c56b6bL), tobe(0x1a864db2L), tobe(0x1e475005L),
0159 tobe(0x2608edb8L), tobe(0x22c9f00fL), tobe(0x2f8ad6d6L), tobe(0x2b4bcb61L),
0160 tobe(0x350c9b64L), tobe(0x31cd86d3L), tobe(0x3c8ea00aL), tobe(0x384fbdbdL),
0161 tobe(0x4c11db70L), tobe(0x48d0c6c7L), tobe(0x4593e01eL), tobe(0x4152fda9L),
0162 tobe(0x5f15adacL), tobe(0x5bd4b01bL), tobe(0x569796c2L), tobe(0x52568b75L),
0163 tobe(0x6a1936c8L), tobe(0x6ed82b7fL), tobe(0x639b0da6L), tobe(0x675a1011L),
0164 tobe(0x791d4014L), tobe(0x7ddc5da3L), tobe(0x709f7b7aL), tobe(0x745e66cdL),
0165 tobe(0x9823b6e0L), tobe(0x9ce2ab57L), tobe(0x91a18d8eL), tobe(0x95609039L),
0166 tobe(0x8b27c03cL), tobe(0x8fe6dd8bL), tobe(0x82a5fb52L), tobe(0x8664e6e5L),
0167 tobe(0xbe2b5b58L), tobe(0xbaea46efL), tobe(0xb7a96036L), tobe(0xb3687d81L),
0168 tobe(0xad2f2d84L), tobe(0xa9ee3033L), tobe(0xa4ad16eaL), tobe(0xa06c0b5dL),
0169 tobe(0xd4326d90L), tobe(0xd0f37027L), tobe(0xddb056feL), tobe(0xd9714b49L),
0170 tobe(0xc7361b4cL), tobe(0xc3f706fbL), tobe(0xceb42022L), tobe(0xca753d95L),
0171 tobe(0xf23a8028L), tobe(0xf6fb9d9fL), tobe(0xfbb8bb46L), tobe(0xff79a6f1L),
0172 tobe(0xe13ef6f4L), tobe(0xe5ffeb43L), tobe(0xe8bccd9aL), tobe(0xec7dd02dL),
0173 tobe(0x34867077L), tobe(0x30476dc0L), tobe(0x3d044b19L), tobe(0x39c556aeL),
0174 tobe(0x278206abL), tobe(0x23431b1cL), tobe(0x2e003dc5L), tobe(0x2ac12072L),
0175 tobe(0x128e9dcfL), tobe(0x164f8078L), tobe(0x1b0ca6a1L), tobe(0x1fcdbb16L),
0176 tobe(0x018aeb13L), tobe(0x054bf6a4L), tobe(0x0808d07dL), tobe(0x0cc9cdcaL),
0177 tobe(0x7897ab07L), tobe(0x7c56b6b0L), tobe(0x71159069L), tobe(0x75d48ddeL),
0178 tobe(0x6b93dddbL), tobe(0x6f52c06cL), tobe(0x6211e6b5L), tobe(0x66d0fb02L),
0179 tobe(0x5e9f46bfL), tobe(0x5a5e5b08L), tobe(0x571d7dd1L), tobe(0x53dc6066L),
0180 tobe(0x4d9b3063L), tobe(0x495a2dd4L), tobe(0x44190b0dL), tobe(0x40d816baL),
0181 tobe(0xaca5c697L), tobe(0xa864db20L), tobe(0xa527fdf9L), tobe(0xa1e6e04eL),
0182 tobe(0xbfa1b04bL), tobe(0xbb60adfcL), tobe(0xb6238b25L), tobe(0xb2e29692L),
0183 tobe(0x8aad2b2fL), tobe(0x8e6c3698L), tobe(0x832f1041L), tobe(0x87ee0df6L),
0184 tobe(0x99a95df3L), tobe(0x9d684044L), tobe(0x902b669dL), tobe(0x94ea7b2aL),
0185 tobe(0xe0b41de7L), tobe(0xe4750050L), tobe(0xe9362689L), tobe(0xedf73b3eL),
0186 tobe(0xf3b06b3bL), tobe(0xf771768cL), tobe(0xfa325055L), tobe(0xfef34de2L),
0187 tobe(0xc6bcf05fL), tobe(0xc27dede8L), tobe(0xcf3ecb31L), tobe(0xcbffd686L),
0188 tobe(0xd5b88683L), tobe(0xd1799b34L), tobe(0xdc3abdedL), tobe(0xd8fba05aL),
0189 tobe(0x690ce0eeL), tobe(0x6dcdfd59L), tobe(0x608edb80L), tobe(0x644fc637L),
0190 tobe(0x7a089632L), tobe(0x7ec98b85L), tobe(0x738aad5cL), tobe(0x774bb0ebL),
0191 tobe(0x4f040d56L), tobe(0x4bc510e1L), tobe(0x46863638L), tobe(0x42472b8fL),
0192 tobe(0x5c007b8aL), tobe(0x58c1663dL), tobe(0x558240e4L), tobe(0x51435d53L),
0193 tobe(0x251d3b9eL), tobe(0x21dc2629L), tobe(0x2c9f00f0L), tobe(0x285e1d47L),
0194 tobe(0x36194d42L), tobe(0x32d850f5L), tobe(0x3f9b762cL), tobe(0x3b5a6b9bL),
0195 tobe(0x0315d626L), tobe(0x07d4cb91L), tobe(0x0a97ed48L), tobe(0x0e56f0ffL),
0196 tobe(0x1011a0faL), tobe(0x14d0bd4dL), tobe(0x19939b94L), tobe(0x1d528623L),
0197 tobe(0xf12f560eL), tobe(0xf5ee4bb9L), tobe(0xf8ad6d60L), tobe(0xfc6c70d7L),
0198 tobe(0xe22b20d2L), tobe(0xe6ea3d65L), tobe(0xeba91bbcL), tobe(0xef68060bL),
0199 tobe(0xd727bbb6L), tobe(0xd3e6a601L), tobe(0xdea580d8L), tobe(0xda649d6fL),
0200 tobe(0xc423cd6aL), tobe(0xc0e2d0ddL), tobe(0xcda1f604L), tobe(0xc960ebb3L),
0201 tobe(0xbd3e8d7eL), tobe(0xb9ff90c9L), tobe(0xb4bcb610L), tobe(0xb07daba7L),
0202 tobe(0xae3afba2L), tobe(0xaafbe615L), tobe(0xa7b8c0ccL), tobe(0xa379dd7bL),
0203 tobe(0x9b3660c6L), tobe(0x9ff77d71L), tobe(0x92b45ba8L), tobe(0x9675461fL),
0204 tobe(0x8832161aL), tobe(0x8cf30badL), tobe(0x81b02d74L), tobe(0x857130c3L),
0205 tobe(0x5d8a9099L), tobe(0x594b8d2eL), tobe(0x5408abf7L), tobe(0x50c9b640L),
0206 tobe(0x4e8ee645L), tobe(0x4a4ffbf2L), tobe(0x470cdd2bL), tobe(0x43cdc09cL),
0207 tobe(0x7b827d21L), tobe(0x7f436096L), tobe(0x7200464fL), tobe(0x76c15bf8L),
0208 tobe(0x68860bfdL), tobe(0x6c47164aL), tobe(0x61043093L), tobe(0x65c52d24L),
0209 tobe(0x119b4be9L), tobe(0x155a565eL), tobe(0x18197087L), tobe(0x1cd86d30L),
0210 tobe(0x029f3d35L), tobe(0x065e2082L), tobe(0x0b1d065bL), tobe(0x0fdc1becL),
0211 tobe(0x3793a651L), tobe(0x3352bbe6L), tobe(0x3e119d3fL), tobe(0x3ad08088L),
0212 tobe(0x2497d08dL), tobe(0x2056cd3aL), tobe(0x2d15ebe3L), tobe(0x29d4f654L),
0213 tobe(0xc5a92679L), tobe(0xc1683bceL), tobe(0xcc2b1d17L), tobe(0xc8ea00a0L),
0214 tobe(0xd6ad50a5L), tobe(0xd26c4d12L), tobe(0xdf2f6bcbL), tobe(0xdbee767cL),
0215 tobe(0xe3a1cbc1L), tobe(0xe760d676L), tobe(0xea23f0afL), tobe(0xeee2ed18L),
0216 tobe(0xf0a5bd1dL), tobe(0xf464a0aaL), tobe(0xf9278673L), tobe(0xfde69bc4L),
0217 tobe(0x89b8fd09L), tobe(0x8d79e0beL), tobe(0x803ac667L), tobe(0x84fbdbd0L),
0218 tobe(0x9abc8bd5L), tobe(0x9e7d9662L), tobe(0x933eb0bbL), tobe(0x97ffad0cL),
0219 tobe(0xafb010b1L), tobe(0xab710d06L), tobe(0xa6322bdfL), tobe(0xa2f33668L),
0220 tobe(0xbcb4666dL), tobe(0xb8757bdaL), tobe(0xb5365d03L), tobe(0xb1f740b4L)
0221 };
0222
0223
0224 #define __pure
0225
0226
0227
0228
0229
0230
0231
0232
0233 u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len);
0234
0235 #if CRC_LE_BITS == 1
0236
0237
0238
0239
0240
0241 u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
0242 {
0243 int i;
0244 while (len--) {
0245 crc ^= *p++;
0246 for (i = 0; i < 8; i++)
0247 crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
0248 }
0249 return crc;
0250 }
0251 #else
0252
0253 u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
0254 {
0255 # if CRC_LE_BITS == 8
0256 const u32 *b =(u32 *)p;
0257 const u32 *tab = crc32table_le;
0258
0259 # ifdef __LITTLE_ENDIAN
0260 # define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8)
0261 # else
0262 # define DO_CRC(x) crc = tab[ ((crc >> 24) ^ (x)) & 255] ^ (crc<<8)
0263 # endif
0264
0265 crc = __cpu_to_le32(crc);
0266
0267 if(unlikely(((long)b)&3 && len)){
0268 do {
0269 u8 *p = (u8 *)b;
0270 DO_CRC(*p++);
0271 b = (void *)p;
0272 } while ((--len) && ((long)b)&3 );
0273 }
0274 if(likely(len >= 4)){
0275
0276 size_t save_len = len & 3;
0277 len = len >> 2;
0278 --b;
0279 do {
0280 crc ^= *++b;
0281 DO_CRC(0);
0282 DO_CRC(0);
0283 DO_CRC(0);
0284 DO_CRC(0);
0285 } while (--len);
0286 b++;
0287 len = save_len;
0288 }
0289
0290 if(len){
0291 do {
0292 u8 *p = (u8 *)b;
0293 DO_CRC(*p++);
0294 b = (void *)p;
0295 } while (--len);
0296 }
0297
0298 return __le32_to_cpu(crc);
0299 #undef ENDIAN_SHIFT
0300 #undef DO_CRC
0301
0302 # elif CRC_LE_BITS == 4
0303 while (len--) {
0304 crc ^= *p++;
0305 crc = (crc >> 4) ^ crc32table_le[crc & 15];
0306 crc = (crc >> 4) ^ crc32table_le[crc & 15];
0307 }
0308 return crc;
0309 # elif CRC_LE_BITS == 2
0310 while (len--) {
0311 crc ^= *p++;
0312 crc = (crc >> 2) ^ crc32table_le[crc & 3];
0313 crc = (crc >> 2) ^ crc32table_le[crc & 3];
0314 crc = (crc >> 2) ^ crc32table_le[crc & 3];
0315 crc = (crc >> 2) ^ crc32table_le[crc & 3];
0316 }
0317 return crc;
0318 # endif
0319 }
0320 #endif
0321
0322
0323
0324
0325
0326
0327
0328
0329 u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len);
0330
0331 #if CRC_BE_BITS == 1
0332
0333
0334
0335
0336
0337 u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
0338 {
0339 int i;
0340 while (len--) {
0341 crc ^= *p++ << 24;
0342 for (i = 0; i < 8; i++)
0343 crc =
0344 (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE :
0345 0);
0346 }
0347 return crc;
0348 }
0349
0350 #else
0351 u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
0352 {
0353 # if CRC_BE_BITS == 8
0354 const u32 *b =(u32 *)p;
0355 const u32 *tab = crc32table_be;
0356
0357 # ifdef __LITTLE_ENDIAN
0358 # define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8)
0359 # else
0360 # define DO_CRC(x) crc = tab[ ((crc >> 24) ^ (x)) & 255] ^ (crc<<8)
0361 # endif
0362
0363 crc = __cpu_to_be32(crc);
0364
0365 if(unlikely(((long)b)&3 && len)){
0366 do {
0367 u8 *p = (u8 *)b;
0368 DO_CRC(*p++);
0369 b = (u32 *)p;
0370 } while ((--len) && ((long)b)&3 );
0371 }
0372 if(likely(len >= 4)){
0373
0374 size_t save_len = len & 3;
0375 len = len >> 2;
0376 --b;
0377 do {
0378 crc ^= *++b;
0379 DO_CRC(0);
0380 DO_CRC(0);
0381 DO_CRC(0);
0382 DO_CRC(0);
0383 } while (--len);
0384 b++;
0385 len = save_len;
0386 }
0387
0388 if(len){
0389 do {
0390 u8 *p = (u8 *)b;
0391 DO_CRC(*p++);
0392 b = (void *)p;
0393 } while (--len);
0394 }
0395 return __be32_to_cpu(crc);
0396 #undef ENDIAN_SHIFT
0397 #undef DO_CRC
0398
0399 # elif CRC_BE_BITS == 4
0400 while (len--) {
0401 crc ^= *p++ << 24;
0402 crc = (crc << 4) ^ crc32table_be[crc >> 28];
0403 crc = (crc << 4) ^ crc32table_be[crc >> 28];
0404 }
0405 return crc;
0406 # elif CRC_BE_BITS == 2
0407 while (len--) {
0408 crc ^= *p++ << 24;
0409 crc = (crc << 2) ^ crc32table_be[crc >> 30];
0410 crc = (crc << 2) ^ crc32table_be[crc >> 30];
0411 crc = (crc << 2) ^ crc32table_be[crc >> 30];
0412 crc = (crc << 2) ^ crc32table_be[crc >> 30];
0413 }
0414 return crc;
0415 # endif
0416 }
0417 #endif
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546 #ifdef UNITTEST
0547
0548 #include <stdlib.h>
0549 #include <stdio.h>
0550
0551 #if 0
0552 static void
0553 buf_dump(char const *prefix, unsigned char const *buf, size_t len)
0554 {
0555 fputs(prefix, stdout);
0556 while (len--)
0557 printf(" %02x", *buf++);
0558 putchar('\n');
0559
0560 }
0561 #endif
0562
0563 static void bytereverse(unsigned char *buf, size_t len)
0564 {
0565 while (len--) {
0566 unsigned char x = bitrev8(*buf);
0567 *buf++ = x;
0568 }
0569 }
0570
0571 static void random_garbage(unsigned char *buf, size_t len)
0572 {
0573 while (len--)
0574 *buf++ = (unsigned char) random();
0575 }
0576
0577 #if 0
0578 static void store_le(u32 x, unsigned char *buf)
0579 {
0580 buf[0] = (unsigned char) x;
0581 buf[1] = (unsigned char) (x >> 8);
0582 buf[2] = (unsigned char) (x >> 16);
0583 buf[3] = (unsigned char) (x >> 24);
0584 }
0585 #endif
0586
0587 static void store_be(u32 x, unsigned char *buf)
0588 {
0589 buf[0] = (unsigned char) (x >> 24);
0590 buf[1] = (unsigned char) (x >> 16);
0591 buf[2] = (unsigned char) (x >> 8);
0592 buf[3] = (unsigned char) x;
0593 }
0594
0595
0596
0597
0598
0599
0600
0601 static u32 test_step(u32 init, unsigned char *buf, size_t len)
0602 {
0603 u32 crc1, crc2;
0604 size_t i;
0605
0606 crc1 = crc32_be(init, buf, len);
0607 store_be(crc1, buf + len);
0608 crc2 = crc32_be(init, buf, len + 4);
0609 if (crc2)
0610 printf("\nCRC cancellation fail: 0x%08x should be 0\n",
0611 crc2);
0612
0613 for (i = 0; i <= len + 4; i++) {
0614 crc2 = crc32_be(init, buf, i);
0615 crc2 = crc32_be(crc2, buf + i, len + 4 - i);
0616 if (crc2)
0617 printf("\nCRC split fail: 0x%08x\n", crc2);
0618 }
0619
0620
0621
0622 bytereverse(buf, len + 4);
0623 init = bitrev32(init);
0624 crc2 = bitrev32(crc1);
0625 if (crc1 != bitrev32(crc2))
0626 printf("\nBit reversal fail: 0x%08x -> 0x%08x -> 0x%08x\n",
0627 crc1, crc2, bitrev32(crc2));
0628 crc1 = crc32_le(init, buf, len);
0629 if (crc1 != crc2)
0630 printf("\nCRC endianness fail: 0x%08x != 0x%08x\n", crc1,
0631 crc2);
0632 crc2 = crc32_le(init, buf, len + 4);
0633 if (crc2)
0634 printf("\nCRC cancellation fail: 0x%08x should be 0\n",
0635 crc2);
0636
0637 for (i = 0; i <= len + 4; i++) {
0638 crc2 = crc32_le(init, buf, i);
0639 crc2 = crc32_le(crc2, buf + i, len + 4 - i);
0640 if (crc2)
0641 printf("\nCRC split fail: 0x%08x\n", crc2);
0642 }
0643
0644 return crc1;
0645 }
0646
0647 #define SIZE 64
0648 #define INIT1 0
0649 #define INIT2 0
0650
0651 int main(void)
0652 {
0653 unsigned char buf1[SIZE + 4];
0654 unsigned char buf2[SIZE + 4];
0655 unsigned char buf3[SIZE + 4];
0656 int i, j;
0657 u32 crc1, crc2, crc3;
0658
0659 for (i = 0; i <= SIZE; i++) {
0660 printf("\rTesting length %d...", i);
0661 fflush(stdout);
0662 random_garbage(buf1, i);
0663 random_garbage(buf2, i);
0664 for (j = 0; j < i; j++)
0665 buf3[j] = buf1[j] ^ buf2[j];
0666
0667 crc1 = test_step(INIT1, buf1, i);
0668 crc2 = test_step(INIT2, buf2, i);
0669
0670 crc3 = test_step(INIT1 ^ INIT2, buf3, i);
0671 if (crc3 != (crc1 ^ crc2))
0672 printf("CRC XOR fail: 0x%08x != 0x%08x ^ 0x%08x\n",
0673 crc3, crc1, crc2);
0674 }
0675 printf("\nAll test complete. No failures expected.\n");
0676 return 0;
0677 }
0678
0679 #endif
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690