u8 *part_num, struct part_info **part);
#endif
-static int nand_dump(nand_info_t *nand, ulong off, int only_oob)
+static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat)
{
int i;
u_char *datbuf, *oobbuf, *p;
+ static loff_t last;
+
+ if (repeat)
+ off = last + nand->writesize;
+
+ last = off;
datbuf = malloc(nand->writesize + nand->oobsize);
oobbuf = malloc(nand->oobsize);
#endif
const char *quiet_str = getenv("quiet");
int dev = nand_curr_device;
+ int repeat = flag & CMD_FLAG_REPEAT;
/* at least two arguments please */
if (argc < 2)
cmd = argv[1];
+ /* Only "dump" is repeatable. */
+ if (repeat && strcmp(cmd, "dump"))
+ return 0;
+
if (strcmp(cmd, "info") == 0) {
putc('\n');
* 0 1 2 3 4
* nand erase [clean] [off size]
*/
- if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "scrub") == 0) {
+ if (strncmp(cmd, "erase", 5) == 0 || strncmp(cmd, "scrub", 5) == 0) {
nand_erase_options_t opts;
/* "clean" at index 2 means request to write cleanmarker */
int clean = argc > 2 && !strcmp("clean", argv[2]);
int o = clean ? 3 : 2;
- int scrub = !strcmp(cmd, "scrub");
+ int scrub = !strncmp(cmd, "scrub", 5);
+ int part = 0;
+ int chip = 0;
+ int spread = 0;
+ int args = 2;
+
+ if (cmd[5] != 0) {
+ if (!strcmp(&cmd[5], ".spread")) {
+ spread = 1;
+ } else if (!strcmp(&cmd[5], ".part")) {
+ part = 1;
+ args = 1;
+ } else if (!strcmp(&cmd[5], ".chip")) {
+ chip = 1;
+ args = 0;
+ } else {
+ goto usage;
+ }
+ }
- printf("\nNAND %s: ", scrub ? "scrub" : "erase");
+ /*
+ * Don't allow missing arguments to cause full chip/partition
+ * erases -- easy to do accidentally, e.g. with a misspelled
+ * variable name.
+ */
+ if (argc != o + args)
+ goto usage;
+
+ printf("\nNAND %s: ", cmd);
/* skip first two or three arguments, look for offset and size */
if (arg_off_size(argc - o, argv + o, &dev, &off, &size) != 0)
return 1;
opts.length = size;
opts.jffs2 = clean;
opts.quiet = quiet;
+ opts.spread = spread;
if (scrub) {
puts("Warning: "
if (argc < 3)
goto usage;
- s = strchr(cmd, '.');
off = (int)simple_strtoul(argv[2], NULL, 16);
-
- if (s != NULL && strcmp(s, ".oob") == 0)
- ret = nand_dump(nand, off, 1);
- else
- ret = nand_dump(nand, off, 0);
+ ret = nand_dump(nand, off, !strcmp(&cmd[4], ".oob"), repeat);
return ret == 0 ? 1 : 0;
-
}
if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
(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 = {
}
if (strcmp(cmd, "unlock") == 0) {
- if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0)
+ if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size) < 0)
return 1;
if (!nand_unlock(&nand_info[dev], off, size)) {
"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 erase [clean] [off size] - erase 'size' bytes from\n"
- " offset 'off' (entire device if not specified)\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"
+ " 'size' includes skipped bad blocks.\n"
+ "nand erase.part [clean] partition - erase entire mtd partition'\n"
+ "nand erase.chip [clean] - erase entire chip'\n"
"nand bad - show bad blocks\n"
"nand dump[.oob] off - dump page\n"
- "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n"
+ "nand scrub 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
/* Check if we should attempt an auto-start */
if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) {
char *local_args[2];
- extern int do_bootm(cmd_tbl_t *, int, int, char *[]);
local_args[0] = cmd;
local_args[1] = NULL;