Patchwork [U-Boot] onenand: add yaffs write command

login
register
mail settings
Submitter Lei Wen
Date Dec. 2, 2010, 3:17 p.m.
Message ID <1291303075-27638-1-git-send-email-leiwen@marvell.com>
Download mbox | patch
Permalink /patch/73980/
State Accepted
Commit 41c86240567307655ad837be17e6f5fa2a06452f
Delegated to: Scott Wood
Headers show

Comments

Lei Wen - Dec. 2, 2010, 3:17 p.m.
Yaffs image require to use the oob to store some info, so when we
burn the yaffs image, we need to also write the image's oob part
into flash.

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

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
 common/cmd_onenand.c |   41 ++++++++++++++++++++++++++++++++++++-----
 1 files changed, 36 insertions(+), 5 deletions(-)
Scott Wood - Dec. 10, 2010, 11:47 p.m.
On Thu, Dec 02, 2010 at 05:17:55AM -0000, Lei Wen wrote:
> Yaffs image require to use the oob to store some info, so when we
> burn the yaffs image, we need to also write the image's oob part
> into flash.
> 
> This patch add addition suffix to onenand write to give the uboot
> the power to directly burn the yaffs image to onenand.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> 
> ---
> common/cmd_onenand.c |   41 ++++++++++++++++++++++++++++++++++++-----
>  1 files changed, 36 insertions(+), 5 deletions(-)

Applied to u-boot-nand-flash next

-Scott

Patch

diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c
index 6d77495..6a22b8a 100644
--- a/common/cmd_onenand.c
+++ b/common/cmd_onenand.c
@@ -112,8 +112,32 @@  static int onenand_block_read(loff_t from, size_t len,
 	return 0;
 }
 
+static int onenand_write_oneblock_withoob(loff_t to, const u_char * buf,
+					  size_t *retlen)
+{
+	struct mtd_oob_ops ops = {
+		.len = mtd->writesize,
+		.ooblen = mtd->oobsize,
+		.mode = MTD_OOB_AUTO,
+	};
+	int page, ret = 0;
+	for (page = 0; page < (mtd->erasesize / mtd->writesize); page ++) {
+		ops.datbuf = (u_char *)buf;
+		buf += mtd->writesize;
+		ops.oobbuf = (u_char *)buf;
+		buf += mtd->oobsize;
+		ret = mtd->write_oob(mtd, to, &ops);
+		if (ret)
+			break;
+		to += mtd->writesize;
+	}
+
+	*retlen = (ret) ? 0 : mtd->erasesize;
+	return ret;
+}
+
 static int onenand_block_write(loff_t to, size_t len,
-			       size_t *retlen, const u_char * buf)
+			       size_t *retlen, const u_char * buf, int withoob)
 {
 	struct onenand_chip *this = mtd->priv;
 	int blocks = len >> this->erase_shift;
@@ -140,7 +164,10 @@  static int onenand_block_write(loff_t to, size_t len,
 			goto next;
 		}
 
-		ret = mtd->write(mtd, ofs, blocksize, &_retlen, buf);
+		if (!withoob)
+			ret = mtd->write(mtd, ofs, blocksize, &_retlen, buf);
+		else
+			ret = onenand_write_oneblock_withoob(ofs, buf, &_retlen);
 		if (ret) {
 			printk("Write failed 0x%x, %d", (u32)ofs, ret);
 			skip_ofs += blocksize;
@@ -386,19 +413,22 @@  static int do_onenand_write(cmd_tbl_t * cmdtp, int flag, int argc, char * const
 {
 	ulong addr, ofs;
 	size_t len;
-	int ret = 0;
+	int ret = 0, withoob = 0;
 	size_t retlen = 0;
 
 	if (argc < 3)
 		return cmd_usage(cmdtp);
 
+	if (strncmp(argv[0] + 6, "yaffs", 5) == 0)
+		withoob = 1;
+
 	addr = (ulong)simple_strtoul(argv[1], NULL, 16);
 
 	printf("\nOneNAND write: ");
 	if (arg_off_size(argc - 2, argv + 2, &ofs, &len) != 0)
 		return 1;
 
-	ret = onenand_block_write(ofs, len, &retlen, (u8 *)addr);
+	ret = onenand_block_write(ofs, len, &retlen, (u8 *)addr, withoob);
 
 	printf(" %d bytes written: %s\n", retlen, ret ? "ERROR" : "OK");
 
@@ -521,6 +551,7 @@  static cmd_tbl_t cmd_onenand_sub[] = {
 	U_BOOT_CMD_MKENT(bad, 1, 0, do_onenand_bad, "", ""),
 	U_BOOT_CMD_MKENT(read, 4, 0, do_onenand_read, "", ""),
 	U_BOOT_CMD_MKENT(write, 4, 0, do_onenand_write, "", ""),
+	U_BOOT_CMD_MKENT(write.yaffs, 4, 0, do_onenand_write, "", ""),
 	U_BOOT_CMD_MKENT(erase, 3, 0, do_onenand_erase, "", ""),
 	U_BOOT_CMD_MKENT(test, 3, 0, do_onenand_test, "", ""),
 	U_BOOT_CMD_MKENT(dump, 2, 0, do_onenand_dump, "", ""),
@@ -560,7 +591,7 @@  U_BOOT_CMD(
 	"info - show available OneNAND devices\n"
 	"onenand bad - show bad blocks\n"
 	"onenand read[.oob] addr off size\n"
-	"onenand write addr off size\n"
+	"onenand write[.yaffs] addr off size\n"
 	"    read/write 'size' bytes starting at offset 'off'\n"
 	"    to/from memory address 'addr', skipping bad blocks.\n"
 	"onenand erase [force] [off size] - erase 'size' bytes from\n"