From 2c629e07b87746d49e267db286f096541ef01d90 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 9 Aug 2007 16:23:19 +0800 Subject: Add nand integrity testing utility. Signed-off-by: David Woodhouse --- nandtest.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 nandtest.c (limited to 'nandtest.c') diff --git a/nandtest.c b/nandtest.c new file mode 100644 index 0000000..254d41f --- /dev/null +++ b/nandtest.c @@ -0,0 +1,172 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "mtd/mtd-user.h" + + + +/* + * Main program + */ +int main(int argc, char **argv) +{ + int fd; + int block, i; + unsigned char *wbuf, *rbuf; + struct mtd_info_user meminfo; + struct mtd_ecc_stats oldstats, newstats; + int seed; + int pass; + int nr_passes = 1; + + if (argc == 4) { + seed = atol(argv[3]); + argc = 3; + } + if (argc == 3) { + nr_passes = atol(argv[2]); + argc = 2; + } + if (argc != 2) { + fprintf(stderr, "usage: %s [] []\n", + (strrchr(argv[0],',')?:argv[0]-1)+1); + exit(1); + } + + fd = open(argv[1], O_RDWR); + if (fd < 0) { + perror("open"); + exit(1); + } + + if (ioctl(fd, MEMGETINFO, &meminfo)) { + perror("MEMGETINFO"); + close(fd); + exit(1); + } + + wbuf = malloc(meminfo.erasesize * 2); + if (!wbuf) { + fprintf(stderr, "Could not allocate %d bytes for buffer\n", + meminfo.erasesize * 2); + exit(1); + } + rbuf = wbuf + meminfo.erasesize; + + if (ioctl(fd, ECCGETSTATS, &oldstats)) { + perror("ECCGETSTATS"); + close(fd); + exit(1); + } + + printf("ECC corrections: %d\n", oldstats.corrected); + printf("ECC failures : %d\n", oldstats.failed); + printf("Bad blocks : %d\n", oldstats.badblocks); + printf("BBT blocks : %d\n", oldstats.bbtblocks); + + for (pass = 0; pass < nr_passes; pass++) { + + for (block = 0; block < meminfo.size / meminfo.erasesize ; block++) { + loff_t ofs = block * meminfo.erasesize; + struct erase_info_user er; + ssize_t len; + + seed = rand(); + srand(seed); + + if (ioctl(fd, MEMGETBADBLOCK, &ofs)) { + printf("\rBad block at 0x%08x\n", (unsigned)ofs); + continue; + } + + printf("\r%08x: erasing... ", (unsigned)ofs); + fflush(stdout); + + er.start = ofs; + er.length = meminfo.erasesize; + + if (ioctl(fd, MEMERASE, &er)) { + perror("MEMERASE"); + exit(1); + } + + printf("\r%08x: writing...", (unsigned)ofs); + fflush(stdout); + + for (i=0; i oldstats.corrected) { + printf("\nECC corrected at %08x\n", (unsigned) ofs); + newstats.corrected = oldstats.corrected; + } + if (newstats.failed > oldstats.failed) { + printf("\nECC failed at %08x\n", (unsigned) ofs); + newstats.corrected = oldstats.corrected; + } + if (len < meminfo.erasesize) + exit(1); + + printf("\r%08x: checking...", (unsigned)ofs); + fflush(stdout); + + if (memcmp(wbuf, rbuf, meminfo.erasesize)) { + printf("\n"); + fprintf(stderr, "compare failed. seed %d\n", seed); + for (i=0; i