42 #include <linux/types.h>
43 #include <linux/kernel.h>
44 #include <linux/module.h>
48 #include <asm/byteorder.h>
52 #define EXPORT_SYMBOL(x)
54 #define MODULE_LICENSE(x)
55 #define MODULE_AUTHOR(x)
56 #define MODULE_DESCRIPTION(x)
68 static const char invparity[256] = {
69 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
70 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
71 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
72 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
73 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
74 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
75 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
76 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
77 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
78 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
79 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
80 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
81 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
82 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
83 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
84 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
92 static const char bitsperbyte[256] = {
93 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
94 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
95 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
96 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
97 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
98 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
99 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
100 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
101 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
102 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
103 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
104 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
105 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
106 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
107 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
108 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
117 static const char addressbits[256] = {
118 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
119 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
120 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
121 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
122 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
123 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
124 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
125 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
126 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
127 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
128 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
129 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
130 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
131 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
132 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
133 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
134 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
135 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
136 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
137 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
138 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
139 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
140 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
141 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
142 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
143 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
144 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
145 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
146 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
147 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
148 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
149 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f
165 const uint32_t eccsize_mult = eccsize >> 8;
168 uint32_t rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7;
169 uint32_t rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15, rp16;
195 for (i = 0; i < eccsize_mult << 2; i++) {
258 if (eccsize_mult == 2 && (i & 0x4) == 0)
277 rp10 ^= (rp10 >> 16);
280 rp12 ^= (rp12 >> 16);
283 rp14 ^= (rp14 >> 16);
286 if (eccsize_mult == 2) {
287 rp16 ^= (rp16 >> 16);
321 rp0 = (par >> 8) & 0xff;
324 rp1 = (par >> 8) & 0xff;
341 rp5 = (par ^ rp4) & 0xff;
342 rp7 = (par ^ rp6) & 0xff;
343 rp9 = (par ^ rp8) & 0xff;
344 rp11 = (par ^ rp10) & 0xff;
345 rp13 = (par ^ rp12) & 0xff;
346 rp15 = (par ^ rp14) & 0xff;
347 if (eccsize_mult == 2)
348 rp17 = (par ^ rp16) & 0xff;
356 #ifdef CONFIG_MTD_NAND_ECC_SMC
358 (invparity[rp7] << 7) |
359 (invparity[rp6] << 6) |
360 (invparity[rp5] << 5) |
361 (invparity[rp4] << 4) |
362 (invparity[rp3] << 3) |
363 (invparity[rp2] << 2) |
364 (invparity[rp1] << 1) |
367 (invparity[rp15] << 7) |
368 (invparity[rp14] << 6) |
369 (invparity[rp13] << 5) |
370 (invparity[rp12] << 4) |
371 (invparity[rp11] << 3) |
372 (invparity[rp10] << 2) |
373 (invparity[rp9] << 1) |
377 (invparity[rp7] << 7) |
378 (invparity[rp6] << 6) |
379 (invparity[rp5] << 5) |
380 (invparity[rp4] << 4) |
381 (invparity[rp3] << 3) |
382 (invparity[rp2] << 2) |
383 (invparity[rp1] << 1) |
386 (invparity[rp15] << 7) |
387 (invparity[rp14] << 6) |
388 (invparity[rp13] << 5) |
389 (invparity[rp12] << 4) |
390 (invparity[rp11] << 3) |
391 (invparity[rp10] << 2) |
392 (invparity[rp9] << 1) |
395 if (eccsize_mult == 1)
397 (invparity[par & 0xf0] << 7) |
398 (invparity[par & 0x0f] << 6) |
399 (invparity[par & 0xcc] << 5) |
400 (invparity[par & 0x33] << 4) |
401 (invparity[par & 0xaa] << 3) |
402 (invparity[par & 0x55] << 2) |
406 (invparity[par & 0xf0] << 7) |
407 (invparity[par & 0x0f] << 6) |
408 (invparity[par & 0xcc] << 5) |
409 (invparity[par & 0x33] << 4) |
410 (invparity[par & 0xaa] << 3) |
411 (invparity[par & 0x55] << 2) |
412 (invparity[rp17] << 1) |
413 (invparity[rp16] << 0);
444 unsigned char *read_ecc,
unsigned char *calc_ecc,
445 unsigned int eccsize)
447 unsigned char b0, b1, b2, bit_addr;
448 unsigned int byte_addr;
450 const uint32_t eccsize_mult = eccsize >> 8;
457 #ifdef CONFIG_MTD_NAND_ECC_SMC
458 b0 = read_ecc[0] ^ calc_ecc[0];
459 b1 = read_ecc[1] ^ calc_ecc[1];
461 b0 = read_ecc[1] ^ calc_ecc[1];
462 b1 = read_ecc[0] ^ calc_ecc[0];
464 b2 = read_ecc[2] ^ calc_ecc[2];
471 if ((b0 | b1 | b2) == 0)
474 if ((((b0 ^ (b0 >> 1)) & 0x55) == 0x55) &&
475 (((b1 ^ (b1 >> 1)) & 0x55) == 0x55) &&
476 ((eccsize_mult == 1 && ((b2 ^ (b2 >> 1)) & 0x54) == 0x54) ||
477 (eccsize_mult == 2 && ((b2 ^ (b2 >> 1)) & 0x55) == 0x55))) {
495 if (eccsize_mult == 1)
496 byte_addr = (addressbits[b1] << 4) + addressbits[b0];
498 byte_addr = (addressbits[b2 & 0x3] << 8) +
499 (addressbits[b1] << 4) + addressbits[b0];
500 bit_addr = addressbits[b2 >> 2];
502 buf[byte_addr] ^= (1 << bit_addr);
507 if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1)
525 unsigned char *read_ecc,
unsigned char *calc_ecc)