• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <asm/div64.h>
23 #include <linux/init.h>
24 #include <linux/module.h>
25 #include <linux/moduleparam.h>
26 #include <linux/err.h>
27 #include <linux/mtd/mtd.h>
28 #include <linux/slab.h>
29 #include <linux/sched.h>
30 
31 #define PRINT_PREF KERN_INFO "mtd_pagetest: "
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 
simple_rand(void)50 static inline unsigned int simple_rand(void)
51 {
52 	next = next * 1103515245 + 12345;
53 	return (unsigned int)((next / 65536) % 32768);
54 }
55 
simple_srand(unsigned long seed)56 static inline void simple_srand(unsigned long seed)
57 {
58 	next = seed;
59 }
60 
set_random_data(unsigned char * buf,size_t len)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 
erase_eraseblock(int ebnum)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 		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
83 		return err;
84 	}
85 
86 	if (ei.state == MTD_ERASE_FAILED) {
87 		printk(PRINT_PREF "some erase error occurred at EB %d\n",
88 		       ebnum);
89 		return -EIO;
90 	}
91 
92 	return 0;
93 }
94 
write_eraseblock(int ebnum)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 		printk(PRINT_PREF "error: write failed at %#llx\n",
106 		       (long long)addr);
107 
108 	return err;
109 }
110 
verify_eraseblock(int ebnum)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 			printk(PRINT_PREF "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 			printk(PRINT_PREF "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 			printk(PRINT_PREF "error: read failed at %#llx\n",
152 			       (long long)addr);
153 			break;
154 		}
155 		if (memcmp(twopages, writebuf + (j * pgsize), bufsize)) {
156 			printk(PRINT_PREF "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 			printk(PRINT_PREF "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 			printk(PRINT_PREF "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 			printk(PRINT_PREF "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 			printk(PRINT_PREF "error: verify failed at %#llx\n",
194 			       (long long)addr);
195 			errcnt += 1;
196 		}
197 		next = oldnext;
198 	}
199 	return err;
200 }
201 
crosstest(void)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 	printk(PRINT_PREF "crosstest\n");
210 	pp1 = kmalloc(pgsize * 4, GFP_KERNEL);
211 	if (!pp1) {
212 		printk(PRINT_PREF "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 		printk(PRINT_PREF "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 		printk(PRINT_PREF "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 	printk(PRINT_PREF "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 		printk(PRINT_PREF "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 	printk(PRINT_PREF "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 		printk(PRINT_PREF "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 	printk(PRINT_PREF "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 		printk(PRINT_PREF "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 	printk(PRINT_PREF "verifying pages read at %#llx match\n",
293 	       (long long)addr0);
294 	if (memcmp(pp2, pp4, pgsize)) {
295 		printk(PRINT_PREF "verify failed!\n");
296 		errcnt += 1;
297 	} else if (!err)
298 		printk(PRINT_PREF "crosstest ok\n");
299 	kfree(pp1);
300 	return err;
301 }
302 
erasecrosstest(void)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 	printk(PRINT_PREF "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 	printk(PRINT_PREF "erasing block %d\n", ebnum);
324 	err = erase_eraseblock(ebnum);
325 	if (err)
326 		return err;
327 
328 	printk(PRINT_PREF "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 		printk(PRINT_PREF "error: write failed at %#llx\n",
334 		       (long long)addr0);
335 		return err ? err : -1;
336 	}
337 
338 	printk(PRINT_PREF "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 		printk(PRINT_PREF "error: read failed at %#llx\n",
345 		       (long long)addr0);
346 		return err ? err : -1;
347 	}
348 
349 	printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum);
350 	if (memcmp(writebuf, readbuf, pgsize)) {
351 		printk(PRINT_PREF "verify failed!\n");
352 		errcnt += 1;
353 		return -1;
354 	}
355 
356 	printk(PRINT_PREF "erasing block %d\n", ebnum);
357 	err = erase_eraseblock(ebnum);
358 	if (err)
359 		return err;
360 
361 	printk(PRINT_PREF "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 		printk(PRINT_PREF "error: write failed at %#llx\n",
367 		       (long long)addr0);
368 		return err ? err : -1;
369 	}
370 
371 	printk(PRINT_PREF "erasing block %d\n", ebnum2);
372 	err = erase_eraseblock(ebnum2);
373 	if (err)
374 		return err;
375 
376 	printk(PRINT_PREF "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 		printk(PRINT_PREF "error: read failed at %#llx\n",
383 		       (long long)addr0);
384 		return err ? err : -1;
385 	}
386 
387 	printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum);
388 	if (memcmp(writebuf, readbuf, pgsize)) {
389 		printk(PRINT_PREF "verify failed!\n");
390 		errcnt += 1;
391 		return -1;
392 	}
393 
394 	if (!err)
395 		printk(PRINT_PREF "erasecrosstest ok\n");
396 	return err;
397 }
398 
erasetest(void)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 	printk(PRINT_PREF "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 	printk(PRINT_PREF "erasing block %d\n", ebnum);
415 	err = erase_eraseblock(ebnum);
416 	if (err)
417 		return err;
418 
419 	printk(PRINT_PREF "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 		printk(PRINT_PREF "error: write failed at %#llx\n",
424 		       (long long)addr0);
425 		return err ? err : -1;
426 	}
427 
428 	printk(PRINT_PREF "erasing block %d\n", ebnum);
429 	err = erase_eraseblock(ebnum);
430 	if (err)
431 		return err;
432 
433 	printk(PRINT_PREF "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 		printk(PRINT_PREF "error: read failed at %#llx\n",
439 		       (long long)addr0);
440 		return err ? err : -1;
441 	}
442 
443 	printk(PRINT_PREF "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 			printk(PRINT_PREF "verifying all 0xff failed at %d\n",
448 			       i);
449 			errcnt += 1;
450 			ok = 0;
451 			break;
452 		}
453 
454 	if (ok && !err)
455 		printk(PRINT_PREF "erasetest ok\n");
456 
457 	return err;
458 }
459 
is_block_bad(int ebnum)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 		printk(PRINT_PREF "block %d is bad\n", ebnum);
468 	return ret;
469 }
470 
scan_for_bad_eraseblocks(void)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 		printk(PRINT_PREF "error: cannot allocate memory\n");
478 		return -ENOMEM;
479 	}
480 
481 	printk(PRINT_PREF "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 	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
489 	return 0;
490 }
491 
mtd_pagetest_init(void)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 		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");
504 		return -EINVAL;
505 	}
506 
507 	printk(PRINT_PREF "MTD device: %d\n", dev);
508 
509 	mtd = get_mtd_device(NULL, dev);
510 	if (IS_ERR(mtd)) {
511 		err = PTR_ERR(mtd);
512 		printk(PRINT_PREF "error: cannot get MTD device\n");
513 		return err;
514 	}
515 
516 	if (mtd->type != MTD_NANDFLASH) {
517 		printk(PRINT_PREF "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 	printk(PRINT_PREF "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 		printk(PRINT_PREF "error: cannot allocate memory\n");
538 		goto out;
539 	}
540 	twopages = kmalloc(bufsize, GFP_KERNEL);
541 	if (!twopages) {
542 		printk(PRINT_PREF "error: cannot allocate memory\n");
543 		goto out;
544 	}
545 	boundary = kmalloc(bufsize, GFP_KERNEL);
546 	if (!boundary) {
547 		printk(PRINT_PREF "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 	printk(PRINT_PREF "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 	printk(PRINT_PREF "erased %u eraseblocks\n", i);
566 
567 	/* Write all eraseblocks */
568 	simple_srand(1);
569 	printk(PRINT_PREF "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 			printk(PRINT_PREF "written up to eraseblock %u\n", i);
578 		cond_resched();
579 	}
580 	printk(PRINT_PREF "written %u eraseblocks\n", i);
581 
582 	/* Check all eraseblocks */
583 	simple_srand(1);
584 	printk(PRINT_PREF "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 			printk(PRINT_PREF "verified up to eraseblock %u\n", i);
593 		cond_resched();
594 	}
595 	printk(PRINT_PREF "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 	printk(PRINT_PREF "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 		printk(PRINT_PREF "error %d occurred\n", err);
619 	printk(KERN_INFO "=================================================\n");
620 	return err;
621 }
622 module_init(mtd_pagetest_init);
623 
mtd_pagetest_exit(void)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");
633