0001
0002 #define pr_fmt(fmt) "mtd_test: " fmt
0003
0004 #include <linux/module.h>
0005 #include <linux/sched.h>
0006 #include <linux/printk.h>
0007
0008 #include "mtd_test.h"
0009
0010 int mtdtest_erase_eraseblock(struct mtd_info *mtd, unsigned int ebnum)
0011 {
0012 int err;
0013 struct erase_info ei;
0014 loff_t addr = (loff_t)ebnum * mtd->erasesize;
0015
0016 memset(&ei, 0, sizeof(struct erase_info));
0017 ei.addr = addr;
0018 ei.len = mtd->erasesize;
0019
0020 err = mtd_erase(mtd, &ei);
0021 if (err) {
0022 pr_info("error %d while erasing EB %d\n", err, ebnum);
0023 return err;
0024 }
0025
0026 return 0;
0027 }
0028
0029 static int is_block_bad(struct mtd_info *mtd, unsigned int ebnum)
0030 {
0031 int ret;
0032 loff_t addr = (loff_t)ebnum * mtd->erasesize;
0033
0034 ret = mtd_block_isbad(mtd, addr);
0035 if (ret)
0036 pr_info("block %d is bad\n", ebnum);
0037
0038 return ret;
0039 }
0040
0041 int mtdtest_scan_for_bad_eraseblocks(struct mtd_info *mtd, unsigned char *bbt,
0042 unsigned int eb, int ebcnt)
0043 {
0044 int i, bad = 0;
0045
0046 if (!mtd_can_have_bb(mtd))
0047 return 0;
0048
0049 pr_info("scanning for bad eraseblocks\n");
0050 for (i = 0; i < ebcnt; ++i) {
0051 bbt[i] = is_block_bad(mtd, eb + i) ? 1 : 0;
0052 if (bbt[i])
0053 bad += 1;
0054 cond_resched();
0055 }
0056 pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
0057
0058 return 0;
0059 }
0060
0061 int mtdtest_erase_good_eraseblocks(struct mtd_info *mtd, unsigned char *bbt,
0062 unsigned int eb, int ebcnt)
0063 {
0064 int err;
0065 unsigned int i;
0066
0067 for (i = 0; i < ebcnt; ++i) {
0068 if (bbt[i])
0069 continue;
0070 err = mtdtest_erase_eraseblock(mtd, eb + i);
0071 if (err)
0072 return err;
0073 cond_resched();
0074 }
0075
0076 return 0;
0077 }
0078
0079 int mtdtest_read(struct mtd_info *mtd, loff_t addr, size_t size, void *buf)
0080 {
0081 size_t read;
0082 int err;
0083
0084 err = mtd_read(mtd, addr, size, &read, buf);
0085
0086 if (mtd_is_bitflip(err))
0087 err = 0;
0088 if (!err && read != size)
0089 err = -EIO;
0090 if (err)
0091 pr_err("error: read failed at %#llx\n", addr);
0092
0093 return err;
0094 }
0095
0096 int mtdtest_write(struct mtd_info *mtd, loff_t addr, size_t size,
0097 const void *buf)
0098 {
0099 size_t written;
0100 int err;
0101
0102 err = mtd_write(mtd, addr, size, &written, buf);
0103 if (!err && written != size)
0104 err = -EIO;
0105 if (err)
0106 pr_err("error: write failed at %#llx\n", addr);
0107
0108 return err;
0109 }