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