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 12static 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 19static unsigned char data[512]; 20static unsigned char error_data[512]; 21 22static 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 60static int nand_ecc_test(const size_t size) 61{ 62 return 0; 63} 64 65#endif 66 67static 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 77static void __exit ecc_test_exit(void) 78{ 79} 80 81module_init(ecc_test_init); 82module_exit(ecc_test_exit); 83 84MODULE_DESCRIPTION("NAND ECC function test module"); 85MODULE_AUTHOR("Akinobu Mita"); 86MODULE_LICENSE("GPL"); 87