diff options
Diffstat (limited to 'drivers/mtd/nand/nand_ecc.c')
-rw-r--r-- | drivers/mtd/nand/nand_ecc.c | 554 |
1 files changed, 430 insertions, 124 deletions
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c index 918a806a8471..868147acce2c 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/nand_ecc.c | |||
@@ -1,13 +1,18 @@ | |||
1 | /* | 1 | /* |
2 | * This file contains an ECC algorithm from Toshiba that detects and | 2 | * This file contains an ECC algorithm that detects and corrects 1 bit |
3 | * corrects 1 bit errors in a 256 byte block of data. | 3 | * errors in a 256 byte block of data. |
4 | * | 4 | * |
5 | * drivers/mtd/nand/nand_ecc.c | 5 | * drivers/mtd/nand/nand_ecc.c |
6 | * | 6 | * |
7 | * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) | 7 | * Copyright © 2008 Koninklijke Philips Electronics NV. |
8 | * Toshiba America Electronics Components, Inc. | 8 | * Author: Frans Meulenbroeks |
9 | * | 9 | * |
10 | * Copyright (C) 2006 Thomas Gleixner <tglx@linutronix.de> | 10 | * Completely replaces the previous ECC implementation which was written by: |
11 | * Steven J. Hill (sjhill@realitydiluted.com) | ||
12 | * Thomas Gleixner (tglx@linutronix.de) | ||
13 | * | ||
14 | * Information on how this algorithm works and how it was developed | ||
15 | * can be found in Documentation/mtd/nand_ecc.txt | ||
11 | * | 16 | * |
12 | * This file is free software; you can redistribute it and/or modify it | 17 | * This file is free software; you can redistribute it and/or modify it |
13 | * under the terms of the GNU General Public License as published by the | 18 | * under the terms of the GNU General Public License as published by the |
@@ -23,174 +28,475 @@ | |||
23 | * with this file; if not, write to the Free Software Foundation, Inc., | 28 | * with this file; if not, write to the Free Software Foundation, Inc., |
24 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | 29 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
25 | * | 30 | * |
26 | * As a special exception, if other files instantiate templates or use | ||
27 | * macros or inline functions from these files, or you compile these | ||
28 | * files and link them with other works to produce a work based on these | ||
29 | * files, these files do not by themselves cause the resulting work to be | ||
30 | * covered by the GNU General Public License. However the source code for | ||
31 | * these files must still be made available in accordance with section (3) | ||
32 | * of the GNU General Public License. | ||
33 | * | ||
34 | * This exception does not invalidate any other reasons why a work based on | ||
35 | * this file might be covered by the GNU General Public License. | ||
36 | */ | 31 | */ |
37 | 32 | ||
33 | /* | ||
34 | * The STANDALONE macro is useful when running the code outside the kernel | ||
35 | * e.g. when running the code in a testbed or a benchmark program. | ||
36 | * When STANDALONE is used, the module related macros are commented out | ||
37 | * as well as the linux include files. | ||
38 | * Instead a private definition of mtd_info is given to satisfy the compiler | ||
39 | * (the code does not use mtd_info, so the code does not care) | ||
40 | */ | ||
41 | #ifndef STANDALONE | ||
38 | #include <linux/types.h> | 42 | #include <linux/types.h> |
39 | #include <linux/kernel.h> | 43 | #include <linux/kernel.h> |
40 | #include <linux/module.h> | 44 | #include <linux/module.h> |
45 | #include <linux/mtd/mtd.h> | ||
46 | #include <linux/mtd/nand.h> | ||
41 | #include <linux/mtd/nand_ecc.h> | 47 | #include <linux/mtd/nand_ecc.h> |
48 | #include <asm/byteorder.h> | ||
49 | #else | ||
50 | #include <stdint.h> | ||
51 | struct mtd_info; | ||
52 | #define EXPORT_SYMBOL(x) /* x */ | ||
53 | |||
54 | #define MODULE_LICENSE(x) /* x */ | ||
55 | #define MODULE_AUTHOR(x) /* x */ | ||
56 | #define MODULE_DESCRIPTION(x) /* x */ | ||
57 | |||
58 | #define printk printf | ||
59 | #define KERN_ERR "" | ||
60 | #endif | ||
61 | |||
62 | /* | ||
63 | * invparity is a 256 byte table that contains the odd parity | ||
64 | * for each byte. So if the number of bits in a byte is even, | ||
65 | * the array element is 1, and when the number of bits is odd | ||
66 | * the array eleemnt is 0. | ||
67 | */ | ||
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 | ||
85 | }; | ||
86 | |||
87 | /* | ||
88 | * bitsperbyte contains the number of bits per byte | ||
89 | * this is only used for testing and repairing parity | ||
90 | * (a precalculated value slightly improves performance) | ||
91 | */ | ||
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, | ||
109 | }; | ||
42 | 110 | ||
43 | /* | 111 | /* |
44 | * Pre-calculated 256-way 1 byte column parity | 112 | * addressbits is a lookup table to filter out the bits from the xor-ed |
113 | * ecc data that identify the faulty location. | ||
114 | * this is only used for repairing parity | ||
115 | * see the comments in nand_correct_data for more details | ||
45 | */ | 116 | */ |
46 | static const u_char nand_ecc_precalc_table[] = { | 117 | static const char addressbits[256] = { |
47 | 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00, | 118 | 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, |
48 | 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, | 119 | 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, |
49 | 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, | 120 | 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, |
50 | 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, | 121 | 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, |
51 | 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, | 122 | 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05, |
52 | 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, | 123 | 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07, |
53 | 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, | 124 | 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05, |
54 | 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, | 125 | 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07, |
55 | 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, | 126 | 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, |
56 | 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, | 127 | 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, |
57 | 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, | 128 | 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, |
58 | 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, | 129 | 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, |
59 | 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, | 130 | 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05, |
60 | 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, | 131 | 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07, |
61 | 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, | 132 | 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05, |
62 | 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 | 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 | ||
63 | }; | 150 | }; |
64 | 151 | ||
65 | /** | 152 | /** |
66 | * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256-byte block | 153 | * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256/512-byte |
154 | * block | ||
67 | * @mtd: MTD block structure | 155 | * @mtd: MTD block structure |
68 | * @dat: raw data | 156 | * @buf: input buffer with raw data |
69 | * @ecc_code: buffer for ECC | 157 | * @code: output buffer with ECC |
70 | */ | 158 | */ |
71 | int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, | 159 | int nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf, |
72 | u_char *ecc_code) | 160 | unsigned char *code) |
73 | { | 161 | { |
74 | uint8_t idx, reg1, reg2, reg3, tmp1, tmp2; | ||
75 | int i; | 162 | int i; |
163 | const uint32_t *bp = (uint32_t *)buf; | ||
164 | /* 256 or 512 bytes/ecc */ | ||
165 | const uint32_t eccsize_mult = | ||
166 | (((struct nand_chip *)mtd->priv)->ecc.size) >> 8; | ||
167 | uint32_t cur; /* current value in buffer */ | ||
168 | /* rp0..rp15..rp17 are the various accumulated parities (per byte) */ | ||
169 | uint32_t rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7; | ||
170 | uint32_t rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15, rp16; | ||
171 | uint32_t uninitialized_var(rp17); /* to make compiler happy */ | ||
172 | uint32_t par; /* the cumulative parity for all data */ | ||
173 | uint32_t tmppar; /* the cumulative parity for this iteration; | ||
174 | for rp12, rp14 and rp16 at the end of the | ||
175 | loop */ | ||
176 | |||
177 | par = 0; | ||
178 | rp4 = 0; | ||
179 | rp6 = 0; | ||
180 | rp8 = 0; | ||
181 | rp10 = 0; | ||
182 | rp12 = 0; | ||
183 | rp14 = 0; | ||
184 | rp16 = 0; | ||
185 | |||
186 | /* | ||
187 | * The loop is unrolled a number of times; | ||
188 | * This avoids if statements to decide on which rp value to update | ||
189 | * Also we process the data by longwords. | ||
190 | * Note: passing unaligned data might give a performance penalty. | ||
191 | * It is assumed that the buffers are aligned. | ||
192 | * tmppar is the cumulative sum of this iteration. | ||
193 | * needed for calculating rp12, rp14, rp16 and par | ||
194 | * also used as a performance improvement for rp6, rp8 and rp10 | ||
195 | */ | ||
196 | for (i = 0; i < eccsize_mult << 2; i++) { | ||
197 | cur = *bp++; | ||
198 | tmppar = cur; | ||
199 | rp4 ^= cur; | ||
200 | cur = *bp++; | ||
201 | tmppar ^= cur; | ||
202 | rp6 ^= tmppar; | ||
203 | cur = *bp++; | ||
204 | tmppar ^= cur; | ||
205 | rp4 ^= cur; | ||
206 | cur = *bp++; | ||
207 | tmppar ^= cur; | ||
208 | rp8 ^= tmppar; | ||
76 | 209 | ||
77 | /* Initialize variables */ | 210 | cur = *bp++; |
78 | reg1 = reg2 = reg3 = 0; | 211 | tmppar ^= cur; |
212 | rp4 ^= cur; | ||
213 | rp6 ^= cur; | ||
214 | cur = *bp++; | ||
215 | tmppar ^= cur; | ||
216 | rp6 ^= cur; | ||
217 | cur = *bp++; | ||
218 | tmppar ^= cur; | ||
219 | rp4 ^= cur; | ||
220 | cur = *bp++; | ||
221 | tmppar ^= cur; | ||
222 | rp10 ^= tmppar; | ||
79 | 223 | ||
80 | /* Build up column parity */ | 224 | cur = *bp++; |
81 | for(i = 0; i < 256; i++) { | 225 | tmppar ^= cur; |
82 | /* Get CP0 - CP5 from table */ | 226 | rp4 ^= cur; |
83 | idx = nand_ecc_precalc_table[*dat++]; | 227 | rp6 ^= cur; |
84 | reg1 ^= (idx & 0x3f); | 228 | rp8 ^= cur; |
229 | cur = *bp++; | ||
230 | tmppar ^= cur; | ||
231 | rp6 ^= cur; | ||
232 | rp8 ^= cur; | ||
233 | cur = *bp++; | ||
234 | tmppar ^= cur; | ||
235 | rp4 ^= cur; | ||
236 | rp8 ^= cur; | ||
237 | cur = *bp++; | ||
238 | tmppar ^= cur; | ||
239 | rp8 ^= cur; | ||
85 | 240 | ||
86 | /* All bit XOR = 1 ? */ | 241 | cur = *bp++; |
87 | if (idx & 0x40) { | 242 | tmppar ^= cur; |
88 | reg3 ^= (uint8_t) i; | 243 | rp4 ^= cur; |
89 | reg2 ^= ~((uint8_t) i); | 244 | rp6 ^= cur; |
90 | } | 245 | cur = *bp++; |
246 | tmppar ^= cur; | ||
247 | rp6 ^= cur; | ||
248 | cur = *bp++; | ||
249 | tmppar ^= cur; | ||
250 | rp4 ^= cur; | ||
251 | cur = *bp++; | ||
252 | tmppar ^= cur; | ||
253 | |||
254 | par ^= tmppar; | ||
255 | if ((i & 0x1) == 0) | ||
256 | rp12 ^= tmppar; | ||
257 | if ((i & 0x2) == 0) | ||
258 | rp14 ^= tmppar; | ||
259 | if (eccsize_mult == 2 && (i & 0x4) == 0) | ||
260 | rp16 ^= tmppar; | ||
91 | } | 261 | } |
92 | 262 | ||
93 | /* Create non-inverted ECC code from line parity */ | 263 | /* |
94 | tmp1 = (reg3 & 0x80) >> 0; /* B7 -> B7 */ | 264 | * handle the fact that we use longword operations |
95 | tmp1 |= (reg2 & 0x80) >> 1; /* B7 -> B6 */ | 265 | * we'll bring rp4..rp14..rp16 back to single byte entities by |
96 | tmp1 |= (reg3 & 0x40) >> 1; /* B6 -> B5 */ | 266 | * shifting and xoring first fold the upper and lower 16 bits, |
97 | tmp1 |= (reg2 & 0x40) >> 2; /* B6 -> B4 */ | 267 | * then the upper and lower 8 bits. |
98 | tmp1 |= (reg3 & 0x20) >> 2; /* B5 -> B3 */ | 268 | */ |
99 | tmp1 |= (reg2 & 0x20) >> 3; /* B5 -> B2 */ | 269 | rp4 ^= (rp4 >> 16); |
100 | tmp1 |= (reg3 & 0x10) >> 3; /* B4 -> B1 */ | 270 | rp4 ^= (rp4 >> 8); |
101 | tmp1 |= (reg2 & 0x10) >> 4; /* B4 -> B0 */ | 271 | rp4 &= 0xff; |
102 | 272 | rp6 ^= (rp6 >> 16); | |
103 | tmp2 = (reg3 & 0x08) << 4; /* B3 -> B7 */ | 273 | rp6 ^= (rp6 >> 8); |
104 | tmp2 |= (reg2 & 0x08) << 3; /* B3 -> B6 */ | 274 | rp6 &= 0xff; |
105 | tmp2 |= (reg3 & 0x04) << 3; /* B2 -> B5 */ | 275 | rp8 ^= (rp8 >> 16); |
106 | tmp2 |= (reg2 & 0x04) << 2; /* B2 -> B4 */ | 276 | rp8 ^= (rp8 >> 8); |
107 | tmp2 |= (reg3 & 0x02) << 2; /* B1 -> B3 */ | 277 | rp8 &= 0xff; |
108 | tmp2 |= (reg2 & 0x02) << 1; /* B1 -> B2 */ | 278 | rp10 ^= (rp10 >> 16); |
109 | tmp2 |= (reg3 & 0x01) << 1; /* B0 -> B1 */ | 279 | rp10 ^= (rp10 >> 8); |
110 | tmp2 |= (reg2 & 0x01) << 0; /* B7 -> B0 */ | 280 | rp10 &= 0xff; |
111 | 281 | rp12 ^= (rp12 >> 16); | |
112 | /* Calculate final ECC code */ | 282 | rp12 ^= (rp12 >> 8); |
113 | #ifdef CONFIG_MTD_NAND_ECC_SMC | 283 | rp12 &= 0xff; |
114 | ecc_code[0] = ~tmp2; | 284 | rp14 ^= (rp14 >> 16); |
115 | ecc_code[1] = ~tmp1; | 285 | rp14 ^= (rp14 >> 8); |
286 | rp14 &= 0xff; | ||
287 | if (eccsize_mult == 2) { | ||
288 | rp16 ^= (rp16 >> 16); | ||
289 | rp16 ^= (rp16 >> 8); | ||
290 | rp16 &= 0xff; | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | * we also need to calculate the row parity for rp0..rp3 | ||
295 | * This is present in par, because par is now | ||
296 | * rp3 rp3 rp2 rp2 in little endian and | ||
297 | * rp2 rp2 rp3 rp3 in big endian | ||
298 | * as well as | ||
299 | * rp1 rp0 rp1 rp0 in little endian and | ||
300 | * rp0 rp1 rp0 rp1 in big endian | ||
301 | * First calculate rp2 and rp3 | ||
302 | */ | ||
303 | #ifdef __BIG_ENDIAN | ||
304 | rp2 = (par >> 16); | ||
305 | rp2 ^= (rp2 >> 8); | ||
306 | rp2 &= 0xff; | ||
307 | rp3 = par & 0xffff; | ||
308 | rp3 ^= (rp3 >> 8); | ||
309 | rp3 &= 0xff; | ||
116 | #else | 310 | #else |
117 | ecc_code[0] = ~tmp1; | 311 | rp3 = (par >> 16); |
118 | ecc_code[1] = ~tmp2; | 312 | rp3 ^= (rp3 >> 8); |
313 | rp3 &= 0xff; | ||
314 | rp2 = par & 0xffff; | ||
315 | rp2 ^= (rp2 >> 8); | ||
316 | rp2 &= 0xff; | ||
119 | #endif | 317 | #endif |
120 | ecc_code[2] = ((~reg1) << 2) | 0x03; | ||
121 | 318 | ||
122 | return 0; | 319 | /* reduce par to 16 bits then calculate rp1 and rp0 */ |
123 | } | 320 | par ^= (par >> 16); |
124 | EXPORT_SYMBOL(nand_calculate_ecc); | 321 | #ifdef __BIG_ENDIAN |
322 | rp0 = (par >> 8) & 0xff; | ||
323 | rp1 = (par & 0xff); | ||
324 | #else | ||
325 | rp1 = (par >> 8) & 0xff; | ||
326 | rp0 = (par & 0xff); | ||
327 | #endif | ||
125 | 328 | ||
126 | static inline int countbits(uint32_t byte) | 329 | /* finally reduce par to 8 bits */ |
127 | { | 330 | par ^= (par >> 8); |
128 | int res = 0; | 331 | par &= 0xff; |
129 | 332 | ||
130 | for (;byte; byte >>= 1) | 333 | /* |
131 | res += byte & 0x01; | 334 | * and calculate rp5..rp15..rp17 |
132 | return res; | 335 | * note that par = rp4 ^ rp5 and due to the commutative property |
336 | * of the ^ operator we can say: | ||
337 | * rp5 = (par ^ rp4); | ||
338 | * The & 0xff seems superfluous, but benchmarking learned that | ||
339 | * leaving it out gives slightly worse results. No idea why, probably | ||
340 | * it has to do with the way the pipeline in pentium is organized. | ||
341 | */ | ||
342 | rp5 = (par ^ rp4) & 0xff; | ||
343 | rp7 = (par ^ rp6) & 0xff; | ||
344 | rp9 = (par ^ rp8) & 0xff; | ||
345 | rp11 = (par ^ rp10) & 0xff; | ||
346 | rp13 = (par ^ rp12) & 0xff; | ||
347 | rp15 = (par ^ rp14) & 0xff; | ||
348 | if (eccsize_mult == 2) | ||
349 | rp17 = (par ^ rp16) & 0xff; | ||
350 | |||
351 | /* | ||
352 | * Finally calculate the ecc bits. | ||
353 | * Again here it might seem that there are performance optimisations | ||
354 | * possible, but benchmarks showed that on the system this is developed | ||
355 | * the code below is the fastest | ||
356 | */ | ||
357 | #ifdef CONFIG_MTD_NAND_ECC_SMC | ||
358 | code[0] = | ||
359 | (invparity[rp7] << 7) | | ||
360 | (invparity[rp6] << 6) | | ||
361 | (invparity[rp5] << 5) | | ||
362 | (invparity[rp4] << 4) | | ||
363 | (invparity[rp3] << 3) | | ||
364 | (invparity[rp2] << 2) | | ||
365 | (invparity[rp1] << 1) | | ||
366 | (invparity[rp0]); | ||
367 | code[1] = | ||
368 | (invparity[rp15] << 7) | | ||
369 | (invparity[rp14] << 6) | | ||
370 | (invparity[rp13] << 5) | | ||
371 | (invparity[rp12] << 4) | | ||
372 | (invparity[rp11] << 3) | | ||
373 | (invparity[rp10] << 2) | | ||
374 | (invparity[rp9] << 1) | | ||
375 | (invparity[rp8]); | ||
376 | #else | ||
377 | code[1] = | ||
378 | (invparity[rp7] << 7) | | ||
379 | (invparity[rp6] << 6) | | ||
380 | (invparity[rp5] << 5) | | ||
381 | (invparity[rp4] << 4) | | ||
382 | (invparity[rp3] << 3) | | ||
383 | (invparity[rp2] << 2) | | ||
384 | (invparity[rp1] << 1) | | ||
385 | (invparity[rp0]); | ||
386 | code[0] = | ||
387 | (invparity[rp15] << 7) | | ||
388 | (invparity[rp14] << 6) | | ||
389 | (invparity[rp13] << 5) | | ||
390 | (invparity[rp12] << 4) | | ||
391 | (invparity[rp11] << 3) | | ||
392 | (invparity[rp10] << 2) | | ||
393 | (invparity[rp9] << 1) | | ||
394 | (invparity[rp8]); | ||
395 | #endif | ||
396 | if (eccsize_mult == 1) | ||
397 | code[2] = | ||
398 | (invparity[par & 0xf0] << 7) | | ||
399 | (invparity[par & 0x0f] << 6) | | ||
400 | (invparity[par & 0xcc] << 5) | | ||
401 | (invparity[par & 0x33] << 4) | | ||
402 | (invparity[par & 0xaa] << 3) | | ||
403 | (invparity[par & 0x55] << 2) | | ||
404 | 3; | ||
405 | else | ||
406 | code[2] = | ||
407 | (invparity[par & 0xf0] << 7) | | ||
408 | (invparity[par & 0x0f] << 6) | | ||
409 | (invparity[par & 0xcc] << 5) | | ||
410 | (invparity[par & 0x33] << 4) | | ||
411 | (invparity[par & 0xaa] << 3) | | ||
412 | (invparity[par & 0x55] << 2) | | ||
413 | (invparity[rp17] << 1) | | ||
414 | (invparity[rp16] << 0); | ||
415 | return 0; | ||
133 | } | 416 | } |
417 | EXPORT_SYMBOL(nand_calculate_ecc); | ||
134 | 418 | ||
135 | /** | 419 | /** |
136 | * nand_correct_data - [NAND Interface] Detect and correct bit error(s) | 420 | * nand_correct_data - [NAND Interface] Detect and correct bit error(s) |
137 | * @mtd: MTD block structure | 421 | * @mtd: MTD block structure |
138 | * @dat: raw data read from the chip | 422 | * @buf: raw data read from the chip |
139 | * @read_ecc: ECC from the chip | 423 | * @read_ecc: ECC from the chip |
140 | * @calc_ecc: the ECC calculated from raw data | 424 | * @calc_ecc: the ECC calculated from raw data |
141 | * | 425 | * |
142 | * Detect and correct a 1 bit error for 256 byte block | 426 | * Detect and correct a 1 bit error for 256/512 byte block |
143 | */ | 427 | */ |
144 | int nand_correct_data(struct mtd_info *mtd, u_char *dat, | 428 | int nand_correct_data(struct mtd_info *mtd, unsigned char *buf, |
145 | u_char *read_ecc, u_char *calc_ecc) | 429 | unsigned char *read_ecc, unsigned char *calc_ecc) |
146 | { | 430 | { |
147 | uint8_t s0, s1, s2; | 431 | unsigned char b0, b1, b2; |
432 | unsigned char byte_addr, bit_addr; | ||
433 | /* 256 or 512 bytes/ecc */ | ||
434 | const uint32_t eccsize_mult = | ||
435 | (((struct nand_chip *)mtd->priv)->ecc.size) >> 8; | ||
148 | 436 | ||
437 | /* | ||
438 | * b0 to b2 indicate which bit is faulty (if any) | ||
439 | * we might need the xor result more than once, | ||
440 | * so keep them in a local var | ||
441 | */ | ||
149 | #ifdef CONFIG_MTD_NAND_ECC_SMC | 442 | #ifdef CONFIG_MTD_NAND_ECC_SMC |
150 | s0 = calc_ecc[0] ^ read_ecc[0]; | 443 | b0 = read_ecc[0] ^ calc_ecc[0]; |
151 | s1 = calc_ecc[1] ^ read_ecc[1]; | 444 | b1 = read_ecc[1] ^ calc_ecc[1]; |
152 | s2 = calc_ecc[2] ^ read_ecc[2]; | ||
153 | #else | 445 | #else |
154 | s1 = calc_ecc[0] ^ read_ecc[0]; | 446 | b0 = read_ecc[1] ^ calc_ecc[1]; |
155 | s0 = calc_ecc[1] ^ read_ecc[1]; | 447 | b1 = read_ecc[0] ^ calc_ecc[0]; |
156 | s2 = calc_ecc[2] ^ read_ecc[2]; | ||
157 | #endif | 448 | #endif |
158 | if ((s0 | s1 | s2) == 0) | 449 | b2 = read_ecc[2] ^ calc_ecc[2]; |
159 | return 0; | ||
160 | |||
161 | /* Check for a single bit error */ | ||
162 | if( ((s0 ^ (s0 >> 1)) & 0x55) == 0x55 && | ||
163 | ((s1 ^ (s1 >> 1)) & 0x55) == 0x55 && | ||
164 | ((s2 ^ (s2 >> 1)) & 0x54) == 0x54) { | ||
165 | 450 | ||
166 | uint32_t byteoffs, bitnum; | 451 | /* check if there are any bitfaults */ |
167 | 452 | ||
168 | byteoffs = (s1 << 0) & 0x80; | 453 | /* repeated if statements are slightly more efficient than switch ... */ |
169 | byteoffs |= (s1 << 1) & 0x40; | 454 | /* ordered in order of likelihood */ |
170 | byteoffs |= (s1 << 2) & 0x20; | ||
171 | byteoffs |= (s1 << 3) & 0x10; | ||
172 | 455 | ||
173 | byteoffs |= (s0 >> 4) & 0x08; | 456 | if ((b0 | b1 | b2) == 0) |
174 | byteoffs |= (s0 >> 3) & 0x04; | 457 | return 0; /* no error */ |
175 | byteoffs |= (s0 >> 2) & 0x02; | ||
176 | byteoffs |= (s0 >> 1) & 0x01; | ||
177 | |||
178 | bitnum = (s2 >> 5) & 0x04; | ||
179 | bitnum |= (s2 >> 4) & 0x02; | ||
180 | bitnum |= (s2 >> 3) & 0x01; | ||
181 | |||
182 | dat[byteoffs] ^= (1 << bitnum); | ||
183 | 458 | ||
459 | if ((((b0 ^ (b0 >> 1)) & 0x55) == 0x55) && | ||
460 | (((b1 ^ (b1 >> 1)) & 0x55) == 0x55) && | ||
461 | ((eccsize_mult == 1 && ((b2 ^ (b2 >> 1)) & 0x54) == 0x54) || | ||
462 | (eccsize_mult == 2 && ((b2 ^ (b2 >> 1)) & 0x55) == 0x55))) { | ||
463 | /* single bit error */ | ||
464 | /* | ||
465 | * rp17/rp15/13/11/9/7/5/3/1 indicate which byte is the faulty | ||
466 | * byte, cp 5/3/1 indicate the faulty bit. | ||
467 | * A lookup table (called addressbits) is used to filter | ||
468 | * the bits from the byte they are in. | ||
469 | * A marginal optimisation is possible by having three | ||
470 | * different lookup tables. | ||
471 | * One as we have now (for b0), one for b2 | ||
472 | * (that would avoid the >> 1), and one for b1 (with all values | ||
473 | * << 4). However it was felt that introducing two more tables | ||
474 | * hardly justify the gain. | ||
475 | * | ||
476 | * The b2 shift is there to get rid of the lowest two bits. | ||
477 | * We could also do addressbits[b2] >> 1 but for the | ||
478 | * performace it does not make any difference | ||
479 | */ | ||
480 | if (eccsize_mult == 1) | ||
481 | byte_addr = (addressbits[b1] << 4) + addressbits[b0]; | ||
482 | else | ||
483 | byte_addr = (addressbits[b2 & 0x3] << 8) + | ||
484 | (addressbits[b1] << 4) + addressbits[b0]; | ||
485 | bit_addr = addressbits[b2 >> 2]; | ||
486 | /* flip the bit */ | ||
487 | buf[byte_addr] ^= (1 << bit_addr); | ||
184 | return 1; | 488 | return 1; |
185 | } | ||
186 | 489 | ||
187 | if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1) | 490 | } |
188 | return 1; | 491 | /* count nr of bits; use table lookup, faster than calculating it */ |
492 | if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1) | ||
493 | return 1; /* error in ecc data; no action needed */ | ||
189 | 494 | ||
190 | return -EBADMSG; | 495 | printk(KERN_ERR "uncorrectable error : "); |
496 | return -1; | ||
191 | } | 497 | } |
192 | EXPORT_SYMBOL(nand_correct_data); | 498 | EXPORT_SYMBOL(nand_correct_data); |
193 | 499 | ||
194 | MODULE_LICENSE("GPL"); | 500 | MODULE_LICENSE("GPL"); |
195 | MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>"); | 501 | MODULE_AUTHOR("Frans Meulenbroeks <fransmeulenbroeks@gmail.com>"); |
196 | MODULE_DESCRIPTION("Generic NAND ECC support"); | 502 | MODULE_DESCRIPTION("Generic NAND ECC support"); |