22 #include <asm/div64.h>
24 #include <linux/module.h>
28 #include <linux/slab.h>
29 #include <linux/sched.h>
31 #define PRINT_PREF KERN_INFO "mtd_pagetest: "
38 static unsigned char *twopages;
39 static unsigned char *writebuf;
40 static unsigned char *boundary;
41 static unsigned char *bbt;
48 static unsigned long next = 1;
50 static inline unsigned int simple_rand(
void)
53 return (
unsigned int)((
next / 65536) % 32768);
56 static inline void simple_srand(
unsigned long seed)
61 static void set_random_data(
unsigned char *
buf,
size_t len)
65 for (i = 0; i < len; ++
i)
66 buf[i] = simple_rand();
69 static int erase_eraseblock(
int ebnum)
95 static int write_eraseblock(
int ebnum)
101 set_random_data(writebuf, mtd->
erasesize);
111 static int verify_eraseblock(
int ebnum)
120 for (i = 0; i < ebcnt && bbt[
i]; ++
i)
124 for (i = 0; i < ebcnt && bbt[ebcnt - i - 1]; ++
i)
127 set_random_data(writebuf, mtd->
erasesize);
128 for (j = 0; j < pgcnt - 1; ++
j, addr += pgsize) {
131 if (mtd_is_bitflip(err))
139 if (mtd_is_bitflip(err))
148 if (mtd_is_bitflip(err))
162 if (addr <= addrn - pgsize - pgsize && !bbt[ebnum + 1]) {
163 unsigned long oldnext =
next;
166 if (mtd_is_bitflip(err))
174 if (mtd_is_bitflip(err))
183 if (mtd_is_bitflip(err))
191 set_random_data(boundary + pgsize, pgsize);
202 static int crosstest(
void)
206 loff_t
addr, addr0, addrn;
207 unsigned char *pp1, *pp2, *pp3, *pp4;
218 memset(pp1, 0, pgsize * 4);
221 for (i = 0; i < ebcnt && bbt[
i]; ++
i)
225 for (i = 0; i < ebcnt && bbt[ebcnt - i - 1]; ++
i)
229 addr = addrn - pgsize - pgsize;
230 err =
mtd_read(mtd, addr, pgsize, &read, pp1);
231 if (mtd_is_bitflip(err))
233 if (err || read != pgsize) {
241 addr = addrn - pgsize - pgsize - pgsize;
242 err =
mtd_read(mtd, addr, pgsize, &read, pp1);
243 if (mtd_is_bitflip(err))
245 if (err || read != pgsize) {
255 err =
mtd_read(mtd, addr, pgsize, &read, pp2);
256 if (mtd_is_bitflip(err))
258 if (err || read != pgsize) {
266 addr = addrn - pgsize;
268 err =
mtd_read(mtd, addr, pgsize, &read, pp3);
269 if (mtd_is_bitflip(err))
271 if (err || read != pgsize) {
281 err =
mtd_read(mtd, addr, pgsize, &read, pp4);
282 if (mtd_is_bitflip(err))
284 if (err || read != pgsize) {
294 if (
memcmp(pp2, pp4, pgsize)) {
303 static int erasecrosstest(
void)
305 size_t read, written;
306 int err = 0,
i, ebnum, ebnum2;
308 char *readbuf = twopages;
314 for (i = 0; i < ebcnt && bbt[
i]; ++
i) {
320 while (ebnum2 && bbt[ebnum2])
324 err = erase_eraseblock(ebnum);
329 set_random_data(writebuf, pgsize);
330 strcpy(writebuf,
"There is no data like this!");
331 err =
mtd_write(mtd, addr0, pgsize, &written, writebuf);
332 if (err || written != pgsize) {
335 return err ? err : -1;
339 memset(readbuf, 0, pgsize);
340 err =
mtd_read(mtd, addr0, pgsize, &read, readbuf);
341 if (mtd_is_bitflip(err))
343 if (err || read != pgsize) {
346 return err ? err : -1;
350 if (
memcmp(writebuf, readbuf, pgsize)) {
357 err = erase_eraseblock(ebnum);
362 set_random_data(writebuf, pgsize);
363 strcpy(writebuf,
"There is no data like this!");
364 err =
mtd_write(mtd, addr0, pgsize, &written, writebuf);
365 if (err || written != pgsize) {
368 return err ? err : -1;
372 err = erase_eraseblock(ebnum2);
377 memset(readbuf, 0, pgsize);
378 err =
mtd_read(mtd, addr0, pgsize, &read, readbuf);
379 if (mtd_is_bitflip(err))
381 if (err || read != pgsize) {
384 return err ? err : -1;
388 if (
memcmp(writebuf, readbuf, pgsize)) {
399 static int erasetest(
void)
401 size_t read, written;
402 int err = 0,
i, ebnum, ok = 1;
409 for (i = 0; i < ebcnt && bbt[
i]; ++
i) {
415 err = erase_eraseblock(ebnum);
420 set_random_data(writebuf, pgsize);
421 err =
mtd_write(mtd, addr0, pgsize, &written, writebuf);
422 if (err || written != pgsize) {
425 return err ? err : -1;
429 err = erase_eraseblock(ebnum);
434 err =
mtd_read(mtd, addr0, pgsize, &read, twopages);
435 if (mtd_is_bitflip(err))
437 if (err || read != pgsize) {
440 return err ? err : -1;
445 for (i = 0; i < pgsize; ++
i)
446 if (twopages[i] != 0xff) {
460 static int is_block_bad(
int ebnum)
471 static int scan_for_bad_eraseblocks(
void)
482 for (i = 0; i < ebcnt; ++
i) {
483 bbt[
i] = is_block_bad(i) ? 1 : 0;
492 static int __init mtd_pagetest_init(
void)
499 printk(
KERN_INFO "=================================================\n");
502 printk(
PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
503 printk(
KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
528 "page size %u, count of eraseblocks %u, pages per "
529 "eraseblock %u, OOB size %u\n",
531 pgsize, ebcnt, pgcnt, mtd->
oobsize);
551 err = scan_for_bad_eraseblocks();
557 for (i = 0; i < ebcnt; ++
i) {
560 err = erase_eraseblock(i);
570 for (i = 0; i < ebcnt; ++
i) {
573 err = write_eraseblock(i);
585 for (i = 0; i < ebcnt; ++
i) {
588 err = verify_eraseblock(i);
601 err = erasecrosstest();
619 printk(
KERN_INFO "=================================================\n");
624 static void __exit mtd_pagetest_exit(
void)