All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] allow scrubbing (erasing of bad blocks)
@ 2012-12-13 16:18 Wolfram Sang
  2012-12-13 16:18 ` [PATCH 1/2] mtd: nand: add flag to ignore special handling of bad blocks Wolfram Sang
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Wolfram Sang @ 2012-12-13 16:18 UTC (permalink / raw)
  To: barebox; +Cc: Wolfram Sang

This patch series first adds a flag to mtd devices which disables special
treatment for bad blocks. That means, they are handled like every other good
block. The second one then adds a scrub command which is basically a simple
erase, only that bad blocks are treated like good blocks and are trying to be
erased (which may succeed or not). This is really *not recommended*, except for
certain development use cases!

Wolfram Sang (2):
  mtd: nand: add flag to allow erasing of bad blocks
  commands: add scrub

 commands/Kconfig              |    8 +++++
 commands/flash.c              |   68 ++++++++++++++++++++++++++++++++++++++++-
 drivers/mtd/core.c            |    9 +++++-
 drivers/mtd/nand/nand_write.c |   37 +++++++++++-----------
 include/linux/mtd/mtd-abi.h   |    2 ++
 5 files changed, 105 insertions(+), 19 deletions(-)

-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 1/2] mtd: nand: add flag to ignore special handling of bad blocks
  2012-12-13 16:18 [PATCH 0/2] allow scrubbing (erasing of bad blocks) Wolfram Sang
@ 2012-12-13 16:18 ` Wolfram Sang
  2012-12-13 16:18 ` [PATCH 2/2] commands: add scrub Wolfram Sang
  2012-12-20 22:06 ` [PATCH 0/2] allow scrubbing (erasing of bad blocks) Marc Reilly
  2 siblings, 0 replies; 4+ messages in thread
From: Wolfram Sang @ 2012-12-13 16:18 UTC (permalink / raw)
  To: barebox; +Cc: Wolfram Sang

This is needed for a later command to scrub away bad blocks. ONLY USE THIS
FEATURE WHEN YOU KNOW WHAT YOU ARE DOING!

Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
---
 drivers/mtd/core.c            |    3 ++-
 drivers/mtd/nand/nand_write.c |   37 ++++++++++++++++++++-----------------
 include/linux/mtd/mtd-abi.h   |    1 +
 3 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 8601787..95db1d6 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -18,6 +18,7 @@
 #include <common.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/mtd.h>
+#include <linux/mtd/mtd-abi.h>
 #include <init.h>
 #include <xfuncs.h>
 #include <driver.h>
