1 #include <linux/kernel.h> 2 #include <linux/module.h> 3 #include <linux/list.h> 4 #include <linux/random.h> 5 #include <linux/string.h> 6 #include <linux/bitops.h> 7 #include <linux/jiffies.h> 8 #include <linux/mtd/nand_ecc.h> 9 10 #if defined(CONFIG_MTD_NAND) || defined(CONFIG_MTD_NAND_MODULE) 11 12 static void inject_single_bit_error(void *data, size_t size) 13 { 14 unsigned long offset = random32() % (size * BITS_PER_BYTE); 15 16 __change_bit(offset, data); 17 } 18 19 static unsigned char data[512]; 20 static unsigned char error_data[512]; 21 22 static int nand_ecc_test(const size_t size) 23 { 24 unsigned char code[3]; 25 unsigned char error_code[3]; 26 char testname[30]; 27 28 BUG_ON(sizeof(data) < size); 29 30 sprintf(testname, "nand-ecc-%zu", size); 31 32 get_random_bytes(data, size); 33 34 memcpy(error_data, data, size); 35 inject_single_bit_error(error_data, size); 36 37 __nand_calculate_ecc(data, size, code); 38 __nand_calculate_ecc(error_data, size, error_code); 39 __nand_correct_data(error_data, code, error_code, size); 40 41 if (!memcmp(data, error_data, size)) { 42 printk(KERN_INFO "mtd_nandecctest: ok - %s\n", testname); 43 return 0; 44 } 45 46 printk(KERN_ERR "mtd_nandecctest: not ok - %s\n", testname); 47 48 printk(KERN_DEBUG "hexdump of data:\n"); 49 print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4, 50 data, size, false); 51 printk(KERN_DEBUG "hexdump of error data:\n"); 52 print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4, 53 error_data, size, false); 54 55 return -1; 56 } 57 58 #else 59 60 static int nand_ecc_test(const size_t size) 61 { 62 return 0; 63 } 64 65 #endif 66 67 static int __init ecc_test_init(void) 68 { 69 srandom32(jiffies); 70 71 nand_ecc_test(256); 72 nand_ecc_test(512); 73 74 return 0; 75 } 76 77 static void __exit ecc_test_exit(void) 78 { 79 } 80 81 module_init(ecc_test_init); 82 module_exit(ecc_test_exit); 83 84 MODULE_DESCRIPTION("NAND ECC function test module"); 85 MODULE_AUTHOR("Akinobu Mita"); 86 MODULE_LICENSE("GPL"); 87