Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e7e4730 authored by Baruch Siach's avatar Baruch Siach Committed by Brian Norris
Browse files

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: default avatarSascha Hauer <s.hauer@pengutronix.de>
Acked-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: default avatarBaruch Siach <baruch@tkos.co.il>
Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
parent 35d5d20e
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -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;