X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=common%2Fcmd_doc.c;h=3d717c039d444a54c3cd756d8a8c44e0474abbc0;hb=4c58eb5552220e425c8af6ac8d2839244a2f57b1;hp=37d0fbdfc3105c38223b0217e853b6426974d3ed;hpb=c609719b8d1b2dca590e0ed499016d041203e403;p=u-boot diff --git a/common/cmd_doc.c b/common/cmd_doc.c index 37d0fbdfc3..3d717c039d 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -11,20 +11,8 @@ #include #include #include - -#ifdef CONFIG_SHOW_BOOT_PROGRESS -# include -# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) -#else -# define SHOW_BOOT_PROGRESS(arg) -#endif - -#if (CONFIG_COMMANDS & CFG_CMD_DOC) - -#include -#include -#include #include +#include #ifdef CFG_DOC_SUPPORT_2000 #define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k) @@ -67,6 +55,32 @@ static struct DiskOnChip doc_dev_desc[CFG_MAX_DOC_DEVICE]; /* Current DOC Device */ static int curr_device = -1; +/* Supported NAND flash devices */ +static struct nand_flash_dev nand_flash_ids[] = { + {"Toshiba TC5816BDC", NAND_MFR_TOSHIBA, 0x64, 21, 1, 2, 0x1000, 0}, + {"Toshiba TC5832DC", NAND_MFR_TOSHIBA, 0x6b, 22, 0, 2, 0x2000, 0}, + {"Toshiba TH58V128DC", NAND_MFR_TOSHIBA, 0x73, 24, 0, 2, 0x4000, 0}, + {"Toshiba TC58256FT/DC", NAND_MFR_TOSHIBA, 0x75, 25, 0, 2, 0x4000, 0}, + {"Toshiba TH58512FT", NAND_MFR_TOSHIBA, 0x76, 26, 0, 3, 0x4000, 0}, + {"Toshiba TC58V32DC", NAND_MFR_TOSHIBA, 0xe5, 22, 0, 2, 0x2000, 0}, + {"Toshiba TC58V64AFT/DC", NAND_MFR_TOSHIBA, 0xe6, 23, 0, 2, 0x2000, 0}, + {"Toshiba TC58V16BDC", NAND_MFR_TOSHIBA, 0xea, 21, 1, 2, 0x1000, 0}, + {"Toshiba TH58100FT", NAND_MFR_TOSHIBA, 0x79, 27, 0, 3, 0x4000, 0}, + {"Samsung KM29N16000", NAND_MFR_SAMSUNG, 0x64, 21, 1, 2, 0x1000, 0}, + {"Samsung unknown 4Mb", NAND_MFR_SAMSUNG, 0x6b, 22, 0, 2, 0x2000, 0}, + {"Samsung KM29U128T", NAND_MFR_SAMSUNG, 0x73, 24, 0, 2, 0x4000, 0}, + {"Samsung KM29U256T", NAND_MFR_SAMSUNG, 0x75, 25, 0, 2, 0x4000, 0}, + {"Samsung unknown 64Mb", NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0}, + {"Samsung KM29W32000", NAND_MFR_SAMSUNG, 0xe3, 22, 0, 2, 0x2000, 0}, + {"Samsung unknown 4Mb", NAND_MFR_SAMSUNG, 0xe5, 22, 0, 2, 0x2000, 0}, + {"Samsung KM29U64000", NAND_MFR_SAMSUNG, 0xe6, 23, 0, 2, 0x2000, 0}, + {"Samsung KM29W16000", NAND_MFR_SAMSUNG, 0xea, 21, 1, 2, 0x1000, 0}, + {"Samsung K9F5616Q0C", NAND_MFR_SAMSUNG, 0x45, 25, 0, 2, 0x4000, 1}, + {"Samsung K9K1216Q0C", NAND_MFR_SAMSUNG, 0x46, 26, 0, 3, 0x4000, 1}, + {"Samsung K9F1G08U0M", NAND_MFR_SAMSUNG, 0xf1, 27, 0, 2, 0, 0}, + {NULL,} +}; + /* ------------------------------------------------------------------------- */ int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) @@ -79,7 +93,7 @@ int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf ("Usage:\n%s\n", cmdtp->usage); return 1; case 2: - if (strcmp(argv[1],"info") == 0) { + if (strcmp(argv[1],"info") == 0) { int i; putc ('\n'); @@ -142,7 +156,7 @@ int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) cmd ? "read" : "write", curr_device, off, size); ret = doc_rw(doc_dev_desc + curr_device, cmd, off, size, - &total, (u_char*)addr); + (size_t *)&total, (u_char*)addr); printf ("%d bytes %s: %s\n", total, cmd ? "read" : "write", ret ? "ERROR" : "OK"); @@ -169,6 +183,17 @@ int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return rcode; } } +U_BOOT_CMD( + doc, 5, 1, do_doc, + "doc - Disk-On-Chip sub-system\n", + "info - show available DOC devices\n" + "doc device [dev] - show or set current device\n" + "doc read addr off size\n" + "doc write addr off size - read/write `size'" + " bytes starting at offset `off'\n" + " to/from memory address `addr'\n" + "doc erase off size - erase `size' bytes of DOC from offset `off'\n" +); int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { @@ -181,6 +206,7 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) image_header_t *hdr; int rcode = 0; + show_boot_progress (34); switch (argc) { case 1: addr = CFG_LOAD_ADDR; @@ -201,24 +227,27 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; default: printf ("Usage:\n%s\n", cmdtp->usage); - SHOW_BOOT_PROGRESS (-1); + show_boot_progress (-35); return 1; } + show_boot_progress (35); if (!boot_device) { puts ("\n** No boot device **\n"); - SHOW_BOOT_PROGRESS (-1); + show_boot_progress (-36); return 1; } + show_boot_progress (36); dev = simple_strtoul(boot_device, &ep, 16); if ((dev >= CFG_MAX_DOC_DEVICE) || (doc_dev_desc[dev].ChipID == DOC_ChipID_UNKNOWN)) { printf ("\n** Device %d not available\n", dev); - SHOW_BOOT_PROGRESS (-1); + show_boot_progress (-37); return 1; } + show_boot_progress (37); printf ("\nLoading from device %d: %s at 0x%lX (offset 0x%lX)\n", dev, doc_dev_desc[dev].name, doc_dev_desc[dev].physadr, @@ -227,9 +256,10 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (doc_rw (doc_dev_desc + dev, 1, offset, SECTORSIZE, NULL, (u_char *)addr)) { printf ("** Read error on %d\n", dev); - SHOW_BOOT_PROGRESS (-1); + show_boot_progress (-38); return 1; } + show_boot_progress (38); hdr = (image_header_t *)addr; @@ -237,20 +267,22 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) print_image_hdr (hdr); - cnt = (hdr->ih_size + sizeof(image_header_t)); + cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); cnt -= SECTORSIZE; } else { puts ("\n** Bad Magic Number **\n"); - SHOW_BOOT_PROGRESS (-1); + show_boot_progress (-39); return 1; } + show_boot_progress (39); if (doc_rw (doc_dev_desc + dev, 1, offset + SECTORSIZE, cnt, NULL, (u_char *)(addr+SECTORSIZE))) { printf ("** Read error on %d\n", dev); - SHOW_BOOT_PROGRESS (-1); + show_boot_progress (-40); return 1; } + show_boot_progress (40); /* Loading ok, update default load address */ @@ -272,6 +304,12 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return rcode; } +U_BOOT_CMD( + docboot, 4, 1, do_docboot, + "docboot - boot from DOC device\n", + "loadAddr dev\n" +); + int doc_rw (struct DiskOnChip* this, int cmd, loff_t from, size_t len, size_t * retlen, u_char * buf) @@ -286,12 +324,12 @@ int doc_rw (struct DiskOnChip* this, int cmd, if (cmd) ret = doc_read_ecc(this, from, len, - &n, (u_char*)buf, - noecc ? NULL : eccbuf); + (size_t *)&n, (u_char*)buf, + noecc ? (uchar *)NULL : (uchar *)eccbuf); else ret = doc_write_ecc(this, from, len, - &n, (u_char*)buf, - noecc ? NULL : eccbuf); + (size_t *)&n, (u_char*)buf, + noecc ? (uchar *)NULL : (uchar *)eccbuf); if (ret) break; @@ -384,7 +422,7 @@ static int _DoC_WaitReady(struct DiskOnChip *doc) } #endif udelay(1); - } + } return 0; } @@ -507,7 +545,7 @@ static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs, return DoC_WaitReady(doc); } -/* Read a buffer from DoC, taking care of Millennium odditys */ +/* Read a buffer from DoC, taking care of Millennium oddities */ static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len) { volatile int dummy; @@ -540,7 +578,7 @@ static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len) } } -/* Write a buffer to DoC, taking care of Millennium odditys */ +/* Write a buffer to DoC, taking care of Millennium oddities */ static void DoC_WriteBuf(struct DiskOnChip *doc, const u_char * buf, int len) { unsigned long docptr; @@ -786,7 +824,7 @@ static int find_boot_record(struct NFTLrecord *nftl) /* Check for ANAND header first. Then can whinge if it's found but later checks fail */ if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize, SECTORSIZE, - &retlen, buf, NULL))) { + (size_t *)&retlen, buf, NULL))) { static int warncount = 5; if (warncount) { @@ -811,7 +849,7 @@ static int find_boot_record(struct NFTLrecord *nftl) /* To be safer with BIOS, also use erase mark as discriminant */ if ((ret = doc_read_oob(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, - 8, &retlen, (char *)&h1) < 0)) { + 8, (size_t *)&retlen, (uchar *)&h1) < 0)) { #ifdef NFTL_DEBUG printf("ANAND header found at 0x%x, but OOB data read failed\n", block * nftl->EraseSize); @@ -843,8 +881,13 @@ static int find_boot_record(struct NFTLrecord *nftl) memcpy(mh, buf, sizeof(struct NFTLMediaHeader)); /* Do some sanity checks on it */ - if (mh->UnitSizeFactor != 0xff) { - puts ("Sorry, we don't support UnitSizeFactor " + if (mh->UnitSizeFactor == 0) { +#ifdef NFTL_DEBUG + puts ("UnitSizeFactor 0x00 detected.\n" + "This violates the spec but we think we know what it means...\n"); +#endif + } else if (mh->UnitSizeFactor != 0xff) { + printf ("Sorry, we don't support UnitSizeFactor " "of != 1 yet.\n"); return -1; } @@ -879,7 +922,7 @@ static int find_boot_record(struct NFTLrecord *nftl) /* read one sector for every SECTORSIZE of blocks */ if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize + i + SECTORSIZE, SECTORSIZE, - &retlen, buf, (char *)&oob)) < 0) { + (size_t *)&retlen, buf, (uchar *)&oob)) < 0) { puts ("Read of bad sector table failed\n"); return -1; } @@ -932,12 +975,14 @@ static void DoC2k_init(struct DiskOnChip* this) /* Ident all the chips present. */ DoC_ScanChips(this); + if ((!this->numchips) || (!this->chips)) + return; nftl = &this->nftl; /* Get physical parameters */ nftl->EraseSize = this->erasesize; - nftl->nb_blocks = this->totlen / this->erasesize; + nftl->nb_blocks = this->totlen / this->erasesize; nftl->mtd = this; if (find_boot_record(nftl) != 0) @@ -974,7 +1019,7 @@ int doc_read_ecc(struct DiskOnChip* this, loff_t from, size_t len, printf("ECC needs a full sector read (adr: %lx size %lx)\n", (long) from, (long) len); -#ifdef PHYCH_DEBUG +#ifdef PSYCHO_DEBUG printf("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len); #endif @@ -1053,18 +1098,18 @@ int doc_read_ecc(struct DiskOnChip* this, loff_t from, size_t len, syndrome[i] = ReadDOC(docptr, ECCSyndrome0 + i); } - nb_errors = doc_decode_ecc(buf, syndrome); + nb_errors = doc_decode_ecc(buf, syndrome); #ifdef ECC_DEBUG printf("Errors corrected: %x\n", nb_errors); #endif - if (nb_errors < 0) { + if (nb_errors < 0) { /* We return error, but have actually done the read. Not that this can be told to user-space, via sys_read(), but at least MTD-aware stuff can know about it by checking *retlen */ printf("ECC Errors at %lx\n", (long)from); ret = DOC_EECC; - } + } } #ifdef PSYCHO_DEBUG @@ -1078,7 +1123,7 @@ int doc_read_ecc(struct DiskOnChip* this, loff_t from, size_t len, } /* according to 11.4.1, we need to wait for the busy line - * drop if we read to the end of the page. */ + * drop if we read to the end of the page. */ if(0 == ((from + *retlen) & 0x1ff)) { DoC_WaitReady(this); @@ -1290,8 +1335,8 @@ int doc_read_oob(struct DiskOnChip* this, loff_t ofs, size_t len, *retlen = len; /* Reading the full OOB data drops us off of the end of the page, - * causing the flash device to go into busy mode, so we need - * to wait until ready 11.4.1 and Toshiba TC58256FT docs */ + * causing the flash device to go into busy mode, so we need + * to wait until ready 11.4.1 and Toshiba TC58256FT docs */ ret = DoC_WaitReady(this); @@ -1559,5 +1604,3 @@ void doc_probe(unsigned long physadr) puts ("No DiskOnChip found\n"); } } - -#endif /* (CONFIG_COMMANDS & CFG_CMD_DOC) */