Messages in this thread Patch in this message | | | From | quanyang.wang@windrive ... | Subject | [PATCH] mtd: spi-nor: swp: fix unlock lower area failure | Date | Thu, 22 Jul 2021 20:14:00 +0800 |
| |
From: Quanyang Wang <quanyang.wang@windriver.com>
In the function spi_nor_sr_unlock, the variables "can_be_top" and "can_be_bottom" determine how to calculate the value of "lock_len".
When we try to unlock a locked region in the lower area of flash, the variables "can_be_top" and "can_be_bottom" may be all true and this is not right because for this case "lock_len" is only "ofs" but not "mtd->size - (ofs + len)".
So introduce spi_nor_is_lower_area() to check if the area to be unlocked is in the lower and use it to exclude "can_be_top".
It's similar to spi_nor_is_upper_area() which is used to exclude "can_be_bottom".
Signed-off-by: Quanyang Wang <quanyang.wang@windriver.com> --- drivers/mtd/spi-nor/swp.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index 63512ff3b184..3214b644f093 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -118,6 +118,26 @@ static bool spi_nor_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, return spi_nor_check_lock_status_sr(nor, ofs, len, sr, false); } +static bool spi_nor_is_lower_area(struct spi_nor *nor, loff_t ofs, uint64_t len) +{ + struct mtd_info *mtd = &nor->mtd; + + if (nor->flags & SNOR_F_HAS_SR_TB) + return ((ofs + len) <= (mtd->size >> 1)); + else + return false; +} + +static bool spi_nor_is_upper_area(struct spi_nor *nor, loff_t ofs, uint64_t len) +{ + struct mtd_info *mtd = &nor->mtd; + + if ((nor->flags & SNOR_F_HAS_SR_TB)) + return (ofs >= (mtd->size >> 1)); + else + return true; +} + /* * Lock a region of the flash. Compatible with ST Micro and similar flash. * Supports the block protection bits BP{0,1,2}/BP{0,1,2,3} in the status @@ -259,12 +279,13 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) return 0; /* If anything below us is locked, we can't use 'top' protection */ - if (!spi_nor_is_unlocked_sr(nor, 0, ofs, status_old)) + if ((!spi_nor_is_unlocked_sr(nor, 0, ofs, status_old)) || + spi_nor_is_lower_area(nor, ofs, len)) can_be_top = false; /* If anything above us is locked, we can't use 'bottom' protection */ if (!spi_nor_is_unlocked_sr(nor, ofs + len, mtd->size - (ofs + len), - status_old)) + status_old) || spi_nor_is_upper_area(nor, ofs, len)) can_be_bottom = false; if (!can_be_bottom && !can_be_top) -- 2.25.1
| |