aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/tests
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2012-09-07 12:48:10 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-09-29 10:48:02 -0400
commit6ed089c0a1bc6f371dbcf97fb4e8218deaa0ae17 (patch)
tree25254895560a1c0a8997928b2dbd0f12bc6eb9ae /drivers/mtd/tests
parent200ab8454c42c607efd281b2c2398624eccdd2cc (diff)
mtd: mtd_nandecctest: add double bit error detection tests
This adds the double bit error detection test cases listed below: * Prepare data block with double bit error and ECC data without corruption, and verify that the uncorrectable error is detected by __nand_correct_data(). * Prepare data block with single bit error and ECC data with single bit error, and verify that the uncorrectable error is detected. * Prepare data block without corruption and ECC data with double bit error, and verify that the uncorrectable error is detected. Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/tests')
-rw-r--r--drivers/mtd/tests/mtd_nandecctest.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/mtd/tests/mtd_nandecctest.c b/drivers/mtd/tests/mtd_nandecctest.c
index caaeb64acdea..b437fa425077 100644
--- a/drivers/mtd/tests/mtd_nandecctest.c
+++ b/drivers/mtd/tests/mtd_nandecctest.c
@@ -48,6 +48,22 @@ static void single_bit_error_data(void *error_data, void *correct_data,
48 __change_bit_le(offset, error_data); 48 __change_bit_le(offset, error_data);
49} 49}
50 50
51static void double_bit_error_data(void *error_data, void *correct_data,
52 size_t size)
53{
54 unsigned int offset[2];
55
56 offset[0] = random32() % (size * BITS_PER_BYTE);
57 do {
58 offset[1] = random32() % (size * BITS_PER_BYTE);
59 } while (offset[0] == offset[1]);
60
61 memcpy(error_data, correct_data, size);
62
63 __change_bit_le(offset[0], error_data);
64 __change_bit_le(offset[1], error_data);
65}
66
51static unsigned int random_ecc_bit(size_t size) 67static unsigned int random_ecc_bit(size_t size)
52{ 68{
53 unsigned int offset = random32() % (3 * BITS_PER_BYTE); 69 unsigned int offset = random32() % (3 * BITS_PER_BYTE);
@@ -73,6 +89,21 @@ static void single_bit_error_ecc(void *error_ecc, void *correct_ecc,
73 __change_bit_le(offset, error_ecc); 89 __change_bit_le(offset, error_ecc);
74} 90}
75 91
92static void double_bit_error_ecc(void *error_ecc, void *correct_ecc,
93 size_t size)
94{
95 unsigned int offset[2];
96
97 offset[0] = random_ecc_bit(size);
98 do {
99 offset[1] = random_ecc_bit(size);
100 } while (offset[0] == offset[1]);
101
102 memcpy(error_ecc, correct_ecc, 3);
103 __change_bit_le(offset[0], error_ecc);
104 __change_bit_le(offset[1], error_ecc);
105}
106
76static void no_bit_error(void *error_data, void *error_ecc, 107static void no_bit_error(void *error_data, void *error_ecc,
77 void *correct_data, void *correct_ecc, const size_t size) 108 void *correct_data, void *correct_ecc, const size_t size)
78{ 109{
@@ -122,6 +153,39 @@ static int single_bit_error_correct(void *error_data, void *error_ecc,
122 return -EINVAL; 153 return -EINVAL;
123} 154}
124 155
156static void double_bit_error_in_data(void *error_data, void *error_ecc,
157 void *correct_data, void *correct_ecc, const size_t size)
158{
159 double_bit_error_data(error_data, correct_data, size);
160 memcpy(error_ecc, correct_ecc, 3);
161}
162
163static void single_bit_error_in_data_and_ecc(void *error_data, void *error_ecc,
164 void *correct_data, void *correct_ecc, const size_t size)
165{
166 single_bit_error_data(error_data, correct_data, size);
167 single_bit_error_ecc(error_ecc, correct_ecc, size);
168}
169
170static void double_bit_error_in_ecc(void *error_data, void *error_ecc,
171 void *correct_data, void *correct_ecc, const size_t size)
172{
173 memcpy(error_data, correct_data, size);
174 double_bit_error_ecc(error_ecc, correct_ecc, size);
175}
176
177static int double_bit_error_detect(void *error_data, void *error_ecc,
178 void *correct_data, const size_t size)
179{
180 unsigned char calc_ecc[3];
181 int ret;
182
183 __nand_calculate_ecc(error_data, size, calc_ecc);
184 ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size);
185
186 return (ret == -1) ? 0 : -EINVAL;
187}
188
125static const struct nand_ecc_test nand_ecc_test[] = { 189static const struct nand_ecc_test nand_ecc_test[] = {
126 { 190 {
127 .name = "no-bit-error", 191 .name = "no-bit-error",
@@ -138,6 +202,21 @@ static const struct nand_ecc_test nand_ecc_test[] = {
138 .prepare = single_bit_error_in_ecc, 202 .prepare = single_bit_error_in_ecc,
139 .verify = single_bit_error_correct, 203 .verify = single_bit_error_correct,
140 }, 204 },
205 {
206 .name = "double-bit-error-in-data-detect",
207 .prepare = double_bit_error_in_data,
208 .verify = double_bit_error_detect,
209 },
210 {
211 .name = "single-bit-error-in-data-and-ecc-detect",
212 .prepare = single_bit_error_in_data_and_ecc,
213 .verify = double_bit_error_detect,
214 },
215 {
216 .name = "double-bit-error-in-ecc-detect",
217 .prepare = double_bit_error_in_ecc,
218 .verify = double_bit_error_detect,
219 },
141}; 220};
142 221
143static void dump_data_ecc(void *error_data, void *error_ecc, void *correct_data, 222static void dump_data_ecc(void *error_data, void *error_ecc, void *correct_data,