GNU Linux-libre 4.9.309-gnu1
[releases.git] / drivers / mtd / tests / oobtest.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 OOB 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 #include <linux/random.h>
33
34 #include "mtd_test.h"
35
36 static int dev = -EINVAL;
37 static int bitflip_limit;
38 module_param(dev, int, S_IRUGO);
39 MODULE_PARM_DESC(dev, "MTD device number to use");
40 module_param(bitflip_limit, int, S_IRUGO);
41 MODULE_PARM_DESC(bitflip_limit, "Max. allowed bitflips per page");
42
43 static struct mtd_info *mtd;
44 static unsigned char *readbuf;
45 static unsigned char *writebuf;
46 static unsigned char *bbt;
47
48 static int ebcnt;
49 static int pgcnt;
50 static int errcnt;
51 static int use_offset;
52 static int use_len;
53 static int use_len_max;
54 static int vary_offset;
55 static struct rnd_state rnd_state;
56
57 static void do_vary_offset(void)
58 {
59         use_len -= 1;
60         if (use_len < 1) {
61                 use_offset += 1;
62                 if (use_offset >= use_len_max)
63                         use_offset = 0;
64                 use_len = use_len_max - use_offset;
65         }
66 }
67
68 static int write_eraseblock(int ebnum)
69 {
70         int i;
71         struct mtd_oob_ops ops;
72         int err = 0;
73         loff_t addr = (loff_t)ebnum * mtd->erasesize;
74
75         prandom_bytes_state(&rnd_state, writebuf, use_len_max * pgcnt);
76         for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) {
77                 ops.mode      = MTD_OPS_AUTO_OOB;
78                 ops.len       = 0;
79                 ops.retlen    = 0;
80                 ops.ooblen    = use_len;
81                 ops.oobretlen = 0;
82                 ops.ooboffs   = use_offset;
83                 ops.datbuf    = NULL;
84                 ops.oobbuf    = writebuf + (use_len_max * i) + use_offset;
85                 err = mtd_write_oob(mtd, addr, &ops);
86                 if (err || ops.oobretlen != use_len) {
87                         pr_err("error: writeoob failed at %#llx\n",
88                                (long long)addr);
89                         pr_err("error: use_len %d, use_offset %d\n",
90                                use_len, use_offset);
91                         errcnt += 1;
92                         return err ? err : -1;
93                 }
94                 if (vary_offset)
95                         do_vary_offset();
96         }
97
98         return err;
99 }
100
101 static int write_whole_device(void)
102 {
103         int err;
104         unsigned int i;
105
106         pr_info("writing OOBs of whole device\n");
107         for (i = 0; i < ebcnt; ++i) {
108                 if (bbt[i])
109                         continue;
110                 err = write_eraseblock(i);
111                 if (err)
112                         return err;
113                 if (i % 256 == 0)
114                         pr_info("written up to eraseblock %u\n", i);
115
116                 err = mtdtest_relax();
117                 if (err)
118                         return err;
119         }
120         pr_info("written %u eraseblocks\n", i);
121         return 0;
122 }
123
124 /*
125  * Display the address, offset and data bytes at comparison failure.
126  * Return number of bitflips encountered.
127  */
128 static size_t memcmpshowoffset(loff_t addr, loff_t offset, const void *cs,
129                                const void *ct, size_t count)
130 {
131         const unsigned char *su1, *su2;
132         int res;
133         size_t i = 0;
134         size_t bitflips = 0;
135
136         for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--, i++) {
137                 res = *su1 ^ *su2;
138                 if (res) {
139                         pr_info("error @addr[0x%lx:0x%lx] 0x%x -> 0x%x diff 0x%x\n",
140                                 (unsigned long)addr, (unsigned long)offset + i,
141                                 *su1, *su2, res);
142                         bitflips += hweight8(res);
143                 }
144         }
145
146         return bitflips;
147 }
148
149 #define memcmpshow(addr, cs, ct, count) memcmpshowoffset((addr), 0, (cs), (ct),\
150                                                          (count))
151
152 /*
153  * Compare with 0xff and show the address, offset and data bytes at
154  * comparison failure. Return number of bitflips encountered.
155  */
156 static size_t memffshow(loff_t addr, loff_t offset, const void *cs,
157                         size_t count)
158 {
159         const unsigned char *su1;
160         int res;
161         size_t i = 0;
162         size_t bitflips = 0;
163
164         for (su1 = cs; 0 < count; ++su1, count--, i++) {
165                 res = *su1 ^ 0xff;
166                 if (res) {
167                         pr_info("error @addr[0x%lx:0x%lx] 0x%x -> 0xff diff 0x%x\n",
168                                 (unsigned long)addr, (unsigned long)offset + i,
169                                 *su1, res);
170                         bitflips += hweight8(res);
171                 }
172         }
173
174         return bitflips;
175 }
176
177 static int verify_eraseblock(int ebnum)
178 {
179         int i;
180         struct mtd_oob_ops ops;
181         int err = 0;
182         loff_t addr = (loff_t)ebnum * mtd->erasesize;
183         size_t bitflips;
184
185         prandom_bytes_state(&rnd_state, writebuf, use_len_max * pgcnt);
186         for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) {
187                 ops.mode      = MTD_OPS_AUTO_OOB;
188                 ops.len       = 0;
189                 ops.retlen    = 0;
190                 ops.ooblen    = use_len;
191                 ops.oobretlen = 0;
192                 ops.ooboffs   = use_offset;
193                 ops.datbuf    = NULL;
194                 ops.oobbuf    = readbuf;
195                 err = mtd_read_oob(mtd, addr, &ops);
196                 if (mtd_is_bitflip(err))
197                         err = 0;
198
199                 if (err || ops.oobretlen != use_len) {
200                         pr_err("error: readoob failed at %#llx\n",
201                                (long long)addr);
202                         errcnt += 1;
203                         return err ? err : -1;
204                 }
205
206                 bitflips = memcmpshow(addr, readbuf,
207                                       writebuf + (use_len_max * i) + use_offset,
208                                       use_len);
209                 if (bitflips > bitflip_limit) {
210                         pr_err("error: verify failed at %#llx\n",
211                                (long long)addr);
212                         errcnt += 1;
213                         if (errcnt > 1000) {
214                                 pr_err("error: too many errors\n");
215                                 return -1;
216                         }
217                 } else if (bitflips) {
218                         pr_info("ignoring error as within bitflip_limit\n");
219                 }
220
221                 if (use_offset != 0 || use_len < mtd->oobavail) {
222                         int k;
223
224                         ops.mode      = MTD_OPS_AUTO_OOB;
225                         ops.len       = 0;
226                         ops.retlen    = 0;
227                         ops.ooblen    = mtd->oobavail;
228                         ops.oobretlen = 0;
229                         ops.ooboffs   = 0;
230                         ops.datbuf    = NULL;
231                         ops.oobbuf    = readbuf;
232                         err = mtd_read_oob(mtd, addr, &ops);
233                         if (mtd_is_bitflip(err))
234                                 err = 0;
235
236                         if (err || ops.oobretlen != mtd->oobavail) {
237                                 pr_err("error: readoob failed at %#llx\n",
238                                                 (long long)addr);
239                                 errcnt += 1;
240                                 return err ? err : -1;
241                         }
242                         bitflips = memcmpshowoffset(addr, use_offset,
243                                                     readbuf + use_offset,
244                                                     writebuf + (use_len_max * i) + use_offset,
245                                                     use_len);
246
247                         /* verify pre-offset area for 0xff */
248                         bitflips += memffshow(addr, 0, readbuf, use_offset);
249
250                         /* verify post-(use_offset + use_len) area for 0xff */
251                         k = use_offset + use_len;
252                         bitflips += memffshow(addr, k, readbuf + k,
253                                               mtd->oobavail - k);
254
255                         if (bitflips > bitflip_limit) {
256                                 pr_err("error: verify failed at %#llx\n",
257                                                 (long long)addr);
258                                 errcnt += 1;
259                                 if (errcnt > 1000) {
260                                         pr_err("error: too many errors\n");
261                                         return -1;
262                                 }
263                         } else if (bitflips) {
264                                 pr_info("ignoring errors as within bitflip limit\n");
265                         }
266                 }
267                 if (vary_offset)
268                         do_vary_offset();
269         }
270         return err;
271 }
272
273 static int verify_eraseblock_in_one_go(int ebnum)
274 {
275         struct mtd_oob_ops ops;
276         int err = 0;
277         loff_t addr = (loff_t)ebnum * mtd->erasesize;
278         size_t len = mtd->oobavail * pgcnt;
279         size_t oobavail = mtd->oobavail;
280         size_t bitflips;
281         int i;
282
283         prandom_bytes_state(&rnd_state, writebuf, len);
284         ops.mode      = MTD_OPS_AUTO_OOB;
285         ops.len       = 0;
286         ops.retlen    = 0;
287         ops.ooblen    = len;
288         ops.oobretlen = 0;
289         ops.ooboffs   = 0;
290         ops.datbuf    = NULL;
291         ops.oobbuf    = readbuf;
292
293         /* read entire block's OOB at one go */
294         err = mtd_read_oob(mtd, addr, &ops);
295         if (mtd_is_bitflip(err))
296                 err = 0;
297
298         if (err || ops.oobretlen != len) {
299                 pr_err("error: readoob failed at %#llx\n",
300                        (long long)addr);
301                 errcnt += 1;
302                 return err ? err : -1;
303         }
304
305         /* verify one page OOB at a time for bitflip per page limit check */
306         for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) {
307                 bitflips = memcmpshow(addr, readbuf + (i * oobavail),
308                                       writebuf + (i * oobavail), oobavail);
309                 if (bitflips > bitflip_limit) {
310                         pr_err("error: verify failed at %#llx\n",
311                                (long long)addr);
312                         errcnt += 1;
313                         if (errcnt > 1000) {
314                                 pr_err("error: too many errors\n");
315                                 return -1;
316                         }
317                 } else if (bitflips) {
318                         pr_info("ignoring error as within bitflip_limit\n");
319                 }
320         }
321
322         return err;
323 }
324
325 static int verify_all_eraseblocks(void)
326 {
327         int err;
328         unsigned int i;
329
330         pr_info("verifying all eraseblocks\n");
331         for (i = 0; i < ebcnt; ++i) {
332                 if (bbt[i])
333                         continue;
334                 err = verify_eraseblock(i);
335                 if (err)
336                         return err;
337                 if (i % 256 == 0)
338                         pr_info("verified up to eraseblock %u\n", i);
339
340                 err = mtdtest_relax();
341                 if (err)
342                         return err;
343         }
344         pr_info("verified %u eraseblocks\n", i);
345         return 0;
346 }
347
348 static int __init mtd_oobtest_init(void)
349 {
350         int err = 0;
351         unsigned int i;
352         uint64_t tmp;
353         struct mtd_oob_ops ops;
354         loff_t addr = 0, addr0;
355
356         printk(KERN_INFO "\n");
357         printk(KERN_INFO "=================================================\n");
358
359         if (dev < 0) {
360                 pr_info("Please specify a valid mtd-device via module parameter\n");
361                 pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
362                 return -EINVAL;
363         }
364
365         pr_info("MTD device: %d\n", dev);
366
367         mtd = get_mtd_device(NULL, dev);
368         if (IS_ERR(mtd)) {
369                 err = PTR_ERR(mtd);
370                 pr_err("error: cannot get MTD device\n");
371                 return err;
372         }
373
374         if (!mtd_type_is_nand(mtd)) {
375                 pr_info("this test requires NAND flash\n");
376                 goto out;
377         }
378
379         tmp = mtd->size;
380         do_div(tmp, mtd->erasesize);
381         ebcnt = tmp;
382         pgcnt = mtd->erasesize / mtd->writesize;
383
384         pr_info("MTD device size %llu, eraseblock size %u, "
385                "page size %u, count of eraseblocks %u, pages per "
386                "eraseblock %u, OOB size %u\n",
387                (unsigned long long)mtd->size, mtd->erasesize,
388                mtd->writesize, ebcnt, pgcnt, mtd->oobsize);
389
390         err = -ENOMEM;
391         readbuf = kmalloc(mtd->erasesize, GFP_KERNEL);
392         if (!readbuf)
393                 goto out;
394         writebuf = kmalloc(mtd->erasesize, GFP_KERNEL);
395         if (!writebuf)
396                 goto out;
397         bbt = kzalloc(ebcnt, GFP_KERNEL);
398         if (!bbt)
399                 goto out;
400
401         err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt);
402         if (err)
403                 goto out;
404
405         use_offset = 0;
406         use_len = mtd->oobavail;
407         use_len_max = mtd->oobavail;
408         vary_offset = 0;
409
410         /* First test: write all OOB, read it back and verify */
411         pr_info("test 1 of 5\n");
412
413         err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt);
414         if (err)
415                 goto out;
416
417         prandom_seed_state(&rnd_state, 1);
418         err = write_whole_device();
419         if (err)
420                 goto out;
421
422         prandom_seed_state(&rnd_state, 1);
423         err = verify_all_eraseblocks();
424         if (err)
425                 goto out;
426
427         /*
428          * Second test: write all OOB, a block at a time, read it back and
429          * verify.
430          */
431         pr_info("test 2 of 5\n");
432
433         err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt);
434         if (err)
435                 goto out;
436
437         prandom_seed_state(&rnd_state, 3);
438         err = write_whole_device();
439         if (err)
440                 goto out;
441
442         /* Check all eraseblocks */
443         prandom_seed_state(&rnd_state, 3);
444         pr_info("verifying all eraseblocks\n");
445         for (i = 0; i < ebcnt; ++i) {
446                 if (bbt[i])
447                         continue;
448                 err = verify_eraseblock_in_one_go(i);
449                 if (err)
450                         goto out;
451                 if (i % 256 == 0)
452                         pr_info("verified up to eraseblock %u\n", i);
453
454                 err = mtdtest_relax();
455                 if (err)
456                         goto out;
457         }
458         pr_info("verified %u eraseblocks\n", i);
459
460         /*
461          * Third test: write OOB at varying offsets and lengths, read it back
462          * and verify.
463          */
464         pr_info("test 3 of 5\n");
465
466         err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt);
467         if (err)
468                 goto out;
469
470         /* Write all eraseblocks */
471         use_offset = 0;
472         use_len = mtd->oobavail;
473         use_len_max = mtd->oobavail;
474         vary_offset = 1;
475         prandom_seed_state(&rnd_state, 5);
476
477         err = write_whole_device();
478         if (err)
479                 goto out;
480
481         /* Check all eraseblocks */
482         use_offset = 0;
483         use_len = mtd->oobavail;
484         use_len_max = mtd->oobavail;
485         vary_offset = 1;
486         prandom_seed_state(&rnd_state, 5);
487         err = verify_all_eraseblocks();
488         if (err)
489                 goto out;
490
491         use_offset = 0;
492         use_len = mtd->oobavail;
493         use_len_max = mtd->oobavail;
494         vary_offset = 0;
495
496         /* Fourth test: try to write off end of device */
497         pr_info("test 4 of 5\n");
498
499         err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt);
500         if (err)
501                 goto out;
502
503         addr0 = 0;
504         for (i = 0; i < ebcnt && bbt[i]; ++i)
505                 addr0 += mtd->erasesize;
506
507         /* Attempt to write off end of OOB */
508         ops.mode      = MTD_OPS_AUTO_OOB;
509         ops.len       = 0;
510         ops.retlen    = 0;
511         ops.ooblen    = 1;
512         ops.oobretlen = 0;
513         ops.ooboffs   = mtd->oobavail;
514         ops.datbuf    = NULL;
515         ops.oobbuf    = writebuf;
516         pr_info("attempting to start write past end of OOB\n");
517         pr_info("an error is expected...\n");
518         err = mtd_write_oob(mtd, addr0, &ops);
519         if (err) {
520                 pr_info("error occurred as expected\n");
521                 err = 0;
522         } else {
523                 pr_err("error: can write past end of OOB\n");
524                 errcnt += 1;
525         }
526
527         /* Attempt to read off end of OOB */
528         ops.mode      = MTD_OPS_AUTO_OOB;
529         ops.len       = 0;
530         ops.retlen    = 0;
531         ops.ooblen    = 1;
532         ops.oobretlen = 0;
533         ops.ooboffs   = mtd->oobavail;
534         ops.datbuf    = NULL;
535         ops.oobbuf    = readbuf;
536         pr_info("attempting to start read past end of OOB\n");
537         pr_info("an error is expected...\n");
538         err = mtd_read_oob(mtd, addr0, &ops);
539         if (mtd_is_bitflip(err))
540                 err = 0;
541
542         if (err) {
543                 pr_info("error occurred as expected\n");
544                 err = 0;
545         } else {
546                 pr_err("error: can read past end of OOB\n");
547                 errcnt += 1;
548         }
549
550         if (bbt[ebcnt - 1])
551                 pr_info("skipping end of device tests because last "
552                        "block is bad\n");
553         else {
554                 /* Attempt to write off end of device */
555                 ops.mode      = MTD_OPS_AUTO_OOB;
556                 ops.len       = 0;
557                 ops.retlen    = 0;
558                 ops.ooblen    = mtd->oobavail + 1;
559                 ops.oobretlen = 0;
560                 ops.ooboffs   = 0;
561                 ops.datbuf    = NULL;
562                 ops.oobbuf    = writebuf;
563                 pr_info("attempting to write past end of device\n");
564                 pr_info("an error is expected...\n");
565                 err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops);
566                 if (err) {
567                         pr_info("error occurred as expected\n");
568                         err = 0;
569                 } else {
570                         pr_err("error: wrote past end of device\n");
571                         errcnt += 1;
572                 }
573
574                 /* Attempt to read off end of device */
575                 ops.mode      = MTD_OPS_AUTO_OOB;
576                 ops.len       = 0;
577                 ops.retlen    = 0;
578                 ops.ooblen    = mtd->oobavail + 1;
579                 ops.oobretlen = 0;
580                 ops.ooboffs   = 0;
581                 ops.datbuf    = NULL;
582                 ops.oobbuf    = readbuf;
583                 pr_info("attempting to read past end of device\n");
584                 pr_info("an error is expected...\n");
585                 err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
586                 if (mtd_is_bitflip(err))
587                         err = 0;
588
589                 if (err) {
590                         pr_info("error occurred as expected\n");
591                         err = 0;
592                 } else {
593                         pr_err("error: read past end of device\n");
594                         errcnt += 1;
595                 }
596
597                 err = mtdtest_erase_eraseblock(mtd, ebcnt - 1);
598                 if (err)
599                         goto out;
600
601                 /* Attempt to write off end of device */
602                 ops.mode      = MTD_OPS_AUTO_OOB;
603                 ops.len       = 0;
604                 ops.retlen    = 0;
605                 ops.ooblen    = mtd->oobavail;
606                 ops.oobretlen = 0;
607                 ops.ooboffs   = 1;
608                 ops.datbuf    = NULL;
609                 ops.oobbuf    = writebuf;
610                 pr_info("attempting to write past end of device\n");
611                 pr_info("an error is expected...\n");
612                 err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops);
613                 if (err) {
614                         pr_info("error occurred as expected\n");
615                         err = 0;
616                 } else {
617                         pr_err("error: wrote past end of device\n");
618                         errcnt += 1;
619                 }
620
621                 /* Attempt to read off end of device */
622                 ops.mode      = MTD_OPS_AUTO_OOB;
623                 ops.len       = 0;
624                 ops.retlen    = 0;
625                 ops.ooblen    = mtd->oobavail;
626                 ops.oobretlen = 0;
627                 ops.ooboffs   = 1;
628                 ops.datbuf    = NULL;
629                 ops.oobbuf    = readbuf;
630                 pr_info("attempting to read past end of device\n");
631                 pr_info("an error is expected...\n");
632                 err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
633                 if (mtd_is_bitflip(err))
634                         err = 0;
635
636                 if (err) {
637                         pr_info("error occurred as expected\n");
638                         err = 0;
639                 } else {
640                         pr_err("error: read past end of device\n");
641                         errcnt += 1;
642                 }
643         }
644
645         /* Fifth test: write / read across block boundaries */
646         pr_info("test 5 of 5\n");
647
648         /* Erase all eraseblocks */
649         err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt);
650         if (err)
651                 goto out;
652
653         /* Write all eraseblocks */
654         prandom_seed_state(&rnd_state, 11);
655         pr_info("writing OOBs of whole device\n");
656         for (i = 0; i < ebcnt - 1; ++i) {
657                 int cnt = 2;
658                 int pg;
659                 size_t sz = mtd->oobavail;
660                 if (bbt[i] || bbt[i + 1])
661                         continue;
662                 addr = (loff_t)(i + 1) * mtd->erasesize - mtd->writesize;
663                 prandom_bytes_state(&rnd_state, writebuf, sz * cnt);
664                 for (pg = 0; pg < cnt; ++pg) {
665                         ops.mode      = MTD_OPS_AUTO_OOB;
666                         ops.len       = 0;
667                         ops.retlen    = 0;
668                         ops.ooblen    = sz;
669                         ops.oobretlen = 0;
670                         ops.ooboffs   = 0;
671                         ops.datbuf    = NULL;
672                         ops.oobbuf    = writebuf + pg * sz;
673                         err = mtd_write_oob(mtd, addr, &ops);
674                         if (err)
675                                 goto out;
676                         if (i % 256 == 0)
677                                 pr_info("written up to eraseblock %u\n", i);
678
679                         err = mtdtest_relax();
680                         if (err)
681                                 goto out;
682
683                         addr += mtd->writesize;
684                 }
685         }
686         pr_info("written %u eraseblocks\n", i);
687
688         /* Check all eraseblocks */
689         prandom_seed_state(&rnd_state, 11);
690         pr_info("verifying all eraseblocks\n");
691         for (i = 0; i < ebcnt - 1; ++i) {
692                 if (bbt[i] || bbt[i + 1])
693                         continue;
694                 prandom_bytes_state(&rnd_state, writebuf, mtd->oobavail * 2);
695                 addr = (loff_t)(i + 1) * mtd->erasesize - mtd->writesize;
696                 ops.mode      = MTD_OPS_AUTO_OOB;
697                 ops.len       = 0;
698                 ops.retlen    = 0;
699                 ops.ooblen    = mtd->oobavail * 2;
700                 ops.oobretlen = 0;
701                 ops.ooboffs   = 0;
702                 ops.datbuf    = NULL;
703                 ops.oobbuf    = readbuf;
704                 err = mtd_read_oob(mtd, addr, &ops);
705                 if (mtd_is_bitflip(err))
706                         err = 0;
707
708                 if (err)
709                         goto out;
710                 if (memcmpshow(addr, readbuf, writebuf,
711                                mtd->oobavail * 2)) {
712                         pr_err("error: verify failed at %#llx\n",
713                                (long long)addr);
714                         errcnt += 1;
715                         if (errcnt > 1000) {
716                                 pr_err("error: too many errors\n");
717                                 goto out;
718                         }
719                 }
720                 if (i % 256 == 0)
721                         pr_info("verified up to eraseblock %u\n", i);
722
723                 err = mtdtest_relax();
724                 if (err)
725                         goto out;
726         }
727         pr_info("verified %u eraseblocks\n", i);
728
729         pr_info("finished with %d errors\n", errcnt);
730 out:
731         kfree(bbt);
732         kfree(writebuf);
733         kfree(readbuf);
734         put_mtd_device(mtd);
735         if (err)
736                 pr_info("error %d occurred\n", err);
737         printk(KERN_INFO "=================================================\n");
738         return err;
739 }
740 module_init(mtd_oobtest_init);
741
742 static void __exit mtd_oobtest_exit(void)
743 {
744         return;
745 }
746 module_exit(mtd_oobtest_exit);
747
748 MODULE_DESCRIPTION("Out-of-band test module");
749 MODULE_AUTHOR("Adrian Hunter");
750 MODULE_LICENSE("GPL");