diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index b011b5e..2760874 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -351,6 +351,23 @@ #endif
opts.quiet = quiet;
ret = nand_write_opts(nand, &opts);
}
+#ifdef CFG_NAND_YAFFS_WRITE
+ } else if (!read && s != NULL &&
+ (!strcmp(s, ".yaffs") || !strcmp(s, ".yaffs1"))) {
+ nand_write_options_t opts;
+ memset(&opts, 0, sizeof(opts));
+ opts.buffer = (u_char*) addr;
+ opts.length = size;
+ opts.offset = off;
+ opts.pad = 0;
+ opts.blockalign = 1;
+ opts.quiet = quiet;
+ opts.writeoob = 1;
+ opts.autoplace = 1;
+ if (s[6] == '1')
+ opts.forceyaffs = 1;
+ ret = nand_write_opts(nand, &opts);
+#endif
} else {
if (read)
ret = nand_read(nand, off, &size, (u_char *)addr);
@@ -462,6 +479,10 @@ U_BOOT_CMD(nand, 5, 1, do_nand,
"nand read[.jffs2] - addr off|partition size\n"
"nand write[.jffs2] - addr off|partiton size - read/write `size' bytes starting\n"
" at offset `off' to/from memory address `addr'\n"
+#ifdef CFG_NAND_YAFFS_WRITE
+ "nand write[.yaffs[1]] - addr off|partition size - write `size' byte yaffs image\n"
+ " starting at offset `off' from memory address `addr' (.yaffs1 for 512+16 NAND)\n"
+#endif
"nand erase [clean] [off size] - erase `size' bytes from\n"
" offset `off' (entire device if not specified)\n"
"nand bad - show bad blocks\n"
diff --git a/drivers/nand/nand_util.c b/drivers/nand/nand_util.c
index 10bf036..bea5c1e 100644
--- a/drivers/nand/nand_util.c
+++ b/drivers/nand/nand_util.c
@@ -343,6 +343,10 @@ int nand_write_opts(nand_info_t *meminfo
struct nand_oobinfo *oobsel =
opts->forcejffs2 ? &jffs2_oobinfo : &yaffs_oobinfo;
+#ifdef CFG_NAND_YAFFS1_NEW_OOB_LAYOUT
+ /* jffs2_oobinfo matches 2.6.18+ MTD nand_oob_16 ecclayout */
+ oobsel = &jffs2_oobinfo;
+#endif
if (meminfo->oobsize == 8) {
if (opts->forceyaffs) {
printf("YAFSS cannot operate on "
@@ -443,6 +447,28 @@ int nand_write_opts(nand_info_t *meminfo
memcpy(oob_buf, buffer, meminfo->oobsize);
buffer += meminfo->oobsize;
+ if (opts->forceyaffs) {
+#ifdef CFG_NAND_YAFFS1_NEW_OOB_LAYOUT
+ /* translate OOB for yaffs1 on Linux 2.6.18+ */
+ oob_buf[15] = oob_buf[12];
+ oob_buf[14] = oob_buf[11];
+ oob_buf[13] = (oob_buf[7] & 0x3f)
+ | (oob_buf[5] == 'Y' ? 0 : 0x80)
+ | (oob_buf[4] == 0 ? 0 : 0x40);
+ oob_buf[12] = oob_buf[6];
+ oob_buf[11] = oob_buf[3];
+ oob_buf[10] = oob_buf[2];
+ oob_buf[9] = oob_buf[1];
+ oob_buf[8] = oob_buf[0];
+ memset(oob_buf, 0xff, 8);
+#else
+ /* set the ECC bytes to 0xff so MTD will
+ calculate it */
+ int i;
+ for (i = 0; i < meminfo->oobinfo.eccbytes; i++)
+ oob_buf[meminfo->oobinfo.eccpos[i]] = 0xff;
+#endif
+ }
/* write OOB data first, as ecc will be placed
* in there*/
result = meminfo->write_oob(meminfo,
|