aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/nand_ecc.c
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-11-07 22:51:47 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-11-07 22:51:47 -0500
commit6b995751c2e851d2bc9c277b5884d0adb519e31d (patch)
tree7a15b41b5d8ce612915584a0773c670d5c0ab5b8 /drivers/mtd/nand/nand_ecc.c
parent6c2f4267833f453156f8f439cc32eb4c92f357b4 (diff)
parentd27ba47e7e8c466c18983a1779d611f82d6a354f (diff)
Merge branch 'master'
Diffstat (limited to 'drivers/mtd/nand/nand_ecc.c')
-rw-r--r--drivers/mtd/nand/nand_ecc.c44
1 files changed, 22 insertions, 22 deletions
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index 2e341b75437a..40ac909150a3 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -7,22 +7,22 @@
7 * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) 7 * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
8 * Toshiba America Electronics Components, Inc. 8 * Toshiba America Electronics Components, Inc.
9 * 9 *
10 * $Id: nand_ecc.c,v 1.14 2004/06/16 15:34:37 gleixner Exp $ 10 * $Id: nand_ecc.c,v 1.15 2005/11/07 11:14:30 gleixner Exp $
11 * 11 *
12 * This file is free software; you can redistribute it and/or modify it 12 * 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 13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 or (at your option) any 14 * Free Software Foundation; either version 2 or (at your option) any
15 * later version. 15 * later version.
16 * 16 *
17 * This file is distributed in the hope that it will be useful, but WITHOUT 17 * This file is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details. 20 * for more details.
21 * 21 *
22 * You should have received a copy of the GNU General Public License along 22 * You should have received a copy of the GNU General Public License along
23 * with this file; if not, write to the Free Software Foundation, Inc., 23 * with this file; if not, write to the Free Software Foundation, Inc.,
24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 * 25 *
26 * As a special exception, if other files instantiate templates or use 26 * As a special exception, if other files instantiate templates or use
27 * macros or inline functions from these files, or you compile these 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 28 * files and link them with other works to produce a work based on these
@@ -30,7 +30,7 @@
30 * covered by the GNU General Public License. However the source code for 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) 31 * these files must still be made available in accordance with section (3)
32 * of the GNU General Public License. 32 * of the GNU General Public License.
33 * 33 *
34 * This exception does not invalidate any other reasons why a work based on 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. 35 * this file might be covered by the GNU General Public License.
36 */ 36 */
@@ -67,7 +67,7 @@ static const u_char nand_ecc_precalc_table[] = {
67 * nand_trans_result - [GENERIC] create non-inverted ECC 67 * nand_trans_result - [GENERIC] create non-inverted ECC
68 * @reg2: line parity reg 2 68 * @reg2: line parity reg 2
69 * @reg3: line parity reg 3 69 * @reg3: line parity reg 3
70 * @ecc_code: ecc 70 * @ecc_code: ecc
71 * 71 *
72 * Creates non-inverted ECC code from line parity 72 * Creates non-inverted ECC code from line parity
73 */ 73 */
@@ -75,11 +75,11 @@ static void nand_trans_result(u_char reg2, u_char reg3,
75 u_char *ecc_code) 75 u_char *ecc_code)
76{ 76{
77 u_char a, b, i, tmp1, tmp2; 77 u_char a, b, i, tmp1, tmp2;
78 78
79 /* Initialize variables */ 79 /* Initialize variables */
80 a = b = 0x80; 80 a = b = 0x80;
81 tmp1 = tmp2 = 0; 81 tmp1 = tmp2 = 0;
82 82
83 /* Calculate first ECC byte */ 83 /* Calculate first ECC byte */
84 for (i = 0; i < 4; i++) { 84 for (i = 0; i < 4; i++) {
85 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ 85 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
@@ -90,7 +90,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
90 b >>= 1; 90 b >>= 1;
91 a >>= 1; 91 a >>= 1;
92 } 92 }
93 93
94 /* Calculate second ECC byte */ 94 /* Calculate second ECC byte */
95 b = 0x80; 95 b = 0x80;
96 for (i = 0; i < 4; i++) { 96 for (i = 0; i < 4; i++) {
@@ -102,7 +102,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
102 b >>= 1; 102 b >>= 1;
103 a >>= 1; 103 a >>= 1;
104 } 104 }
105 105
106 /* Store two of the ECC bytes */ 106 /* Store two of the ECC bytes */
107 ecc_code[0] = tmp1; 107 ecc_code[0] = tmp1;
108 ecc_code[1] = tmp2; 108 ecc_code[1] = tmp2;
@@ -118,28 +118,28 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
118{ 118{
119 u_char idx, reg1, reg2, reg3; 119 u_char idx, reg1, reg2, reg3;
120 int j; 120 int j;
121 121
122 /* Initialize variables */ 122 /* Initialize variables */
123 reg1 = reg2 = reg3 = 0; 123 reg1 = reg2 = reg3 = 0;
124 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; 124 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
125 125
126 /* Build up column parity */ 126 /* Build up column parity */
127 for(j = 0; j < 256; j++) { 127 for(j = 0; j < 256; j++) {
128 128
129 /* Get CP0 - CP5 from table */ 129 /* Get CP0 - CP5 from table */
130 idx = nand_ecc_precalc_table[dat[j]]; 130 idx = nand_ecc_precalc_table[dat[j]];
131 reg1 ^= (idx & 0x3f); 131 reg1 ^= (idx & 0x3f);
132 132
133 /* All bit XOR = 1 ? */ 133 /* All bit XOR = 1 ? */
134 if (idx & 0x40) { 134 if (idx & 0x40) {
135 reg3 ^= (u_char) j; 135 reg3 ^= (u_char) j;
136 reg2 ^= ~((u_char) j); 136 reg2 ^= ~((u_char) j);
137 } 137 }
138 } 138 }
139 139
140 /* Create non-inverted ECC code from line parity */ 140 /* Create non-inverted ECC code from line parity */
141 nand_trans_result(reg2, reg3, ecc_code); 141 nand_trans_result(reg2, reg3, ecc_code);
142 142
143 /* Calculate final ECC code */ 143 /* Calculate final ECC code */
144 ecc_code[0] = ~ecc_code[0]; 144 ecc_code[0] = ~ecc_code[0];
145 ecc_code[1] = ~ecc_code[1]; 145 ecc_code[1] = ~ecc_code[1];
@@ -159,12 +159,12 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
159int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) 159int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
160{ 160{
161 u_char a, b, c, d1, d2, d3, add, bit, i; 161 u_char a, b, c, d1, d2, d3, add, bit, i;
162 162
163 /* Do error detection */ 163 /* Do error detection */
164 d1 = calc_ecc[0] ^ read_ecc[0]; 164 d1 = calc_ecc[0] ^ read_ecc[0];
165 d2 = calc_ecc[1] ^ read_ecc[1]; 165 d2 = calc_ecc[1] ^ read_ecc[1];
166 d3 = calc_ecc[2] ^ read_ecc[2]; 166 d3 = calc_ecc[2] ^ read_ecc[2];
167 167
168 if ((d1 | d2 | d3) == 0) { 168 if ((d1 | d2 | d3) == 0) {
169 /* No errors */ 169 /* No errors */
170 return 0; 170 return 0;
@@ -173,7 +173,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
173 a = (d1 ^ (d1 >> 1)) & 0x55; 173 a = (d1 ^ (d1 >> 1)) & 0x55;
174 b = (d2 ^ (d2 >> 1)) & 0x55; 174 b = (d2 ^ (d2 >> 1)) & 0x55;
175 c = (d3 ^ (d3 >> 1)) & 0x54; 175 c = (d3 ^ (d3 >> 1)) & 0x54;
176 176
177 /* Found and will correct single bit error in the data */ 177 /* Found and will correct single bit error in the data */
178 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { 178 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
179 c = 0x80; 179 c = 0x80;
@@ -237,7 +237,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
237 } 237 }
238 } 238 }
239 } 239 }
240 240
241 /* Should never happen */ 241 /* Should never happen */
242 return -1; 242 return -1;
243} 243}