diff options
author | Prabhakar Kushwaha <prabhakar@freescale.com> | 2012-01-20 18:38:14 +0530 |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2012-02-28 14:03:39 -0600 |
commit | 5f720b85141646055c08bbccb0e2549f654563de (patch) | |
tree | 5d1b00f9a132eeb4226bacd3e8cfb6add6bf9807 /drivers/mtd/nand | |
parent | d90361285c1c9751bd1b3700a18db882b32ddad5 (diff) | |
download | u-boot-imx-5f720b85141646055c08bbccb0e2549f654563de.zip u-boot-imx-5f720b85141646055c08bbccb0e2549f654563de.tar.gz u-boot-imx-5f720b85141646055c08bbccb0e2549f654563de.tar.bz2 |
mtd/nand:Fix wrong usage of is_blank() in fsl_ifc_run_command
Freescale IFC NAND Machine calculates ECC on 512byte sector and same is used in
fsl_ifc_run_command() during ECC status verification. Also this sector is passed
to is_blank() for blank checking. It is wrong at first place because
is_blank()'s implementation checks for Page size and OOB area size.
is_blank() should be called per page for main and OOB area verification.
Variables name are redefined to avoid confusion between buffer and ecc sector.
Signed-off-by: Poonam Aggrwal <poonam.aggrwal@freescale.com>
Signed-off-by: Prabhakar Kushwaha <prabhakar@freescale.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r-- | drivers/mtd/nand/fsl_ifc_nand.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 36e1bae..5cac78b 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -1,6 +1,6 @@ /* Integrated Flash Controller NAND Machine Driver * - * Copyright (c) 2011 Freescale Semiconductor, Inc + * Copyright (c) 2012 Freescale Semiconductor, Inc * * Authors: Dipen Dudhat <Dipen.Dudhat@freescale.com> * @@ -221,24 +221,11 @@ static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl, u32 *eccstat, unsigned int bufnum) { u32 reg = eccstat[bufnum / 4]; - int errors = (reg >> ((3 - bufnum % 4) * 8)) & 15; - - if (errors == 15) { /* uncorrectable */ - /* Blank pages fail hw ECC checks */ - if (is_blank(mtd, ctrl, bufnum)) - return 1; - - /* - * We disable ECCER reporting in hardware due to - * erratum IFC-A002770 -- so report it now if we - * see an uncorrectable error in ECCSTAT. - */ - ctrl->status |= IFC_NAND_EVTER_STAT_ECCER; - } else if (errors > 0) { - mtd->ecc_stats.corrected += errors; - } + int errors; - return 0; + errors = (reg >> ((3 - bufnum % 4) * 8)) & 15; + + return errors; } /* @@ -279,16 +266,33 @@ static int fsl_ifc_run_command(struct mtd_info *mtd) printf("%s: Write Protect Error\n", __func__); if (ctrl->eccread) { - int bufperpage = mtd->writesize / 512; - int bufnum = (ctrl->page & priv->bufnum_mask) * bufperpage; - int bufnum_end = bufnum + bufperpage - 1; + int errors; + int bufnum = ctrl->page & priv->bufnum_mask; + int sector = bufnum * chip->ecc.steps; + int sector_end = sector + chip->ecc.steps - 1; - for (i = bufnum / 4; i <= bufnum_end / 4; i++) + for (i = sector / 4; i <= sector_end / 4; i++) eccstat[i] = in_be32(&ifc->ifc_nand.nand_eccstat[i]); - for (i = bufnum; i <= bufnum_end; i++) { - if (check_read_ecc(mtd, ctrl, eccstat, i)) + for (i = sector; i <= sector_end; i++) { + errors = check_read_ecc(mtd, ctrl, eccstat, i); + + if (errors == 15) { + /* + * Uncorrectable error. + * OK only if the whole page is blank. + * + * We disable ECCER reporting due to erratum + * IFC-A002770 -- so report it now if we + * see an uncorrectable error in ECCSTAT. + */ + if (!is_blank(mtd, ctrl, bufnum)) + ctrl->status |= + IFC_NAND_EVTER_STAT_ECCER; break; + } + + mtd->ecc_stats.corrected += errors; } ctrl->eccread = 0; |