diff options
author | Baruch Siach <baruch@tkos.co.il> | 2011-03-09 09:12:20 -0500 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2011-03-11 09:23:48 -0500 |
commit | 2c1c5f199482356c00f70b6f2f368c3455d1230c (patch) | |
tree | c2f59799e1e9d510980539de6ee998ac937bd5e4 /drivers/mtd/nand | |
parent | f43272c482661bc88347bba237976eecfc1dbf5b (diff) |
mtd: mxc_nand: fix OOB corruption when page size > 2KiB
When page size is 4KiB, ecc.total is set to 8*9, and this causes
nand_write_page_hwecc() to read past the initialized part of the eccpos array,
which corrupts chip->oob_poi with bogus values from ecc_calc.
Fix this by creating a proper nand_ecclayout for 4KiB flashes.
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r-- | drivers/mtd/nand/mxc_nand.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 6cd78ed439a7..b7d5a5b9a543 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
@@ -211,6 +211,31 @@ static struct nand_ecclayout nandv2_hw_eccoob_largepage = { | |||
211 | } | 211 | } |
212 | }; | 212 | }; |
213 | 213 | ||
214 | /* OOB description for 4096 byte pages with 128 byte OOB */ | ||
215 | static struct nand_ecclayout nandv2_hw_eccoob_4k = { | ||
216 | .eccbytes = 8 * 9, | ||
217 | .eccpos = { | ||
218 | 7, 8, 9, 10, 11, 12, 13, 14, 15, | ||
219 | 23, 24, 25, 26, 27, 28, 29, 30, 31, | ||
220 | 39, 40, 41, 42, 43, 44, 45, 46, 47, | ||
221 | 55, 56, 57, 58, 59, 60, 61, 62, 63, | ||
222 | 71, 72, 73, 74, 75, 76, 77, 78, 79, | ||
223 | 87, 88, 89, 90, 91, 92, 93, 94, 95, | ||
224 | 103, 104, 105, 106, 107, 108, 109, 110, 111, | ||
225 | 119, 120, 121, 122, 123, 124, 125, 126, 127, | ||
226 | }, | ||
227 | .oobfree = { | ||
228 | {.offset = 2, .length = 4}, | ||
229 | {.offset = 16, .length = 7}, | ||
230 | {.offset = 32, .length = 7}, | ||
231 | {.offset = 48, .length = 7}, | ||
232 | {.offset = 64, .length = 7}, | ||
233 | {.offset = 80, .length = 7}, | ||
234 | {.offset = 96, .length = 7}, | ||
235 | {.offset = 112, .length = 7}, | ||
236 | } | ||
237 | }; | ||
238 | |||
214 | #ifdef CONFIG_MTD_PARTITIONS | 239 | #ifdef CONFIG_MTD_PARTITIONS |
215 | static const char *part_probes[] = { "RedBoot", "cmdlinepart", NULL }; | 240 | static const char *part_probes[] = { "RedBoot", "cmdlinepart", NULL }; |
216 | #endif | 241 | #endif |
@@ -1186,6 +1211,8 @@ static int __init mxcnd_probe(struct platform_device *pdev) | |||
1186 | 1211 | ||
1187 | if (mtd->writesize == 2048) | 1212 | if (mtd->writesize == 2048) |
1188 | this->ecc.layout = oob_largepage; | 1213 | this->ecc.layout = oob_largepage; |
1214 | if (nfc_is_v21() && mtd->writesize == 4096) | ||
1215 | this->ecc.layout = &nandv2_hw_eccoob_4k; | ||
1189 | 1216 | ||
1190 | /* second phase scan */ | 1217 | /* second phase scan */ |
1191 | if (nand_scan_tail(mtd)) { | 1218 | if (nand_scan_tail(mtd)) { |