From patchwork Wed Aug 31 07:28:35 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Walter X-Patchwork-Id: 664396 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3sPHFx699Sz9s9G for ; Wed, 31 Aug 2016 17:34:29 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bf01P-0008KR-LY; Wed, 31 Aug 2016 07:33:19 +0000 Received: from mail.sigma-star.at ([95.130.255.111]) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bezyI-0004t6-Ju for linux-mtd@lists.infradead.org; Wed, 31 Aug 2016 07:30:17 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by mail.sigma-star.at (Postfix) with ESMTP id D9F2524E001B; Wed, 31 Aug 2016 09:29:50 +0200 (CEST) X-Virus-Scanned: amavisd-new at mail.sigma-star.at Received: from dw (unknown [82.150.214.13]) by mail.sigma-star.at (Postfix) with ESMTPSA id ED1B524E0003; Wed, 31 Aug 2016 09:29:48 +0200 (CEST) Received: by dw (sSMTP sendmail emulation); Wed, 31 Aug 2016 09:29:49 +0200 From: Daniel Walter To: linux-mtd@lists.infradead.org Subject: [PATCH 28/46] mtd: nandsim: Refine exports Date: Wed, 31 Aug 2016 09:28:35 +0200 Message-Id: <20160831072853.27822-29-dwalter@sigma-star.at> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20160831072853.27822-1-dwalter@sigma-star.at> References: <20160831072853.27822-1-dwalter@sigma-star.at> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160831_003007_373333_ED3275FE X-CRM114-Status: GOOD ( 21.01 ) X-Spam-Score: -3.3 (---) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-3.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -1.4 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Weinberger , linux-kernel@vger.kernel.org MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Richard Weinberger Keep the file backend logic directly in nandsim such that other users of only have to implement simple read/write functions. Signed-off-by: Richard Weinberger --- drivers/mtd/nand/nandsim.c | 101 +++++++++++++++++++++++++++++++++----------- include/linux/mtd/nandsim.h | 33 ++++++--------- 2 files changed, 88 insertions(+), 46 deletions(-) diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index f5aa0c4..f2ebf8b 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -302,6 +302,14 @@ struct nandsim_debug_info { 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; @@ -350,7 +358,17 @@ struct nandsim { /* Internal buffer of page + OOB size bytes */ union ns_mem buf; struct nandsim_geom geom; - struct nandsim_regs regs; + + /* NAND flash internal registers */ + struct { + unsigned int 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; /* NAND flash lines state */ struct { @@ -773,12 +791,6 @@ struct nandsim_geom *nandsim_get_geom(struct nandsim *ns) } 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; @@ -791,12 +803,6 @@ void *nandsim_get_backend_data(struct nandsim *ns) } 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; @@ -1706,9 +1712,10 @@ static void ns_cachefile_read_page(struct nandsim *ns, int num) } } -static void ns_file_read_page(struct nandsim *ns, int num) +void __ns_file_read_page(struct nandsim *ns, int num, + int (*read_fn)(struct nandsim *ns, char *addr, + unsigned long count, loff_t offset)) { - struct ns_file_data *data = ns->backend_data; loff_t pos; ssize_t tx; @@ -1734,12 +1741,26 @@ static void ns_file_read_page(struct nandsim *ns, int num) } pos = (loff_t)NS_RAW_OFFSET(ns) + ns->regs.off; - tx = kernel_read(data->file, pos, ns->buf.byte, num); + tx = read_fn(ns, ns->buf.byte, num, pos); if (tx == 0) memset(ns->buf.byte, 0xff, num); else if (tx != num) NS_ERR("read_page: read error for page %d ret %ld\n", ns->regs.row, (long)tx); } +EXPORT_SYMBOL_GPL(__ns_file_read_page); + +static inline int do_kernel_read(struct nandsim *ns, char *addr, + unsigned long count, loff_t offset) +{ + struct ns_file_data *data = ns->backend_data; + + return kernel_read(data->file, offset, addr, count); +} + +static void ns_file_read_page(struct nandsim *ns, int num) +{ + __ns_file_read_page(ns, num, do_kernel_read); +} static void ns_ram_erase_sector(struct nandsim *ns) { @@ -1771,24 +1792,42 @@ static void ns_cachefile_erase_sector(struct nandsim *ns) } } -static void ns_file_erase_sector(struct nandsim *ns) +static inline ssize_t do_kernel_write(struct nandsim *ns, const char *addr, + size_t count, loff_t offset) +{ + struct ns_file_data *data = ns->backend_data; + + return kernel_write(data->file, addr, count, offset); +} + + +void __ns_file_erase_sector(struct nandsim *ns, char *file_buf, + ssize_t (*write_fn)(struct nandsim *ns, const char *buf, + size_t count, loff_t pos)) { int i; loff_t pos; ssize_t tx; unsigned int pagesz = ns->no_oob ? ns->geom.pgsz : ns->geom.pgszoob; - struct ns_file_data *data = ns->backend_data; - memset(data->file_buf, 0xff, pagesz); + memset(file_buf, 0xff, pagesz); for (i = 0; i < ns->geom.pgsec; i++) { pos = (loff_t)(ns->regs.row + i) * pagesz; - tx = kernel_write(data->file, data->file_buf, pagesz, pos); + tx = write_fn(ns, file_buf, pagesz, pos); if (tx != pagesz) { NS_ERR("prog_page: write error for page %d ret %ld\n", ns->regs.row, (long)tx); } } } +EXPORT_SYMBOL_GPL(__ns_file_erase_sector); + +static void ns_file_erase_sector(struct nandsim *ns) +{ + struct ns_file_data *data = ns->backend_data; + + __ns_file_erase_sector(ns, data->file_buf, do_kernel_write); +} static int ns_ram_prog_page(struct nandsim *ns, int num) { @@ -1863,13 +1902,16 @@ static int ns_cachefile_prog_page(struct nandsim *ns, int num) return 0; } -static int ns_file_prog_page(struct nandsim *ns, int num) +int __ns_file_prog_page(struct nandsim *ns, int num, char *file_buf, + int (*read_fn)(struct nandsim *ns, char *addr, + unsigned long count, loff_t offset), + ssize_t (*write_fn)(struct nandsim *ns, const char *buf, + size_t count, loff_t pos)) { int i; loff_t off; ssize_t tx; u_char *pg_off; - struct ns_file_data *data = ns->backend_data; NS_DBG("prog_page: writing page %d\n", ns->regs.row); @@ -1885,10 +1927,10 @@ static int ns_file_prog_page(struct nandsim *ns, int num) num -= pg_write_end - ns->geom.pgsz; } - pg_off = data->file_buf + ns->regs.column + ns->regs.off; + pg_off = file_buf + ns->regs.column + ns->regs.off; off = (loff_t)NS_RAW_OFFSET(ns) + ns->regs.off; - tx = kernel_read(data->file, off, pg_off, num); + tx = read_fn(ns, pg_off, num, off); if (tx == 0) memset(pg_off, 0xff, num); else if (tx != num) { @@ -1899,7 +1941,7 @@ static int ns_file_prog_page(struct nandsim *ns, int num) for (i = 0; i < num; i++) pg_off[i] &= ns->buf.byte[i]; - tx = kernel_write(data->file, pg_off, num, off); + tx = write_fn(ns, pg_off, num, off); if (tx != num) { NS_ERR("prog_page: write error for page %d ret %ld\n", ns->regs.row, (long)tx); return -1; @@ -1907,6 +1949,15 @@ static int ns_file_prog_page(struct nandsim *ns, int num) return 0; } +EXPORT_SYMBOL_GPL(__ns_file_prog_page); + +static int ns_file_prog_page(struct nandsim *ns, int num) +{ + struct ns_file_data *data = ns->backend_data; + + return __ns_file_prog_page(ns, num, data->file_buf, do_kernel_read, + do_kernel_write); +} static struct ns_backend_ops ns_ram_bops = { .erase_sector = ns_ram_erase_sector, diff --git a/include/linux/mtd/nandsim.h b/include/linux/mtd/nandsim.h index 05ac7e3..85d4d7e 100644 --- a/include/linux/mtd/nandsim.h +++ b/include/linux/mtd/nandsim.h @@ -47,25 +47,6 @@ struct nandsim_geom { 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); @@ -79,9 +60,19 @@ struct ns_backend_ops { struct mtd_info *ns_new_instance(struct nandsim_params *nsparam); int 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); +void __ns_file_read_page(struct nandsim *ns, int num, + int (*read_fn)(struct nandsim *ns, char *addr, + unsigned long count, loff_t offset)); + +int __ns_file_prog_page(struct nandsim *ns, int num, char *file_buf, + int (*read_fn)(struct nandsim *ns, char *addr, + unsigned long count, loff_t offset), + ssize_t (*write_fn)(struct nandsim *ns, const char *buf, + size_t count, loff_t pos)); +void __ns_file_erase_sector(struct nandsim *ns, char *file_buf, + ssize_t (*write_fn)(struct nandsim *ns, const char *buf, + size_t count, loff_t pos)); #endif /* __LINUX_NANDSIM_H__ */