All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH] NAND: add the ability to directly write yaffs image
@ 2011-01-03 13:09 Lei Wen
  2011-01-05 21:29 ` Scott Wood
  0 siblings, 1 reply; 4+ messages in thread
From: Lei Wen @ 2011-01-03 13:09 UTC (permalink / raw)
  To: u-boot

This patch add addition suffix to nand write to give the uboot
the power to directly burn the yaffs image to nand.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
 common/cmd_nand.c            |   12 ++++++++--
 drivers/mtd/nand/nand_util.c |   43 +++++++++++++++++++++++++++++++++++------
 include/nand.h               |    2 +-
 3 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index c547a68..e113971 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -574,7 +574,13 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 							 (u_char *)addr);
 			else
 				ret = nand_write_skip_bad(nand, off, &rwsize,
-							  (u_char *)addr);
+							  (u_char *)addr, 0);
+		} else if (!strcmp(s, ".yaffs")) {
+			if (read) {
+				printf("Unknown nand command suffix '%s'.\n", s);
+				return 1;
+			}
+			ret = nand_write_skip_bad(nand, off, &size, (u_char *)addr, 1);
 		} else if (!strcmp(s, ".oob")) {
 			/* out-of-band data */
 			mtd_oob_ops_t ops = {
@@ -677,7 +683,7 @@ U_BOOT_CMD(
 	"info - show available NAND devices\n"
 	"nand device [dev] - show or set current device\n"
 	"nand read - addr off|partition size\n"
-	"nand write - addr off|partition size\n"
+	"nand write[.yaffs] - addr off|partition size\n"
 	"    read/write 'size' bytes starting at offset 'off'\n"
 	"    to/from memory address 'addr', skipping bad blocks.\n"
 	"nand erase[.spread] [clean] [off [size]] - erase 'size' bytes "
@@ -720,7 +726,7 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
 
 	s = strchr(cmd, '.');
 	if (s != NULL &&
-	    (strcmp(s, ".jffs2") && strcmp(s, ".e") && strcmp(s, ".i"))) {
+	    (strcmp(s, ".jffs2") && strcmp(s, ".e") && strcmp(s, ".i") && strcmp(s, ".yaffs"))) {
 		printf("Unknown nand load suffix '%s'\n", s);
 		show_boot_progress(-53);
 		return 1;
diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
index 22c7411..e7a314a 100644
--- a/drivers/mtd/nand/nand_util.c
+++ b/drivers/mtd/nand/nand_util.c
@@ -451,12 +451,24 @@ static int check_skip_len(nand_info_t *nand, loff_t offset, size_t length)
  * @return		0 in case of success
  */
 int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
-			u_char *buffer)
+			u_char *buffer, int withoob)
 {
-	int rval;
+	int rval = 0, blocksize, pages, page;
 	size_t left_to_write = *length;
 	u_char *p_buffer = buffer;
 	int need_skip;
+	struct mtd_oob_ops ops;
+
+	if (withoob) {
+		pages = nand->erasesize / nand->writesize;
+		blocksize = (pages * nand->oobsize) + nand->erasesize;
+		if (*length % (nand->writesize + nand->oobsize)) {
+			printf ("Attempt to write non yaffs page aligned data\n");
+			return -EINVAL;
+		}
+	}
+	else
+		blocksize = nand->erasesize;
 
 	/*
 	 * nand_write() handles unaligned, partial page writes.
@@ -506,12 +518,26 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
 			continue;
 		}
 
-		if (left_to_write < (nand->erasesize - block_offset))
+		if (left_to_write < (blocksize - block_offset))
 			write_size = left_to_write;
 		else
-			write_size = nand->erasesize - block_offset;
-
-		rval = nand_write (nand, offset, &write_size, p_buffer);
+			write_size = blocksize - block_offset;
+
+		if (withoob) {
+			ops.len = nand->writesize;
+			ops.ooblen = nand->oobsize;
+			ops.mode = MTD_OOB_AUTO;
+			ops.ooboffs = 0;
+			pages = write_size / (nand->writesize + nand->oobsize);
+			for (page = 0; page < pages && !rval; page ++) {
+				ops.datbuf = (page * (nand->writesize + nand->oobsize))
+					     + p_buffer;
+				ops.oobbuf = ops.datbuf + nand->writesize;
+				rval = nand->write_oob(nand, offset + page *nand->writesize, &ops);
+			}
+		}
+		else
+			rval = nand_write (nand, offset, &write_size, p_buffer);
 		if (rval != 0) {
 			printf ("NAND write to offset %llx failed %d\n",
 				offset, rval);
@@ -520,8 +546,11 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
 		}
 
 		left_to_write -= write_size;
-		offset        += write_size;
 		p_buffer      += write_size;
+		if (withoob)
+			offset += (write_size + nand->erasesize - blocksize);
+		else
+			offset += write_size;
 	}
 
 	return 0;
diff --git a/include/nand.h b/include/nand.h
index a452411..7459bd0 100644
--- a/include/nand.h
+++ b/include/nand.h
@@ -115,7 +115,7 @@ typedef struct nand_erase_options nand_erase_options_t;
 int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
 		       u_char *buffer);
 int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
-			u_char *buffer);
+			u_char *buffer, int withoob);
 int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts);
 
 #define NAND_LOCK_STATUS_TIGHT	0x01
-- 
1.7.0.4

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

* [U-Boot] [PATCH] NAND: add the ability to directly write yaffs image
  2011-01-03 13:09 [U-Boot] [PATCH] NAND: add the ability to directly write yaffs image Lei Wen
@ 2011-01-05 21:29 ` Scott Wood
  2011-01-06  3:11   ` [U-Boot] [U-BOOT] [PATCH V2] " Lei Wen
  0 siblings, 1 reply; 4+ messages in thread
From: Scott Wood @ 2011-01-05 21:29 UTC (permalink / raw)
  To: u-boot

On Mon, Jan 03, 2011 at 09:09:20PM +0800, Lei Wen wrote:
> This patch add addition suffix to nand write to give the uboot
> the power to directly burn the yaffs image to nand.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
>  common/cmd_nand.c            |   12 ++++++++--
>  drivers/mtd/nand/nand_util.c |   43 +++++++++++++++++++++++++++++++++++------
>  include/nand.h               |    2 +-
>  3 files changed, 46 insertions(+), 11 deletions(-)
> 
> diff --git a/common/cmd_nand.c b/common/cmd_nand.c
> index c547a68..e113971 100644
> --- a/common/cmd_nand.c
> +++ b/common/cmd_nand.c
> @@ -574,7 +574,13 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
>  							 (u_char *)addr);
>  			else
>  				ret = nand_write_skip_bad(nand, off, &rwsize,
> -							  (u_char *)addr);
> +							  (u_char *)addr, 0);
> +		} else if (!strcmp(s, ".yaffs")) {
> +			if (read) {
> +				printf("Unknown nand command suffix '%s'.\n", s);
> +				return 1;
> +			}
> +			ret = nand_write_skip_bad(nand, off, &size, (u_char *)addr, 1);

cmd_nand.c:583:4: warning: passing argument 3 of 'nand_write_skip_bad' from incompatible pointer type
include/nand.h:117:5: note: expected 'size_t *' but argument is of type 'loff_t *'

Use rwsize.

> diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
> index 22c7411..e7a314a 100644
> --- a/drivers/mtd/nand/nand_util.c
> +++ b/drivers/mtd/nand/nand_util.c
> @@ -451,12 +451,24 @@ static int check_skip_len(nand_info_t *nand, loff_t offset, size_t length)
>   * @return		0 in case of success
>   */
>  int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
> -			u_char *buffer)
> +			u_char *buffer, int withoob)
>  {
> -	int rval;
> +	int rval = 0, blocksize, pages, page;
>  	size_t left_to_write = *length;
>  	u_char *p_buffer = buffer;
>  	int need_skip;
> +	struct mtd_oob_ops ops;
> +
> +	if (withoob) {
> +		pages = nand->erasesize / nand->writesize;
> +		blocksize = (pages * nand->oobsize) + nand->erasesize;
> +		if (*length % (nand->writesize + nand->oobsize)) {
> +			printf ("Attempt to write non yaffs page aligned data\n");
> +			return -EINVAL;
> +		}
> +	}
> +	else
> +		blocksize = nand->erasesize;

if (withoob) {
	...
} else {
	blocksize = nand->erasesize;
}

For the error message, how about, "Attempt to write incomplete page
in yaffs mode"?

>  	/*
>  	 * nand_write() handles unaligned, partial page writes.
> @@ -506,12 +518,26 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
>  			continue;
>  		}
>  
> -		if (left_to_write < (nand->erasesize - block_offset))
> +		if (left_to_write < (blocksize - block_offset))
>  			write_size = left_to_write;
>  		else
> -			write_size = nand->erasesize - block_offset;
> -
> -		rval = nand_write (nand, offset, &write_size, p_buffer);
> +			write_size = blocksize - block_offset;
> +
> +		if (withoob) {
> +			ops.len = nand->writesize;
> +			ops.ooblen = nand->oobsize;
> +			ops.mode = MTD_OOB_AUTO;
> +			ops.ooboffs = 0;
> +			pages = write_size / (nand->writesize + nand->oobsize);
> +			for (page = 0; page < pages && !rval; page ++) {
> +				ops.datbuf = (page * (nand->writesize + nand->oobsize))
> +					     + p_buffer;
> +				ops.oobbuf = ops.datbuf + nand->writesize;
> +				rval = nand->write_oob(nand, offset + page *nand->writesize, &ops);

This looks like you're dereferencing a pointer, rather than multiplying page
with nand->writesize.  Also, line length.

How about something like this (untested), IMHO a little clearer, and 60
bytes smaller (out of 481 bytes added by the patch as written) on powerpc
with GCC 4.5:

	while (left_to_write > 0) {
		...

		if (withoob) {
			size_t pagesize = nand->writesize;
			size_t pagesize_oob = pagesize + nand->oobsize;

			ops.len = pagesize;
			ops.ooblen = nand->oobsize;
			ops.mode = MTD_OOB_AUTO;
			ops.ooboffs = 0;

			pages = write_size / pagesize_oob;
			for (page = 0; page < pages; page++) {
				ops.databuf = p_buffer;
				ops.oobbuf = ops.databuf + pagesize;

				rval = nand->write_oob(nand, offset, &ops);
				if (!rval)
					break;

				offset += pagesize;
				p_buffer += pagesize_oob;
			}
		} else {
			rval = nand_write(nand, offset, &write_size, p_buffer);
			offset += write_size;
			p_buffer += write_size;
		}

		if (rval != 0) {
			...
		}

		left_to_write -= write_size;
	}

Should this be conditional on CONFIG_YAFFS2, or a new CONFIG_CMD_NAND_YAFFS? 
The NAND code is too big already...

> +			}
> +		}
> +		else
> +			rval = nand_write (nand, offset, &write_size, p_buffer);

	}
} else {
	rval = ...;
}

-Scott

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

* [U-Boot] [U-BOOT] [PATCH V2] NAND: add the ability to directly write yaffs image
  2011-01-05 21:29 ` Scott Wood
