Commit 70facf93 authored by Xiaolei Li's avatar Xiaolei Li Committed by Greg Kroah-Hartman

mtd: rawnand: mtk: Fix wrongly assigned OOB buffer pointer issue

commit 336d4b13 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: 1d6b1e46 ("mtd: mediatek: driver for MTK Smart Device")
Signed-off-by: default avatarXiaolei Li <xiaolei.li@mediatek.com>
Reviewed-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6da56f89
...@@ -863,19 +863,21 @@ static int mtk_nfc_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -863,19 +863,21 @@ static int mtk_nfc_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
return mtk_nfc_write_page_raw(mtd, chip, NULL, 1, page); return mtk_nfc_write_page_raw(mtd, chip, NULL, 1, page);
} }
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 nand_chip *chip = mtd_to_nand(mtd);
struct mtk_nfc *nfc = nand_get_controller_data(chip); struct mtk_nfc *nfc = nand_get_controller_data(chip);
struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
struct mtk_ecc_stats stats; struct mtk_ecc_stats stats;
u32 reg_size = mtk_nand->fdm.reg_size;
int rc, i; int rc, i;
rc = nfi_readl(nfc, NFI_STA) & STA_EMP_PAGE; rc = nfi_readl(nfc, NFI_STA) & STA_EMP_PAGE;
if (rc) { if (rc) {
memset(buf, 0xff, sectors * chip->ecc.size); memset(buf, 0xff, sectors * chip->ecc.size);
for (i = 0; i < sectors; i++) 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; return 0;
} }
...@@ -895,7 +897,7 @@ static int mtk_nfc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -895,7 +897,7 @@ static int mtk_nfc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
u32 spare = mtk_nand->spare_per_sector; u32 spare = mtk_nand->spare_per_sector;
u32 column, sectors, start, end, reg; u32 column, sectors, start, end, reg;
dma_addr_t addr; dma_addr_t addr;
int bitflips; int bitflips = 0;
size_t len; size_t len;
u8 *buf; u8 *buf;
int rc; int rc;
...@@ -962,15 +964,12 @@ static int mtk_nfc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -962,15 +964,12 @@ static int mtk_nfc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
if (rc < 0) { if (rc < 0) {
dev_err(nfc->dev, "subpage done timeout\n"); dev_err(nfc->dev, "subpage done timeout\n");
bitflips = -EIO; bitflips = -EIO;
} else { } else if (!raw) {
bitflips = 0;
if (!raw) {
rc = mtk_ecc_wait_done(nfc->ecc, ECC_DECODE); rc = mtk_ecc_wait_done(nfc->ecc, ECC_DECODE);
bitflips = rc < 0 ? -ETIMEDOUT : bitflips = rc < 0 ? -ETIMEDOUT :
mtk_nfc_update_ecc_stats(mtd, buf, sectors); mtk_nfc_update_ecc_stats(mtd, buf, start, sectors);
mtk_nfc_read_fdm(chip, start, sectors); mtk_nfc_read_fdm(chip, start, sectors);
} }
}
dma_unmap_single(nfc->dev, addr, len, DMA_FROM_DEVICE); dma_unmap_single(nfc->dev, addr, len, DMA_FROM_DEVICE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment