|
@@ -11,13 +11,14 @@
|
|
#include <common.h>
|
|
#include <common.h>
|
|
|
|
|
|
|
|
|
|
-#ifndef CFG_NAND_LEGACY
|
|
|
|
|
|
+#ifndef CONFIG_NAND_LEGACY
|
|
/*
|
|
/*
|
|
*
|
|
*
|
|
* New NAND support
|
|
* New NAND support
|
|
*
|
|
*
|
|
*/
|
|
*/
|
|
#include <common.h>
|
|
#include <common.h>
|
|
|
|
+#include <linux/mtd/mtd.h>
|
|
|
|
|
|
#if defined(CONFIG_CMD_NAND)
|
|
#if defined(CONFIG_CMD_NAND)
|
|
|
|
|
|
@@ -34,48 +35,58 @@
|
|
int mtdparts_init(void);
|
|
int mtdparts_init(void);
|
|
int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num);
|
|
int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num);
|
|
int find_dev_and_part(const char *id, struct mtd_device **dev,
|
|
int find_dev_and_part(const char *id, struct mtd_device **dev,
|
|
- u8 *part_num, struct part_info **part);
|
|
|
|
|
|
+ u8 *part_num, struct part_info **part);
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-static int nand_dump_oob(nand_info_t *nand, ulong off)
|
|
|
|
-{
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static int nand_dump(nand_info_t *nand, ulong off)
|
|
|
|
|
|
+static int nand_dump(nand_info_t *nand, ulong off, int only_oob)
|
|
{
|
|
{
|
|
int i;
|
|
int i;
|
|
- u_char *buf, *p;
|
|
|
|
|
|
+ u_char *datbuf, *oobbuf, *p;
|
|
|
|
|
|
- buf = malloc(nand->oobblock + nand->oobsize);
|
|
|
|
- if (!buf) {
|
|
|
|
|
|
+ datbuf = malloc(nand->writesize + nand->oobsize);
|
|
|
|
+ oobbuf = malloc(nand->oobsize);
|
|
|
|
+ if (!datbuf || !oobbuf) {
|
|
puts("No memory for page buffer\n");
|
|
puts("No memory for page buffer\n");
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
- off &= ~(nand->oobblock - 1);
|
|
|
|
- i = nand_read_raw(nand, buf, off, nand->oobblock, nand->oobsize);
|
|
|
|
|
|
+ off &= ~(nand->writesize - 1);
|
|
|
|
+ loff_t addr = (loff_t) off;
|
|
|
|
+ struct mtd_oob_ops ops;
|
|
|
|
+ memset(&ops, 0, sizeof(ops));
|
|
|
|
+ ops.datbuf = datbuf;
|
|
|
|
+ ops.oobbuf = oobbuf; /* must exist, but oob data will be appended to ops.datbuf */
|
|
|
|
+ ops.len = nand->writesize;
|
|
|
|
+ ops.ooblen = nand->oobsize;
|
|
|
|
+ ops.mode = MTD_OOB_RAW;
|
|
|
|
+ i = nand->read_oob(nand, addr, &ops);
|
|
if (i < 0) {
|
|
if (i < 0) {
|
|
printf("Error (%d) reading page %08lx\n", i, off);
|
|
printf("Error (%d) reading page %08lx\n", i, off);
|
|
- free(buf);
|
|
|
|
|
|
+ free(datbuf);
|
|
|
|
+ free(oobbuf);
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
printf("Page %08lx dump:\n", off);
|
|
printf("Page %08lx dump:\n", off);
|
|
- i = nand->oobblock >> 4; p = buf;
|
|
|
|
|
|
+ i = nand->writesize >> 4;
|
|
|
|
+ p = datbuf;
|
|
|
|
+
|
|
while (i--) {
|
|
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]);
|
|
|
|
|
|
+ if (!only_oob)
|
|
|
|
+ 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");
|
|
puts("OOB:\n");
|
|
i = nand->oobsize >> 3;
|
|
i = nand->oobsize >> 3;
|
|
while (i--) {
|
|
while (i--) {
|
|
- printf( "\t%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]);
|
|
|
|
|
|
+ printf("\t%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 += 8;
|
|
}
|
|
}
|
|
- free(buf);
|
|
|
|
|
|
+ free(datbuf);
|
|
|
|
+ free(oobbuf);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -155,7 +166,7 @@ out:
|
|
|
|
|
|
int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
{
|
|
{
|
|
- int i, dev, ret;
|
|
|
|
|
|
+ int i, dev, ret = 0;
|
|
ulong addr, off;
|
|
ulong addr, off;
|
|
size_t size;
|
|
size_t size;
|
|
char *cmd, *s;
|
|
char *cmd, *s;
|
|
@@ -182,8 +193,8 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
|
|
for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
|
|
if (nand_info[i].name)
|
|
if (nand_info[i].name)
|
|
printf("Device %d: %s, sector size %u KiB\n",
|
|
printf("Device %d: %s, sector size %u KiB\n",
|
|
- i, nand_info[i].name,
|
|
|
|
- nand_info[i].erasesize >> 10);
|
|
|
|
|
|
+ i, nand_info[i].name,
|
|
|
|
+ nand_info[i].erasesize >> 10);
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -196,7 +207,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
puts("\nno devices available\n");
|
|
puts("\nno devices available\n");
|
|
else
|
|
else
|
|
printf("\nDevice %d: %s\n", nand_curr_device,
|
|
printf("\nDevice %d: %s\n", nand_curr_device,
|
|
- nand_info[nand_curr_device].name);
|
|
|
|
|
|
+ nand_info[nand_curr_device].name);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
dev = (int)simple_strtoul(argv[2], NULL, 10);
|
|
dev = (int)simple_strtoul(argv[2], NULL, 10);
|
|
@@ -299,15 +310,14 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
off = (int)simple_strtoul(argv[2], NULL, 16);
|
|
off = (int)simple_strtoul(argv[2], NULL, 16);
|
|
|
|
|
|
if (s != NULL && strcmp(s, ".oob") == 0)
|
|
if (s != NULL && strcmp(s, ".oob") == 0)
|
|
- ret = nand_dump_oob(nand, off);
|
|
|
|
|
|
+ ret = nand_dump(nand, off, 1);
|
|
else
|
|
else
|
|
- ret = nand_dump(nand, off);
|
|
|
|
|
|
+ ret = nand_dump(nand, off, 0);
|
|
|
|
|
|
return ret == 0 ? 1 : 0;
|
|
return ret == 0 ? 1 : 0;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- /* read write */
|
|
|
|
if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
|
|
if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
|
|
int read;
|
|
int read;
|
|
|
|
|
|
@@ -322,43 +332,29 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
return 1;
|
|
return 1;
|
|
|
|
|
|
s = strchr(cmd, '.');
|
|
s = strchr(cmd, '.');
|
|
- if (s != NULL &&
|
|
|
|
- (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) {
|
|
|
|
- if (read) {
|
|
|
|
- /* read */
|
|
|
|
- nand_read_options_t opts;
|
|
|
|
- memset(&opts, 0, sizeof(opts));
|
|
|
|
- opts.buffer = (u_char*) addr;
|
|
|
|
- opts.length = size;
|
|
|
|
- opts.offset = off;
|
|
|
|
- opts.quiet = quiet;
|
|
|
|
- ret = nand_read_opts(nand, &opts);
|
|
|
|
- } else {
|
|
|
|
- /* write */
|
|
|
|
- nand_write_options_t opts;
|
|
|
|
- memset(&opts, 0, sizeof(opts));
|
|
|
|
- opts.buffer = (u_char*) addr;
|
|
|
|
- opts.length = size;
|
|
|
|
- opts.offset = off;
|
|
|
|
- /* opts.forcejffs2 = 1; */
|
|
|
|
- opts.pad = 1;
|
|
|
|
- opts.blockalign = 1;
|
|
|
|
- opts.quiet = quiet;
|
|
|
|
- ret = nand_write_opts(nand, &opts);
|
|
|
|
- }
|
|
|
|
- } else if (s != NULL && !strcmp(s, ".oob")) {
|
|
|
|
- /* read out-of-band data */
|
|
|
|
|
|
+ if (!s || !strcmp(s, ".jffs2") ||
|
|
|
|
+ !strcmp(s, ".e") || !strcmp(s, ".i")) {
|
|
if (read)
|
|
if (read)
|
|
- ret = nand->read_oob(nand, off, size, &size,
|
|
|
|
- (u_char *) addr);
|
|
|
|
|
|
+ ret = nand_read_skip_bad(nand, off, &size,
|
|
|
|
+ (u_char *)addr);
|
|
else
|
|
else
|
|
- ret = nand->write_oob(nand, off, size, &size,
|
|
|
|
- (u_char *) addr);
|
|
|
|
- } else {
|
|
|
|
|
|
+ ret = nand_write_skip_bad(nand, off, &size,
|
|
|
|
+ (u_char *)addr);
|
|
|
|
+ } else if (s != NULL && !strcmp(s, ".oob")) {
|
|
|
|
+ /* out-of-band data */
|
|
|
|
+ mtd_oob_ops_t ops = {
|
|
|
|
+ .oobbuf = (u8 *)addr,
|
|
|
|
+ .ooblen = size,
|
|
|
|
+ .mode = MTD_OOB_RAW
|
|
|
|
+ };
|
|
|
|
+
|
|
if (read)
|
|
if (read)
|
|
- ret = nand_read(nand, off, &size, (u_char *)addr);
|
|
|
|
|
|
+ ret = nand->read_oob(nand, off, &ops);
|
|
else
|
|
else
|
|
- ret = nand_write(nand, off, &size, (u_char *)addr);
|
|
|
|
|
|
+ ret = nand->write_oob(nand, off, &ops);
|
|
|
|
+ } else {
|
|
|
|
+ printf("Unknown nand command suffix '%s'.\n", s);
|
|
|
|
+ return 1;
|
|
}
|
|
}
|
|
|
|
|
|
printf(" %d bytes %s: %s\n", size,
|
|
printf(" %d bytes %s: %s\n", size,
|
|
@@ -381,6 +377,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
}
|
|
}
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
+
|
|
if (strcmp(cmd, "biterr") == 0) {
|
|
if (strcmp(cmd, "biterr") == 0) {
|
|
/* todo */
|
|
/* todo */
|
|
return 1;
|
|
return 1;
|
|
@@ -395,7 +392,12 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
if (!strcmp("status", argv[2]))
|
|
if (!strcmp("status", argv[2]))
|
|
status = 1;
|
|
status = 1;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+/*
|
|
|
|
+ * ! BROKEN !
|
|
|
|
+ *
|
|
|
|
+ * TODO: must be implemented and tested by someone with HW
|
|
|
|
+ */
|
|
|
|
+#if 0
|
|
if (status) {
|
|
if (status) {
|
|
ulong block_start = 0;
|
|
ulong block_start = 0;
|
|
ulong off;
|
|
ulong off;
|
|
@@ -406,28 +408,28 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
nand_chip->cmdfunc (nand, NAND_CMD_STATUS, -1, -1);
|
|
nand_chip->cmdfunc (nand, NAND_CMD_STATUS, -1, -1);
|
|
printf("device is %swrite protected\n",
|
|
printf("device is %swrite protected\n",
|
|
(nand_chip->read_byte(nand) & 0x80 ?
|
|
(nand_chip->read_byte(nand) & 0x80 ?
|
|
- "NOT " : "" ) );
|
|
|
|
|
|
+ "NOT " : ""));
|
|
|
|
|
|
- for (off = 0; off < nand->size; off += nand->oobblock) {
|
|
|
|
|
|
+ for (off = 0; off < nand->size; off += nand->writesize) {
|
|
int s = nand_get_lock_status(nand, off);
|
|
int s = nand_get_lock_status(nand, off);
|
|
|
|
|
|
/* print message only if status has changed
|
|
/* print message only if status has changed
|
|
* or at end of chip
|
|
* or at end of chip
|
|
*/
|
|
*/
|
|
- if (off == nand->size - nand->oobblock
|
|
|
|
|
|
+ if (off == nand->size - nand->writesize
|
|
|| (s != last_status && off != 0)) {
|
|
|| (s != last_status && off != 0)) {
|
|
|
|
|
|
- printf("%08lx - %08lx: %8lu pages %s%s%s\n",
|
|
|
|
|
|
+ printf("%08lx - %08lx: %8d pages %s%s%s\n",
|
|
block_start,
|
|
block_start,
|
|
off-1,
|
|
off-1,
|
|
- (off-block_start)/nand->oobblock,
|
|
|
|
|
|
+ (off-block_start)/nand->writesize,
|
|
((last_status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""),
|
|
((last_status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""),
|
|
((last_status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""),
|
|
((last_status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""),
|
|
((last_status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : ""));
|
|
((last_status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : ""));
|
|
}
|
|
}
|
|
|
|
|
|
last_status = s;
|
|
last_status = s;
|
|
- }
|
|
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
if (!nand_lock(nand, tight)) {
|
|
if (!nand_lock(nand, tight)) {
|
|
puts("NAND flash successfully locked\n");
|
|
puts("NAND flash successfully locked\n");
|
|
@@ -436,6 +438,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -443,6 +446,12 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0)
|
|
if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0)
|
|
return 1;
|
|
return 1;
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * ! BROKEN !
|
|
|
|
+ *
|
|
|
|
+ * TODO: must be implemented and tested by someone with HW
|
|
|
|
+ */
|
|
|
|
+#if 0
|
|
if (!nand_unlock(nand, off, size)) {
|
|
if (!nand_unlock(nand, off, size)) {
|
|
puts("NAND flash successfully unlocked\n");
|
|
puts("NAND flash successfully unlocked\n");
|
|
} else {
|
|
} else {
|
|
@@ -450,6 +459,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
"write and erase will probably fail\n");
|
|
"write and erase will probably fail\n");
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -459,54 +469,47 @@ usage:
|
|
}
|
|
}
|
|
|
|
|
|
U_BOOT_CMD(nand, 5, 1, do_nand,
|
|
U_BOOT_CMD(nand, 5, 1, do_nand,
|
|
- "nand - NAND sub-system\n",
|
|
|
|
- "info - show available NAND devices\n"
|
|
|
|
- "nand device [dev] - show or set current device\n"
|
|
|
|
- "nand read[.jffs2] - addr off|partition size\n"
|
|
|
|
- "nand write[.jffs2] - addr off|partition size - read/write `size' bytes starting\n"
|
|
|
|
- " at offset `off' to/from memory address `addr'\n"
|
|
|
|
- "nand erase [clean] [off size] - erase `size' bytes from\n"
|
|
|
|
- " offset `off' (entire device if not specified)\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 markbad off - mark bad block at offset (UNSAFE)\n"
|
|
|
|
- "nand biterr off - make a bit error at offset (UNSAFE)\n"
|
|
|
|
- "nand lock [tight] [status] - bring nand to lock state or display locked pages\n"
|
|
|
|
- "nand unlock [offset] [size] - unlock section\n");
|
|
|
|
|
|
+ "nand - NAND sub-system\n",
|
|
|
|
+ "info - show available NAND devices\n"
|
|
|
|
+ "nand device [dev] - show or set current device\n"
|
|
|
|
+ "nand read - addr off|partition size\n"
|
|
|
|
+ "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"
|
|
|
|
+ "nand bad - show bad blocks\n"
|
|
|
|
+ "nand dump[.oob] off - dump page\n"
|
|
|
|
+ "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n"
|
|
|
|
+ "nand markbad off - mark bad block at offset (UNSAFE)\n"
|
|
|
|
+ "nand biterr off - make a bit error at offset (UNSAFE)\n"
|
|
|
|
+ "nand lock [tight] [status]\n"
|
|
|
|
+ " bring nand to lock state or display locked pages\n"
|
|
|
|
+ "nand unlock [offset] [size] - unlock section\n");
|
|
|
|
|
|
static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
|
|
static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
|
|
- ulong offset, ulong addr, char *cmd)
|
|
|
|
|
|
+ ulong offset, ulong addr, char *cmd)
|
|
{
|
|
{
|
|
int r;
|
|
int r;
|
|
char *ep, *s;
|
|
char *ep, *s;
|
|
size_t cnt;
|
|
size_t cnt;
|
|
image_header_t *hdr;
|
|
image_header_t *hdr;
|
|
- int jffs2 = 0;
|
|
|
|
#if defined(CONFIG_FIT)
|
|
#if defined(CONFIG_FIT)
|
|
const void *fit_hdr = NULL;
|
|
const void *fit_hdr = NULL;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
s = strchr(cmd, '.');
|
|
s = strchr(cmd, '.');
|
|
if (s != NULL &&
|
|
if (s != NULL &&
|
|
- (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i")))
|
|
|
|
- jffs2 = 1;
|
|
|
|
|
|
+ (strcmp(s, ".jffs2") && !strcmp(s, ".e") && !strcmp(s, ".i"))) {
|
|
|
|
+ printf("Unknown nand load suffix '%s'\n", s);
|
|
|
|
+ show_boot_progress(-53);
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
|
|
printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset);
|
|
printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset);
|
|
|
|
|
|
- cnt = nand->oobblock;
|
|
|
|
- if (jffs2) {
|
|
|
|
- nand_read_options_t opts;
|
|
|
|
- memset(&opts, 0, sizeof(opts));
|
|
|
|
- opts.buffer = (u_char*) addr;
|
|
|
|
- opts.length = cnt;
|
|
|
|
- opts.offset = offset;
|
|
|
|
- opts.quiet = 1;
|
|
|
|
- r = nand_read_opts(nand, &opts);
|
|
|
|
- } else {
|
|
|
|
- r = nand_read(nand, offset, &cnt, (u_char *) addr);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ cnt = nand->writesize;
|
|
|
|
+ r = nand_read(nand, offset, &cnt, (u_char *) addr);
|
|
if (r) {
|
|
if (r) {
|
|
puts("** Read error\n");
|
|
puts("** Read error\n");
|
|
show_boot_progress (-56);
|
|
show_boot_progress (-56);
|
|
@@ -536,19 +539,10 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
|
|
puts ("** Unknown image type\n");
|
|
puts ("** Unknown image type\n");
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
+ show_boot_progress (57);
|
|
|
|
|
|
- if (jffs2) {
|
|
|
|
- nand_read_options_t opts;
|
|
|
|
- memset(&opts, 0, sizeof(opts));
|
|
|
|
- opts.buffer = (u_char*) addr;
|
|
|
|
- opts.length = cnt;
|
|
|
|
- opts.offset = offset;
|
|
|
|
- opts.quiet = 1;
|
|
|
|
- r = nand_read_opts(nand, &opts);
|
|
|
|
- } else {
|
|
|
|
- r = nand_read(nand, offset, &cnt, (u_char *) addr);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ /* FIXME: skip bad blocks */
|
|
|
|
+ r = nand_read(nand, offset, &cnt, (u_char *) addr);
|
|
if (r) {
|
|
if (r) {
|
|
puts("** Read error\n");
|
|
puts("** Read error\n");
|
|
show_boot_progress (-58);
|
|
show_boot_progress (-58);
|
|
@@ -614,7 +608,7 @@ int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
else
|
|
else
|
|
addr = CFG_LOAD_ADDR;
|
|
addr = CFG_LOAD_ADDR;
|
|
return nand_load_image(cmdtp, &nand_info[dev->id->num],
|
|
return nand_load_image(cmdtp, &nand_info[dev->id->num],
|
|
- part->offset, addr, argv[0]);
|
|
|
|
|
|
+ part->offset, addr, argv[0]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
@@ -669,11 +663,11 @@ usage:
|
|
|
|
|
|
U_BOOT_CMD(nboot, 4, 1, do_nandboot,
|
|
U_BOOT_CMD(nboot, 4, 1, do_nandboot,
|
|
"nboot - boot from NAND device\n",
|
|
"nboot - boot from NAND device\n",
|
|
- "[.jffs2] [partition] | [[[loadAddr] dev] offset]\n");
|
|
|
|
|
|
+ "[partition] | [[[loadAddr] dev] offset]\n");
|
|
|
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-#else /* CFG_NAND_LEGACY */
|
|
|
|
|
|
+#else /* CONFIG_NAND_LEGACY */
|
|
/*
|
|
/*
|
|
*
|
|
*
|
|
* Legacy NAND support - to be phased out
|
|
* Legacy NAND support - to be phased out
|
|
@@ -726,10 +720,10 @@ void archflashwp(void *archdata, int wp);
|
|
#define CONFIG_MTD_NAND_ECC_JFFS2
|
|
#define CONFIG_MTD_NAND_ECC_JFFS2
|
|
|
|
|
|
/* bits for nand_legacy_rw() `cmd'; or together as needed */
|
|
/* bits for nand_legacy_rw() `cmd'; or together as needed */
|
|
-#define NANDRW_READ 0x01
|
|
|
|
-#define NANDRW_WRITE 0x00
|
|
|
|
-#define NANDRW_JFFS2 0x02
|
|
|
|
-#define NANDRW_JFFS2_SKIP 0x04
|
|
|
|
|
|
+#define NANDRW_READ 0x01
|
|
|
|
+#define NANDRW_WRITE 0x00
|
|
|
|
+#define NANDRW_JFFS2 0x02
|
|
|
|
+#define NANDRW_JFFS2_SKIP 0x04
|
|
|
|
|
|
/*
|
|
/*
|
|
* Imports from nand_legacy.c
|
|
* Imports from nand_legacy.c
|
|
@@ -839,11 +833,11 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
|
|
|
if (strncmp (argv[1], "read", 4) == 0 ||
|
|
if (strncmp (argv[1], "read", 4) == 0 ||
|
|
strncmp (argv[1], "write", 5) == 0) {
|
|
strncmp (argv[1], "write", 5) == 0) {
|
|
- ulong addr = simple_strtoul (argv[2], NULL, 16);
|
|
|
|
- off_t off = simple_strtoul (argv[3], NULL, 16);
|
|
|
|
- size_t size = simple_strtoul (argv[4], NULL, 16);
|
|
|
|
- int cmd = (strncmp (argv[1], "read", 4) == 0) ?
|
|
|
|
- NANDRW_READ : NANDRW_WRITE;
|
|
|
|
|
|
+ ulong addr = simple_strtoul (argv[2], NULL, 16);
|
|
|
|
+ off_t off = simple_strtoul (argv[3], NULL, 16);
|
|
|
|
+ size_t size = simple_strtoul (argv[4], NULL, 16);
|
|
|
|
+ int cmd = (strncmp (argv[1], "read", 4) == 0) ?
|
|
|
|
+ NANDRW_READ : NANDRW_WRITE;
|
|
size_t total;
|
|
size_t total;
|
|
int ret;
|
|
int ret;
|
|
char *cmdtail = strchr (argv[1], '.');
|
|
char *cmdtail = strchr (argv[1], '.');
|
|
@@ -892,8 +886,7 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
|
|
|
ret = nand_legacy_rw (nand_dev_desc + curr_device,
|
|
ret = nand_legacy_rw (nand_dev_desc + curr_device,
|
|
cmd, off, size,
|
|
cmd, off, size,
|
|
- &total,
|
|
|
|
- (u_char *) addr);
|
|
|
|
|
|
+ &total, (u_char *) addr);
|
|
|
|
|
|
printf (" %d bytes %s: %s\n", total,
|
|
printf (" %d bytes %s: %s\n", total,
|
|
(cmd & NANDRW_READ) ? "read" : "written",
|
|
(cmd & NANDRW_READ) ? "read" : "written",
|
|
@@ -1000,11 +993,11 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|
show_boot_progress (55);
|
|
show_boot_progress (55);
|
|
|
|
|
|
printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n",
|
|
printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n",
|
|
- dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR,
|
|
|
|
- offset);
|
|
|
|
|
|
+ dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR,
|
|
|
|
+ offset);
|
|
|
|
|
|
if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ, offset,
|
|
if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ, offset,
|
|
- SECTORSIZE, NULL, (u_char *)addr)) {
|
|
|
|
|
|
+ SECTORSIZE, NULL, (u_char *)addr)) {
|
|
printf ("** Read error on %d\n", dev);
|
|
printf ("** Read error on %d\n", dev);
|
|
show_boot_progress (-56);
|
|
show_boot_progress (-56);
|
|
return 1;
|
|
return 1;
|
|
@@ -1035,8 +1028,8 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|
show_boot_progress (57);
|
|
show_boot_progress (57);
|
|
|
|
|
|
if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ,
|
|
if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ,
|
|
- offset + SECTORSIZE, cnt, NULL,
|
|
|
|
- (u_char *)(addr+SECTORSIZE))) {
|
|
|
|
|
|
+ offset + SECTORSIZE, cnt, NULL,
|
|
|
|
+ (u_char *)(addr+SECTORSIZE))) {
|
|
printf ("** Read error on %d\n", dev);
|
|
printf ("** Read error on %d\n", dev);
|
|
show_boot_progress (-58);
|
|
show_boot_progress (-58);
|
|
return 1;
|
|
return 1;
|
|
@@ -1084,4 +1077,4 @@ U_BOOT_CMD(
|
|
|
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-#endif /* CFG_NAND_LEGACY */
|
|
|
|
|
|
+#endif /* CONFIG_NAND_LEGACY */
|