0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0031
0032 #include <linux/init.h>
0033 #include <linux/module.h>
0034 #include <linux/moduleparam.h>
0035 #include <linux/mtd/mtd.h>
0036 #include <linux/err.h>
0037 #include <linux/mtd/rawnand.h>
0038 #include <linux/slab.h>
0039 #include "mtd_test.h"
0040
0041 static int dev;
0042 module_param(dev, int, S_IRUGO);
0043 MODULE_PARM_DESC(dev, "MTD device number to use");
0044
0045 static unsigned page_offset;
0046 module_param(page_offset, uint, S_IRUGO);
0047 MODULE_PARM_DESC(page_offset, "Page number relative to dev start");
0048
0049 static unsigned seed;
0050 module_param(seed, uint, S_IRUGO);
0051 MODULE_PARM_DESC(seed, "Random seed");
0052
0053 static int mode;
0054 module_param(mode, int, S_IRUGO);
0055 MODULE_PARM_DESC(mode, "0=incremental errors, 1=overwrite test");
0056
0057 static unsigned max_overwrite = 10000;
0058
0059 static loff_t offset;
0060 static unsigned eraseblock;
0061
0062
0063
0064 static unsigned subsize;
0065 static unsigned subcount;
0066
0067 static struct mtd_info *mtd;
0068
0069 static uint8_t *wbuffer;
0070 static uint8_t *rbuffer;
0071
0072
0073 static uint8_t hash(unsigned offset)
0074 {
0075 unsigned v = offset;
0076 unsigned char c;
0077 v ^= 0x7f7edfd3;
0078 v = v ^ (v >> 3);
0079 v = v ^ (v >> 5);
0080 v = v ^ (v >> 13);
0081 c = v & 0xFF;
0082
0083 c = (c & 0x0F) << 4 | (c & 0xF0) >> 4;
0084 c = (c & 0x33) << 2 | (c & 0xCC) >> 2;
0085 c = (c & 0x55) << 1 | (c & 0xAA) >> 1;
0086 return c;
0087 }
0088
0089
0090 static int write_page(int log)
0091 {
0092 if (log)
0093 pr_info("write_page\n");
0094
0095 return mtdtest_write(mtd, offset, mtd->writesize, wbuffer);
0096 }
0097
0098
0099 static int rewrite_page(int log)
0100 {
0101 int err = 0;
0102 struct mtd_oob_ops ops;
0103
0104 if (log)
0105 pr_info("rewrite page\n");
0106
0107 ops.mode = MTD_OPS_RAW;
0108 ops.len = mtd->writesize;
0109 ops.retlen = 0;
0110 ops.ooblen = 0;
0111 ops.oobretlen = 0;
0112 ops.ooboffs = 0;
0113 ops.datbuf = wbuffer;
0114 ops.oobbuf = NULL;
0115
0116 err = mtd_write_oob(mtd, offset, &ops);
0117 if (err || ops.retlen != mtd->writesize) {
0118 pr_err("error: write_oob failed (%d)\n", err);
0119 if (!err)
0120 err = -EIO;
0121 }
0122
0123 return err;
0124 }
0125
0126
0127
0128 static int read_page(int log)
0129 {
0130 int err = 0;
0131 size_t read;
0132 struct mtd_ecc_stats oldstats;
0133
0134 if (log)
0135 pr_info("read_page\n");
0136
0137
0138 memcpy(&oldstats, &mtd->ecc_stats, sizeof(oldstats));
0139
0140 err = mtd_read(mtd, offset, mtd->writesize, &read, rbuffer);
0141 if (!err || err == -EUCLEAN)
0142 err = mtd->ecc_stats.corrected - oldstats.corrected;
0143
0144 if (err < 0 || read != mtd->writesize) {
0145 pr_err("error: read failed at %#llx\n", (long long)offset);
0146 if (err >= 0)
0147 err = -EIO;
0148 }
0149
0150 return err;
0151 }
0152
0153
0154 static int verify_page(int log)
0155 {
0156 unsigned i, errs = 0;
0157
0158 if (log)
0159 pr_info("verify_page\n");
0160
0161 for (i = 0; i < mtd->writesize; i++) {
0162 if (rbuffer[i] != hash(i+seed)) {
0163 pr_err("Error: page offset %u, expected %02x, got %02x\n",
0164 i, hash(i+seed), rbuffer[i]);
0165 errs++;
0166 }
0167 }
0168
0169 if (errs)
0170 return -EIO;
0171 else
0172 return 0;
0173 }
0174
0175 #define CBIT(v, n) ((v) & (1 << (n)))
0176 #define BCLR(v, n) ((v) = (v) & ~(1 << (n)))
0177
0178
0179
0180 static int insert_biterror(unsigned byte)
0181 {
0182 int bit;
0183
0184 while (byte < mtd->writesize) {
0185 for (bit = 7; bit >= 0; bit--) {
0186 if (CBIT(wbuffer[byte], bit)) {
0187 BCLR(wbuffer[byte], bit);
0188 pr_info("Inserted biterror @ %u/%u\n", byte, bit);
0189 return 0;
0190 }
0191 }
0192 byte++;
0193 }
0194 pr_err("biterror: Failed to find a '1' bit\n");
0195 return -EIO;
0196 }
0197
0198
0199
0200 static int incremental_errors_test(void)
0201 {
0202 int err = 0;
0203 unsigned i;
0204 unsigned errs_per_subpage = 0;
0205
0206 pr_info("incremental biterrors test\n");
0207
0208 for (i = 0; i < mtd->writesize; i++)
0209 wbuffer[i] = hash(i+seed);
0210
0211 err = write_page(1);
0212 if (err)
0213 goto exit;
0214
0215 while (1) {
0216
0217 err = rewrite_page(1);
0218 if (err)
0219 goto exit;
0220
0221 err = read_page(1);
0222 if (err > 0)
0223 pr_info("Read reported %d corrected bit errors\n", err);
0224 if (err < 0) {
0225 pr_err("After %d biterrors per subpage, read reported error %d\n",
0226 errs_per_subpage, err);
0227 err = 0;
0228 goto exit;
0229 }
0230
0231 err = verify_page(1);
0232 if (err) {
0233 pr_err("ECC failure, read data is incorrect despite read success\n");
0234 goto exit;
0235 }
0236
0237 pr_info("Successfully corrected %d bit errors per subpage\n",
0238 errs_per_subpage);
0239
0240 for (i = 0; i < subcount; i++) {
0241 err = insert_biterror(i * subsize);
0242 if (err < 0)
0243 goto exit;
0244 }
0245 errs_per_subpage++;
0246 }
0247
0248 exit:
0249 return err;
0250 }
0251
0252
0253
0254
0255
0256 static int overwrite_test(void)
0257 {
0258 int err = 0;
0259 unsigned i;
0260 unsigned max_corrected = 0;
0261 unsigned opno = 0;
0262
0263
0264 #define MAXBITS 512
0265 static unsigned bitstats[MAXBITS];
0266
0267 memset(bitstats, 0, sizeof(bitstats));
0268
0269 pr_info("overwrite biterrors test\n");
0270
0271 for (i = 0; i < mtd->writesize; i++)
0272 wbuffer[i] = hash(i+seed);
0273
0274 err = write_page(1);
0275 if (err)
0276 goto exit;
0277
0278 while (opno < max_overwrite) {
0279
0280 err = write_page(0);
0281 if (err)
0282 break;
0283
0284 err = read_page(0);
0285 if (err >= 0) {
0286 if (err >= MAXBITS) {
0287 pr_info("Implausible number of bit errors corrected\n");
0288 err = -EIO;
0289 break;
0290 }
0291 bitstats[err]++;
0292 if (err > max_corrected) {
0293 max_corrected = err;
0294 pr_info("Read reported %d corrected bit errors\n",
0295 err);
0296 }
0297 } else {
0298 pr_info("Read reported error %d\n", err);
0299 err = 0;
0300 break;
0301 }
0302
0303 err = verify_page(0);
0304 if (err) {
0305 bitstats[max_corrected] = opno;
0306 pr_info("ECC failure, read data is incorrect despite read success\n");
0307 break;
0308 }
0309
0310 err = mtdtest_relax();
0311 if (err)
0312 break;
0313
0314 opno++;
0315 }
0316
0317
0318
0319 pr_info("Bit error histogram (%d operations total):\n", opno);
0320 for (i = 0; i < max_corrected; i++)
0321 pr_info("Page reads with %3d corrected bit errors: %d\n",
0322 i, bitstats[i]);
0323
0324 exit:
0325 return err;
0326 }
0327
0328 static int __init mtd_nandbiterrs_init(void)
0329 {
0330 int err = 0;
0331
0332 printk("\n");
0333 printk(KERN_INFO "==================================================\n");
0334 pr_info("MTD device: %d\n", dev);
0335
0336 mtd = get_mtd_device(NULL, dev);
0337 if (IS_ERR(mtd)) {
0338 err = PTR_ERR(mtd);
0339 pr_err("error: cannot get MTD device\n");
0340 goto exit_mtddev;
0341 }
0342
0343 if (!mtd_type_is_nand(mtd)) {
0344 pr_info("this test requires NAND flash\n");
0345 err = -ENODEV;
0346 goto exit_nand;
0347 }
0348
0349 pr_info("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n",
0350 (unsigned long long)mtd->size, mtd->erasesize,
0351 mtd->writesize, mtd->oobsize);
0352
0353 subsize = mtd->writesize >> mtd->subpage_sft;
0354 subcount = mtd->writesize / subsize;
0355
0356 pr_info("Device uses %d subpages of %d bytes\n", subcount, subsize);
0357
0358 offset = (loff_t)page_offset * mtd->writesize;
0359 eraseblock = mtd_div_by_eb(offset, mtd);
0360
0361 pr_info("Using page=%u, offset=%llu, eraseblock=%u\n",
0362 page_offset, offset, eraseblock);
0363
0364 wbuffer = kmalloc(mtd->writesize, GFP_KERNEL);
0365 if (!wbuffer) {
0366 err = -ENOMEM;
0367 goto exit_wbuffer;
0368 }
0369
0370 rbuffer = kmalloc(mtd->writesize, GFP_KERNEL);
0371 if (!rbuffer) {
0372 err = -ENOMEM;
0373 goto exit_rbuffer;
0374 }
0375
0376 err = mtdtest_erase_eraseblock(mtd, eraseblock);
0377 if (err)
0378 goto exit_error;
0379
0380 if (mode == 0)
0381 err = incremental_errors_test();
0382 else
0383 err = overwrite_test();
0384
0385 if (err)
0386 goto exit_error;
0387
0388
0389 err = mtdtest_erase_eraseblock(mtd, eraseblock);
0390 if (err)
0391 goto exit_error;
0392
0393 err = -EIO;
0394 pr_info("finished successfully.\n");
0395 printk(KERN_INFO "==================================================\n");
0396
0397 exit_error:
0398 kfree(rbuffer);
0399 exit_rbuffer:
0400 kfree(wbuffer);
0401 exit_wbuffer:
0402
0403 exit_nand:
0404 put_mtd_device(mtd);
0405 exit_mtddev:
0406 return err;
0407 }
0408
0409 static void __exit mtd_nandbiterrs_exit(void)
0410 {
0411 return;
0412 }
0413
0414 module_init(mtd_nandbiterrs_init);
0415 module_exit(mtd_nandbiterrs_exit);
0416
0417 MODULE_DESCRIPTION("NAND bit error recovery test");
0418 MODULE_AUTHOR("Iwo Mergler");
0419 MODULE_LICENSE("GPL");