From cfa460adfdefcc30d104e1a9ee44994ee349bb7b Mon Sep 17 00:00:00 2001 From: William Juul Date: Wed, 31 Oct 2007 13:53:06 +0100 Subject: Update MTD to that of Linux 2.6.22.1 A lot changed in the Linux MTD code, since it was last ported from Linux to U-Boot. This patch takes U-Boot NAND support to the level of Linux 2.6.22.1 and will enable support for very large NAND devices (4KB pages) and ease the compatibility between U-Boot and Linux filesystems. This patch is tested on two custom boards with PPC and ARM processors running YAFFS in U-Boot and Linux using gcc-4.1.2 cross compilers. MAKEALL ppc/arm has some issues: * DOC/OneNand/nand_spl is not building (I have not tried porting these parts, and since I do not have any HW and I am not familiar with this code/HW I think its best left to someone else.) Except for the issues mentioned above, I have ported all drivers necessary to run MAKEALL ppc/arm without errors and warnings. Many drivers were trivial to port, but some were not so trivial. The following drivers must be examined carefully and maybe rewritten to some degree: cpu/ppc4xx/ndfc.c cpu/arm926ejs/davinci/nand.c board/delta/nand.c board/zylonite/nand.c Signed-off-by: William Juul Signed-off-by: Stig Olsen Signed-off-by: Scott Wood --- common/cmd_doc.c | 4 + common/cmd_nand.c | 273 ++++++++++++++++++++++++++---------------------------- 2 files changed, 135 insertions(+), 142 deletions(-) (limited to 'common') diff --git a/common/cmd_doc.c b/common/cmd_doc.c index d7b2f535f3d..9d5b3001cc9 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -14,6 +14,7 @@ #include #include +#if 0 #ifdef CFG_DOC_SUPPORT_2000 #define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k) #else @@ -1629,3 +1630,6 @@ void doc_probe(unsigned long physadr) puts ("No DiskOnChip found\n"); } } +#else +void doc_probe(unsigned long physadr) {} +#endif diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 9e38bf768f9..3e76d8207d6 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -18,6 +18,7 @@ * */ #include +#include #if defined(CONFIG_CMD_NAND) @@ -34,7 +35,7 @@ int mtdparts_init(void); 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, - u8 *part_num, struct part_info **part); + u8 *part_num, struct part_info **part); #endif static int nand_dump_oob(nand_info_t *nand, ulong off) @@ -47,32 +48,38 @@ 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 %08lx\n", i, off); free(buf); return 1; } printf("Page %08lx 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", - 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]); + 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; } puts("OOB:\n"); i = nand->oobsize >> 3; 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; } free(buf); @@ -155,7 +162,7 @@ out: 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; size_t size; char *cmd, *s; @@ -182,8 +189,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_info[i].name) 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; } @@ -192,11 +199,11 @@ 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, - nand_info[nand_curr_device].name); + nand_info[nand_curr_device].name); return 0; } dev = (int)simple_strtoul(argv[2], NULL, 10); @@ -219,11 +226,11 @@ 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 */ @@ -250,7 +257,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) 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"); @@ -260,6 +267,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; @@ -320,40 +328,41 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) printf("\nNAND %s: ", read ? "read" : "write"); if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0) return 1; - + 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 (s != NULL && !strcmp(s, ".oob")) { - /* read out-of-band data */ + /* out-of-band data */ + mtd_oob_ops_t ops = { + .oobbuf = (u8 *)addr, + .ooblen = size, + .mode = MTD_OOB_RAW + }; + if (read) - ret = nand->read_oob(nand, off, size, &size, - (u_char *) addr); + ret = nand->read_oob(nand, off, &ops); else - ret = nand->write_oob(nand, off, size, &size, - (u_char *) addr); + ret = nand->write_oob(nand, off, &ops); } else { if (read) ret = nand_read(nand, off, &size, (u_char *)addr); @@ -397,44 +406,44 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } if (status) { - ulong block_start = 0; +// ulong block_start = 0; ulong off; - int last_status = -1; +// 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 ? - "NOT " : "" ) ); - - for (off = 0; off < nand->size; off += nand->oobblock) { - 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)) { - - printf("%08lx - %08lx: %8lu 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 " : "")); - } - - last_status = s; - } - } else { - if (!nand_lock(nand, tight)) { - puts("NAND flash successfully locked\n"); - } else { - puts("Error locking NAND flash\n"); - return 1; + "NOT " : "" ) ); + + for (off = 0; off < nand->size; off += nand->writesize) { +// 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->writesize +// || (s != last_status && off != 0)) { +// +// printf("%08lx - %08lx: %8d pages %s%s%s\n", +// 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; } + } else { +// if (!nand_lock(nand, tight)) { +// puts("NAND flash successfully locked\n"); +// } else { +// puts("Error locking NAND flash\n"); +// return 1; +// } } return 0; } @@ -443,13 +452,13 @@ 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 (!nand_unlock(nand, off, size)) { - puts("NAND flash successfully unlocked\n"); - } else { - puts("Error unlocking NAND flash, " - "write and erase will probably fail\n"); - return 1; - } +// 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"); +// return 1; +// } return 0; } @@ -459,24 +468,26 @@ 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" - " 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[.jffs2] - addr off|partition size\n" + "nand write[.jffs2] - addr off|partition size\n" + " read/write 'size' bytes starting at offset 'off'\n" + " 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]\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, - ulong offset, ulong addr, char *cmd) + ulong offset, ulong addr, char *cmd) { int r; char *ep, *s; @@ -494,19 +505,8 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, 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); @@ -537,18 +537,7 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, return 1; } - 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); @@ -614,7 +603,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 @@ -704,8 +693,8 @@ void archflashwp(void *archdata, int wp); #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 @@ -720,16 +709,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_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 @@ -737,15 +726,15 @@ 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); + 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); + size_t len, size_t *retlen, const u_char *buf); int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) @@ -878,7 +867,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) { @@ -928,7 +917,7 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } U_BOOT_CMD( - nand, 5, 1, do_nand, + 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" @@ -992,7 +981,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; @@ -1000,11 +989,11 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) show_boot_progress (55); 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, - SECTORSIZE, NULL, (u_char *)addr)) { + SECTORSIZE, NULL, (u_char *)addr)) { printf ("** Read error on %d\n", dev); show_boot_progress (-56); return 1; @@ -1035,8 +1024,8 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) show_boot_progress (57); 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); show_boot_progress (-58); return 1; @@ -1077,7 +1066,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" ); -- cgit v1.3.1 From 4cbb651b29cb64d378a06729970e1e153bb605b1 Mon Sep 17 00:00:00 2001 From: William Juul Date: Thu, 8 Nov 2007 10:39:53 +0100 Subject: Remove white space at end. Signed-off-by: William Juul Signed-off-by: Scott Wood --- board/bf537-stamp/nand.c | 4 ++-- board/dave/PPChameleonEVB/nand.c | 2 +- board/nc650/nand.c | 2 +- board/netstar/nand.c | 2 +- board/prodrive/alpr/nand.c | 2 +- board/sc3/sc3nand.c | 4 ++-- common/cmd_nand.c | 2 +- cpu/arm926ejs/davinci/nand.c | 2 +- drivers/mtd/nand/nand_base.c | 4 ++-- drivers/mtd/nand/nand_util.c | 10 +++++----- include/linux/mtd/nand.h | 2 +- 11 files changed, 18 insertions(+), 18 deletions(-) (limited to 'common') diff --git a/board/bf537-stamp/nand.c b/board/bf537-stamp/nand.c index bdf1d6ee456..d90bdd071c9 100644 --- a/board/bf537-stamp/nand.c +++ b/board/bf537-stamp/nand.c @@ -50,7 +50,7 @@ static void bfin_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) if( ctrl & NAND_ALE ) IO_ADDR_W = CFG_NAND_BASE + BFIN_NAND_ALE; else - IO_ADDR_W = CFG_NAND_BASE; + IO_ADDR_W = CFG_NAND_BASE; this->IO_ADDR_W = (void __iomem *) IO_ADDR_W; } this->IO_ADDR_R = this->IO_ADDR_W; @@ -59,7 +59,7 @@ static void bfin_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) SSYNC(); if (cmd != NAND_CMD_NONE) - writeb(cmd, this->IO_ADDR_W); + writeb(cmd, this->IO_ADDR_W); } int bfin_device_ready(struct mtd_info *mtd) diff --git a/board/dave/PPChameleonEVB/nand.c b/board/dave/PPChameleonEVB/nand.c index 4bc4257c889..ea6400c0497 100644 --- a/board/dave/PPChameleonEVB/nand.c +++ b/board/dave/PPChameleonEVB/nand.c @@ -52,7 +52,7 @@ static void ppchameleonevb_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int } if (cmd != NAND_CMD_NONE) - writeb(cmd, this->IO_ADDR_W); + writeb(cmd, this->IO_ADDR_W); } diff --git a/board/nc650/nand.c b/board/nc650/nand.c index faec6053f7e..f59f5e2c9c5 100644 --- a/board/nc650/nand.c +++ b/board/nc650/nand.c @@ -48,7 +48,7 @@ static void nc650_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) } if (cmd != NAND_CMD_NONE) - writeb(cmd, this->IO_ADDR_W); + writeb(cmd, this->IO_ADDR_W); } #elif defined(CONFIG_IDS852_REV2) /* diff --git a/board/netstar/nand.c b/board/netstar/nand.c index 302d78efef1..961c92112d1 100644 --- a/board/netstar/nand.c +++ b/board/netstar/nand.c @@ -46,7 +46,7 @@ static void netstar_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int c IO_ADDR_W |= MASK_ALE; } this->IO_ADDR_W = (void __iomem *) IO_ADDR_W; - + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } diff --git a/board/prodrive/alpr/nand.c b/board/prodrive/alpr/nand.c index 3224d3dd638..e1495feea10 100644 --- a/board/prodrive/alpr/nand.c +++ b/board/prodrive/alpr/nand.c @@ -57,7 +57,7 @@ static struct alpr_ndfc_regs *alpr_ndfc = NULL; * There are 2 NAND devices on the board, a Hynix HY27US08561A (1 GByte). */ static void alpr_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) -{ +{ struct nand_chip *this = mtd->priv; if (ctrl & NAND_CTRL_CHANGE) { diff --git a/board/sc3/sc3nand.c b/board/sc3/sc3nand.c index 2f2e7458975..8ead7c850a8 100644 --- a/board/sc3/sc3nand.c +++ b/board/sc3/sc3nand.c @@ -46,7 +46,7 @@ static void sc3_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) if ( ctrl & NAND_CLE ) set_bit (SC3_NAND_CLE, sc3_control_base); else - clear_bit (SC3_NAND_CLE, sc3_control_base); + clear_bit (SC3_NAND_CLE, sc3_control_base); if ( ctrl & NAND_ALE ) set_bit (SC3_NAND_ALE, sc3_control_base); else @@ -54,7 +54,7 @@ static void sc3_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) if ( ctrl & NAND_NCE ) set_bit (SC3_NAND_CE, sc3_control_base); else - clear_bit (SC3_NAND_CE, sc3_control_base); + clear_bit (SC3_NAND_CE, sc3_control_base); } if (cmd != NAND_CMD_NONE) diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 3e76d8207d6..f825234a7c8 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -328,7 +328,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) printf("\nNAND %s: ", read ? "read" : "write"); if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0) return 1; - + s = strchr(cmd, '.'); if (s != NULL && (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) { diff --git a/cpu/arm926ejs/davinci/nand.c b/cpu/arm926ejs/davinci/nand.c index 43041b635c0..196fc146b38 100644 --- a/cpu/arm926ejs/davinci/nand.c +++ b/cpu/arm926ejs/davinci/nand.c @@ -376,7 +376,7 @@ int board_nand_init(struct nand_chip *nand) // nand->autooob = &davinci_nand_oobinfo; nand->ecc.calculate = nand_davinci_calculate_ecc; nand->ecc.correct = nand_davinci_correct_data; - nand->ecc.hwctl = nand_davinci_enable_hwecc; + nand->ecc.hwctl = nand_davinci_enable_hwecc; #else nand->ecc.mode = NAND_ECC_SOFT; #endif diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index aeb179731d6..e21a18baa4a 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2080,7 +2080,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, /* Calculate pages in each block */ pages_per_block = 1 << (chip->phys_erase_shift - chip->page_shift); - + /* Select the NAND device */ chip->select_chip(mtd, chipnr); @@ -2748,7 +2748,7 @@ int nand_scan(struct mtd_info *mtd, int maxchips) BUG(); } #endif - + ret = nand_scan_ident(mtd, maxchips); if (!ret) ret = nand_scan_tail(mtd); diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 78e70cc807d..9fe486698c1 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -128,7 +128,7 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) for (; erase.addr < opts->offset + erase_length; erase.addr += meminfo->erasesize) { - + WATCHDOG_RESET (); if (!opts->scrub && bbtest) { @@ -163,7 +163,7 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) chip->ops.datbuf = NULL; chip->ops.oobbuf = buf; chip->ops.ooboffs = chip->badblockpos & ~0x01; - + result = meminfo->write_oob(meminfo, erase.addr + meminfo->oobsize, &chip->ops); @@ -254,7 +254,7 @@ static struct nand_ecclayout autoplace_ecclayout = { * @chip: nand chip structure * @oob: oob data buffer * @ops: oob ops structure - * + * * Copied from nand_base.c */ static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, @@ -314,13 +314,13 @@ int nand_write_opts(nand_info_t *mtd, loff_t to, mtd_oob_ops_t *ops) uint8_t *oob = ops->oobbuf; uint8_t *buf = ops->datbuf; int ret, subpage; - + ops->retlen = 0; if (!writelen) return 0; printk("nand_write_opts: to: 0x%08x, ops->len: 0x%08x\n", to, ops->len); - + /* reject writes, which are not page aligned */ if (NOTALIGNED(to) || NOTALIGNED(ops->len)) { printk(KERN_NOTICE "nand_write: " diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index db8bd7ba22e..2984f5f282f 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -421,7 +421,7 @@ struct nand_chip { struct nand_ecc_ctrl ecc; struct nand_buffers *buffers; - + struct nand_hw_control hwcontrol; struct mtd_oob_ops ops; -- cgit v1.3.1 From 5e1dae5c3db7f4026f31b6a2a81ecd9e9dee475f Mon Sep 17 00:00:00 2001 From: William Juul Date: Fri, 9 Nov 2007 13:32:30 +0100 Subject: Fixing coding style issues - Fixing leading white spaces - Fixing indentation where 4 spaces are used instead of tab - Removing C++ comments (//), wherever I introduced them Signed-off-by: William Juul Signed-off-by: Scott Wood --- board/bf537-stamp/nand.c | 2 +- board/dave/PPChameleonEVB/nand.c | 4 +- board/delta/nand.c | 2 +- board/esd/common/esd405ep_nand.c | 6 +-- board/nc650/nand.c | 8 +-- board/netstar/nand.c | 2 +- board/prodrive/alpr/nand.c | 2 +- board/prodrive/pdnb3/nand.c | 2 +- board/sc3/sc3nand.c | 6 +-- board/tqc/tqm8272/tqm8272.c | 2 +- board/zylonite/nand.c | 2 +- common/cmd_nand.c | 110 +++++++++++++++++++++------------------ cpu/arm926ejs/davinci/nand.c | 18 +++---- cpu/ppc4xx/ndfc.c | 14 ++--- drivers/mtd/nand/diskonchip.c | 10 ++-- drivers/mtd/nand/nand_base.c | 2 +- include/linux/mtd/compat.h | 6 +-- include/linux/mtd/nand.h | 7 +-- 18 files changed, 106 insertions(+), 99 deletions(-) (limited to 'common') diff --git a/board/bf537-stamp/nand.c b/board/bf537-stamp/nand.c index d90bdd071c9..9800083c9e9 100644 --- a/board/bf537-stamp/nand.c +++ b/board/bf537-stamp/nand.c @@ -40,7 +40,7 @@ static void bfin_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { register struct nand_chip *this = mtd->priv; - u32 IO_ADDR_W = (u32) this->IO_ADDR_W; + u32 IO_ADDR_W = (u32) this->IO_ADDR_W; if (ctrl & NAND_CTRL_CHANGE) { if( ctrl & NAND_CLE ) diff --git a/board/dave/PPChameleonEVB/nand.c b/board/dave/PPChameleonEVB/nand.c index ea6400c0497..3ccbf650db4 100644 --- a/board/dave/PPChameleonEVB/nand.c +++ b/board/dave/PPChameleonEVB/nand.c @@ -36,7 +36,7 @@ static void ppchameleonevb_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int struct nand_chip *this = mtd->priv; ulong base = (ulong) this->IO_ADDR_W; - if (ctrl & NAND_CTRL_CHANGE) { + if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) MACRO_NAND_CTL_SETCLE((unsigned long)base); else @@ -51,7 +51,7 @@ static void ppchameleonevb_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int MACRO_NAND_DISABLE_CE((unsigned long)base); } - if (cmd != NAND_CMD_NONE) + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } diff --git a/board/delta/nand.c b/board/delta/nand.c index 51520f5fb03..b007b090d05 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -549,7 +549,7 @@ int board_nand_init(struct nand_chip *nand) nand->write_buf = dfc_write_buf; nand->cmdfunc = dfc_cmdfunc; -// nand->autooob = &delta_oob; +/* nand->autooob = &delta_oob; */ nand->badblock_pattern = &delta_bbt_descr; return 0; } diff --git a/board/esd/common/esd405ep_nand.c b/board/esd/common/esd405ep_nand.c index 4bf81ab4aac..40d1efb081b 100644 --- a/board/esd/common/esd405ep_nand.c +++ b/board/esd/common/esd405ep_nand.c @@ -32,8 +32,8 @@ */ static void esd405ep_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; - if (ctrl & NAND_CTRL_CHANGE) { + struct nand_chip *this = mtd->priv; + if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_NAND_CLE); else @@ -48,7 +48,7 @@ static void esd405ep_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_NAND_CE); } - if (cmd != NAND_CMD_NONE) + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } diff --git a/board/nc650/nand.c b/board/nc650/nand.c index f59f5e2c9c5..7dca97fdf4a 100644 --- a/board/nc650/nand.c +++ b/board/nc650/nand.c @@ -36,7 +36,7 @@ static void nc650_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *this = mtd->priv; - if (ctrl & NAND_CTRL_CHANGE) { + if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) this->IO_ADDR_W += 2; else @@ -47,7 +47,7 @@ static void nc650_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) this->IO_ADDR_W -= 1; } - if (cmd != NAND_CMD_NONE) + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } #elif defined(CONFIG_IDS852_REV2) @@ -58,7 +58,7 @@ static void nc650_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *this = mtd->priv; - if (ctrl & NAND_CTRL_CHANGE) { + if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) writeb(0, (volatile __u8 *) this->IO_ADDR_W + 0xa); else @@ -73,7 +73,7 @@ static void nc650_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) writeb(0, (volatile __u8 *) this->IO_ADDR_W) + 0xc); } - if (cmd != NAND_CMD_NONE) + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } #else diff --git a/board/netstar/nand.c b/board/netstar/nand.c index 961c92112d1..e3ab66f2fbc 100644 --- a/board/netstar/nand.c +++ b/board/netstar/nand.c @@ -47,7 +47,7 @@ static void netstar_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int c } this->IO_ADDR_W = (void __iomem *) IO_ADDR_W; - if (cmd != NAND_CMD_NONE) + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } diff --git a/board/prodrive/alpr/nand.c b/board/prodrive/alpr/nand.c index e1495feea10..99f5737b85a 100644 --- a/board/prodrive/alpr/nand.c +++ b/board/prodrive/alpr/nand.c @@ -58,7 +58,7 @@ static struct alpr_ndfc_regs *alpr_ndfc = NULL; */ static void alpr_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd->priv; if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) diff --git a/board/prodrive/pdnb3/nand.c b/board/prodrive/pdnb3/nand.c index 281ae70af61..1ce3c8c618f 100644 --- a/board/prodrive/pdnb3/nand.c +++ b/board/prodrive/pdnb3/nand.c @@ -54,7 +54,7 @@ static struct pdnb3_ndfc_regs *pdnb3_ndfc; */ static void pdnb3_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd->priv; if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) diff --git a/board/sc3/sc3nand.c b/board/sc3/sc3nand.c index 8ead7c850a8..45eff28c0ae 100644 --- a/board/sc3/sc3nand.c +++ b/board/sc3/sc3nand.c @@ -41,8 +41,8 @@ static void *sc3_control_base = (void *)0xEF600700; static void sc3_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; - if (ctrl & NAND_CTRL_CHANGE) { + struct nand_chip *this = mtd->priv; + if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) set_bit (SC3_NAND_CLE, sc3_control_base); else @@ -57,7 +57,7 @@ static void sc3_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) clear_bit (SC3_NAND_CE, sc3_control_base); } - if (cmd != NAND_CMD_NONE) + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } diff --git a/board/tqc/tqm8272/tqm8272.c b/board/tqc/tqm8272/tqm8272.c index 5148f3de5fc..a0ec254cedd 100644 --- a/board/tqc/tqm8272/tqm8272.c +++ b/board/tqc/tqm8272/tqm8272.c @@ -1070,7 +1070,7 @@ static u8 hwctl = 0; static void upmnand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd->priv; if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) diff --git a/board/zylonite/nand.c b/board/zylonite/nand.c index 47d5d4b0d73..09bcbb233d2 100644 --- a/board/zylonite/nand.c +++ b/board/zylonite/nand.c @@ -553,7 +553,7 @@ int board_nand_init(struct nand_chip *nand) nand->write_buf = dfc_write_buf; nand->cmdfunc = dfc_cmdfunc; -// nand->autooob = &delta_oob; +/* nand->autooob = &delta_oob; */ nand->badblock_pattern = &delta_bbt_descr; return 0; } diff --git a/common/cmd_nand.c b/common/cmd_nand.c index f825234a7c8..339d82b5da5 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -35,7 +35,7 @@ int mtdparts_init(void); 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, - u8 *part_num, struct part_info **part); + u8 *part_num, struct part_info **part); #endif static int nand_dump_oob(nand_info_t *nand, ulong off) @@ -340,7 +340,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) opts.length = size; opts.offset = off; opts.quiet = quiet; -// ret = nand_read_opts(nand, &opts); +/* ret = nand_read_opts(nand, &opts); */ } else { /* write */ mtd_oob_ops_t opts; @@ -406,44 +406,48 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } if (status) { -// ulong block_start = 0; ulong off; -// int last_status = -1; - +/* 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 ? - "NOT " : "" ) ); + "NOT " : "")); for (off = 0; off < nand->size; off += nand->writesize) { -// 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->writesize -// || (s != last_status && off != 0)) { -// -// printf("%08lx - %08lx: %8d pages %s%s%s\n", -// 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; +#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->writesize + || (s != last_status && off != 0)) { + + printf("%08lx - %08lx: %8d pages %s%s%s\n", + 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 (!nand_lock(nand, tight)) { -// puts("NAND flash successfully locked\n"); -// } else { -// puts("Error locking NAND flash\n"); -// return 1; -// } +#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; } @@ -452,13 +456,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 (!nand_unlock(nand, off, size)) { -// puts("NAND flash successfully unlocked\n"); -// } else { -// puts("Error unlocking NAND flash, " -// "write and erase will probably fail\n"); -// 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"); + return 1; + } +#endif return 0; } @@ -691,7 +697,7 @@ 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 @@ -715,9 +721,9 @@ void archflashwp(void *archdata, int wp); #define CONFIG_MTD_NAND_ECC_JFFS2 /* bits for nand_legacy_rw() `cmd'; or together as needed */ -#define NANDRW_READ 0x01 -#define NANDRW_WRITE 0x00 -#define NANDRW_JFFS2 0x02 +#define NANDRW_READ 0x01 +#define NANDRW_WRITE 0x00 +#define NANDRW_JFFS2 0x02 #define NANDRW_JFFS2_SKIP 0x04 /* @@ -726,15 +732,15 @@ 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); + 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); + size_t len, size_t *retlen, const u_char *buf); int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) @@ -828,11 +834,11 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (strncmp (argv[1], "read", 4) == 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; int ret; char *cmdtail = strchr (argv[1], '.'); @@ -923,9 +929,9 @@ U_BOOT_CMD( "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" diff --git a/cpu/arm926ejs/davinci/nand.c b/cpu/arm926ejs/davinci/nand.c index 196fc146b38..6afd4d252e7 100644 --- a/cpu/arm926ejs/davinci/nand.c +++ b/cpu/arm926ejs/davinci/nand.c @@ -68,7 +68,7 @@ static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int c this->IO_ADDR_W = (void __iomem *) IO_ADDR_W; } - if (cmd != NAND_CMD_NONE) + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } @@ -363,22 +363,22 @@ int board_nand_init(struct nand_chip *nand) #endif #ifdef CFG_NAND_HW_ECC #ifdef CFG_NAND_LARGEPAGE - nand->ecc.mode = NAND_ECC_HW; - nand->ecc.size = 2048; - nand->ecc.bytes = 12; + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.size = 2048; + nand->ecc.bytes = 12; #elif defined(CFG_NAND_SMALLPAGE) - nand->ecc.mode = NAND_ECC_HW; - nand->ecc.size = 512; - nand->ecc.bytes = 3; + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.size = 512; + nand->ecc.bytes = 3; #else #error "Either CFG_NAND_LARGEPAGE or CFG_NAND_SMALLPAGE must be defined!" #endif -// nand->autooob = &davinci_nand_oobinfo; +/* nand->autooob = &davinci_nand_oobinfo; */ nand->ecc.calculate = nand_davinci_calculate_ecc; nand->ecc.correct = nand_davinci_correct_data; nand->ecc.hwctl = nand_davinci_enable_hwecc; #else - nand->ecc.mode = NAND_ECC_SOFT; + nand->ecc.mode = NAND_ECC_SOFT; #endif /* Set address of hardware control function */ diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c index 7818eb9c54b..86548293152 100644 --- a/cpu/ppc4xx/ndfc.c +++ b/cpu/ppc4xx/ndfc.c @@ -48,7 +48,7 @@ static u8 hwctl = 0; static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd->priv; if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) @@ -183,12 +183,12 @@ int board_nand_init(struct nand_chip *nand) nand->read_buf = ndfc_read_buf; nand->dev_ready = ndfc_dev_ready; - nand->ecc.correct = nand_correct_data; - nand->ecc.hwctl = ndfc_enable_hwecc; - nand->ecc.calculate = ndfc_calculate_ecc; - nand->ecc.mode = NAND_ECC_HW; - nand->ecc.size = 256; - nand->ecc.bytes = 3; + nand->ecc.correct = nand_correct_data; + nand->ecc.hwctl = ndfc_enable_hwecc; + nand->ecc.calculate = ndfc_calculate_ecc; + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.size = 256; + nand->ecc.bytes = 3; #ifndef CONFIG_NAND_SPL nand->write_buf = ndfc_write_buf; diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index a03f982be5f..ce197f5ad16 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -500,11 +500,11 @@ static u_char doc2001_read_byte(struct mtd_info *mtd) struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; - //ReadDOC(docptr, CDSNSlowIO); + /*ReadDOC(docptr, CDSNSlowIO); */ /* 11.4.5 -- delay twice to allow extended length cycle */ DoC_Delay(doc, 2); ReadDOC(docptr, ReadPipeInit); - //return ReadDOC(docptr, Mil_CDSN_IO); + /*return ReadDOC(docptr, Mil_CDSN_IO); */ return ReadDOC(docptr, LastDataRead); } @@ -1051,7 +1051,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, return ret; } -//u_char mydatabuf[528]; +/*u_char mydatabuf[528]; */ /* The strange out-of-order .oobfree list below is a (possibly unneeded) * attempt to retain compatibility. It used to read: @@ -1623,11 +1623,11 @@ static int __init doc_probe(unsigned long physadr) if (ChipID == DOC_ChipID_DocMilPlus16) { WriteDOC(~newval, virtadr, Mplus_AliasResolution); oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution); - WriteDOC(newval, virtadr, Mplus_AliasResolution); // restore it + WriteDOC(newval, virtadr, Mplus_AliasResolution); /* restore it */ } else { WriteDOC(~newval, virtadr, AliasResolution); oldval = ReadDOC(doc->virtadr, AliasResolution); - WriteDOC(newval, virtadr, AliasResolution); // restore it + WriteDOC(newval, virtadr, AliasResolution); /* restore it */ } newval = ~newval; if (oldval == newval) { diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index e21a18baa4a..4b1c564f750 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2557,7 +2557,7 @@ int nand_scan_tail(struct mtd_info *mtd) default: printk(KERN_WARNING "No oob scheme defined for " "oobsize %d\n", mtd->oobsize); -// BUG(); +/* BUG(); */ } } diff --git a/include/linux/mtd/compat.h b/include/linux/mtd/compat.h index 86a6e43ca9a..9036b74f86e 100644 --- a/include/linux/mtd/compat.h +++ b/include/linux/mtd/compat.h @@ -18,10 +18,10 @@ #define KERN_DEBUG #define kmalloc(size, flags) malloc(size) -#define kzalloc(size, flags) calloc(size, 1) +#define kzalloc(size, flags) calloc(size, 1) #define vmalloc(size) malloc(size) -#define kfree(ptr) free(ptr) -#define vfree(ptr) free(ptr) +#define kfree(ptr) free(ptr) +#define vfree(ptr) free(ptr) #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 2984f5f282f..f9b7d36a73a 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -236,11 +236,12 @@ struct nand_chip; * used instead of the per chip wait queue when a hw controller is available */ struct nand_hw_control { +/* XXX U-BOOT XXX */ #if 0 - spinlock_t lock; - wait_queue_head_t wq; + spinlock_t lock; + wait_queue_head_t wq; #endif - struct nand_chip *active; + struct nand_chip *active; }; /** -- cgit v1.3.1 From 3043c045d5a9897faba7d5c7218c2f4d06cd0038 Mon Sep 17 00:00:00 2001 From: William Juul Date: Wed, 14 Nov 2007 14:28:11 +0100 Subject: Whitespace cleanup and marking broken code. Changes requested by maintainer Stefan Roese after posting patch to U-boot mailing list. Signed-off-by: William Juul Signed-off-by: Scott Wood --- common/cmd_doc.c | 5 +++ common/cmd_nand.c | 96 ++++++++++++++++++++++++++++++------------------------- 2 files changed, 57 insertions(+), 44 deletions(-) (limited to 'common') diff --git a/common/cmd_doc.c b/common/cmd_doc.c index 9d5b3001cc9..a55ca41d902 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -14,6 +14,11 @@ #include #include +/* + * ! BROKEN ! + * + * TODO: must be implemented and tested by someone with HW + */ #if 0 #ifdef CFG_DOC_SUPPORT_2000 #define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k) diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 339d82b5da5..8b359e01779 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -54,13 +54,9 @@ static int nand_dump(nand_info_t *nand, ulong off) return 1; } 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 %08lx\n", i, off); free(buf); @@ -199,7 +195,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, @@ -226,11 +222,11 @@ 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 */ @@ -257,7 +253,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) 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 = !strcmp("clean", argv[2]); + int clean = argc > 2 && !strcmp("clean", argv[2]); int o = clean ? 3 : 2; int scrub = !strcmp(cmd, "scrub"); @@ -267,7 +263,6 @@ 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; @@ -331,7 +326,7 @@ 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; @@ -340,7 +335,13 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) opts.length = size; opts.offset = off; opts.quiet = quiet; -/* ret = nand_read_opts(nand, &opts); */ +/* + * ! BROKEN ! + * + * TODO: Function must be implemented + * + * ret = nand_read_opts(nand, &opts); + */ } else { /* write */ mtd_oob_ops_t opts; @@ -404,12 +405,17 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (!strcmp("status", argv[2])) status = 1; } - +/* + * ! BROKEN ! + * + * TODO: must be implemented and tested by someone with HW + */ +#if 0 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); @@ -418,37 +424,34 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) "NOT " : "")); 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->writesize - || (s != last_status && off != 0)) { + || (s != last_status && off != 0)) { printf("%08lx - %08lx: %8d pages %s%s%s\n", - 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 " : "")); + 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 } +#endif return 0; } @@ -456,12 +459,17 @@ 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 */ +/* + * ! BROKEN ! + * + * TODO: must be implemented and tested by someone with HW + */ +#if 0 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 @@ -542,6 +550,7 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, puts ("** Unknown image type\n"); return 1; } + show_boot_progress (57); r = nand_read(nand, offset, &cnt, (u_char *) addr); if (r) { @@ -697,10 +706,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 @@ -715,7 +724,7 @@ 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 @@ -732,13 +741,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); @@ -873,7 +882,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) { @@ -887,8 +896,7 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) ret = nand_legacy_rw (nand_dev_desc + curr_device, cmd, off, size, - &total, - (u_char *) addr); + &total, (u_char *) addr); printf (" %d bytes %s: %s\n", total, (cmd & NANDRW_READ) ? "read" : "written", @@ -923,15 +931,15 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } U_BOOT_CMD( - nand, 5, 1, do_nand, + 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" @@ -987,7 +995,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; @@ -1072,7 +1080,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" ); -- cgit v1.3.1 From 90ef117b68387d66763291af0117677644166611 Mon Sep 17 00:00:00 2001 From: William Juul Date: Thu, 15 Nov 2007 12:23:57 +0100 Subject: Incorporate yaffs2 into U-boot To use YAFFS2 define CONFIG_YAFFS2 Signed-off-by: William Juul Signed-off-by: Scott Wood --- Makefile | 3 +- common/Makefile | 1 + common/cmd_yaffs2.c | 215 +++++++++++++++++++++++++++ fs/Makefile | 2 +- fs/yaffs2/devextras.h | 13 +- fs/yaffs2/direct/Makefile | 58 ++++---- fs/yaffs2/direct/dtest.c | 2 + fs/yaffs2/direct/yaffs_fileem.c | 5 +- fs/yaffs2/direct/yaffs_fileem2k.c | 4 +- fs/yaffs2/direct/yaffs_flashif.c | 3 +- fs/yaffs2/direct/yaffs_malloc.h | 5 +- fs/yaffs2/direct/yaffs_ramdisk.c | 5 +- fs/yaffs2/direct/yaffs_ramem2k.c | 3 +- fs/yaffs2/direct/yaffscfg.c | 303 ++++++++++++++++++++++++++++++++++++-- fs/yaffs2/direct/yaffscfg.h | 1 + fs/yaffs2/direct/yaffscfg2k.c | 4 +- fs/yaffs2/direct/yaffsfs.c | 15 +- fs/yaffs2/direct/ydirectenv.h | 8 +- fs/yaffs2/yaffs_checkptrw.c | 7 +- fs/yaffs2/yaffs_ecc.c | 4 +- fs/yaffs2/yaffs_guts.c | 27 +++- fs/yaffs2/yaffs_guts.h | 26 ++-- fs/yaffs2/yaffs_mtdif.c | 7 +- fs/yaffs2/yaffs_mtdif2.c | 5 +- fs/yaffs2/yaffs_nand.c | 6 +- fs/yaffs2/yaffs_packedtags1.c | 3 + fs/yaffs2/yaffs_packedtags2.c | 3 + fs/yaffs2/yaffs_qsort.c | 3 + fs/yaffs2/yaffs_tagscompat.c | 3 + fs/yaffs2/yaffs_tagsvalidity.c | 3 + fs/yaffs2/yportenv.h | 8 +- 31 files changed, 666 insertions(+), 89 deletions(-) create mode 100644 common/cmd_yaffs2.c (limited to 'common') diff --git a/Makefile b/Makefile index 082b08e2c4c..b2048847c6e 100644 --- a/Makefile +++ b/Makefile @@ -210,7 +210,7 @@ LIBS += cpu/ixp/npe/libnpe.a endif LIBS += lib_$(ARCH)/lib$(ARCH).a LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \ - fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a + fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a fs/yaffs2/direct/libyaffs2.a LIBS += net/libnet.a LIBS += disk/libdisk.a LIBS += drivers/bios_emulator/libatibiosemu.a @@ -378,6 +378,7 @@ TAG_SUBDIRS += fs/cramfs TAG_SUBDIRS += fs/fat TAG_SUBDIRS += fs/fdos TAG_SUBDIRS += fs/jffs2 +TAG_SUBDIRS += fs/yaffs2/direct TAG_SUBDIRS += net TAG_SUBDIRS += disk TAG_SUBDIRS += common diff --git a/common/Makefile b/common/Makefile index 42871087a48..ecf755f3f2b 100644 --- a/common/Makefile +++ b/common/Makefile @@ -98,6 +98,7 @@ COBJS-$(CONFIG_CMD_TERMINAL) += cmd_terminal.o COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o COBJS-$(CONFIG_CMD_USB) += cmd_usb.o COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o +COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o COBJS-y += cmd_vfd.o COBJS-y += command.o COBJS-y += console.o diff --git a/common/cmd_yaffs2.c b/common/cmd_yaffs2.c new file mode 100644 index 00000000000..ac4a518b397 --- /dev/null +++ b/common/cmd_yaffs2.c @@ -0,0 +1,215 @@ +#include + +#include +#include + +#ifdef YAFFS2_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +extern void cmd_yaffs_mount(char *mp); +extern void cmd_yaffs_umount(char *mp); +extern void cmd_yaffs_read_file(char *fn); +extern void cmd_yaffs_write_file(char *fn,char bval,int sizeOfFile); +extern void cmd_yaffs_ls(const char *mountpt, int longlist); +extern void cmd_yaffs_mwrite_file(char *fn, char *addr, int size); +extern void cmd_yaffs_mread_file(char *fn, char *addr); +extern void cmd_yaffs_mkdir(const char *dir); +extern void cmd_yaffs_rmdir(const char *dir); +extern void cmd_yaffs_rm(const char *path); +extern void cmd_yaffs_mv(const char *oldPath, const char *newPath); + +extern int yaffs_DumpDevStruct(const char *path); + + +int do_ymount (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + char *mtpoint = argv[1]; + cmd_yaffs_mount(mtpoint); + + return(0); +} + +int do_yumount (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + char *mtpoint = argv[1]; + cmd_yaffs_umount(mtpoint); + + return(0); +} + +int do_yls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + char *dirname = argv[argc-1]; + + cmd_yaffs_ls(dirname, (argc>2)?1:0); + + return(0); +} + +int do_yrd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + char *filename = argv[1]; + printf ("Reading file %s ", filename); + + cmd_yaffs_read_file(filename); + + printf ("done\n"); + return(0); +} + +int do_ywr (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + char *filename = argv[1]; + ulong value = simple_strtoul(argv[2], NULL, 16); + ulong numValues = simple_strtoul(argv[3], NULL, 16); + + printf ("Writing value (%x) %x times to %s... ", value, numValues, filename); + + cmd_yaffs_write_file(filename,value,numValues); + + printf ("done\n"); + return(0); +} + +int do_yrdm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + char *filename = argv[1]; + ulong addr = simple_strtoul(argv[2], NULL, 16); + + cmd_yaffs_mread_file(filename, (char *)addr); + + return(0); +} + +int do_ywrm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + char *filename = argv[1]; + ulong addr = simple_strtoul(argv[2], NULL, 16); + ulong size = simple_strtoul(argv[3], NULL, 16); + + cmd_yaffs_mwrite_file(filename, (char *)addr, size); + + return(0); +} + +int do_ymkdir (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + char *dirname = argv[1]; + + cmd_yaffs_mkdir(dirname); + + return(0); +} + +int do_yrmdir (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + char *dirname = argv[1]; + + cmd_yaffs_rmdir(dirname); + + return(0); +} + +int do_yrm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + char *path = argv[1]; + + cmd_yaffs_rm(path); + + return(0); +} + +int do_ymv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + char *oldPath = argv[1]; + char *newPath = argv[2]; + + cmd_yaffs_mv(newPath, oldPath); + + return(0); +} + +int do_ydump (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + char *dirname = argv[1]; + if (yaffs_DumpDevStruct(dirname) != 0) + printf("yaffs_DumpDevStruct returning error when dumping path: , %s\n", dirname); + return 0; +} + + + +U_BOOT_CMD( + ymount, 3, 0, do_ymount, + "ymount\t- mount yaffs\n", + "\n" +); + +U_BOOT_CMD( + yumount, 3, 0, do_yumount, + "yumount\t- unmount yaffs\n", + "\n" +); + +U_BOOT_CMD( + yls, 4, 0, do_yls, + "yls\t- yaffs ls\n", + "[-l] name\n" +); + +U_BOOT_CMD( + yrd, 2, 0, do_yrd, + "yrd\t- read file from yaffs\n", + "filename\n" +); + +U_BOOT_CMD( + ywr, 4, 0, do_ywr, + "ywr\t- write file to yaffs\n", + "filename value num_vlues\n" +); + +U_BOOT_CMD( + yrdm, 3, 0, do_yrdm, + "yrdm\t- read file to memory from yaffs\n", + "filename offset\n" +); + +U_BOOT_CMD( + ywrm, 4, 0, do_ywrm, + "ywrm\t- write file from memory to yaffs\n", + "filename offset size\n" +); + +U_BOOT_CMD( + ymkdir, 2, 0, do_ymkdir, + "ymkdir\t- YAFFS mkdir\n", + "dirname\n" +); + +U_BOOT_CMD( + yrmdir, 2, 0, do_yrmdir, + "yrmdir\t- YAFFS rmdir\n", + "dirname\n" +); + +U_BOOT_CMD( + yrm, 2, 0, do_yrm, + "yrm\t- YAFFS rm\n", + "path\n" +); + +U_BOOT_CMD( + ymv, 4, 0, do_ymv, + "ymv\t- YAFFS mv\n", + "oldPath newPath\n" +); + +U_BOOT_CMD( + ydump, 2, 0, do_ydump, + "ydump\t- YAFFS device struct\n", + "dirname\n" +); diff --git a/fs/Makefile b/fs/Makefile index 273d90e011b..48cf1d2c3a8 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -22,7 +22,7 @@ # # -SUBDIRS := jffs2 cramfs fdos fat reiserfs ext2 +SUBDIRS := jffs2 cramfs fdos fat reiserfs ext2 yaffs2/direct $(obj).depend all: @for dir in $(SUBDIRS) ; do \ diff --git a/fs/yaffs2/devextras.h b/fs/yaffs2/devextras.h index 9635c7a7381..9acda79e860 100644 --- a/fs/yaffs2/devextras.h +++ b/fs/yaffs2/devextras.h @@ -28,13 +28,19 @@ #define new newHack #endif -#if !(defined __KERNEL__) || (defined WIN32) +/* XXX U-BOOT XXX */ +#if 1 /* !(defined __KERNEL__) || (defined WIN32) */ /* User space defines */ +/* XXX U-BOOT XXX */ +#if 0 typedef unsigned char __u8; typedef unsigned short __u16; typedef unsigned __u32; +#endif + +#include /* * Simple doubly linked list implementation. @@ -213,7 +219,12 @@ static __inline__ void list_splice(struct list_head *list, #define DT_WHT 14 #ifndef WIN32 +/* XXX U-BOOT XXX */ +#if 0 #include +#else +#include "common.h" +#endif #endif /* diff --git a/fs/yaffs2/direct/Makefile b/fs/yaffs2/direct/Makefile index 6315117cdf2..0ee18e5c8a0 100644 --- a/fs/yaffs2/direct/Makefile +++ b/fs/yaffs2/direct/Makefile @@ -17,50 +17,46 @@ # $Id: Makefile,v 1.15 2007/07/18 19:40:38 charles Exp $ #EXTRA_COMPILE_FLAGS = -DYAFFS_IGNORE_TAGS_ECC +include $(TOPDIR)/config.mk -CFLAGS = -Wall -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_YAFFS2 -g $(EXTRA_COMPILE_FLAGS) -DNO_Y_INLINE -CFLAGS+= -fstack-check -O0 +LIB = $(obj)libyaffs2.a -#CFLAGS+= -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations -#CFLAGS+= -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline +COBJS-$(CONFIG_YAFFS2) := \ + yaffscfg.o yaffs_ecc.o yaffsfs.o yaffs_guts.o yaffs_packedtags1.o \ + yaffs_tagscompat.o yaffs_packedtags2.o yaffs_tagsvalidity.o \ + yaffs_nand.o yaffs_checkptrw.o yaffs_qsort.o yaffs_mtdif.o \ + yaffs_mtdif2.o - -DIRECTTESTOBJS = dtest.o yaffscfg2k.o yaffs_ecc.o yaffs_fileem2k.o yaffsfs.o yaffs_guts.o \ - yaffs_packedtags1.o yaffs_ramdisk.o yaffs_ramem2k.o \ - yaffs_tagscompat.o yaffs_packedtags2.o yaffs_tagsvalidity.o yaffs_nand.o \ - yaffs_checkptrw.o yaffs_qsort.o \ -# yaffs_checkptrwtest.o\ - - -BOOTTESTOBJS = bootldtst.o yboot.o yaffs_fileem.o nand_ecc.o - -#ALLOBJS = dtest.o nand_ecc.o yaffscfg.o yaffs_fileem.o yaffsfs.o yaffs_ramdisk.o bootldtst.o yboot.o yaffs_ramem2k.o - -ALLOBJS = $(DIRECTTESTOBJS) $(BOOTTESTOBJS) +SRCS := $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) SYMLINKS = devextras.h yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h yaffsinterface.h yportenv.h yaffs_tagscompat.c yaffs_tagscompat.h \ yaffs_packedtags1.c yaffs_packedtags1.h yaffs_packedtags2.c yaffs_packedtags2.h yaffs_nandemul2k.h \ - yaffs_nand.c yaffs_nand.h \ + yaffs_nand.c yaffs_nand.h yaffs_mtdif.c yaffs_mtdif.h \ yaffs_tagsvalidity.c yaffs_tagsvalidity.h yaffs_checkptrw.h yaffs_checkptrw.c \ - yaffs_qsort.c yaffs_qsort.h + yaffs_qsort.c yaffs_qsort.h yaffs_mtdif2.c yaffs_mtdif2.h -#all: directtest2k boottest +# -DCONFIG_YAFFS_NO_YAFFS1 +CFLAGS += -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_YAFFS2 -DNO_Y_INLINE -DLINUX_VERSION_CODE=0x20616 -all: directtest2k +all: $(LIB) -$(ALLOBJS): %.o: %.c - gcc -c $(CFLAGS) $< -o $@ +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) -$(SYMLINKS): - ln -s ../$@ $@ +.PHONY: clean distclean +clean: + rm -f $(OBJS) -directtest2k: $(SYMLINKS) $(DIRECTTESTOBJS) - gcc -o $@ $(DIRECTTESTOBJS) +distclean: clean + rm -f $(LIB) core *.bak .depend +######################################################################### -boottest: $(SYMLINKS) $(BOOTTESTOBJS) - gcc -o $@ $(BOOTTESTOBJS) +# defines $(obj).depend target +include $(SRCTREE)/rules.mk +sinclude $(obj).depend + +######################################################################### -clean: - rm -f $(ALLOBJS) core diff --git a/fs/yaffs2/direct/dtest.c b/fs/yaffs2/direct/dtest.c index be492b47c9a..a9156ca1908 100644 --- a/fs/yaffs2/direct/dtest.c +++ b/fs/yaffs2/direct/dtest.c @@ -15,6 +15,8 @@ * Test code for the "direct" interface. */ +/* XXX U-BOOT XXX */ +#include #include #include diff --git a/fs/yaffs2/direct/yaffs_fileem.c b/fs/yaffs2/direct/yaffs_fileem.c index e3cc30eb8a6..5779d7ebc35 100644 --- a/fs/yaffs2/direct/yaffs_fileem.c +++ b/fs/yaffs2/direct/yaffs_fileem.c @@ -16,6 +16,9 @@ * This is only intended as test code to test persistence etc. */ +/* XXX U-BOOT XXX */ +#include + const char *yaffs_flashif_c_version = "$Id: yaffs_fileem.c,v 1.3 2007/02/14 01:09:06 wookey Exp $"; @@ -214,5 +217,3 @@ int yflash_InitialiseNAND(yaffs_Device *dev) return YAFFS_OK; } - - diff --git a/fs/yaffs2/direct/yaffs_fileem2k.c b/fs/yaffs2/direct/yaffs_fileem2k.c index 7a3b2999963..34a4e87b3dc 100644 --- a/fs/yaffs2/direct/yaffs_fileem2k.c +++ b/fs/yaffs2/direct/yaffs_fileem2k.c @@ -16,6 +16,9 @@ * This is only intended as test code to test persistence etc. */ +/* XXX U-BOOT XXX */ +#include + const char *yaffs_flashif_c_version = "$Id: yaffs_fileem2k.c,v 1.12 2007/02/14 01:09:06 wookey Exp $"; @@ -438,4 +441,3 @@ int yflash_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_Blo } return YAFFS_OK; } - diff --git a/fs/yaffs2/direct/yaffs_flashif.c b/fs/yaffs2/direct/yaffs_flashif.c index 5178cb2ac3b..8d51dc6af7f 100644 --- a/fs/yaffs2/direct/yaffs_flashif.c +++ b/fs/yaffs2/direct/yaffs_flashif.c @@ -11,6 +11,8 @@ * published by the Free Software Foundation. */ +/* XXX U-BOOT XXX */ +#include const char *yaffs_flashif_c_version = "$Id: yaffs_flashif.c,v 1.3 2007/02/14 01:09:06 wookey Exp $"; @@ -226,4 +228,3 @@ int yflash_InitialiseNAND(yaffs_Device *dev) { return YAFFS_OK; } - diff --git a/fs/yaffs2/direct/yaffs_malloc.h b/fs/yaffs2/direct/yaffs_malloc.h index 245f9c96340..122fb4c06f8 100644 --- a/fs/yaffs2/direct/yaffs_malloc.h +++ b/fs/yaffs2/direct/yaffs_malloc.h @@ -14,8 +14,11 @@ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. */ +/* XXX U-BOOT XXX */ +#if 0 #include - +#endif + void *yaffs_malloc(size_t size); void yaffs_free(void *ptr); diff --git a/fs/yaffs2/direct/yaffs_ramdisk.c b/fs/yaffs2/direct/yaffs_ramdisk.c index 6afee81f4cb..57f27ce07c0 100644 --- a/fs/yaffs2/direct/yaffs_ramdisk.c +++ b/fs/yaffs2/direct/yaffs_ramdisk.c @@ -18,6 +18,9 @@ * Use this with dev->useNANDECC enabled, then ECC overheads are not required. */ +/* XXX U-BOOT XXX */ +#include + const char *yaffs_ramdisk_c_version = "$Id: yaffs_ramdisk.c,v 1.4 2007/02/14 01:09:06 wookey Exp $"; @@ -230,5 +233,3 @@ int yramdisk_InitialiseNAND(yaffs_Device *dev) return YAFFS_OK; } - - diff --git a/fs/yaffs2/direct/yaffs_ramem2k.c b/fs/yaffs2/direct/yaffs_ramem2k.c index 1ab053c4673..81617892801 100644 --- a/fs/yaffs2/direct/yaffs_ramem2k.c +++ b/fs/yaffs2/direct/yaffs_ramem2k.c @@ -15,6 +15,8 @@ * yaffs_ramem2k.c: RAM emulation in-kernel for 2K pages (YAFFS2) */ +/* XXX U-BOOT XXX */ +#include const char *yaffs_ramem2k_c_version = "$Id: yaffs_ramem2k.c,v 1.3 2007/02/14 01:09:06 wookey Exp $"; @@ -360,4 +362,3 @@ int nandemul2k_GetNumberOfBlocks(void) {return nandemul2k_CalcNBlocks();} #endif //YAFFS_RAM_ENABLED - diff --git a/fs/yaffs2/direct/yaffscfg.c b/fs/yaffs2/direct/yaffscfg.c index b1d311e5693..a4a0924ef91 100644 --- a/fs/yaffs2/direct/yaffscfg.c +++ b/fs/yaffs2/direct/yaffscfg.c @@ -18,17 +18,34 @@ * There is no need to redistribute this file. */ +/* XXX U-BOOT XXX */ +#include + +#include +#include "nand.h" #include "yaffscfg.h" #include "yaffsfs.h" +#include "yaffs_packedtags2.h" +#include "yaffs_mtdif.h" +#include "yaffs_mtdif2.h" +#if 0 #include +#else +#include "malloc.h" +#endif unsigned yaffs_traceMask = 0xFFFFFFFF; - +static int yaffs_errno = 0; void yaffsfs_SetError(int err) { //Do whatever to set error - errno = err; + yaffs_errno = err; +} + +int yaffsfs_GetError(void) +{ + return yaffs_errno; } void yaffsfs_Lock(void) @@ -71,27 +88,47 @@ void yaffsfs_LocalInitialisation(void) #include "yaffs_ramdisk.h" #include "yaffs_flashif.h" +static int isMounted = 0; +#define MOUNT_POINT "/flash" +extern nand_info_t nand_info[]; + +/* XXX U-BOOT XXX */ +#if 0 static yaffs_Device ramDev; static yaffs_Device bootDev; static yaffs_Device flashDev; +#endif static yaffsfs_DeviceConfiguration yaffsfs_config[] = { - +/* XXX U-BOOT XXX */ +#if 0 { "/ram", &ramDev}, { "/boot", &bootDev}, { "/flash", &flashDev}, +#else + { MOUNT_POINT, 0}, +#endif {(void *)0,(void *)0} }; int yaffs_StartUp(void) { + struct mtd_info *mtd = &nand_info[0]; + int yaffsVersion = 2; + int nBlocks; + + yaffs_Device *flashDev = calloc(1, sizeof(yaffs_Device)); + yaffsfs_config[0].dev = flashDev; + // Stuff to configure YAFFS // Stuff to initialise anything special (eg lock semaphore). yaffsfs_LocalInitialisation(); // Set up devices +/* XXX U-BOOT XXX */ +#if 0 // /ram ramDev.nBytesPerChunk = 512; ramDev.nChunksPerBlock = 32; @@ -119,20 +156,50 @@ int yaffs_StartUp(void) bootDev.readChunkFromNAND = yflash_ReadChunkFromNAND; bootDev.eraseBlockInNAND = yflash_EraseBlockInNAND; bootDev.initialiseNAND = yflash_InitialiseNAND; +#endif // /flash - flashDev.nBytesPerChunk = 512; - flashDev.nChunksPerBlock = 32; - flashDev.nReservedBlocks = 5; - flashDev.startBlock = 128; // First block after 2MB - flashDev.endBlock = 1023; // Last block in 16MB - flashDev.useNANDECC = 0; // use YAFFS's ECC - flashDev.nShortOpCaches = 10; // Use caches - flashDev.genericDevice = (void *) 2; // Used to identify the device in fstat. - flashDev.writeChunkToNAND = yflash_WriteChunkToNAND; - flashDev.readChunkFromNAND = yflash_ReadChunkFromNAND; - flashDev.eraseBlockInNAND = yflash_EraseBlockInNAND; - flashDev.initialiseNAND = yflash_InitialiseNAND; + flashDev->nReservedBlocks = 5; +// flashDev->nShortOpCaches = (options.no_cache) ? 0 : 10; + flashDev->nShortOpCaches = 10; // Use caches + flashDev->useNANDECC = 0; // do not use YAFFS's ECC + + if (yaffsVersion == 2) + { + flashDev->writeChunkWithTagsToNAND = nandmtd2_WriteChunkWithTagsToNAND; + flashDev->readChunkWithTagsFromNAND = nandmtd2_ReadChunkWithTagsFromNAND; + flashDev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad; + flashDev->queryNANDBlock = nandmtd2_QueryNANDBlock; + flashDev->spareBuffer = YMALLOC(mtd->oobsize); + flashDev->isYaffs2 = 1; +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) + flashDev->nDataBytesPerChunk = mtd->writesize; + flashDev->nChunksPerBlock = mtd->erasesize / mtd->writesize; +#else + flashDev->nDataBytesPerChunk = mtd->oobblock; + flashDev->nChunksPerBlock = mtd->erasesize / mtd->oobblock; +#endif + nBlocks = mtd->size / mtd->erasesize; + + flashDev->nCheckpointReservedBlocks = 10; + flashDev->startBlock = 0; + flashDev->endBlock = nBlocks - 1; + } + else + { + flashDev->writeChunkToNAND = nandmtd_WriteChunkToNAND; + flashDev->readChunkFromNAND = nandmtd_ReadChunkFromNAND; + flashDev->isYaffs2 = 0; + nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK); + flashDev->startBlock = 320; + flashDev->endBlock = nBlocks - 1; + flashDev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK; + flashDev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK; + } + + /* ... and common functions */ + flashDev->eraseBlockInNAND = nandmtd_EraseBlockInNAND; + flashDev->initialiseNAND = nandmtd_InitialiseNAND; yaffs_initialise(yaffsfs_config); @@ -140,5 +207,211 @@ int yaffs_StartUp(void) } +void make_a_file(char *yaffsName,char bval,int sizeOfFile) +{ + int outh; + int i; + unsigned char buffer[100]; + + outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE); + if (outh < 0) + { + printf("Error opening file: %d\n", outh); + return; + } + + memset(buffer,bval,100); + + do{ + i = sizeOfFile; + if(i > 100) i = 100; + sizeOfFile -= i; + + yaffs_write(outh,buffer,i); + + } while (sizeOfFile > 0); + + + yaffs_close(outh); +} + +void read_a_file(char *fn) +{ + int h; + int i = 0; + unsigned char b; + + h = yaffs_open(fn, O_RDWR,0); + if(h<0) + { + printf("File not found\n"); + return; + } + + while(yaffs_read(h,&b,1)> 0) + { + printf("%02x ",b); + i++; + if(i > 32) + { + printf("\n"); + i = 0;; + } + } + printf("\n"); + yaffs_close(h); +} + +void cmd_yaffs_mount(char *mp) +{ + yaffs_StartUp(); + int retval = yaffs_mount(mp); + if( retval != -1) + isMounted = 1; + else + printf("Error mounting %s, return value: %d\n", mp, yaffsfs_GetError()); +} + +static void checkMount(void) +{ + if( !isMounted ) + { + cmd_yaffs_mount(MOUNT_POINT); + } +} + +void cmd_yaffs_umount(char *mp) +{ + checkMount(); + if( yaffs_unmount(mp) == -1) + printf("Error umounting %s, return value: %d\n", mp, yaffsfs_GetError()); +} + +void cmd_yaffs_write_file(char *yaffsName,char bval,int sizeOfFile) +{ + checkMount(); + make_a_file(yaffsName,bval,sizeOfFile); +} +void cmd_yaffs_read_file(char *fn) +{ + checkMount(); + read_a_file(fn); +} + + +void cmd_yaffs_mread_file(char *fn, char *addr) +{ + int h; + struct yaffs_stat s; + + checkMount(); + + yaffs_stat(fn,&s); + + printf ("Copy %s to 0x%08x... ", fn, addr); + h = yaffs_open(fn, O_RDWR,0); + if(h<0) + { + printf("File not found\n"); + return; + } + + yaffs_read(h,addr,(int)s.st_size); + printf("\t[DONE]\n"); + + yaffs_close(h); +} + + +void cmd_yaffs_mwrite_file(char *fn, char *addr, int size) +{ + int outh; + + checkMount(); + outh = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE); + if (outh < 0) + { + printf("Error opening file: %d\n", outh); + } + + yaffs_write(outh,addr,size); + + yaffs_close(outh); +} + + +void cmd_yaffs_ls(const char *mountpt, int longlist) +{ + int i; + yaffs_DIR *d; + yaffs_dirent *de; + struct yaffs_stat stat; + char tempstr[255]; + + checkMount(); + d = yaffs_opendir(mountpt); + + if(!d) + { + printf("opendir failed\n"); + } + else + { + for(i = 0; (de = yaffs_readdir(d)) != NULL; i++) + { + if (longlist) + { + sprintf(tempstr, "%s/%s", mountpt, de->d_name); + yaffs_stat(tempstr, &stat); + printf("%-25s\t%7d\n",de->d_name, stat.st_size); + } + else + { + printf("%s\n",de->d_name); + } + } + } +} + + +void cmd_yaffs_mkdir(const char *dir) +{ + checkMount(); + + int retval = yaffs_mkdir(dir, 0); + + if ( retval < 0) + printf("yaffs_mkdir returning error: %d\n", retval); +} + +void cmd_yaffs_rmdir(const char *dir) +{ + checkMount(); + + int retval = yaffs_rmdir(dir); + + if ( retval < 0) + printf("yaffs_rmdir returning error: %d\n", retval); +} + +void cmd_yaffs_rm(const char *path) +{ + checkMount(); + + int retval = yaffs_unlink(path); + + if ( retval < 0) + printf("yaffs_unlink returning error: %d\n", retval); +} + +void cmd_yaffs_mv(const char *oldPath, const char *newPath) +{ + checkMount(); + + int retval = yaffs_rename(newPath, oldPath); + + if ( retval < 0) + printf("yaffs_unlink returning error: %d\n", retval); +} diff --git a/fs/yaffs2/direct/yaffscfg.h b/fs/yaffs2/direct/yaffscfg.h index 2a60dc132cb..6ae169612b8 100644 --- a/fs/yaffs2/direct/yaffscfg.h +++ b/fs/yaffs2/direct/yaffscfg.h @@ -40,6 +40,7 @@ void yaffsfs_Unlock(void); __u32 yaffsfs_CurrentTime(void); void yaffsfs_SetError(int err); +int yaffsfs_GetError(void); #endif diff --git a/fs/yaffs2/direct/yaffscfg2k.c b/fs/yaffs2/direct/yaffscfg2k.c index 6d5f542fc4b..1daede181e3 100644 --- a/fs/yaffs2/direct/yaffscfg2k.c +++ b/fs/yaffs2/direct/yaffscfg2k.c @@ -18,6 +18,9 @@ * There is no need to redistribute this file. */ +/* XXX U-BOOT XXX */ +#include + #include "yaffscfg.h" #include "yaffsfs.h" #include "yaffs_fileem2k.h" @@ -226,4 +229,3 @@ void SetCheckpointReservedBlocks(int n) { flashDev.nCheckpointReservedBlocks = n; } - diff --git a/fs/yaffs2/direct/yaffsfs.c b/fs/yaffs2/direct/yaffsfs.c index a8519c28e71..f62c952ddcc 100644 --- a/fs/yaffs2/direct/yaffsfs.c +++ b/fs/yaffs2/direct/yaffsfs.c @@ -11,12 +11,20 @@ * published by the Free Software Foundation. */ +/* XXX U-BOOT XXX */ +#include +#include + #include "yaffsfs.h" #include "yaffs_guts.h" #include "yaffscfg.h" -#include // for memset #include "yportenv.h" +/* XXX U-BOOT XXX */ +#if 0 +#include // for memset +#endif + #define YAFFSFS_MAX_SYMLINK_DEREFERENCES 5 #ifndef NULL @@ -925,7 +933,7 @@ int yaffs_fstat(int fd, struct yaffs_stat *buf) static int yaffsfs_DoChMod(yaffs_Object *obj,mode_t mode) { - int result; + int result = YAFFS_FAIL; if(obj) { @@ -1158,8 +1166,6 @@ void yaffs_initialise(yaffsfs_DeviceConfiguration *cfgList) cfg->dev->removeObjectCallback = yaffsfs_RemoveObjectCallback; cfg++; } - - } @@ -1502,4 +1508,3 @@ int yaffs_DumpDevStruct(const char *path) } return 0; } - diff --git a/fs/yaffs2/direct/ydirectenv.h b/fs/yaffs2/direct/ydirectenv.h index 0c2820579ea..adcc0b54685 100644 --- a/fs/yaffs2/direct/ydirectenv.h +++ b/fs/yaffs2/direct/ydirectenv.h @@ -24,13 +24,19 @@ #include "devextras.h" +/* XXX U-BOOT XXX */ +#if 0 #include "stdlib.h" #include "stdio.h" #include "string.h" +#include "assert.h" +#endif #include "yaffs_malloc.h" -#include "assert.h" +/* XXX U-BOOT XXX */ +#if 0 #define YBUG() assert(1) +#endif #define YCHAR char #define YUCHAR unsigned char diff --git a/fs/yaffs2/yaffs_checkptrw.c b/fs/yaffs2/yaffs_checkptrw.c index d3a811e2774..f97ba4b4272 100644 --- a/fs/yaffs2/yaffs_checkptrw.c +++ b/fs/yaffs2/yaffs_checkptrw.c @@ -11,6 +11,10 @@ * published by the Free Software Foundation. */ +/* XXX U-BOOT XXX */ +#include +#include + const char *yaffs_checkptrw_c_version = "$Id: yaffs_checkptrw.c,v 1.14 2007/05/15 20:07:40 charles Exp $"; @@ -399,6 +403,3 @@ int yaffs_CheckpointInvalidateStream(yaffs_Device *dev) return yaffs_CheckpointErase(dev); } - - - diff --git a/fs/yaffs2/yaffs_ecc.c b/fs/yaffs2/yaffs_ecc.c index d0b405f1eea..a05a6b583b6 100644 --- a/fs/yaffs2/yaffs_ecc.c +++ b/fs/yaffs2/yaffs_ecc.c @@ -28,6 +28,9 @@ * this bytes influence on the line parity. */ +/* XXX U-BOOT XXX */ +#include + const char *yaffs_ecc_c_version = "$Id: yaffs_ecc.c,v 1.9 2007/02/14 01:09:06 wookey Exp $"; @@ -328,4 +331,3 @@ int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes, return -1; } - diff --git a/fs/yaffs2/yaffs_guts.c b/fs/yaffs2/yaffs_guts.c index 134ed018ad8..7dc62ef4d99 100644 --- a/fs/yaffs2/yaffs_guts.c +++ b/fs/yaffs2/yaffs_guts.c @@ -11,12 +11,17 @@ * published by the Free Software Foundation. */ +/* XXX U-BOOT XXX */ +#include + const char *yaffs_guts_c_version = "$Id: yaffs_guts.c,v 1.52 2007/10/16 00:45:05 charles Exp $"; #include "yportenv.h" +#include "linux/stat.h" #include "yaffsinterface.h" +#include "yaffsfs.h" #include "yaffs_guts.h" #include "yaffs_tagsvalidity.h" @@ -31,6 +36,7 @@ const char *yaffs_guts_c_version = #include "yaffs_nand.h" #include "yaffs_packedtags2.h" +#include "malloc.h" #ifdef CONFIG_YAFFS_WINCE void yfsd_LockYAFFS(BOOL fsLockOnly); @@ -597,7 +603,6 @@ static int yaffs_VerifyTnodeWorker(yaffs_Object * obj, yaffs_Tnode * tn, int i; yaffs_Device *dev = obj->myDev; int ok = 1; - int nTnodeBytes = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8; if (tn) { if (level > 0) { @@ -646,7 +651,6 @@ static void yaffs_VerifyFile(yaffs_Object *obj) __u32 lastChunk; __u32 x; __u32 i; - int ok; yaffs_Device *dev; yaffs_ExtendedTags tags; yaffs_Tnode *tn; @@ -854,7 +858,10 @@ static void yaffs_VerifyObjects(yaffs_Device *dev) static Y_INLINE int yaffs_HashFunction(int n) { - n = abs(n); +/* XXX U-BOOT XXX */ + /*n = abs(n); */ + if (n < 0) + n = -n; return (n % YAFFS_NOBJECT_BUCKETS); } @@ -1954,6 +1961,8 @@ static void yaffs_FreeObject(yaffs_Object * tn) yaffs_Device *dev = tn->myDev; +/* XXX U-BOOT XXX */ +#if 0 #ifdef __KERNEL__ if (tn->myInode) { /* We're still hooked up to a cached inode. @@ -1963,7 +1972,7 @@ static void yaffs_FreeObject(yaffs_Object * tn) return; } #endif - +#endif yaffs_UnhashObject(tn); /* Link into the free list. */ @@ -1972,6 +1981,8 @@ static void yaffs_FreeObject(yaffs_Object * tn) dev->nFreeObjects++; } +/* XXX U-BOOT XXX */ +#if 0 #ifdef __KERNEL__ void yaffs_HandleDeferedFree(yaffs_Object * obj) @@ -1981,6 +1992,7 @@ void yaffs_HandleDeferedFree(yaffs_Object * obj) } } +#endif #endif static void yaffs_DeinitialiseObjects(yaffs_Device * dev) @@ -2107,12 +2119,14 @@ yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device * dev, __u32 number) if (i) { in = list_entry(i, yaffs_Object, hashLink); if (in->objectId == number) { +/* XXX U-BOOT XXX */ +#if 0 #ifdef __KERNEL__ /* Don't tell the VFS about this one if it is defered free */ if (in->deferedFree) return NULL; #endif - +#endif return in; } } @@ -5085,11 +5099,14 @@ static int yaffs_UnlinkFile(yaffs_Object * in) int immediateDeletion = 0; if (1) { +/* XXX U-BOOT XXX */ +#if 0 #ifdef __KERNEL__ if (!in->myInode) { immediateDeletion = 1; } +#endif #else if (in->inUse <= 0) { immediateDeletion = 1; diff --git a/fs/yaffs2/yaffs_guts.h b/fs/yaffs2/yaffs_guts.h index 87b539b05b7..ecf701f5a08 100644 --- a/fs/yaffs2/yaffs_guts.h +++ b/fs/yaffs2/yaffs_guts.h @@ -446,9 +446,10 @@ struct yaffs_ObjectStruct { YCHAR shortName[YAFFS_SHORT_NAME_LENGTH + 1]; #endif -#ifndef __KERNEL__ +/* XXX U-BOOT XXX */ +/* #ifndef __KERNEL__ */ __u32 inUse; -#endif +/* #endif */ #ifdef CONFIG_YAFFS_WINCE __u32 win_ctime[2]; @@ -464,10 +465,10 @@ struct yaffs_ObjectStruct { __u32 yst_rdev; -#ifdef __KERNEL__ +/* XXX U-BOOT XXX */ +/* #ifndef __KERNEL__ */ struct inode *myInode; - -#endif +/* #endif */ yaffs_ObjectType variantType; @@ -626,15 +627,18 @@ struct yaffs_DeviceStruct { __u32 chunkMask; -#ifdef __KERNEL__ +/* XXX U-BOOT XXX */ +#if 0 +#ifndef __KERNEL__ struct semaphore sem; /* Semaphore for waiting on erasure.*/ struct semaphore grossLock; /* Gross locking semaphore */ + void (*putSuperFunc) (struct super_block * sb); +#endif +#endif __u8 *spareBuffer; /* For mtdif2 use. Don't know the size of the buffer * at compile time so we have to allocate it. */ - void (*putSuperFunc) (struct super_block * sb); -#endif int isMounted; @@ -883,10 +887,12 @@ yaffs_Object *yaffs_LostNFound(yaffs_Device * dev); void yfsd_WinFileTimeNow(__u32 target[2]); #endif -#ifdef __KERNEL__ - +/* XXX U-BOOT XXX */ +#if 0 +#ifndef __KERNEL__ void yaffs_HandleDeferedFree(yaffs_Object * obj); #endif +#endif /* Debug dump */ int yaffs_DumpObject(yaffs_Object * obj); diff --git a/fs/yaffs2/yaffs_mtdif.c b/fs/yaffs2/yaffs_mtdif.c index 031827e45be..407ef2b4e2c 100644 --- a/fs/yaffs2/yaffs_mtdif.c +++ b/fs/yaffs2/yaffs_mtdif.c @@ -11,6 +11,9 @@ * published by the Free Software Foundation. */ +/* XXX U-BOOT XXX */ +#include + const char *yaffs_mtdif_c_version = "$Id: yaffs_mtdif.c,v 1.19 2007/02/14 01:09:06 wookey Exp $"; @@ -224,7 +227,10 @@ int nandmtd_EraseBlockInNAND(yaffs_Device * dev, int blockNumber) /* Todo finish off the ei if required */ +/* XXX U-BOOT XXX */ +#if 0 sema_init(&dev->sem, 0); +#endif retval = mtd->erase(mtd, &ei); @@ -238,4 +244,3 @@ int nandmtd_InitialiseNAND(yaffs_Device * dev) { return YAFFS_OK; } - diff --git a/fs/yaffs2/yaffs_mtdif2.c b/fs/yaffs2/yaffs_mtdif2.c index 5a18725730c..cd2a2a15c76 100644 --- a/fs/yaffs2/yaffs_mtdif2.c +++ b/fs/yaffs2/yaffs_mtdif2.c @@ -13,6 +13,10 @@ /* mtd interface for YAFFS2 */ +/* XXX U-BOOT XXX */ +#include +#include "asm/errno.h" + const char *yaffs_mtdif2_c_version = "$Id: yaffs_mtdif2.c,v 1.17 2007/02/14 01:09:06 wookey Exp $"; @@ -229,4 +233,3 @@ int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, else return YAFFS_FAIL; } - diff --git a/fs/yaffs2/yaffs_nand.c b/fs/yaffs2/yaffs_nand.c index 6a1585da35a..b20165584fe 100644 --- a/fs/yaffs2/yaffs_nand.c +++ b/fs/yaffs2/yaffs_nand.c @@ -11,6 +11,9 @@ * published by the Free Software Foundation. */ +/* XXX U-BOOT XXX */ +#include + const char *yaffs_nand_c_version = "$Id: yaffs_nand.c,v 1.7 2007/02/14 01:09:06 wookey Exp $"; @@ -129,6 +132,3 @@ int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev) { return dev->initialiseNAND(dev); } - - - diff --git a/fs/yaffs2/yaffs_packedtags1.c b/fs/yaffs2/yaffs_packedtags1.c index f480bf1df11..a149431d4f2 100644 --- a/fs/yaffs2/yaffs_packedtags1.c +++ b/fs/yaffs2/yaffs_packedtags1.c @@ -11,6 +11,9 @@ * published by the Free Software Foundation. */ +/* XXX U-BOOT XXX */ +#include + #include "yaffs_packedtags1.h" #include "yportenv.h" diff --git a/fs/yaffs2/yaffs_packedtags2.c b/fs/yaffs2/yaffs_packedtags2.c index 6860876c438..467d5ac1be3 100644 --- a/fs/yaffs2/yaffs_packedtags2.c +++ b/fs/yaffs2/yaffs_packedtags2.c @@ -11,6 +11,9 @@ * published by the Free Software Foundation. */ +/* XXX U-BOOT XXX */ +#include + #include "yaffs_packedtags2.h" #include "yportenv.h" #include "yaffs_tagsvalidity.h" diff --git a/fs/yaffs2/yaffs_qsort.c b/fs/yaffs2/yaffs_qsort.c index 0429838de8e..a74709f0eb2 100644 --- a/fs/yaffs2/yaffs_qsort.c +++ b/fs/yaffs2/yaffs_qsort.c @@ -27,6 +27,9 @@ * SUCH DAMAGE. */ +/* XXX U-BOOT XXX */ +#include + #include "yportenv.h" //#include diff --git a/fs/yaffs2/yaffs_tagscompat.c b/fs/yaffs2/yaffs_tagscompat.c index 7622b1af7c0..70a8a8c72a4 100644 --- a/fs/yaffs2/yaffs_tagscompat.c +++ b/fs/yaffs2/yaffs_tagscompat.c @@ -11,6 +11,9 @@ * published by the Free Software Foundation. */ +/* XXX U-BOOT XXX */ +#include + #include "yaffs_guts.h" #include "yaffs_tagscompat.h" #include "yaffs_ecc.h" diff --git a/fs/yaffs2/yaffs_tagsvalidity.c b/fs/yaffs2/yaffs_tagsvalidity.c index 9e0bd1cf56b..f588d3aa213 100644 --- a/fs/yaffs2/yaffs_tagsvalidity.c +++ b/fs/yaffs2/yaffs_tagsvalidity.c @@ -11,6 +11,9 @@ * published by the Free Software Foundation. */ +/* XXX U-BOOT XXX */ +#include + #include "yaffs_tagsvalidity.h" void yaffs_InitialiseTags(yaffs_ExtendedTags * tags) diff --git a/fs/yaffs2/yportenv.h b/fs/yaffs2/yportenv.h index 8b80c6d6889..b316b16d702 100644 --- a/fs/yaffs2/yportenv.h +++ b/fs/yaffs2/yportenv.h @@ -17,11 +17,17 @@ #ifndef __YPORTENV_H__ #define __YPORTENV_H__ +/* XXX U-BOOT XXX */ +#ifndef CONFIG_YAFFS_DIRECT +#define CONFIG_YAFFS_DIRECT +#endif + #if defined CONFIG_YAFFS_WINCE #include "ywinceenv.h" -#elif defined __KERNEL__ +/* XXX U-BOOT XXX */ +#elif 0 /* defined __KERNEL__ */ #include "moduleconfig.h" -- cgit v1.3.1 From 9ad754fef5053144daed3b007adaf1c9bec654c9 Mon Sep 17 00:00:00 2001 From: William Juul Date: Fri, 14 Dec 2007 16:33:45 +0100 Subject: make nand dump and nand dump.oob work Signed-off-by: William Juul Signed-off-by: Scott Wood --- common/cmd_nand.c | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) (limited to 'common') diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 8b359e01779..af1b1cadd61 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -38,37 +38,44 @@ int find_dev_and_part(const char *id, struct mtd_device **dev, u8 *part_num, struct part_info **part); #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; - u_char *buf, *p; + u_char *datbuf, *oobbuf, *p; - buf = malloc(nand->writesize + nand->oobsize); - if (!buf) { + datbuf = malloc(nand->writesize + nand->oobsize); + oobbuf = malloc(nand->oobsize); + if (!datbuf || !oobbuf) { puts("No memory for page buffer\n"); return 1; } off &= ~(nand->writesize - 1); size_t dummy; loff_t addr = (loff_t) off; - i = nand->read(nand, addr, nand->writesize, &dummy, buf); + 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) { printf("Error (%d) reading page %08lx\n", i, off); - free(buf); + free(datbuf); + free(oobbuf); return 1; } printf("Page %08lx dump:\n", off); - i = nand->writesize >> 4; p = buf; + 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]); + 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; } puts("OOB:\n"); @@ -78,7 +85,8 @@ static int nand_dump(nand_info_t *nand, ulong off) p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); p += 8; } - free(buf); + free(datbuf); + free(oobbuf); return 0; } @@ -302,9 +310,9 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) off = (int)simple_strtoul(argv[2], NULL, 16); if (s != NULL && strcmp(s, ".oob") == 0) - ret = nand_dump_oob(nand, off); + ret = nand_dump(nand, off, 1); else - ret = nand_dump(nand, off); + ret = nand_dump(nand, off, 0); return ret == 0 ? 1 : 0; -- cgit v1.3.1 From deac913effd8d80535c9ff4687b6fcdff540c554 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Sat, 5 Jan 2008 16:50:32 +0100 Subject: NAND: Fix compilation warning and small coding style issue Signed-off-by: Stefan Roese --- common/cmd_nand.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'common') diff --git a/common/cmd_nand.c b/common/cmd_nand.c index af1b1cadd61..710ba8f9460 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -50,7 +50,6 @@ static int nand_dump(nand_info_t *nand, ulong off, int only_oob) return 1; } off &= ~(nand->writesize - 1); - size_t dummy; loff_t addr = (loff_t) off; struct mtd_oob_ops ops; memset(&ops, 0, sizeof(ops)); @@ -415,7 +414,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } /* * ! BROKEN ! - * + * * TODO: must be implemented and tested by someone with HW */ #if 0 @@ -469,7 +468,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) /* * ! BROKEN ! - * + * * TODO: must be implemented and tested by someone with HW */ #if 0 -- cgit v1.3.1 From 984e03cdf1431bb593aeaa1b74c445d616f955d3 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Thu, 12 Jun 2008 13:13:23 -0500 Subject: NAND: Always skip blocks on read/write/boot. Use of the non-skipping versions was almost always (if not always) an error, and no valid use case has been identified. Signed-off-by: Scott Wood --- common/cmd_nand.c | 27 ++++++++++++++------------- doc/README.nand | 37 ++++++++++++------------------------- 2 files changed, 26 insertions(+), 38 deletions(-) (limited to 'common') diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 710ba8f9460..2c421e948ed 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -332,8 +332,8 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return 1; s = strchr(cmd, '.'); - if (s != NULL && - (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) { + if (!s || !strcmp(s, ".jffs2") || + !strcmp(s, ".e") || !strcmp(s, ".i")) { if (read) { /* read */ nand_read_options_t opts; @@ -372,10 +372,8 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) else ret = nand->write_oob(nand, off, &ops); } else { - if (read) - ret = nand_read(nand, off, &size, (u_char *)addr); - else - ret = nand_write(nand, off, &size, (u_char *)addr); + printf("Unknown nand command suffix '%s'.\n", s); + return 1; } printf(" %d bytes %s: %s\n", size, @@ -492,10 +490,10 @@ 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\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'\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" @@ -514,15 +512,17 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, char *ep, *s; size_t cnt; image_header_t *hdr; - int jffs2 = 0; #if defined(CONFIG_FIT) const void *fit_hdr = NULL; #endif s = strchr(cmd, '.'); 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); @@ -559,6 +559,7 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, } show_boot_progress (57); + /* FIXME: skip bad blocks */ r = nand_read(nand, offset, &cnt, (u_char *) addr); if (r) { puts("** Read error\n"); @@ -680,7 +681,7 @@ usage: U_BOOT_CMD(nboot, 4, 1, do_nandboot, "nboot - boot from NAND device\n", - "[.jffs2] [partition] | [[[loadAddr] dev] offset]\n"); + "[partition] | [[[loadAddr] dev] offset]\n"); #endif diff --git a/doc/README.nand b/doc/README.nand index 647a6b8e67f..0ad5e18dd39 100644 --- a/doc/README.nand +++ b/doc/README.nand @@ -57,14 +57,9 @@ Commands: Print information about all of the NAND devices found. nand read addr ofs|partition size - Read `size' bytes from `ofs' in NAND flash to `addr'. If a page - cannot be read because it is marked bad or an uncorrectable data - error is found the command stops with an error. - - nand read.jffs2 addr ofs|partition size - Like `read', but the data for blocks that are marked bad is read as - 0xff. This gives a readable JFFS2 image that can be processed by - the JFFS2 commands such as ls and fsload. + Read `size' bytes from `ofs' in NAND flash to `addr'. Blocks that + are marked bad are skipped. If a page cannot be read because an + uncorrectable data error is found, the command stops with an error. nand read.oob addr ofs|partition size Read `size' bytes from the out-of-band data area corresponding to @@ -73,17 +68,15 @@ Commands: for bad blocks or ECC errors. nand write addr ofs|partition size - Write `size' bytes from `addr' to `ofs' in NAND flash. If a page - cannot be written because it is marked bad or the write fails the - command stops with an error. - - nand write.jffs2 addr ofs|partition size - Like `write', but blocks that are marked bad are skipped and the - data is written to the next block instead. This allows writing - a JFFS2 image, as long as the image is short enough to fit even - after skipping the bad blocks. Compact images, such as those - produced by mkfs.jffs2 should work well, but loading an image copied - from another flash is going to be trouble if there are any bad blocks. + Write `size' bytes from `addr' to `ofs' in NAND flash. Blocks that + are marked bad are skipped. If a page cannot be read because an + uncorrectable data error is found, the command stops with an error. + + As JFFS2 skips blocks similarly, this allows writing a JFFS2 image, + as long as the image is short enough to fit even after skipping the + bad blocks. Compact images, such as those produced by mkfs.jffs2 + should work well, but loading an image copied from another flash is + going to be trouble if there are any bad blocks. nand write.oob addr ofs|partition size Write `size' bytes from `addr' to the out-of-band data area @@ -215,12 +208,6 @@ JFFS2 related commands: using both the new code which is able to skip bad blocks "nand erase clean" additionally writes JFFS2-cleanmarkers in the oob. - "nand write.jffs2" - like "nand write" but skip found bad eraseblocks - - "nand read.jffs2" - like "nand read" but skip found bad eraseblocks - Miscellaneous and testing commands: "markbad [offset]" create an artificial bad block (for testing bad block handling) -- cgit v1.3.1 From dfbf617ff055e4216f78d358b0867c548916d14b Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Thu, 12 Jun 2008 13:20:16 -0500 Subject: NAND read/write fix Implement block-skipping read/write, based on a patch from Morten Ebbell Hestens . Signed-off-by: Morten Ebbell Hestnes Signed-off-by: Scott Wood --- common/cmd_nand.c | 36 +- drivers/mtd/nand/nand_util.c | 762 ++++++++++--------------------------------- include/nand.h | 7 +- 3 files changed, 194 insertions(+), 611 deletions(-) (limited to 'common') diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 2c421e948ed..520c15217c2 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -74,7 +74,8 @@ static int nand_dump(nand_info_t *nand, ulong off, int 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[8], p[9], p[10], p[11], p[12], p[13], p[14], + p[15]); p += 16; } puts("OOB:\n"); @@ -317,7 +318,6 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } - /* read write */ if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { int read; @@ -334,31 +334,12 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) s = strchr(cmd, '.'); if (!s || !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; -/* - * ! BROKEN ! - * - * TODO: Function must be implemented - * - * ret = nand_read_opts(nand, &opts); - */ - } else { - /* write */ - mtd_oob_ops_t opts; - memset(&opts, 0, sizeof(opts)); - opts.datbuf = (u_char*) addr; - opts.len = size; - opts.ooblen = 64; - opts.mode = MTD_OOB_AUTO; - ret = nand_write_opts(nand, off, &opts); - } + if (read) + ret = nand_read_skip_bad(nand, off, &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 = { @@ -396,6 +377,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } return 1; } + if (strcmp(cmd, "biterr") == 0) { /* todo */ return 1; diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 9fe486698c1..02fe914db8b 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -248,586 +248,6 @@ static struct nand_ecclayout autoplace_ecclayout = { }; #endif - -/** - * nand_fill_oob - [Internal] Transfer client buffer to oob - * @chip: nand chip structure - * @oob: oob data buffer - * @ops: oob ops structure - * - * Copied from nand_base.c - */ -static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, - struct mtd_oob_ops *ops) -{ - size_t len = ops->ooblen; - - switch(ops->mode) { - - case MTD_OOB_PLACE: - case MTD_OOB_RAW: - memcpy(chip->oob_poi + ops->ooboffs, oob, len); - return oob + len; - - case MTD_OOB_AUTO: { - struct nand_oobfree *free = chip->ecc.layout->oobfree; - uint32_t boffs = 0, woffs = ops->ooboffs; - size_t bytes = 0; - - for(; free->length && len; free++, len -= bytes) { - /* Write request not from offset 0 ? */ - if (unlikely(woffs)) { - if (woffs >= free->length) { - woffs -= free->length; - continue; - } - boffs = free->offset + woffs; - bytes = min_t(size_t, len, - (free->length - woffs)); - woffs = 0; - } else { - bytes = min_t(size_t, len, free->length); - boffs = free->offset; - } - memcpy(chip->oob_poi + boffs, oob, bytes); - oob += bytes; - } - return oob; - } - default: - BUG(); - } - return NULL; -} - -#define NOTALIGNED(x) (x & (chip->subpagesize - 1)) != 0 - - -/* copied from nand_base.c: nand_do_write_ops() - * Only very small changes - */ -int nand_write_opts(nand_info_t *mtd, loff_t to, mtd_oob_ops_t *ops) -{ - int chipnr, realpage, page, blockmask, column; - struct nand_chip *chip = mtd->priv; - uint32_t writelen = ops->len; - uint8_t *oob = ops->oobbuf; - uint8_t *buf = ops->datbuf; - int ret, subpage; - - ops->retlen = 0; - if (!writelen) - return 0; - - printk("nand_write_opts: to: 0x%08x, ops->len: 0x%08x\n", to, ops->len); - - /* reject writes, which are not page aligned */ - if (NOTALIGNED(to) || NOTALIGNED(ops->len)) { - printk(KERN_NOTICE "nand_write: " - "Attempt to write not page aligned data\n"); - return -EINVAL; - } - - column = to & (mtd->writesize - 1); - subpage = column || (writelen & (mtd->writesize - 1)); - - if (subpage && oob) { - printk(KERN_NOTICE "nand_write: " - "Attempt to write oob to subpage\n"); - return -EINVAL; - } - - chipnr = (int)(to >> chip->chip_shift); - chip->select_chip(mtd, chipnr); - - /* XXX U-BOOT XXX */ -#if 0 - /* Check, if it is write protected */ - if (nand_check_wp(mtd)) - return -EIO; -#endif - - realpage = (int)(to >> chip->page_shift); - page = realpage & chip->pagemask; - blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; - - /* Invalidate the page cache, when we write to the cached page */ - if (to <= (chip->pagebuf << chip->page_shift) && - (chip->pagebuf << chip->page_shift) < (to + ops->len)) - chip->pagebuf = -1; - - /* If we're not given explicit OOB data, let it be 0xFF */ - if (likely(!oob)) { - printf("!oob, writing %d bytes with 0xff to chip->oob_poi (0x%08x)\n", mtd->oobsize, chip->oob_poi); - memset(chip->oob_poi, 0xff, mtd->oobsize); - } - - while(1) { - int bytes = mtd->writesize; - int cached = writelen > bytes && page != blockmask; - uint8_t *wbuf = buf; - - /* Partial page write ? */ - if (unlikely(column || writelen < (mtd->writesize - 1))) { - cached = 0; - bytes = min_t(int, bytes - column, (int) writelen); - chip->pagebuf = -1; - memset(chip->buffers->databuf, 0xff, mtd->writesize); - memcpy(&chip->buffers->databuf[column], buf, bytes); - wbuf = chip->buffers->databuf; - } - - if (unlikely(oob)) - oob = nand_fill_oob(chip, oob, ops); - - ret = chip->write_page(mtd, chip, wbuf, page, cached, - (ops->mode == MTD_OOB_RAW)); - if (ret) - break; - - writelen -= bytes; - if (!writelen) - break; - - column = 0; - buf += bytes; - realpage++; - - page = realpage & chip->pagemask; - /* Check, if we cross a chip boundary */ - if (!page) { - chipnr++; - chip->select_chip(mtd, -1); - chip->select_chip(mtd, chipnr); - } - } - - ops->retlen = ops->len - writelen; - if (unlikely(oob)) - ops->oobretlen = ops->ooblen; - return ret; -} - -/* XXX U-BOOT XXX */ -#if 0 -/** - * nand_write_opts: - write image to NAND flash with support for various options - * - * @param meminfo NAND device to erase - * @param opts write options (@see nand_write_options) - * @return 0 in case of success - * - * This code is ported from nandwrite.c from Linux mtd utils by - * Steven J. Hill and Thomas Gleixner. - */ -int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts) -{ - int imglen = 0; - int pagelen; - int baderaseblock; - int blockstart = -1; - loff_t offs; - int readlen; - int ecclayoutchanged = 0; - int percent_complete = -1; - struct nand_ecclayout old_ecclayout; - ulong mtdoffset = opts->offset; - ulong erasesize_blockalign; - u_char *buffer = opts->buffer; - size_t written; - int result; - - if (opts->pad && opts->writeoob) { - printf("Can't pad when oob data is present.\n"); - return -1; - } - - /* set erasesize to specified number of blocks - to match - * jffs2 (virtual) block size */ - if (opts->blockalign == 0) { - erasesize_blockalign = meminfo->erasesize; - } else { - erasesize_blockalign = meminfo->erasesize * opts->blockalign; - } - - /* make sure device page sizes are valid */ - if (!(meminfo->oobsize == 16 && meminfo->writesize == 512) - && !(meminfo->oobsize == 8 && meminfo->writesize == 256) - && !(meminfo->oobsize == 64 && meminfo->writesize == 2048)) { - printf("Unknown flash (not normal NAND)\n"); - return -1; - } - - /* read the current oob info */ - memcpy(&old_ecclayout, &meminfo->ecclayout, sizeof(old_ecclayout)); - - /* write without ecc? */ - if (opts->noecc) { - memcpy(&meminfo->ecclayout, &none_ecclayout, - sizeof(meminfo->ecclayout)); - ecclayoutchanged = 1; - } - - /* autoplace ECC? */ - if (opts->autoplace && (old_ecclayout.useecc != MTD_NANDECC_AUTOPLACE)) { - - memcpy(&meminfo->ecclayout, &autoplace_ecclayout, - sizeof(meminfo->ecclayout)); - ecclayoutchanged = 1; - } - - /* force OOB layout for jffs2 or yaffs? */ - if (opts->forcejffs2 || opts->forceyaffs) { - struct nand_ecclayout *oobsel = - opts->forcejffs2 ? &jffs2_ecclayout : &yaffs_ecclayout; - - if (meminfo->oobsize == 8) { - if (opts->forceyaffs) { - printf("YAFSS cannot operate on " - "256 Byte page size\n"); - goto restoreoob; - } - /* Adjust number of ecc bytes */ - jffs2_ecclayout.eccbytes = 3; - } - - memcpy(&meminfo->ecclayout, oobsel, sizeof(meminfo->ecclayout)); - } - - /* get image length */ - imglen = opts->length; - pagelen = meminfo->writesize - + ((opts->writeoob != 0) ? meminfo->oobsize : 0); - - /* check, if file is pagealigned */ - if ((!opts->pad) && ((imglen % pagelen) != 0)) { - printf("Input block length is not page aligned\n"); - goto restoreoob; - } - - /* check, if length fits into device */ - if (((imglen / pagelen) * meminfo->writesize) - > (meminfo->size - opts->offset)) { - printf("Image %d bytes, NAND page %d bytes, " - "OOB area %u bytes, device size %u bytes\n", - imglen, pagelen, meminfo->writesize, meminfo->size); - printf("Input block does not fit into device\n"); - goto restoreoob; - } - - if (!opts->quiet) - printf("\n"); - - /* get data from input and write to the device */ - while (imglen && (mtdoffset < meminfo->size)) { - - WATCHDOG_RESET (); - - /* - * new eraseblock, check for bad block(s). Stay in the - * loop to be sure if the offset changes because of - * a bad block, that the next block that will be - * written to is also checked. Thus avoiding errors if - * the block(s) after the skipped block(s) is also bad - * (number of blocks depending on the blockalign - */ - while (blockstart != (mtdoffset & (~erasesize_blockalign+1))) { - blockstart = mtdoffset & (~erasesize_blockalign+1); - offs = blockstart; - baderaseblock = 0; - - /* check all the blocks in an erase block for - * bad blocks */ - do { - int ret = meminfo->block_isbad(meminfo, offs); - - if (ret < 0) { - printf("Bad block check failed\n"); - goto restoreoob; - } - if (ret == 1) { - baderaseblock = 1; - if (!opts->quiet) - printf("\rBad block at 0x%lx " - "in erase block from " - "0x%x will be skipped\n", - (long) offs, - blockstart); - } - - if (baderaseblock) { - mtdoffset = blockstart - + erasesize_blockalign; - } - offs += erasesize_blockalign - / opts->blockalign; - } while (offs < blockstart + erasesize_blockalign); - } - - readlen = meminfo->writesize; - if (opts->pad && (imglen < readlen)) { - readlen = imglen; - memset(data_buf + readlen, 0xff, - meminfo->writesize - readlen); - } - - /* read page data from input memory buffer */ - memcpy(data_buf, buffer, readlen); - buffer += readlen; - - if (opts->writeoob) { - /* read OOB data from input memory block, exit - * on failure */ - memcpy(oob_buf, buffer, meminfo->oobsize); - buffer += meminfo->oobsize; - - /* write OOB data first, as ecc will be placed - * in there*/ - result = meminfo->write_oob(meminfo, - mtdoffset, - meminfo->oobsize, - &written, - (unsigned char *) - &oob_buf); - - if (result != 0) { - printf("\nMTD writeoob failure: %d\n", - result); - goto restoreoob; - } - imglen -= meminfo->oobsize; - } - - /* write out the page data */ - result = meminfo->write(meminfo, - mtdoffset, - meminfo->writesize, - &written, - (unsigned char *) &data_buf); - - if (result != 0) { - printf("writing NAND page at offset 0x%lx failed\n", - mtdoffset); - goto restoreoob; - } - imglen -= readlen; - - if (!opts->quiet) { - unsigned long long n = (unsigned long long) - (opts->length-imglen) * 100; - int percent; - - do_div(n, opts->length); - percent = (int)n; - - /* output progress message only at whole percent - * steps to reduce the number of messages printed - * on (slow) serial consoles - */ - if (percent != percent_complete) { - printf("\rWriting data at 0x%lx " - "-- %3d%% complete.", - mtdoffset, percent); - percent_complete = percent; - } - } - - mtdoffset += meminfo->writesize; - } - - if (!opts->quiet) - printf("\n"); - -restoreoob: - if (ecclayoutchanged) { - memcpy(&meminfo->ecclayout, &old_ecclayout, - sizeof(meminfo->ecclayout)); - } - - if (imglen > 0) { - printf("Data did not fit into device, due to bad blocks\n"); - return -1; - } - - /* return happy */ - return 0; -} - -/** - * nand_read_opts: - read image from NAND flash with support for various options - * - * @param meminfo NAND device to erase - * @param opts read options (@see struct nand_read_options) - * @return 0 in case of success - * - */ -int nand_read_opts(nand_info_t *meminfo, const nand_read_options_t *opts) -{ - int imglen = opts->length; - int pagelen; - int baderaseblock; - int blockstart = -1; - int percent_complete = -1; - loff_t offs; - size_t readlen; - ulong mtdoffset = opts->offset; - u_char *buffer = opts->buffer; - int result; - - /* make sure device page sizes are valid */ - if (!(meminfo->oobsize == 16 && meminfo->writesize == 512) - && !(meminfo->oobsize == 8 && meminfo->writesize == 256) - && !(meminfo->oobsize == 64 && meminfo->writesize == 2048)) { - printf("Unknown flash (not normal NAND)\n"); - return -1; - } - - pagelen = meminfo->writesize - + ((opts->readoob != 0) ? meminfo->oobsize : 0); - - /* check, if length is not larger than device */ - if (((imglen / pagelen) * meminfo->writesize) - > (meminfo->size - opts->offset)) { - printf("Image %d bytes, NAND page %d bytes, " - "OOB area %u bytes, device size %u bytes\n", - imglen, pagelen, meminfo->writesize, meminfo->size); - printf("Input block is larger than device\n"); - return -1; - } - - if (!opts->quiet) - printf("\n"); - - /* get data from input and write to the device */ - while (imglen && (mtdoffset < meminfo->size)) { - - WATCHDOG_RESET (); - - /* - * new eraseblock, check for bad block(s). Stay in the - * loop to be sure if the offset changes because of - * a bad block, that the next block that will be - * written to is also checked. Thus avoiding errors if - * the block(s) after the skipped block(s) is also bad - * (number of blocks depending on the blockalign - */ - while (blockstart != (mtdoffset & (~meminfo->erasesize+1))) { - blockstart = mtdoffset & (~meminfo->erasesize+1); - offs = blockstart; - baderaseblock = 0; - - /* check all the blocks in an erase block for - * bad blocks */ - do { - int ret = meminfo->block_isbad(meminfo, offs); - - if (ret < 0) { - printf("Bad block check failed\n"); - return -1; - } - if (ret == 1) { - baderaseblock = 1; - if (!opts->quiet) - printf("\rBad block at 0x%lx " - "in erase block from " - "0x%x will be skipped\n", - (long) offs, - blockstart); - } - - if (baderaseblock) { - mtdoffset = blockstart - + meminfo->erasesize; - } - offs += meminfo->erasesize; - - } while (offs < blockstart + meminfo->erasesize); - } - - - /* read page data to memory buffer */ - result = meminfo->read(meminfo, - mtdoffset, - meminfo->writesize, - &readlen, - (unsigned char *) &data_buf); - - if (result != 0) { - printf("reading NAND page at offset 0x%lx failed\n", - mtdoffset); - return -1; - } - - if (imglen < readlen) { - readlen = imglen; - } - - memcpy(buffer, data_buf, readlen); - buffer += readlen; - imglen -= readlen; - - if (opts->readoob) { - result = meminfo->read_oob(meminfo, - mtdoffset, - meminfo->oobsize, - &readlen, - (unsigned char *) - &oob_buf); - - if (result != 0) { - printf("\nMTD readoob failure: %d\n", - result); - return -1; - } - - - if (imglen < readlen) { - readlen = imglen; - } - - memcpy(buffer, oob_buf, readlen); - - buffer += readlen; - imglen -= readlen; - } - - if (!opts->quiet) { - unsigned long long n = (unsigned long long) - (opts->length-imglen) * 100; - int percent; - - do_div(n, opts->length); - percent = (int)n; - - /* output progress message only at whole percent - * steps to reduce the number of messages printed - * on (slow) serial consoles - */ - if (percent != percent_complete) { - if (!opts->quiet) - printf("\rReading data from 0x%lx " - "-- %3d%% complete.", - mtdoffset, percent); - percent_complete = percent; - } - } - - mtdoffset += meminfo->writesize; - } - - if (!opts->quiet) - printf("\n"); - - if (imglen > 0) { - printf("Could not read entire image due to bad blocks\n"); - return -1; - } - - /* return happy */ - return 0; -} -#endif - /* XXX U-BOOT XXX */ #if 0 /****************************************************************************** @@ -1007,4 +427,184 @@ int nand_unlock(nand_info_t *meminfo, ulong start, ulong length) } #endif -#endif +/** + * get_len_incl_bad + * + * Check if length including bad blocks fits into device. + * + * @param nand NAND device + * @param offset offset in flash + * @param length image length + * @return image length including bad blocks + */ +static size_t get_len_incl_bad (nand_info_t *nand, size_t offset, + const size_t length) +{ + size_t len_incl_bad = 0; + size_t len_excl_bad = 0; + size_t block_len; + + while (len_excl_bad < length) { + block_len = nand->erasesize - (offset & (nand->erasesize - 1)); + + if (!nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) + len_excl_bad += block_len; + + len_incl_bad += block_len; + offset += block_len; + + if ((offset + len_incl_bad) >= nand->size) + break; + } + + return len_incl_bad; +} + +/** + * nand_write_skip_bad: + * + * Write image to NAND flash. + * Blocks that are marked bad are skipped and the is written to the next + * block instead as long as the image is short enough to fit even after + * skipping the bad blocks. + * + * @param nand NAND device + * @param offset offset in flash + * @param length buffer length + * @param buf buffer to read from + * @return 0 in case of success + */ +int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length, + u_char *buffer) +{ + int rval; + size_t left_to_write = *length; + size_t len_incl_bad; + u_char *p_buffer = buffer; + + /* Reject writes, which are not page aligned */ + if ((offset & (nand->writesize - 1)) != 0 || + (*length & (nand->writesize - 1)) != 0) { + printf ("Attempt to write non page aligned data\n"); + return -EINVAL; + } + + len_incl_bad = get_len_incl_bad (nand, offset, *length); + + if ((offset + len_incl_bad) >= nand->size) { + printf ("Attempt to write outside the flash area\n"); + return -EINVAL; + } + + if (len_incl_bad == *length) { + rval = nand_write (nand, offset, length, buffer); + if (rval != 0) { + printf ("NAND write to offset %x failed %d\n", + offset, rval); + return rval; + } + } + + while (left_to_write > 0) { + size_t block_offset = offset & (nand->erasesize - 1); + size_t write_size; + + if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) { + printf ("Skip bad block 0x%08x\n", + offset & ~(nand->erasesize - 1)); + offset += nand->erasesize - block_offset; + continue; + } + + if (left_to_write < (nand->erasesize - block_offset)) + write_size = left_to_write; + else + write_size = nand->erasesize - block_offset; + + rval = nand_write (nand, offset, &write_size, p_buffer); + if (rval != 0) { + printf ("NAND write to offset %x failed %d\n", + offset, rval); + *length -= left_to_write; + return rval; + } + + left_to_write -= write_size; + offset += write_size; + p_buffer += write_size; + } + + return 0; +} + +/** + * nand_read_skip_bad: + * + * Read image from NAND flash. + * Blocks that are marked bad are skipped and the next block is readen + * instead as long as the image is short enough to fit even after skipping the + * bad blocks. + * + * @param nand NAND device + * @param offset offset in flash + * @param length buffer length, on return holds remaining bytes to read + * @param buffer buffer to write to + * @return 0 in case of success + */ +int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length, + u_char *buffer) +{ + int rval; + size_t left_to_read = *length; + size_t len_incl_bad; + u_char *p_buffer = buffer; + + len_incl_bad = get_len_incl_bad (nand, offset, *length); + + if ((offset + len_incl_bad) >= nand->size) { + printf ("Attempt to read outside the flash area\n"); + return -EINVAL; + } + + if (len_incl_bad == *length) { + rval = nand_read (nand, offset, length, buffer); + if (rval != 0) { + printf ("NAND read from offset %x failed %d\n", + offset, rval); + return rval; + } + } + + while (left_to_read > 0) { + size_t block_offset = offset & (nand->erasesize - 1); + size_t read_length; + + if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) { + printf ("Skipping bad block 0x%08x\n", + offset & ~(nand->erasesize - 1)); + offset += nand->erasesize - block_offset; + continue; + } + + if (left_to_read < (nand->erasesize - block_offset)) + read_length = left_to_read; + else + read_length = nand->erasesize - block_offset; + + rval = nand_read (nand, offset, &read_length, p_buffer); + if (rval != 0) { + printf ("NAND read from offset %x failed %d\n", + offset, rval); + *length -= left_to_read; + return rval; + } + + left_to_read -= read_length; + offset += read_length; + p_buffer += read_length; + } + + return 0; +} + +#endif /* defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) */ diff --git a/include/nand.h b/include/nand.h index 83d597dc7db..d5af4324cb2 100644 --- a/include/nand.h +++ b/include/nand.h @@ -108,9 +108,10 @@ struct nand_erase_options { typedef struct nand_erase_options nand_erase_options_t; -int nand_write_opts(nand_info_t *mtd, loff_t to, mtd_oob_ops_t *ops); - -int nand_read_opts(nand_info_t *meminfo, const nand_read_options_t *opts); +int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length, + u_char *buffer); +int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length, + u_char *buffer); int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts); #define NAND_LOCK_STATUS_TIGHT 0x01 -- cgit v1.3.1 From c3db8c649c6ab3da2f1411c4c6d61aecea054aa4 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 31 Jul 2008 12:38:26 +0200 Subject: NAND: Do not write or read a whole block if it is larger than the environment Environment can be smaller than NAND block size, do not need to read a whole block and minimum for writing is one page. Also remove an unused variable. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Scott Wood --- common/env_nand.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'common') diff --git a/common/env_nand.c b/common/env_nand.c index 104f0856af2..a8f0de7ae24 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -159,22 +159,23 @@ int writeenv(size_t offset, u_char *buf) { size_t end = offset + CFG_ENV_RANGE; size_t amount_saved = 0; - size_t blocksize; + size_t blocksize, len; u_char *char_ptr; blocksize = nand_info[0].erasesize; + len = min(blocksize, CFG_ENV_SIZE); while (amount_saved < CFG_ENV_SIZE && offset < end) { if (nand_block_isbad(&nand_info[0], offset)) { offset += blocksize; } else { char_ptr = &buf[amount_saved]; - if (nand_write(&nand_info[0], offset, &blocksize, + if (nand_write(&nand_info[0], offset, &len, char_ptr)) return 1; offset += blocksize; - amount_saved += blocksize; + amount_saved += len; } } if (amount_saved != CFG_ENV_SIZE) @@ -261,21 +262,22 @@ int readenv (size_t offset, u_char * buf) { size_t end = offset + CFG_ENV_RANGE; size_t amount_loaded = 0; - size_t blocksize; + size_t blocksize, len; u_char *char_ptr; blocksize = nand_info[0].erasesize; + len = min(blocksize, CFG_ENV_SIZE); while (amount_loaded < CFG_ENV_SIZE && offset < end) { if (nand_block_isbad(&nand_info[0], offset)) { offset += blocksize; } else { char_ptr = &buf[amount_loaded]; - if (nand_read(&nand_info[0], offset, &blocksize, char_ptr)) + if (nand_read(&nand_info[0], offset, &len, char_ptr)) return 1; offset += blocksize; - amount_loaded += blocksize; + amount_loaded += len; } } if (amount_loaded != CFG_ENV_SIZE) @@ -345,12 +347,10 @@ void env_relocate_spec (void) void env_relocate_spec (void) { #if !defined(ENV_IS_EMBEDDED) - size_t total; int ret; - total = CFG_ENV_SIZE; ret = readenv(CFG_ENV_OFFSET, (u_char *) env_ptr); - if (ret || total != CFG_ENV_SIZE) + if (ret) return use_default(); if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc) -- cgit v1.3.1 From 195ccfc5991d48764b2519941e3507f693851d5d Mon Sep 17 00:00:00 2001 From: Fathi BOUDRA Date: Wed, 6 Aug 2008 10:06:20 +0200 Subject: OneNAND: Fill in MTD function pointers for OneNAND. onenand_print_device_info(): - Now returns a string to be placed in mtd->name, rather than calling printf. - Remove verbose parameter as it becomes useless. Signed-off-by: Fathi Boudra Signed-off-by: Scott Wood --- common/cmd_onenand.c | 2 +- drivers/mtd/onenand/onenand_base.c | 24 ++++++++++++++++++------ include/onenand_uboot.h | 2 +- 3 files changed, 20 insertions(+), 8 deletions(-) (limited to 'common') diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index d6d337628ec..419bf70988f 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -38,7 +38,7 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) onenand_init(); return 0; } - onenand_print_device_info(onenand_chip.device_id, 1); + printf("%s\n", onenand_mtd.name); return 0; default: diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index a7054aebca6..ded1706abbe 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -19,6 +19,7 @@ #include #include +#include /* It should access 16-bit instead of 8-bit */ static inline void *memcpy_16(void *dst, const void *src, unsigned int len) @@ -1110,21 +1111,21 @@ int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) * * Print device ID */ -void onenand_print_device_info(int device, int verbose) +char * onenand_print_device_info(int device) { int vcc, demuxed, ddp, density; - - if (!verbose) - return; + char *dev_info = malloc(80); vcc = device & ONENAND_DEVICE_VCC_MASK; demuxed = device & ONENAND_DEVICE_IS_DEMUX; ddp = device & ONENAND_DEVICE_IS_DDP; density = device >> ONENAND_DEVICE_DENSITY_SHIFT; - printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n", + sprintf(dev_info, "%sOneNAND%s %dMB %sV 16-bit (0x%02x)", demuxed ? "" : "Muxed ", ddp ? "(DDP)" : "", (16 << density), vcc ? "2.65/3.3" : "1.8", device); + + return dev_info; } static const struct onenand_manufacturers onenand_manuf_ids[] = { @@ -1203,7 +1204,7 @@ static int onenand_probe(struct mtd_info *mtd) } /* Flash device information */ - onenand_print_device_info(dev_id, 0); + mtd->name = onenand_print_device_info(dev_id); this->device_id = dev_id; density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT; @@ -1239,6 +1240,17 @@ static int onenand_probe(struct mtd_info *mtd) this->options |= ONENAND_CONT_LOCK; } + mtd->erase = onenand_erase; + mtd->read = onenand_read; + mtd->write = onenand_write; + mtd->read_ecc = onenand_read_ecc; + mtd->write_ecc = onenand_write_ecc; + mtd->read_oob = onenand_read_oob; + mtd->write_oob = onenand_write_oob; + mtd->sync = onenand_sync; + mtd->block_isbad = onenand_block_isbad; + mtd->block_markbad = onenand_block_markbad; + return 0; } diff --git a/include/onenand_uboot.h b/include/onenand_uboot.h index 4449f987bf7..4260ee7eb44 100644 --- a/include/onenand_uboot.h +++ b/include/onenand_uboot.h @@ -39,6 +39,6 @@ extern int onenand_erase(struct mtd_info *mtd, struct erase_info *instr); extern int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len); -extern void onenand_print_device_info(int device, int verbose); +extern char *onenand_print_device_info(int device); #endif /* __UBOOT_ONENAND_H */ -- cgit v1.3.1