Exemplo n.º 1
0
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;
}