static int __init mtd_pagetest_init(void) { int err = 0; uint64_t tmp; uint32_t i; #ifdef CONFIG_DEBUG_PRINTK printk(KERN_INFO "\n"); #else ; #endif #ifdef CONFIG_DEBUG_PRINTK printk(KERN_INFO "=================================================\n"); #else ; #endif #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "MTD device: %d\n", dev); #else ; #endif mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "error: cannot get MTD device\n"); #else ; #endif return err; } if (mtd->type != MTD_NANDFLASH) { #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "this test requires NAND flash\n"); #else ; #endif goto out; } tmp = mtd->size; do_div(tmp, mtd->erasesize); ebcnt = tmp; pgcnt = mtd->erasesize / mtd->writesize; pgsize = mtd->writesize; #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " "page size %u, count of eraseblocks %u, pages per " "eraseblock %u, OOB size %u\n", (unsigned long long)mtd->size, mtd->erasesize, pgsize, ebcnt, pgcnt, mtd->oobsize); #else ; #endif err = -ENOMEM; bufsize = pgsize * 2; writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!writebuf) { #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "error: cannot allocate memory\n"); #else ; #endif goto out; } twopages = kmalloc(bufsize, GFP_KERNEL); if (!twopages) { #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "error: cannot allocate memory\n"); #else ; #endif goto out; } boundary = kmalloc(bufsize, GFP_KERNEL); if (!boundary) { #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "error: cannot allocate memory\n"); #else ; #endif goto out; } err = scan_for_bad_eraseblocks(); if (err) goto out; /* Erase all eraseblocks */ #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "erasing whole device\n"); #else ; #endif for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = erase_eraseblock(i); if (err) goto out; cond_resched(); } #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "erased %u eraseblocks\n", i); #else ; #endif /* Write all eraseblocks */ simple_srand(1); #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "writing whole device\n"); #else ; #endif for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = write_eraseblock(i); if (err) goto out; if (i % 256 == 0) #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "written up to eraseblock %u\n", i); #else ; #endif cond_resched(); } #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "written %u eraseblocks\n", i); #else ; #endif /* Check all eraseblocks */ simple_srand(1); #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "verifying all eraseblocks\n"); #else ; #endif for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = verify_eraseblock(i); if (err) goto out; if (i % 256 == 0) #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "verified up to eraseblock %u\n", i); #else ; #endif cond_resched(); } #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "verified %u eraseblocks\n", i); #else ; #endif err = crosstest(); if (err) goto out; err = erasecrosstest(); if (err) goto out; err = erasetest(); if (err) goto out; #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "finished with %d errors\n", errcnt); #else ; #endif out: kfree(bbt); kfree(boundary); kfree(twopages); kfree(writebuf); put_mtd_device(mtd); if (err) #ifdef CONFIG_DEBUG_PRINTK printk(PRINT_PREF "error %d occurred\n", err); #else ; #endif #ifdef CONFIG_DEBUG_PRINTK printk(KERN_INFO "=================================================\n"); #else ; #endif return err; }
static int __init mtd_pagetest_init(void) { int err = 0; uint64_t tmp; uint32_t i; printk(KERN_INFO "\n"); printk(KERN_INFO "=================================================\n"); if (dev < 0) { pr_info("Please specify a valid mtd-device via module parameter\n"); pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } pr_info("MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); pr_err("error: cannot get MTD device\n"); return err; } if (mtd->type != MTD_NANDFLASH) { pr_info("this test requires NAND flash\n"); goto out; } tmp = mtd->size; do_div(tmp, mtd->erasesize); ebcnt = tmp; pgcnt = mtd->erasesize / mtd->writesize; pgsize = mtd->writesize; pr_info("MTD device size %llu, eraseblock size %u, " "page size %u, count of eraseblocks %u, pages per " "eraseblock %u, OOB size %u\n", (unsigned long long)mtd->size, mtd->erasesize, pgsize, ebcnt, pgcnt, mtd->oobsize); err = -ENOMEM; bufsize = pgsize * 2; writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!writebuf) { pr_err("error: cannot allocate memory\n"); goto out; } twopages = kmalloc(bufsize, GFP_KERNEL); if (!twopages) { pr_err("error: cannot allocate memory\n"); goto out; } boundary = kmalloc(bufsize, GFP_KERNEL); if (!boundary) { pr_err("error: cannot allocate memory\n"); goto out; } err = scan_for_bad_eraseblocks(); if (err) goto out; /* Erase all eraseblocks */ pr_info("erasing whole device\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = erase_eraseblock(i); if (err) goto out; cond_resched(); } pr_info("erased %u eraseblocks\n", i); /* Write all eraseblocks */ prandom_seed_state(&rnd_state, 1); pr_info("writing whole device\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = write_eraseblock(i); if (err) goto out; if (i % 256 == 0) pr_info("written up to eraseblock %u\n", i); cond_resched(); } pr_info("written %u eraseblocks\n", i); /* Check all eraseblocks */ prandom_seed_state(&rnd_state, 1); pr_info("verifying all eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = verify_eraseblock(i); if (err) goto out; if (i % 256 == 0) pr_info("verified up to eraseblock %u\n", i); cond_resched(); } pr_info("verified %u eraseblocks\n", i); err = crosstest(); if (err) goto out; err = erasecrosstest(); if (err) goto out; err = erasetest(); if (err) goto out; pr_info("finished with %d errors\n", errcnt); out: kfree(bbt); kfree(boundary); kfree(twopages); kfree(writebuf); put_mtd_device(mtd); if (err) pr_info("error %d occurred\n", err); printk(KERN_INFO "=================================================\n"); return err; }