From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932764AbcIUJuS (ORCPT ); Wed, 21 Sep 2016 05:50:18 -0400 Received: from mail.sigma-star.at ([95.130.255.111]:45996 "EHLO mail.sigma-star.at" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751493AbcIUJuM (ORCPT ); Wed, 21 Sep 2016 05:50:12 -0400 From: Daniel Walter To: linux-mtd@lists.infradead.org Cc: linux-kernel@vger.kernel.org, computersforpeace@gmail.com, dwmw2@infradead.org, boris.brezillon@free-electrons.com, Richard Weinberger Subject: [PATCH v2 17/46] mtd: nandsim: Allow external backends Date: Wed, 21 Sep 2016 11:50:04 +0200 Message-Id: <5d7d64cbb45a2bd58bcd26e8c84a964cedc76356.1474450296.git.dwalter@sigma-star.at> X-Mailer: git-send-email 2.8.3 In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Richard Weinberger This turns nandsim into a mini framework to allow backends implemented in different drivers. i.e. virtio or usermodelinux. Signed-off-by: Richard Weinberger --- drivers/mtd/nand/nandsim.c | 124 +++++++++++++++++--------------------------- include/linux/mtd/nandsim.h | 83 +++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 77 deletions(-) create mode 100644 include/linux/mtd/nandsim.h diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index e333c5c..21a6e1a 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -294,42 +295,11 @@ MODULE_PARM_DESC(defaults, "Register a MTD during module load using default val /* Maximum page cache pages needed to read or write a NAND page to the cache_file */ #define NS_MAX_HELD_PAGES 16 -struct nandsim_params { - unsigned int access_delay; - unsigned int program_delay; - unsigned int erase_delay; - unsigned int output_cycle; - unsigned int input_cycle; - unsigned int bus_width; - unsigned int do_delays; - unsigned long *parts; - unsigned int parts_num; - char *badblocks; - char *weakblocks; - char *weakpages; - unsigned int bitflips; - char *gravepages; - unsigned int overridesize; - char *cache_file; - unsigned int bbt; - unsigned int bch; - unsigned char *id_bytes; - struct ns_backend_ops *bops; -}; - struct nandsim_debug_info { struct dentry *dfs_root; struct dentry *dfs_wear_report; }; -/* - * A union to represent flash memory contents and flash buffer. - */ -union ns_mem { - u_char *byte; /* for byte access */ - uint16_t *word; /* for 16-bit word access */ -}; - struct ns_ram_data { /* The simulated NAND flash pages array */ union ns_mem *pages; @@ -367,35 +337,8 @@ struct nandsim { /* Internal buffer of page + OOB size bytes */ union ns_mem buf; - - /* NAND flash "geometry" */ - struct { - uint64_t totsz; /* total flash size, bytes */ - uint32_t secsz; /* flash sector (erase block) size, bytes */ - uint pgsz; /* NAND flash page size, bytes */ - uint oobsz; /* page OOB area size, bytes */ - uint64_t totszoob; /* total flash size including OOB, bytes */ - uint pgszoob; /* page size including OOB , bytes*/ - uint secszoob; /* sector size including OOB, bytes */ - uint pgnum; /* total number of pages */ - uint pgsec; /* number of pages per sector */ - uint secshift; /* bits number in sector size */ - uint pgshift; /* bits number in page size */ - uint pgaddrbytes; /* bytes per page address */ - uint secaddrbytes; /* bytes per sector address */ - uint idbytes; /* the number ID bytes that this chip outputs */ - } geom; - - /* NAND flash internal registers */ - struct { - unsigned command; /* the command register */ - u_char status; /* the status register */ - uint row; /* the page number */ - uint column; /* the offset within page */ - uint count; /* internal counter */ - uint num; /* number of bytes which must be processed */ - uint off; /* fixed page offset */ - } regs; + struct nandsim_geom geom; + struct nandsim_regs regs; /* NAND flash lines state */ struct { @@ -427,14 +370,6 @@ struct nandsim { struct nandsim_debug_info dbg; }; -struct ns_backend_ops { - void (*erase_sector)(struct nandsim *ns); - int (*prog_page)(struct nandsim *ns, int num); - void (*read_page)(struct nandsim *ns, int num); - int (*init)(struct nandsim *ns, struct nandsim_params *nsparam); - void (*destroy)(struct nandsim *ns); -}; - static struct ns_backend_ops ns_ram_bops; static struct ns_backend_ops ns_cachefile_bops; @@ -736,6 +671,36 @@ err_close: return err; } +struct nandsim_geom *nandsim_get_geom(struct nandsim *ns) +{ + return &ns->geom; +} +EXPORT_SYMBOL_GPL(nandsim_get_geom); + +struct nandsim_regs *nandsim_get_regs(struct nandsim *ns) +{ + return &ns->regs; +} +EXPORT_SYMBOL_GPL(nandsim_get_regs); + +void nandsim_set_backend_data(struct nandsim *ns, void *data) +{ + ns->backend_data = data; +} +EXPORT_SYMBOL_GPL(nandsim_set_backend_data); + +void *nandsim_get_backend_data(struct nandsim *ns) +{ + return ns->backend_data; +} +EXPORT_SYMBOL_GPL(nandsim_get_backend_data); + +union ns_mem *nandsim_get_buf(struct nandsim *ns) +{ + return &ns->buf; +} +EXPORT_SYMBOL_GPL(nandsim_get_buf); + static void ns_ram_destroy(struct nandsim *ns) { struct ns_ram_data *data = ns->backend_data; @@ -2396,7 +2361,7 @@ static struct miscdevice nandsim_ctrl_cdev = { .fops = &nansim_ctrl_fops, }; -static int ns_new_instance(struct nandsim_params *nsparam) +struct mtd_info *ns_new_instance(struct nandsim_params *nsparam) { struct nand_chip *chip; struct nandsim *nand; @@ -2406,7 +2371,7 @@ static int ns_new_instance(struct nandsim_params *nsparam) if (nsparam->bus_width != 8 && nsparam->bus_width != 16) { NS_ERR("wrong bus width (%d), use only 8 or 16\n", nsparam->bus_width); - return -EINVAL; + return ERR_PTR(-EINVAL); } /* Allocate and initialize mtd_info, nand_chip and nandsim structures */ @@ -2414,7 +2379,7 @@ static int ns_new_instance(struct nandsim_params *nsparam) GFP_KERNEL); if (!chip) { NS_ERR("unable to allocate core structures.\n"); - return -ENOMEM; + return ERR_PTR(-ENOMEM); } mutex_lock(&ns_mtd_mutex); @@ -2588,7 +2553,7 @@ static int ns_new_instance(struct nandsim_params *nsparam) if (retval != 0) goto err_exit; - return 0; + return nsmtd; err_exit: free_nandsim(nand); @@ -2599,10 +2564,11 @@ error: free_lists(nand); kfree(chip); - return retval; + return ERR_PTR(retval); } +EXPORT_SYMBOL_GPL(ns_new_instance); -static void ns_destroy_instance(struct mtd_info *nsmtd) +void ns_destroy_instance(struct mtd_info *nsmtd) { struct nand_chip *chip = mtd_to_nand(nsmtd); struct nandsim *ns = nand_get_controller_data(chip); @@ -2616,6 +2582,7 @@ static void ns_destroy_instance(struct mtd_info *nsmtd) kfree(ns->partitions[i].name); kfree(mtd_to_nand(nsmtd)); /* Free other structures */ } +EXPORT_SYMBOL_GPL(ns_destroy_instance); static void ns_destroy_all(void) { @@ -2630,7 +2597,7 @@ static void ns_destroy_all(void) static int __init ns_init_default(void) { - int ret; + struct mtd_info *nsmtd; struct nandsim_params *nsparam = kzalloc(sizeof(*nsparam), GFP_KERNEL); if (!nsparam) @@ -2661,10 +2628,13 @@ static int __init ns_init_default(void) else nsparam->bops = &ns_cachefile_bops; - ret = ns_new_instance(nsparam); + nsmtd = ns_new_instance(nsparam); kfree(nsparam); - return ret; + if (IS_ERR(nsmtd)) + return PTR_ERR(nsmtd); + + return 0; } static int __init ns_init_module(void) diff --git a/include/linux/mtd/nandsim.h b/include/linux/mtd/nandsim.h new file mode 100644 index 0000000..2d596ad --- /dev/null +++ b/include/linux/mtd/nandsim.h @@ -0,0 +1,83 @@ +#ifndef __LINUX_NANDSIM_H__ +#define __LINUX_NANDSIM_H__ + +#include + +struct nandsim_params { + unsigned int access_delay; + unsigned int program_delay; + unsigned int erase_delay; + unsigned int output_cycle; + unsigned int input_cycle; + unsigned int bus_width; + unsigned int do_delays; + unsigned long *parts; + unsigned int parts_num; + char *badblocks; + char *weakblocks; + char *weakpages; + unsigned int bitflips; + char *gravepages; + unsigned int overridesize; + char *cache_file; + unsigned int bbt; + unsigned int bch; + unsigned char *id_bytes; + struct ns_backend_ops *bops; +}; + +/* NAND flash "geometry" */ +struct nandsim_geom { + uint64_t totsz; /* total flash size, bytes */ + uint32_t secsz; /* flash sector (erase block) size, bytes */ + uint pgsz; /* NAND flash page size, bytes */ + uint oobsz; /* page OOB area size, bytes */ + uint64_t totszoob; /* total flash size including OOB, bytes */ + uint pgszoob; /* page size including OOB , bytes*/ + uint secszoob; /* sector size including OOB, bytes */ + uint pgnum; /* total number of pages */ + uint pgsec; /* number of pages per sector */ + uint secshift; /* bits number in sector size */ + uint pgshift; /* bits number in page size */ + uint pgaddrbytes; /* bytes per page address */ + uint secaddrbytes; /* bytes per sector address */ + uint idbytes; /* the number ID bytes that this chip outputs */ +}; + +/* NAND flash internal registers */ +struct nandsim_regs { + unsigned command; /* the command register */ + u_char status; /* the status register */ + uint row; /* the page number */ + uint column; /* the offset within page */ + uint count; /* internal counter */ + uint num; /* number of bytes which must be processed */ + uint off; /* fixed page offset */ +}; + +/* + * A union to represent flash memory contents and flash buffer. + */ +union ns_mem { + u_char *byte; /* for byte access */ + uint16_t *word; /* for 16-bit word access */ +}; + +struct nandsim; +struct ns_backend_ops { + void (*erase_sector)(struct nandsim *ns); + int (*prog_page)(struct nandsim *ns, int num); + void (*read_page)(struct nandsim *ns, int num); + int (*init)(struct nandsim *ns, struct nandsim_params *nsparam); + void (*destroy)(struct nandsim *ns); +}; + +struct mtd_info *ns_new_instance(struct nandsim_params *nsparam); +void ns_destroy_instance(struct mtd_info *nsmtd); +struct nandsim_geom *nandsim_get_geom(struct nandsim *ns); +struct nandsim_regs *nandsim_get_regs(struct nandsim *ns); +void nandsim_set_backend_data(struct nandsim *ns, void *data); +void *nandsim_get_backend_data(struct nandsim *ns); +union ns_mem *nandsim_get_buf(struct nandsim *ns); + +#endif /* __LINUX_NANDSIM_H__ */ -- 2.8.3