mtd: mxc_nand: limit the size of used oob
Linux-MTD Mailing List
linux-mtd at lists.infradead.org
Tue Jun 23 10:59:05 PDT 2015
Gitweb: http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=7e7e4730c178f32a14b781f7c55564d99c4dda3f
Commit: 7e7e4730c178f32a14b781f7c55564d99c4dda3f
Parent: 35d5d20efad8a04c8c002c7f31241dff973977a6
Author: Baruch Siach <baruch at tkos.co.il>
AuthorDate: Wed May 13 11:17:37 2015 +0300
Committer: Brian Norris <computersforpeace at gmail.com>
CommitDate: Wed May 20 15:29:53 2015 -0700
mtd: mxc_nand: limit the size of used oob
For 4k pages the i.MX NFC hardware uses no more than 218 bytes for 8bit ECC
data. Larger oobsize confuses the logic of copy_spare(). Limit the size of used
oob size to avoid that.
Reviewed-by: Sascha Hauer <s.hauer at pengutronix.de>
Acked-by: Uwe Kleine-König <u.kleine-koenig at pengutronix.de>
Signed-off-by: Baruch Siach <baruch at tkos.co.il>
Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
drivers/mtd/nand/mxc_nand.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 5bbc1c5..ceeb61c 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -189,6 +189,7 @@ struct mxc_nand_host {
int clk_act;
int irq;
int eccsize;
+ int used_oobsize;
int active_cs;
struct completion op_completion;
@@ -827,7 +828,7 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom)
u16 sparebuf_size = host->devtype_data->spare_len;
/* size of oob chunk for all but possibly the last one */
- oob_chunk_size = (mtd->oobsize / num_chunks) & ~1;
+ oob_chunk_size = (host->used_oobsize / num_chunks) & ~1;
if (bfrom) {
for (i = 0; i < num_chunks - 1; i++)
@@ -838,7 +839,7 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom)
/* the last chunk */
memcpy32_fromio(d + i * oob_chunk_size,
s + i * sparebuf_size,
- mtd->oobsize - i * oob_chunk_size);
+ host->used_oobsize - i * oob_chunk_size);
} else {
for (i = 0; i < num_chunks - 1; i++)
memcpy32_toio(&s[i * sparebuf_size],
@@ -848,7 +849,7 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom)
/* the last chunk */
memcpy32_toio(&s[oob_chunk_size * sparebuf_size],
&d[i * oob_chunk_size],
- mtd->oobsize - i * oob_chunk_size);
+ host->used_oobsize - i * oob_chunk_size);
}
}
@@ -1606,6 +1607,15 @@ static int mxcnd_probe(struct platform_device *pdev)
else if (mtd->writesize == 4096)
this->ecc.layout = host->devtype_data->ecclayout_4k;
+ /*
+ * Experimentation shows that i.MX NFC can only handle up to 218 oob
+ * bytes. Limit used_oobsize to 218 so as to not confuse copy_spare()
+ * into copying invalid data to/from the spare IO buffer, as this
+ * might cause ECC data corruption when doing sub-page write to a
+ * partially written page.
+ */
+ host->used_oobsize = min(mtd->oobsize, 218U);
+
if (this->ecc.mode == NAND_ECC_HW) {
if (is_imx21_nfc(host) || is_imx27_nfc(host))
this->ecc.strength = 1;
More information about the linux-mtd-cvs
mailing list