aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/nand_bbt.c
diff options
context:
space:
mode:
authorBrian Norris <computersforpeace@gmail.com>2011-09-20 21:35:57 -0400
committerArtem Bityutskiy <artem.bityutskiy@intel.com>2011-09-21 02:19:08 -0400
commitdadc17a3e34810ed411a62e6b4cafdf3e5e1d5c8 (patch)
treed8cc96a7f3109126c2c73cc5ce98102f901387d5 /drivers/mtd/nand/nand_bbt.c
parent623978de362a5faeb18d8395fa86089650642626 (diff)
mtd: nand: wait to set BBT version
Because there are so many cases of checking, writing, and re-writing of the bad block table(s), we might as well wait until the we've settled on a valid, clean copy of the table. This also prevents us from falsely incrementing the table version. For example, we may have the following: Primary table, with version 0x02 Mirror table, with version 0x01 Primary table has uncorrectable ECC errors If we don't have this fix applied, then we will: Choose to read the primary table (higher version) Set mirror table version to 0x02 Read back primary table Invalidate table because of ECC errors Retry readback operation with mirror table, now version 0x02 Mirrored table reads cleanly Writeback BBT to primary table location (with "version 0x02") However, the mirrored table shouldn't have a new version number. Instead, we actually want: Choose to read the primary table (higher version) Read back primary table Invalidate table because of ECC errors Retry readback with mirror table (version 0x01) Mirrored table reads cleanly Set both tables to version 0x01 Writeback BBT to primary table location (version 0x01) Signed-off-by: Brian Norris <computersforpeace@gmail.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@intel.com>
Diffstat (limited to 'drivers/mtd/nand/nand_bbt.c')
-rw-r--r--drivers/mtd/nand/nand_bbt.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 11185aa6273c..e7976c7a7bb0 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -909,11 +909,9 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
909 writeops = 0x03; 909 writeops = 0x03;
910 } else if (td->pages[i] == -1) { 910 } else if (td->pages[i] == -1) {
911 rd = md; 911 rd = md;
912 td->version[i] = md->version[i];
913 writeops = 0x01; 912 writeops = 0x01;
914 } else if (md->pages[i] == -1) { 913 } else if (md->pages[i] == -1) {
915 rd = td; 914 rd = td;
916 md->version[i] = td->version[i];
917 writeops = 0x02; 915 writeops = 0x02;
918 } else if (td->version[i] == md->version[i]) { 916 } else if (td->version[i] == md->version[i]) {
919 rd = td; 917 rd = td;
@@ -921,11 +919,9 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
921 rd2 = md; 919 rd2 = md;
922 } else if (((int8_t)(td->version[i] - md->version[i])) > 0) { 920 } else if (((int8_t)(td->version[i] - md->version[i])) > 0) {
923 rd = td; 921 rd = td;
924 md->version[i] = td->version[i];
925 writeops = 0x02; 922 writeops = 0x02;
926 } else { 923 } else {
927 rd = md; 924 rd = md;
928 td->version[i] = md->version[i];
929 writeops = 0x01; 925 writeops = 0x01;
930 } 926 }
931 } else { 927 } else {
@@ -957,6 +953,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
957 if (mtd_is_eccerr(res)) { 953 if (mtd_is_eccerr(res)) {
958 /* Mark table as invalid */ 954 /* Mark table as invalid */
959 rd->pages[i] = -1; 955 rd->pages[i] = -1;
956 rd->version[i] = 0;
960 i--; 957 i--;
961 continue; 958 continue;
962 } 959 }
@@ -967,6 +964,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
967 if (mtd_is_eccerr(res2)) { 964 if (mtd_is_eccerr(res2)) {
968 /* Mark table as invalid */ 965 /* Mark table as invalid */
969 rd2->pages[i] = -1; 966 rd2->pages[i] = -1;
967 rd2->version[i] = 0;
970 i--; 968 i--;
971 continue; 969 continue;
972 } 970 }
@@ -976,6 +974,12 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
976 if (mtd_is_bitflip(res) || mtd_is_bitflip(res2)) 974 if (mtd_is_bitflip(res) || mtd_is_bitflip(res2))
977 writeops = 0x03; 975 writeops = 0x03;
978 976
977 /* Update version numbers before writing */
978 if (md) {
979 td->version[i] = max(td->version[i], md->version[i]);
980 md->version[i] = td->version[i];
981 }
982
979 /* Write the bad block table to the device? */ 983 /* Write the bad block table to the device? */
980 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { 984 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
981 res = write_bbt(mtd, buf, td, md, chipsel); 985 res = write_bbt(mtd, buf, td, md, chipsel);