* [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.