mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
eae39cb493
commit
aa6092f983
|
@ -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");
|
||||||
|
|
Loading…
Reference in New Issue