Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e941192 authored by Boris Brezillon's avatar Boris Brezillon Committed by Brian Norris
Browse files

mtd: nand: return consistent error codes in ecc.correct() implementations



The error code returned by the ecc.correct() are not consistent over the
all implementations.

Document the expected behavior in include/linux/mtd/nand.h and fix
offending implementations.

[Brian: this looks like a bugfix for the ECC reporting in the bf5xx_nand
driver, but we haven't seen any testing results for it]

Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
Tested-by: default avatarFranklin S Cooper Jr. <fcooper@ti.com>
Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
parent 6f357de8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1445,7 +1445,7 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat,
		 * We can't correct so many errors */
		dev_dbg(host->dev, "atmel_nand : multiple errors detected."
				" Unable to correct.\n");
		return -EIO;
		return -EBADMSG;
	}

	/* if there's a single bit error : we can correct it */
+14 −6
Original line number Diff line number Diff line
@@ -252,7 +252,7 @@ static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat,
	 */
	if (hweight32(syndrome[0]) == 1) {
		dev_err(info->device, "ECC data was incorrect!\n");
		return 1;
		return -EBADMSG;
	}

	syndrome[1] = (calced & 0x7FF) ^ (stored & 0x7FF);
@@ -285,7 +285,7 @@ static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat,
		data = data ^ (0x1 << failing_bit);
		*(dat + failing_byte) = data;

		return 0;
		return 1;
	}

	/*
@@ -298,26 +298,34 @@ static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat,
	dev_err(info->device,
		"Please discard data, mark bad block\n");

	return 1;
	return -EBADMSG;
}

static int bf5xx_nand_correct_data(struct mtd_info *mtd, u_char *dat,
					u_char *read_ecc, u_char *calc_ecc)
{
	struct nand_chip *chip = mtd_to_nand(mtd);
	int ret;
	int ret, bitflips = 0;

	ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc);
	if (ret < 0)
		return ret;

	bitflips = ret;

	/* If ecc size is 512, correct second 256 bytes */
	if (chip->ecc.size == 512) {
		dat += 256;
		read_ecc += 3;
		calc_ecc += 3;
		ret |= bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc);
		ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc);
		if (ret < 0)
			return ret;

		bitflips += ret;
	}

	return ret;
	return bitflips;
}

static void bf5xx_nand_enable_hwecc(struct mtd_info *mtd, int mode)
+3 −3
Original line number Diff line number Diff line
@@ -207,7 +207,7 @@ static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat,
				dat[diff >> (12 + 3)] ^= BIT((diff >> 12) & 7);
				return 1;
			} else {
				return -1;
				return -EBADMSG;
			}
		} else if (!(diff & (diff - 1))) {
			/* Single bit ECC error in the ECC itself,
@@ -215,7 +215,7 @@ static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat,
			return 1;
		} else {
			/* Uncorrectable error */
			return -1;
			return -EBADMSG;
		}

	}
@@ -391,7 +391,7 @@ static int nand_davinci_correct_4bit(struct mtd_info *mtd,
			return 0;
		case 1:		/* five or more errors detected */
			davinci_nand_readl(info, NAND_ERR_ERRVAL1_OFFSET);
			return -EIO;
			return -EBADMSG;
		case 2:		/* error addresses computed */
		case 3:
			num_errors = 1 + ((fsr >> 16) & 0x03);
+2 −2
Original line number Diff line number Diff line
@@ -254,7 +254,7 @@ static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat,
	} while (!(status & JZ_NAND_STATUS_DEC_FINISH) && --timeout);

	if (timeout == 0)
	    return -1;
		return -ETIMEDOUT;

	reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL);
	reg &= ~JZ_NAND_ECC_CTRL_ENABLE;
@@ -262,7 +262,7 @@ static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat,

	if (status & JZ_NAND_STATUS_ERROR) {
		if (status & JZ_NAND_STATUS_UNCOR_ERROR)
			return -1;
			return -EBADMSG;

		error_count = (status & JZ_NAND_STATUS_ERR_COUNT) >> 29;

+2 −2
Original line number Diff line number Diff line
@@ -674,7 +674,7 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,

	if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
		pr_debug("MXC_NAND: HWECC uncorrectable 2-bit ECC error\n");
		return -1;
		return -EBADMSG;
	}

	return 0;
@@ -701,7 +701,7 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
		err = ecc_stat & ecc_bit_mask;
		if (err > err_limit) {
			printk(KERN_WARNING "UnCorrectable RS-ECC Error\n");
			return -1;
			return -EBADMSG;
		} else {
			ret += err;
		}
Loading