diff options
Diffstat (limited to 'drivers/mtd/onenand')
-rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 38 | ||||
-rw-r--r-- | drivers/mtd/onenand/onenand_bbt.c | 3 |
2 files changed, 17 insertions, 24 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 63ca61b83bf5..3fab4d1b68bd 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
@@ -318,15 +318,10 @@ static int onenand_wait(struct mtd_info *mtd, int state) | |||
318 | ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); | 318 | ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); |
319 | 319 | ||
320 | if (ctrl & ONENAND_CTRL_ERROR) { | 320 | if (ctrl & ONENAND_CTRL_ERROR) { |
321 | /* It maybe occur at initial bad block */ | ||
322 | DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl); | 321 | DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl); |
323 | /* Clear other interrupt bits for preventing ECC error */ | 322 | if (ctrl & ONENAND_CTRL_LOCK) |
324 | interrupt &= ONENAND_INT_MASTER; | 323 | DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error.\n"); |
325 | } | 324 | return ctrl; |
326 | |||
327 | if (ctrl & ONENAND_CTRL_LOCK) { | ||
328 | DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error = 0x%04x\n", ctrl); | ||
329 | return -EACCES; | ||
330 | } | 325 | } |
331 | 326 | ||
332 | if (interrupt & ONENAND_INT_READ) { | 327 | if (interrupt & ONENAND_INT_READ) { |
@@ -750,21 +745,21 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
750 | 745 | ||
751 | ret = this->wait(mtd, FL_READING); | 746 | ret = this->wait(mtd, FL_READING); |
752 | /* First copy data and check return value for ECC handling */ | 747 | /* First copy data and check return value for ECC handling */ |
753 | onenand_update_bufferram(mtd, from, 1); | 748 | onenand_update_bufferram(mtd, from, !ret); |
754 | } | 749 | } |
755 | 750 | ||
756 | this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen); | 751 | this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen); |
757 | 752 | ||
758 | read += thislen; | ||
759 | |||
760 | if (read == len) | ||
761 | break; | ||
762 | |||
763 | if (ret) { | 753 | if (ret) { |
764 | DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: read failed = %d\n", ret); | 754 | DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: read failed = %d\n", ret); |
765 | goto out; | 755 | goto out; |
766 | } | 756 | } |
767 | 757 | ||
758 | read += thislen; | ||
759 | |||
760 | if (read == len) | ||
761 | break; | ||
762 | |||
768 | from += thislen; | 763 | from += thislen; |
769 | buf += thislen; | 764 | buf += thislen; |
770 | } | 765 | } |
@@ -832,16 +827,16 @@ int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len, | |||
832 | 827 | ||
833 | this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen); | 828 | this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen); |
834 | 829 | ||
830 | if (ret) { | ||
831 | DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = 0x%x\n", ret); | ||
832 | goto out; | ||
833 | } | ||
834 | |||
835 | read += thislen; | 835 | read += thislen; |
836 | 836 | ||
837 | if (read == len) | 837 | if (read == len) |
838 | break; | 838 | break; |
839 | 839 | ||
840 | if (ret) { | ||
841 | DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = %d\n", ret); | ||
842 | goto out; | ||
843 | } | ||
844 | |||
845 | buf += thislen; | 840 | buf += thislen; |
846 | 841 | ||
847 | /* Read more? */ | 842 | /* Read more? */ |
@@ -1199,10 +1194,7 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
1199 | ret = this->wait(mtd, FL_ERASING); | 1194 | ret = this->wait(mtd, FL_ERASING); |
1200 | /* Check, if it is write protected */ | 1195 | /* Check, if it is write protected */ |
1201 | if (ret) { | 1196 | if (ret) { |
1202 | if (ret == -EPERM) | 1197 | DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift)); |
1203 | DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Device is write protected!!!\n"); | ||
1204 | else | ||
1205 | DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift)); | ||
1206 | instr->state = MTD_ERASE_FAILED; | 1198 | instr->state = MTD_ERASE_FAILED; |
1207 | instr->fail_addr = addr; | 1199 | instr->fail_addr = addr; |
1208 | goto erase_exit; | 1200 | goto erase_exit; |
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c index 6cceeca40567..98f8fd1c6375 100644 --- a/drivers/mtd/onenand/onenand_bbt.c +++ b/drivers/mtd/onenand/onenand_bbt.c | |||
@@ -93,7 +93,8 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr | |||
93 | ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs, | 93 | ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs, |
94 | readlen, &retlen, &buf[0]); | 94 | readlen, &retlen, &buf[0]); |
95 | 95 | ||
96 | if (ret) | 96 | /* If it is a initial bad block, just ignore it */ |
97 | if (ret && !(ret & ONENAND_CTRL_LOAD)) | ||
97 | return ret; | 98 | return ret; |
98 | 99 | ||
99 | if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) { | 100 | if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) { |