[PATCH 02/46] mtd: nand: TODO Propagate mtd_device_unregister() return value in tear down

From: Daniel Walter
Date: Wed Aug 31 2016 - 03:29:27 EST


From: Richard Weinberger <richard@xxxxxx>

Provide a __nand_release() function for drivers which can deal
with a failing nand release operation.
Most drivers should be safe since they rely on module refcounting.
To catch outliers implement a nand_release() with a WARN_ON().

Signed-off-by: Richard Weinberger <richard@xxxxxx>
---
drivers/mtd/nand/nand_base.c | 15 ++++++++++-----
include/linux/mtd/nand.h | 12 +++++++++++-
2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 77533f7..d5608dd 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -4601,19 +4601,22 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
EXPORT_SYMBOL(nand_scan);

/**
- * nand_release - [NAND Interface] Free resources held by the NAND device
+ * __nand_release - [NAND Interface] Free resources held by the NAND device
* @mtd: MTD device structure
*/
-void nand_release(struct mtd_info *mtd)
+int __nand_release(struct mtd_info *mtd)
{
+ int ret;
struct nand_chip *chip = mtd_to_nand(mtd);

+ ret = mtd_device_unregister(mtd);
+ if (ret)
+ return ret;
+
if (chip->ecc.mode == NAND_ECC_SOFT &&
chip->ecc.algo == NAND_ECC_BCH)
nand_bch_free((struct nand_bch_control *)chip->ecc.priv);

- mtd_device_unregister(mtd);
-
/* Free bad block table memory */
kfree(chip->bbt);
if (!(chip->options & NAND_OWN_BUFFERS))
@@ -4623,8 +4626,10 @@ void nand_release(struct mtd_info *mtd)
if (chip->badblock_pattern && chip->badblock_pattern->options
& NAND_BBT_DYNAMICSTRUCT)
kfree(chip->badblock_pattern);
+
+ return 0;
}
-EXPORT_SYMBOL_GPL(nand_release);
+EXPORT_SYMBOL_GPL(__nand_release);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Steven J. Hill <sjhill@xxxxxxxxxxxxxxxxxx>");
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 8dd6e01..06be25e 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -39,7 +39,7 @@ extern int nand_scan_ident(struct mtd_info *mtd, int max_chips,
extern int nand_scan_tail(struct mtd_info *mtd);

/* Free resources held by the NAND device */
-extern void nand_release(struct mtd_info *mtd);
+extern int __nand_release(struct mtd_info *mtd);

/* Internal helper for board drivers which need to override command function */
extern void nand_wait_ready(struct mtd_info *mtd);
@@ -1023,6 +1023,16 @@ static inline int jedec_feature(struct nand_chip *chip)
: 0;
}

+static inline void nand_release(struct mtd_info *mtd)
+{
+ /*
+ * If you face this warning your driver is doing something bad.
+ * Don't issue nand_release() when your MTD is in use.
+ * Use __nand_release() and handle the error correctly.
+ */
+ WARN_ON(__nand_release(mtd) != 0);
+}
+
/*
* struct nand_sdr_timings - SDR NAND chip timings
*
--
2.8.3