Commit 5f4d47d5d1060a93be83e33a167a53a7f8c08b20

Authored by Adrian Hunter
Committed by David Woodhouse
1 parent b1c9c9be6d

[MTD] [OneNAND] Do not stop reading for ECC errors

When an ECC error occurs, the read should be completed
anyway before returning -EBADMSG.  Returning -EBADMSG
straight away is incorrect.

Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>

Showing 1 changed file with 22 additions and 10 deletions Side-by-side Diff

drivers/mtd/onenand/onenand_base.c
... ... @@ -855,6 +855,8 @@
855 855 this->command(mtd, ONENAND_CMD_READ, from, writesize);
856 856 ret = this->wait(mtd, FL_READING);
857 857 onenand_update_bufferram(mtd, from, !ret);
  858 + if (ret == -EBADMSG)
  859 + ret = 0;
858 860 }
859 861 }
860 862  
... ... @@ -913,6 +915,8 @@
913 915 /* Now wait for load */
914 916 ret = this->wait(mtd, FL_READING);
915 917 onenand_update_bufferram(mtd, from, !ret);
  918 + if (ret == -EBADMSG)
  919 + ret = 0;
916 920 }
917 921  
918 922 /*
919 923  
... ... @@ -923,12 +927,12 @@
923 927 ops->retlen = read;
924 928 ops->oobretlen = oobread;
925 929  
926   - if (mtd->ecc_stats.failed - stats.failed)
927   - return -EBADMSG;
928   -
929 930 if (ret)
930 931 return ret;
931 932  
  933 + if (mtd->ecc_stats.failed - stats.failed)
  934 + return -EBADMSG;
  935 +
932 936 return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
933 937 }
934 938  
... ... @@ -944,6 +948,7 @@
944 948 struct mtd_oob_ops *ops)
945 949 {
946 950 struct onenand_chip *this = mtd->priv;
  951 + struct mtd_ecc_stats stats;
947 952 int read = 0, thislen, column, oobsize;
948 953 size_t len = ops->ooblen;
949 954 mtd_oob_mode_t mode = ops->mode;
... ... @@ -977,6 +982,8 @@
977 982 return -EINVAL;
978 983 }
979 984  
  985 + stats = mtd->ecc_stats;
  986 +
980 987 while (read < len) {
981 988 cond_resched();
982 989  
983 990  
... ... @@ -988,18 +995,16 @@
988 995 onenand_update_bufferram(mtd, from, 0);
989 996  
990 997 ret = this->wait(mtd, FL_READING);
991   - /* First copy data and check return value for ECC handling */
  998 + if (ret && ret != -EBADMSG) {
  999 + printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret);
  1000 + break;
  1001 + }
992 1002  
993 1003 if (mode == MTD_OOB_AUTO)
994 1004 onenand_transfer_auto_oob(mtd, buf, column, thislen);
995 1005 else
996 1006 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
997 1007  
998   - if (ret) {
999   - printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret);
1000   - break;
1001   - }
1002   -
1003 1008 read += thislen;
1004 1009  
1005 1010 if (read == len)
... ... @@ -1016,7 +1021,14 @@
1016 1021 }
1017 1022  
1018 1023 ops->oobretlen = read;
1019   - return ret;
  1024 +
  1025 + if (ret)
  1026 + return ret;
  1027 +
  1028 + if (mtd->ecc_stats.failed - stats.failed)
  1029 + return -EBADMSG;
  1030 +
  1031 + return 0;
1020 1032 }
1021 1033  
1022 1034 /**