summaryrefslogtreecommitdiff
path: root/drivers/mtd/tests
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/tests')
-rw-r--r--drivers/mtd/tests/Makefile9
-rw-r--r--drivers/mtd/tests/mtd_test.c114
-rw-r--r--drivers/mtd/tests/mtd_test.h11
-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 bd0065c0d359..937a829bb701 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 000000000000..c818a63532e7
--- /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 000000000000..f437c776c54f
--- /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 207bf9a9972f..3cd3aabbe1cd 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 3e24b379ffa4..ff35c465bfee 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 0c1140b6c286..44b96e999ad4 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 266de04b6d29..626e66d0f7e7 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 a6ce9c1fa6c5..87ff6a29f84e 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 787f539d16ca..c9d42cc2df1b 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 aade56f27945..e2c0adf24cfc 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 3a9f6a6a79f9..eeab96973cf0 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) {