[PATCH 13/46] mtd: nandsim: Add final logic for multiple instances

From: Daniel Walter
Date: Wed Aug 31 2016 - 03:37:15 EST


From: Richard Weinberger <richard@xxxxxx>

Signed-off-by: Richard Weinberger <richard@xxxxxx>
---
drivers/mtd/nand/nandsim.c | 59 ++++++++++++++++++++++++++++++++++++++--------
1 file changed, 49 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index 057cc7a..bef5afa 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -47,6 +47,7 @@
#include <linux/compat.h>
#include <linux/miscdevice.h>
#include <linux/major.h>
+#include <linux/mutex.h>

/* Default simulator parameters values */
#if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE) || \
@@ -117,6 +118,7 @@ static u_char id_bytes[8] = {
[3] = CONFIG_NANDSIM_FOURTH_ID_BYTE,
[4 ... 7] = 0xFF,
};
+static bool defaults = true;

module_param_array(id_bytes, byte, NULL, 0400);
module_param_named(first_id_byte, id_bytes[0], byte, 0400);
@@ -142,6 +144,7 @@ module_param(overridesize, uint, 0400);
module_param(cache_file, charp, 0400);
module_param(bbt, uint, 0400);
module_param(bch, uint, 0400);
+module_param(defaults, bool, 0400);

MODULE_PARM_DESC(id_bytes, "The ID bytes returned by NAND Flash 'read ID' command");
MODULE_PARM_DESC(first_id_byte, "The first byte returned by NAND Flash 'read ID' command (manufacturer ID) (obsolete)");
@@ -177,6 +180,8 @@ MODULE_PARM_DESC(cache_file, "File to use to cache nand pages instead of mem
MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in data area");
MODULE_PARM_DESC(bch, "Enable BCH ecc and set how many bits should "
"be correctable in 512-byte blocks");
+MODULE_PARM_DESC(defaults, "Register a MTD during module load using default values and module parametes. "
+ "Set to N if you want to use the nandsimctl user space tool to setup nandsim.");

/* The largest possible page size */
#define NS_LARGEST_PAGE_SIZE 4096
@@ -483,6 +488,7 @@ struct grave_page {

/* MTD structure for NAND controller */
static struct mtd_info *ns_mtds[NS_MAX_DEVICES];
+static DEFINE_MUTEX(ns_mtd_mutex);

static struct dentry *dfs_root;

@@ -2358,11 +2364,24 @@ static int ns_new_instance(struct nandsim_params *nsparam)
return -ENOMEM;
}

- WARN_ON(ns_mtds[0]);
- nsmtd = ns_mtds[0] = nand_to_mtd(chip);
+ mutex_lock(&ns_mtd_mutex);
+ for (i = 0; i < NS_MAX_DEVICES; i++) {
+ if (!ns_mtds[i])
+ break;
+ }
+
+ if (i == NS_MAX_DEVICES) {
+ NS_ERR("Cannot allocate more than %i instances!\n", NS_MAX_DEVICES);
+ retval = -ENFILE;
+ mutex_unlock(&ns_mtd_mutex);
+ goto error;
+ }
+
+ nsmtd = ns_mtds[i] = nand_to_mtd(chip);
nand = chip_to_ns(chip);
nand_set_controller_data(chip, (void *)nand);
- nand->index = 0;
+ nand->index = i;
+ mutex_unlock(&ns_mtd_mutex);

INIT_LIST_HEAD(&nand->weak_blocks);
INIT_LIST_HEAD(&nand->grave_pages);
@@ -2530,9 +2549,8 @@ error:
return retval;
}

-static void __exit ns_cleanup_default(void)
+static void ns_destroy_instance(struct mtd_info *nsmtd)
{
- struct mtd_info *nsmtd = ns_mtds[0];
struct nand_chip *chip = mtd_to_nand(nsmtd);
struct nandsim *ns = nand_get_controller_data(chip);
int i;
@@ -2546,6 +2564,17 @@ static void __exit ns_cleanup_default(void)
kfree(mtd_to_nand(nsmtd)); /* Free other structures */
}

+static void ns_destroy_all(void)
+{
+ int i;
+
+ mutex_lock(&ns_mtd_mutex);
+ for (i = 0; i < NS_MAX_DEVICES; i++)
+ if (ns_mtds[i])
+ ns_destroy_instance(ns_mtds[i]);
+ mutex_unlock(&ns_mtd_mutex);
+}
+
static int __init ns_init_default(void)
{
int ret;
@@ -2588,18 +2617,28 @@ static int __init ns_init_module(void)
if (ret)
return ret;

- ret = ns_init_default();
- if (ret)
- return ret;
+ if (defaults) {
+ ret = ns_init_default();
+ if (ret) {
+ debugfs_remove_recursive(dfs_root);
+ return ret;
+ }
+ }
+
+ ret = misc_register(&nandsim_ctrl_cdev);
+ if (ret) {
+ ns_destroy_all();
+ debugfs_remove_recursive(dfs_root);
+ }

- return misc_register(&nandsim_ctrl_cdev);
+ return ret;
}
module_init(ns_init_module);

static void __exit ns_cleanup_module(void)
{
- ns_cleanup_default();
misc_deregister(&nandsim_ctrl_cdev);
+ ns_destroy_all();
debugfs_remove_recursive(dfs_root);
}
module_exit(ns_cleanup_module);
--
2.8.3