static int __init mtd_stresstest_init(void) { int err; int i, op; uint64_t tmp; printk(KERN_INFO "\n"); printk(KERN_INFO "=================================================\n"); printk(PRINT_PREF "MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); printk(PRINT_PREF "error: cannot get MTD device\n"); return err; } if (mtd->writesize == 1) { printk(PRINT_PREF "not NAND flash, assume page size is 512 " "bytes.\n"); pgsize = 512; } else pgsize = mtd->writesize; tmp = mtd->size; do_div(tmp, mtd->erasesize); ebcnt = tmp; pgcnt = mtd->erasesize / mtd->writesize; 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); /* Read or write up 2 eraseblocks at a time */ bufsize = mtd->erasesize * 2; err = -ENOMEM; readbuf = vmalloc(bufsize); writebuf = vmalloc(bufsize); offsets = kmalloc(ebcnt * sizeof(int), GFP_KERNEL); if (!readbuf || !writebuf || !offsets) { printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } for (i = 0; i < ebcnt; i++) offsets[i] = mtd->erasesize; simple_srand(current->pid); for (i = 0; i < bufsize; i++) writebuf[i] = simple_rand(); err = scan_for_bad_eraseblocks(); if (err) goto out; /* Do operations */ printk(PRINT_PREF "doing operations\n"); for (op = 0; op < count; op++) { if ((op & 1023) == 0) printk(PRINT_PREF "%d operations done\n", op); err = do_operation(); if (err) goto out; cond_resched(); } printk(PRINT_PREF "finished, %d operations done\n", op); out: kfree(offsets); kfree(bbt); vfree(writebuf); vfree(readbuf); put_mtd_device(mtd); if (err) printk(PRINT_PREF "error %d occurred\n", err); printk(KERN_INFO "=================================================\n"); return err; }
static int __init mtd_speedtest_init(void) { int err, i, blocks, j, k; long speed; uint64_t tmp; printk(KERN_INFO "\n"); printk(KERN_INFO "=================================================\n"); if (dev < 0) { printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } if (count) printk(PRINT_PREF "MTD device: %d count: %d\n", dev, count); else printk(PRINT_PREF "MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); printk(PRINT_PREF "error: cannot get MTD device\n"); return err; } if (mtd->writesize == 1) { printk(PRINT_PREF "not NAND flash, assume page size is 512 " "bytes.\n"); pgsize = 512; } else pgsize = mtd->writesize; tmp = mtd->size; do_div(tmp, mtd->erasesize); ebcnt = tmp; pgcnt = mtd->erasesize / pgsize; 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); if (count > 0 && count < ebcnt) ebcnt = count; err = -ENOMEM; iobuf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!iobuf) { printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } simple_srand(1); set_random_data(iobuf, mtd->erasesize); err = scan_for_bad_eraseblocks(); if (err) goto out; err = erase_whole_device(); if (err) goto out; /* Write all eraseblocks, 1 eraseblock at a time */ printk(PRINT_PREF "testing eraseblock write speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = write_eraseblock(i); if (err) goto out; cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "eraseblock write speed is %ld KiB/s\n", speed); /* Read all eraseblocks, 1 eraseblock at a time */ printk(PRINT_PREF "testing eraseblock read speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = read_eraseblock(i); if (err) goto out; cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "eraseblock read speed is %ld KiB/s\n", speed); err = erase_whole_device(); if (err) goto out; /* Write all eraseblocks, 1 page at a time */ printk(PRINT_PREF "testing page write speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = write_eraseblock_by_page(i); if (err) goto out; cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "page write speed is %ld KiB/s\n", speed); /* Read all eraseblocks, 1 page at a time */ printk(PRINT_PREF "testing page read speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = read_eraseblock_by_page(i); if (err) goto out; cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "page read speed is %ld KiB/s\n", speed); err = erase_whole_device(); if (err) goto out; /* Write all eraseblocks, 2 pages at a time */ printk(PRINT_PREF "testing 2 page write speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = write_eraseblock_by_2pages(i); if (err) goto out; cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "2 page write speed is %ld KiB/s\n", speed); /* Read all eraseblocks, 2 pages at a time */ printk(PRINT_PREF "testing 2 page read speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = read_eraseblock_by_2pages(i); if (err) goto out; cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "2 page read speed is %ld KiB/s\n", speed); /* Erase all eraseblocks */ printk(PRINT_PREF "Testing erase speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = erase_eraseblock(i); if (err) goto out; cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "erase speed is %ld KiB/s\n", speed); /* Multi-block erase all eraseblocks */ for (k = 1; k < 7; k++) { blocks = 1 << k; printk(PRINT_PREF "Testing %dx multi-block erase speed\n", blocks); start_timing(); for (i = 0; i < ebcnt; ) { for (j = 0; j < blocks && (i + j) < ebcnt; j++) if (bbt[i + j]) break; if (j < 1) { i++; continue; } err = multiblock_erase(i, j); if (err) goto out; cond_resched(); i += j; } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "%dx multi-block erase speed is %ld KiB/s\n", blocks, speed); } printk(PRINT_PREF "finished\n"); out: kfree(iobuf); kfree(bbt); put_mtd_device(mtd); if (err) printk(PRINT_PREF "error %d occurred\n", err); printk(KERN_INFO "=================================================\n"); return err; }
static int __init mtd_oobtest_init(void) { int err = 0; unsigned int i; uint64_t tmp; struct mtd_oob_ops ops; loff_t addr = 0, addr0; printk(KERN_INFO "\n"); printk(KERN_INFO "=================================================\n"); printk(PRINT_PREF "MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); printk(PRINT_PREF "error: cannot get MTD device\n"); return err; } if (mtd->type != MTD_NANDFLASH) { printk(PRINT_PREF "this test requires NAND flash\n"); goto out; } tmp = mtd->size; do_div(tmp, mtd->erasesize); ebcnt = tmp; pgcnt = mtd->erasesize / mtd->writesize; 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, mtd->writesize, ebcnt, pgcnt, mtd->oobsize); err = -ENOMEM; mtd->erasesize = mtd->erasesize; readbuf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!readbuf) { printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!writebuf) { printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } err = scan_for_bad_eraseblocks(); if (err) goto out; use_offset = 0; use_len = mtd->ecclayout->oobavail; use_len_max = mtd->ecclayout->oobavail; vary_offset = 0; printk(PRINT_PREF "test 1 of 5\n"); err = erase_whole_device(); if (err) goto out; simple_srand(1); err = write_whole_device(); if (err) goto out; simple_srand(1); err = verify_all_eraseblocks(); if (err) goto out; printk(PRINT_PREF "test 2 of 5\n"); err = erase_whole_device(); if (err) goto out; simple_srand(3); err = write_whole_device(); if (err) goto out; simple_srand(3); printk(PRINT_PREF "verifying all eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = verify_eraseblock_in_one_go(i); if (err) goto out; if (i % 256 == 0) printk(PRINT_PREF "verified up to eraseblock %u\n", i); cond_resched(); } printk(PRINT_PREF "verified %u eraseblocks\n", i); printk(PRINT_PREF "test 3 of 5\n"); err = erase_whole_device(); if (err) goto out; use_offset = 0; use_len = mtd->ecclayout->oobavail; use_len_max = mtd->ecclayout->oobavail; vary_offset = 1; simple_srand(5); printk(PRINT_PREF "writing OOBs of 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) printk(PRINT_PREF "written up to eraseblock %u\n", i); cond_resched(); } printk(PRINT_PREF "written %u eraseblocks\n", i); use_offset = 0; use_len = mtd->ecclayout->oobavail; use_len_max = mtd->ecclayout->oobavail; vary_offset = 1; simple_srand(5); err = verify_all_eraseblocks(); if (err) goto out; use_offset = 0; use_len = mtd->ecclayout->oobavail; use_len_max = mtd->ecclayout->oobavail; vary_offset = 0; printk(PRINT_PREF "test 4 of 5\n"); err = erase_whole_device(); if (err) goto out; addr0 = 0; for (i = 0; i < ebcnt && bbt[i]; ++i) addr0 += mtd->erasesize; ops.mode = MTD_OOB_AUTO; ops.len = 0; ops.retlen = 0; ops.ooblen = 1; ops.oobretlen = 0; ops.ooboffs = mtd->ecclayout->oobavail; ops.datbuf = NULL; ops.oobbuf = writebuf; printk(PRINT_PREF "attempting to start write past end of OOB\n"); printk(PRINT_PREF "an error is expected...\n"); err = mtd->write_oob(mtd, addr0, &ops); if (err) { printk(PRINT_PREF "error occurred as expected\n"); err = 0; } else { printk(PRINT_PREF "error: can write past end of OOB\n"); errcnt += 1; } ops.mode = MTD_OOB_AUTO; ops.len = 0; ops.retlen = 0; ops.ooblen = 1; ops.oobretlen = 0; ops.ooboffs = mtd->ecclayout->oobavail; ops.datbuf = NULL; ops.oobbuf = readbuf; printk(PRINT_PREF "attempting to start read past end of OOB\n"); printk(PRINT_PREF "an error is expected...\n"); err = mtd->read_oob(mtd, addr0, &ops); if (err) { printk(PRINT_PREF "error occurred as expected\n"); err = 0; } else { printk(PRINT_PREF "error: can read past end of OOB\n"); errcnt += 1; } if (bbt[ebcnt - 1]) printk(PRINT_PREF "skipping end of device tests because last " "block is bad\n"); else { ops.mode = MTD_OOB_AUTO; ops.len = 0; ops.retlen = 0; ops.ooblen = mtd->ecclayout->oobavail + 1; ops.oobretlen = 0; ops.ooboffs = 0; ops.datbuf = NULL; ops.oobbuf = writebuf; printk(PRINT_PREF "attempting to write past end of device\n"); printk(PRINT_PREF "an error is expected...\n"); err = mtd->write_oob(mtd, mtd->size - mtd->writesize, &ops); if (err) { printk(PRINT_PREF "error occurred as expected\n"); err = 0; } else { printk(PRINT_PREF "error: wrote past end of device\n"); errcnt += 1; } ops.mode = MTD_OOB_AUTO; ops.len = 0; ops.retlen = 0; ops.ooblen = mtd->ecclayout->oobavail + 1; ops.oobretlen = 0; ops.ooboffs = 0; ops.datbuf = NULL; ops.oobbuf = readbuf; printk(PRINT_PREF "attempting to read past end of device\n"); printk(PRINT_PREF "an error is expected...\n"); err = mtd->read_oob(mtd, mtd->size - mtd->writesize, &ops); if (err) { printk(PRINT_PREF "error occurred as expected\n"); err = 0; } else { printk(PRINT_PREF "error: read past end of device\n"); errcnt += 1; } err = erase_eraseblock(ebcnt - 1); if (err) goto out; ops.mode = MTD_OOB_AUTO; ops.len = 0; ops.retlen = 0; ops.ooblen = mtd->ecclayout->oobavail; ops.oobretlen = 0; ops.ooboffs = 1; ops.datbuf = NULL; ops.oobbuf = writebuf; printk(PRINT_PREF "attempting to write past end of device\n"); printk(PRINT_PREF "an error is expected...\n"); err = mtd->write_oob(mtd, mtd->size - mtd->writesize, &ops); if (err) { printk(PRINT_PREF "error occurred as expected\n"); err = 0; } else { printk(PRINT_PREF "error: wrote past end of device\n"); errcnt += 1; } ops.mode = MTD_OOB_AUTO; ops.len = 0; ops.retlen = 0; ops.ooblen = mtd->ecclayout->oobavail; ops.oobretlen = 0; ops.ooboffs = 1; ops.datbuf = NULL; ops.oobbuf = readbuf; printk(PRINT_PREF "attempting to read past end of device\n"); printk(PRINT_PREF "an error is expected...\n"); err = mtd->read_oob(mtd, mtd->size - mtd->writesize, &ops); if (err) { printk(PRINT_PREF "error occurred as expected\n"); err = 0; } else { printk(PRINT_PREF "error: read past end of device\n"); errcnt += 1; } } printk(PRINT_PREF "test 5 of 5\n"); err = erase_whole_device(); if (err) goto out; simple_srand(11); printk(PRINT_PREF "writing OOBs of whole device\n"); for (i = 0; i < ebcnt - 1; ++i) { int cnt = 2; int pg; size_t sz = mtd->ecclayout->oobavail; if (bbt[i] || bbt[i + 1]) continue; addr = (i + 1) * mtd->erasesize - mtd->writesize; for (pg = 0; pg < cnt; ++pg) { set_random_data(writebuf, sz); ops.mode = MTD_OOB_AUTO; ops.len = 0; ops.retlen = 0; ops.ooblen = sz; ops.oobretlen = 0; ops.ooboffs = 0; ops.datbuf = NULL; ops.oobbuf = writebuf; err = mtd->write_oob(mtd, addr, &ops); if (err) goto out; if (i % 256 == 0) printk(PRINT_PREF "written up to eraseblock " "%u\n", i); cond_resched(); addr += mtd->writesize; } } printk(PRINT_PREF "written %u eraseblocks\n", i); simple_srand(11); printk(PRINT_PREF "verifying all eraseblocks\n"); for (i = 0; i < ebcnt - 1; ++i) { if (bbt[i] || bbt[i + 1]) continue; set_random_data(writebuf, mtd->ecclayout->oobavail * 2); addr = (i + 1) * mtd->erasesize - mtd->writesize; ops.mode = MTD_OOB_AUTO; ops.len = 0; ops.retlen = 0; ops.ooblen = mtd->ecclayout->oobavail * 2; ops.oobretlen = 0; ops.ooboffs = 0; ops.datbuf = NULL; ops.oobbuf = readbuf; err = mtd->read_oob(mtd, addr, &ops); if (err) goto out; if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) { printk(PRINT_PREF "error: verify failed at %#llx\n", (long long)addr); errcnt += 1; if (errcnt > 1000) { printk(PRINT_PREF "error: too many errors\n"); goto out; } } if (i % 256 == 0) printk(PRINT_PREF "verified up to eraseblock %u\n", i); cond_resched(); } printk(PRINT_PREF "verified %u eraseblocks\n", i); printk(PRINT_PREF "finished with %d errors\n", errcnt); out: kfree(bbt); kfree(writebuf); kfree(readbuf); put_mtd_device(mtd); if (err) printk(PRINT_PREF "error %d occurred\n", err); printk(KERN_INFO "=================================================\n"); return err; }
static int __init mtd_subpagetest_init(void) { int err = 0; uint32_t i; uint64_t tmp; printk(KERN_INFO "\n"); printk(KERN_INFO "=================================================\n"); printk(PRINT_PREF "MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); printk(PRINT_PREF "error: cannot get MTD device\n"); return err; } if (mtd->type != MTD_NANDFLASH) { printk(PRINT_PREF "this test requires NAND flash\n"); goto out; } subpgsize = mtd->writesize >> mtd->subpage_sft; tmp = mtd->size; do_div(tmp, mtd->erasesize); ebcnt = tmp; pgcnt = mtd->erasesize / mtd->writesize; printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " "page size %u, subpage size %u, count of eraseblocks %u, " "pages per eraseblock %u, OOB size %u\n", (unsigned long long)mtd->size, mtd->erasesize, mtd->writesize, subpgsize, ebcnt, pgcnt, mtd->oobsize); err = -ENOMEM; bufsize = subpgsize * 32; writebuf = kmalloc(bufsize, GFP_KERNEL); if (!writebuf) { printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } readbuf = kmalloc(bufsize, GFP_KERNEL); if (!readbuf) { printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } err = scan_for_bad_eraseblocks(); if (err) goto out; err = erase_whole_device(); if (err) goto out; printk(PRINT_PREF "writing whole device\n"); simple_srand(1); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = write_eraseblock(i); if (unlikely(err)) goto out; if (i % 256 == 0) printk(PRINT_PREF "written up to eraseblock %u\n", i); cond_resched(); } printk(PRINT_PREF "written %u eraseblocks\n", i); simple_srand(1); printk(PRINT_PREF "verifying all eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = verify_eraseblock(i); if (unlikely(err)) goto out; if (i % 256 == 0) printk(PRINT_PREF "verified up to eraseblock %u\n", i); cond_resched(); } printk(PRINT_PREF "verified %u eraseblocks\n", i); err = erase_whole_device(); if (err) goto out; err = verify_all_eraseblocks_ff(); if (err) goto out; /* Write all eraseblocks */ simple_srand(3); printk(PRINT_PREF "writing whole device\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = write_eraseblock2(i); if (unlikely(err)) goto out; if (i % 256 == 0) printk(PRINT_PREF "written up to eraseblock %u\n", i); cond_resched(); } printk(PRINT_PREF "written %u eraseblocks\n", i); /* Check all eraseblocks */ simple_srand(3); printk(PRINT_PREF "verifying all eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = verify_eraseblock2(i); if (unlikely(err)) goto out; if (i % 256 == 0) printk(PRINT_PREF "verified up to eraseblock %u\n", i); cond_resched(); } printk(PRINT_PREF "verified %u eraseblocks\n", i); err = erase_whole_device(); if (err) goto out; err = verify_all_eraseblocks_ff(); if (err) goto out; printk(PRINT_PREF "finished with %d errors\n", errcnt); out: kfree(bbt); kfree(readbuf); kfree(writebuf); put_mtd_device(mtd); if (err) printk(PRINT_PREF "error %d occurred\n", err); printk(KERN_INFO "=================================================\n"); return err; }
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 fsspeed_init(void) { int err, i; long speed; struct file *fp; mm_segment_t fs; printk(KERN_INFO "\n"); printk(KERN_INFO "=================================================\n"); printk(PRINT_PREF "rw %d PAGES using file: %s\n", count, fname); err = -ENOMEM; iobuf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!iobuf) { printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } simple_srand(1); set_random_data(iobuf, PAGE_SIZE); fp = filp_open(fname, O_RDWR|O_CREAT, 0600); if (IS_ERR(fp)) { printk("open file %s failed.\n", fname); err = PTR_ERR(fp); goto out; } /* Write all eraseblocks, 1 eraseblock at a time */ printk(PRINT_PREF "testing file system write speed\n"); fs = get_fs(); set_fs(KERNEL_DS); start_timing(); for (i = 0; i < count; ++i) { err = vfs_write(fp, iobuf, PAGE_SIZE, &fp->f_pos); if (err < 0) goto out2; // cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "write speed is %ld KiB/s\n", speed); vfs_fsync(fp, fp->f_path.dentry, 0); invalidate_mapping_pages(fp->f_dentry->d_inode->i_mapping, 0, -1); vfs_llseek(fp, 0, SEEK_SET); /* Read all eraseblocks, 1 eraseblock at a time */ printk(PRINT_PREF "testing file system read speed\n"); start_timing(); for (i = 0; i < count; ++i) { err = vfs_read(fp, iobuf, PAGE_SIZE, &fp->f_pos); if (err < 0) goto out2; // cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "read speed is %ld KiB/s\n", speed); printk(PRINT_PREF "finished\n"); err = 0; out2: filp_close(fp, NULL); set_fs(fs); out: kfree(iobuf); if (err) printk(PRINT_PREF "error %d occurred\n", err); printk(KERN_INFO "=================================================\n"); return err; }
static int __init mtd_speedtest_init(void) { int err, i; long speed; uint64_t tmp; printk(KERN_INFO "\n"); printk(KERN_INFO "=================================================\n"); printk(PRINT_PREF "MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); printk(PRINT_PREF "error: cannot get MTD device\n"); return err; } if (mtd->writesize == 1) { printk(PRINT_PREF "not NAND flash, assume page size is 512 " "bytes.\n"); pgsize = 512; } else pgsize = mtd->writesize; tmp = mtd->size; do_div(tmp, mtd->erasesize); ebcnt = tmp; pgcnt = mtd->erasesize / pgsize; 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); err = -ENOMEM; iobuf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!iobuf) { printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } simple_srand(1); set_random_data(iobuf, mtd->erasesize); err = scan_for_bad_eraseblocks(); if (err) goto out; err = erase_whole_device(); if (err) goto out; /* Write all eraseblocks, 1 eraseblock at a time */ printk(PRINT_PREF "testing eraseblock write speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = write_eraseblock(i); if (err) goto out; cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "eraseblock write speed is %ld KiB/s\n", speed); /* Read all eraseblocks, 1 eraseblock at a time */ printk(PRINT_PREF "testing eraseblock read speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = read_eraseblock(i); if (err) goto out; cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "eraseblock read speed is %ld KiB/s\n", speed); err = erase_whole_device(); if (err) goto out; /* Write all eraseblocks, 1 page at a time */ printk(PRINT_PREF "testing page write speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = write_eraseblock_by_page(i); if (err) goto out; cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "page write speed is %ld KiB/s\n", speed); /* Read all eraseblocks, 1 page at a time */ printk(PRINT_PREF "testing page read speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = read_eraseblock_by_page(i); if (err) goto out; cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "page read speed is %ld KiB/s\n", speed); err = erase_whole_device(); if (err) goto out; /* Write all eraseblocks, 2 pages at a time */ printk(PRINT_PREF "testing 2 page write speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = write_eraseblock_by_2pages(i); if (err) goto out; cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "2 page write speed is %ld KiB/s\n", speed); /* Read all eraseblocks, 2 pages at a time */ printk(PRINT_PREF "testing 2 page read speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = read_eraseblock_by_2pages(i); if (err) goto out; cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "2 page read speed is %ld KiB/s\n", speed); /* Erase all eraseblocks */ printk(PRINT_PREF "Testing erase speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = erase_eraseblock(i); if (err) goto out; cond_resched(); } stop_timing(); speed = calc_speed(); printk(PRINT_PREF "erase speed is %ld KiB/s\n", speed); printk(PRINT_PREF "finished\n"); out: kfree(iobuf); kfree(bbt); put_mtd_device(mtd); if (err) printk(PRINT_PREF "error %d occurred\n", err); printk(KERN_INFO "=================================================\n"); return err; }