|
@@ -1353,6 +1353,7 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
|
|
|
int bitflip_count;
|
|
int bitflip_count;
|
|
|
bool is_error_reported = false;
|
|
bool is_error_reported = false;
|
|
|
u32 bit_pos, byte_pos, error_max, pos;
|
|
u32 bit_pos, byte_pos, error_max, pos;
|
|
|
|
|
+ int err;
|
|
|
|
|
|
|
|
switch (info->ecc_opt) {
|
|
switch (info->ecc_opt) {
|
|
|
case OMAP_ECC_BCH4_CODE_HW:
|
|
case OMAP_ECC_BCH4_CODE_HW:
|
|
@@ -1434,8 +1435,12 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
|
|
|
/* Decode BCH error using ELM module */
|
|
/* Decode BCH error using ELM module */
|
|
|
elm_decode_bch_error_page(info->elm_dev, ecc_vec, err_vec);
|
|
elm_decode_bch_error_page(info->elm_dev, ecc_vec, err_vec);
|
|
|
|
|
|
|
|
|
|
+ err = 0;
|
|
|
for (i = 0; i < eccsteps; i++) {
|
|
for (i = 0; i < eccsteps; i++) {
|
|
|
- if (err_vec[i].error_reported) {
|
|
|
|
|
|
|
+ if (err_vec[i].error_uncorrectable) {
|
|
|
|
|
+ pr_err("nand: uncorrectable bit-flips found\n");
|
|
|
|
|
+ err = -EBADMSG;
|
|
|
|
|
+ } else if (err_vec[i].error_reported) {
|
|
|
for (j = 0; j < err_vec[i].error_count; j++) {
|
|
for (j = 0; j < err_vec[i].error_count; j++) {
|
|
|
switch (info->ecc_opt) {
|
|
switch (info->ecc_opt) {
|
|
|
case OMAP_ECC_BCH4_CODE_HW:
|
|
case OMAP_ECC_BCH4_CODE_HW:
|
|
@@ -1457,13 +1462,22 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
|
|
|
byte_pos = (error_max - pos - 1) / 8;
|
|
byte_pos = (error_max - pos - 1) / 8;
|
|
|
|
|
|
|
|
if (pos < error_max) {
|
|
if (pos < error_max) {
|
|
|
- if (byte_pos < 512)
|
|
|
|
|
|
|
+ if (byte_pos < 512) {
|
|
|
|
|
+ pr_debug("bitflip@dat[%d]=%x\n",
|
|
|
|
|
+ byte_pos, data[byte_pos]);
|
|
|
data[byte_pos] ^= 1 << bit_pos;
|
|
data[byte_pos] ^= 1 << bit_pos;
|
|
|
- else
|
|
|
|
|
|
|
+ } else {
|
|
|
|
|
+ pr_debug("bitflip@oob[%d]=%x\n",
|
|
|
|
|
+ (byte_pos - 512),
|
|
|
|
|
+ spare_ecc[byte_pos - 512]);
|
|
|
spare_ecc[byte_pos - 512] ^=
|
|
spare_ecc[byte_pos - 512] ^=
|
|
|
1 << bit_pos;
|
|
1 << bit_pos;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ pr_err("invalid bit-flip @ %d:%d\n",
|
|
|
|
|
+ byte_pos, bit_pos);
|
|
|
|
|
+ err = -EBADMSG;
|
|
|
}
|
|
}
|
|
|
- /* else, not interested to correct ecc */
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1475,12 +1489,7 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
|
|
|
spare_ecc += ecc->bytes;
|
|
spare_ecc += ecc->bytes;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- for (i = 0; i < eccsteps; i++)
|
|
|
|
|
- /* Return error if uncorrectable error present */
|
|
|
|
|
- if (err_vec[i].error_uncorrectable)
|
|
|
|
|
- return -EINVAL;
|
|
|
|
|
-
|
|
|
|
|
- return stat;
|
|
|
|
|
|
|
+ return (err) ? err : stat;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|