3ba2a77dbdaa26427dfee0bfb2fb9aadd342c1da
[linux-3.10.git] / drivers / mtd / tests / mtd_pagetest.c
1 /*
2  * Copyright (C) 2006-2008 Nokia Corporation
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 as published by
6  * the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License along with
14  * this program; see the file COPYING. If not, write to the Free Software
15  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16  *
17  * Test page read and write on MTD device.
18  *
19  * Author: Adrian Hunter <ext-adrian.hunter@nokia.com>
20  */
21
22 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23
24 #include <asm/div64.h>
25 #include <linux/init.h>
26 #include <linux/module.h>
27 #include <linux/moduleparam.h>
28 #include <linux/err.h>
29 #include <linux/mtd/mtd.h>
30 #include <linux/slab.h>
31 #include <linux/sched.h>
32
33 static int dev = -EINVAL;
34 module_param(dev, int, S_IRUGO);
35 MODULE_PARM_DESC(dev, "MTD device number to use");
36
37 static struct mtd_info *mtd;
38 static unsigned char *twopages;
39 static unsigned char *writebuf;
40 static unsigned char *boundary;
41 static unsigned char *bbt;
42
43 static int pgsize;
44 static int bufsize;
45 static int ebcnt;
46 static int pgcnt;
47 static int errcnt;
48 static unsigned long next = 1;
49
50 static inline unsigned int simple_rand(void)
51 {
52         next = next * 1103515245 + 12345;
53         return (unsigned int)((next / 65536) % 32768);
54 }
55
56 static inline void simple_srand(unsigned long seed)
57 {
58         next = seed;
59 }
60
61 static void set_random_data(unsigned char *buf, size_t len)
62 {
63         size_t i;
64
65         for (i = 0; i < len; ++i)
66                 buf[i] = simple_rand();
67 }
68
69 static int erase_eraseblock(int ebnum)
70 {
71         int err;
72         struct erase_info ei;
73         loff_t addr = ebnum * mtd->erasesize;
74
75         memset(&ei, 0, sizeof(struct erase_info));
76         ei.mtd  = mtd;
77         ei.addr = addr;
78         ei.len  = mtd->erasesize;
79
80         err = mtd_erase(mtd, &ei);
81         if (err) {
82                 pr_err("error %d while erasing EB %d\n", err, ebnum);
83                 return err;
84         }
85
86         if (ei.state == MTD_ERASE_FAILED) {
87                 pr_err("some erase error occurred at EB %d\n",
88                        ebnum);
89                 return -EIO;
90         }
91
92         return 0;
93 }
94
95 static int write_eraseblock(int ebnum)
96 {
97         int err = 0;
98         size_t written;
99         loff_t addr = ebnum * mtd->erasesize;
100
101         set_random_data(writebuf, mtd->erasesize);
102         cond_resched();
103         err = mtd_write(mtd, addr, mtd->erasesize, &written, writebuf);
104         if (err || written != mtd->erasesize)
105                 pr_err("error: write failed at %#llx\n",
106                        (long long)addr);
107
108         return err;
109 }
110
111 static int verify_eraseblock(int ebnum)
112 {
113         uint32_t j;
114         size_t read;
115         int err = 0, i;
116         loff_t addr0, addrn;
117         loff_t addr = ebnum * mtd->erasesize;
118
119         addr0 = 0;
120         for (i = 0; i < ebcnt && bbt[i]; ++i)
121                 addr0 += mtd->erasesize;
122
123         addrn = mtd->size;
124         for (i = 0; i < ebcnt && bbt[ebcnt - i - 1]; ++i)
125                 addrn -= mtd->erasesize;
126
127         set_random_data(writebuf, mtd->erasesize);
128         for (j = 0; j < pgcnt - 1; ++j, addr += pgsize) {
129                 /* Do a read to set the internal dataRAMs to different data */
130                 err = mtd_read(mtd, addr0, bufsize, &read, twopages);
131                 if (mtd_is_bitflip(err))
132                         err = 0;
133                 if (err || read != bufsize) {
134                         pr_err("error: read failed at %#llx\n",
135                                (long long)addr0);
136                         return err;
137                 }
138                 err = mtd_read(mtd, addrn - bufsize, bufsize, &read, twopages);
139                 if (mtd_is_bitflip(err))
140                         err = 0;
141                 if (err || read != bufsize) {
142                         pr_err("error: read failed at %#llx\n",
143                                (long long)(addrn - bufsize));
144                         return err;
145                 }
146                 memset(twopages, 0, bufsize);
147                 err = mtd_read(mtd, addr, bufsize, &read, twopages);
148                 if (mtd_is_bitflip(err))
149                         err = 0;
150                 if (err || read != bufsize) {
151                         pr_err("error: read failed at %#llx\n",
152                                (long long)addr);
153                         break;
154                 }
155                 if (memcmp(twopages, writebuf + (j * pgsize), bufsize)) {
156                         pr_err("error: verify failed at %#llx\n",
157                                (long long)addr);
158                         errcnt += 1;
159                 }
160         }
161         /* Check boundary between eraseblocks */
162         if (addr <= addrn - pgsize - pgsize && !bbt[ebnum + 1]) {
163                 unsigned long oldnext = next;
164                 /* Do a read to set the internal dataRAMs to different data */
165                 err = mtd_read(mtd, addr0, bufsize, &read, twopages);
166                 if (mtd_is_bitflip(err))
167                         err = 0;
168                 if (err || read != bufsize) {
169                         pr_err("error: read failed at %#llx\n",
170                                (long long)addr0);
171                         return err;
172                 }
173                 err = mtd_read(mtd, addrn - bufsize, bufsize, &read, twopages);
174                 if (mtd_is_bitflip(err))
175                         err = 0;
176                 if (err || read != bufsize) {
177                         pr_err("error: read failed at %#llx\n",
178                                (long long)(addrn - bufsize));
179                         return err;
180                 }
181                 memset(twopages, 0, bufsize);
182                 err = mtd_read(mtd, addr, bufsize, &read, twopages);
183                 if (mtd_is_bitflip(err))
184                         err = 0;
185                 if (err || read != bufsize) {
186                         pr_err("error: read failed at %#llx\n",
187                                (long long)addr);
188                         return err;
189                 }
190                 memcpy(boundary, writebuf + mtd->erasesize - pgsize, pgsize);
191                 set_random_data(boundary + pgsize, pgsize);
192                 if (memcmp(twopages, boundary, bufsize)) {
193                         pr_err("error: verify failed at %#llx\n",
194                                (long long)addr);
195                         errcnt += 1;
196                 }
197                 next = oldnext;
198         }
199         return err;
200 }
201
202 static int crosstest(void)
203 {
204         size_t read;
205         int err = 0, i;
206         loff_t addr, addr0, addrn;
207         unsigned char *pp1, *pp2, *pp3, *pp4;
208
209         pr_info("crosstest\n");
210         pp1 = kmalloc(pgsize * 4, GFP_KERNEL);
211         if (!pp1) {
212                 pr_err("error: cannot allocate memory\n");
213                 return -ENOMEM;
214         }
215         pp2 = pp1 + pgsize;
216         pp3 = pp2 + pgsize;
217         pp4 = pp3 + pgsize;
218         memset(pp1, 0, pgsize * 4);
219
220         addr0 = 0;
221         for (i = 0; i < ebcnt && bbt[i]; ++i)
222                 addr0 += mtd->erasesize;
223
224         addrn = mtd->size;
225         for (i = 0; i < ebcnt && bbt[ebcnt - i - 1]; ++i)
226                 addrn -= mtd->erasesize;
227
228         /* Read 2nd-to-last page to pp1 */
229         addr = addrn - pgsize - pgsize;
230         err = mtd_read(mtd, addr, pgsize, &read, pp1);
231         if (mtd_is_bitflip(err))
232                 err = 0;
233         if (err || read != pgsize) {
234                 pr_err("error: read failed at %#llx\n",
235                        (long long)addr);
236                 kfree(pp1);
237                 return err;
238         }
239
240         /* Read 3rd-to-last page to pp1 */
241         addr = addrn - pgsize - pgsize - pgsize;
242         err = mtd_read(mtd, addr, pgsize, &read, pp1);
243         if (mtd_is_bitflip(err))
244                 err = 0;
245         if (err || read != pgsize) {
246                 pr_err("error: read failed at %#llx\n",
247                        (long long)addr);
248                 kfree(pp1);
249                 return err;
250         }
251
252         /* Read first page to pp2 */
253         addr = addr0;
254         pr_info("reading page at %#llx\n", (long long)addr);
255         err = mtd_read(mtd, addr, pgsize, &read, pp2);
256         if (mtd_is_bitflip(err))
257                 err = 0;
258         if (err || read != pgsize) {
259                 pr_err("error: read failed at %#llx\n",
260                        (long long)addr);
261                 kfree(pp1);
262                 return err;
263         }
264
265         /* Read last page to pp3 */
266         addr = addrn - pgsize;
267         pr_info("reading page at %#llx\n", (long long)addr);
268         err = mtd_read(mtd, addr, pgsize, &read, pp3);
269         if (mtd_is_bitflip(err))
270                 err = 0;
271         if (err || read != pgsize) {
272                 pr_err("error: read failed at %#llx\n",
273                        (long long)addr);
274                 kfree(pp1);
275                 return err;
276         }
277
278         /* Read first page again to pp4 */
279         addr = addr0;
280         pr_info("reading page at %#llx\n", (long long)addr);
281         err = mtd_read(mtd, addr, pgsize, &read, pp4);
282         if (mtd_is_bitflip(err))
283                 err = 0;
284         if (err || read != pgsize) {
285                 pr_err("error: read failed at %#llx\n",
286                        (long long)addr);
287                 kfree(pp1);
288                 return err;
289         }
290
291         /* pp2 and pp4 should be the same */
292         pr_info("verifying pages read at %#llx match\n",
293                (long long)addr0);
294         if (memcmp(pp2, pp4, pgsize)) {
295                 pr_err("verify failed!\n");
296                 errcnt += 1;
297         } else if (!err)
298                 pr_info("crosstest ok\n");
299         kfree(pp1);
300         return err;
301 }
302
303 static int erasecrosstest(void)
304 {
305         size_t read, written;
306         int err = 0, i, ebnum, ebnum2;
307         loff_t addr0;
308         char *readbuf = twopages;
309
310         pr_info("erasecrosstest\n");
311
312         ebnum = 0;
313         addr0 = 0;
314         for (i = 0; i < ebcnt && bbt[i]; ++i) {
315                 addr0 += mtd->erasesize;
316                 ebnum += 1;
317         }
318
319         ebnum2 = ebcnt - 1;
320         while (ebnum2 && bbt[ebnum2])
321                 ebnum2 -= 1;
322
323         pr_info("erasing block %d\n", ebnum);
324         err = erase_eraseblock(ebnum);
325         if (err)
326                 return err;
327
328         pr_info("writing 1st page of block %d\n", 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) {
333                 pr_info("error: write failed at %#llx\n",
334                        (long long)addr0);
335                 return err ? err : -1;
336         }
337
338         pr_info("reading 1st page of block %d\n", ebnum);
339         memset(readbuf, 0, pgsize);
340         err = mtd_read(mtd, addr0, pgsize, &read, readbuf);
341         if (mtd_is_bitflip(err))
342                 err = 0;
343         if (err || read != pgsize) {
344                 pr_err("error: read failed at %#llx\n",
345                        (long long)addr0);
346                 return err ? err : -1;
347         }
348
349         pr_info("verifying 1st page of block %d\n", ebnum);
350         if (memcmp(writebuf, readbuf, pgsize)) {
351                 pr_err("verify failed!\n");
352                 errcnt += 1;
353                 return -1;
354         }
355
356         pr_info("erasing block %d\n", ebnum);
357         err = erase_eraseblock(ebnum);
358         if (err)
359                 return err;
360
361         pr_info("writing 1st page of block %d\n", 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) {
366                 pr_err("error: write failed at %#llx\n",
367                        (long long)addr0);
368                 return err ? err : -1;
369         }
370
371         pr_info("erasing block %d\n", ebnum2);
372         err = erase_eraseblock(ebnum2);
373         if (err)
374                 return err;
375
376         pr_info("reading 1st page of block %d\n", ebnum);
377         memset(readbuf, 0, pgsize);
378         err = mtd_read(mtd, addr0, pgsize, &read, readbuf);
379         if (mtd_is_bitflip(err))
380                 err = 0;
381         if (err || read != pgsize) {
382                 pr_err("error: read failed at %#llx\n",
383                        (long long)addr0);
384                 return err ? err : -1;
385         }
386
387         pr_info("verifying 1st page of block %d\n", ebnum);
388         if (memcmp(writebuf, readbuf, pgsize)) {
389                 pr_err("verify failed!\n");
390                 errcnt += 1;
391                 return -1;
392         }
393
394         if (!err)
395                 pr_info("erasecrosstest ok\n");
396         return err;
397 }
398
399 static int erasetest(void)
400 {
401         size_t read, written;
402         int err = 0, i, ebnum, ok = 1;
403         loff_t addr0;
404
405         pr_info("erasetest\n");
406
407         ebnum = 0;
408         addr0 = 0;
409         for (i = 0; i < ebcnt && bbt[i]; ++i) {
410                 addr0 += mtd->erasesize;
411                 ebnum += 1;
412         }
413
414         pr_info("erasing block %d\n", ebnum);
415         err = erase_eraseblock(ebnum);
416         if (err)
417                 return err;
418
419         pr_info("writing 1st page of block %d\n", ebnum);
420         set_random_data(writebuf, pgsize);
421         err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
422         if (err || written != pgsize) {
423                 pr_err("error: write failed at %#llx\n",
424                        (long long)addr0);
425                 return err ? err : -1;
426         }
427
428         pr_info("erasing block %d\n", ebnum);
429         err = erase_eraseblock(ebnum);
430         if (err)
431                 return err;
432
433         pr_info("reading 1st page of block %d\n", ebnum);
434         err = mtd_read(mtd, addr0, pgsize, &read, twopages);
435         if (mtd_is_bitflip(err))
436                 err = 0;
437         if (err || read != pgsize) {
438                 pr_err("error: read failed at %#llx\n",
439                        (long long)addr0);
440                 return err ? err : -1;
441         }
442
443         pr_info("verifying 1st page of block %d is all 0xff\n",
444                ebnum);
445         for (i = 0; i < pgsize; ++i)
446                 if (twopages[i] != 0xff) {
447                         pr_err("verifying all 0xff failed at %d\n",
448                                i);
449                         errcnt += 1;
450                         ok = 0;
451                         break;
452                 }
453
454         if (ok && !err)
455                 pr_info("erasetest ok\n");
456
457         return err;
458 }
459
460 static int is_block_bad(int ebnum)
461 {
462         loff_t addr = ebnum * mtd->erasesize;
463         int ret;
464
465         ret = mtd_block_isbad(mtd, addr);
466         if (ret)
467                 pr_info("block %d is bad\n", ebnum);
468         return ret;
469 }
470
471 static int scan_for_bad_eraseblocks(void)
472 {
473         int i, bad = 0;
474
475         bbt = kzalloc(ebcnt, GFP_KERNEL);
476         if (!bbt) {
477                 pr_err("error: cannot allocate memory\n");
478                 return -ENOMEM;
479         }
480
481         pr_info("scanning for bad eraseblocks\n");
482         for (i = 0; i < ebcnt; ++i) {
483                 bbt[i] = is_block_bad(i) ? 1 : 0;
484                 if (bbt[i])
485                         bad += 1;
486                 cond_resched();
487         }
488         pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
489         return 0;
490 }
491
492 static int __init mtd_pagetest_init(void)
493 {
494         int err = 0;
495         uint64_t tmp;
496         uint32_t i;
497
498         printk(KERN_INFO "\n");
499         printk(KERN_INFO "=================================================\n");
500
501         if (dev < 0) {
502                 pr_info("Please specify a valid mtd-device via module paramter\n");
503                 pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
504                 return -EINVAL;
505         }
506
507         pr_info("MTD device: %d\n", dev);
508
509         mtd = get_mtd_device(NULL, dev);
510         if (IS_ERR(mtd)) {
511                 err = PTR_ERR(mtd);
512                 pr_err("error: cannot get MTD device\n");
513                 return err;
514         }
515
516         if (mtd->type != MTD_NANDFLASH) {
517                 pr_info("this test requires NAND flash\n");
518                 goto out;
519         }
520
521         tmp = mtd->size;
522         do_div(tmp, mtd->erasesize);
523         ebcnt = tmp;
524         pgcnt = mtd->erasesize / mtd->writesize;
525         pgsize = mtd->writesize;
526
527         pr_info("MTD device size %llu, eraseblock size %u, "
528                "page size %u, count of eraseblocks %u, pages per "
529                "eraseblock %u, OOB size %u\n",
530                (unsigned long long)mtd->size, mtd->erasesize,
531                pgsize, ebcnt, pgcnt, mtd->oobsize);
532
533         err = -ENOMEM;
534         bufsize = pgsize * 2;
535         writebuf = kmalloc(mtd->erasesize, GFP_KERNEL);
536         if (!writebuf) {
537                 pr_err("error: cannot allocate memory\n");
538                 goto out;
539         }
540         twopages = kmalloc(bufsize, GFP_KERNEL);
541         if (!twopages) {
542                 pr_err("error: cannot allocate memory\n");
543                 goto out;
544         }
545         boundary = kmalloc(bufsize, GFP_KERNEL);
546         if (!boundary) {
547                 pr_err("error: cannot allocate memory\n");
548                 goto out;
549         }
550
551         err = scan_for_bad_eraseblocks();
552         if (err)
553                 goto out;
554
555         /* Erase all eraseblocks */
556         pr_info("erasing whole device\n");
557         for (i = 0; i < ebcnt; ++i) {
558                 if (bbt[i])
559                         continue;
560                 err = erase_eraseblock(i);
561                 if (err)
562                         goto out;
563                 cond_resched();
564         }
565         pr_info("erased %u eraseblocks\n", i);
566
567         /* Write all eraseblocks */
568         simple_srand(1);
569         pr_info("writing whole device\n");
570         for (i = 0; i < ebcnt; ++i) {
571                 if (bbt[i])
572                         continue;
573                 err = write_eraseblock(i);
574                 if (err)
575                         goto out;
576                 if (i % 256 == 0)
577                         pr_info("written up to eraseblock %u\n", i);
578                 cond_resched();
579         }
580         pr_info("written %u eraseblocks\n", i);
581
582         /* Check all eraseblocks */
583         simple_srand(1);
584         pr_info("verifying all eraseblocks\n");
585         for (i = 0; i < ebcnt; ++i) {
586                 if (bbt[i])
587                         continue;
588                 err = verify_eraseblock(i);
589                 if (err)
590                         goto out;
591                 if (i % 256 == 0)
592                         pr_info("verified up to eraseblock %u\n", i);
593                 cond_resched();
594         }
595         pr_info("verified %u eraseblocks\n", i);
596
597         err = crosstest();
598         if (err)
599                 goto out;
600
601         err = erasecrosstest();
602         if (err)
603                 goto out;
604
605         err = erasetest();
606         if (err)
607                 goto out;
608
609         pr_info("finished with %d errors\n", errcnt);
610 out:
611
612         kfree(bbt);
613         kfree(boundary);
614         kfree(twopages);
615         kfree(writebuf);
616         put_mtd_device(mtd);
617         if (err)
618                 pr_info("error %d occurred\n", err);
619         printk(KERN_INFO "=================================================\n");
620         return err;
621 }
622 module_init(mtd_pagetest_init);
623
624 static void __exit mtd_pagetest_exit(void)
625 {
626         return;
627 }
628 module_exit(mtd_pagetest_exit);
629
630 MODULE_DESCRIPTION("NAND page test");
631 MODULE_AUTHOR("Adrian Hunter");
632 MODULE_LICENSE("GPL");