1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31#include <linux/types.h>
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/mtd/mtd.h>
35#include <linux/mtd/rawnand.h>
36#include <linux/mtd/nand_ecc.h>
37#include <asm/byteorder.h>
38
39
40
41
42
43
44
45static const char invparity[256] = {
46 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
47 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
48 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
49 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
50 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
51 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
52 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
53 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
54 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
55 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
56 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
57 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
58 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
59 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
60 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
61 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
62};
63
64
65
66
67
68
69static const char bitsperbyte[256] = {
70 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
71 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
72 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
73 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
74 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
75 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
76 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
77 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
78 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
79 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
80 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
81 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
82 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
83 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
84 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
85 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
86};
87
88
89
90
91
92
93
94static const char addressbits[256] = {
95 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
96 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
97 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
98 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
99 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
100 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
101 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
102 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
103 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
104 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
105 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
106 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
107 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
108 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
109 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
110 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
111 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
112 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
113 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
114 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
115 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
116 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
117 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
118 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
119 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
120 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
121 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
122 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
123 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
124 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
125 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
126 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f
127};
128
129
130
131
132
133
134
135
136void __nand_calculate_ecc(const unsigned char *buf, unsigned int eccsize,
137 unsigned char *code)
138{
139 int i;
140 const uint32_t *bp = (uint32_t *)buf;
141
142 const uint32_t eccsize_mult = eccsize >> 8;
143 uint32_t cur;
144
145 uint32_t rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7;
146 uint32_t rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15, rp16;
147 uint32_t uninitialized_var(rp17);
148 uint32_t par;
149 uint32_t tmppar;
150
151
152
153 par = 0;
154 rp4 = 0;
155 rp6 = 0;
156 rp8 = 0;
157 rp10 = 0;
158 rp12 = 0;
159 rp14 = 0;
160 rp16 = 0;
161
162
163
164
165
166
167
168
169
170
171
172 for (i = 0; i < eccsize_mult << 2; i++) {
173 cur = *bp++;
174 tmppar = cur;
175 rp4 ^= cur;
176 cur = *bp++;
177 tmppar ^= cur;
178 rp6 ^= tmppar;
179 cur = *bp++;
180 tmppar ^= cur;
181 rp4 ^= cur;
182 cur = *bp++;
183 tmppar ^= cur;
184 rp8 ^= tmppar;
185
186 cur = *bp++;
187 tmppar ^= cur;
188 rp4 ^= cur;
189 rp6 ^= cur;
190 cur = *bp++;
191 tmppar ^= cur;
192 rp6 ^= cur;
193 cur = *bp++;
194 tmppar ^= cur;
195 rp4 ^= cur;
196 cur = *bp++;
197 tmppar ^= cur;
198 rp10 ^= tmppar;
199
200 cur = *bp++;
201 tmppar ^= cur;
202 rp4 ^= cur;
203 rp6 ^= cur;
204 rp8 ^= cur;
205 cur = *bp++;
206 tmppar ^= cur;
207 rp6 ^= cur;
208 rp8 ^= cur;
209 cur = *bp++;
210 tmppar ^= cur;
211 rp4 ^= cur;
212 rp8 ^= cur;
213 cur = *bp++;
214 tmppar ^= cur;
215 rp8 ^= cur;
216
217 cur = *bp++;
218 tmppar ^= cur;
219 rp4 ^= cur;
220 rp6 ^= cur;
221 cur = *bp++;
222 tmppar ^= cur;
223 rp6 ^= cur;
224 cur = *bp++;
225 tmppar ^= cur;
226 rp4 ^= cur;
227 cur = *bp++;
228 tmppar ^= cur;
229
230 par ^= tmppar;
231 if ((i & 0x1) == 0)
232 rp12 ^= tmppar;
233 if ((i & 0x2) == 0)
234 rp14 ^= tmppar;
235 if (eccsize_mult == 2 && (i & 0x4) == 0)
236 rp16 ^= tmppar;
237 }
238
239
240
241
242
243
244
245 rp4 ^= (rp4 >> 16);
246 rp4 ^= (rp4 >> 8);
247 rp4 &= 0xff;
248 rp6 ^= (rp6 >> 16);
249 rp6 ^= (rp6 >> 8);
250 rp6 &= 0xff;
251 rp8 ^= (rp8 >> 16);
252 rp8 ^= (rp8 >> 8);
253 rp8 &= 0xff;
254 rp10 ^= (rp10 >> 16);
255 rp10 ^= (rp10 >> 8);
256 rp10 &= 0xff;
257 rp12 ^= (rp12 >> 16);
258 rp12 ^= (rp12 >> 8);
259 rp12 &= 0xff;
260 rp14 ^= (rp14 >> 16);
261 rp14 ^= (rp14 >> 8);
262 rp14 &= 0xff;
263 if (eccsize_mult == 2) {
264 rp16 ^= (rp16 >> 16);
265 rp16 ^= (rp16 >> 8);
266 rp16 &= 0xff;
267 }
268
269
270
271
272
273
274
275
276
277
278
279#ifdef __BIG_ENDIAN
280 rp2 = (par >> 16);
281 rp2 ^= (rp2 >> 8);
282 rp2 &= 0xff;
283 rp3 = par & 0xffff;
284 rp3 ^= (rp3 >> 8);
285 rp3 &= 0xff;
286#else
287 rp3 = (par >> 16);
288 rp3 ^= (rp3 >> 8);
289 rp3 &= 0xff;
290 rp2 = par & 0xffff;
291 rp2 ^= (rp2 >> 8);
292 rp2 &= 0xff;
293#endif
294
295
296 par ^= (par >> 16);
297#ifdef __BIG_ENDIAN
298 rp0 = (par >> 8) & 0xff;
299 rp1 = (par & 0xff);
300#else
301 rp1 = (par >> 8) & 0xff;
302 rp0 = (par & 0xff);
303#endif
304
305
306 par ^= (par >> 8);
307 par &= 0xff;
308
309
310
311
312
313
314
315
316
317
318 rp5 = (par ^ rp4) & 0xff;
319 rp7 = (par ^ rp6) & 0xff;
320 rp9 = (par ^ rp8) & 0xff;
321 rp11 = (par ^ rp10) & 0xff;
322 rp13 = (par ^ rp12) & 0xff;
323 rp15 = (par ^ rp14) & 0xff;
324 if (eccsize_mult == 2)
325 rp17 = (par ^ rp16) & 0xff;
326
327
328
329
330
331
332
333#ifdef CONFIG_MTD_NAND_ECC_SMC
334 code[0] =
335 (invparity[rp7] << 7) |
336 (invparity[rp6] << 6) |
337 (invparity[rp5] << 5) |
338 (invparity[rp4] << 4) |
339 (invparity[rp3] << 3) |
340 (invparity[rp2] << 2) |
341 (invparity[rp1] << 1) |
342 (invparity[rp0]);
343 code[1] =
344 (invparity[rp15] << 7) |
345 (invparity[rp14] << 6) |
346 (invparity[rp13] << 5) |
347 (invparity[rp12] << 4) |
348 (invparity[rp11] << 3) |
349 (invparity[rp10] << 2) |
350 (invparity[rp9] << 1) |
351 (invparity[rp8]);
352#else
353 code[1] =
354 (invparity[rp7] << 7) |
355 (invparity[rp6] << 6) |
356 (invparity[rp5] << 5) |
357 (invparity[rp4] << 4) |
358 (invparity[rp3] << 3) |
359 (invparity[rp2] << 2) |
360 (invparity[rp1] << 1) |
361 (invparity[rp0]);
362 code[0] =
363 (invparity[rp15] << 7) |
364 (invparity[rp14] << 6) |
365 (invparity[rp13] << 5) |
366 (invparity[rp12] << 4) |
367 (invparity[rp11] << 3) |
368 (invparity[rp10] << 2) |
369 (invparity[rp9] << 1) |
370 (invparity[rp8]);
371#endif
372 if (eccsize_mult == 1)
373 code[2] =
374 (invparity[par & 0xf0] << 7) |
375 (invparity[par & 0x0f] << 6) |
376 (invparity[par & 0xcc] << 5) |
377 (invparity[par & 0x33] << 4) |
378 (invparity[par & 0xaa] << 3) |
379 (invparity[par & 0x55] << 2) |
380 3;
381 else
382 code[2] =
383 (invparity[par & 0xf0] << 7) |
384 (invparity[par & 0x0f] << 6) |
385 (invparity[par & 0xcc] << 5) |
386 (invparity[par & 0x33] << 4) |
387 (invparity[par & 0xaa] << 3) |
388 (invparity[par & 0x55] << 2) |
389 (invparity[rp17] << 1) |
390 (invparity[rp16] << 0);
391}
392EXPORT_SYMBOL(__nand_calculate_ecc);
393
394
395
396
397
398
399
400
401int nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf,
402 unsigned char *code)
403{
404 __nand_calculate_ecc(buf,
405 mtd_to_nand(mtd)->ecc.size, code);
406
407 return 0;
408}
409EXPORT_SYMBOL(nand_calculate_ecc);
410
411
412
413
414
415
416
417
418
419
420int __nand_correct_data(unsigned char *buf,
421 unsigned char *read_ecc, unsigned char *calc_ecc,
422 unsigned int eccsize)
423{
424 unsigned char b0, b1, b2, bit_addr;
425 unsigned int byte_addr;
426
427 const uint32_t eccsize_mult = eccsize >> 8;
428
429
430
431
432
433
434#ifdef CONFIG_MTD_NAND_ECC_SMC
435 b0 = read_ecc[0] ^ calc_ecc[0];
436 b1 = read_ecc[1] ^ calc_ecc[1];
437#else
438 b0 = read_ecc[1] ^ calc_ecc[1];
439 b1 = read_ecc[0] ^ calc_ecc[0];
440#endif
441 b2 = read_ecc[2] ^ calc_ecc[2];
442
443
444
445
446
447
448 if ((b0 | b1 | b2) == 0)
449 return 0;
450
451 if ((((b0 ^ (b0 >> 1)) & 0x55) == 0x55) &&
452 (((b1 ^ (b1 >> 1)) & 0x55) == 0x55) &&
453 ((eccsize_mult == 1 && ((b2 ^ (b2 >> 1)) & 0x54) == 0x54) ||
454 (eccsize_mult == 2 && ((b2 ^ (b2 >> 1)) & 0x55) == 0x55))) {
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472 if (eccsize_mult == 1)
473 byte_addr = (addressbits[b1] << 4) + addressbits[b0];
474 else
475 byte_addr = (addressbits[b2 & 0x3] << 8) +
476 (addressbits[b1] << 4) + addressbits[b0];
477 bit_addr = addressbits[b2 >> 2];
478
479 buf[byte_addr] ^= (1 << bit_addr);
480 return 1;
481
482 }
483
484 if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1)
485 return 1;
486
487 pr_err("%s: uncorrectable ECC error\n", __func__);
488 return -EBADMSG;
489}
490EXPORT_SYMBOL(__nand_correct_data);
491
492
493
494
495
496
497
498
499
500
501int nand_correct_data(struct mtd_info *mtd, unsigned char *buf,
502 unsigned char *read_ecc, unsigned char *calc_ecc)
503{
504 return __nand_correct_data(buf, read_ecc, calc_ecc,
505 mtd_to_nand(mtd)->ecc.size);
506}
507EXPORT_SYMBOL(nand_correct_data);
508
509MODULE_LICENSE("GPL");
510MODULE_AUTHOR("Frans Meulenbroeks <fransmeulenbroeks@gmail.com>");
511MODULE_DESCRIPTION("Generic NAND ECC support");
512