|
@@ -325,28 +325,11 @@ static int onenand_wait(struct mtd_info *mtd, int state)
|
|
|
|
|
|
ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
|
|
|
|
|
|
- if (ctrl & ONENAND_CTRL_ERROR) {
|
|
|
- printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", ctrl);
|
|
|
- if (ctrl & ONENAND_CTRL_LOCK)
|
|
|
- printk(KERN_ERR "onenand_wait: it's locked error.\n");
|
|
|
- if (state == FL_READING) {
|
|
|
- /*
|
|
|
- * A power loss while writing can result in a page
|
|
|
- * becoming unreadable. When the device is mounted
|
|
|
- * again, reading that page gives controller errors.
|
|
|
- * Upper level software like JFFS2 treat -EIO as fatal,
|
|
|
- * refusing to mount at all. That means it is necessary
|
|
|
- * to treat the error as an ECC error to allow recovery.
|
|
|
- * Note that typically in this case, the eraseblock can
|
|
|
- * still be erased and rewritten i.e. it has not become
|
|
|
- * a bad block.
|
|
|
- */
|
|
|
- mtd->ecc_stats.failed++;
|
|
|
- return -EBADMSG;
|
|
|
- }
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
-
|
|
|
+ /*
|
|
|
+ * In the Spec. it checks the controller status first
|
|
|
+ * However if you get the correct information in case of
|
|
|
+ * power off recovery (POR) test, it should read ECC status first
|
|
|
+ */
|
|
|
if (interrupt & ONENAND_INT_READ) {
|
|
|
int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
|
|
|
if (ecc) {
|
|
@@ -364,6 +347,15 @@ static int onenand_wait(struct mtd_info *mtd, int state)
|
|
|
return -EIO;
|
|
|
}
|
|
|
|
|
|
+ /* If there's controller error, it's a real error */
|
|
|
+ if (ctrl & ONENAND_CTRL_ERROR) {
|
|
|
+ printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n",
|
|
|
+ ctrl);
|
|
|
+ if (ctrl & ONENAND_CTRL_LOCK)
|
|
|
+ printk(KERN_ERR "onenand_wait: it's locked error.\n");
|
|
|
+ return -EIO;
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1135,22 +1127,26 @@ static int onenand_bbt_wait(struct mtd_info *mtd, int state)
|
|
|
interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
|
|
|
ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
|
|
|
|
|
|
- /* Initial bad block case: 0x2400 or 0x0400 */
|
|
|
- if (ctrl & ONENAND_CTRL_ERROR) {
|
|
|
- printk(KERN_DEBUG "onenand_bbt_wait: controller error = 0x%04x\n", ctrl);
|
|
|
- return ONENAND_BBT_READ_ERROR;
|
|
|
- }
|
|
|
-
|
|
|
if (interrupt & ONENAND_INT_READ) {
|
|
|
int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
|
|
|
- if (ecc & ONENAND_ECC_2BIT_ALL)
|
|
|
+ if (ecc & ONENAND_ECC_2BIT_ALL) {
|
|
|
+ printk(KERN_INFO "onenand_bbt_wait: ecc error = 0x%04x"
|
|
|
+ ", controller error 0x%04x\n", ecc, ctrl);
|
|
|
return ONENAND_BBT_READ_ERROR;
|
|
|
+ }
|
|
|
} else {
|
|
|
printk(KERN_ERR "onenand_bbt_wait: read timeout!"
|
|
|
"ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt);
|
|
|
return ONENAND_BBT_READ_FATAL_ERROR;
|
|
|
}
|
|
|
|
|
|
+ /* Initial bad block case: 0x2400 or 0x0400 */
|
|
|
+ if (ctrl & ONENAND_CTRL_ERROR) {
|
|
|
+ printk(KERN_DEBUG "onenand_bbt_wait: "
|
|
|
+ "controller error = 0x%04x\n", ctrl);
|
|
|
+ return ONENAND_BBT_READ_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|