| From 336d4b138be2dad372b67a2388e42805c48aaa38 Mon Sep 17 00:00:00 2001 |
| From: Xiaolei Li <xiaolei.li@mediatek.com> |
| Date: Tue, 7 May 2019 18:25:41 +0800 |
| Subject: mtd: rawnand: mtk: Fix wrongly assigned OOB buffer pointer issue |
| |
| From: Xiaolei Li <xiaolei.li@mediatek.com> |
| |
| commit 336d4b138be2dad372b67a2388e42805c48aaa38 upstream. |
| |
| One main goal of the function mtk_nfc_update_ecc_stats is to check |
| whether sectors are all empty. If they are empty, set these sectors's |
| data buffer and OOB buffer as 0xff. |
| |
| But now, the sector OOB buffer pointer is wrongly assigned. We always |
| do memset from sector 0. |
| |
| To fix this issue, pass start sector number to make OOB buffer pointer |
| be properly assigned. |
| |
| Fixes: 1d6b1e464950 ("mtd: mediatek: driver for MTK Smart Device") |
| Signed-off-by: Xiaolei Li <xiaolei.li@mediatek.com> |
| Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com> |
| Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/mtd/nand/mtk_nand.c | 21 ++++++++++----------- |
| 1 file changed, 10 insertions(+), 11 deletions(-) |
| |
| --- a/drivers/mtd/nand/mtk_nand.c |
| +++ b/drivers/mtd/nand/mtk_nand.c |
| @@ -846,19 +846,21 @@ static int mtk_nfc_write_oob_std(struct |
| return ret & NAND_STATUS_FAIL ? -EIO : 0; |
| } |
| |
| -static int mtk_nfc_update_ecc_stats(struct mtd_info *mtd, u8 *buf, u32 sectors) |
| +static int mtk_nfc_update_ecc_stats(struct mtd_info *mtd, u8 *buf, u32 start, |
| + u32 sectors) |
| { |
| struct nand_chip *chip = mtd_to_nand(mtd); |
| struct mtk_nfc *nfc = nand_get_controller_data(chip); |
| struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); |
| struct mtk_ecc_stats stats; |
| + u32 reg_size = mtk_nand->fdm.reg_size; |
| int rc, i; |
| |
| rc = nfi_readl(nfc, NFI_STA) & STA_EMP_PAGE; |
| if (rc) { |
| memset(buf, 0xff, sectors * chip->ecc.size); |
| for (i = 0; i < sectors; i++) |
| - memset(oob_ptr(chip, i), 0xff, mtk_nand->fdm.reg_size); |
| + memset(oob_ptr(chip, start + i), 0xff, reg_size); |
| return 0; |
| } |
| |
| @@ -878,7 +880,7 @@ static int mtk_nfc_read_subpage(struct m |
| u32 spare = mtk_nand->spare_per_sector; |
| u32 column, sectors, start, end, reg; |
| dma_addr_t addr; |
| - int bitflips; |
| + int bitflips = 0; |
| size_t len; |
| u8 *buf; |
| int rc; |
| @@ -946,14 +948,11 @@ static int mtk_nfc_read_subpage(struct m |
| if (rc < 0) { |
| dev_err(nfc->dev, "subpage done timeout\n"); |
| bitflips = -EIO; |
| - } else { |
| - bitflips = 0; |
| - if (!raw) { |
| - rc = mtk_ecc_wait_done(nfc->ecc, ECC_DECODE); |
| - bitflips = rc < 0 ? -ETIMEDOUT : |
| - mtk_nfc_update_ecc_stats(mtd, buf, sectors); |
| - mtk_nfc_read_fdm(chip, start, sectors); |
| - } |
| + } else if (!raw) { |
| + rc = mtk_ecc_wait_done(nfc->ecc, ECC_DECODE); |
| + bitflips = rc < 0 ? -ETIMEDOUT : |
| + mtk_nfc_update_ecc_stats(mtd, buf, start, sectors); |
| + mtk_nfc_read_fdm(chip, start, sectors); |
| } |
| |
| dma_unmap_single(nfc->dev, addr, len, DMA_FROM_DEVICE); |