aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2010-05-03 02:04:39 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2010-06-04 04:30:42 -0400
commiteb89580e1a8388d206bf143c6c39d001095106ba (patch)
treea0cee0ac8e62a9731ade3d8aa400b621252ea3f4 /drivers/mtd
parent786d78318586cbdc8aec539fe5a4942490267fef (diff)
UBI: introduce a new IO return code
This patch introduces the %UBI_IO_BAD_HDR_READ return code for the I/O level function. We will use this code in order to distinguish between "corrupted header possibly because this is non-ubi data" and "corrupted header possibly because of real data corruption and ECC error". So far this patch does not introduce any functional change, just a preparation. This patch is pased on a patch from Sebastian Andrzej Siewior <sebastian@breakpoint.cc> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com> Reviewed-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> Tested-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/ubi/eba.c5
-rw-r--r--drivers/mtd/ubi/io.c42
-rw-r--r--drivers/mtd/ubi/scan.c4
-rw-r--r--drivers/mtd/ubi/ubi.h3
4 files changed, 31 insertions, 23 deletions
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
index 8e8226744320..b582671ca3a0 100644
--- a/drivers/mtd/ubi/eba.c
+++ b/drivers/mtd/ubi/eba.c
@@ -418,7 +418,8 @@ retry:
418 * may try to recover data. FIXME: but this is 418 * may try to recover data. FIXME: but this is
419 * not implemented. 419 * not implemented.
420 */ 420 */
421 if (err == UBI_IO_BAD_HDR) { 421 if (err == UBI_IO_BAD_HDR_READ ||
422 err == UBI_IO_BAD_HDR) {
422 ubi_warn("corrupted VID header at PEB " 423 ubi_warn("corrupted VID header at PEB "
423 "%d, LEB %d:%d", pnum, vol_id, 424 "%d, LEB %d:%d", pnum, vol_id,
424 lnum); 425 lnum);
@@ -962,7 +963,7 @@ write_error:
962static int is_error_sane(int err) 963static int is_error_sane(int err)
963{ 964{
964 if (err == -EIO || err == -ENOMEM || err == UBI_IO_BAD_HDR || 965 if (err == -EIO || err == -ENOMEM || err == UBI_IO_BAD_HDR ||
965 err == -ETIMEDOUT) 966 err == UBI_IO_BAD_HDR_READ || err == -ETIMEDOUT)
966 return 0; 967 return 0;
967 return 1; 968 return 1;
968} 969}
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index 02b19327dcc4..b812f8805367 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -515,7 +515,7 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
515 * In this case we probably anyway have garbage in this PEB. 515 * In this case we probably anyway have garbage in this PEB.
516 */ 516 */
517 err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0); 517 err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
518 if (err1 == UBI_IO_BAD_HDR) 518 if (err1 == UBI_IO_BAD_HDR_READ || err1 == UBI_IO_BAD_HDR)
519 /* 519 /*
520 * The VID header is corrupted, so we can safely erase this 520 * The VID header is corrupted, so we can safely erase this
521 * PEB and not afraid that it will be treated as a valid PEB in 521 * PEB and not afraid that it will be treated as a valid PEB in
@@ -736,23 +736,21 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
736 * header is still OK, we just report this as there was a 736 * header is still OK, we just report this as there was a
737 * bit-flip. 737 * bit-flip.
738 */ 738 */
739 read_err = err; 739 if (err == -EBADMSG)
740 read_err = UBI_IO_BAD_HDR_READ;
740 } 741 }
741 742
742 magic = be32_to_cpu(ec_hdr->magic); 743 magic = be32_to_cpu(ec_hdr->magic);
743 if (magic != UBI_EC_HDR_MAGIC) { 744 if (magic != UBI_EC_HDR_MAGIC) {
745 if (read_err)
746 return read_err;
747
744 /* 748 /*
745 * The magic field is wrong. Let's check if we have read all 749 * The magic field is wrong. Let's check if we have read all
746 * 0xFF. If yes, this physical eraseblock is assumed to be 750 * 0xFF. If yes, this physical eraseblock is assumed to be
747 * empty. 751 * empty.
748 *
749 * But if there was a read error, we do not test it for all
750 * 0xFFs. Even if it does contain all 0xFFs, this error
751 * indicates that something is still wrong with this physical
752 * eraseblock and we anyway cannot treat it as empty.
753 */ 752 */
754 if (read_err != -EBADMSG && 753 if (check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) {
755 check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) {
756 /* The physical eraseblock is supposedly empty */ 754 /* The physical eraseblock is supposedly empty */
757 if (verbose) 755 if (verbose)
758 ubi_warn("no EC header found at PEB %d, " 756 ubi_warn("no EC header found at PEB %d, "
@@ -788,7 +786,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
788 } else if (UBI_IO_DEBUG) 786 } else if (UBI_IO_DEBUG)
789 dbg_msg("bad EC header CRC at PEB %d, calculated " 787 dbg_msg("bad EC header CRC at PEB %d, calculated "
790 "%#08x, read %#08x", pnum, crc, hdr_crc); 788 "%#08x, read %#08x", pnum, crc, hdr_crc);
791 return UBI_IO_BAD_HDR; 789 return read_err ?: UBI_IO_BAD_HDR;
792 } 790 }
793 791
794 /* And of course validate what has just been read from the media */ 792 /* And of course validate what has just been read from the media */
@@ -798,6 +796,10 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
798 return -EINVAL; 796 return -EINVAL;
799 } 797 }
800 798
799 /*
800 * If there was %-EBADMSG, but the header CRC is still OK, report about
801 * a bit-flip to force scrubbing on this PEB.
802 */
801 return read_err ? UBI_IO_BITFLIPS : 0; 803 return read_err ? UBI_IO_BITFLIPS : 0;
802} 804}
803 805
@@ -1008,22 +1010,20 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
1008 * CRC check-sum and we will identify this. If the VID header is 1010 * CRC check-sum and we will identify this. If the VID header is
1009 * still OK, we just report this as there was a bit-flip. 1011 * still OK, we just report this as there was a bit-flip.
1010 */ 1012 */
1011 read_err = err; 1013 if (err == -EBADMSG)
1014 read_err = UBI_IO_BAD_HDR_READ;
1012 } 1015 }
1013 1016
1014 magic = be32_to_cpu(vid_hdr->magic); 1017 magic = be32_to_cpu(vid_hdr->magic);
1015 if (magic != UBI_VID_HDR_MAGIC) { 1018 if (magic != UBI_VID_HDR_MAGIC) {
1019 if (read_err)
1020 return read_err;
1021
1016 /* 1022 /*
1017 * If we have read all 0xFF bytes, the VID header probably does 1023 * If we have read all 0xFF bytes, the VID header probably does
1018 * not exist and the physical eraseblock is assumed to be free. 1024 * not exist and the physical eraseblock is assumed to be free.
1019 *
1020 * But if there was a read error, we do not test the data for
1021 * 0xFFs. Even if it does contain all 0xFFs, this error
1022 * indicates that something is still wrong with this physical
1023 * eraseblock and it cannot be regarded as free.
1024 */ 1025 */
1025 if (read_err != -EBADMSG && 1026 if (check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) {
1026 check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) {
1027 /* The physical eraseblock is supposedly free */ 1027 /* The physical eraseblock is supposedly free */
1028 if (verbose) 1028 if (verbose)
1029 ubi_warn("no VID header found at PEB %d, " 1029 ubi_warn("no VID header found at PEB %d, "
@@ -1059,7 +1059,7 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
1059 } else if (UBI_IO_DEBUG) 1059 } else if (UBI_IO_DEBUG)
1060 dbg_msg("bad CRC at PEB %d, calculated %#08x, " 1060 dbg_msg("bad CRC at PEB %d, calculated %#08x, "
1061 "read %#08x", pnum, crc, hdr_crc); 1061 "read %#08x", pnum, crc, hdr_crc);
1062 return UBI_IO_BAD_HDR; 1062 return read_err ?: UBI_IO_BAD_HDR;
1063 } 1063 }
1064 1064
1065 /* Validate the VID header that we have just read */ 1065 /* Validate the VID header that we have just read */
@@ -1069,6 +1069,10 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
1069 return -EINVAL; 1069 return -EINVAL;
1070 } 1070 }
1071 1071
1072 /*
1073 * If there was a read error (%-EBADMSG), but the header CRC is still
1074 * OK, report about a bit-flip to force scrubbing on this PEB.
1075 */
1072 return read_err ? UBI_IO_BITFLIPS : 0; 1076 return read_err ? UBI_IO_BITFLIPS : 0;
1073} 1077}
1074 1078
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index b878a7661f5a..c45900744107 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -745,7 +745,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
745 bitflips = 1; 745 bitflips = 1;
746 else if (err == UBI_IO_PEB_EMPTY) 746 else if (err == UBI_IO_PEB_EMPTY)
747 return add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, &si->erase); 747 return add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, &si->erase);
748 else if (err == UBI_IO_BAD_HDR) { 748 else if (err == UBI_IO_BAD_HDR_READ || err == UBI_IO_BAD_HDR) {
749 /* 749 /*
750 * We have to also look at the VID header, possibly it is not 750 * We have to also look at the VID header, possibly it is not
751 * corrupted. Set %bitflips flag in order to make this PEB be 751 * corrupted. Set %bitflips flag in order to make this PEB be
@@ -813,7 +813,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
813 return err; 813 return err;
814 else if (err == UBI_IO_BITFLIPS) 814 else if (err == UBI_IO_BITFLIPS)
815 bitflips = 1; 815 bitflips = 1;
816 else if (err == UBI_IO_BAD_HDR || 816 else if (err == UBI_IO_BAD_HDR_READ || err == UBI_IO_BAD_HDR ||
817 (err == UBI_IO_PEB_FREE && ec_corr)) { 817 (err == UBI_IO_PEB_FREE && ec_corr)) {
818 /* VID header is corrupted */ 818 /* VID header is corrupted */
819 err = add_to_list(si, pnum, ec, &si->corr); 819 err = add_to_list(si, pnum, ec, &si->corr);
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 539b3f6c7a56..0359e0cce482 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -90,12 +90,15 @@
90 * UBI_IO_PEB_FREE: the physical eraseblock is free, i.e. it contains only a 90 * UBI_IO_PEB_FREE: the physical eraseblock is free, i.e. it contains only a
91 * valid erase counter header, and the rest are %0xFF bytes 91 * valid erase counter header, and the rest are %0xFF bytes
92 * UBI_IO_BAD_HDR: the EC or VID header is corrupted (bad magic or CRC) 92 * UBI_IO_BAD_HDR: the EC or VID header is corrupted (bad magic or CRC)
93 * UBI_IO_BAD_HDR_READ: the same as %UBI_IO_BAD_HDR, but also there was a read
94 * error reported by the flash driver
93 * UBI_IO_BITFLIPS: bit-flips were detected and corrected 95 * UBI_IO_BITFLIPS: bit-flips were detected and corrected
94 */ 96 */
95enum { 97enum {
96 UBI_IO_PEB_EMPTY = 1, 98 UBI_IO_PEB_EMPTY = 1,
97 UBI_IO_PEB_FREE, 99 UBI_IO_PEB_FREE,
98 UBI_IO_BAD_HDR, 100 UBI_IO_BAD_HDR,
101 UBI_IO_BAD_HDR_READ,
99 UBI_IO_BITFLIPS 102 UBI_IO_BITFLIPS
100}; 103};
101 104