From a67b3719f32673a9890700c72b980acbd2749e49 Mon Sep 17 00:00:00 2001 From: Marek Behún Date: Tue, 5 Oct 2021 15:56:01 +0200 Subject: mtd: spi-flash: Check for zero length in legacy spi_flash_*() Check for zero length in the legacy spi_flash_read() / spi_flash_write() / spi_flash_erase() functions. On zero length, return 0 immediately, don't call the underlying method. Rationale: - these legacy functions call the _read(), _write() and _erase() methods of struct mtd - the DM callers of these methods already check for zero length - making all callers of these methods check for zero length makes it possible to remove the check from implementations of these _read(), _write() and _erase() methods Signed-off-by: Marek Behún --- include/spi_flash.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/spi_flash.h b/include/spi_flash.h index 3d747c925b9..4d4ae89c192 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -165,6 +165,9 @@ static inline int spi_flash_read(struct spi_flash *flash, u32 offset, struct mtd_info *mtd = &flash->mtd; size_t retlen; + if (!len) + return 0; + return mtd->_read(mtd, offset, len, &retlen, buf); } @@ -174,6 +177,9 @@ static inline int spi_flash_write(struct spi_flash *flash, u32 offset, struct mtd_info *mtd = &flash->mtd; size_t retlen; + if (!len) + return 0; + return mtd->_write(mtd, offset, len, &retlen, buf); } @@ -188,6 +194,9 @@ static inline int spi_flash_erase(struct spi_flash *flash, u32 offset, return -EINVAL; } + if (!len) + return 0; + memset(&instr, 0, sizeof(instr)); instr.addr = offset; instr.len = len; -- cgit v1.2.3 From 0d1ecc99cb59c2190257f7738f91db21f174dc02 Mon Sep 17 00:00:00 2001 From: Marek Behún Date: Tue, 5 Oct 2021 15:56:06 +0200 Subject: mtd: Remove mtd_erase_callback() entirely The original purpose of mtd_erase_callback() in Linux at the time it was imported to U-Boot, was to inform the caller that erasing is done (since it was an asynchronous operation). All supplied callback methods in U-Boot do nothing, but the mtd_erase_callback() function was (until previous patch) grossly abused in U-Boot's mtdpart implementation for completely different purpose. Since we got rid of the abusement, remove the mtd_erase_callback() function and the .callback member from struct erase_info entirely, in order to avoid such problems in the future. Signed-off-by: Marek Behún --- cmd/onenand.c | 9 ++------- drivers/mtd/altera_qspi.c | 3 --- drivers/mtd/cfi_mtd.c | 1 - drivers/mtd/mtdconcat.c | 11 ----------- drivers/mtd/mtdcore.c | 8 -------- drivers/mtd/mtdpart.c | 21 --------------------- drivers/mtd/nand/raw/nand_base.c | 4 ---- drivers/mtd/onenand/onenand_base.c | 3 --- drivers/mtd/spi/sf_mtd.c | 1 - drivers/mtd/spi/spi-nor-core.c | 5 ++--- drivers/mtd/ubi/io.c | 13 ------------- env/onenand.c | 4 +--- fs/yaffs2/yaffs_mtdif.c | 1 - include/linux/mtd/mtd.h | 11 ----------- include/nand.h | 1 - 15 files changed, 5 insertions(+), 91 deletions(-) (limited to 'include') diff --git a/cmd/onenand.c b/cmd/onenand.c index 852ed5c7b21..592985a7ee3 100644 --- a/cmd/onenand.c +++ b/cmd/onenand.c @@ -186,9 +186,7 @@ next: static int onenand_block_erase(u32 start, u32 size, int force) { struct onenand_chip *this = mtd->priv; - struct erase_info instr = { - .callback = NULL, - }; + struct erase_info instr = {}; loff_t ofs; int ret; int blocksize = 1 << this->erase_shift; @@ -219,10 +217,7 @@ static int onenand_block_erase(u32 start, u32 size, int force) static int onenand_block_test(u32 start, u32 size) { struct onenand_chip *this = mtd->priv; - struct erase_info instr = { - .callback = NULL, - .priv = 0, - }; + struct erase_info instr = {}; int blocks; loff_t ofs; diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c index 7bac599a54a..d31391f36a4 100644 --- a/drivers/mtd/altera_qspi.c +++ b/drivers/mtd/altera_qspi.c @@ -153,7 +153,6 @@ static int altera_qspi_erase(struct mtd_info *mtd, struct erase_info *instr) putc('\n'); instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; instr->state = MTD_ERASE_FAILED; - mtd_erase_callback(instr); return -EIO; } flash = pdata->base + addr; @@ -177,7 +176,6 @@ static int altera_qspi_erase(struct mtd_info *mtd, struct erase_info *instr) writel(stat, ®s->isr); /* clear isr */ instr->fail_addr = addr; instr->state = MTD_ERASE_FAILED; - mtd_erase_callback(instr); return -EIO; } if (flash_verbose) @@ -189,7 +187,6 @@ static int altera_qspi_erase(struct mtd_info *mtd, struct erase_info *instr) addr += mtd->erasesize; } instr->state = MTD_ERASE_DONE; - mtd_erase_callback(instr); return 0; } diff --git a/drivers/mtd/cfi_mtd.c b/drivers/mtd/cfi_mtd.c index 78293caa2f7..2295bb7220b 100644 --- a/drivers/mtd/cfi_mtd.c +++ b/drivers/mtd/cfi_mtd.c @@ -58,7 +58,6 @@ static int cfi_mtd_erase(struct mtd_info *mtd, struct erase_info *instr) } instr->state = MTD_ERASE_DONE; - mtd_erase_callback(instr); return 0; } diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index 684bc949985..af3c4765c4d 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.c @@ -338,14 +338,6 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) return -EINVAL; } -static void concat_erase_callback(struct erase_info *instr) -{ - /* Nothing to do here in U-Boot */ -#ifndef __UBOOT__ - wake_up((wait_queue_head_t *) instr->priv); -#endif -} - static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase) { int err; @@ -358,7 +350,6 @@ static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase) init_waitqueue_head(&waitq); erase->mtd = mtd; - erase->callback = concat_erase_callback; erase->priv = (unsigned long) &waitq; /* @@ -498,8 +489,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) if (err) return err; - if (instr->callback) - instr->callback(instr); return 0; } diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 9496903e861..1d45fb55c72 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -906,13 +906,6 @@ void __put_mtd_device(struct mtd_info *mtd) } EXPORT_SYMBOL_GPL(__put_mtd_device); -/* - * Erase is an asynchronous operation. Device drivers are supposed - * to call instr->callback() whenever the operation completes, even - * if it completes with a failure. - * Callers are supposed to pass a callback function and wait for it - * to be called before writing to the block. - */ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) { if (instr->addr > mtd->size || instr->len > mtd->size - instr->addr) @@ -922,7 +915,6 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; if (!instr->len) { instr->state = MTD_ERASE_DONE; - mtd_erase_callback(instr); return 0; } return mtd->_erase(mtd, instr); diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 6ab481a7b1c..a435ce6d079 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -456,27 +456,6 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr) return ret; } -void mtd_erase_callback(struct erase_info *instr) -{ - if (!instr->callback) - return; - - if (instr->mtd->_erase == part_erase && instr->len) { - if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) - instr->fail_addr -= instr->mtd->offset; - instr->addr -= instr->mtd->offset; - } - - instr->callback(instr); - - if (instr->mtd->_erase == part_erase && instr->len) { - if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) - instr->fail_addr += instr->mtd->offset; - instr->addr += instr->mtd->offset; - } -} -EXPORT_SYMBOL_GPL(mtd_erase_callback); - static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { return mtd->parent->_lock(mtd->parent, ofs + mtd->offset, len); diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index b533683dfe6..f7616985d95 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -3602,10 +3602,6 @@ erase_exit: chip->select_chip(mtd, -1); nand_release_device(mtd); - /* Do call back function */ - if (!ret) - mtd_erase_callback(instr); - /* Return more or less happy */ return ret; } diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 46aeef258d9..56e1858de45 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1836,9 +1836,6 @@ int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) erase_exit: ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; - /* Do call back function */ - if (!ret) - mtd_erase_callback(instr); /* Deselect and wake up anyone waiting on the device */ onenand_release_device(mtd); diff --git a/drivers/mtd/spi/sf_mtd.c b/drivers/mtd/spi/sf_mtd.c index 04de8680809..0aed28a52b7 100644 --- a/drivers/mtd/spi/sf_mtd.c +++ b/drivers/mtd/spi/sf_mtd.c @@ -46,7 +46,6 @@ static int spi_flash_mtd_erase(struct mtd_info *mtd, struct erase_info *instr) } instr->state = MTD_ERASE_DONE; - mtd_erase_callback(instr); return 0; } diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index a85759967b0..4388a08a90d 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -918,7 +918,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) div_u64_rem(instr->len, mtd->erasesize, &rem); if (rem) { ret = -EINVAL; - goto erase_err_callback; + goto err; } addr = instr->addr; @@ -966,14 +966,13 @@ erase_err: if (!ret) ret = err; -erase_err_callback: +err: if (ret) { instr->fail_addr = addr_known ? addr : MTD_FAIL_ADDR_UNKNOWN; instr->state = MTD_ERASE_FAILED; } else { instr->state = MTD_ERASE_DONE; } - mtd_erase_callback(instr); return ret; } diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index b8b878b9182..14be95b74bc 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -304,18 +304,6 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, return err; } -/** - * erase_callback - MTD erasure call-back. - * @ei: MTD erase information object. - * - * Note, even though MTD erase interface is asynchronous, all the current - * implementations are synchronous anyway. - */ -static void erase_callback(struct erase_info *ei) -{ - wake_up_interruptible((wait_queue_head_t *)ei->priv); -} - /** * do_sync_erase - synchronously erase a physical eraseblock. * @ubi: UBI device description object @@ -346,7 +334,6 @@ retry: ei.mtd = ubi->mtd; ei.addr = (loff_t)pnum * ubi->peb_size; ei.len = ubi->peb_size; - ei.callback = erase_callback; ei.priv = (unsigned long)&wq; err = mtd_erase(ubi->mtd, &ei); diff --git a/env/onenand.c b/env/onenand.c index c8da3ff8114..1faa2cb62a3 100644 --- a/env/onenand.c +++ b/env/onenand.c @@ -73,9 +73,7 @@ static int env_onenand_save(void) #endif loff_t env_addr = CONFIG_ENV_ADDR; size_t retlen; - struct erase_info instr = { - .callback = NULL, - }; + struct erase_info instr = {}; ret = env_export(&env_new); if (ret) diff --git a/fs/yaffs2/yaffs_mtdif.c b/fs/yaffs2/yaffs_mtdif.c index d338f9aa918..50fed2d4b15 100644 --- a/fs/yaffs2/yaffs_mtdif.c +++ b/fs/yaffs2/yaffs_mtdif.c @@ -145,7 +145,6 @@ int nandmtd_EraseBlockInNAND(struct yaffs_dev *dev, int blockNumber) ei.len = dev->data_bytes_per_chunk * dev->param.chunks_per_block; ei.time = 1000; ei.retries = 2; - ei.callback = NULL; ei.priv = (u_long) dev; /* Todo finish off the ei if required */ diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 3b302fb8c31..74554009815 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -51,7 +51,6 @@ struct erase_info { u_long retries; unsigned dev; unsigned cell; - void (*callback) (struct erase_info *self); u_long priv; u_char state; struct erase_info *next; @@ -535,16 +534,6 @@ extern int unregister_mtd_user (struct mtd_notifier *old); #endif void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size); -#ifdef CONFIG_MTD_PARTITIONS -void mtd_erase_callback(struct erase_info *instr); -#else -static inline void mtd_erase_callback(struct erase_info *instr) -{ - if (instr->callback) - instr->callback(instr); -} -#endif - static inline int mtd_is_bitflip(int err) { return err == -EUCLEAN; } diff --git a/include/nand.h b/include/nand.h index 75c605193ab..09dbda4e81b 100644 --- a/include/nand.h +++ b/include/nand.h @@ -69,7 +69,6 @@ static inline int nand_erase(struct mtd_info *info, loff_t off, size_t size) instr.mtd = info; instr.addr = off; instr.len = size; - instr.callback = 0; return mtd_erase(info, &instr); } -- cgit v1.2.3