diff options
-rw-r--r-- | drivers/mtd/nand/Kconfig | 15 | ||||
-rw-r--r-- | drivers/mtd/nand/Makefile | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 40 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_bch.c | 243 | ||||
-rw-r--r-- | include/linux/mtd/nand.h | 3 | ||||
-rw-r--r-- | include/linux/mtd/nand_bch.h | 72 |
6 files changed, 373 insertions, 1 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index c89592239bc7..78205ac2b10f 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -31,6 +31,21 @@ config MTD_NAND_VERIFY_WRITE | |||
31 | device thinks the write was successful, a bit could have been | 31 | device thinks the write was successful, a bit could have been |
32 | flipped accidentally due to device wear or something else. | 32 | flipped accidentally due to device wear or something else. |
33 | 33 | ||
34 | config MTD_NAND_BCH | ||
35 | tristate | ||
36 | select BCH | ||
37 | depends on MTD_NAND_ECC_BCH | ||
38 | default MTD_NAND | ||
39 | |||
40 | config MTD_NAND_ECC_BCH | ||
41 | bool "Support software BCH ECC" | ||
42 | default n | ||
43 | help | ||
44 | This enables support for software BCH error correction. Binary BCH | ||
45 | codes are more powerful and cpu intensive than traditional Hamming | ||
46 | ECC codes. They are used with NAND devices requiring more than 1 bit | ||
47 | of error correction. | ||
48 | |||
34 | config MTD_SM_COMMON | 49 | config MTD_SM_COMMON |
35 | tristate | 50 | tristate |
36 | default n | 51 | default n |
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 8ad6faec72cb..5745d831168e 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_MTD_NAND) += nand.o | 5 | obj-$(CONFIG_MTD_NAND) += nand.o |
6 | obj-$(CONFIG_MTD_NAND_ECC) += nand_ecc.o | 6 | obj-$(CONFIG_MTD_NAND_ECC) += nand_ecc.o |
7 | obj-$(CONFIG_MTD_NAND_BCH) += nand_bch.o | ||
7 | obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o | 8 | obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o |
8 | obj-$(CONFIG_MTD_SM_COMMON) += sm_common.o | 9 | obj-$(CONFIG_MTD_SM_COMMON) += sm_common.o |
9 | 10 | ||
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index da7604050347..85cfc061d41c 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/mtd/mtd.h> | 42 | #include <linux/mtd/mtd.h> |
43 | #include <linux/mtd/nand.h> | 43 | #include <linux/mtd/nand.h> |
44 | #include <linux/mtd/nand_ecc.h> | 44 | #include <linux/mtd/nand_ecc.h> |
45 | #include <linux/mtd/nand_bch.h> | ||
45 | #include <linux/interrupt.h> | 46 | #include <linux/interrupt.h> |
46 | #include <linux/bitops.h> | 47 | #include <linux/bitops.h> |
47 | #include <linux/leds.h> | 48 | #include <linux/leds.h> |
@@ -3248,7 +3249,7 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
3248 | /* | 3249 | /* |
3249 | * If no default placement scheme is given, select an appropriate one | 3250 | * If no default placement scheme is given, select an appropriate one |
3250 | */ | 3251 | */ |
3251 | if (!chip->ecc.layout) { | 3252 | if (!chip->ecc.layout && (chip->ecc.mode != NAND_ECC_SOFT_BCH)) { |
3252 | switch (mtd->oobsize) { | 3253 | switch (mtd->oobsize) { |
3253 | case 8: | 3254 | case 8: |
3254 | chip->ecc.layout = &nand_oob_8; | 3255 | chip->ecc.layout = &nand_oob_8; |
@@ -3351,6 +3352,40 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
3351 | chip->ecc.bytes = 3; | 3352 | chip->ecc.bytes = 3; |
3352 | break; | 3353 | break; |
3353 | 3354 | ||
3355 | case NAND_ECC_SOFT_BCH: | ||
3356 | if (!mtd_nand_has_bch()) { | ||
3357 | printk(KERN_WARNING "CONFIG_MTD_ECC_BCH not enabled\n"); | ||
3358 | BUG(); | ||
3359 | } | ||
3360 | chip->ecc.calculate = nand_bch_calculate_ecc; | ||
3361 | chip->ecc.correct = nand_bch_correct_data; | ||
3362 | chip->ecc.read_page = nand_read_page_swecc; | ||
3363 | chip->ecc.read_subpage = nand_read_subpage; | ||
3364 | chip->ecc.write_page = nand_write_page_swecc; | ||
3365 | chip->ecc.read_page_raw = nand_read_page_raw; | ||
3366 | chip->ecc.write_page_raw = nand_write_page_raw; | ||
3367 | chip->ecc.read_oob = nand_read_oob_std; | ||
3368 | chip->ecc.write_oob = nand_write_oob_std; | ||
3369 | /* | ||
3370 | * Board driver should supply ecc.size and ecc.bytes values to | ||
3371 | * select how many bits are correctable; see nand_bch_init() | ||
3372 | * for details. | ||
3373 | * Otherwise, default to 4 bits for large page devices | ||
3374 | */ | ||
3375 | if (!chip->ecc.size && (mtd->oobsize >= 64)) { | ||
3376 | chip->ecc.size = 512; | ||
3377 | chip->ecc.bytes = 7; | ||
3378 | } | ||
3379 | chip->ecc.priv = nand_bch_init(mtd, | ||
3380 | chip->ecc.size, | ||
3381 | chip->ecc.bytes, | ||
3382 | &chip->ecc.layout); | ||
3383 | if (!chip->ecc.priv) { | ||
3384 | printk(KERN_WARNING "BCH ECC initialization failed!\n"); | ||
3385 | BUG(); | ||
3386 | } | ||
3387 | break; | ||
3388 | |||
3354 | case NAND_ECC_NONE: | 3389 | case NAND_ECC_NONE: |
3355 | printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. " | 3390 | printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. " |
3356 | "This is not recommended !!\n"); | 3391 | "This is not recommended !!\n"); |
@@ -3501,6 +3536,9 @@ void nand_release(struct mtd_info *mtd) | |||
3501 | { | 3536 | { |
3502 | struct nand_chip *chip = mtd->priv; | 3537 | struct nand_chip *chip = mtd->priv; |
3503 | 3538 | ||
3539 | if (chip->ecc.mode == NAND_ECC_SOFT_BCH) | ||
3540 | nand_bch_free((struct nand_bch_control *)chip->ecc.priv); | ||
3541 | |||
3504 | #ifdef CONFIG_MTD_PARTITIONS | 3542 | #ifdef CONFIG_MTD_PARTITIONS |
3505 | /* Deregister partitions */ | 3543 | /* Deregister partitions */ |
3506 | del_mtd_partitions(mtd); | 3544 | del_mtd_partitions(mtd); |
diff --git a/drivers/mtd/nand/nand_bch.c b/drivers/mtd/nand/nand_bch.c new file mode 100644 index 000000000000..0f931e757116 --- /dev/null +++ b/drivers/mtd/nand/nand_bch.c | |||
@@ -0,0 +1,243 @@ | |||
1 | /* | ||
2 | * This file provides ECC correction for more than 1 bit per block of data, | ||
3 | * using binary BCH codes. It relies on the generic BCH library lib/bch.c. | ||
4 | * | ||
5 | * Copyright © 2011 Ivan Djelic <ivan.djelic@parrot.com> | ||
6 | * | ||
7 | * This file is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 or (at your option) any | ||
10 | * later version. | ||
11 | * | ||
12 | * This file is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
15 | * for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this file; if not, write to the Free Software Foundation, Inc., | ||
19 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/types.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/bitops.h> | ||
27 | #include <linux/mtd/mtd.h> | ||
28 | #include <linux/mtd/nand.h> | ||
29 | #include <linux/mtd/nand_bch.h> | ||
30 | #include <linux/bch.h> | ||
31 | |||
32 | /** | ||
33 | * struct nand_bch_control - private NAND BCH control structure | ||
34 | * @bch: BCH control structure | ||
35 | * @ecclayout: private ecc layout for this BCH configuration | ||
36 | * @errloc: error location array | ||
37 | * @eccmask: XOR ecc mask, allows erased pages to be decoded as valid | ||
38 | */ | ||
39 | struct nand_bch_control { | ||
40 | struct bch_control *bch; | ||
41 | struct nand_ecclayout ecclayout; | ||
42 | unsigned int *errloc; | ||
43 | unsigned char *eccmask; | ||
44 | }; | ||
45 | |||
46 | /** | ||
47 | * nand_bch_calculate_ecc - [NAND Interface] Calculate ECC for data block | ||
48 | * @mtd: MTD block structure | ||
49 | * @buf: input buffer with raw data | ||
50 | * @code: output buffer with ECC | ||
51 | */ | ||
52 | int nand_bch_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf, | ||
53 | unsigned char *code) | ||
54 | { | ||
55 | const struct nand_chip *chip = mtd->priv; | ||
56 | struct nand_bch_control *nbc = chip->ecc.priv; | ||
57 | unsigned int i; | ||
58 | |||
59 | memset(code, 0, chip->ecc.bytes); | ||
60 | encode_bch(nbc->bch, buf, chip->ecc.size, code); | ||
61 | |||
62 | /* apply mask so that an erased page is a valid codeword */ | ||
63 | for (i = 0; i < chip->ecc.bytes; i++) | ||
64 | code[i] ^= nbc->eccmask[i]; | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | EXPORT_SYMBOL(nand_bch_calculate_ecc); | ||
69 | |||
70 | /** | ||
71 | * nand_bch_correct_data - [NAND Interface] Detect and correct bit error(s) | ||
72 | * @mtd: MTD block structure | ||
73 | * @buf: raw data read from the chip | ||
74 | * @read_ecc: ECC from the chip | ||
75 | * @calc_ecc: the ECC calculated from raw data | ||
76 | * | ||
77 | * Detect and correct bit errors for a data byte block | ||
78 | */ | ||
79 | int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf, | ||
80 | unsigned char *read_ecc, unsigned char *calc_ecc) | ||
81 | { | ||
82 | const struct nand_chip *chip = mtd->priv; | ||
83 | struct nand_bch_control *nbc = chip->ecc.priv; | ||
84 | unsigned int *errloc = nbc->errloc; | ||
85 | int i, count; | ||
86 | |||
87 | count = decode_bch(nbc->bch, NULL, chip->ecc.size, read_ecc, calc_ecc, | ||
88 | NULL, errloc); | ||
89 | if (count > 0) { | ||
90 | for (i = 0; i < count; i++) { | ||
91 | if (errloc[i] < (chip->ecc.size*8)) | ||
92 | /* error is located in data, correct it */ | ||
93 | buf[errloc[i] >> 3] ^= (1 << (errloc[i] & 7)); | ||
94 | /* else error in ecc, no action needed */ | ||
95 | |||
96 | DEBUG(MTD_DEBUG_LEVEL0, "%s: corrected bitflip %u\n", | ||
97 | __func__, errloc[i]); | ||
98 | } | ||
99 | } else if (count < 0) { | ||
100 | printk(KERN_ERR "ecc unrecoverable error\n"); | ||
101 | count = -1; | ||
102 | } | ||
103 | return count; | ||
104 | } | ||
105 | EXPORT_SYMBOL(nand_bch_correct_data); | ||
106 | |||
107 | /** | ||
108 | * nand_bch_init - [NAND Interface] Initialize NAND BCH error correction | ||
109 | * @mtd: MTD block structure | ||
110 | * @eccsize: ecc block size in bytes | ||
111 | * @eccbytes: ecc length in bytes | ||
112 | * @ecclayout: output default layout | ||
113 | * | ||
114 | * Returns: | ||
115 | * a pointer to a new NAND BCH control structure, or NULL upon failure | ||
116 | * | ||
117 | * Initialize NAND BCH error correction. Parameters @eccsize and @eccbytes | ||
118 | * are used to compute BCH parameters m (Galois field order) and t (error | ||
119 | * correction capability). @eccbytes should be equal to the number of bytes | ||
120 | * required to store m*t bits, where m is such that 2^m-1 > @eccsize*8. | ||
121 | * | ||
122 | * Example: to configure 4 bit correction per 512 bytes, you should pass | ||
123 | * @eccsize = 512 (thus, m=13 is the smallest integer such that 2^m-1 > 512*8) | ||
124 | * @eccbytes = 7 (7 bytes are required to store m*t = 13*4 = 52 bits) | ||
125 | */ | ||
126 | struct nand_bch_control * | ||
127 | nand_bch_init(struct mtd_info *mtd, unsigned int eccsize, unsigned int eccbytes, | ||
128 | struct nand_ecclayout **ecclayout) | ||
129 | { | ||
130 | unsigned int m, t, eccsteps, i; | ||
131 | struct nand_ecclayout *layout; | ||
132 | struct nand_bch_control *nbc = NULL; | ||
133 | unsigned char *erased_page; | ||
134 | |||
135 | if (!eccsize || !eccbytes) { | ||
136 | printk(KERN_WARNING "ecc parameters not supplied\n"); | ||
137 | goto fail; | ||
138 | } | ||
139 | |||
140 | m = fls(1+8*eccsize); | ||
141 | t = (eccbytes*8)/m; | ||
142 | |||
143 | nbc = kzalloc(sizeof(*nbc), GFP_KERNEL); | ||
144 | if (!nbc) | ||
145 | goto fail; | ||
146 | |||
147 | nbc->bch = init_bch(m, t, 0); | ||
148 | if (!nbc->bch) | ||
149 | goto fail; | ||
150 | |||
151 | /* verify that eccbytes has the expected value */ | ||
152 | if (nbc->bch->ecc_bytes != eccbytes) { | ||
153 | printk(KERN_WARNING "invalid eccbytes %u, should be %u\n", | ||
154 | eccbytes, nbc->bch->ecc_bytes); | ||
155 | goto fail; | ||
156 | } | ||
157 | |||
158 | eccsteps = mtd->writesize/eccsize; | ||
159 | |||
160 | /* if no ecc placement scheme was provided, build one */ | ||
161 | if (!*ecclayout) { | ||
162 | |||
163 | /* handle large page devices only */ | ||
164 | if (mtd->oobsize < 64) { | ||
165 | printk(KERN_WARNING "must provide an oob scheme for " | ||
166 | "oobsize %d\n", mtd->oobsize); | ||
167 | goto fail; | ||
168 | } | ||
169 | |||
170 | layout = &nbc->ecclayout; | ||
171 | layout->eccbytes = eccsteps*eccbytes; | ||
172 | |||
173 | /* reserve 2 bytes for bad block marker */ | ||
174 | if (layout->eccbytes+2 > mtd->oobsize) { | ||
175 | printk(KERN_WARNING "no suitable oob scheme available " | ||
176 | "for oobsize %d eccbytes %u\n", mtd->oobsize, | ||
177 | eccbytes); | ||
178 | goto fail; | ||
179 | } | ||
180 | /* put ecc bytes at oob tail */ | ||
181 | for (i = 0; i < layout->eccbytes; i++) | ||
182 | layout->eccpos[i] = mtd->oobsize-layout->eccbytes+i; | ||
183 | |||
184 | layout->oobfree[0].offset = 2; | ||
185 | layout->oobfree[0].length = mtd->oobsize-2-layout->eccbytes; | ||
186 | |||
187 | *ecclayout = layout; | ||
188 | } | ||
189 | |||
190 | /* sanity checks */ | ||
191 | if (8*(eccsize+eccbytes) >= (1 << m)) { | ||
192 | printk(KERN_WARNING "eccsize %u is too large\n", eccsize); | ||
193 | goto fail; | ||
194 | } | ||
195 | if ((*ecclayout)->eccbytes != (eccsteps*eccbytes)) { | ||
196 | printk(KERN_WARNING "invalid ecc layout\n"); | ||
197 | goto fail; | ||
198 | } | ||
199 | |||
200 | nbc->eccmask = kmalloc(eccbytes, GFP_KERNEL); | ||
201 | nbc->errloc = kmalloc(t*sizeof(*nbc->errloc), GFP_KERNEL); | ||
202 | if (!nbc->eccmask || !nbc->errloc) | ||
203 | goto fail; | ||
204 | /* | ||
205 | * compute and store the inverted ecc of an erased ecc block | ||
206 | */ | ||
207 | erased_page = kmalloc(eccsize, GFP_KERNEL); | ||
208 | if (!erased_page) | ||
209 | goto fail; | ||
210 | |||
211 | memset(erased_page, 0xff, eccsize); | ||
212 | memset(nbc->eccmask, 0, eccbytes); | ||
213 | encode_bch(nbc->bch, erased_page, eccsize, nbc->eccmask); | ||
214 | kfree(erased_page); | ||
215 | |||
216 | for (i = 0; i < eccbytes; i++) | ||
217 | nbc->eccmask[i] ^= 0xff; | ||
218 | |||
219 | return nbc; | ||
220 | fail: | ||
221 | nand_bch_free(nbc); | ||
222 | return NULL; | ||
223 | } | ||
224 | EXPORT_SYMBOL(nand_bch_init); | ||
225 | |||
226 | /** | ||
227 | * nand_bch_free - [NAND Interface] Release NAND BCH ECC resources | ||
228 | * @nbc: NAND BCH control structure | ||
229 | */ | ||
230 | void nand_bch_free(struct nand_bch_control *nbc) | ||
231 | { | ||
232 | if (nbc) { | ||
233 | free_bch(nbc->bch); | ||
234 | kfree(nbc->errloc); | ||
235 | kfree(nbc->eccmask); | ||
236 | kfree(nbc); | ||
237 | } | ||
238 | } | ||
239 | EXPORT_SYMBOL(nand_bch_free); | ||
240 | |||
241 | MODULE_LICENSE("GPL"); | ||
242 | MODULE_AUTHOR("Ivan Djelic <ivan.djelic@parrot.com>"); | ||
243 | MODULE_DESCRIPTION("NAND software BCH ECC support"); | ||
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 1f489b247a29..ae67ef56a8f5 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
@@ -140,6 +140,7 @@ typedef enum { | |||
140 | NAND_ECC_HW, | 140 | NAND_ECC_HW, |
141 | NAND_ECC_HW_SYNDROME, | 141 | NAND_ECC_HW_SYNDROME, |
142 | NAND_ECC_HW_OOB_FIRST, | 142 | NAND_ECC_HW_OOB_FIRST, |
143 | NAND_ECC_SOFT_BCH, | ||
143 | } nand_ecc_modes_t; | 144 | } nand_ecc_modes_t; |
144 | 145 | ||
145 | /* | 146 | /* |
@@ -339,6 +340,7 @@ struct nand_hw_control { | |||
339 | * @prepad: padding information for syndrome based ecc generators | 340 | * @prepad: padding information for syndrome based ecc generators |
340 | * @postpad: padding information for syndrome based ecc generators | 341 | * @postpad: padding information for syndrome based ecc generators |
341 | * @layout: ECC layout control struct pointer | 342 | * @layout: ECC layout control struct pointer |
343 | * @priv: pointer to private ecc control data | ||
342 | * @hwctl: function to control hardware ecc generator. Must only | 344 | * @hwctl: function to control hardware ecc generator. Must only |
343 | * be provided if an hardware ECC is available | 345 | * be provided if an hardware ECC is available |
344 | * @calculate: function for ecc calculation or readback from ecc hardware | 346 | * @calculate: function for ecc calculation or readback from ecc hardware |
@@ -362,6 +364,7 @@ struct nand_ecc_ctrl { | |||
362 | int prepad; | 364 | int prepad; |
363 | int postpad; | 365 | int postpad; |
364 | struct nand_ecclayout *layout; | 366 | struct nand_ecclayout *layout; |
367 | void *priv; | ||
365 | void (*hwctl)(struct mtd_info *mtd, int mode); | 368 | void (*hwctl)(struct mtd_info *mtd, int mode); |
366 | int (*calculate)(struct mtd_info *mtd, const uint8_t *dat, | 369 | int (*calculate)(struct mtd_info *mtd, const uint8_t *dat, |
367 | uint8_t *ecc_code); | 370 | uint8_t *ecc_code); |
diff --git a/include/linux/mtd/nand_bch.h b/include/linux/mtd/nand_bch.h new file mode 100644 index 000000000000..74acf5367556 --- /dev/null +++ b/include/linux/mtd/nand_bch.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * Copyright © 2011 Ivan Djelic <ivan.djelic@parrot.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This file is the header for the NAND BCH ECC implementation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __MTD_NAND_BCH_H__ | ||
12 | #define __MTD_NAND_BCH_H__ | ||
13 | |||
14 | struct mtd_info; | ||
15 | struct nand_bch_control; | ||
16 | |||
17 | #if defined(CONFIG_MTD_NAND_ECC_BCH) | ||
18 | |||
19 | static inline int mtd_nand_has_bch(void) { return 1; } | ||
20 | |||
21 | /* | ||
22 | * Calculate BCH ecc code | ||
23 | */ | ||
24 | int nand_bch_calculate_ecc(struct mtd_info *mtd, const u_char *dat, | ||
25 | u_char *ecc_code); | ||
26 | |||
27 | /* | ||
28 | * Detect and correct bit errors | ||
29 | */ | ||
30 | int nand_bch_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, | ||
31 | u_char *calc_ecc); | ||
32 | /* | ||
33 | * Initialize BCH encoder/decoder | ||
34 | */ | ||
35 | struct nand_bch_control * | ||
36 | nand_bch_init(struct mtd_info *mtd, unsigned int eccsize, | ||
37 | unsigned int eccbytes, struct nand_ecclayout **ecclayout); | ||
38 | /* | ||
39 | * Release BCH encoder/decoder resources | ||
40 | */ | ||
41 | void nand_bch_free(struct nand_bch_control *nbc); | ||
42 | |||
43 | #else /* !CONFIG_MTD_NAND_ECC_BCH */ | ||
44 | |||
45 | static inline int mtd_nand_has_bch(void) { return 0; } | ||
46 | |||
47 | static inline int | ||
48 | nand_bch_calculate_ecc(struct mtd_info *mtd, const u_char *dat, | ||
49 | u_char *ecc_code) | ||
50 | { | ||
51 | return -1; | ||
52 | } | ||
53 | |||
54 | static inline int | ||
55 | nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf, | ||
56 | unsigned char *read_ecc, unsigned char *calc_ecc) | ||
57 | { | ||
58 | return -1; | ||
59 | } | ||
60 | |||
61 | static inline struct nand_bch_control * | ||
62 | nand_bch_init(struct mtd_info *mtd, unsigned int eccsize, | ||
63 | unsigned int eccbytes, struct nand_ecclayout **ecclayout) | ||
64 | { | ||
65 | return NULL; | ||
66 | } | ||
67 | |||
68 | static inline void nand_bch_free(struct nand_bch_control *nbc) {} | ||
69 | |||
70 | #endif /* CONFIG_MTD_NAND_ECC_BCH */ | ||
71 | |||
72 | #endif /* __MTD_NAND_BCH_H__ */ | ||