diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-09 10:33:19 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-09 10:33:19 -0700 |
commit | ef9a61bef917e38f8e096f6df303329aed6cf467 (patch) | |
tree | 31cfe2444d0270e77ff8ef792df11591fed6075c /drivers/mtd/tests | |
parent | b5f0998cae3d7ea56d3d8377e46328fe972b9546 (diff) | |
parent | 6c3b88970175e18a67eb8e55c4eba10614d0d5dc (diff) | |
download | kernel_goldelico_gta04-ef9a61bef917e38f8e096f6df303329aed6cf467.zip kernel_goldelico_gta04-ef9a61bef917e38f8e096f6df303329aed6cf467.tar.gz kernel_goldelico_gta04-ef9a61bef917e38f8e096f6df303329aed6cf467.tar.bz2 |
Merge tag 'for-linus-20130909' of git://git.infradead.org/linux-mtd
Pull mtd updates from David Woodhouse:
- factor out common code from MTD tests
- nand-gpio cleanup and portability to non-ARM
- m25p80 support for 4-byte addressing chips, other new chips
- pxa3xx cleanup and support for new platforms
- remove obsolete alauda, octagon-5066 drivers
- erase/write support for bcm47xxsflash
- improve detection of ECC requirements for NAND, controller setup
- NFC acceleration support for atmel-nand, read/write via SRAM
- etc
* tag 'for-linus-20130909' of git://git.infradead.org/linux-mtd: (184 commits)
mtd: chips: Add support for PMC SPI Flash chips in m25p80.c
mtd: ofpart: use for_each_child_of_node() macro
mtd: mtdswap: replace strict_strtoul() with kstrtoul()
mtd cs553x_nand: use kzalloc() instead of memset
mtd: atmel_nand: fix error return code in atmel_nand_probe()
mtd: bcm47xxsflash: writing support
mtd: bcm47xxsflash: implement erasing support
mtd: bcm47xxsflash: convert to module_platform_driver instead of init/exit
mtd: bcm47xxsflash: convert kzalloc to avoid invalid access
mtd: remove alauda driver
mtd: nand: mxc_nand: mark 'const' properly
mtd: maps: cfi_flagadm: add missing __iomem annotation
mtd: spear_smi: add missing __iomem annotation
mtd: r852: Staticize local symbols
mtd: nandsim: Staticize local symbols
mtd: impa7: add missing __iomem annotation
mtd: sm_ftl: Staticize local symbols
mtd: m25p80: add support for mr25h10
mtd: m25p80: make CONFIG_M25PXX_USE_FAST_READ safe to enable
mtd: m25p80: Pass flags through CAT25_INFO macro
...
Diffstat (limited to 'drivers/mtd/tests')
-rw-r--r-- | drivers/mtd/tests/Makefile | 9 | ||||
-rw-r--r-- | drivers/mtd/tests/mtd_test.c | 114 | ||||
-rw-r--r-- | drivers/mtd/tests/mtd_test.h | 11 | ||||
-rw-r--r-- | drivers/mtd/tests/nandbiterrs.c (renamed from drivers/mtd/tests/mtd_nandbiterrs.c) | 41 | ||||
-rw-r--r-- | drivers/mtd/tests/oobtest.c (renamed from drivers/mtd/tests/mtd_oobtest.c) | 102 | ||||
-rw-r--r-- | drivers/mtd/tests/pagetest.c (renamed from drivers/mtd/tests/mtd_pagetest.c) | 271 | ||||
-rw-r--r-- | drivers/mtd/tests/readtest.c (renamed from drivers/mtd/tests/mtd_readtest.c) | 61 | ||||
-rw-r--r-- | drivers/mtd/tests/speedtest.c (renamed from drivers/mtd/tests/mtd_speedtest.c) | 210 | ||||
-rw-r--r-- | drivers/mtd/tests/stresstest.c (renamed from drivers/mtd/tests/mtd_stresstest.c) | 101 | ||||
-rw-r--r-- | drivers/mtd/tests/subpagetest.c (renamed from drivers/mtd/tests/mtd_subpagetest.c) | 97 | ||||
-rw-r--r-- | drivers/mtd/tests/torturetest.c (renamed from drivers/mtd/tests/mtd_torturetest.c) | 66 |
11 files changed, 286 insertions, 797 deletions
diff --git a/drivers/mtd/tests/Makefile b/drivers/mtd/tests/Makefile index bd0065c..937a829 100644 --- a/drivers/mtd/tests/Makefile +++ b/drivers/mtd/tests/Makefile @@ -7,3 +7,12 @@ obj-$(CONFIG_MTD_TESTS) += mtd_subpagetest.o obj-$(CONFIG_MTD_TESTS) += mtd_torturetest.o obj-$(CONFIG_MTD_TESTS) += mtd_nandecctest.o obj-$(CONFIG_MTD_TESTS) += mtd_nandbiterrs.o + +mtd_oobtest-objs := oobtest.o mtd_test.o +mtd_pagetest-objs := pagetest.o mtd_test.o +mtd_readtest-objs := readtest.o mtd_test.o +mtd_speedtest-objs := speedtest.o mtd_test.o +mtd_stresstest-objs := stresstest.o mtd_test.o +mtd_subpagetest-objs := subpagetest.o mtd_test.o +mtd_torturetest-objs := torturetest.o mtd_test.o +mtd_nandbiterrs-objs := nandbiterrs.o mtd_test.o diff --git a/drivers/mtd/tests/mtd_test.c b/drivers/mtd/tests/mtd_test.c new file mode 100644 index 0000000..c818a63 --- /dev/null +++ b/drivers/mtd/tests/mtd_test.c @@ -0,0 +1,114 @@ +#define pr_fmt(fmt) "mtd_test: " fmt + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/printk.h> + +#include "mtd_test.h" + +int mtdtest_erase_eraseblock(struct mtd_info *mtd, unsigned int ebnum) +{ + int err; + struct erase_info ei; + loff_t addr = ebnum * mtd->erasesize; + + memset(&ei, 0, sizeof(struct erase_info)); + ei.mtd = mtd; + ei.addr = addr; + ei.len = mtd->erasesize; + + err = mtd_erase(mtd, &ei); + if (err) { + pr_info("error %d while erasing EB %d\n", err, ebnum); + return err; + } + + if (ei.state == MTD_ERASE_FAILED) { + pr_info("some erase error occurred at EB %d\n", ebnum); + return -EIO; + } + return 0; +} + +static int is_block_bad(struct mtd_info *mtd, unsigned int ebnum) +{ + int ret; + loff_t addr = ebnum * mtd->erasesize; + + ret = mtd_block_isbad(mtd, addr); + if (ret) + pr_info("block %d is bad\n", ebnum); + + return ret; +} + +int mtdtest_scan_for_bad_eraseblocks(struct mtd_info *mtd, unsigned char *bbt, + unsigned int eb, int ebcnt) +{ + int i, bad = 0; + + if (!mtd_can_have_bb(mtd)) + return 0; + + pr_info("scanning for bad eraseblocks\n"); + for (i = 0; i < ebcnt; ++i) { + bbt[i] = is_block_bad(mtd, eb + i) ? 1 : 0; + if (bbt[i]) + bad += 1; + cond_resched(); + } + pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); + + return 0; +} + +int mtdtest_erase_good_eraseblocks(struct mtd_info *mtd, unsigned char *bbt, + unsigned int eb, int ebcnt) +{ + int err; + unsigned int i; + + for (i = 0; i < ebcnt; ++i) { + if (bbt[i]) + continue; + err = mtdtest_erase_eraseblock(mtd, eb + i); + if (err) + return err; + cond_resched(); + } + + return 0; +} + +int mtdtest_read(struct mtd_info *mtd, loff_t addr, size_t size, void *buf) +{ + size_t read; + int err; + + err = mtd_read(mtd, addr, size, &read, buf); + /* Ignore corrected ECC errors */ + if (mtd_is_bitflip(err)) + err = 0; + if (!err && read != size) + err = -EIO; + if (err) + pr_err("error: read failed at %#llx\n", addr); + + return err; +} + +int mtdtest_write(struct mtd_info *mtd, loff_t addr, size_t size, + const void *buf) +{ + size_t written; + int err; + + err = mtd_write(mtd, addr, size, &written, buf); + if (!err && written != size) + err = -EIO; + if (err) + pr_err("error: write failed at %#llx\n", addr); + + return err; +} diff --git a/drivers/mtd/tests/mtd_test.h b/drivers/mtd/tests/mtd_test.h new file mode 100644 index 0000000..f437c77 --- /dev/null +++ b/drivers/mtd/tests/mtd_test.h @@ -0,0 +1,11 @@ +#include <linux/mtd/mtd.h> + +int mtdtest_erase_eraseblock(struct mtd_info *mtd, unsigned int ebnum); +int mtdtest_scan_for_bad_eraseblocks(struct mtd_info *mtd, unsigned char *bbt, + unsigned int eb, int ebcnt); +int mtdtest_erase_good_eraseblocks(struct mtd_info *mtd, unsigned char *bbt, + unsigned int eb, int ebcnt); + +int mtdtest_read(struct mtd_info *mtd, loff_t addr, size_t size, void *buf); +int mtdtest_write(struct mtd_info *mtd, loff_t addr, size_t size, + const void *buf); diff --git a/drivers/mtd/tests/mtd_nandbiterrs.c b/drivers/mtd/tests/nandbiterrs.c index 207bf9a..3cd3aab 100644 --- a/drivers/mtd/tests/mtd_nandbiterrs.c +++ b/drivers/mtd/tests/nandbiterrs.c @@ -49,6 +49,7 @@ #include <linux/err.h> #include <linux/mtd/nand.h> #include <linux/slab.h> +#include "mtd_test.h" static int dev; module_param(dev, int, S_IRUGO); @@ -98,47 +99,13 @@ static uint8_t hash(unsigned offset) return c; } -static int erase_block(void) -{ - int err; - struct erase_info ei; - loff_t addr = eraseblock * mtd->erasesize; - - pr_info("erase_block\n"); - - memset(&ei, 0, sizeof(struct erase_info)); - ei.mtd = mtd; - ei.addr = addr; - ei.len = mtd->erasesize; - - err = mtd_erase(mtd, &ei); - if (err || ei.state == MTD_ERASE_FAILED) { - pr_err("error %d while erasing\n", err); - if (!err) - err = -EIO; - return err; - } - - return 0; -} - /* Writes wbuffer to page */ static int write_page(int log) { - int err = 0; - size_t written; - if (log) pr_info("write_page\n"); - err = mtd_write(mtd, offset, mtd->writesize, &written, wbuffer); - if (err || written != mtd->writesize) { - pr_err("error: write failed at %#llx\n", (long long)offset); - if (!err) - err = -EIO; - } - - return err; + return mtdtest_write(mtd, offset, mtd->writesize, wbuffer); } /* Re-writes the data area while leaving the OOB alone. */ @@ -415,7 +382,7 @@ static int __init mtd_nandbiterrs_init(void) goto exit_rbuffer; } - err = erase_block(); + err = mtdtest_erase_eraseblock(mtd, eraseblock); if (err) goto exit_error; @@ -428,7 +395,7 @@ static int __init mtd_nandbiterrs_init(void) goto exit_error; /* We leave the block un-erased in case of test failure. */ - err = erase_block(); + err = mtdtest_erase_eraseblock(mtd, eraseblock); if (err) goto exit_error; diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/oobtest.c index 3e24b37..ff35c46 100644 --- a/drivers/mtd/tests/mtd_oobtest.c +++ b/drivers/mtd/tests/oobtest.c @@ -31,6 +31,8 @@ #include <linux/sched.h> #include <linux/random.h> +#include "mtd_test.h" + static int dev = -EINVAL; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -49,49 +51,6 @@ static int use_len_max; static int vary_offset; static struct rnd_state rnd_state; -static int erase_eraseblock(int ebnum) -{ - int err; - struct erase_info ei; - loff_t addr = ebnum * mtd->erasesize; - - memset(&ei, 0, sizeof(struct erase_info)); - ei.mtd = mtd; - ei.addr = addr; - ei.len = mtd->erasesize; - - err = mtd_erase(mtd, &ei); - if (err) { - pr_err("error %d while erasing EB %d\n", err, ebnum); - return err; - } - - if (ei.state == MTD_ERASE_FAILED) { - pr_err("some erase error occurred at EB %d\n", ebnum); - return -EIO; - } - - return 0; -} - -static int erase_whole_device(void) -{ - int err; - unsigned int i; - - pr_info("erasing whole device\n"); - for (i = 0; i < ebcnt; ++i) { - if (bbt[i]) - continue; - err = erase_eraseblock(i); - if (err) - return err; - cond_resched(); - } - pr_info("erased %u eraseblocks\n", i); - return 0; -} - static void do_vary_offset(void) { use_len -= 1; @@ -304,38 +263,6 @@ static int verify_all_eraseblocks(void) return 0; } -static int is_block_bad(int ebnum) -{ - int ret; - loff_t addr = ebnum * mtd->erasesize; - - ret = mtd_block_isbad(mtd, addr); - if (ret) - pr_info("block %d is bad\n", ebnum); - return ret; -} - -static int scan_for_bad_eraseblocks(void) -{ - int i, bad = 0; - - bbt = kmalloc(ebcnt, GFP_KERNEL); - if (!bbt) { - pr_err("error: cannot allocate memory\n"); - return -ENOMEM; - } - - pr_info("scanning for bad eraseblocks\n"); - for (i = 0; i < ebcnt; ++i) { - bbt[i] = is_block_bad(i) ? 1 : 0; - if (bbt[i]) - bad += 1; - cond_resched(); - } - pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); - return 0; -} - static int __init mtd_oobtest_init(void) { int err = 0; @@ -380,17 +307,16 @@ static int __init mtd_oobtest_init(void) err = -ENOMEM; readbuf = kmalloc(mtd->erasesize, GFP_KERNEL); - if (!readbuf) { - pr_err("error: cannot allocate memory\n"); + if (!readbuf) goto out; - } writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); - if (!writebuf) { - pr_err("error: cannot allocate memory\n"); + if (!writebuf) + goto out; + bbt = kzalloc(ebcnt, GFP_KERNEL); + if (!bbt) goto out; - } - err = scan_for_bad_eraseblocks(); + err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; @@ -402,7 +328,7 @@ static int __init mtd_oobtest_init(void) /* First test: write all OOB, read it back and verify */ pr_info("test 1 of 5\n"); - err = erase_whole_device(); + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; @@ -422,7 +348,7 @@ static int __init mtd_oobtest_init(void) */ pr_info("test 2 of 5\n"); - err = erase_whole_device(); + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; @@ -452,7 +378,7 @@ static int __init mtd_oobtest_init(void) */ pr_info("test 3 of 5\n"); - err = erase_whole_device(); + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; @@ -485,7 +411,7 @@ static int __init mtd_oobtest_init(void) /* Fourth test: try to write off end of device */ pr_info("test 4 of 5\n"); - err = erase_whole_device(); + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; @@ -577,7 +503,7 @@ static int __init mtd_oobtest_init(void) errcnt += 1; } - err = erase_eraseblock(ebcnt - 1); + err = mtdtest_erase_eraseblock(mtd, ebcnt - 1); if (err) goto out; @@ -626,7 +552,7 @@ static int __init mtd_oobtest_init(void) pr_info("test 5 of 5\n"); /* Erase all eraseblocks */ - err = erase_whole_device(); + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; diff --git a/drivers/mtd/tests/mtd_pagetest.c b/drivers/mtd/tests/pagetest.c index 0c1140b..44b96e9 100644 --- a/drivers/mtd/tests/mtd_pagetest.c +++ b/drivers/mtd/tests/pagetest.c @@ -31,6 +31,8 @@ #include <linux/sched.h> #include <linux/random.h> +#include "mtd_test.h" + static int dev = -EINVAL; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -48,52 +50,18 @@ static int pgcnt; static int errcnt; static struct rnd_state rnd_state; -static int erase_eraseblock(int ebnum) -{ - int err; - struct erase_info ei; - loff_t addr = ebnum * mtd->erasesize; - - memset(&ei, 0, sizeof(struct erase_info)); - ei.mtd = mtd; - ei.addr = addr; - ei.len = mtd->erasesize; - - err = mtd_erase(mtd, &ei); - if (err) { - pr_err("error %d while erasing EB %d\n", err, ebnum); - return err; - } - - if (ei.state == MTD_ERASE_FAILED) { - pr_err("some erase error occurred at EB %d\n", - ebnum); - return -EIO; - } - - return 0; -} - static int write_eraseblock(int ebnum) { - int err = 0; - size_t written; loff_t addr = ebnum * mtd->erasesize; prandom_bytes_state(&rnd_state, writebuf, mtd->erasesize); cond_resched(); - err = mtd_write(mtd, addr, mtd->erasesize, &written, writebuf); - if (err || written != mtd->erasesize) - pr_err("error: write failed at %#llx\n", - (long long)addr); - - return err; + return mtdtest_write(mtd, addr, mtd->erasesize, writebuf); } static int verify_eraseblock(int ebnum) { uint32_t j; - size_t read; int err = 0, i; loff_t addr0, addrn; loff_t addr = ebnum * mtd->erasesize; @@ -109,31 +77,16 @@ static int verify_eraseblock(int ebnum) prandom_bytes_state(&rnd_state, writebuf, mtd->erasesize); for (j = 0; j < pgcnt - 1; ++j, addr += pgsize) { /* Do a read to set the internal dataRAMs to different data */ - err = mtd_read(mtd, addr0, bufsize, &read, twopages); - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != bufsize) { - pr_err("error: read failed at %#llx\n", - (long long)addr0); + err = mtdtest_read(mtd, addr0, bufsize, twopages); + if (err) return err; - } - err = mtd_read(mtd, addrn - bufsize, bufsize, &read, twopages); - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != bufsize) { - pr_err("error: read failed at %#llx\n", - (long long)(addrn - bufsize)); + err = mtdtest_read(mtd, addrn - bufsize, bufsize, twopages); + if (err) return err; - } memset(twopages, 0, bufsize); - err = mtd_read(mtd, addr, bufsize, &read, twopages); - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != bufsize) { - pr_err("error: read failed at %#llx\n", - (long long)addr); + err = mtdtest_read(mtd, addr, bufsize, twopages); + if (err) break; - } if (memcmp(twopages, writebuf + (j * pgsize), bufsize)) { pr_err("error: verify failed at %#llx\n", (long long)addr); @@ -145,31 +98,16 @@ static int verify_eraseblock(int ebnum) struct rnd_state old_state = rnd_state; /* Do a read to set the internal dataRAMs to different data */ - err = mtd_read(mtd, addr0, bufsize, &read, twopages); - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != bufsize) { - pr_err("error: read failed at %#llx\n", - (long long)addr0); + err = mtdtest_read(mtd, addr0, bufsize, twopages); + if (err) return err; - } - err = mtd_read(mtd, addrn - bufsize, bufsize, &read, twopages); - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != bufsize) { - pr_err("error: read failed at %#llx\n", - (long long)(addrn - bufsize)); + err = mtdtest_read(mtd, addrn - bufsize, bufsize, twopages); + if (err) return err; - } memset(twopages, 0, bufsize); - err = mtd_read(mtd, addr, bufsize, &read, twopages); - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != bufsize) { - pr_err("error: read failed at %#llx\n", - (long long)addr); + err = mtdtest_read(mtd, addr, bufsize, twopages); + if (err) return err; - } memcpy(boundary, writebuf + mtd->erasesize - pgsize, pgsize); prandom_bytes_state(&rnd_state, boundary + pgsize, pgsize); if (memcmp(twopages, boundary, bufsize)) { @@ -184,17 +122,14 @@ static int verify_eraseblock(int ebnum) static int crosstest(void) { - size_t read; int err = 0, i; loff_t addr, addr0, addrn; unsigned char *pp1, *pp2, *pp3, *pp4; pr_info("crosstest\n"); pp1 = kmalloc(pgsize * 4, GFP_KERNEL); - if (!pp1) { - pr_err("error: cannot allocate memory\n"); + if (!pp1) return -ENOMEM; - } pp2 = pp1 + pgsize; pp3 = pp2 + pgsize; pp4 = pp3 + pgsize; @@ -210,24 +145,16 @@ static int crosstest(void) /* Read 2nd-to-last page to pp1 */ addr = addrn - pgsize - pgsize; - err = mtd_read(mtd, addr, pgsize, &read, pp1); - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", - (long long)addr); + err = mtdtest_read(mtd, addr, pgsize, pp1); + if (err) { kfree(pp1); return err; } /* Read 3rd-to-last page to pp1 */ addr = addrn - pgsize - pgsize - pgsize; - err = mtd_read(mtd, addr, pgsize, &read, pp1); - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", - (long long)addr); + err = mtdtest_read(mtd, addr, pgsize, pp1); + if (err) { kfree(pp1); return err; } @@ -235,12 +162,8 @@ static int crosstest(void) /* Read first page to pp2 */ addr = addr0; pr_info("reading page at %#llx\n", (long long)addr); - err = mtd_read(mtd, addr, pgsize, &read, pp2); - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", - (long long)addr); + err = mtdtest_read(mtd, addr, pgsize, pp2); + if (err) { kfree(pp1); return err; } @@ -248,12 +171,8 @@ static int crosstest(void) /* Read last page to pp3 */ addr = addrn - pgsize; pr_info("reading page at %#llx\n", (long long)addr); - err = mtd_read(mtd, addr, pgsize, &read, pp3); - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", - (long long)addr); + err = mtdtest_read(mtd, addr, pgsize, pp3); + if (err) { kfree(pp1); return err; } @@ -261,12 +180,8 @@ static int crosstest(void) /* Read first page again to pp4 */ addr = addr0; pr_info("reading page at %#llx\n", (long long)addr); - err = mtd_read(mtd, addr, pgsize, &read, pp4); - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", - (long long)addr); + err = mtdtest_read(mtd, addr, pgsize, pp4); + if (err) { kfree(pp1); return err; } @@ -285,7 +200,6 @@ static int crosstest(void) static int erasecrosstest(void) { - size_t read, written; int err = 0, i, ebnum, ebnum2; loff_t addr0; char *readbuf = twopages; @@ -304,30 +218,22 @@ static int erasecrosstest(void) ebnum2 -= 1; pr_info("erasing block %d\n", ebnum); - err = erase_eraseblock(ebnum); + err = mtdtest_erase_eraseblock(mtd, ebnum); if (err) return err; pr_info("writing 1st page of block %d\n", ebnum); prandom_bytes_state(&rnd_state, writebuf, pgsize); strcpy(writebuf, "There is no data like this!"); - err = mtd_write(mtd, addr0, pgsize, &written, writebuf); - if (err || written != pgsize) { - pr_info("error: write failed at %#llx\n", - (long long)addr0); - return err ? err : -1; - } + err = mtdtest_write(mtd, addr0, pgsize, writebuf); + if (err) + return err; pr_info("reading 1st page of block %d\n", ebnum); memset(readbuf, 0, pgsize); - err = mtd_read(mtd, addr0, pgsize, &read, readbuf); - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", - (long long)addr0); - return err ? err : -1; - } + err = mtdtest_read(mtd, addr0, pgsize, readbuf); + if (err) + return err; pr_info("verifying 1st page of block %d\n", ebnum); if (memcmp(writebuf, readbuf, pgsize)) { @@ -337,35 +243,27 @@ static int erasecrosstest(void) } pr_info("erasing block %d\n", ebnum); - err = erase_eraseblock(ebnum); + err = mtdtest_erase_eraseblock(mtd, ebnum); if (err) return err; pr_info("writing 1st page of block %d\n", ebnum); prandom_bytes_state(&rnd_state, writebuf, pgsize); strcpy(writebuf, "There is no data like this!"); - err = mtd_write(mtd, addr0, pgsize, &written, writebuf); - if (err || written != pgsize) { - pr_err("error: write failed at %#llx\n", - (long long)addr0); - return err ? err : -1; - } + err = mtdtest_write(mtd, addr0, pgsize, writebuf); + if (err) + return err; pr_info("erasing block %d\n", ebnum2); - err = erase_eraseblock(ebnum2); + err = mtdtest_erase_eraseblock(mtd, ebnum2); if (err) return err; pr_info("reading 1st page of block %d\n", ebnum); memset(readbuf, 0, pgsize); - err = mtd_read(mtd, addr0, pgsize, &read, readbuf); - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", - (long long)addr0); - return err ? err : -1; - } + err = mtdtest_read(mtd, addr0, pgsize, readbuf); + if (err) + return err; pr_info("verifying 1st page of block %d\n", ebnum); if (memcmp(writebuf, readbuf, pgsize)) { @@ -381,7 +279,6 @@ static int erasecrosstest(void) static int erasetest(void) { - size_t read, written; int err = 0, i, ebnum, ok = 1; loff_t addr0; @@ -395,33 +292,25 @@ static int erasetest(void) } pr_info("erasing block %d\n", ebnum); - err = erase_eraseblock(ebnum); + err = mtdtest_erase_eraseblock(mtd, ebnum); if (err) return err; pr_info("writing 1st page of block %d\n", ebnum); prandom_bytes_state(&rnd_state, writebuf, pgsize); - err = mtd_write(mtd, addr0, pgsize, &written, writebuf); - if (err || written != pgsize) { - pr_err("error: write failed at %#llx\n", - (long long)addr0); - return err ? err : -1; - } + err = mtdtest_write(mtd, addr0, pgsize, writebuf); + if (err) + return err; pr_info("erasing block %d\n", ebnum); - err = erase_eraseblock(ebnum); + err = mtdtest_erase_eraseblock(mtd, ebnum); if (err) return err; pr_info("reading 1st page of block %d\n", ebnum); - err = mtd_read(mtd, addr0, pgsize, &read, twopages); - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", - (long long)addr0); - return err ? err : -1; - } + err = mtdtest_read(mtd, addr0, pgsize, twopages); + if (err) + return err; pr_info("verifying 1st page of block %d is all 0xff\n", ebnum); @@ -440,38 +329,6 @@ static int erasetest(void) return err; } -static int is_block_bad(int ebnum) -{ - loff_t addr = ebnum * mtd->erasesize; - int ret; - - ret = mtd_block_isbad(mtd, addr); - if (ret) - pr_info("block %d is bad\n", ebnum); - return ret; -} - -static int scan_for_bad_eraseblocks(void) -{ - int i, bad = 0; - - bbt = kzalloc(ebcnt, GFP_KERNEL); - if (!bbt) { - pr_err("error: cannot allocate memory\n"); - return -ENOMEM; - } - - pr_info("scanning for bad eraseblocks\n"); - for (i = 0; i < ebcnt; ++i) { - bbt[i] = is_block_bad(i) ? 1 : 0; - if (bbt[i]) - bad += 1; - cond_resched(); - } - pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); - return 0; -} - static int __init mtd_pagetest_init(void) { int err = 0; @@ -516,36 +373,28 @@ static int __init mtd_pagetest_init(void) err = -ENOMEM; bufsize = pgsize * 2; writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); - if (!writebuf) { - pr_err("error: cannot allocate memory\n"); + if (!writebuf) goto out; - } twopages = kmalloc(bufsize, GFP_KERNEL); - if (!twopages) { - pr_err("error: cannot allocate memory\n"); + if (!twopages) goto out; - } boundary = kmalloc(bufsize, GFP_KERNEL); - if (!boundary) { - pr_err("error: cannot allocate memory\n"); + if (!boundary) goto out; - } - err = scan_for_bad_eraseblocks(); + bbt = kzalloc(ebcnt, GFP_KERNEL); + if (!bbt) + goto out; + err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt); 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); + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); + if (err) + goto out; + pr_info("erased %u eraseblocks\n", ebcnt); /* Write all eraseblocks */ prandom_seed_state(&rnd_state, 1); diff --git a/drivers/mtd/tests/mtd_readtest.c b/drivers/mtd/tests/readtest.c index 266de04..626e66d 100644 --- a/drivers/mtd/tests/mtd_readtest.c +++ b/drivers/mtd/tests/readtest.c @@ -29,6 +29,8 @@ #include <linux/slab.h> #include <linux/sched.h> +#include "mtd_test.h" + static int dev = -EINVAL; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -44,7 +46,6 @@ static int pgcnt; static int read_eraseblock_by_page(int ebnum) { - size_t read; int i, ret, err = 0; loff_t addr = ebnum * mtd->erasesize; void *buf = iobuf; @@ -52,16 +53,10 @@ static int read_eraseblock_by_page(int ebnum) for (i = 0; i < pgcnt; i++) { memset(buf, 0 , pgsize); - ret = mtd_read(mtd, addr, pgsize, &read, buf); - if (ret == -EUCLEAN) - ret = 0; - if (ret || read != pgsize) { - pr_err("error: read failed at %#llx\n", - (long long)addr); + ret = mtdtest_read(mtd, addr, pgsize, buf); + if (ret) { if (!err) err = ret; - if (!err) - err = -EINVAL; } if (mtd->oobsize) { struct mtd_oob_ops ops; @@ -127,41 +122,6 @@ static void dump_eraseblock(int ebnum) } } -static int is_block_bad(int ebnum) -{ - loff_t addr = ebnum * mtd->erasesize; - int ret; - - ret = mtd_block_isbad(mtd, addr); - if (ret) - pr_info("block %d is bad\n", ebnum); - return ret; -} - -static int scan_for_bad_eraseblocks(void) -{ - int i, bad = 0; - - bbt = kzalloc(ebcnt, GFP_KERNEL); - if (!bbt) { - pr_err("error: cannot allocate memory\n"); - return -ENOMEM; - } - - if (!mtd_can_have_bb(mtd)) - return 0; - - pr_info("scanning for bad eraseblocks\n"); - for (i = 0; i < ebcnt; ++i) { - bbt[i] = is_block_bad(i) ? 1 : 0; - if (bbt[i]) - bad += 1; - cond_resched(); - } - pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); - return 0; -} - static int __init mtd_readtest_init(void) { uint64_t tmp; @@ -204,17 +164,16 @@ static int __init mtd_readtest_init(void) err = -ENOMEM; iobuf = kmalloc(mtd->erasesize, GFP_KERNEL); - if (!iobuf) { - pr_err("error: cannot allocate memory\n"); + if (!iobuf) goto out; - } iobuf1 = kmalloc(mtd->erasesize, GFP_KERNEL); - if (!iobuf1) { - pr_err("error: cannot allocate memory\n"); + if (!iobuf1) goto out; - } - err = scan_for_bad_eraseblocks(); + bbt = kzalloc(ebcnt, GFP_KERNEL); + if (!bbt) + goto out; + err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; diff --git a/drivers/mtd/tests/mtd_speedtest.c b/drivers/mtd/tests/speedtest.c index a6ce9c1..87ff6a2 100644 --- a/drivers/mtd/tests/mtd_speedtest.c +++ b/drivers/mtd/tests/speedtest.c @@ -30,6 +30,8 @@ #include <linux/sched.h> #include <linux/random.h> +#include "mtd_test.h" + static int dev = -EINVAL; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -49,33 +51,6 @@ static int pgcnt; static int goodebcnt; static struct timeval start, finish; - -static int erase_eraseblock(int ebnum) -{ - int err; - struct erase_info ei; - loff_t addr = ebnum * mtd->erasesize; - - memset(&ei, 0, sizeof(struct erase_info)); - ei.mtd = mtd; - ei.addr = addr; - ei.len = mtd->erasesize; - - err = mtd_erase(mtd, &ei); - if (err) { - pr_err("error %d while erasing EB %d\n", err, ebnum); - return err; - } - - if (ei.state == MTD_ERASE_FAILED) { - pr_err("some erase error occurred at EB %d\n", - ebnum); - return -EIO; - } - - return 0; -} - static int multiblock_erase(int ebnum, int blocks) { int err; @@ -103,54 +78,23 @@ static int multiblock_erase(int ebnum, int blocks) return 0; } -static int erase_whole_device(void) -{ - int err; - unsigned int i; - - for (i = 0; i < ebcnt; ++i) { - if (bbt[i]) - continue; - err = erase_eraseblock(i); - if (err) - return err; - cond_resched(); - } - return 0; -} - static int write_eraseblock(int ebnum) { - size_t written; - int err = 0; loff_t addr = ebnum * mtd->erasesize; - err = mtd_write(mtd, addr, mtd->erasesize, &written, iobuf); - if (err || written != mtd->erasesize) { - pr_err("error: write failed at %#llx\n", addr); - if (!err) - err = -EINVAL; - } - - return err; + return mtdtest_write(mtd, addr, mtd->erasesize, iobuf); } static int write_eraseblock_by_page(int ebnum) { - size_t written; int i, err = 0; loff_t addr = ebnum * mtd->erasesize; void *buf = iobuf; for (i = 0; i < pgcnt; i++) { - err = mtd_write(mtd, addr, pgsize, &written, buf); - if (err || written != pgsize) { - pr_err("error: write failed at %#llx\n", - addr); - if (!err) - err = -EINVAL; + err = mtdtest_write(mtd, addr, pgsize, buf); + if (err) break; - } addr += pgsize; buf += pgsize; } @@ -160,74 +104,41 @@ static int write_eraseblock_by_page(int ebnum) static int write_eraseblock_by_2pages(int ebnum) { - size_t written, sz = pgsize * 2; + size_t sz = pgsize * 2; int i, n = pgcnt / 2, err = 0; loff_t addr = ebnum * mtd->erasesize; void *buf = iobuf; for (i = 0; i < n; i++) { - err = mtd_write(mtd, addr, sz, &written, buf); - if (err || written != sz) { - pr_err("error: write failed at %#llx\n", - addr); - if (!err) - err = -EINVAL; + err = mtdtest_write(mtd, addr, sz, buf); + if (err) return err; - } addr += sz; buf += sz; } - if (pgcnt % 2) { - err = mtd_write(mtd, addr, pgsize, &written, buf); - if (err || written != pgsize) { - pr_err("error: write failed at %#llx\n", - addr); - if (!err) - err = -EINVAL; - } - } + if (pgcnt % 2) + err = mtdtest_write(mtd, addr, pgsize, buf); return err; } static int read_eraseblock(int ebnum) { - size_t read; - int err = 0; loff_t addr = ebnum * mtd->erasesize; - err = mtd_read(mtd, addr, mtd->erasesize, &read, iobuf); - /* Ignore corrected ECC errors */ - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != mtd->erasesize) { - pr_err("error: read failed at %#llx\n", addr); - if (!err) - err = -EINVAL; - } - - return err; + return mtdtest_read(mtd, addr, mtd->erasesize, iobuf); } static int read_eraseblock_by_page(int ebnum) { - size_t read; int i, err = 0; loff_t addr = ebnum * mtd->erasesize; void *buf = iobuf; for (i = 0; i < pgcnt; i++) { - err = mtd_read(mtd, addr, pgsize, &read, buf); - /* Ignore corrected ECC errors */ - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", - addr); - if (!err) - err = -EINVAL; + err = mtdtest_read(mtd, addr, pgsize, buf); + if (err) break; - } addr += pgsize; buf += pgsize; } @@ -237,53 +148,24 @@ static int read_eraseblock_by_page(int ebnum) static int read_eraseblock_by_2pages(int ebnum) { - size_t read, sz = pgsize * 2; + size_t sz = pgsize * 2; int i, n = pgcnt / 2, err = 0; loff_t addr = ebnum * mtd->erasesize; void *buf = iobuf; for (i = 0; i < n; i++) { - err = mtd_read(mtd, addr, sz, &read, buf); - /* Ignore corrected ECC errors */ - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != sz) { - pr_err("error: read failed at %#llx\n", - addr); - if (!err) - err = -EINVAL; + err = mtdtest_read(mtd, addr, sz, buf); + if (err) return err; - } addr += sz; buf += sz; } - if (pgcnt % 2) { - err = mtd_read(mtd, addr, pgsize, &read, buf); - /* Ignore corrected ECC errors */ - if (mtd_is_bitflip(err)) - err = 0; - if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", - addr); - if (!err) - err = -EINVAL; - } - } + if (pgcnt % 2) + err = mtdtest_read(mtd, addr, pgsize, buf); return err; } -static int is_block_bad(int ebnum) -{ - loff_t addr = ebnum * mtd->erasesize; - int ret; - - ret = mtd_block_isbad(mtd, addr); - if (ret) - pr_info("block %d is bad\n", ebnum); - return ret; -} - static inline void start_timing(void) { do_gettimeofday(&start); @@ -308,32 +190,6 @@ static long calc_speed(void) return k; } -static int scan_for_bad_eraseblocks(void) -{ - int i, bad = 0; - - bbt = kzalloc(ebcnt, GFP_KERNEL); - if (!bbt) { - pr_err("error: cannot allocate memory\n"); - return -ENOMEM; - } - - if (!mtd_can_have_bb(mtd)) - goto out; - - pr_info("scanning for bad eraseblocks\n"); - for (i = 0; i < ebcnt; ++i) { - bbt[i] = is_block_bad(i) ? 1 : 0; - if (bbt[i]) - bad += 1; - cond_resched(); - } - pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); -out: - goodebcnt = ebcnt - bad; - return 0; -} - static int __init mtd_speedtest_init(void) { int err, i, blocks, j, k; @@ -384,18 +240,23 @@ static int __init mtd_speedtest_init(void) err = -ENOMEM; iobuf = kmalloc(mtd->erasesize, GFP_KERNEL); - if (!iobuf) { - pr_err("error: cannot allocate memory\n"); + if (!iobuf) goto out; - } prandom_bytes(iobuf, mtd->erasesize); - err = scan_for_bad_eraseblocks(); + bbt = kzalloc(ebcnt, GFP_KERNEL); + if (!bbt) + goto out; + err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; + for (i = 0; i < ebcnt; i++) { + if (!bbt[i]) + goodebcnt++; + } - err = erase_whole_device(); + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; @@ -429,7 +290,7 @@ static int __init mtd_speedtest_init(void) speed = calc_speed(); pr_info("eraseblock read speed is %ld KiB/s\n", speed); - err = erase_whole_device(); + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; @@ -463,7 +324,7 @@ static int __init mtd_speedtest_init(void) speed = calc_speed(); pr_info("page read speed is %ld KiB/s\n", speed); - err = erase_whole_device(); + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; @@ -500,14 +361,9 @@ static int __init mtd_speedtest_init(void) /* Erase all eraseblocks */ pr_info("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(); - } + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); + if (err) + goto out; stop_timing(); speed = calc_speed(); pr_info("erase speed is %ld KiB/s\n", speed); diff --git a/drivers/mtd/tests/mtd_stresstest.c b/drivers/mtd/tests/stresstest.c index 787f539..c9d42cc 100644 --- a/drivers/mtd/tests/mtd_stresstest.c +++ b/drivers/mtd/tests/stresstest.c @@ -31,6 +31,8 @@ #include <linux/vmalloc.h> #include <linux/random.h> +#include "mtd_test.h" + static int dev = -EINVAL; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -81,49 +83,11 @@ static int rand_len(int offs) return len; } -static int erase_eraseblock(int ebnum) -{ - int err; - struct erase_info ei; - loff_t addr = ebnum * mtd->erasesize; - - memset(&ei, 0, sizeof(struct erase_info)); - ei.mtd = mtd; - ei.addr = addr; - ei.len = mtd->erasesize; - - err = mtd_erase(mtd, &ei); - if (unlikely(err)) { - pr_err("error %d while erasing EB %d\n", err, ebnum); - return err; - } - - if (unlikely(ei.state == MTD_ERASE_FAILED)) { - pr_err("some erase error occurred at EB %d\n", - ebnum); - return -EIO; - } - - return 0; -} - -static int is_block_bad(int ebnum) -{ - loff_t addr = ebnum * mtd->erasesize; - int ret; - - ret = mtd_block_isbad(mtd, addr); - if (ret) - pr_info("block %d is bad\n", ebnum); - return ret; -} - static int do_read(void) { - size_t read; int eb = rand_eb(); int offs = rand_offs(); - int len = rand_len(offs), err; + int len = rand_len(offs); loff_t addr; if (bbt[eb + 1]) { @@ -133,28 +97,17 @@ static int do_read(void) len = mtd->erasesize - offs; } addr = eb * mtd->erasesize + offs; - err = mtd_read(mtd, addr, len, &read, readbuf); - if (mtd_is_bitflip(err)) - err = 0; - if (unlikely(err || read != len)) { - pr_err("error: read failed at 0x%llx\n", - (long long)addr); - if (!err) - err = -EINVAL; - return err; - } - return 0; + return mtdtest_read(mtd, addr, len, readbuf); } static int do_write(void) { int eb = rand_eb(), offs, err, len; - size_t written; loff_t addr; offs = offsets[eb]; if (offs >= mtd->erasesize) { - err = erase_eraseblock(eb); + err = mtdtest_erase_eraseblock(mtd, eb); if (err) return err; offs = offsets[eb] = 0; @@ -165,21 +118,16 @@ static int do_write(void) if (bbt[eb + 1]) len = mtd->erasesize - offs; else { - err = erase_eraseblock(eb + 1); + err = mtdtest_erase_eraseblock(mtd, eb + 1); if (err) return err; offsets[eb + 1] = 0; } } addr = eb * mtd->erasesize + offs; - err = mtd_write(mtd, addr, len, &written, writebuf); - if (unlikely(err || written != len)) { - pr_err("error: write failed at 0x%llx\n", - (long long)addr); - if (!err) - err = -EINVAL; + err = mtdtest_write(mtd, addr, len, writebuf); + if (unlikely(err)) return err; - } offs += len; while (offs > mtd->erasesize) { offsets[eb++] = mtd->erasesize; @@ -197,30 +145,6 @@ static int do_operation(void) return do_write(); } -static int scan_for_bad_eraseblocks(void) -{ - int i, bad = 0; - - bbt = kzalloc(ebcnt, GFP_KERNEL); - if (!bbt) { - pr_err("error: cannot allocate memory\n"); - return -ENOMEM; - } - - if (!mtd_can_have_bb(mtd)) - return 0; - - pr_info("scanning for bad eraseblocks\n"); - for (i = 0; i < ebcnt; ++i) { - bbt[i] = is_block_bad(i) ? 1 : 0; - if (bbt[i]) - bad += 1; - cond_resched(); - } - pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); - return 0; -} - static int __init mtd_stresstest_init(void) { int err; @@ -276,15 +200,16 @@ static int __init mtd_stresstest_init(void) readbuf = vmalloc(bufsize); writebuf = vmalloc(bufsize); offsets = kmalloc(ebcnt * sizeof(int), GFP_KERNEL); - if (!readbuf || !writebuf || !offsets) { - pr_err("error: cannot allocate memory\n"); + if (!readbuf || !writebuf || !offsets) goto out; - } for (i = 0; i < ebcnt; i++) offsets[i] = mtd->erasesize; prandom_bytes(writebuf, bufsize); - err = scan_for_bad_eraseblocks(); + bbt = kzalloc(ebcnt, GFP_KERNEL); + if (!bbt) + goto out; + err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; diff --git a/drivers/mtd/tests/mtd_subpagetest.c b/drivers/mtd/tests/subpagetest.c index aade56f..e2c0adf 100644 --- a/drivers/mtd/tests/mtd_subpagetest.c +++ b/drivers/mtd/tests/subpagetest.c @@ -30,6 +30,8 @@ #include <linux/sched.h> #include <linux/random.h> +#include "mtd_test.h" + static int dev = -EINVAL; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -51,50 +53,6 @@ static inline void clear_data(unsigned char *buf, size_t len) memset(buf, 0, len); } -static int erase_eraseblock(int ebnum) -{ - int err; - struct erase_info ei; - loff_t addr = ebnum * mtd->erasesize; - - memset(&ei, 0, sizeof(struct erase_info)); - ei.mtd = mtd; - ei.addr = addr; - ei.len = mtd->erasesize; - - err = mtd_erase(mtd, &ei); - if (err) { - pr_err("error %d while erasing EB %d\n", err, ebnum); - return err; - } - - if (ei.state == MTD_ERASE_FAILED) { - pr_err("some erase error occurred at EB %d\n", - ebnum); - return -EIO; - } - - return 0; -} - -static int erase_whole_device(void) -{ - int err; - unsigned int i; - - pr_info("erasing whole device\n"); - for (i = 0; i < ebcnt; ++i) { - if (bbt[i]) - continue; - err = erase_eraseblock(i); - if (err) - return err; - cond_resched(); - } - pr_info("erased %u eraseblocks\n", i); - return 0; -} - static int write_eraseblock(int ebnum) { size_t written; @@ -317,38 +275,6 @@ static int verify_all_eraseblocks_ff(void) return 0; } -static int is_block_bad(int ebnum) -{ - loff_t addr = ebnum * mtd->erasesize; - int ret; - - ret = mtd_block_isbad(mtd, addr); - if (ret) - pr_info("block %d is bad\n", ebnum); - return ret; -} - -static int scan_for_bad_eraseblocks(void) -{ - int i, bad = 0; - - bbt = kzalloc(ebcnt, GFP_KERNEL); - if (!bbt) { - pr_err("error: cannot allocate memory\n"); - return -ENOMEM; - } - - pr_info("scanning for bad eraseblocks\n"); - for (i = 0; i < ebcnt; ++i) { - bbt[i] = is_block_bad(i) ? 1 : 0; - if (bbt[i]) - bad += 1; - cond_resched(); - } - pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); - return 0; -} - static int __init mtd_subpagetest_init(void) { int err = 0; @@ -393,21 +319,20 @@ static int __init mtd_subpagetest_init(void) err = -ENOMEM; bufsize = subpgsize * 32; writebuf = kmalloc(bufsize, GFP_KERNEL); - if (!writebuf) { - pr_info("error: cannot allocate memory\n"); + if (!writebuf) goto out; - } readbuf = kmalloc(bufsize, GFP_KERNEL); - if (!readbuf) { - pr_info("error: cannot allocate memory\n"); + if (!readbuf) + goto out; + bbt = kzalloc(ebcnt, GFP_KERNEL); + if (!bbt) goto out; - } - err = scan_for_bad_eraseblocks(); + err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; - err = erase_whole_device(); + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; @@ -439,7 +364,7 @@ static int __init mtd_subpagetest_init(void) } pr_info("verified %u eraseblocks\n", i); - err = erase_whole_device(); + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; @@ -477,7 +402,7 @@ static int __init mtd_subpagetest_init(void) } pr_info("verified %u eraseblocks\n", i); - err = erase_whole_device(); + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; diff --git a/drivers/mtd/tests/mtd_torturetest.c b/drivers/mtd/tests/torturetest.c index 3a9f6a6..eeab969 100644 --- a/drivers/mtd/tests/mtd_torturetest.c +++ b/drivers/mtd/tests/torturetest.c @@ -32,6 +32,7 @@ #include <linux/mtd/mtd.h> #include <linux/slab.h> #include <linux/sched.h> +#include "mtd_test.h" #define RETRIES 3 @@ -93,35 +94,6 @@ static inline void stop_timing(void) } /* - * Erase eraseblock number @ebnum. - */ -static inline int erase_eraseblock(int ebnum) -{ - int err; - struct erase_info ei; - loff_t addr = ebnum * mtd->erasesize; - - memset(&ei, 0, sizeof(struct erase_info)); - ei.mtd = mtd; - ei.addr = addr; - ei.len = mtd->erasesize; - - err = mtd_erase(mtd, &ei); - if (err) { - pr_err("error %d while erasing EB %d\n", err, ebnum); - return err; - } - - if (ei.state == MTD_ERASE_FAILED) { - pr_err("some erase error occurred at EB %d\n", - ebnum); - return -EIO; - } - - return 0; -} - -/* * Check that the contents of eraseblock number @enbum is equivalent to the * @buf buffer. */ @@ -208,7 +180,7 @@ static inline int write_pattern(int ebnum, void *buf) static int __init tort_init(void) { int err = 0, i, infinite = !cycles_count; - int *bad_ebs; + unsigned char *bad_ebs; printk(KERN_INFO "\n"); printk(KERN_INFO "=================================================\n"); @@ -265,7 +237,7 @@ static int __init tort_init(void) if (!check_buf) goto out_patt_FF; - bad_ebs = kcalloc(ebcnt, sizeof(*bad_ebs), GFP_KERNEL); + bad_ebs = kzalloc(ebcnt, GFP_KERNEL); if (!bad_ebs) goto out_check_buf; @@ -283,40 +255,16 @@ static int __init tort_init(void) } } - /* - * Check if there is a bad eraseblock among those we are going to test. - */ - if (mtd_can_have_bb(mtd)) { - for (i = eb; i < eb + ebcnt; i++) { - err = mtd_block_isbad(mtd, (loff_t)i * mtd->erasesize); - - if (err < 0) { - pr_info("block_isbad() returned %d " - "for EB %d\n", err, i); - goto out; - } - - if (err) { - pr_err("EB %d is bad. Skip it.\n", i); - bad_ebs[i - eb] = 1; - } - } - } + err = mtdtest_scan_for_bad_eraseblocks(mtd, bad_ebs, eb, ebcnt); + if (err) + goto out; start_timing(); while (1) { int i; void *patt; - /* Erase all eraseblocks */ - for (i = eb; i < eb + ebcnt; i++) { - if (bad_ebs[i - eb]) - continue; - err = erase_eraseblock(i); - if (err) - goto out; - cond_resched(); - } + mtdtest_erase_good_eraseblocks(mtd, bad_ebs, eb, ebcnt); /* Check if the eraseblocks contain only 0xFF bytes */ if (check) { |