From mboxrd@z Thu Jan 1 00:00:00 1970 From: William Juul Date: Mon, 12 Nov 2007 14:02:05 +0100 Subject: [U-Boot-Users] [PATCH 2/9] NAND update Message-ID: <47384ECD.8020405@juul.no> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de The following modifications have been made in common/ Note that the patch-series is broken unless it is seen as one single patch. It is broken up to multiple emails to fit the size limit. We have set up a git repository were you can pull the complete patch: http://git.tandberg.com/tandberg/u-boot.git Best regards William ------------------------------------------------- William Juul, Senior Development Engineer Data Respons Norge AS Sandviksveien 26 P.O. Box 489 NO-1323 H?vik, Norway www.datarespons.no ------------------------------------------------- diff --git a/common/cmd_doc.c b/common/cmd_doc.c index d6d3aff..8f5006d 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -17,6 +17,7 @@ #include #include +#if 0 #ifdef CFG_DOC_SUPPORT_2000 #define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k) #else @@ -1607,5 +1608,7 @@ void doc_probe(unsigned long physadr) puts ("No DiskOnChip found\n"); } } - +#else +void doc_probe(unsigned long physadr) {} +#endif #endif diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 1fdd7a6..4ed6788 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -18,6 +18,7 @@ * */ #include +#include #if defined(CONFIG_CMD_NAND) @@ -37,7 +38,7 @@ int find_dev_and_part(const char *id, struct mtd_device **dev, u8 *part_num, struct part_info **part); #endif -extern nand_info_t nand_info[]; /* info for NAND chips */ +extern nand_info_t nand_info[]; /* info for NAND chips */ static int nand_dump_oob(nand_info_t *nand, ulong off) { @@ -49,20 +50,26 @@ static int nand_dump(nand_info_t *nand, ulong off) int i; u_char *buf, *p; - buf = malloc(nand->oobblock + nand->oobsize); + buf = malloc(nand->writesize + nand->oobsize); if (!buf) { puts("No memory for page buffer\n"); return 1; } - off &= ~(nand->oobblock - 1); - i = nand_read_raw(nand, buf, off, nand->oobblock, nand->oobsize); + off &= ~(nand->writesize - 1); +#if 0 + i = nand_read_raw(nand, buf, off, nand->writesize, nand->oobsize); +#else + size_t dummy; + loff_t addr = (loff_t) off; + i = nand->read(nand, addr, nand->writesize, &dummy, buf); +#endif if (i < 0) { printf("Error (%d) reading page %08x\n", i, off); free(buf); return 1; } printf("Page %08x dump:\n", off); - i = nand->oobblock >> 4; p = buf; + i = nand->writesize >> 4; p = buf; while (i--) { printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x" " %02x %02x %02x %02x %02x %02x %02x %02x\n", @@ -103,7 +110,7 @@ arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size) if (argc >= 1 && !(str2long(argv[0], off))) { if ((mtdparts_init() == 0) && - (find_dev_and_part(argv[0], &dev, &pnum, &part) == 0)) { + (find_dev_and_part(argv[0], &dev, &pnum, &part) == 0)) { if (dev->id->type != MTD_DEV_TYPE_NAND) { puts("not a NAND device\n"); return -1; @@ -158,6 +165,7 @@ out: int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { int i, dev, ret; + ret = 0; ulong addr, off, size; char *cmd, *s; nand_info_t *nand; @@ -193,7 +201,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (argc < 3) { if ((nand_curr_device < 0) || - (nand_curr_device >= CFG_MAX_NAND_DEVICE)) + (nand_curr_device >= CFG_MAX_NAND_DEVICE)) puts("\nno devices available\n"); else printf("\nDevice %d: %s\n", nand_curr_device, @@ -220,16 +228,16 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 && - strncmp(cmd, "dump", 4) != 0 && - strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 && - strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 && - strcmp(cmd, "biterr") != 0 && - strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 ) + strncmp(cmd, "dump", 4) != 0 && + strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 && + strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 && + strcmp(cmd, "biterr") != 0 && + strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 ) goto usage; /* the following commands operate on the current device */ if (nand_curr_device < 0 || nand_curr_device >= CFG_MAX_NAND_DEVICE || - !nand_info[nand_curr_device].name) { + !nand_info[nand_curr_device].name) { puts("\nno devices available\n"); return 1; } @@ -245,13 +253,13 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) /* * Syntax is: - * 0 1 2 3 4 + * 0 1 2 3 4 * nand erase [clean] [off size] */ if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "scrub") == 0) { nand_erase_options_t opts; /* "clean" at index 2 means request to write cleanmarker */ - int clean = argc > 2 && !strcmp("clean", argv[2]); + int clean = !strcmp("clean", argv[2]); int o = clean ? 3 : 2; int scrub = !strcmp(cmd, "scrub"); @@ -261,6 +269,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return 1; memset(&opts, 0, sizeof(opts)); + opts.offset = off; opts.length = size; opts.jffs2 = clean; @@ -268,16 +277,16 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (scrub) { puts("Warning: " - "scrub option will erase all factory set " - "bad blocks!\n" - " " - "There is no reliable way to recover them.\n" - " " - "Use this command only for testing purposes " - "if you\n" - " " - "are sure of what you are doing!\n" - "\nReally scrub this NAND flash? \n"); + "scrub option will erase all factory set " + "bad blocks!\n" + " " + "There is no reliable way to recover them.\n" + " " + "Use this command only for testing purposes " + "if you\n" + " " + "are sure of what you are doing!\n" + "\nReally scrub this NAND flash? \n"); if (getc() == 'y' && getc() == '\r') { opts.scrub = 1; @@ -324,28 +333,25 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) s = strchr(cmd, '.'); if (s != NULL && - (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) { + (!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); + 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; + mtd_oob_ops_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); + opts.datbuf = (u_char*) addr; + opts.len = size; + opts.ooblen = 64; + opts.mode = MTD_OOB_AUTO; + ret = nand_write_opts(nand, off, &opts); } } else { if (read) @@ -355,7 +361,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } printf(" %d bytes %s: %s\n", size, - read ? "read" : "written", ret ? "ERROR" : "OK"); + read ? "read" : "written", ret ? "ERROR" : "OK"); return ret == 0 ? 0 : 1; } @@ -366,11 +372,11 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) int ret = nand->block_markbad(nand, addr); if (ret == 0) { printf("block 0x%08lx successfully marked as bad\n", - (ulong) addr); + (ulong) addr); return 0; } else { printf("block 0x%08lx NOT marked as bad! ERROR %d\n", - (ulong) addr, ret); + (ulong) addr, ret); } return 1; } @@ -390,44 +396,48 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } if (status) { - ulong block_start = 0; ulong off; +/* ulong block_start = 0; int last_status = -1; - +*/ struct nand_chip *nand_chip = nand->priv; /* check the WP bit */ nand_chip->cmdfunc (nand, NAND_CMD_STATUS, -1, -1); printf("device is %swrite protected\n", - (nand_chip->read_byte(nand) & 0x80 ? + (nand_chip->read_byte(nand) & 0x80 ? "NOT " : "" ) ); - for (off = 0; off < nand->size; off += nand->oobblock) { + for (off = 0; off < nand->size; off += nand->writesize) { +#if 0 /* must be fixed */ int s = nand_get_lock_status(nand, off); /* print message only if status has changed * or at end of chip */ - if (off == nand->size - nand->oobblock - || (s != last_status && off != 0)) { + if (off == nand->size - nand->writesize + || (s != last_status && off != 0)) { printf("%08x - %08x: %8d pages %s%s%s\n", - block_start, - off-1, - (off-block_start)/nand->oobblock, - ((last_status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""), - ((last_status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""), - ((last_status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); + block_start, + off-1, + (off-block_start)/nand->writesize, + ((last_status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""), + ((last_status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""), + ((last_status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); } last_status = s; - } +#endif + } } else { +#if 0 /* must be fixed */ if (!nand_lock(nand, tight)) { puts("NAND flash successfully locked\n"); } else { puts("Error locking NAND flash\n"); return 1; } +#endif } return 0; } @@ -436,13 +446,15 @@ 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) return 1; +#if 0 /* must be fixed */ if (!nand_unlock(nand, off, size)) { puts("NAND flash successfully unlocked\n"); } else { puts("Error unlocking NAND flash, " - "write and erase will probably fail\n"); + "write and erase will probably fail\n"); return 1; } +#endif return 0; } @@ -452,14 +464,14 @@ usage: } 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" - " @offset `off' to/from memory address `addr'\n" + "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" + " 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" @@ -479,24 +491,13 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, s = strchr(cmd, '.'); if (s != NULL && - (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) + (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) jffs2 = 1; 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) { puts("** Read error\n"); show_boot_progress (-56); @@ -511,23 +512,12 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, show_boot_progress (-57); return 1; } - show_boot_progress (57); print_image_hdr(hdr); cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t)); - 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); - } + r = nand_read(nand, offset, &cnt, (u_char *) addr); if (r) { puts("** Read error\n"); show_boot_progress (-58); @@ -568,7 +558,7 @@ int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (argc >= 2) { char *p = (argc == 2) ? argv[1] : argv[2]; if (!(str2long(p, &addr)) && (mtdparts_init() == 0) && - (find_dev_and_part(p, &dev, &pnum, &part) == 0)) { + (find_dev_and_part(p, &dev, &pnum, &part) == 0)) { if (dev->id->type != MTD_DEV_TYPE_NAND) { puts("Not a NAND device\n"); return 1; @@ -580,7 +570,7 @@ int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) else addr = CFG_LOAD_ADDR; return nand_load_image(cmdtp, &nand_info[dev->id->num], - part->offset, addr, argv[0]); + part->offset, addr, argv[0]); } } #endif @@ -668,10 +658,10 @@ U_BOOT_CMD(nboot, 4, 1, do_nandboot, void archflashwp(void *archdata, int wp); #endif -#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) +#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) -#undef NAND_DEBUG -#undef PSYCHO_DEBUG +#undef NAND_DEBUG +#undef PSYCHO_DEBUG /* ****************** WARNING ********************* * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will @@ -686,16 +676,16 @@ void archflashwp(void *archdata, int wp); * and attempting to program or erase bad blocks can affect * the data in _other_ (good) blocks. */ -#define ALLOW_ERASE_BAD_DEBUG 0 +#define ALLOW_ERASE_BAD_DEBUG 0 #define CONFIG_MTD_NAND_ECC /* enable ECC */ #define CONFIG_MTD_NAND_ECC_JFFS2 /* bits for nand_legacy_rw() `cmd'; or together as needed */ -#define NANDRW_READ 0x01 +#define NANDRW_READ 0x01 #define NANDRW_WRITE 0x00 #define NANDRW_JFFS2 0x02 -#define NANDRW_JFFS2_SKIP 0x04 +#define NANDRW_JFFS2_SKIP 0x04 /* * Imports from nand_legacy.c @@ -703,13 +693,13 @@ void archflashwp(void *archdata, int wp); extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; extern int curr_device; extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs, - size_t len, int clean); + size_t len, int clean); extern int nand_legacy_rw(struct nand_chip *nand, int cmd, size_t start, size_t len, size_t *retlen, u_char *buf); extern void nand_print(struct nand_chip *nand); extern void nand_print_bad(struct nand_chip *nand); extern int nand_read_oob(struct nand_chip *nand, size_t ofs, - size_t len, size_t *retlen, u_char *buf); + size_t len, size_t *retlen, u_char *buf); extern int nand_write_oob(struct nand_chip *nand, size_t ofs, size_t len, size_t *retlen, const u_char *buf); @@ -731,8 +721,8 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) for (i = 0; i < CFG_MAX_NAND_DEVICE; ++i) { if (nand_dev_desc[i].ChipID == - NAND_ChipID_UNKNOWN) - continue; /* list only known devices */ + NAND_ChipID_UNKNOWN) + continue; /* list only known devices */ printf ("Device %d: ", i); nand_print (&nand_dev_desc[i]); } @@ -740,7 +730,7 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } else if (strcmp (argv[1], "device") == 0) { if ((curr_device < 0) - || (curr_device >= CFG_MAX_NAND_DEVICE)) { + || (curr_device >= CFG_MAX_NAND_DEVICE)) { puts ("\nno devices available\n"); return 1; } @@ -750,7 +740,7 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } else if (strcmp (argv[1], "bad") == 0) { if ((curr_device < 0) - || (curr_device >= CFG_MAX_NAND_DEVICE)) { + || (curr_device >= CFG_MAX_NAND_DEVICE)) { puts ("\nno devices available\n"); return 1; } @@ -804,7 +794,7 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) /* at least 4 args */ 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); ulong off = simple_strtoul (argv[3], NULL, 16); ulong size = simple_strtoul (argv[4], NULL, 16); @@ -817,12 +807,12 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) /* read out-of-band data */ if (cmd & NANDRW_READ) { ret = nand_read_oob (nand_dev_desc + curr_device, - off, size, (size_t *) & total, - (u_char *) addr); + off, size, (size_t *) & total, + (u_char *) addr); } else { ret = nand_write_oob (nand_dev_desc + curr_device, - off, size, (size_t *) & total, - (u_char *) addr); + off, size, (size_t *) & total, + (u_char *) addr); } return ret; } else if (cmdtail && !strncmp (cmdtail, ".jffs2", 2)) @@ -830,7 +820,7 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) else if (cmdtail && !strncmp (cmdtail, ".jffs2s", 2)) { cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */ if (cmd & NANDRW_READ) - cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ + cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ } #ifdef SXNI855T /* need ".e" same as ".j" for compatibility with older units */ @@ -843,7 +833,7 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) else if (cmdtail && !strcmp (cmdtail, ".i")) { cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */ if (cmd & NANDRW_READ) - cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ + cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ } #endif /* CFG_NAND_SKIP_BAD_DOT_I */ else if (cmdtail) { @@ -856,9 +846,9 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) curr_device, off, size); ret = nand_legacy_rw (nand_dev_desc + curr_device, - cmd, off, size, - (size_t *) & total, - (u_char *) addr); + cmd, off, size, + (size_t *) & total, + (u_char *) addr); printf (" %d bytes %s: %s\n", total, (cmd & NANDRW_READ) ? "read" : "written", @@ -893,15 +883,15 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } U_BOOT_CMD( - nand, 5, 1, do_nand, - "nand - legacy NAND sub-system\n", + nand, 5, 1, do_nand, + "nand - legacy NAND sub-system\n", "info - show available NAND devices\n" "nand device [dev] - show or set current device\n" "nand read[.jffs2[s]] addr off size\n" "nand write[.jffs2] addr off size - read/write `size' bytes starting\n" - " at offset `off' to/from memory address `addr'\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" + " offset `off' (entire device if not specified)\n" "nand bad - show bad blocks\n" "nand read.oob addr off size - read out-of-band data\n" "nand write.oob addr off size - read out-of-band data\n" @@ -953,7 +943,7 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) dev = simple_strtoul(boot_device, &ep, 16); if ((dev >= CFG_MAX_NAND_DEVICE) || - (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) { + (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) { printf ("\n** Device %d not available\n", dev); show_boot_progress (-55); return 1; @@ -1017,7 +1007,7 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } U_BOOT_CMD( - nboot, 4, 1, do_nandboot, + nboot, 4, 1, do_nandboot, "nboot - boot from NAND device\n", "loadAddr dev\n" );