diff options
| -rw-r--r-- | drivers/mtd/tests/mtd_nandecctest.c | 79 | 
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/mtd/tests/mtd_nandecctest.c b/drivers/mtd/tests/mtd_nandecctest.c index caaeb64acde..b437fa42507 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,  	__change_bit_le(offset, error_data);  } +static void double_bit_error_data(void *error_data, void *correct_data, +				size_t size) +{ +	unsigned int offset[2]; + +	offset[0] = random32() % (size * BITS_PER_BYTE); +	do { +		offset[1] = random32() % (size * BITS_PER_BYTE); +	} while (offset[0] == offset[1]); + +	memcpy(error_data, correct_data, size); + +	__change_bit_le(offset[0], error_data); +	__change_bit_le(offset[1], error_data); +} +  static unsigned int random_ecc_bit(size_t size)  {  	unsigned int offset = random32() % (3 * BITS_PER_BYTE); @@ -73,6 +89,21 @@ static void single_bit_error_ecc(void *error_ecc, void *correct_ecc,  	__change_bit_le(offset, error_ecc);  } +static void double_bit_error_ecc(void *error_ecc, void *correct_ecc, +				size_t size) +{ +	unsigned int offset[2]; + +	offset[0] = random_ecc_bit(size); +	do { +		offset[1] = random_ecc_bit(size); +	} while (offset[0] == offset[1]); + +	memcpy(error_ecc, correct_ecc, 3); +	__change_bit_le(offset[0], error_ecc); +	__change_bit_le(offset[1], error_ecc); +} +  static void no_bit_error(void *error_data, void *error_ecc,  		void *correct_data, void *correct_ecc, const size_t size)  { @@ -122,6 +153,39 @@ static int single_bit_error_correct(void *error_data, void *error_ecc,  	return -EINVAL;  } +static void double_bit_error_in_data(void *error_data, void *error_ecc, +		void *correct_data, void *correct_ecc, const size_t size) +{ +	double_bit_error_data(error_data, correct_data, size); +	memcpy(error_ecc, correct_ecc, 3); +} + +static void single_bit_error_in_data_and_ecc(void *error_data, void *error_ecc, +		void *correct_data, void *correct_ecc, const size_t size) +{ +	single_bit_error_data(error_data, correct_data, size); +	single_bit_error_ecc(error_ecc, correct_ecc, size); +} + +static void double_bit_error_in_ecc(void *error_data, void *error_ecc, +		void *correct_data, void *correct_ecc, const size_t size) +{ +	memcpy(error_data, correct_data, size); +	double_bit_error_ecc(error_ecc, correct_ecc, size); +} + +static int double_bit_error_detect(void *error_data, void *error_ecc, +				void *correct_data, const size_t size) +{ +	unsigned char calc_ecc[3]; +	int ret; + +	__nand_calculate_ecc(error_data, size, calc_ecc); +	ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size); + +	return (ret == -1) ? 0 : -EINVAL; +} +  static const struct nand_ecc_test nand_ecc_test[] = {  	{  		.name = "no-bit-error", @@ -138,6 +202,21 @@ static const struct nand_ecc_test nand_ecc_test[] = {  		.prepare = single_bit_error_in_ecc,  		.verify = single_bit_error_correct,  	}, +	{ +		.name = "double-bit-error-in-data-detect", +		.prepare = double_bit_error_in_data, +		.verify = double_bit_error_detect, +	}, +	{ +		.name = "single-bit-error-in-data-and-ecc-detect", +		.prepare = single_bit_error_in_data_and_ecc, +		.verify = double_bit_error_detect, +	}, +	{ +		.name = "double-bit-error-in-ecc-detect", +		.prepare = double_bit_error_in_ecc, +		.verify = double_bit_error_detect, +	},  };  static void dump_data_ecc(void *error_data, void *error_ecc, void *correct_data,  |