0001
0002
0003
0004
0005
0006
0007
0008
0009 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0010
0011 #include <linux/init.h>
0012 #include <linux/module.h>
0013 #include <linux/moduleparam.h>
0014 #include <linux/err.h>
0015 #include <linux/mtd/mtd.h>
0016 #include <linux/slab.h>
0017 #include <linux/sched.h>
0018 #include <linux/random.h>
0019
0020 #include "mtd_test.h"
0021
0022 static int dev = -EINVAL;
0023 module_param(dev, int, S_IRUGO);
0024 MODULE_PARM_DESC(dev, "MTD device number to use");
0025
0026 static struct mtd_info *mtd;
0027 static unsigned char *writebuf;
0028 static unsigned char *readbuf;
0029 static unsigned char *bbt;
0030
0031 static int subpgsize;
0032 static int bufsize;
0033 static int ebcnt;
0034 static int pgcnt;
0035 static int errcnt;
0036 static struct rnd_state rnd_state;
0037
0038 static inline void clear_data(unsigned char *buf, size_t len)
0039 {
0040 memset(buf, 0, len);
0041 }
0042
0043 static int write_eraseblock(int ebnum)
0044 {
0045 size_t written;
0046 int err = 0;
0047 loff_t addr = (loff_t)ebnum * mtd->erasesize;
0048
0049 prandom_bytes_state(&rnd_state, writebuf, subpgsize);
0050 err = mtd_write(mtd, addr, subpgsize, &written, writebuf);
0051 if (unlikely(err || written != subpgsize)) {
0052 pr_err("error: write failed at %#llx\n",
0053 (long long)addr);
0054 if (written != subpgsize) {
0055 pr_err(" write size: %#x\n", subpgsize);
0056 pr_err(" written: %#zx\n", written);
0057 }
0058 return err ? err : -1;
0059 }
0060
0061 addr += subpgsize;
0062
0063 prandom_bytes_state(&rnd_state, writebuf, subpgsize);
0064 err = mtd_write(mtd, addr, subpgsize, &written, writebuf);
0065 if (unlikely(err || written != subpgsize)) {
0066 pr_err("error: write failed at %#llx\n",
0067 (long long)addr);
0068 if (written != subpgsize) {
0069 pr_err(" write size: %#x\n", subpgsize);
0070 pr_err(" written: %#zx\n", written);
0071 }
0072 return err ? err : -1;
0073 }
0074
0075 return err;
0076 }
0077
0078 static int write_eraseblock2(int ebnum)
0079 {
0080 size_t written;
0081 int err = 0, k;
0082 loff_t addr = (loff_t)ebnum * mtd->erasesize;
0083
0084 for (k = 1; k < 33; ++k) {
0085 if (addr + (subpgsize * k) > (loff_t)(ebnum + 1) * mtd->erasesize)
0086 break;
0087 prandom_bytes_state(&rnd_state, writebuf, subpgsize * k);
0088 err = mtd_write(mtd, addr, subpgsize * k, &written, writebuf);
0089 if (unlikely(err || written != subpgsize * k)) {
0090 pr_err("error: write failed at %#llx\n",
0091 (long long)addr);
0092 if (written != subpgsize * k) {
0093 pr_err(" write size: %#x\n",
0094 subpgsize * k);
0095 pr_err(" written: %#08zx\n",
0096 written);
0097 }
0098 return err ? err : -1;
0099 }
0100 addr += subpgsize * k;
0101 }
0102
0103 return err;
0104 }
0105
0106 static void print_subpage(unsigned char *p)
0107 {
0108 int i, j;
0109
0110 for (i = 0; i < subpgsize; ) {
0111 for (j = 0; i < subpgsize && j < 32; ++i, ++j)
0112 printk("%02x", *p++);
0113 printk("\n");
0114 }
0115 }
0116
0117 static int verify_eraseblock(int ebnum)
0118 {
0119 size_t read;
0120 int err = 0;
0121 loff_t addr = (loff_t)ebnum * mtd->erasesize;
0122
0123 prandom_bytes_state(&rnd_state, writebuf, subpgsize);
0124 clear_data(readbuf, subpgsize);
0125 err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
0126 if (unlikely(err || read != subpgsize)) {
0127 if (mtd_is_bitflip(err) && read == subpgsize) {
0128 pr_info("ECC correction at %#llx\n",
0129 (long long)addr);
0130 err = 0;
0131 } else {
0132 pr_err("error: read failed at %#llx\n",
0133 (long long)addr);
0134 return err ? err : -1;
0135 }
0136 }
0137 if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
0138 pr_err("error: verify failed at %#llx\n",
0139 (long long)addr);
0140 pr_info("------------- written----------------\n");
0141 print_subpage(writebuf);
0142 pr_info("------------- read ------------------\n");
0143 print_subpage(readbuf);
0144 pr_info("-------------------------------------\n");
0145 errcnt += 1;
0146 }
0147
0148 addr += subpgsize;
0149
0150 prandom_bytes_state(&rnd_state, writebuf, subpgsize);
0151 clear_data(readbuf, subpgsize);
0152 err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
0153 if (unlikely(err || read != subpgsize)) {
0154 if (mtd_is_bitflip(err) && read == subpgsize) {
0155 pr_info("ECC correction at %#llx\n",
0156 (long long)addr);
0157 err = 0;
0158 } else {
0159 pr_err("error: read failed at %#llx\n",
0160 (long long)addr);
0161 return err ? err : -1;
0162 }
0163 }
0164 if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
0165 pr_info("error: verify failed at %#llx\n",
0166 (long long)addr);
0167 pr_info("------------- written----------------\n");
0168 print_subpage(writebuf);
0169 pr_info("------------- read ------------------\n");
0170 print_subpage(readbuf);
0171 pr_info("-------------------------------------\n");
0172 errcnt += 1;
0173 }
0174
0175 return err;
0176 }
0177
0178 static int verify_eraseblock2(int ebnum)
0179 {
0180 size_t read;
0181 int err = 0, k;
0182 loff_t addr = (loff_t)ebnum * mtd->erasesize;
0183
0184 for (k = 1; k < 33; ++k) {
0185 if (addr + (subpgsize * k) > (loff_t)(ebnum + 1) * mtd->erasesize)
0186 break;
0187 prandom_bytes_state(&rnd_state, writebuf, subpgsize * k);
0188 clear_data(readbuf, subpgsize * k);
0189 err = mtd_read(mtd, addr, subpgsize * k, &read, readbuf);
0190 if (unlikely(err || read != subpgsize * k)) {
0191 if (mtd_is_bitflip(err) && read == subpgsize * k) {
0192 pr_info("ECC correction at %#llx\n",
0193 (long long)addr);
0194 err = 0;
0195 } else {
0196 pr_err("error: read failed at "
0197 "%#llx\n", (long long)addr);
0198 return err ? err : -1;
0199 }
0200 }
0201 if (unlikely(memcmp(readbuf, writebuf, subpgsize * k))) {
0202 pr_err("error: verify failed at %#llx\n",
0203 (long long)addr);
0204 errcnt += 1;
0205 }
0206 addr += subpgsize * k;
0207 }
0208
0209 return err;
0210 }
0211
0212 static int verify_eraseblock_ff(int ebnum)
0213 {
0214 uint32_t j;
0215 size_t read;
0216 int err = 0;
0217 loff_t addr = (loff_t)ebnum * mtd->erasesize;
0218
0219 memset(writebuf, 0xff, subpgsize);
0220 for (j = 0; j < mtd->erasesize / subpgsize; ++j) {
0221 clear_data(readbuf, subpgsize);
0222 err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
0223 if (unlikely(err || read != subpgsize)) {
0224 if (mtd_is_bitflip(err) && read == subpgsize) {
0225 pr_info("ECC correction at %#llx\n",
0226 (long long)addr);
0227 err = 0;
0228 } else {
0229 pr_err("error: read failed at "
0230 "%#llx\n", (long long)addr);
0231 return err ? err : -1;
0232 }
0233 }
0234 if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
0235 pr_err("error: verify 0xff failed at "
0236 "%#llx\n", (long long)addr);
0237 errcnt += 1;
0238 }
0239 addr += subpgsize;
0240 }
0241
0242 return err;
0243 }
0244
0245 static int verify_all_eraseblocks_ff(void)
0246 {
0247 int err;
0248 unsigned int i;
0249
0250 pr_info("verifying all eraseblocks for 0xff\n");
0251 for (i = 0; i < ebcnt; ++i) {
0252 if (bbt[i])
0253 continue;
0254 err = verify_eraseblock_ff(i);
0255 if (err)
0256 return err;
0257 if (i % 256 == 0)
0258 pr_info("verified up to eraseblock %u\n", i);
0259
0260 err = mtdtest_relax();
0261 if (err)
0262 return err;
0263 }
0264 pr_info("verified %u eraseblocks\n", i);
0265 return 0;
0266 }
0267
0268 static int __init mtd_subpagetest_init(void)
0269 {
0270 int err = 0;
0271 uint32_t i;
0272 uint64_t tmp;
0273
0274 printk(KERN_INFO "\n");
0275 printk(KERN_INFO "=================================================\n");
0276
0277 if (dev < 0) {
0278 pr_info("Please specify a valid mtd-device via module parameter\n");
0279 pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
0280 return -EINVAL;
0281 }
0282
0283 pr_info("MTD device: %d\n", dev);
0284
0285 mtd = get_mtd_device(NULL, dev);
0286 if (IS_ERR(mtd)) {
0287 err = PTR_ERR(mtd);
0288 pr_err("error: cannot get MTD device\n");
0289 return err;
0290 }
0291
0292 if (!mtd_type_is_nand(mtd)) {
0293 pr_info("this test requires NAND flash\n");
0294 goto out;
0295 }
0296
0297 subpgsize = mtd->writesize >> mtd->subpage_sft;
0298 tmp = mtd->size;
0299 do_div(tmp, mtd->erasesize);
0300 ebcnt = tmp;
0301 pgcnt = mtd->erasesize / mtd->writesize;
0302
0303 pr_info("MTD device size %llu, eraseblock size %u, "
0304 "page size %u, subpage size %u, count of eraseblocks %u, "
0305 "pages per eraseblock %u, OOB size %u\n",
0306 (unsigned long long)mtd->size, mtd->erasesize,
0307 mtd->writesize, subpgsize, ebcnt, pgcnt, mtd->oobsize);
0308
0309 err = -ENOMEM;
0310 bufsize = subpgsize * 32;
0311 writebuf = kmalloc(bufsize, GFP_KERNEL);
0312 if (!writebuf)
0313 goto out;
0314 readbuf = kmalloc(bufsize, GFP_KERNEL);
0315 if (!readbuf)
0316 goto out;
0317 bbt = kzalloc(ebcnt, GFP_KERNEL);
0318 if (!bbt)
0319 goto out;
0320
0321 err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt);
0322 if (err)
0323 goto out;
0324
0325 err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt);
0326 if (err)
0327 goto out;
0328
0329 pr_info("writing whole device\n");
0330 prandom_seed_state(&rnd_state, 1);
0331 for (i = 0; i < ebcnt; ++i) {
0332 if (bbt[i])
0333 continue;
0334 err = write_eraseblock(i);
0335 if (unlikely(err))
0336 goto out;
0337 if (i % 256 == 0)
0338 pr_info("written up to eraseblock %u\n", i);
0339
0340 err = mtdtest_relax();
0341 if (err)
0342 goto out;
0343 }
0344 pr_info("written %u eraseblocks\n", i);
0345
0346 prandom_seed_state(&rnd_state, 1);
0347 pr_info("verifying all eraseblocks\n");
0348 for (i = 0; i < ebcnt; ++i) {
0349 if (bbt[i])
0350 continue;
0351 err = verify_eraseblock(i);
0352 if (unlikely(err))
0353 goto out;
0354 if (i % 256 == 0)
0355 pr_info("verified up to eraseblock %u\n", i);
0356
0357 err = mtdtest_relax();
0358 if (err)
0359 goto out;
0360 }
0361 pr_info("verified %u eraseblocks\n", i);
0362
0363 err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt);
0364 if (err)
0365 goto out;
0366
0367 err = verify_all_eraseblocks_ff();
0368 if (err)
0369 goto out;
0370
0371
0372 prandom_seed_state(&rnd_state, 3);
0373 pr_info("writing whole device\n");
0374 for (i = 0; i < ebcnt; ++i) {
0375 if (bbt[i])
0376 continue;
0377 err = write_eraseblock2(i);
0378 if (unlikely(err))
0379 goto out;
0380 if (i % 256 == 0)
0381 pr_info("written up to eraseblock %u\n", i);
0382
0383 err = mtdtest_relax();
0384 if (err)
0385 goto out;
0386 }
0387 pr_info("written %u eraseblocks\n", i);
0388
0389
0390 prandom_seed_state(&rnd_state, 3);
0391 pr_info("verifying all eraseblocks\n");
0392 for (i = 0; i < ebcnt; ++i) {
0393 if (bbt[i])
0394 continue;
0395 err = verify_eraseblock2(i);
0396 if (unlikely(err))
0397 goto out;
0398 if (i % 256 == 0)
0399 pr_info("verified up to eraseblock %u\n", i);
0400
0401 err = mtdtest_relax();
0402 if (err)
0403 goto out;
0404 }
0405 pr_info("verified %u eraseblocks\n", i);
0406
0407 err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt);
0408 if (err)
0409 goto out;
0410
0411 err = verify_all_eraseblocks_ff();
0412 if (err)
0413 goto out;
0414
0415 pr_info("finished with %d errors\n", errcnt);
0416
0417 out:
0418 kfree(bbt);
0419 kfree(readbuf);
0420 kfree(writebuf);
0421 put_mtd_device(mtd);
0422 if (err)
0423 pr_info("error %d occurred\n", err);
0424 printk(KERN_INFO "=================================================\n");
0425 return err;
0426 }
0427 module_init(mtd_subpagetest_init);
0428
0429 static void __exit mtd_subpagetest_exit(void)
0430 {
0431 return;
0432 }
0433 module_exit(mtd_subpagetest_exit);
0434
0435 MODULE_DESCRIPTION("Subpage test module");
0436 MODULE_AUTHOR("Adrian Hunter");
0437 MODULE_LICENSE("GPL");