[U-Boot] [PATCH] NAND: add the ability to directly write yaffs image
Lei Wen
leiwen at marvell.com
Mon Jan 3 14:09:20 CET 2011
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 at 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
More information about the U-Boot
mailing list