Beispiel #1
0
static int tmio_nand_correct_data(struct mtd_info *mtd, unsigned char *buf,
		unsigned char *read_ecc, unsigned char *calc_ecc)
{
	int r0, r1;

	/* assume ecc.size = 512 and ecc.bytes = 6 */
	r0 = __nand_correct_data(buf, read_ecc, calc_ecc, 256);
	if (r0 < 0)
		return r0;
	r1 = __nand_correct_data(buf + 256, read_ecc + 3, calc_ecc + 3, 256);
	if (r1 < 0)
		return r1;
	return r0 + r1;
}
static int nand_ecc_test(const size_t size)
{
	unsigned char code[3];
	unsigned char error_code[3];
	char testname[30];

	BUG_ON(sizeof(data) < size);

	sprintf(testname, "nand-ecc-%zu", size);

	get_random_bytes(data, size);

	memcpy(error_data, data, size);
	inject_single_bit_error(error_data, size);

	__nand_calculate_ecc(data, size, code);
	__nand_calculate_ecc(error_data, size, error_code);
	__nand_correct_data(error_data, code, error_code, size);

	if (!memcmp(data, error_data, size)) {
		printk(KERN_INFO "mtd_nandecctest: ok - %s\n", testname);
		return 0;
	}

	printk(KERN_ERR "mtd_nandecctest: not ok - %s\n", testname);

	printk(KERN_DEBUG "hexdump of data:\n");
	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4,
			data, size, false);
	printk(KERN_DEBUG "hexdump of error data:\n");
	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4,
			error_data, size, false);

	return -1;
}
Beispiel #3
0
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 == -EBADMSG) ? 0 : -EINVAL;
}
Beispiel #4
0
static int single_bit_error_correct(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);
	if (ret == 1 && !memcmp(correct_data, error_data, size))
		return 0;

	return -EINVAL;
}
Beispiel #5
0
static int txx9ndfmc_correct_data(struct mtd_info *mtd, unsigned char *buf,
		unsigned char *read_ecc, unsigned char *calc_ecc)
{
	struct nand_chip *chip = mtd_to_nand(mtd);
	int eccsize;
	int corrected = 0;
	int stat;

	for (eccsize = chip->ecc.size; eccsize > 0; eccsize -= 256) {
		stat = __nand_correct_data(buf, read_ecc, calc_ecc, 256);
		if (stat < 0)
			return stat;
		corrected += stat;
		buf += 256;
		read_ecc += 3;
		calc_ecc += 3;
	}
	return corrected;
}