From 2810efc860f4e41d82c6ac017ce1e5fa9cc933d0 Mon Sep 17 00:00:00 2001 From: Yifeng Zhao Date: Tue, 12 Jan 2021 18:46:41 +0800 Subject: [PATCH] soc: rockchip: mtd_vendor_storage: fix write issue The page offset is need point to empty page. And also need to deal case with ECC error. Signed-off-by: Yifeng Zhao Change-Id: I459345f18823b63cc5084be63c9a64c36838a151 --- drivers/soc/rockchip/mtd_vendor_storage.c | 28 ++++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/soc/rockchip/mtd_vendor_storage.c b/drivers/soc/rockchip/mtd_vendor_storage.c index 1cce16889d93..f466023f9684 100644 --- a/drivers/soc/rockchip/mtd_vendor_storage.c +++ b/drivers/soc/rockchip/mtd_vendor_storage.c @@ -133,7 +133,9 @@ static int mtd_vendor_storage_init(void) if (!mtd_block_isbad(mtd, offset)) { err = mtd_read(mtd, offset, sizeof(*g_vendor), &bytes_read, (u8 *)g_vendor); - if (!err && bytes_read == sizeof(*g_vendor) && + if (err && err != -EUCLEAN) + continue; + if (bytes_read == sizeof(*g_vendor) && g_vendor->tag == MTD_VENDOR_TAG && g_vendor->version == g_vendor->version2) { if (g_vendor->version > nand_info.version) { @@ -141,28 +143,38 @@ static int mtd_vendor_storage_init(void) nand_info.blk_offset = offset; } } - } else if (nand_info.blk_offset == offset) { + } else if (nand_info.blk_offset == offset) nand_info.blk_offset += mtd->erasesize; - } } if (nand_info.version) { for (offset = mtd->erasesize - nand_info.ops_size; offset >= 0; offset -= nand_info.ops_size) { - err = mtd_read(mtd, nand_info.blk_offset + offset, - 512, &bytes_read, (u8 *)g_vendor); - if (err || g_vendor->tag != MTD_VENDOR_TAG) - continue; err = mtd_read(mtd, nand_info.blk_offset + offset, sizeof(*g_vendor), &bytes_read, (u8 *)g_vendor); + + /* the page is not programmed */ if (!err && bytes_read == sizeof(*g_vendor) && + g_vendor->tag == 0xFFFFFFFF && + g_vendor->version == 0xFFFFFFFF && + g_vendor->version2 == 0xFFFFFFFF) + continue; + + /* point to the next free page */ + if (nand_info.page_offset < offset) + nand_info.page_offset = offset + nand_info.ops_size; + + /* ecc error or io error */ + if (err && err != -EUCLEAN) + continue; + + if (bytes_read == sizeof(*g_vendor) && g_vendor->tag == MTD_VENDOR_TAG && g_vendor->version == g_vendor->version2) { nand_info.version = g_vendor->version; - nand_info.page_offset = offset; break; } }