public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/1] nand: adjust erase/read/write partition/chip size for bad blocks
@ 2013-02-27  3:57 Harvey Chapman
  2013-02-27  3:57 ` [U-Boot] [PATCH 1/1] " Harvey Chapman
  0 siblings, 1 reply; 3+ messages in thread
From: Harvey Chapman @ 2013-02-27  3:57 UTC (permalink / raw)
  To: u-boot

Accidentally let a test sneak in to the patch. Corrected.

Harvey Chapman (1):
  nand: adjust erase/read/write partition/chip size for bad blocks

 common/cmd_nand.c |   35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

-- 
1.7.10.4

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

* [U-Boot] [PATCH 1/1] nand: adjust erase/read/write partition/chip size for bad blocks
  2013-02-27  3:57 [U-Boot] [PATCH 0/1] nand: adjust erase/read/write partition/chip size for bad blocks Harvey Chapman
@ 2013-02-27  3:57 ` Harvey Chapman
  2013-02-27 21:48   ` Scott Wood
  0 siblings, 1 reply; 3+ messages in thread
From: Harvey Chapman @ 2013-02-27  3:57 UTC (permalink / raw)
  To: u-boot

Adjust the sizes calculated for whole partition/chip operations by
removing the size of bad blocks so we don't try to erase/read/write
past a partition/chip boundary.

Signed-off-by: Harvey Chapman <hchapman@3gfp.com>
---
 common/cmd_nand.c |   35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index 495610c..460b370 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -428,6 +428,31 @@ static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count,
 	return ret;
 }
 
+/* Adjust a chip/partition size down for bad blocks so we don't
+ * read/write/erase past the end of a chip/partition by accident.
+ */
+static void adjust_size_for_badblocks(loff_t *size, loff_t offset, int dev)
+{
+	/* We grab the nand info object here fresh because this is usually
+	 * called after arg_off_size() which can change the value of dev.
+	 */
+	nand_info_t *nand = &nand_info[dev];
+	loff_t maxoffset = offset + *size;
+	int badblocks = 0;
+
+	/* count badblocks in NAND from offset to offset + size */
+	for (; offset < maxoffset; offset += nand->erasesize) {
+		if (nand_block_isbad(nand, offset))
+			badblocks++;
+	}
+	/* adjust size if any bad blocks found */
+	if (badblocks) {
+		*size -= badblocks * nand->erasesize;
+		printf("size adjusted to 0x%llx (%d bad blocks)\n",
+		       (unsigned long long)*size, badblocks);
+	}
+}
+
 static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	int i, ret = 0;
@@ -524,6 +549,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		int scrub = !strncmp(cmd, "scrub", 5);
 		int spread = 0;
 		int args = 2;
+		int adjust_size = 0;
 		const char *scrub_warn =
 			"Warning: "
 			"scrub option will erase all factory set bad blocks!\n"
@@ -540,8 +566,10 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 				spread = 1;
 			} else if (!strcmp(&cmd[5], ".part")) {
 				args = 1;
+				adjust_size = 1;
 			} else if (!strcmp(&cmd[5], ".chip")) {
 				args = 0;
+				adjust_size = 1;
 			} else {
 				goto usage;
 			}
@@ -560,6 +588,10 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		if (arg_off_size(argc - o, argv + o, &dev, &off, &size) != 0)
 			return 1;
 
+		/* size is unspecified */
+		if (adjust_size && !scrub)
+			adjust_size_for_badblocks(&size, off, dev);
+
 		nand = &nand_info[dev];
 
 		memset(&opts, 0, sizeof(opts));
@@ -644,6 +676,9 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 						&off, &size) != 0)
 				return 1;
 
+			/* size is unspecified */
+			if (argc < 5)
+				adjust_size_for_badblocks(&size, off, dev);
 			rwsize = size;
 		}
 
-- 
1.7.10.4

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

* [U-Boot] [PATCH 1/1] nand: adjust erase/read/write partition/chip size for bad blocks
  2013-02-27  3:57 ` [U-Boot] [PATCH 1/1] " Harvey Chapman
@ 2013-02-27 21:48   ` Scott Wood
  0 siblings, 0 replies; 3+ messages in thread
From: Scott Wood @ 2013-02-27 21:48 UTC (permalink / raw)
  To: u-boot

On 02/26/2013 09:57:14 PM, Harvey Chapman wrote:
> Adjust the sizes calculated for whole partition/chip operations by
> removing the size of bad blocks so we don't try to erase/read/write
> past a partition/chip boundary.
> 
> Signed-off-by: Harvey Chapman <hchapman@3gfp.com>
> ---
>  common/cmd_nand.c |   35 +++++++++++++++++++++++++++++++++++
>  1 file changed, 35 insertions(+)

I don't think we want to do this adjustment for erase -- the value you  
pass in there is already defined as being the range of blocks on the  
flash, rather than the amount of data you want to be able to store in  
the range (except for the ".spread" variant, but that can't be used  
with .part or .chip).

This makes me wonder if a better approach would be a flag that tells  
the nand_read|write_skip_bad() function whether "size" is meant as  
"good data size" or "actual size"?  Then we could just set that flag  
for whole-chip/whole-partition accesses, and let the existing bad block  
skipping code handle it with some minor tweaks.  This would be similar  
to opts->spread for erase.

-Scott

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

end of thread, other threads:[~2013-02-27 21:48 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-02-27  3:57 [U-Boot] [PATCH 0/1] nand: adjust erase/read/write partition/chip size for bad blocks Harvey Chapman
2013-02-27  3:57 ` [U-Boot] [PATCH 1/1] " Harvey Chapman
2013-02-27 21:48   ` Scott Wood

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox