int i;
u_char *datbuf, *oobbuf, *p;
static loff_t last;
+ int ret = 0;
if (repeat)
off = last + nand->writesize;
last = off;
datbuf = memalign(ARCH_DMA_MINALIGN, nand->writesize);
- oobbuf = memalign(ARCH_DMA_MINALIGN, nand->oobsize);
- if (!datbuf || !oobbuf) {
+ if (!datbuf) {
puts("No memory for page buffer\n");
return 1;
}
+
+ oobbuf = memalign(ARCH_DMA_MINALIGN, nand->oobsize);
+ if (!oobbuf) {
+ puts("No memory for page buffer\n");
+ ret = 1;
+ goto free_dat;
+ }
off &= ~(nand->writesize - 1);
loff_t addr = (loff_t) off;
struct mtd_oob_ops ops;
i = mtd_read_oob(nand, addr, &ops);
if (i < 0) {
printf("Error (%d) reading page %08lx\n", i, off);
- free(datbuf);
- free(oobbuf);
- return 1;
+ ret = 1;
+ goto free_all;
}
printf("Page %08lx dump:\n", off);
- i = nand->writesize >> 4;
- p = datbuf;
- while (i--) {
- if (!only_oob)
+ if (!only_oob) {
+ i = nand->writesize >> 4;
+ p = datbuf;
+
+ while (i--) {
printf("\t%02x %02x %02x %02x %02x %02x %02x %02x"
" %02x %02x %02x %02x %02x %02x %02x %02x\n",
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
p[8], p[9], p[10], p[11], p[12], p[13], p[14],
p[15]);
- p += 16;
+ p += 16;
+ }
}
+
puts("OOB:\n");
i = nand->oobsize >> 3;
p = oobbuf;
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
p += 8;
}
- free(datbuf);
+
+free_all:
free(oobbuf);
+free_dat:
+ free(datbuf);
- return 0;
+ return ret;
}
/* ------------------------------------------------------------------------- */
.mode = MTD_OPS_RAW
};
- if (read)
+ if (read) {
ret = mtd_read_oob(nand, off, &ops);
- else
+ } else {
ret = mtd_write_oob(nand, off, &ops);
+ if (!ret)
+ ret = nand_verify_page_oob(nand, &ops, off);
+ }
if (ret) {
printf("%s: error at offset %llx, ret %d\n",
}
/* Adjust a chip/partition size down for bad blocks so we don't
- * read/write/erase past the end of a chip/partition by accident.
+ * read/write past the end of a chip/partition by accident.
*/
static void adjust_size_for_badblocks(loff_t *size, loff_t offset, int dev)
{
int scrub = !strncmp(cmd, "scrub", 5);
int spread = 0;
int args = 2;
- int adjust_size = 0;
const char *scrub_warn =
"Warning: "
"scrub option will erase all factory set bad blocks!\n"
spread = 1;
} else if (!strcmp(&cmd[5], ".part")) {
args = 1;
- adjust_size = 1;
} else if (!strcmp(&cmd[5], ".chip")) {
args = 0;
- adjust_size = 1;
} else {
goto usage;
}
&maxsize) != 0)
return 1;
- /* size is unspecified */
- if (adjust_size && !scrub)
- adjust_size_for_badblocks(&size, off, dev);
-
nand = &nand_info[dev];
memset(&opts, 0, sizeof(opts));
opts.spread = spread;
if (scrub) {
- if (!scrub_yes)
- puts(scrub_warn);
-
- if (scrub_yes)
+ if (scrub_yes) {
opts.scrub = 1;
- else if (getc() == 'y') {
- puts("y");
- if (getc() == '\r')
+ } else {
+ puts(scrub_warn);
+ if (confirm_yesno()) {
opts.scrub = 1;
- else {
+ } else {
puts("scrub aborted\n");
- return -1;
+ return 1;
}
- } else {
- puts("scrub aborted\n");
- return -1;
}
}
ret = nand_erase_opts(nand, &opts);
read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
printf("\nNAND %s: ", read ? "read" : "write");
- nand = &nand_info[dev];
-
s = strchr(cmd, '.');
if (s && !strcmp(s, ".raw")) {
if (arg_off(argv[3], &dev, &off, &size, &maxsize))
return 1;
+ nand = &nand_info[dev];
+
if (argc > 4 && !str2long(argv[4], &pagecount)) {
printf("'%s' is not a number\n", argv[4]);
return 1;
rwsize = size;
}
+ nand = &nand_info[dev];
+
if (!s || !strcmp(s, ".jffs2") ||
!strcmp(s, ".e") || !strcmp(s, ".i")) {
if (read)
else
ret = nand_write_skip_bad(nand, off, &rwsize,
NULL, maxsize,
- (u_char *)addr, 0);
+ (u_char *)addr,
+ WITH_WR_VERIFY);
#ifdef CONFIG_CMD_NAND_TRIMFFS
} else if (!strcmp(s, ".trimffs")) {
if (read) {
}
ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
maxsize, (u_char *)addr,
- WITH_DROP_FFS);
-#endif
-#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, NULL,
- maxsize, (u_char *)addr,
- WITH_YAFFS_OOB);
+ WITH_DROP_FFS | WITH_WR_VERIFY);
#endif
} else if (!strcmp(s, ".oob")) {
/* out-of-band data */
" 'addr', skipping bad blocks and dropping any pages at the end\n"
" of eraseblocks that contain only 0xFF\n"
#endif
-#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"
int r;
char *s;
size_t cnt;
+#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
image_header_t *hdr;
+#endif
#if defined(CONFIG_FIT)
const void *fit_hdr = NULL;
#endif
bootstage_mark(BOOTSTAGE_ID_NAND_HDR_READ);
switch (genimg_get_format ((void *)addr)) {
+#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
case IMAGE_FORMAT_LEGACY:
hdr = (image_header_t *)addr;
cnt = image_get_image_size (hdr);
break;
+#endif
#if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT:
fit_hdr = (const void *)addr;