mtd_erase() calls mtd->_erase() without checking that the driver has
one, so on a device which does not provide one it jumps to a NULL
pointer.
MTD_NO_ERASE alone does not tell us whether erase is supported, as the
flag means erase is unnecessary, not unavailable.
Linux guards mtd_erase() with
if (!mtd->erasesize || !master->_erase)
return -ENOTSUPP;
so do the same in U-Boot, but with EOPNOTSUPP as the error code,
as checkpatch asks for ("ENOTSUPP is not a SUSV4 error code, prefer
EOPNOTSUPP").
A partition gets part_erase() only when its master has an _erase, so
part_erase() cannot call through a NULL master->_erase either.
Signed-off-by: Heiko Schocher <[email protected]>
Reviewed-by: Simon Glass <[email protected]>
---
Changes in v3:
- Dropped the sentence saying nobody reads MTD_NO_ERASE, which is wrong,
spi-nor sets it for SPI_NOR_NO_ERASE parts. Say instead why the check
asks for erasesize and _erase (Simon)
- Mention the mtdpart.c hunk, a partition gets part_erase() only when
its master has an _erase (Simon)
- Added Reviewed-by from Simon, as all comments are in, beside
mtd_is_aligned_with_block_size() comment which is moved to patch
"cmd: mtd: get through a device that has no erase size"
Changes in v2:
- New patch. The SRAM driver of patch 3 has no erase, which the old
mtd_erase() would have turned into a NULL pointer jump
drivers/mtd/mtdcore.c | 3 +++
drivers/mtd/mtdpart.c | 3 ++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 3d3a84df0a6..6d5b7023bf4 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -945,6 +945,9 @@ EXPORT_SYMBOL_GPL(__put_mtd_device);
int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
{
+ if (!mtd->erasesize || !mtd->_erase)
+ return -EOPNOTSUPP;
+
if (instr->addr > mtd->size || instr->len > mtd->size - instr->addr)
return -EINVAL;
if (!(mtd->flags & MTD_WRITEABLE))
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index f3b7f1ee13c..a3003cf44b0 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -654,7 +654,8 @@ static struct mtd_info *allocate_partition(struct mtd_info
*master,
slave->_block_isbad = part_block_isbad;
if (master->_block_markbad)
slave->_block_markbad = part_block_markbad;
- slave->_erase = part_erase;
+ if (master->_erase)
+ slave->_erase = part_erase;
slave->parent = master;
slave->offset = part->offset;
INIT_LIST_HEAD(&slave->partitions);
--
2.55.0