diff mbox

[v3,2/3] mtd: nand: omap: fix ecclayout->oobfree->offset

Message ID 1392622885-8415-3-git-send-email-pekon@ti.com
State Accepted
Commit aa6092f9835893290e77c3e24649def49dac1583
Headers show

Commit Message

pekon gupta Feb. 17, 2014, 7:41 a.m. UTC
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: Enric Balletbo i Serra <eballetbo@gmail.com>
Tested-by: Stefan Roese <sr@denx.de>
Signed-off-by: Pekon Gupta <pekon@ti.com>
---
 drivers/mtd/nand/omap2.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

Comments

pekon gupta Feb. 17, 2014, 7:49 a.m. UTC | #1
removing  stable@vger.kernel.org from CC list.
(git send-email --suppress-cc=cc din't work for me)

>From: Gupta, Pekon
>
>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: Enric Balletbo i Serra <eballetbo@gmail.com>
>Tested-by: Stefan Roese <sr@denx.de>
>Signed-off-by: Pekon Gupta <pekon@ti.com>
>---
> drivers/mtd/nand/omap2.c | 25 +++++++++++++++----------
> 1 file changed, 15 insertions(+), 10 deletions(-)
>
>diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
>index 34ef941..58685ab 100644
>--- a/drivers/mtd/nand/omap2.c
>+++ b/drivers/mtd/nand/omap2.c
>@@ -1832,8 +1832,9 @@ static int omap_nand_probe(struct platform_device *pdev)
> 			oob_index		= 1;
> 		for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
> 			ecclayout->eccpos[i]	= oob_index;
>-		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
>-							ecclayout->eccbytes;
>+		/* no reserved-marker in ecclayout for this ecc-scheme */
>+		ecclayout->oobfree->offset	=
>+				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
> 		break;
>
> 	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)
> 				oob_index++;
> 		}
>-		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
>-							ecclayout->eccbytes;
>+		/* include reserved-marker in ecclayout->oobfree calculation */
>+		ecclayout->oobfree->offset	= 1 +
>+				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
> 		/* software bch library is used for locating errors */
> 		nand_chip->ecc.priv		= nand_bch_init(mtd,
> 							nand_chip->ecc.size,
>@@ -1894,8 +1896,9 @@ static int omap_nand_probe(struct platform_device *pdev)
> 		oob_index			= BADBLOCK_MARKER_LENGTH;
> 		for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
> 			ecclayout->eccpos[i]	= oob_index;
>-		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
>-							ecclayout->eccbytes;
>+		/* reserved marker already included in ecclayout->eccbytes */
>+		ecclayout->oobfree->offset	=
>+				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
> 		/* This ECC scheme requires ELM H/W block */
> 		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
> 			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)
> 				oob_index++;
> 		}
>-		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
>-							ecclayout->eccbytes;
>+		/* include reserved-marker in ecclayout->oobfree calculation */
>+		ecclayout->oobfree->offset	= 1 +
>+				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
> 		/* software bch library is used for locating errors */
> 		nand_chip->ecc.priv		= nand_bch_init(mtd,
> 							nand_chip->ecc.size,
>@@ -1974,8 +1978,9 @@ static int omap_nand_probe(struct platform_device *pdev)
> 		oob_index			= BADBLOCK_MARKER_LENGTH;
> 		for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
> 			ecclayout->eccpos[i]	= oob_index;
>-		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
>-							ecclayout->eccbytes;
>+		/* reserved marker already included in ecclayout->eccbytes */
>+		ecclayout->oobfree->offset	=
>+				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
> 		break;
> #else
> 		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
>--
>1.8.5.1.163.gd7aced9


With regards, pekon
diff mbox

Patch

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 34ef941..58685ab 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1832,8 +1832,9 @@  static int omap_nand_probe(struct platform_device *pdev)
 			oob_index		= 1;
 		for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
 			ecclayout->eccpos[i]	= oob_index;
-		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
-							ecclayout->eccbytes;
+		/* no reserved-marker in ecclayout for this ecc-scheme */
+		ecclayout->oobfree->offset	=
+				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
 		break;
 
 	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)
 				oob_index++;
 		}
-		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
-							ecclayout->eccbytes;
+		/* include reserved-marker in ecclayout->oobfree calculation */
+		ecclayout->oobfree->offset	= 1 +
+				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
 		/* software bch library is used for locating errors */
 		nand_chip->ecc.priv		= nand_bch_init(mtd,
 							nand_chip->ecc.size,
@@ -1894,8 +1896,9 @@  static int omap_nand_probe(struct platform_device *pdev)
 		oob_index			= BADBLOCK_MARKER_LENGTH;
 		for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
 			ecclayout->eccpos[i]	= oob_index;
-		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
-							ecclayout->eccbytes;
+		/* reserved marker already included in ecclayout->eccbytes */
+		ecclayout->oobfree->offset	=
+				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
 		/* This ECC scheme requires ELM H/W block */
 		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
 			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)
 				oob_index++;
 		}
-		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
-							ecclayout->eccbytes;
+		/* include reserved-marker in ecclayout->oobfree calculation */
+		ecclayout->oobfree->offset	= 1 +
+				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
 		/* software bch library is used for locating errors */
 		nand_chip->ecc.priv		= nand_bch_init(mtd,
 							nand_chip->ecc.size,
@@ -1974,8 +1978,9 @@  static int omap_nand_probe(struct platform_device *pdev)
 		oob_index			= BADBLOCK_MARKER_LENGTH;
 		for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
 			ecclayout->eccpos[i]	= oob_index;
-		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
-							ecclayout->eccbytes;
+		/* reserved marker already included in ecclayout->eccbytes */
+		ecclayout->oobfree->offset	=
+				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
 		break;
 #else
 		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");