17c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg#include <stdio.h> 27c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg#include <stdlib.h> 37c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg#include <string.h> 47c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg#include <ctype.h> 57c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg#include <errno.h> 67c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg#include <fcntl.h> 7b93e5812faffd3b6c5fb349072413aace31918d8Olivier Bailly#include <unistd.h> 87c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 97c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg#include <mtd/mtd-user.h> 107c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg#include <sys/ioctl.h> 117c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 12b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevågstatic int test_empty(const char *buf, size_t size) 137c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg{ 147c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg while(size--) { 157c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (*buf++ != 0xff) 167c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg return 0; 177c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 187c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg return 1; 197c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg} 207c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 217c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevågint nandread_main(int argc, char **argv) 227c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg{ 237c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg char *devname = NULL; 247c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg char *filename = NULL; 257c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg char *statusfilename = NULL; 267c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg char *statusext = ".stat"; 277c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg int fd; 287c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg int outfd = -1; 297c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg FILE *statusfile = NULL; 307c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg int ret; 317c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg int verbose = 0; 327c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg void *buffer; 33b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg loff_t pos, opos, end, bpos; 34b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg loff_t start = 0, len = 0; 357c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg int c; 367c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg int i; 377c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg int empty_pages = 0; 387c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg int page_count = 0; 397c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg int bad_block; 40b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg int rawmode = 0; 417c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg uint32_t *oob_data; 427c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg uint8_t *oob_fixed; 437c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg size_t spare_size = 64; 447c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg struct mtd_info_user mtdinfo; 457c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg struct mtd_ecc_stats initial_ecc, last_ecc, ecc; 467c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg struct mtd_oob_buf oobbuf; 477c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg struct nand_ecclayout ecclayout; 487c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 497c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg do { 50b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg c = getopt(argc, argv, "d:f:s:S:L:Rhv"); 517c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (c == EOF) 527c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg break; 537c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg switch (c) { 547c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg case 'd': 557c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg devname = optarg; 567c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg break; 577c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg case 'f': 587c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg filename = optarg; 597c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg break; 607c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg case 's': 617c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg spare_size = atoi(optarg); 627c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg break; 63b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg case 'S': 64b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg start = strtoll(optarg, NULL, 0); 65b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg break; 66b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg case 'L': 67b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg len = strtoll(optarg, NULL, 0); 68b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg break; 69b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg case 'R': 70b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg rawmode = 1; 71b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg break; 727c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg case 'v': 737c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg verbose++; 747c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg break; 757c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg case 'h': 767c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(stderr, "%s [-d <dev>] [-f file] [-s sparesize] [-vh]\n" 777c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg " -d <dev> Read from <dev>\n" 787c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg " -f <file> Write to <file>\n" 797c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg " -s <size> Number of spare bytes in file (default 64)\n" 80b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg " -R Raw mode\n" 81b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg " -S <start> Start offset (default 0)\n" 82b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg " -L <len> Length (default 0)\n" 837c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg " -v Print info\n" 847c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg " -h Print help\n", argv[0]); 857c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg return -1; 867c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg case '?': 877c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(stderr, "%s: invalid option -%c\n", 887c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg argv[0], optopt); 897c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg exit(1); 907c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 917c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } while (1); 927c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 937c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (optind < argc) { 947c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(stderr, "%s: extra arguments\n", argv[0]); 957c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg return 1; 967c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 977c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (!devname) { 987c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(stderr, "%s: specify device name\n", argv[0]); 997c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg return 1; 1007c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 1017c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 1027c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fd = open(devname, O_RDONLY); 1037c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (fd < 0) { 1047c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(stderr, "cannot open %s, %s\n", devname, strerror(errno)); 1057c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg return 1; 1067c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 1077c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 1087c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (filename) { 1097c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg outfd = creat(filename, 0666); 1107c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (outfd < 0) { 1117c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(stderr, "cannot open %s, %s\n", filename, strerror(errno)); 1127c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg return 1; 1137c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 1147c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg statusfilename = malloc(strlen(filename) + strlen(statusext) + 1); 1157c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg strcpy(statusfilename, filename); 1167c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg strcat(statusfilename, statusext); 1177c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg statusfile = fopen(statusfilename, "w+"); 1187c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (!statusfile) { 1197c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(stderr, "cannot open %s, %s\n", statusfilename, strerror(errno)); 1207c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg return 1; 1217c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 1227c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 1237c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 1247c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg ret = ioctl(fd, MEMGETINFO, &mtdinfo); 1257c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (ret) { 1267c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(stderr, "failed get mtd info for %s, %s\n", 1277c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg devname, strerror(errno)); 1287c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg return 1; 1297c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 1307c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 1317c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (verbose) { 1327c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("size: %u\n", mtdinfo.size); 1337c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("erase size: %u\n", mtdinfo.erasesize); 1347c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("write size: %u\n", mtdinfo.writesize); 1357c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("oob size: %u\n", mtdinfo.oobsize); 1367c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 1377c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 1387c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg buffer = malloc(mtdinfo.writesize + mtdinfo.oobsize + spare_size); 1397c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (!buffer) { 1407c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(stderr, "failed allocate readbuffer size %u\n", 1417c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg mtdinfo.writesize + mtdinfo.oobsize); 1427c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg return 1; 1437c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 1447c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 1457c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg oobbuf.length = mtdinfo.oobsize; 1467c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg oob_data = (uint32_t *)((uint8_t *)buffer + mtdinfo.writesize); 147b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg memset(oob_data, 0xff, mtdinfo.oobsize + spare_size); 1487c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg oobbuf.ptr = (uint8_t *)oob_data + spare_size; 1497c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 1507c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg ret = ioctl(fd, ECCGETLAYOUT, &ecclayout); 1517c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (ret) { 1527c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(stderr, "failed get ecc layout for %s, %s\n", 1537c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg devname, strerror(errno)); 1547c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg return 1; 1557c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 1567c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (verbose) { 1577c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("ecc bytes: %u\n", ecclayout.eccbytes); 1587c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("oobavail: %u\n", ecclayout.oobavail); 1597c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 1607c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (ecclayout.oobavail > spare_size) 1617c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("oobavail, %d > image spare size, %d\n", ecclayout.oobavail, spare_size); 1627c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 1637c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg ret = ioctl(fd, ECCGETSTATS, &initial_ecc); 1647c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (ret) { 1657c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(stderr, "failed get ecc stats for %s, %s\n", 1667c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg devname, strerror(errno)); 1677c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg return 1; 1687c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 1697c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg last_ecc = initial_ecc; 1707c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 1717c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (verbose) { 1727c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("initial ecc corrected: %u\n", initial_ecc.corrected); 1737c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("initial ecc failed: %u\n", initial_ecc.failed); 1747c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("initial ecc badblocks: %u\n", initial_ecc.badblocks); 1757c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("initial ecc bbtblocks: %u\n", initial_ecc.bbtblocks); 1767c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 1777c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 178b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg if (rawmode) { 179b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg rawmode = mtdinfo.oobsize; 180b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg ret = ioctl(fd, MTDFILEMODE, MTD_MODE_RAW); 181b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg if (ret) { 182b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg fprintf(stderr, "failed set raw mode for %s, %s\n", 183b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg devname, strerror(errno)); 184b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg return 1; 185b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg } 186b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg } 187b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg 188b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg end = len ? (start + len) : mtdinfo.size; 189b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg for (pos = start, opos = 0; pos < end; pos += mtdinfo.writesize) { 1907c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg bad_block = 0; 1917c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (verbose > 3) 1927c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("reading at %llx\n", pos); 1937c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg lseek64(fd, pos, SEEK_SET); 194b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg ret = read(fd, buffer, mtdinfo.writesize + rawmode); 1957c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (ret < (int)mtdinfo.writesize) { 1967c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(stderr, "short read at %llx, %d\n", pos, ret); 1977c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg bad_block = 2; 1987c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 199b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg if (!rawmode) { 200b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg oobbuf.start = pos; 201b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg ret = ioctl(fd, MEMREADOOB, &oobbuf); 202b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg if (ret) { 203b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg fprintf(stderr, "failed to read oob data at %llx, %d\n", pos, ret); 204b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg bad_block = 2; 205b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg } 2067c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 2077c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg ret = ioctl(fd, ECCGETSTATS, &ecc); 2087c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (ret) { 2097c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(stderr, "failed get ecc stats for %s, %s\n", 2107c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg devname, strerror(errno)); 2117c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg return 1; 2127c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 213b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg bpos = pos / mtdinfo.erasesize * mtdinfo.erasesize; 214b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg ret = ioctl(fd, MEMGETBADBLOCK, &bpos); 2157c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (ret && errno != EOPNOTSUPP) { 2167c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("badblock at %llx\n", pos); 2177c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg bad_block = 1; 2187c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 2197c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (ecc.corrected != last_ecc.corrected) 2207c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("ecc corrected, %u, at %llx\n", ecc.corrected - last_ecc.corrected, pos); 2217c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (ecc.failed != last_ecc.failed) 2227c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("ecc failed, %u, at %llx\n", ecc.failed - last_ecc.failed, pos); 2237c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (ecc.badblocks != last_ecc.badblocks) 2247c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("ecc badblocks, %u, at %llx\n", ecc.badblocks - last_ecc.badblocks, pos); 2257c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (ecc.bbtblocks != last_ecc.bbtblocks) 2267c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("ecc bbtblocks, %u, at %llx\n", ecc.bbtblocks - last_ecc.bbtblocks, pos); 2277c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 228b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg if (!rawmode) { 229b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg oob_fixed = (uint8_t *)oob_data; 230b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++) { 231b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg int len = ecclayout.oobfree[i].length; 232b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg if (oob_fixed + len > oobbuf.ptr) 233b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg len = oobbuf.ptr - oob_fixed; 234b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg if (len) { 235b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg memcpy(oob_fixed, oobbuf.ptr + ecclayout.oobfree[i].offset, len); 236b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg oob_fixed += len; 237b6b8793b8b6dad500f6884539e47efb4c161576aArve Hjønnevåg } 2387c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 2397c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 2407c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 2417c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (outfd >= 0) { 2427c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg ret = write(outfd, buffer, mtdinfo.writesize + spare_size); 2437c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (ret < (int)(mtdinfo.writesize + spare_size)) { 2447c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(stderr, "short write at %llx, %d\n", pos, ret); 2457c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg close(outfd); 2467c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg outfd = -1; 2477c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 2487c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (ecc.corrected != last_ecc.corrected) 2497c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(statusfile, "%08llx: ecc corrected\n", opos); 2507c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (ecc.failed != last_ecc.failed) 2517c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(statusfile, "%08llx: ecc failed\n", opos); 2527c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (bad_block == 1) 2537c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(statusfile, "%08llx: badblock\n", opos); 2547c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (bad_block == 2) 2557c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(statusfile, "%08llx: read error\n", opos); 2567c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg opos += mtdinfo.writesize + spare_size; 2577c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 2587c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 2597c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg last_ecc = ecc; 2607c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg page_count++; 2617c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (test_empty(buffer, mtdinfo.writesize + mtdinfo.oobsize + spare_size)) 2627c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg empty_pages++; 2637c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg else if (verbose > 2 || (verbose > 1 && !(pos & (mtdinfo.erasesize - 1)))) 2647c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("page at %llx (%d oobbytes): %08x %08x %08x %08x " 2657c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg "%08x %08x %08x %08x\n", pos, oobbuf.start, 2667c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg oob_data[0], oob_data[1], oob_data[2], oob_data[3], 2677c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg oob_data[4], oob_data[5], oob_data[6], oob_data[7]); 2687c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 2697c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 2707c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (outfd >= 0) { 2717c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(statusfile, "read %d pages, %d empty\n", page_count, empty_pages); 2727c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(statusfile, "total ecc corrected, %u\n", ecc.corrected - initial_ecc.corrected); 2737c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(statusfile, "total ecc failed, %u\n", ecc.failed - initial_ecc.failed); 2747c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(statusfile, "total ecc badblocks, %u\n", ecc.badblocks - initial_ecc.badblocks); 2757c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg fprintf(statusfile, "total ecc bbtblocks, %u\n", ecc.bbtblocks - initial_ecc.bbtblocks); 2767c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 2777c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg if (verbose) { 2787c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("total ecc corrected, %u\n", ecc.corrected - initial_ecc.corrected); 2797c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("total ecc failed, %u\n", ecc.failed - initial_ecc.failed); 2807c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("total ecc badblocks, %u\n", ecc.badblocks - initial_ecc.badblocks); 2817c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("total ecc bbtblocks, %u\n", ecc.bbtblocks - initial_ecc.bbtblocks); 2827c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg } 2837c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg printf("read %d pages, %d empty\n", page_count, empty_pages); 2847c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg 2857c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg return 0; 2867c953d04bcc9070a1bce171e979c5201dd39325bArve Hjønnevåg} 287