]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mtd: spi-nor: Fix spi_nor_try_unlock_all()
authorMichael Walle <mwalle@kernel.org>
Tue, 1 Jul 2025 14:04:26 +0000 (16:04 +0200)
committerPratyush Yadav <pratyush@kernel.org>
Thu, 3 Jul 2025 15:12:17 +0000 (17:12 +0200)
Commit ff67592cbdfc ("mtd: spi-nor: Introduce spi_nor_set_mtd_info()")
moved all initialization of the mtd fields at the end of spi_nor_scan().
Normally, the mtd info is only needed for the mtd ops on the device,
with one exception: spi_nor_try_unlock_all(), which will also make use
of the mtd->size parameter. With that commit, the size will always be
zero because it is not initialized. Fix that by not using the size of
the mtd_info struct, but use the size from struct spi_nor_flash_parameter.

Fixes: ff67592cbdfc ("mtd: spi-nor: Introduce spi_nor_set_mtd_info()")
Cc: stable@vger.kernel.org
Reported-by: Jean-Marc Ranger <jmranger@hotmail.com>
Closes: https://lore.kernel.org/all/DM6PR06MB561177323DC5207E34AF2A06C547A@DM6PR06MB5611.namprd06.prod.outlook.com/
Tested-by: Jean-Marc Ranger <jmranger@hotmail.com>
Signed-off-by: Michael Walle <mwalle@kernel.org>
Reviewed-by: Pratyush Yadav <pratyush@kernel.org>
Signed-off-by: Pratyush Yadav <pratyush@kernel.org>
Link: https://lore.kernel.org/r/20250701140426.2355182-1-mwalle@kernel.org
drivers/mtd/spi-nor/swp.c

index 9c9328478d8a5ba3f54de18cda4fae91232cce51..9b07f83aeac76dce2109f90dfa1534c9bd93330d 100644 (file)
@@ -56,7 +56,6 @@ static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor)
 static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs,
                                        u64 *len)
 {
-       struct mtd_info *mtd = &nor->mtd;
        u64 min_prot_len;
        u8 mask = spi_nor_get_sr_bp_mask(nor);
        u8 tb_mask = spi_nor_get_sr_tb_mask(nor);
@@ -77,13 +76,13 @@ static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs,
        min_prot_len = spi_nor_get_min_prot_length_sr(nor);
        *len = min_prot_len << (bp - 1);
 
-       if (*len > mtd->size)
-               *len = mtd->size;
+       if (*len > nor->params->size)
+               *len = nor->params->size;
 
        if (nor->flags & SNOR_F_HAS_SR_TB && sr & tb_mask)
                *ofs = 0;
        else
-               *ofs = mtd->size - *len;
+               *ofs = nor->params->size - *len;
 }
 
 /*
@@ -158,7 +157,6 @@ static bool spi_nor_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, u64 len,
  */
 static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
 {
-       struct mtd_info *mtd = &nor->mtd;
        u64 min_prot_len;
        int ret, status_old, status_new;
        u8 mask = spi_nor_get_sr_bp_mask(nor);
@@ -183,7 +181,7 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
                can_be_bottom = false;
 
        /* If anything above us is unlocked, we can't use 'top' protection */
-       if (!spi_nor_is_locked_sr(nor, ofs + len, mtd->size - (ofs + len),
+       if (!spi_nor_is_locked_sr(nor, ofs + len, nor->params->size - (ofs + len),
                                  status_old))
                can_be_top = false;
 
@@ -195,11 +193,11 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
 
        /* lock_len: length of region that should end up locked */
        if (use_top)
-               lock_len = mtd->size - ofs;
+               lock_len = nor->params->size - ofs;
        else
                lock_len = ofs + len;
 
-       if (lock_len == mtd->size) {
+       if (lock_len == nor->params->size) {
                val = mask;
        } else {
                min_prot_len = spi_nor_get_min_prot_length_sr(nor);
@@ -248,7 +246,6 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
  */
 static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len)
 {
-       struct mtd_info *mtd = &nor->mtd;
        u64 min_prot_len;
        int ret, status_old, status_new;
        u8 mask = spi_nor_get_sr_bp_mask(nor);
@@ -273,7 +270,7 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 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),
+       if (!spi_nor_is_unlocked_sr(nor, ofs + len, nor->params->size - (ofs + len),
                                    status_old))
                can_be_bottom = false;
 
@@ -285,7 +282,7 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len)
 
        /* lock_len: length of region that should remain locked */
        if (use_top)
-               lock_len = mtd->size - (ofs + len);
+               lock_len = nor->params->size - (ofs + len);
        else
                lock_len = ofs;