[PATCH RFC] mtd: spi nor: fix erase_map.regions after memcpy for uniform eraseregion
John Thomson
git at johnthomson.fastmail.com.au
Tue Sep 22 05:21:35 EDT 2020
For a uniform erase regions device, erase_map.regions points to the
address of erase_map.uniform_region.
There is a memcpy of nor->params, which includes
erase_map.regions, and erase_map.uniform_region.
The memcpy destination erase_map.regions pointer needs to be updated to
the new address of uniform_region.
Without this change, when a uniform erase region spi-nor device used
the multiple erase regions code path,
e.g. spi_nor_has_uniform_erase forced to return false,
erase operations failed in find_erase_region.
This code path is not currently used for uniform eraseregion devices,
but is useful to allow use of minor (4K) erase while otherwise using 64K erase.
Signed-off-by: John Thomson <git at johnthomson.fastmail.com.au>
---
Only build tested on master,
what devices or approach is used to test master MTD SPI NOR?
Found and tested in kernel 5.4 on Openwrt on a MIPS access point,
while testing changes to mtdpart.c to allow writes for partitions
on 4K (minor) erase boundaries.
with:
- CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
- spi_nor_has_uniform_erase forced to return false,
so that a request for a 4K erase could use the multiple erase sectors
code path on a uniform erase regions SPI NOR device.
---
drivers/mtd/spi-nor/core.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 65eff4ce6ab..30f5db65781 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2716,12 +2716,20 @@ static void spi_nor_sfdp_init_params(struct spi_nor *nor)
struct spi_nor_flash_parameter sfdp_params;
memcpy(&sfdp_params, nor->params, sizeof(sfdp_params));
+ if (nor->params->erase_map.regions ==
+ &nor->params->erase_map.uniform_region)
+ sfdp_params.erase_map.regions = (
+ &sfdp_params.erase_map.uniform_region);
if (spi_nor_parse_sfdp(nor, &sfdp_params)) {
nor->addr_width = 0;
nor->flags &= ~SNOR_F_4B_OPCODES;
} else {
memcpy(nor->params, &sfdp_params, sizeof(*nor->params));
+ if (sfdp_params.erase_map.regions ==
+ &sfdp_params.erase_map.uniform_region)
+ nor->params->erase_map.regions = (
+ &nor->params->erase_map.uniform_region);
}
}
--
2.28.0
More information about the linux-mtd
mailing list