diff options
-rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 54 |
1 files changed, 25 insertions, 29 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 5d7965f7e9ce..926cf3a4135d 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
@@ -325,28 +325,11 @@ static int onenand_wait(struct mtd_info *mtd, int state) | |||
325 | 325 | ||
326 | ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); | 326 | ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); |
327 | 327 | ||
328 | if (ctrl & ONENAND_CTRL_ERROR) { | 328 | /* |
329 | printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", ctrl); | 329 | * In the Spec. it checks the controller status first |
330 | if (ctrl & ONENAND_CTRL_LOCK) | 330 | * However if you get the correct information in case of |
331 | printk(KERN_ERR "onenand_wait: it's locked error.\n"); | 331 | * power off recovery (POR) test, it should read ECC status first |
332 | if (state == FL_READING) { | 332 | */ |
333 | /* | ||
334 | * A power loss while writing can result in a page | ||
335 | * becoming unreadable. When the device is mounted | ||
336 | * again, reading that page gives controller errors. | ||
337 | * Upper level software like JFFS2 treat -EIO as fatal, | ||
338 | * refusing to mount at all. That means it is necessary | ||
339 | * to treat the error as an ECC error to allow recovery. | ||
340 | * Note that typically in this case, the eraseblock can | ||
341 | * still be erased and rewritten i.e. it has not become | ||
342 | * a bad block. | ||
343 | */ | ||
344 | mtd->ecc_stats.failed++; | ||
345 | return -EBADMSG; | ||
346 | } | ||
347 | return -EIO; | ||
348 | } | ||
349 | |||
350 | if (interrupt & ONENAND_INT_READ) { | 333 | if (interrupt & ONENAND_INT_READ) { |
351 | int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); | 334 | int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); |
352 | if (ecc) { | 335 | if (ecc) { |
@@ -364,6 +347,15 @@ static int onenand_wait(struct mtd_info *mtd, int state) | |||
364 | return -EIO; | 347 | return -EIO; |
365 | } | 348 | } |
366 | 349 | ||
350 | /* If there's controller error, it's a real error */ | ||
351 | if (ctrl & ONENAND_CTRL_ERROR) { | ||
352 | printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", | ||
353 | ctrl); | ||
354 | if (ctrl & ONENAND_CTRL_LOCK) | ||
355 | printk(KERN_ERR "onenand_wait: it's locked error.\n"); | ||
356 | return -EIO; | ||
357 | } | ||
358 | |||
367 | return 0; | 359 | return 0; |
368 | } | 360 | } |
369 | 361 | ||
@@ -1135,22 +1127,26 @@ static int onenand_bbt_wait(struct mtd_info *mtd, int state) | |||
1135 | interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); | 1127 | interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); |
1136 | ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); | 1128 | ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); |
1137 | 1129 | ||
1138 | /* Initial bad block case: 0x2400 or 0x0400 */ | ||
1139 | if (ctrl & ONENAND_CTRL_ERROR) { | ||
1140 | printk(KERN_DEBUG "onenand_bbt_wait: controller error = 0x%04x\n", ctrl); | ||
1141 | return ONENAND_BBT_READ_ERROR; | ||
1142 | } | ||
1143 | |||
1144 | if (interrupt & ONENAND_INT_READ) { | 1130 | if (interrupt & ONENAND_INT_READ) { |
1145 | int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); | 1131 | int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); |
1146 | if (ecc & ONENAND_ECC_2BIT_ALL) | 1132 | if (ecc & ONENAND_ECC_2BIT_ALL) { |
1133 | printk(KERN_INFO "onenand_bbt_wait: ecc error = 0x%04x" | ||
1134 | ", controller error 0x%04x\n", ecc, ctrl); | ||
1147 | return ONENAND_BBT_READ_ERROR; | 1135 | return ONENAND_BBT_READ_ERROR; |
1136 | } | ||
1148 | } else { | 1137 | } else { |
1149 | printk(KERN_ERR "onenand_bbt_wait: read timeout!" | 1138 | printk(KERN_ERR "onenand_bbt_wait: read timeout!" |
1150 | "ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt); | 1139 | "ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt); |
1151 | return ONENAND_BBT_READ_FATAL_ERROR; | 1140 | return ONENAND_BBT_READ_FATAL_ERROR; |
1152 | } | 1141 | } |
1153 | 1142 | ||
1143 | /* Initial bad block case: 0x2400 or 0x0400 */ | ||
1144 | if (ctrl & ONENAND_CTRL_ERROR) { | ||
1145 | printk(KERN_DEBUG "onenand_bbt_wait: " | ||
1146 | "controller error = 0x%04x\n", ctrl); | ||
1147 | return ONENAND_BBT_READ_ERROR; | ||
1148 | } | ||
1149 | |||
1154 | return 0; | 1150 | return 0; |
1155 | } | 1151 | } |
1156 | 1152 | ||