@@ -32,7 +33,7 @@ static LIST_HEAD(mtd_register_hooks);
 
 int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs)
 {
-	if (!mtd->block_isbad)
+	if (!mtd->block_isbad || mtd->flags & MTD_IGNORE_BB)
 		return 0;
 	if (ofs < 0 || ofs > mtd->size)
 		return -EINVAL;
diff --git a/drivers/mtd/nand/nand_write.c b/drivers/mtd/nand/nand_write.c
index 5ed04ce..a1fa5f7 100644
--- a/drivers/mtd/nand/nand_write.c
+++ b/drivers/mtd/nand/nand_write.c
@@ -567,6 +567,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 	struct nand_chip *chip = mtd->priv;
 	int rewrite_bbt[NAND_MAX_CHIPS]={0};
 	unsigned int bbt_masked_page = 0xffffffff;
+	bool do_scrub = mtd->flags & MTD_IGNORE_BB;
 
 	MTD_DEBUG(MTD_DEBUG_LEVEL3, "nand_erase: start = 0x%08x, len = %i\n",
 	      (unsigned int)instr->addr, (unsigned int)instr->len);
@@ -627,9 +628,9 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 
 	while (len) {
 		/*
-		 * heck if we have a bad block, we do not erase bad blocks !
+		 * Check if we have a bad block, if desired
 		 */
-		if (nand_block_checkbad(mtd, ((loff_t) page) <<
+		if (!do_scrub && nand_block_checkbad(mtd, ((loff_t) page) <<
 					chip->page_shift, 0, allowbbt)) {
 			printk(KERN_WARNING "nand_erase: attempt to erase a "
 			       "bad block at page 0x%08x\n", page);
@@ -657,22 +658,24 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 			status = chip->errstat(mtd, chip, FL_ERASING,
 					       status, page);
 
-		/* See if block erase succeeded */
-		if (status & NAND_STATUS_FAIL) {
-			MTD_DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: "
-			      "Failed erase, page 0x%08x\n", page);
-			instr->state = MTD_ERASE_FAILED;
-			instr->fail_addr = (page << chip->page_shift);
-			goto erase_exit;
-		}
+		if (!do_scrub) {
+			/* See if block erase succeeded */
+			if (status & NAND_STATUS_FAIL) {
+				MTD_DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: "
+				      "Failed erase, page 0x%08x\n", page);
+				instr->state = MTD_ERASE_FAILED;
+				instr->fail_addr = (page << chip->page_shift);
+				goto erase_exit;
+			}
 
-		/*
-		 * If BBT requires refresh, set the BBT rewrite flag to the
-		 * page being erased
-		 */
-		if (bbt_masked_page != 0xffffffff &&
-		    (page & BBT_PAGE_MASK) == bbt_masked_page)
-			    rewrite_bbt[chipnr] = (page << chip->page_shift);
+			/*
+			 * If BBT requires refresh, set the BBT rewrite flag to the
+			 * page being erased
+			 */
+			if (bbt_masked_page != 0xffffffff &&
+			    (page & BBT_PAGE_MASK) == bbt_masked_page)
+				    rewrite_bbt[chipnr] = (page << chip->page_shift);
+		}
 
 		/* Increment page address and decrement length */
 		len -= (1 << chip->phys_erase_shift);
diff --git a/include/linux/mtd/mtd-abi.h b/include/linux/mtd/mtd-abi.h
index 90dee7e..49eb8e6 100644
--- a/include/linux/mtd/mtd-abi.h
+++ b/include/linux/mtd/mtd-abi.h
@@ -32,6 +32,7 @@ struct mtd_oob_buf {
 #define MTD_BIT_WRITEABLE	0x800	/* Single bits can be flipped */
 #define MTD_NO_ERASE		0x1000	/* No erase necessary */
 #define MTD_POWERUP_LOCK	0x2000	/* Always locked after reset */
+#define MTD_IGNORE_BB		0x8000	/* Ignore BadBlocks, treat them normally (DANGEROUS!) */
 
 // Some common devices / combinations of capabilities
 #define MTD_CAP_ROM		0
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 2/2] commands: add scrub
  2012-12-13 16:18 [PATCH 0/2] allow scrubbing (erasing of bad blocks) Wolfram Sang
  2012-12-13 16:18 ` [PATCH 1/2] mtd: nand: add flag to ignore special handling of bad blocks Wolfram Sang
@ 2012-12-13 16:18 ` Wolfram Sang
  2012-12-20 22:06 ` [PATCH 0/2] allow scrubbing (erasing of bad blocks) Marc Reilly
  2 siblings, 0 replies; 4+ messages in thread
From: Wolfram Sang @ 2012-12-13 16:18 UTC (permalink / raw)
  To: barebox; +Cc: Wolfram Sang

Allows erasing a whole NAND device including the bad blocks. Only meant
for development where one might accidently overwrite real bad block
information. Make sure you understood the help text!

Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
---
 commands/Kconfig            |    8 +++++
 commands/flash.c            |   68 ++++++++++++++++++++++++++++++++++++++++++-
 drivers/mtd/core.c          |    6 ++++
 include/linux/mtd/mtd-abi.h |    1 +
 4 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/commands/Kconfig b/commands/Kconfig
index ac9b797..32ba35f 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -341,6 +341,14 @@ config CMD_FLASH
 	tristate
 	prompt "protect/erase"
 
+config CMD_SCRUB
+	tristate
+	depends on CMD_FLASH && EXPERIMENTAL
+	prompt "scrub"
+	help
+	  DANGEROUS! Like erase, but will erase badblocks, too!
+	  Only meant for development!
+
 config CMD_UBI
 	tristate
 	default y if UBI
diff --git a/commands/flash.c b/commands/flash.c
index d22d6a0..7cdc86d 100644
--- a/commands/flash.c
+++ b/commands/flash.c
@@ -28,9 +28,13 @@
 #include <command.h>
 #include <errno.h>
 #include <getopt.h>
+#include <malloc.h>
 #include <fs.h>
 #include <fcntl.h>
+#include <ioctl.h>
 #include <linux/stat.h>
+#include <linux/mtd/mtd-abi.h>
+#include <linux/mtd/nand.h>
 
 static int do_flerase(int argc, char *argv[])
 {
@@ -38,11 +42,14 @@ static int do_flerase(int argc, char *argv[])
 	char *filename = NULL;
 	struct stat s;
 	loff_t start = 0, size = ~0;
-	int ret = 0;
+	int ret = 0, do_scrub;
 
 	if (argc == 1)
 		return COMMAND_ERROR_USAGE;
 
+	/* was 'scrub' called? */
+	do_scrub = (*argv[0] == 's');
+
 	filename = argv[1];
 
 	if (stat(filename, &s)) {
@@ -64,10 +71,50 @@ static int do_flerase(int argc, char *argv[])
 		goto out;
 	}
 
+	if (do_scrub) {
+		ret = ioctl(fd, MEMIGNOREBAD, (void *)1);
+		if (ret) {
+			perror("activating scrub");
+			printf("Currently, scrub only works with whole NAND devices, not partitions.\n");
+			goto out;
+		}
+	}
+
 	if (erase(fd, size, start)) {
 		perror("erase");
 		ret = 1;
 	}
+
+	if (do_scrub) {
+		struct mtd_info_user user;
+		int tmp_ret;
+
+		/* Always clear 'MEMIGNOREBAD', even when erase failed! */
+		tmp_ret = ioctl(fd, MEMIGNOREBAD, (void *)0);
+		if (tmp_ret) {
+			perror("deactivating scrub");
+			ret = tmp_ret;
+		}
+
+		/* Bail out on erase error or ioctl error */
+		if (ret)
+			goto out;
+
+		/* After scrubbing, recreate BBTs */
+		ret = ioctl(fd, MEMGETINFO, &user);
+		if (ret) {
+			perror("ioctl");
+			goto out;
+		}
+
+		if (user.type == MTD_NANDFLASH) {
+			struct nand_chip *chip = user.mtd->priv;
+
+			kfree(chip->bbt);
+			chip->bbt = NULL;
+			ret = chip->scan_bbt(user.mtd);
+		}
+	}
 out:
 	close(fd);
 
@@ -99,6 +146,25 @@ devinfo_command for partition handling.
 
  */
 
+#ifdef CONFIG_CMD_SCRUB
+
+BAREBOX_CMD_HELP_START(scrub)
+BAREBOX_CMD_HELP_USAGE("scrub <device>\n")
+BAREBOX_CMD_HELP_SHORT("Scrub a NAND device. DANGEROUS! Make sure you read all help text.\n")
+BAREBOX_CMD_HELP_TEXT("This is similar to erase but will erase badblocks, too!\n")
+BAREBOX_CMD_HELP_TEXT("That will also erase factory written badblock information, but might\n")
+BAREBOX_CMD_HELP_TEXT("restore blocks you accidently marked bad. USE ONLY WHEN YOU ARE SURE!\n")
+BAREBOX_CMD_HELP_TEXT("It will always scrub the whole device, areas are not supported (yet).\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(scrub)
+	.cmd		= do_flerase,
+	.usage		= "scrub FLASH memory (DANGEROUS!)",
+	BAREBOX_CMD_HELP(cmd_scrub_help)
+BAREBOX_CMD_END
+
+#endif /* CONFIG_CMD_SCRUB */
+
 static int do_protect(int argc, char *argv[])
 {
 	int fd;
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 95db1d6..9c68b89 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -148,6 +148,12 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf)
 		ret = mtd->block_markbad(mtd, *offset);
 		break;
 #endif
+	case MEMIGNOREBAD:
+		dev_dbg(cdev->dev, "MEMINGNOREBAD: %d\n", (bool)buf);
+		mtd->flags &= ~MTD_IGNORE_BB;
+		if ((bool)buf)
+			mtd->flags |= MTD_IGNORE_BB;
+		break;
 	case MEMGETINFO:
 		user->type	= mtd->type;
 		user->flags	= mtd->flags;
diff --git a/include/linux/mtd/mtd-abi.h b/include/linux/mtd/mtd-abi.h
index 49eb8e6..a1b2eb4 100644
--- a/include/linux/mtd/mtd-abi.h
+++ b/include/linux/mtd/mtd-abi.h
@@ -99,6 +99,7 @@ struct otp_info {
 #define ECCGETLAYOUT		_IOR('M', 17, struct nand_ecclayout)
 #define ECCGETSTATS		_IOR('M', 18, struct mtd_ecc_stats)
 #define MTDFILEMODE		_IO('M', 19)
+#define MEMIGNOREBAD		_IOW('M', 64, int)
 
 /*
  * Obsolete legacy interface. Keep it in order not to break userspace
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [PATCH 0/2] allow scrubbing (erasing of bad blocks)
  2012-12-13 16:18 [PATCH 0/2] allow scrubbing (erasing of bad blocks) Wolfram Sang
  2012-12-13 16:18 ` [PATCH 1/2] mtd: nand: add flag to ignore special handling of bad blocks Wolfram Sang
  2012-12-13 16:18 ` [PATCH 2/2] commands: add scrub Wolfram Sang
@ 2012-12-20 22:06 ` Marc Reilly
  2 siblings, 0 replies; 4+ messages in thread
From: Marc Reilly @ 2012-12-20 22:06 UTC (permalink / raw)
  To: barebox; +Cc: Wolfram Sang

Hi,


On Thursday, December 13, 2012 05:18:20 PM Wolfram Sang wrote:
> This patch series first adds a flag to mtd devices which disables special
> treatment for bad blocks. That means, they are handled like every other good
> block. The second one then adds a scrub command which is basically a simple
> erase, only that bad blocks are treated like good blocks and are trying to
> be erased (which may succeed or not). This is really *not recommended*,
> except for certain development use cases!


Much nicer than the hacks I did to clear the BBT !

(unfortunately, don't have any boards that I can test on at the moment).

Cheers,
Marc

> 
> Wolfram Sang (2):
>   mtd: nand: add flag to allow erasing of bad blocks
>   commands: add scrub
> 
>  commands/Kconfig              |    8 +++++
>  commands/flash.c              |   68
> ++++++++++++++++++++++++++++++++++++++++- drivers/mtd/core.c            |  
>  9 +++++-
>  drivers/mtd/nand/nand_write.c |   37 +++++++++++-----------
>  include/linux/mtd/mtd-abi.h   |    2 ++
>  5 files changed, 105 insertions(+), 19 deletions(-)

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

end of thread, other threads:[~2012-12-20 22:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-13 16:18 [PATCH 0/2] allow scrubbing (erasing of bad blocks) Wolfram Sang
2012-12-13 16:18 ` [PATCH 1/2] mtd: nand: add flag to ignore special handling of bad blocks Wolfram Sang
2012-12-13 16:18 ` [PATCH 2/2] commands: add scrub Wolfram Sang
2012-12-20 22:06 ` [PATCH 0/2] allow scrubbing (erasing of bad blocks) Marc Reilly

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.