Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright © 2012 NetCommWireless
0004  * Iwo Mergler <Iwo.Mergler@netcommwireless.com.au>
0005  *
0006  * Test for multi-bit error recovery on a NAND page This mostly tests the
0007  * ECC controller / driver.
0008  *
0009  * There are two test modes:
0010  *
0011  *  0 - artificially inserting bit errors until the ECC fails
0012  *      This is the default method and fairly quick. It should
0013  *      be independent of the quality of the FLASH.
0014  *
0015  *  1 - re-writing the same pattern repeatedly until the ECC fails.
0016  *      This method relies on the physics of NAND FLASH to eventually
0017  *      generate '0' bits if '1' has been written sufficient times.
0018  *      Depending on the NAND, the first bit errors will appear after
0019  *      1000 or more writes and then will usually snowball, reaching the
0020  *      limits of the ECC quickly.
0021  *
0022  *      The test stops after 10000 cycles, should your FLASH be
0023  *      exceptionally good and not generate bit errors before that. Try
0024  *      a different page in that case.
0025  *
0026  * Please note that neither of these tests will significantly 'use up' any
0027  * FLASH endurance. Only a maximum of two erase operations will be performed.
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;     /* Offset of the page we're using. */
0060 static unsigned eraseblock; /* Eraseblock number for our page. */
0061 
0062 /* We assume that the ECC can correct up to a certain number
0063  * of biterrors per subpage. */
0064 static unsigned subsize;  /* Size of subpages */
0065 static unsigned subcount; /* Number of subpages per page */
0066 
0067 static struct mtd_info *mtd;   /* MTD device */
0068 
0069 static uint8_t *wbuffer; /* One page write / compare buffer */
0070 static uint8_t *rbuffer; /* One page read buffer */
0071 
0072 /* 'random' bytes from known offsets */
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     /* Reverse bits of result. */
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 /* Writes wbuffer to page */
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 /* Re-writes the data area while leaving the OOB alone. */
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; /* No ECC */
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 /* Reads page into rbuffer. Returns number of corrected bit errors (>=0)
0127  * or error (<0) */
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     /* Saving last mtd stats */
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 /* Verifies rbuffer against random sequence */
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 /* Finds the first '1' bit in wbuffer starting at offset 'byte'
0179  * and sets it to '0'. */
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 /* Writes 'random' data to page and then introduces deliberate bit
0199  * errors into the page, while verifying each step. */
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 /* Writes 'random' data to page and then re-writes that same data repeatedly.
0254    This eventually develops bit errors (bits written as '1' will slowly become
0255    '0'), which are corrected as far as the ECC is capable of. */
0256 static int overwrite_test(void)
0257 {
0258     int err = 0;
0259     unsigned i;
0260     unsigned max_corrected = 0;
0261     unsigned opno = 0;
0262     /* We don't expect more than this many correctable bit errors per
0263      * page. */
0264     #define MAXBITS 512
0265     static unsigned bitstats[MAXBITS]; /* bit error histogram. */
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 { /* err < 0 */
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     /* At this point bitstats[0] contains the number of ops with no bit
0318      * errors, bitstats[1] the number of ops with 1 bit error, etc. */
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     /* We leave the block un-erased in case of test failure. */
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     /* Nothing */
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");