From: Quanyang Wang <[email protected]> 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 <[email protected]> --- drivers/mtd/spi-nor/core.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 33433c3ed995d..944499999ecca 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1773,6 +1773,26 @@ static int spi_nor_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len, 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 @@ -1917,12 +1937,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
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#10539): https://lists.yoctoproject.org/g/linux-yocto/message/10539 Mute This Topic: https://lists.yoctoproject.org/mt/86435170/21656 Group Owner: [email protected] Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
