aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPekon Gupta <pekon@ti.com>2014-02-17 02:41:24 -0500
committerBrian Norris <computersforpeace@gmail.com>2014-02-23 17:49:57 -0500
commitaa6092f9835893290e77c3e24649def49dac1583 (patch)
treeec1e53b24298e5e237f608bc8e6fc52c1f4a45b9 /drivers
parenteae39cb4934d3daab3ec828c5201c955b2e56af9 (diff)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/omap2.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 34ef941e3bfb..58685ab6d865 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)
1832 oob_index = 1; 1832 oob_index = 1;
1833 for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) 1833 for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
1834 ecclayout->eccpos[i] = oob_index; 1834 ecclayout->eccpos[i] = oob_index;
1835 ecclayout->oobfree->offset = ecclayout->eccpos[0] + 1835 /* no reserved-marker in ecclayout for this ecc-scheme */
1836 ecclayout->eccbytes; 1836 ecclayout->oobfree->offset =
1837 ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
1837 break; 1838 break;
1838 1839
1839 case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: 1840 case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
@@ -1856,8 +1857,9 @@ static int omap_nand_probe(struct platform_device *pdev)
1856 if (((i + 1) % nand_chip->ecc.bytes) == 0) 1857 if (((i + 1) % nand_chip->ecc.bytes) == 0)
1857 oob_index++; 1858 oob_index++;
1858 } 1859 }
1859 ecclayout->oobfree->offset = ecclayout->eccpos[0] + 1860 /* include reserved-marker in ecclayout->oobfree calculation */
1860 ecclayout->eccbytes; 1861 ecclayout->oobfree->offset = 1 +
1862 ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
1861 /* software bch library is used for locating errors */ 1863 /* software bch library is used for locating errors */
1862 nand_chip->ecc.priv = nand_bch_init(mtd, 1864 nand_chip->ecc.priv = nand_bch_init(mtd,
1863 nand_chip->ecc.size, 1865 nand_chip->ecc.size,
@@ -1894,8 +1896,9 @@ static int omap_nand_probe(struct platform_device *pdev)
1894 oob_index = BADBLOCK_MARKER_LENGTH; 1896 oob_index = BADBLOCK_MARKER_LENGTH;
1895 for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) 1897 for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
1896 ecclayout->eccpos[i] = oob_index; 1898 ecclayout->eccpos[i] = oob_index;
1897 ecclayout->oobfree->offset = ecclayout->eccpos[0] + 1899 /* reserved marker already included in ecclayout->eccbytes */
1898 ecclayout->eccbytes; 1900 ecclayout->oobfree->offset =
1901 ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
1899 /* This ECC scheme requires ELM H/W block */ 1902 /* This ECC scheme requires ELM H/W block */
1900 if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) { 1903 if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
1901 pr_err("nand: error: could not initialize ELM\n"); 1904 pr_err("nand: error: could not initialize ELM\n");
@@ -1929,8 +1932,9 @@ static int omap_nand_probe(struct platform_device *pdev)
1929 if (((i + 1) % nand_chip->ecc.bytes) == 0) 1932 if (((i + 1) % nand_chip->ecc.bytes) == 0)
1930 oob_index++; 1933 oob_index++;
1931 } 1934 }
1932 ecclayout->oobfree->offset = ecclayout->eccpos[0] + 1935 /* include reserved-marker in ecclayout->oobfree calculation */
1933 ecclayout->eccbytes; 1936 ecclayout->oobfree->offset = 1 +
1937 ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
1934 /* software bch library is used for locating errors */ 1938 /* software bch library is used for locating errors */
1935 nand_chip->ecc.priv = nand_bch_init(mtd, 1939 nand_chip->ecc.priv = nand_bch_init(mtd,
1936 nand_chip->ecc.size, 1940 nand_chip->ecc.size,
@@ -1974,8 +1978,9 @@ static int omap_nand_probe(struct platform_device *pdev)
1974 oob_index = BADBLOCK_MARKER_LENGTH; 1978 oob_index = BADBLOCK_MARKER_LENGTH;
1975 for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) 1979 for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
1976 ecclayout->eccpos[i] = oob_index; 1980 ecclayout->eccpos[i] = oob_index;
1977 ecclayout->oobfree->offset = ecclayout->eccpos[0] + 1981 /* reserved marker already included in ecclayout->eccbytes */
1978 ecclayout->eccbytes; 1982 ecclayout->oobfree->offset =
1983 ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;
1979 break; 1984 break;
1980#else 1985#else
1981 pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); 1986 pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");