nand: extend .raw accesses to work on multiple pages
PATCH 1/2 nand: extend .raw accesses to work on multiple pages
A use for this is to read, modify, erase, and write an entire block as a single unit, as a replacement for the biterr command. This way gives more flexibility in that you can also test multiple bit errors, errors in the ECC, etc.
--- common/cmd_nand.c | 95 +++++++++++++++++++++++++++++++++++++++------------- doc/README.nand | 16 ++++---- 2 files changed, 79 insertions(+), 32 deletions(-)
common/cmd_nand.c +71 -24
@@ -11,7 +11,7 @@* Added 16-bit nand support * (C) 2004 Texas Instruments * -* Copyright 2010 Freescale Semiconductor +* Copyright 2010, 2012 Freescale Semiconductor * The portions of this file whose copyright is held by Freescale and which * are not considered a derived work of GPL v2-only code may be distributed * and/or modified under the terms of the GNU General Public License as
@@ -390,6 +390,41 @@ static void nand_print_and_set_info(int idx)setenv ("nand_erasesize" , buf); } +static int raw_access (nand_info_t *nand,ulong addr,loff_t off,ulong count, +int read) +{ +int ret =0 ; +size_t rwsize; + +while (count--) { +/* Raw access */ +mtd_oob_ops_t ops = { + .datbuf = (u8 *)addr, + .oobbuf = ((u8 *)addr) + nand->writesize, + .len = nand->writesize, + .ooblen = nand->oobsize, + .mode =MTD_OOB_RAW + }; + + rwsize = nand->writesize + nand->oobsize; +if (read) + ret = nand->read_oob (nand, off, &ops); +else + ret = nand->write_oob (nand, off, &ops); + +if (ret) { +printf ("%s: error at offset %llx, ret %d\n" , + __func__, (long long )off, ret); +break ; + } + + addr += nand->writesize + nand->oobsize; + off += nand->writesize; + } + +return ret; +} +int do_nand (cmd_tbl_t * cmdtp,int flag,int argc,char *const argv[]) {int i, ret =0 ;
@@ -568,7 +603,9 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])if (strncmp (cmd,"read" ,4 ) ==0 ||strncmp (cmd,"write" ,5 ) ==0 ) {size_t rwsize; +ulong pagecount =1 ;int read; +int raw;if (argc <4 ) goto usage;
@@ -577,13 +614,36 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) read =strncmp (cmd,"read" ,4 ) ==0 ;/* 1 = read, 0 = write */ printf ("\nNAND %s: " , read ?"read" :"write" ); -if (arg_off_size (argc -3 , argv +3 , &dev, &off, &size) !=0 ) -return 1 ; nand = &nand_info[dev]; - rwsize = size; s =strchr (cmd,'.' ); + +if (!strcmp (s,".raw" )) { + raw =1 ; + +if (arg_off (argv[3 ], &dev, &off, &size)) +return 1 ; + +if (argc >4 && !str2long (argv[4 ], &pagecount)) { +printf ("'%s' is not a number\n" , argv[4 ]); +return 1 ; + } + +if (pagecount * nand->writesize > size) { +puts ("Size exceeds partition or device limit\n" ); +return -1 ; + } + + rwsize = pagecount * (nand->writesize + nand->oobsize); + }else { +if (arg_off_size (argc -3 , argv +3 , &dev, + &off, &size) !=0 ) +return 1 ; + + rwsize = size; + } +if (!s || !strcmp (s,".jffs2" ) || !strcmp (s,".e" ) || !strcmp (s,".i" )) {if (read)
@@ -609,7 +669,8 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) return 1; } ret =nand_write_skip_bad (nand, off, &rwsize, - (u_char *)addr,WITH_YAFFS_OOB ); + (u_char *)addr, +WITH_INLINE_OOB );#endif }else if (!strcmp (s,".oob" )) {/* out-of-band data */
@@ -623,22 +684,8 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) ret = nand->read_oob (nand, off, &ops); else ret = nand->write_oob (nand, off, &ops); - }else if (!strcmp (s,".raw" )) { -/* Raw access */ -mtd_oob_ops_t ops = { - .datbuf = (u8 *)addr, - .oobbuf = ((u8 *)addr) + nand->writesize, - .len = nand->writesize, - .ooblen = nand->oobsize, - .mode =MTD_OOB_RAW - }; - - rwsize = nand->writesize + nand->oobsize; - -if (read) - ret = nand->read_oob (nand, off, &ops); -else - ret = nand->write_oob (nand, off, &ops); + }else if (raw) { + ret =raw_access (nand, addr, off, pagecount, read); }else {printf ("Unknown nand command suffix '%s'.\n" , s);return 1 ;
@@ -732,9 +779,9 @@ 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" -"nand read.raw - addr off|partition\n" -"nand write.raw - addr off|partition\n" -" Use read.raw/write.raw to avoid ECC and access the page as-is.\n" +"nand read.raw - addr off|partition [count]\n" +"nand write.raw - addr off|partition [count]\n" +" Use read.raw/write.raw to avoid ECC and access the flash as-is.\n" #ifdef CONFIG_CMD_NAND_TRIMFFS"nand write.trimffs - addr off|partition size\n" " write 'size' bytes starting at offset 'off' from memory address\n"
doc/README.nand +8 -8
@@ -94,14 +94,14 @@ Commands: of data for one 512-byte page or 2 256-byte pages. There is no check for bad blocks. - nand read.raw addr ofs|partition - Read page from `ofs' in NAND flash to `addr'. This reads the raw page, - so ECC is avoided and the OOB area is read as well. - - nand write.raw addr ofs|partition - Write page from `addr' to `ofs' in NAND flash. This writes the raw page, - so ECC is avoided and the OOB area is written as well, making the whole - page written as-is. + nand read.raw addr ofs|partition [count] + nand write.raw addr ofs|partition [count] + Read or write one or more pages at "ofs" in NAND flash, from or to + "addr" in memory. This is a raw access, so ECC is avoided and the + OOB area is transferred as well. If count is absent, it is assumed + to be one page. As with .yaffs2 accesses, the data is formatted as + a packed sequence of "data, oob, data, oob, ..." -- no alignment of + individual pages is maintained. Configuration Options:
Signature · 1 line
1.7.7.rc3.4.g8d714
PATCH 1/2 nand: extend .raw accesses to work on multiple pages
Quoted 10 lines · Scott Wood
A use for this is to read, modify, erase, and write an entire block as a single unit, as a replacement for the biterr command. This way gives more flexibility in that you can also test multiple bit errors, errors in the ECC, etc.
Signed-off-by Scott Wood <[email protected]>--- common/cmd_nand.c | 95 +++++++++++++++++++++++++++++++++++++++------------- doc/README.nand | 16 ++++---- 2 files changed, 79 insertions(+), 32 deletions(-)
Applied to u-boot-nand-flash.
-Scott
PATCH 2/2 nand: remote biterr command stub
In reply to Scott WoodIt can be scripted instead with .raw accesses.
--- common/cmd_nand.c | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-)
common/cmd_nand.c +0 -6
@@ -723,11 +723,6 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])return ret; } -if (strcmp (cmd,"biterr" ) ==0 ) { -/* todo */ -return 1 ; - } -#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK if (strcmp (cmd,"lock" ) ==0 ) {int tight =0 ;
@@ -804,7 +799,6 @@ U_BOOT_CMD("nand scrub [-y] off size | scrub.part partition | scrub.chip\n" " really clean NAND erasing bad blocks (UNSAFE)\n" "nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n" -"nand biterr off - make a bit error at offset (UNSAFE)" #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK"\n" "nand lock [tight] [status]\n"
Signature · 1 line
1.7.7.rc3.4.g8d714
PATCH 2/2 nand: remote biterr command stub
Quoted 1 line · On Thursday 29 March 2012 00:27:43 Scott Wood wrote:
It can be scripted instead with .raw accesses.
Typo in the subject: s/remote/remove
Thanks,
Stefan
PATCH 2/2 nand: remote biterr command stub
In reply to Scott WoodDear Scott Wood,
Quoted 3 lines · In message <[email protected]> you wrote:
It can be scripted instead with .raw accesses.
Signed-off-by Scott Wood <[email protected]>
Can you please add an example how to do that to the commit message? Thanks.
Best regards,
Wolfgang Denk
Signature · 6 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de You Earth people glorified organized violence for forty centuries. But you imprison those who employ it privately. -- Spock, "Dagger of the Mind", stardate 2715.1