All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mtd: nandsim: Allow nandsim to re-use persisted data
@ 2013-09-25 19:25 Matthew Gabeler-Lee
  2013-11-07 15:12 ` Richard Weinberger
  0 siblings, 1 reply; 3+ messages in thread
From: Matthew Gabeler-Lee @ 2013-09-25 19:25 UTC (permalink / raw)
  To: linux-mtd

mtd: nandsim: Allow nandsim to re-use persisted data

Add optional (default disabled) module parameter to nandsim to instruct it
to assume that the cache file already has valid data in it.  This allows
data written to the cache file (or device) to be re-used across reloads of
the nandsim module, and thus reboots of the host, in much the same way that
block2mtd allows.

Signed-off-by: Matthew Gabeler-Lee <matthew@beechwoods.com>
---
  drivers/mtd/nand/nandsim.c | 42 ++++++++++++++++++++++++++++++++++++++----
  1 file changed, 38 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index bdc1d15..65ac60f 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -109,6 +109,7 @@ static unsigned int bitflips = 0;
  static char *gravepages = NULL;
  static unsigned int overridesize = 0;
  static char *cache_file = NULL;
+static uint cache_file_written = 0;
  static unsigned int bbt;
  static unsigned int bch;

@@ -133,6 +134,7 @@ module_param(bitflips,       uint, 0400);
  module_param(gravepages,     charp, 0400);
  module_param(overridesize,   uint, 0400);
  module_param(cache_file,     charp, 0400);
+module_param(cache_file_written, uint, 0400);
  module_param(bbt,	     uint, 0400);
  module_param(bch,	     uint, 0400);

@@ -166,6 +168,7 @@ MODULE_PARM_DESC(overridesize,   "Specifies the NAND Flash size overriding the I
  				 "The size is specified in erase blocks and as the exponent of a power of two"
  				 " e.g. 5 means a size of 32 erase blocks");
  MODULE_PARM_DESC(cache_file,     "File to use to cache nand pages instead of memory");
+MODULE_PARM_DESC(cache_file_written, "Assume any pages in cache file have already been written, use their existing contents");
  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");
@@ -592,6 +595,9 @@ static int alloc_device(struct nandsim *ns)
  			err = -ENOMEM;
  			goto err_close;
  		}
+		if (cache_file_written) {
+			memset(ns->pages_written, 0xFF, ns->geom.pgnum);
+		}
  		ns->file_buf = kmalloc(ns->geom.pgszoob, GFP_KERNEL);
  		if (!ns->file_buf) {
  			NS_ERR("alloc_device: unable to allocate file buf\n");
@@ -1484,7 +1490,17 @@ static void read_page(struct nandsim *ns, int num)
  			pos = (loff_t)NS_RAW_OFFSET(ns) + ns->regs.off;
  			tx = read_file(ns, ns->cfile, ns->buf.byte, num, pos);
  			if (tx != num) {
-				NS_ERR("read_page: read error for page %d ret %ld\n", ns->regs.row, (long)tx);
+				if (ns->pages_written[ns->regs.row] == 0xFF) {
+					NS_WARN("read_page: read error assuming unwritten for page %d ret %ld\n", ns->regs.row, (long)tx);
+					ns->pages_written[ns->regs.row] = 0;
+					memset(ns->buf.byte, 0xFF, num);
+					tx = write_file(ns, ns->cfile, ns->buf.byte, num, pos);
+					if (tx != num) {
+						NS_ERR("read_page: write error for page %d ret %ld\n", ns->regs.row, (long)tx);
+					}
+				} else {
+					NS_ERR("read_page: read error for page %d ret %ld\n", ns->regs.row, (long)tx);
+				}
  				return;
  			}
  			do_bit_flips(ns, num);
@@ -1515,11 +1531,22 @@ static void erase_sector(struct nandsim *ns)
  	int i;

  	if (ns->cfile) {
-		for (i = 0; i < ns->geom.pgsec; i++)
+		loff_t pos;
+		ssize_t tx;
+ 
+		memset(ns->file_buf, 0xff, ns->geom.pgszoob);
+		for (i = 0; i < ns->geom.pgsec; i++) {
  			if (__test_and_clear_bit(ns->regs.row + i,
  						 ns->pages_written)) {
  				NS_DBG("erase_sector: freeing page %d\n", ns->regs.row + i);
+				pos = (loff_t)(ns->regs.row + i) * ns->geom.pgszoob;
+				tx = write_file(ns, ns->cfile, ns->file_buf, ns->geom.pgszoob, pos);
+				if (tx != ns->geom.pgszoob) {
+					NS_ERR("erase_sector: write error for page %d ret %ld\n", ns->regs.row, (long)tx);
+				}
  			}
+			ns->pages_written[ns->regs.row + i] = 0;
+		}
  		return;
  	}

@@ -1558,8 +1585,15 @@ static int prog_page(struct nandsim *ns, int num)
  			all = 0;
  			tx = read_file(ns, ns->cfile, pg_off, num, off);
  			if (tx != num) {
-				NS_ERR("prog_page: read error for page %d ret %ld\n", ns->regs.row, (long)tx);
-				return -1;
+				if (ns->pages_written[ns->regs.row] == 0xFF) {
+					NS_WARN("prog_page: read error assuming unwritten for page %d ret %ld\n", ns->regs.row, (long)tx);
+					ns->pages_written[ns->regs.row] = 0;
+					all = 1;
+					memset(ns->file_buf, 0xff, ns->geom.pgszoob);
+				} else {
+					NS_ERR("prog_page: read error for page %d ret %ld\n", ns->regs.row, (long)tx);
+					return -1;
+				}
  			}
  		}
  		for (i = 0; i < num; i++)
-- 
1.8.4.rc3

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-11-07 17:36 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-25 19:25 [PATCH] mtd: nandsim: Allow nandsim to re-use persisted data Matthew Gabeler-Lee
2013-11-07 15:12 ` Richard Weinberger
2013-11-07 17:36   ` Matthew Gabeler-Lee

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.