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