@ 2011-01-06  3:11   ` Lei Wen
  2011-01-10 23:18     ` Scott Wood
  0 siblings, 1 reply; 4+ messages in thread
From: Lei Wen @ 2011-01-06  3:11 UTC (permalink / raw)
  To: u-boot

This patch add addition suffix to nand write to give the uboot
the power to directly burn the yaffs image to nand.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
V2: fix compile warning, and add CONFIG_CMD_NAND_YAFFS to reduce code
        when not use this function.

 common/cmd_nand.c            |   15 +++++++++-
 drivers/mtd/nand/nand_util.c |   63 ++++++++++++++++++++++++++++++++++++-----
 include/nand.h               |    2 +-
 3 files changed, 70 insertions(+), 10 deletions(-)

diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index c547a68..4b7e144 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -574,7 +574,15 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 							 (u_char *)addr);
 			else
 				ret = nand_write_skip_bad(nand, off, &rwsize,
-							  (u_char *)addr);
+							  (u_char *)addr, 0);
+#ifdef CONFIG_CMD_NAND_YAFFS
+		} else if (!strcmp(s, ".yaffs")) {
+			if (read) {
+				printf("Unknown nand command suffix '%s'.\n", s);
+				return 1;
+			}
+			ret = nand_write_skip_bad(nand, off, &rwsize, (u_char *)addr, 1);
+#endif
 		} else if (!strcmp(s, ".oob")) {
 			/* out-of-band data */
 			mtd_oob_ops_t ops = {
@@ -680,6 +688,11 @@ U_BOOT_CMD(
 	"nand write - addr off|partition size\n"
 	"    read/write 'size' bytes starting at offset 'off'\n"
 	"    to/from memory address 'addr', skipping bad blocks.\n"
+#ifdef CONFIG_CMD_NAND_YAFFS
+	"nand write.yaffs - addr off|partition size\n"
+	"    write 'size' bytes starting at offset 'off' with yaffs format\n"
+	"    from memory address 'addr', skipping bad blocks.\n"
+#endif
 	"nand erase[.spread] [clean] [off [size]] - erase 'size' bytes "
 	"from offset 'off'\n"
 	"    With '.spread', erase enough for given file size, otherwise,\n"
diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
index 22c7411..8b4f738 100644
--- a/drivers/mtd/nand/nand_util.c
+++ b/drivers/mtd/nand/nand_util.c
@@ -447,17 +447,34 @@ static int check_skip_len(nand_info_t *nand, loff_t offset, size_t length)
  * @param nand  	NAND device
  * @param offset	offset in flash
  * @param length	buffer length
- * @param buf           buffer to read from
+ * @param buffer        buffer to read from
+ * @param withoob	whether write with yaffs format
  * @return		0 in case of success
  */
 int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
-			u_char *buffer)
+			u_char *buffer, int withoob)
 {
-	int rval;
+	int rval = 0, blocksize;
 	size_t left_to_write = *length;
 	u_char *p_buffer = buffer;
 	int need_skip;
 
+#ifdef CONFIG_CMD_NAND_YAFFS
+	if (withoob) {
+		int pages;
+		pages = nand->erasesize / nand->writesize;
+		blocksize = (pages * nand->oobsize) + nand->erasesize;
+		if (*length % (nand->writesize + nand->oobsize)) {
+			printf ("Attempt to write incomplete page"
+				" in yaffs mode\n");
+			return -EINVAL;
+		}
+	} else
+#endif
+	{
+		blocksize = nand->erasesize;
+	}
+
 	/*
 	 * nand_write() handles unaligned, partial page writes.
 	 *
@@ -506,12 +523,44 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
 			continue;
 		}
 
-		if (left_to_write < (nand->erasesize - block_offset))
+		if (left_to_write < (blocksize - block_offset))
 			write_size = left_to_write;
 		else
-			write_size = nand->erasesize - block_offset;
+			write_size = blocksize - block_offset;
+
+#ifdef CONFIG_CMD_NAND_YAFFS
+		if (withoob) {
+			int page, pages;
+			size_t pagesize = nand->writesize;
+			size_t pagesize_oob = pagesize + nand->oobsize;
+			struct mtd_oob_ops ops;
+
+			ops.len = pagesize;
+			ops.ooblen = nand->oobsize;
+			ops.mode = MTD_OOB_AUTO;
+			ops.ooboffs = 0;
+
+			pages = write_size / pagesize_oob;
+			for (page = 0; page < pages; page++) {
+				ops.datbuf = p_buffer;
+				ops.oobbuf = ops.datbuf + pagesize;
+
+				rval = nand->write_oob(nand, offset, &ops);
+				if (!rval)
+					break;
+
+				offset += pagesize;
+				p_buffer += pagesize_oob;
+			}
+		}
+		else
+#endif
+		{
+			rval = nand_write (nand, offset, &write_size, p_buffer);
+			offset += write_size;
+			p_buffer += write_size;
+		}
 
-		rval = nand_write (nand, offset, &write_size, p_buffer);
 		if (rval != 0) {
 			printf ("NAND write to offset %llx failed %d\n",
 				offset, rval);
@@ -520,8 +569,6 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
 		}
 
 		left_to_write -= write_size;
-		offset        += write_size;
-		p_buffer      += write_size;
 	}
 
 	return 0;
diff --git a/include/nand.h b/include/nand.h
index a452411..7459bd0 100644
--- a/include/nand.h
+++ b/include/nand.h
@@ -115,7 +115,7 @@ typedef struct nand_erase_options nand_erase_options_t;
 int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
 		       u_char *buffer);
 int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
-			u_char *buffer);
+			u_char *buffer, int withoob);
 int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts);
 
 #define NAND_LOCK_STATUS_TIGHT	0x01
-- 
1.7.0.4

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

* [U-Boot] [U-BOOT] [PATCH V2] NAND: add the ability to directly write yaffs image
  2011-01-06  3:11   ` [U-Boot] [U-BOOT] [PATCH V2] " Lei Wen
@ 2011-01-10 23:18     ` Scott Wood
  0 siblings, 0 replies; 4+ messages in thread
From: Scott Wood @ 2011-01-10 23:18 UTC (permalink / raw)
  To: u-boot

On Thu, Jan 06, 2011 at 11:11:58AM +0800, Lei Wen wrote:
> This patch add addition suffix to nand write to give the uboot
> the power to directly burn the yaffs image to nand.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> V2: fix compile warning, and add CONFIG_CMD_NAND_YAFFS to reduce code
>         when not use this function.
> 
>  common/cmd_nand.c            |   15 +++++++++-
>  drivers/mtd/nand/nand_util.c |   63 ++++++++++++++++++++++++++++++++++++-----
>  include/nand.h               |    2 +-
>  3 files changed, 70 insertions(+), 10 deletions(-)

Applied to u-boot-nand-flash.

-Scott

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

end of thread, other threads:[~2011-01-10 23:18 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-03 13:09 [U-Boot] [PATCH] NAND: add the ability to directly write yaffs image Lei Wen
2011-01-05 21:29 ` Scott Wood
2011-01-06  3:11   ` [U-Boot] [U-BOOT] [PATCH V2] " Lei Wen
2011-01-10 23:18     ` Scott Wood

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.