diff options
| author | Pekon Gupta <pekon@ti.com> | 2014-02-17 13:11:24 +0530 | 
|---|---|---|
| committer | Evan Wilson <evan@oliodevices.com> | 2014-11-29 14:51:31 -0800 | 
| commit | 4df3be9685dfaa1e78d89376199d04a8cee36cf9 (patch) | |
| tree | 4f7603192caf8311ab7bf07c16a9850b09f097ce | |
| parent | b7a61e1ee2d5bb7a3c594517913d7f514bbea07a (diff) | |
| download | olio-linux-3.10-4df3be9685dfaa1e78d89376199d04a8cee36cf9.tar.xz olio-linux-3.10-4df3be9685dfaa1e78d89376199d04a8cee36cf9.zip | |
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: Enric Balletbo i Serra <eballetbo@gmail.com>
Tested-by: Stefan Roese <sr@denx.de>
Signed-off-by: Pekon Gupta <pekon@ti.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
| -rw-r--r-- | drivers/mtd/nand/omap2.c | 25 | 
1 files changed, 15 insertions, 10 deletions
| diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 34ef941e3bf..58685ab6d86 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"); |