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

Commit aa6092f9 authored by Pekon Gupta's avatar Pekon Gupta Committed by Brian Norris
Browse files

mtd: nand: omap: fix ecclayout->oobfree->offset



1) In current implementation, ecclayout->oobfree->offset is calculated with
 respect to ecclayout->eccpos[0] which is incorrect because ECC bytes may not
 be stored contiguously in OOB.
 So, this patch calculates ecclayout->oobfree->offset with respect to last
 ECC byte-position 'eccpos[ecclayout->eccbytes-1]'.

2) ECC layout of some ecc-schemes expects reserved-markers at specific eccpos[]
 which should not be over-written by any file-system metadata.
 So this patch aligns oobfree->offset taking into account of such markers.

CC: <stable@vger.kernel.org> # 3.13.x+
Tested-by: default avatarEnric Balletbo i Serra <eballetbo@gmail.com>
Tested-by: default avatarStefan Roese <sr@denx.de>
Signed-off-by: default avatarPekon Gupta <pekon@ti.com>
Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
parent eae39cb4
Loading
Loading
Loading
Loading
+15 −10
Original line number Original line Diff line number Diff line
@@ -1832,8 +1832,9 @@ static int omap_nand_probe(struct platform_device *pdev)
			oob_index		= 1;
			oob_index		= 1;
		for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
		for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
			ecclayout->eccpos[i]	= oob_index;
			ecclayout->eccpos[i]	= oob_index;
		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
		/* no reserved-marker in ecclayout for this ecc-scheme */
							ecclayout->eccbytes;
		ecclayout->oobfree->offset	=
				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
		break;
		break;


	case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
	case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
@@ -1856,8 +1857,9 @@ static int omap_nand_probe(struct platform_device *pdev)
			if (((i + 1) % nand_chip->ecc.bytes) == 0)
			if (((i + 1) % nand_chip->ecc.bytes) == 0)
				oob_index++;
				oob_index++;
		}
		}
		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
		/* include reserved-marker in ecclayout->oobfree calculation */
							ecclayout->eccbytes;
		ecclayout->oobfree->offset	= 1 +
				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
		/* software bch library is used for locating errors */
		/* software bch library is used for locating errors */
		nand_chip->ecc.priv		= nand_bch_init(mtd,
		nand_chip->ecc.priv		= nand_bch_init(mtd,
							nand_chip->ecc.size,
							nand_chip->ecc.size,
@@ -1894,8 +1896,9 @@ static int omap_nand_probe(struct platform_device *pdev)
		oob_index			= BADBLOCK_MARKER_LENGTH;
		oob_index			= BADBLOCK_MARKER_LENGTH;
		for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
		for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
			ecclayout->eccpos[i]	= oob_index;
			ecclayout->eccpos[i]	= oob_index;
		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
		/* reserved marker already included in ecclayout->eccbytes */
							ecclayout->eccbytes;
		ecclayout->oobfree->offset	=
				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
		/* This ECC scheme requires ELM H/W block */
		/* This ECC scheme requires ELM H/W block */
		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
			pr_err("nand: error: could not initialize ELM\n");
			pr_err("nand: error: could not initialize ELM\n");
@@ -1929,8 +1932,9 @@ static int omap_nand_probe(struct platform_device *pdev)
			if (((i + 1) % nand_chip->ecc.bytes) == 0)
			if (((i + 1) % nand_chip->ecc.bytes) == 0)
				oob_index++;
				oob_index++;
		}
		}
		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
		/* include reserved-marker in ecclayout->oobfree calculation */
							ecclayout->eccbytes;
		ecclayout->oobfree->offset	= 1 +
				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
		/* software bch library is used for locating errors */
		/* software bch library is used for locating errors */
		nand_chip->ecc.priv		= nand_bch_init(mtd,
		nand_chip->ecc.priv		= nand_bch_init(mtd,
							nand_chip->ecc.size,
							nand_chip->ecc.size,
@@ -1974,8 +1978,9 @@ static int omap_nand_probe(struct platform_device *pdev)
		oob_index			= BADBLOCK_MARKER_LENGTH;
		oob_index			= BADBLOCK_MARKER_LENGTH;
		for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
		for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
			ecclayout->eccpos[i]	= oob_index;
			ecclayout->eccpos[i]	= oob_index;
		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
		/* reserved marker already included in ecclayout->eccbytes */
							ecclayout->eccbytes;
		ecclayout->oobfree->offset	=
				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
		break;
		break;
#else
#else
		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");