[PATCH 3/3] nandtest: report estimated BER
Ben Gardiner
bengardiner at nanometrics.ca
Tue Aug 9 16:57:29 EDT 2011
The nandtest program will excercise every block on a given mtd device by
writing to it and monitoring the ECC corrections and failures.
Augment this utility to report an estimate of the program-disturb raw BER
based on the writesize, eccsize, number of passes and ecc corrections stat.
Signed-off-by: Ben Gardiner <bengardiner at nanometrics.ca>
---
This estimate relies on the eccbytes field of the now deprecated struct
nand_ecclayout_user. Since I found it useful I thought I should propose
the change anyways. I'm open to modifications to retrieve 'eccbytes' the
right way.
---
nandtest.c | 25 ++++++++++++++++++++++++-
1 files changed, 24 insertions(+), 1 deletions(-)
diff --git a/nandtest.c b/nandtest.c
index dc28d09..35e3e94 100644
--- a/nandtest.c
+++ b/nandtest.c
@@ -4,6 +4,7 @@
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -32,7 +33,8 @@ void usage(void)
}
struct mtd_info_user meminfo;
-struct mtd_ecc_stats oldstats, newstats;
+struct mtd_ecc_stats origstats, oldstats, newstats;
+struct nand_ecclayout_user ecclayout;
int fd;
int markbad=0;
int seed;
@@ -126,6 +128,16 @@ int erase_and_write(loff_t ofs, unsigned char *data, unsigned char *rbuf)
return 0;
}
+void report_raw_ber(unsigned long len)
+{
+ unsigned long corrections = newstats.corrected - origstats.corrected;
+ long double rate = (long double) corrections;
+ rate /= (long double) len;
+ rate /= CHAR_BIT;
+
+ printf("%lu bit corrections in %lu bytes. Estimated program-disturb raw BER: %Lg\n",
+ corrections, len, rate);
+}
/*
* Main program
@@ -204,6 +216,12 @@ int main(int argc, char **argv)
exit(1);
}
+ if (ioctl(fd, ECCGETLAYOUT, &ecclayout)) {
+ perror("ECCGETLAYOUT");
+ close(fd);
+ exit(1);
+ }
+
if (length == -1)
length = meminfo.size;
@@ -243,6 +261,8 @@ int main(int argc, char **argv)
printf("Bad blocks : %d\n", oldstats.badblocks);
printf("BBT blocks : %d\n", oldstats.bbtblocks);
+ origstats = oldstats;
+
for (pass = 0; pass < nr_passes; pass++) {
loff_t test_ofs;
@@ -281,6 +301,9 @@ int main(int argc, char **argv)
}
printf("\nFinished pass %d successfully\n", pass+1);
}
+
+ report_raw_ber(length * (meminfo.erasesize + meminfo.erasesize/meminfo.writesize * ecclayout.eccbytes) *(unsigned long)nr_passes);
+
/* Return happy */
return 0;
}
--
1.7.3.5
More information about the linux-mtd
mailing list