mtd: nand: fsl_ifc: Fix eccstat array overflow for IFC ver >= 2.0.0

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Fri Mar 23 00:59:02 PDT 2018


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=843c3a59997f18060848b8632607dd04781b52d1
Commit:     843c3a59997f18060848b8632607dd04781b52d1
Parent:     fa8e6d58c5bc260f4369c6699683d69695daed0a
Author:     Jagdish Gediya <jagdish.gediya at nxp.com>
AuthorDate: Wed Mar 21 05:51:46 2018 +0530
Committer:  Boris Brezillon <boris.brezillon at bootlin.com>
CommitDate: Wed Mar 21 10:18:34 2018 +0100

    mtd: nand: fsl_ifc: Fix eccstat array overflow for IFC ver >= 2.0.0
    
    Number of ECC status registers i.e. (ECCSTATx) has been increased in IFC
    version 2.0.0 due to increase in SRAM size. This is causing eccstat
    array to over flow.
    
    So, replace eccstat array with u32 variable to make it fail-safe and
    independent of number of ECC status registers or SRAM size.
    
    Fixes: bccb06c353af ("mtd: nand: ifc: update bufnum mask for ver >= 2.0.0")
    Cc: stable at vger.kernel.org # 3.18+
    Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
    Signed-off-by: Jagdish Gediya <jagdish.gediya at nxp.com>
    Signed-off-by: Boris Brezillon <boris.brezillon at bootlin.com>
---
 drivers/mtd/nand/fsl_ifc_nand.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index b6a3ba445cfb..fae01b04abc7 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -173,14 +173,9 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
 
 /* returns nonzero if entire page is blank */
 static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl,
-			  u32 *eccstat, unsigned int bufnum)
+			  u32 eccstat, unsigned int bufnum)
 {
-	u32 reg = eccstat[bufnum / 4];
-	int errors;
-
-	errors = (reg >> ((3 - bufnum % 4) * 8)) & 15;
-
-	return errors;
+	return  (eccstat >> ((3 - bufnum % 4) * 8)) & 15;
 }
 
 /*
@@ -193,7 +188,7 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
 	struct fsl_ifc_ctrl *ctrl = priv->ctrl;
 	struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl;
 	struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs;
-	u32 eccstat[4];
+	u32 eccstat;
 	int i;
 
 	/* set the chip select for NAND Transaction */
@@ -228,8 +223,8 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
 	if (nctrl->eccread) {
 		int errors;
 		int bufnum = nctrl->page & priv->bufnum_mask;
-		int sector = bufnum * chip->ecc.steps;
-		int sector_end = sector + chip->ecc.steps - 1;
+		int sector_start = bufnum * chip->ecc.steps;
+		int sector_end = sector_start + chip->ecc.steps - 1;
 		__be32 *eccstat_regs;
 
 		if (ctrl->version >= FSL_IFC_VERSION_2_0_0)
@@ -237,10 +232,12 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
 		else
 			eccstat_regs = ifc->ifc_nand.v1_nand_eccstat;
 
-		for (i = sector / 4; i <= sector_end / 4; i++)
-			eccstat[i] = ifc_in32(&eccstat_regs[i]);
+		eccstat = ifc_in32(&eccstat_regs[sector_start / 4]);
+
+		for (i = sector_start; i <= sector_end; i++) {
+			if (i != sector_start && !(i % 4))
+				eccstat = ifc_in32(&eccstat_regs[i / 4]);
 
-		for (i = sector; i <= sector_end; i++) {
 			errors = check_read_ecc(mtd, ctrl, eccstat, i);
 
 			if (errors == 15) {



More information about the linux-mtd-cvs mailing list