Skip to content

Commit

Permalink
mtd: nand: fsl_ifc: Fix eccstat array overflow for IFC ver >= 2.0.0
Browse files Browse the repository at this point in the history
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: bccb06c ("mtd: nand: ifc: update bufnum mask for ver >= 2.0.0")
Cc: stable@vger.kernel.org # 3.18+
Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
Signed-off-by: Jagdish Gediya <jagdish.gediya@nxp.com>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
  • Loading branch information
Jagdish Gediya authored and Boris Brezillon committed Mar 21, 2018
1 parent fa8e6d5 commit 843c3a5
Showing 1 changed file with 10 additions and 13 deletions.
23 changes: 10 additions & 13 deletions drivers/mtd/nand/fsl_ifc_nand.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/*
Expand All @@ -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 */
Expand Down Expand Up @@ -228,19 +223,21 @@ 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)
eccstat_regs = ifc->ifc_nand.v2_nand_eccstat;
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) {
Expand Down

0 comments on commit 843c3a5

Please sign in to comment.