diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-18 13:50:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-18 13:50:02 -0400 |
commit | fd57ed021990157ee5b3997c3f21c734093a9e23 (patch) | |
tree | a32d18647b1becc1ee81fb04c5dd5dedeed4e1d7 /drivers/mtd | |
parent | ca749e2af01bb3e6b94d441696903dc26c357443 (diff) | |
parent | 28237e4583604818294dc1ce7881db5f53377b9c (diff) |
Merge branch 'linux-next' of git://git.infradead.org/ubi-2.6
* 'linux-next' of git://git.infradead.org/ubi-2.6:
UBI: make tests modes dynamic
UBI: make self-checks dynamic
UBI: make debugging messages dynamic
UBI: remove UBI_IO_DEBUG macro
UBI: kill debugging buffer
UBI: allocate erase checking buffer on demand
UBI: allocate write checking buffer on demand
UBI: always re-read in case of read failures
UBI: cleanup comments about corrupted PEBs
UBI: add slab cache for ubi_scan_leb objects
UBI: use raw mtd read function in debugging code
UBI: try to reveal buggy MTD drivers
UBI: add a commentary about allocating VID header buffer on stack
UBI: cleanup LEB start calculations
UBI: fix NOR erase preparation quirk
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/ubi/Kconfig | 8 | ||||
-rw-r--r-- | drivers/mtd/ubi/Kconfig.debug | 73 | ||||
-rw-r--r-- | drivers/mtd/ubi/build.c | 20 | ||||
-rw-r--r-- | drivers/mtd/ubi/debug.c | 14 | ||||
-rw-r--r-- | drivers/mtd/ubi/debug.h | 131 | ||||
-rw-r--r-- | drivers/mtd/ubi/io.c | 145 | ||||
-rw-r--r-- | drivers/mtd/ubi/scan.c | 95 | ||||
-rw-r--r-- | drivers/mtd/ubi/scan.h | 2 | ||||
-rw-r--r-- | drivers/mtd/ubi/ubi.h | 7 | ||||
-rw-r--r-- | drivers/mtd/ubi/vmt.c | 7 | ||||
-rw-r--r-- | drivers/mtd/ubi/vtbl.c | 9 | ||||
-rw-r--r-- | drivers/mtd/ubi/wl.c | 20 |
12 files changed, 297 insertions, 234 deletions
diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig index 3cf193fb5e00..6abeb4f13403 100644 --- a/drivers/mtd/ubi/Kconfig +++ b/drivers/mtd/ubi/Kconfig | |||
@@ -52,6 +52,12 @@ config MTD_UBI_GLUEBI | |||
52 | work on top of UBI. Do not enable this unless you use legacy | 52 | work on top of UBI. Do not enable this unless you use legacy |
53 | software. | 53 | software. |
54 | 54 | ||
55 | source "drivers/mtd/ubi/Kconfig.debug" | 55 | config MTD_UBI_DEBUG |
56 | bool "UBI debugging" | ||
57 | depends on SYSFS | ||
58 | select DEBUG_FS | ||
59 | select KALLSYMS_ALL if KALLSYMS && DEBUG_KERNEL | ||
60 | help | ||
61 | This option enables UBI debugging. | ||
56 | 62 | ||
57 | endif # MTD_UBI | 63 | endif # MTD_UBI |
diff --git a/drivers/mtd/ubi/Kconfig.debug b/drivers/mtd/ubi/Kconfig.debug deleted file mode 100644 index fad4adc0fe2c..000000000000 --- a/drivers/mtd/ubi/Kconfig.debug +++ /dev/null | |||
@@ -1,73 +0,0 @@ | |||
1 | comment "UBI debugging options" | ||
2 | |||
3 | config MTD_UBI_DEBUG | ||
4 | bool "UBI debugging" | ||
5 | depends on SYSFS | ||
6 | select DEBUG_FS | ||
7 | select KALLSYMS_ALL if KALLSYMS && DEBUG_KERNEL | ||
8 | help | ||
9 | This option enables UBI debugging. | ||
10 | |||
11 | if MTD_UBI_DEBUG | ||
12 | |||
13 | config MTD_UBI_DEBUG_MSG | ||
14 | bool "UBI debugging messages" | ||
15 | help | ||
16 | This option enables UBI debugging messages. | ||
17 | |||
18 | config MTD_UBI_DEBUG_PARANOID | ||
19 | bool "Extra self-checks" | ||
20 | help | ||
21 | This option enables extra checks in UBI code. Note this slows UBI down | ||
22 | significantly. | ||
23 | |||
24 | config MTD_UBI_DEBUG_DISABLE_BGT | ||
25 | bool "Do not enable the UBI background thread" | ||
26 | help | ||
27 | This option switches the background thread off by default. The thread | ||
28 | may be also be enabled/disabled via UBI sysfs. | ||
29 | |||
30 | config MTD_UBI_DEBUG_EMULATE_BITFLIPS | ||
31 | bool "Emulate flash bit-flips" | ||
32 | help | ||
33 | This option emulates bit-flips with probability 1/50, which in turn | ||
34 | causes scrubbing. Useful for debugging and stressing UBI. | ||
35 | |||
36 | config MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES | ||
37 | bool "Emulate flash write failures" | ||
38 | help | ||
39 | This option emulates write failures with probability 1/100. Useful for | ||
40 | debugging and testing how UBI handlines errors. | ||
41 | |||
42 | config MTD_UBI_DEBUG_EMULATE_ERASE_FAILURES | ||
43 | bool "Emulate flash erase failures" | ||
44 | help | ||
45 | This option emulates erase failures with probability 1/100. Useful for | ||
46 | debugging and testing how UBI handlines errors. | ||
47 | |||
48 | comment "Additional UBI debugging messages" | ||
49 | |||
50 | config MTD_UBI_DEBUG_MSG_BLD | ||
51 | bool "Additional UBI initialization and build messages" | ||
52 | help | ||
53 | This option enables detailed UBI initialization and device build | ||
54 | debugging messages. | ||
55 | |||
56 | config MTD_UBI_DEBUG_MSG_EBA | ||
57 | bool "Eraseblock association unit messages" | ||
58 | help | ||
59 | This option enables debugging messages from the UBI eraseblock | ||
60 | association unit. | ||
61 | |||
62 | config MTD_UBI_DEBUG_MSG_WL | ||
63 | bool "Wear-leveling unit messages" | ||
64 | help | ||
65 | This option enables debugging messages from the UBI wear-leveling | ||
66 | unit. | ||
67 | |||
68 | config MTD_UBI_DEBUG_MSG_IO | ||
69 | bool "Input/output unit messages" | ||
70 | help | ||
71 | This option enables debugging messages from the UBI input/output unit. | ||
72 | |||
73 | endif # MTD_UBI_DEBUG | ||
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 5ebe280225d6..a801ea6b8b6d 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -711,7 +711,7 @@ static int io_init(struct ubi_device *ubi) | |||
711 | } | 711 | } |
712 | 712 | ||
713 | /* Similar for the data offset */ | 713 | /* Similar for the data offset */ |
714 | ubi->leb_start = ubi->vid_hdr_offset + UBI_EC_HDR_SIZE; | 714 | ubi->leb_start = ubi->vid_hdr_offset + UBI_VID_HDR_SIZE; |
715 | ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size); | 715 | ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size); |
716 | 716 | ||
717 | dbg_msg("vid_hdr_offset %d", ubi->vid_hdr_offset); | 717 | dbg_msg("vid_hdr_offset %d", ubi->vid_hdr_offset); |
@@ -923,6 +923,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
923 | spin_lock_init(&ubi->volumes_lock); | 923 | spin_lock_init(&ubi->volumes_lock); |
924 | 924 | ||
925 | ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num); | 925 | ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num); |
926 | dbg_msg("sizeof(struct ubi_scan_leb) %zu", sizeof(struct ubi_scan_leb)); | ||
927 | dbg_msg("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry)); | ||
926 | 928 | ||
927 | err = io_init(ubi); | 929 | err = io_init(ubi); |
928 | if (err) | 930 | if (err) |
@@ -937,13 +939,6 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
937 | if (!ubi->peb_buf2) | 939 | if (!ubi->peb_buf2) |
938 | goto out_free; | 940 | goto out_free; |
939 | 941 | ||
940 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | ||
941 | mutex_init(&ubi->dbg_buf_mutex); | ||
942 | ubi->dbg_peb_buf = vmalloc(ubi->peb_size); | ||
943 | if (!ubi->dbg_peb_buf) | ||
944 | goto out_free; | ||
945 | #endif | ||
946 | |||
947 | err = attach_by_scanning(ubi); | 942 | err = attach_by_scanning(ubi); |
948 | if (err) { | 943 | if (err) { |
949 | dbg_err("failed to attach by scanning, error %d", err); | 944 | dbg_err("failed to attach by scanning, error %d", err); |
@@ -991,8 +986,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
991 | * checks @ubi->thread_enabled. Otherwise we may fail to wake it up. | 986 | * checks @ubi->thread_enabled. Otherwise we may fail to wake it up. |
992 | */ | 987 | */ |
993 | spin_lock(&ubi->wl_lock); | 988 | spin_lock(&ubi->wl_lock); |
994 | if (!DBG_DISABLE_BGT) | 989 | ubi->thread_enabled = 1; |
995 | ubi->thread_enabled = 1; | ||
996 | wake_up_process(ubi->bgt_thread); | 990 | wake_up_process(ubi->bgt_thread); |
997 | spin_unlock(&ubi->wl_lock); | 991 | spin_unlock(&ubi->wl_lock); |
998 | 992 | ||
@@ -1009,9 +1003,6 @@ out_detach: | |||
1009 | out_free: | 1003 | out_free: |
1010 | vfree(ubi->peb_buf1); | 1004 | vfree(ubi->peb_buf1); |
1011 | vfree(ubi->peb_buf2); | 1005 | vfree(ubi->peb_buf2); |
1012 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | ||
1013 | vfree(ubi->dbg_peb_buf); | ||
1014 | #endif | ||
1015 | if (ref) | 1006 | if (ref) |
1016 | put_device(&ubi->dev); | 1007 | put_device(&ubi->dev); |
1017 | else | 1008 | else |
@@ -1082,9 +1073,6 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) | |||
1082 | put_mtd_device(ubi->mtd); | 1073 | put_mtd_device(ubi->mtd); |
1083 | vfree(ubi->peb_buf1); | 1074 | vfree(ubi->peb_buf1); |
1084 | vfree(ubi->peb_buf2); | 1075 | vfree(ubi->peb_buf2); |
1085 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | ||
1086 | vfree(ubi->dbg_peb_buf); | ||
1087 | #endif | ||
1088 | ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); | 1076 | ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); |
1089 | put_device(&ubi->dev); | 1077 | put_device(&ubi->dev); |
1090 | return 0; | 1078 | return 0; |
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 4876977e52cb..d4d07e5f138f 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c | |||
@@ -27,6 +27,20 @@ | |||
27 | #ifdef CONFIG_MTD_UBI_DEBUG | 27 | #ifdef CONFIG_MTD_UBI_DEBUG |
28 | 28 | ||
29 | #include "ubi.h" | 29 | #include "ubi.h" |
30 | #include <linux/module.h> | ||
31 | #include <linux/moduleparam.h> | ||
32 | |||
33 | unsigned int ubi_msg_flags; | ||
34 | unsigned int ubi_chk_flags; | ||
35 | unsigned int ubi_tst_flags; | ||
36 | |||
37 | module_param_named(debug_msgs, ubi_msg_flags, uint, S_IRUGO | S_IWUSR); | ||
38 | module_param_named(debug_chks, ubi_chk_flags, uint, S_IRUGO | S_IWUSR); | ||
39 | module_param_named(debug_tsts, ubi_chk_flags, uint, S_IRUGO | S_IWUSR); | ||
40 | |||
41 | MODULE_PARM_DESC(debug_msgs, "Debug message type flags"); | ||
42 | MODULE_PARM_DESC(debug_chks, "Debug check flags"); | ||
43 | MODULE_PARM_DESC(debug_tsts, "Debug special test flags"); | ||
30 | 44 | ||
31 | /** | 45 | /** |
32 | * ubi_dbg_dump_ec_hdr - dump an erase counter header. | 46 | * ubi_dbg_dump_ec_hdr - dump an erase counter header. |
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 9eca95074bc2..0b0c2888c656 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h | |||
@@ -38,6 +38,11 @@ | |||
38 | printk(KERN_DEBUG "UBI DBG (pid %d): %s: " fmt "\n", \ | 38 | printk(KERN_DEBUG "UBI DBG (pid %d): %s: " fmt "\n", \ |
39 | current->pid, __func__, ##__VA_ARGS__) | 39 | current->pid, __func__, ##__VA_ARGS__) |
40 | 40 | ||
41 | #define dbg_do_msg(typ, fmt, ...) do { \ | ||
42 | if (ubi_msg_flags & typ) \ | ||
43 | dbg_msg(fmt, ##__VA_ARGS__); \ | ||
44 | } while (0) | ||
45 | |||
41 | #define ubi_dbg_dump_stack() dump_stack() | 46 | #define ubi_dbg_dump_stack() dump_stack() |
42 | 47 | ||
43 | struct ubi_ec_hdr; | 48 | struct ubi_ec_hdr; |
@@ -57,62 +62,88 @@ void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type); | |||
57 | void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); | 62 | void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); |
58 | void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len); | 63 | void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len); |
59 | 64 | ||
65 | extern unsigned int ubi_msg_flags; | ||
66 | |||
67 | /* | ||
68 | * Debugging message type flags (must match msg_type_names in debug.c). | ||
69 | * | ||
70 | * UBI_MSG_GEN: general messages | ||
71 | * UBI_MSG_EBA: journal messages | ||
72 | * UBI_MSG_WL: mount messages | ||
73 | * UBI_MSG_IO: commit messages | ||
74 | * UBI_MSG_BLD: LEB find messages | ||
75 | */ | ||
76 | enum { | ||
77 | UBI_MSG_GEN = 0x1, | ||
78 | UBI_MSG_EBA = 0x2, | ||
79 | UBI_MSG_WL = 0x4, | ||
80 | UBI_MSG_IO = 0x8, | ||
81 | UBI_MSG_BLD = 0x10, | ||
82 | }; | ||
83 | |||
60 | #define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) \ | 84 | #define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) \ |
61 | print_hex_dump(l, ps, pt, r, g, b, len, a) | 85 | print_hex_dump(l, ps, pt, r, g, b, len, a) |
62 | 86 | ||
63 | #ifdef CONFIG_MTD_UBI_DEBUG_MSG | ||
64 | /* General debugging messages */ | 87 | /* General debugging messages */ |
65 | #define dbg_gen(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | 88 | #define dbg_gen(fmt, ...) dbg_do_msg(UBI_MSG_GEN, fmt, ##__VA_ARGS__) |
66 | #else | ||
67 | #define dbg_gen(fmt, ...) ({}) | ||
68 | #endif | ||
69 | 89 | ||
70 | #ifdef CONFIG_MTD_UBI_DEBUG_MSG_EBA | ||
71 | /* Messages from the eraseblock association sub-system */ | 90 | /* Messages from the eraseblock association sub-system */ |
72 | #define dbg_eba(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | 91 | #define dbg_eba(fmt, ...) dbg_do_msg(UBI_MSG_EBA, fmt, ##__VA_ARGS__) |
73 | #else | ||
74 | #define dbg_eba(fmt, ...) ({}) | ||
75 | #endif | ||
76 | 92 | ||
77 | #ifdef CONFIG_MTD_UBI_DEBUG_MSG_WL | ||
78 | /* Messages from the wear-leveling sub-system */ | 93 | /* Messages from the wear-leveling sub-system */ |
79 | #define dbg_wl(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | 94 | #define dbg_wl(fmt, ...) dbg_do_msg(UBI_MSG_WL, fmt, ##__VA_ARGS__) |
80 | #else | ||
81 | #define dbg_wl(fmt, ...) ({}) | ||
82 | #endif | ||
83 | 95 | ||
84 | #ifdef CONFIG_MTD_UBI_DEBUG_MSG_IO | ||
85 | /* Messages from the input/output sub-system */ | 96 | /* Messages from the input/output sub-system */ |
86 | #define dbg_io(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | 97 | #define dbg_io(fmt, ...) dbg_do_msg(UBI_MSG_IO, fmt, ##__VA_ARGS__) |
87 | #else | ||
88 | #define dbg_io(fmt, ...) ({}) | ||
89 | #endif | ||
90 | 98 | ||
91 | #ifdef CONFIG_MTD_UBI_DEBUG_MSG_BLD | ||
92 | /* Initialization and build messages */ | 99 | /* Initialization and build messages */ |
93 | #define dbg_bld(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | 100 | #define dbg_bld(fmt, ...) dbg_do_msg(UBI_MSG_BLD, fmt, ##__VA_ARGS__) |
94 | #define UBI_IO_DEBUG 1 | 101 | |
95 | #else | 102 | extern unsigned int ubi_chk_flags; |
96 | #define dbg_bld(fmt, ...) ({}) | 103 | |
97 | #define UBI_IO_DEBUG 0 | 104 | /* |
98 | #endif | 105 | * Debugging check flags. |
106 | * | ||
107 | * UBI_CHK_GEN: general checks | ||
108 | * UBI_CHK_IO: check writes and erases | ||
109 | */ | ||
110 | enum { | ||
111 | UBI_CHK_GEN = 0x1, | ||
112 | UBI_CHK_IO = 0x2, | ||
113 | }; | ||
99 | 114 | ||
100 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | ||
101 | int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); | 115 | int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); |
102 | int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, | 116 | int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, |
103 | int offset, int len); | 117 | int offset, int len); |
104 | #else | ||
105 | #define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0 | ||
106 | #define ubi_dbg_check_write(ubi, buf, pnum, offset, len) 0 | ||
107 | #endif | ||
108 | 118 | ||
109 | #ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT | 119 | extern unsigned int ubi_tst_flags; |
110 | #define DBG_DISABLE_BGT 1 | 120 | |
111 | #else | 121 | /* |
112 | #define DBG_DISABLE_BGT 0 | 122 | * Special testing flags. |
113 | #endif | 123 | * |
124 | * UBIFS_TST_DISABLE_BGT: disable the background thread | ||
125 | * UBI_TST_EMULATE_BITFLIPS: emulate bit-flips | ||
126 | * UBI_TST_EMULATE_WRITE_FAILURES: emulate write failures | ||
127 | * UBI_TST_EMULATE_ERASE_FAILURES: emulate erase failures | ||
128 | */ | ||
129 | enum { | ||
130 | UBI_TST_DISABLE_BGT = 0x1, | ||
131 | UBI_TST_EMULATE_BITFLIPS = 0x2, | ||
132 | UBI_TST_EMULATE_WRITE_FAILURES = 0x4, | ||
133 | UBI_TST_EMULATE_ERASE_FAILURES = 0x8, | ||
134 | }; | ||
135 | |||
136 | /** | ||
137 | * ubi_dbg_is_bgt_disabled - if the background thread is disabled. | ||
138 | * | ||
139 | * Returns non-zero if the UBI background thread is disabled for testing | ||
140 | * purposes. | ||
141 | */ | ||
142 | static inline int ubi_dbg_is_bgt_disabled(void) | ||
143 | { | ||
144 | return ubi_tst_flags & UBI_TST_DISABLE_BGT; | ||
145 | } | ||
114 | 146 | ||
115 | #ifdef CONFIG_MTD_UBI_DEBUG_EMULATE_BITFLIPS | ||
116 | /** | 147 | /** |
117 | * ubi_dbg_is_bitflip - if it is time to emulate a bit-flip. | 148 | * ubi_dbg_is_bitflip - if it is time to emulate a bit-flip. |
118 | * | 149 | * |
@@ -120,13 +151,11 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, | |||
120 | */ | 151 | */ |
121 | static inline int ubi_dbg_is_bitflip(void) | 152 | static inline int ubi_dbg_is_bitflip(void) |
122 | { | 153 | { |
123 | return !(random32() % 200); | 154 | if (ubi_tst_flags & UBI_TST_EMULATE_BITFLIPS) |
155 | return !(random32() % 200); | ||
156 | return 0; | ||
124 | } | 157 | } |
125 | #else | ||
126 | #define ubi_dbg_is_bitflip() 0 | ||
127 | #endif | ||
128 | 158 | ||
129 | #ifdef CONFIG_MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES | ||
130 | /** | 159 | /** |
131 | * ubi_dbg_is_write_failure - if it is time to emulate a write failure. | 160 | * ubi_dbg_is_write_failure - if it is time to emulate a write failure. |
132 | * | 161 | * |
@@ -135,13 +164,11 @@ static inline int ubi_dbg_is_bitflip(void) | |||
135 | */ | 164 | */ |
136 | static inline int ubi_dbg_is_write_failure(void) | 165 | static inline int ubi_dbg_is_write_failure(void) |
137 | { | 166 | { |
138 | return !(random32() % 500); | 167 | if (ubi_tst_flags & UBI_TST_EMULATE_WRITE_FAILURES) |
168 | return !(random32() % 500); | ||
169 | return 0; | ||
139 | } | 170 | } |
140 | #else | ||
141 | #define ubi_dbg_is_write_failure() 0 | ||
142 | #endif | ||
143 | 171 | ||
144 | #ifdef CONFIG_MTD_UBI_DEBUG_EMULATE_ERASE_FAILURES | ||
145 | /** | 172 | /** |
146 | * ubi_dbg_is_erase_failure - if its time to emulate an erase failure. | 173 | * ubi_dbg_is_erase_failure - if its time to emulate an erase failure. |
147 | * | 174 | * |
@@ -150,11 +177,10 @@ static inline int ubi_dbg_is_write_failure(void) | |||
150 | */ | 177 | */ |
151 | static inline int ubi_dbg_is_erase_failure(void) | 178 | static inline int ubi_dbg_is_erase_failure(void) |
152 | { | 179 | { |
180 | if (ubi_tst_flags & UBI_TST_EMULATE_ERASE_FAILURES) | ||
153 | return !(random32() % 400); | 181 | return !(random32() % 400); |
182 | return 0; | ||
154 | } | 183 | } |
155 | #else | ||
156 | #define ubi_dbg_is_erase_failure() 0 | ||
157 | #endif | ||
158 | 184 | ||
159 | #else | 185 | #else |
160 | 186 | ||
@@ -177,8 +203,7 @@ static inline int ubi_dbg_is_erase_failure(void) | |||
177 | #define ubi_dbg_dump_flash(ubi, pnum, offset, len) ({}) | 203 | #define ubi_dbg_dump_flash(ubi, pnum, offset, len) ({}) |
178 | #define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) ({}) | 204 | #define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) ({}) |
179 | 205 | ||
180 | #define UBI_IO_DEBUG 0 | 206 | #define ubi_dbg_is_bgt_disabled() 0 |
181 | #define DBG_DISABLE_BGT 0 | ||
182 | #define ubi_dbg_is_bitflip() 0 | 207 | #define ubi_dbg_is_bitflip() 0 |
183 | #define ubi_dbg_is_write_failure() 0 | 208 | #define ubi_dbg_is_write_failure() 0 |
184 | #define ubi_dbg_is_erase_failure() 0 | 209 | #define ubi_dbg_is_erase_failure() 0 |
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 811775aa8ee8..aaa6e1e83b29 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c | |||
@@ -91,7 +91,7 @@ | |||
91 | #include <linux/slab.h> | 91 | #include <linux/slab.h> |
92 | #include "ubi.h" | 92 | #include "ubi.h" |
93 | 93 | ||
94 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | 94 | #ifdef CONFIG_MTD_UBI_DEBUG |
95 | static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum); | 95 | static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum); |
96 | static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum); | 96 | static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum); |
97 | static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, | 97 | static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, |
@@ -146,6 +146,28 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, | |||
146 | if (err) | 146 | if (err) |
147 | return err; | 147 | return err; |
148 | 148 | ||
149 | /* | ||
150 | * Deliberately corrupt the buffer to improve robustness. Indeed, if we | ||
151 | * do not do this, the following may happen: | ||
152 | * 1. The buffer contains data from previous operation, e.g., read from | ||
153 | * another PEB previously. The data looks like expected, e.g., if we | ||
154 | * just do not read anything and return - the caller would not | ||
155 | * notice this. E.g., if we are reading a VID header, the buffer may | ||
156 | * contain a valid VID header from another PEB. | ||
157 | * 2. The driver is buggy and returns us success or -EBADMSG or | ||
158 | * -EUCLEAN, but it does not actually put any data to the buffer. | ||
159 | * | ||
160 | * This may confuse UBI or upper layers - they may think the buffer | ||
161 | * contains valid data while in fact it is just old data. This is | ||
162 | * especially possible because UBI (and UBIFS) relies on CRC, and | ||
163 | * treats data as correct even in case of ECC errors if the CRC is | ||
164 | * correct. | ||
165 | * | ||
166 | * Try to prevent this situation by changing the first byte of the | ||
167 | * buffer. | ||
168 | */ | ||
169 | *((uint8_t *)buf) ^= 0xFF; | ||
170 | |||
149 | addr = (loff_t)pnum * ubi->peb_size + offset; | 171 | addr = (loff_t)pnum * ubi->peb_size + offset; |
150 | retry: | 172 | retry: |
151 | err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); | 173 | err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); |
@@ -166,7 +188,7 @@ retry: | |||
166 | return UBI_IO_BITFLIPS; | 188 | return UBI_IO_BITFLIPS; |
167 | } | 189 | } |
168 | 190 | ||
169 | if (read != len && retries++ < UBI_IO_RETRIES) { | 191 | if (retries++ < UBI_IO_RETRIES) { |
170 | dbg_io("error %d%s while reading %d bytes from PEB %d:%d," | 192 | dbg_io("error %d%s while reading %d bytes from PEB %d:%d," |
171 | " read only %zd bytes, retry", | 193 | " read only %zd bytes, retry", |
172 | err, errstr, len, pnum, offset, read); | 194 | err, errstr, len, pnum, offset, read); |
@@ -480,6 +502,13 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum) | |||
480 | size_t written; | 502 | size_t written; |
481 | loff_t addr; | 503 | loff_t addr; |
482 | uint32_t data = 0; | 504 | uint32_t data = 0; |
505 | /* | ||
506 | * Note, we cannot generally define VID header buffers on stack, | ||
507 | * because of the way we deal with these buffers (see the header | ||
508 | * comment in this file). But we know this is a NOR-specific piece of | ||
509 | * code, so we can do this. But yes, this is error-prone and we should | ||
510 | * (pre-)allocate VID header buffer instead. | ||
511 | */ | ||
483 | struct ubi_vid_hdr vid_hdr; | 512 | struct ubi_vid_hdr vid_hdr; |
484 | 513 | ||
485 | /* | 514 | /* |
@@ -507,11 +536,13 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum) | |||
507 | * PEB. | 536 | * PEB. |
508 | */ | 537 | */ |
509 | err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0); | 538 | err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0); |
510 | if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR) { | 539 | if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR || |
540 | err1 == UBI_IO_FF) { | ||
511 | struct ubi_ec_hdr ec_hdr; | 541 | struct ubi_ec_hdr ec_hdr; |
512 | 542 | ||
513 | err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0); | 543 | err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0); |
514 | if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR) | 544 | if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR || |
545 | err1 == UBI_IO_FF) | ||
515 | /* | 546 | /* |
516 | * Both VID and EC headers are corrupted, so we can | 547 | * Both VID and EC headers are corrupted, so we can |
517 | * safely erase this PEB and not afraid that it will be | 548 | * safely erase this PEB and not afraid that it will be |
@@ -752,9 +783,8 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, | |||
752 | if (verbose) | 783 | if (verbose) |
753 | ubi_warn("no EC header found at PEB %d, " | 784 | ubi_warn("no EC header found at PEB %d, " |
754 | "only 0xFF bytes", pnum); | 785 | "only 0xFF bytes", pnum); |
755 | else if (UBI_IO_DEBUG) | 786 | dbg_bld("no EC header found at PEB %d, " |
756 | dbg_msg("no EC header found at PEB %d, " | 787 | "only 0xFF bytes", pnum); |
757 | "only 0xFF bytes", pnum); | ||
758 | if (!read_err) | 788 | if (!read_err) |
759 | return UBI_IO_FF; | 789 | return UBI_IO_FF; |
760 | else | 790 | else |
@@ -769,9 +799,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, | |||
769 | ubi_warn("bad magic number at PEB %d: %08x instead of " | 799 | ubi_warn("bad magic number at PEB %d: %08x instead of " |
770 | "%08x", pnum, magic, UBI_EC_HDR_MAGIC); | 800 | "%08x", pnum, magic, UBI_EC_HDR_MAGIC); |
771 | ubi_dbg_dump_ec_hdr(ec_hdr); | 801 | ubi_dbg_dump_ec_hdr(ec_hdr); |
772 | } else if (UBI_IO_DEBUG) | 802 | } |
773 | dbg_msg("bad magic number at PEB %d: %08x instead of " | 803 | dbg_bld("bad magic number at PEB %d: %08x instead of " |
774 | "%08x", pnum, magic, UBI_EC_HDR_MAGIC); | 804 | "%08x", pnum, magic, UBI_EC_HDR_MAGIC); |
775 | return UBI_IO_BAD_HDR; | 805 | return UBI_IO_BAD_HDR; |
776 | } | 806 | } |
777 | 807 | ||
@@ -783,9 +813,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, | |||
783 | ubi_warn("bad EC header CRC at PEB %d, calculated " | 813 | ubi_warn("bad EC header CRC at PEB %d, calculated " |
784 | "%#08x, read %#08x", pnum, crc, hdr_crc); | 814 | "%#08x, read %#08x", pnum, crc, hdr_crc); |
785 | ubi_dbg_dump_ec_hdr(ec_hdr); | 815 | ubi_dbg_dump_ec_hdr(ec_hdr); |
786 | } else if (UBI_IO_DEBUG) | 816 | } |
787 | dbg_msg("bad EC header CRC at PEB %d, calculated " | 817 | dbg_bld("bad EC header CRC at PEB %d, calculated " |
788 | "%#08x, read %#08x", pnum, crc, hdr_crc); | 818 | "%#08x, read %#08x", pnum, crc, hdr_crc); |
789 | 819 | ||
790 | if (!read_err) | 820 | if (!read_err) |
791 | return UBI_IO_BAD_HDR; | 821 | return UBI_IO_BAD_HDR; |
@@ -1008,9 +1038,8 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, | |||
1008 | if (verbose) | 1038 | if (verbose) |
1009 | ubi_warn("no VID header found at PEB %d, " | 1039 | ubi_warn("no VID header found at PEB %d, " |
1010 | "only 0xFF bytes", pnum); | 1040 | "only 0xFF bytes", pnum); |
1011 | else if (UBI_IO_DEBUG) | 1041 | dbg_bld("no VID header found at PEB %d, " |
1012 | dbg_msg("no VID header found at PEB %d, " | 1042 | "only 0xFF bytes", pnum); |
1013 | "only 0xFF bytes", pnum); | ||
1014 | if (!read_err) | 1043 | if (!read_err) |
1015 | return UBI_IO_FF; | 1044 | return UBI_IO_FF; |
1016 | else | 1045 | else |
@@ -1021,9 +1050,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, | |||
1021 | ubi_warn("bad magic number at PEB %d: %08x instead of " | 1050 | ubi_warn("bad magic number at PEB %d: %08x instead of " |
1022 | "%08x", pnum, magic, UBI_VID_HDR_MAGIC); | 1051 | "%08x", pnum, magic, UBI_VID_HDR_MAGIC); |
1023 | ubi_dbg_dump_vid_hdr(vid_hdr); | 1052 | ubi_dbg_dump_vid_hdr(vid_hdr); |
1024 | } else if (UBI_IO_DEBUG) | 1053 | } |
1025 | dbg_msg("bad magic number at PEB %d: %08x instead of " | 1054 | dbg_bld("bad magic number at PEB %d: %08x instead of " |
1026 | "%08x", pnum, magic, UBI_VID_HDR_MAGIC); | 1055 | "%08x", pnum, magic, UBI_VID_HDR_MAGIC); |
1027 | return UBI_IO_BAD_HDR; | 1056 | return UBI_IO_BAD_HDR; |
1028 | } | 1057 | } |
1029 | 1058 | ||
@@ -1035,9 +1064,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, | |||
1035 | ubi_warn("bad CRC at PEB %d, calculated %#08x, " | 1064 | ubi_warn("bad CRC at PEB %d, calculated %#08x, " |
1036 | "read %#08x", pnum, crc, hdr_crc); | 1065 | "read %#08x", pnum, crc, hdr_crc); |
1037 | ubi_dbg_dump_vid_hdr(vid_hdr); | 1066 | ubi_dbg_dump_vid_hdr(vid_hdr); |
1038 | } else if (UBI_IO_DEBUG) | 1067 | } |
1039 | dbg_msg("bad CRC at PEB %d, calculated %#08x, " | 1068 | dbg_bld("bad CRC at PEB %d, calculated %#08x, " |
1040 | "read %#08x", pnum, crc, hdr_crc); | 1069 | "read %#08x", pnum, crc, hdr_crc); |
1041 | if (!read_err) | 1070 | if (!read_err) |
1042 | return UBI_IO_BAD_HDR; | 1071 | return UBI_IO_BAD_HDR; |
1043 | else | 1072 | else |
@@ -1097,7 +1126,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, | |||
1097 | return err; | 1126 | return err; |
1098 | } | 1127 | } |
1099 | 1128 | ||
1100 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | 1129 | #ifdef CONFIG_MTD_UBI_DEBUG |
1101 | 1130 | ||
1102 | /** | 1131 | /** |
1103 | * paranoid_check_not_bad - ensure that a physical eraseblock is not bad. | 1132 | * paranoid_check_not_bad - ensure that a physical eraseblock is not bad. |
@@ -1111,6 +1140,9 @@ static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum) | |||
1111 | { | 1140 | { |
1112 | int err; | 1141 | int err; |
1113 | 1142 | ||
1143 | if (!(ubi_chk_flags & UBI_CHK_IO)) | ||
1144 | return 0; | ||
1145 | |||
1114 | err = ubi_io_is_bad(ubi, pnum); | 1146 | err = ubi_io_is_bad(ubi, pnum); |
1115 | if (!err) | 1147 | if (!err) |
1116 | return err; | 1148 | return err; |
@@ -1135,6 +1167,9 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, | |||
1135 | int err; | 1167 | int err; |
1136 | uint32_t magic; | 1168 | uint32_t magic; |
1137 | 1169 | ||
1170 | if (!(ubi_chk_flags & UBI_CHK_IO)) | ||
1171 | return 0; | ||
1172 | |||
1138 | magic = be32_to_cpu(ec_hdr->magic); | 1173 | magic = be32_to_cpu(ec_hdr->magic); |
1139 | if (magic != UBI_EC_HDR_MAGIC) { | 1174 | if (magic != UBI_EC_HDR_MAGIC) { |
1140 | ubi_err("bad magic %#08x, must be %#08x", | 1175 | ubi_err("bad magic %#08x, must be %#08x", |
@@ -1170,6 +1205,9 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) | |||
1170 | uint32_t crc, hdr_crc; | 1205 | uint32_t crc, hdr_crc; |
1171 | struct ubi_ec_hdr *ec_hdr; | 1206 | struct ubi_ec_hdr *ec_hdr; |
1172 | 1207 | ||
1208 | if (!(ubi_chk_flags & UBI_CHK_IO)) | ||
1209 | return 0; | ||
1210 | |||
1173 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); | 1211 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); |
1174 | if (!ec_hdr) | 1212 | if (!ec_hdr) |
1175 | return -ENOMEM; | 1213 | return -ENOMEM; |
@@ -1211,6 +1249,9 @@ static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, | |||
1211 | int err; | 1249 | int err; |
1212 | uint32_t magic; | 1250 | uint32_t magic; |
1213 | 1251 | ||
1252 | if (!(ubi_chk_flags & UBI_CHK_IO)) | ||
1253 | return 0; | ||
1254 | |||
1214 | magic = be32_to_cpu(vid_hdr->magic); | 1255 | magic = be32_to_cpu(vid_hdr->magic); |
1215 | if (magic != UBI_VID_HDR_MAGIC) { | 1256 | if (magic != UBI_VID_HDR_MAGIC) { |
1216 | ubi_err("bad VID header magic %#08x at PEB %d, must be %#08x", | 1257 | ubi_err("bad VID header magic %#08x at PEB %d, must be %#08x", |
@@ -1249,6 +1290,9 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) | |||
1249 | struct ubi_vid_hdr *vid_hdr; | 1290 | struct ubi_vid_hdr *vid_hdr; |
1250 | void *p; | 1291 | void *p; |
1251 | 1292 | ||
1293 | if (!(ubi_chk_flags & UBI_CHK_IO)) | ||
1294 | return 0; | ||
1295 | |||
1252 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); | 1296 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); |
1253 | if (!vid_hdr) | 1297 | if (!vid_hdr) |
1254 | return -ENOMEM; | 1298 | return -ENOMEM; |
@@ -1294,15 +1338,26 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, | |||
1294 | int offset, int len) | 1338 | int offset, int len) |
1295 | { | 1339 | { |
1296 | int err, i; | 1340 | int err, i; |
1341 | size_t read; | ||
1342 | void *buf1; | ||
1343 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; | ||
1297 | 1344 | ||
1298 | mutex_lock(&ubi->dbg_buf_mutex); | 1345 | if (!(ubi_chk_flags & UBI_CHK_IO)) |
1299 | err = ubi_io_read(ubi, ubi->dbg_peb_buf, pnum, offset, len); | 1346 | return 0; |
1300 | if (err) | 1347 | |
1301 | goto out_unlock; | 1348 | buf1 = __vmalloc(len, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); |
1349 | if (!buf1) { | ||
1350 | ubi_err("cannot allocate memory to check writes"); | ||
1351 | return 0; | ||
1352 | } | ||
1353 | |||
1354 | err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf1); | ||
1355 | if (err && err != -EUCLEAN) | ||
1356 | goto out_free; | ||
1302 | 1357 | ||
1303 | for (i = 0; i < len; i++) { | 1358 | for (i = 0; i < len; i++) { |
1304 | uint8_t c = ((uint8_t *)buf)[i]; | 1359 | uint8_t c = ((uint8_t *)buf)[i]; |
1305 | uint8_t c1 = ((uint8_t *)ubi->dbg_peb_buf)[i]; | 1360 | uint8_t c1 = ((uint8_t *)buf1)[i]; |
1306 | int dump_len; | 1361 | int dump_len; |
1307 | 1362 | ||
1308 | if (c == c1) | 1363 | if (c == c1) |
@@ -1319,17 +1374,17 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, | |||
1319 | ubi_msg("hex dump of the read buffer from %d to %d", | 1374 | ubi_msg("hex dump of the read buffer from %d to %d", |
1320 | i, i + dump_len); | 1375 | i, i + dump_len); |
1321 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, | 1376 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, |
1322 | ubi->dbg_peb_buf + i, dump_len, 1); | 1377 | buf1 + i, dump_len, 1); |
1323 | ubi_dbg_dump_stack(); | 1378 | ubi_dbg_dump_stack(); |
1324 | err = -EINVAL; | 1379 | err = -EINVAL; |
1325 | goto out_unlock; | 1380 | goto out_free; |
1326 | } | 1381 | } |
1327 | mutex_unlock(&ubi->dbg_buf_mutex); | ||
1328 | 1382 | ||
1383 | vfree(buf1); | ||
1329 | return 0; | 1384 | return 0; |
1330 | 1385 | ||
1331 | out_unlock: | 1386 | out_free: |
1332 | mutex_unlock(&ubi->dbg_buf_mutex); | 1387 | vfree(buf1); |
1333 | return err; | 1388 | return err; |
1334 | } | 1389 | } |
1335 | 1390 | ||
@@ -1348,36 +1403,44 @@ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) | |||
1348 | { | 1403 | { |
1349 | size_t read; | 1404 | size_t read; |
1350 | int err; | 1405 | int err; |
1406 | void *buf; | ||
1351 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; | 1407 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; |
1352 | 1408 | ||
1353 | mutex_lock(&ubi->dbg_buf_mutex); | 1409 | if (!(ubi_chk_flags & UBI_CHK_IO)) |
1354 | err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf); | 1410 | return 0; |
1411 | |||
1412 | buf = __vmalloc(len, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); | ||
1413 | if (!buf) { | ||
1414 | ubi_err("cannot allocate memory to check for 0xFFs"); | ||
1415 | return 0; | ||
1416 | } | ||
1417 | |||
1418 | err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); | ||
1355 | if (err && err != -EUCLEAN) { | 1419 | if (err && err != -EUCLEAN) { |
1356 | ubi_err("error %d while reading %d bytes from PEB %d:%d, " | 1420 | ubi_err("error %d while reading %d bytes from PEB %d:%d, " |
1357 | "read %zd bytes", err, len, pnum, offset, read); | 1421 | "read %zd bytes", err, len, pnum, offset, read); |
1358 | goto error; | 1422 | goto error; |
1359 | } | 1423 | } |
1360 | 1424 | ||
1361 | err = ubi_check_pattern(ubi->dbg_peb_buf, 0xFF, len); | 1425 | err = ubi_check_pattern(buf, 0xFF, len); |
1362 | if (err == 0) { | 1426 | if (err == 0) { |
1363 | ubi_err("flash region at PEB %d:%d, length %d does not " | 1427 | ubi_err("flash region at PEB %d:%d, length %d does not " |
1364 | "contain all 0xFF bytes", pnum, offset, len); | 1428 | "contain all 0xFF bytes", pnum, offset, len); |
1365 | goto fail; | 1429 | goto fail; |
1366 | } | 1430 | } |
1367 | mutex_unlock(&ubi->dbg_buf_mutex); | ||
1368 | 1431 | ||
1432 | vfree(buf); | ||
1369 | return 0; | 1433 | return 0; |
1370 | 1434 | ||
1371 | fail: | 1435 | fail: |
1372 | ubi_err("paranoid check failed for PEB %d", pnum); | 1436 | ubi_err("paranoid check failed for PEB %d", pnum); |
1373 | ubi_msg("hex dump of the %d-%d region", offset, offset + len); | 1437 | ubi_msg("hex dump of the %d-%d region", offset, offset + len); |
1374 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, | 1438 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1); |
1375 | ubi->dbg_peb_buf, len, 1); | ||
1376 | err = -EINVAL; | 1439 | err = -EINVAL; |
1377 | error: | 1440 | error: |
1378 | ubi_dbg_dump_stack(); | 1441 | ubi_dbg_dump_stack(); |
1379 | mutex_unlock(&ubi->dbg_buf_mutex); | 1442 | vfree(buf); |
1380 | return err; | 1443 | return err; |
1381 | } | 1444 | } |
1382 | 1445 | ||
1383 | #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ | 1446 | #endif /* CONFIG_MTD_UBI_DEBUG */ |
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 79ca304fc4db..11eb8ef12485 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
@@ -39,32 +39,46 @@ | |||
39 | * eraseblocks are put to the @free list and the physical eraseblock to be | 39 | * eraseblocks are put to the @free list and the physical eraseblock to be |
40 | * erased are put to the @erase list. | 40 | * erased are put to the @erase list. |
41 | * | 41 | * |
42 | * About corruptions | ||
43 | * ~~~~~~~~~~~~~~~~~ | ||
44 | * | ||
45 | * UBI protects EC and VID headers with CRC-32 checksums, so it can detect | ||
46 | * whether the headers are corrupted or not. Sometimes UBI also protects the | ||
47 | * data with CRC-32, e.g., when it executes the atomic LEB change operation, or | ||
48 | * when it moves the contents of a PEB for wear-leveling purposes. | ||
49 | * | ||
42 | * UBI tries to distinguish between 2 types of corruptions. | 50 | * UBI tries to distinguish between 2 types of corruptions. |
43 | * 1. Corruptions caused by power cuts. These are harmless and expected | 51 | * |
44 | * corruptions and UBI tries to handle them gracefully, without printing too | 52 | * 1. Corruptions caused by power cuts. These are expected corruptions and UBI |
45 | * many warnings and error messages. The idea is that we do not lose | 53 | * tries to handle them gracefully, without printing too many warnings and |
46 | * important data in these case - we may lose only the data which was being | 54 | * error messages. The idea is that we do not lose important data in these case |
47 | * written to the media just before the power cut happened, and the upper | 55 | * - we may lose only the data which was being written to the media just before |
48 | * layers (e.g., UBIFS) are supposed to handle these situations. UBI puts | 56 | * the power cut happened, and the upper layers (e.g., UBIFS) are supposed to |
49 | * these PEBs to the head of the @erase list and they are scheduled for | 57 | * handle such data losses (e.g., by using the FS journal). |
50 | * erasure. | 58 | * |
59 | * When UBI detects a corruption (CRC-32 mismatch) in a PEB, and it looks like | ||
60 | * the reason is a power cut, UBI puts this PEB to the @erase list, and all | ||
61 | * PEBs in the @erase list are scheduled for erasure later. | ||
51 | * | 62 | * |
52 | * 2. Unexpected corruptions which are not caused by power cuts. During | 63 | * 2. Unexpected corruptions which are not caused by power cuts. During |
53 | * scanning, such PEBs are put to the @corr list and UBI preserves them. | 64 | * scanning, such PEBs are put to the @corr list and UBI preserves them. |
54 | * Obviously, this lessens the amount of available PEBs, and if at some | 65 | * Obviously, this lessens the amount of available PEBs, and if at some point |
55 | * point UBI runs out of free PEBs, it switches to R/O mode. UBI also loudly | 66 | * UBI runs out of free PEBs, it switches to R/O mode. UBI also loudly informs |
56 | * informs about such PEBs every time the MTD device is attached. | 67 | * about such PEBs every time the MTD device is attached. |
57 | * | 68 | * |
58 | * However, it is difficult to reliably distinguish between these types of | 69 | * However, it is difficult to reliably distinguish between these types of |
59 | * corruptions and UBI's strategy is as follows. UBI assumes (2.) if the VID | 70 | * corruptions and UBI's strategy is as follows. UBI assumes corruption type 2 |
60 | * header is corrupted and the data area does not contain all 0xFFs, and there | 71 | * if the VID header is corrupted and the data area does not contain all 0xFFs, |
61 | * were not bit-flips or integrity errors while reading the data area. Otherwise | 72 | * and there were no bit-flips or integrity errors while reading the data area. |
62 | * UBI assumes (1.). The assumptions are: | 73 | * Otherwise UBI assumes corruption type 1. So the decision criteria are as |
63 | * o if the data area contains only 0xFFs, there is no data, and it is safe | 74 | * follows. |
64 | * to just erase this PEB. | 75 | * o If the data area contains only 0xFFs, there is no data, and it is safe |
65 | * o if the data area has bit-flips and data integrity errors (ECC errors on | 76 | * to just erase this PEB - this is corruption type 1. |
77 | * o If the data area has bit-flips or data integrity errors (ECC errors on | ||
66 | * NAND), it is probably a PEB which was being erased when power cut | 78 | * NAND), it is probably a PEB which was being erased when power cut |
67 | * happened. | 79 | * happened, so this is corruption type 1. However, this is just a guess, |
80 | * which might be wrong. | ||
81 | * o Otherwise this it corruption type 2. | ||
68 | */ | 82 | */ |
69 | 83 | ||
70 | #include <linux/err.h> | 84 | #include <linux/err.h> |
@@ -74,7 +88,7 @@ | |||
74 | #include <linux/random.h> | 88 | #include <linux/random.h> |
75 | #include "ubi.h" | 89 | #include "ubi.h" |
76 | 90 | ||
77 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | 91 | #ifdef CONFIG_MTD_UBI_DEBUG |
78 | static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si); | 92 | static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si); |
79 | #else | 93 | #else |
80 | #define paranoid_check_si(ubi, si) 0 | 94 | #define paranoid_check_si(ubi, si) 0 |
@@ -115,7 +129,7 @@ static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, int to_head, | |||
115 | } else | 129 | } else |
116 | BUG(); | 130 | BUG(); |
117 | 131 | ||
118 | seb = kmalloc(sizeof(struct ubi_scan_leb), GFP_KERNEL); | 132 | seb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL); |
119 | if (!seb) | 133 | if (!seb) |
120 | return -ENOMEM; | 134 | return -ENOMEM; |
121 | 135 | ||
@@ -144,7 +158,7 @@ static int add_corrupted(struct ubi_scan_info *si, int pnum, int ec) | |||
144 | 158 | ||
145 | dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); | 159 | dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); |
146 | 160 | ||
147 | seb = kmalloc(sizeof(struct ubi_scan_leb), GFP_KERNEL); | 161 | seb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL); |
148 | if (!seb) | 162 | if (!seb) |
149 | return -ENOMEM; | 163 | return -ENOMEM; |
150 | 164 | ||
@@ -553,7 +567,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
553 | if (err) | 567 | if (err) |
554 | return err; | 568 | return err; |
555 | 569 | ||
556 | seb = kmalloc(sizeof(struct ubi_scan_leb), GFP_KERNEL); | 570 | seb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL); |
557 | if (!seb) | 571 | if (!seb) |
558 | return -ENOMEM; | 572 | return -ENOMEM; |
559 | 573 | ||
@@ -1152,9 +1166,15 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) | |||
1152 | si->volumes = RB_ROOT; | 1166 | si->volumes = RB_ROOT; |
1153 | 1167 | ||
1154 | err = -ENOMEM; | 1168 | err = -ENOMEM; |
1169 | si->scan_leb_slab = kmem_cache_create("ubi_scan_leb_slab", | ||
1170 | sizeof(struct ubi_scan_leb), | ||
1171 | 0, 0, NULL); | ||
1172 | if (!si->scan_leb_slab) | ||
1173 | goto out_si; | ||
1174 | |||
1155 | ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); | 1175 | ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); |
1156 | if (!ech) | 1176 | if (!ech) |
1157 | goto out_si; | 1177 | goto out_slab; |
1158 | 1178 | ||
1159 | vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); | 1179 | vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); |
1160 | if (!vidh) | 1180 | if (!vidh) |
@@ -1215,6 +1235,8 @@ out_vidh: | |||
1215 | ubi_free_vid_hdr(ubi, vidh); | 1235 | ubi_free_vid_hdr(ubi, vidh); |
1216 | out_ech: | 1236 | out_ech: |
1217 | kfree(ech); | 1237 | kfree(ech); |
1238 | out_slab: | ||
1239 | kmem_cache_destroy(si->scan_leb_slab); | ||
1218 | out_si: | 1240 | out_si: |
1219 | ubi_scan_destroy_si(si); | 1241 | ubi_scan_destroy_si(si); |
1220 | return ERR_PTR(err); | 1242 | return ERR_PTR(err); |
@@ -1223,11 +1245,12 @@ out_si: | |||
1223 | /** | 1245 | /** |
1224 | * destroy_sv - free the scanning volume information | 1246 | * destroy_sv - free the scanning volume information |
1225 | * @sv: scanning volume information | 1247 | * @sv: scanning volume information |
1248 | * @si: scanning information | ||
1226 | * | 1249 | * |
1227 | * This function destroys the volume RB-tree (@sv->root) and the scanning | 1250 | * This function destroys the volume RB-tree (@sv->root) and the scanning |
1228 | * volume information. | 1251 | * volume information. |
1229 | */ | 1252 | */ |
1230 | static void destroy_sv(struct ubi_scan_volume *sv) | 1253 | static void destroy_sv(struct ubi_scan_info *si, struct ubi_scan_volume *sv) |
1231 | { | 1254 | { |
1232 | struct ubi_scan_leb *seb; | 1255 | struct ubi_scan_leb *seb; |
1233 | struct rb_node *this = sv->root.rb_node; | 1256 | struct rb_node *this = sv->root.rb_node; |
@@ -1247,7 +1270,7 @@ static void destroy_sv(struct ubi_scan_volume *sv) | |||
1247 | this->rb_right = NULL; | 1270 | this->rb_right = NULL; |
1248 | } | 1271 | } |
1249 | 1272 | ||
1250 | kfree(seb); | 1273 | kmem_cache_free(si->scan_leb_slab, seb); |
1251 | } | 1274 | } |
1252 | } | 1275 | } |
1253 | kfree(sv); | 1276 | kfree(sv); |
@@ -1265,19 +1288,19 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si) | |||
1265 | 1288 | ||
1266 | list_for_each_entry_safe(seb, seb_tmp, &si->alien, u.list) { | 1289 | list_for_each_entry_safe(seb, seb_tmp, &si->alien, u.list) { |
1267 | list_del(&seb->u.list); | 1290 | list_del(&seb->u.list); |
1268 | kfree(seb); | 1291 | kmem_cache_free(si->scan_leb_slab, seb); |
1269 | } | 1292 | } |
1270 | list_for_each_entry_safe(seb, seb_tmp, &si->erase, u.list) { | 1293 | list_for_each_entry_safe(seb, seb_tmp, &si->erase, u.list) { |
1271 | list_del(&seb->u.list); | 1294 | list_del(&seb->u.list); |
1272 | kfree(seb); | 1295 | kmem_cache_free(si->scan_leb_slab, seb); |
1273 | } | 1296 | } |
1274 | list_for_each_entry_safe(seb, seb_tmp, &si->corr, u.list) { | 1297 | list_for_each_entry_safe(seb, seb_tmp, &si->corr, u.list) { |
1275 | list_del(&seb->u.list); | 1298 | list_del(&seb->u.list); |
1276 | kfree(seb); | 1299 | kmem_cache_free(si->scan_leb_slab, seb); |
1277 | } | 1300 | } |
1278 | list_for_each_entry_safe(seb, seb_tmp, &si->free, u.list) { | 1301 | list_for_each_entry_safe(seb, seb_tmp, &si->free, u.list) { |
1279 | list_del(&seb->u.list); | 1302 | list_del(&seb->u.list); |
1280 | kfree(seb); | 1303 | kmem_cache_free(si->scan_leb_slab, seb); |
1281 | } | 1304 | } |
1282 | 1305 | ||
1283 | /* Destroy the volume RB-tree */ | 1306 | /* Destroy the volume RB-tree */ |
@@ -1298,14 +1321,15 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si) | |||
1298 | rb->rb_right = NULL; | 1321 | rb->rb_right = NULL; |
1299 | } | 1322 | } |
1300 | 1323 | ||
1301 | destroy_sv(sv); | 1324 | destroy_sv(si, sv); |
1302 | } | 1325 | } |
1303 | } | 1326 | } |
1304 | 1327 | ||
1328 | kmem_cache_destroy(si->scan_leb_slab); | ||
1305 | kfree(si); | 1329 | kfree(si); |
1306 | } | 1330 | } |
1307 | 1331 | ||
1308 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | 1332 | #ifdef CONFIG_MTD_UBI_DEBUG |
1309 | 1333 | ||
1310 | /** | 1334 | /** |
1311 | * paranoid_check_si - check the scanning information. | 1335 | * paranoid_check_si - check the scanning information. |
@@ -1323,6 +1347,9 @@ static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) | |||
1323 | struct ubi_scan_leb *seb, *last_seb; | 1347 | struct ubi_scan_leb *seb, *last_seb; |
1324 | uint8_t *buf; | 1348 | uint8_t *buf; |
1325 | 1349 | ||
1350 | if (!(ubi_chk_flags & UBI_CHK_GEN)) | ||
1351 | return 0; | ||
1352 | |||
1326 | /* | 1353 | /* |
1327 | * At first, check that scanning information is OK. | 1354 | * At first, check that scanning information is OK. |
1328 | */ | 1355 | */ |
@@ -1575,4 +1602,4 @@ out: | |||
1575 | return -EINVAL; | 1602 | return -EINVAL; |
1576 | } | 1603 | } |
1577 | 1604 | ||
1578 | #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ | 1605 | #endif /* CONFIG_MTD_UBI_DEBUG */ |
diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index a3264f0bef2b..d48aef15ab5d 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h | |||
@@ -109,6 +109,7 @@ struct ubi_scan_volume { | |||
109 | * @mean_ec: mean erase counter value | 109 | * @mean_ec: mean erase counter value |
110 | * @ec_sum: a temporary variable used when calculating @mean_ec | 110 | * @ec_sum: a temporary variable used when calculating @mean_ec |
111 | * @ec_count: a temporary variable used when calculating @mean_ec | 111 | * @ec_count: a temporary variable used when calculating @mean_ec |
112 | * @scan_leb_slab: slab cache for &struct ubi_scan_leb objects | ||
112 | * | 113 | * |
113 | * This data structure contains the result of scanning and may be used by other | 114 | * This data structure contains the result of scanning and may be used by other |
114 | * UBI sub-systems to build final UBI data structures, further error-recovery | 115 | * UBI sub-systems to build final UBI data structures, further error-recovery |
@@ -134,6 +135,7 @@ struct ubi_scan_info { | |||
134 | int mean_ec; | 135 | int mean_ec; |
135 | uint64_t ec_sum; | 136 | uint64_t ec_sum; |
136 | int ec_count; | 137 | int ec_count; |
138 | struct kmem_cache *scan_leb_slab; | ||
137 | }; | 139 | }; |
138 | 140 | ||
139 | struct ubi_device; | 141 | struct ubi_device; |
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 0b0149c41fe3..49c864d175db 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/notifier.h> | 40 | #include <linux/notifier.h> |
41 | #include <linux/mtd/mtd.h> | 41 | #include <linux/mtd/mtd.h> |
42 | #include <linux/mtd/ubi.h> | 42 | #include <linux/mtd/ubi.h> |
43 | #include <asm/pgtable.h> | ||
43 | 44 | ||
44 | #include "ubi-media.h" | 45 | #include "ubi-media.h" |
45 | #include "scan.h" | 46 | #include "scan.h" |
@@ -387,8 +388,6 @@ struct ubi_wl_entry; | |||
387 | * @peb_buf2: another buffer of PEB size used for different purposes | 388 | * @peb_buf2: another buffer of PEB size used for different purposes |
388 | * @buf_mutex: protects @peb_buf1 and @peb_buf2 | 389 | * @buf_mutex: protects @peb_buf1 and @peb_buf2 |
389 | * @ckvol_mutex: serializes static volume checking when opening | 390 | * @ckvol_mutex: serializes static volume checking when opening |
390 | * @dbg_peb_buf: buffer of PEB size used for debugging | ||
391 | * @dbg_buf_mutex: protects @dbg_peb_buf | ||
392 | */ | 391 | */ |
393 | struct ubi_device { | 392 | struct ubi_device { |
394 | struct cdev cdev; | 393 | struct cdev cdev; |
@@ -470,10 +469,6 @@ struct ubi_device { | |||
470 | void *peb_buf2; | 469 | void *peb_buf2; |
471 | struct mutex buf_mutex; | 470 | struct mutex buf_mutex; |
472 | struct mutex ckvol_mutex; | 471 | struct mutex ckvol_mutex; |
473 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | ||
474 | void *dbg_peb_buf; | ||
475 | struct mutex dbg_buf_mutex; | ||
476 | #endif | ||
477 | }; | 472 | }; |
478 | 473 | ||
479 | extern struct kmem_cache *ubi_wl_entry_slab; | 474 | extern struct kmem_cache *ubi_wl_entry_slab; |
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index c47620dfc722..b79e0dea3632 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include "ubi.h" | 29 | #include "ubi.h" |
30 | 30 | ||
31 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | 31 | #ifdef CONFIG_MTD_UBI_DEBUG |
32 | static int paranoid_check_volumes(struct ubi_device *ubi); | 32 | static int paranoid_check_volumes(struct ubi_device *ubi); |
33 | #else | 33 | #else |
34 | #define paranoid_check_volumes(ubi) 0 | 34 | #define paranoid_check_volumes(ubi) 0 |
@@ -711,7 +711,7 @@ void ubi_free_volume(struct ubi_device *ubi, struct ubi_volume *vol) | |||
711 | volume_sysfs_close(vol); | 711 | volume_sysfs_close(vol); |
712 | } | 712 | } |
713 | 713 | ||
714 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | 714 | #ifdef CONFIG_MTD_UBI_DEBUG |
715 | 715 | ||
716 | /** | 716 | /** |
717 | * paranoid_check_volume - check volume information. | 717 | * paranoid_check_volume - check volume information. |
@@ -876,6 +876,9 @@ static int paranoid_check_volumes(struct ubi_device *ubi) | |||
876 | { | 876 | { |
877 | int i, err = 0; | 877 | int i, err = 0; |
878 | 878 | ||
879 | if (!(ubi_chk_flags & UBI_CHK_GEN)) | ||
880 | return 0; | ||
881 | |||
879 | for (i = 0; i < ubi->vtbl_slots; i++) { | 882 | for (i = 0; i < ubi->vtbl_slots; i++) { |
880 | err = paranoid_check_volume(ubi, i); | 883 | err = paranoid_check_volume(ubi, i); |
881 | if (err) | 884 | if (err) |
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 0b8141fc5c26..fd3bf770f518 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c | |||
@@ -62,7 +62,7 @@ | |||
62 | #include <asm/div64.h> | 62 | #include <asm/div64.h> |
63 | #include "ubi.h" | 63 | #include "ubi.h" |
64 | 64 | ||
65 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | 65 | #ifdef CONFIG_MTD_UBI_DEBUG |
66 | static void paranoid_vtbl_check(const struct ubi_device *ubi); | 66 | static void paranoid_vtbl_check(const struct ubi_device *ubi); |
67 | #else | 67 | #else |
68 | #define paranoid_vtbl_check(ubi) | 68 | #define paranoid_vtbl_check(ubi) |
@@ -868,7 +868,7 @@ out_free: | |||
868 | return err; | 868 | return err; |
869 | } | 869 | } |
870 | 870 | ||
871 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | 871 | #ifdef CONFIG_MTD_UBI_DEBUG |
872 | 872 | ||
873 | /** | 873 | /** |
874 | * paranoid_vtbl_check - check volume table. | 874 | * paranoid_vtbl_check - check volume table. |
@@ -876,10 +876,13 @@ out_free: | |||
876 | */ | 876 | */ |
877 | static void paranoid_vtbl_check(const struct ubi_device *ubi) | 877 | static void paranoid_vtbl_check(const struct ubi_device *ubi) |
878 | { | 878 | { |
879 | if (!(ubi_chk_flags & UBI_CHK_GEN)) | ||
880 | return; | ||
881 | |||
879 | if (vtbl_check(ubi, ubi->vtbl)) { | 882 | if (vtbl_check(ubi, ubi->vtbl)) { |
880 | ubi_err("paranoid check failed"); | 883 | ubi_err("paranoid check failed"); |
881 | BUG(); | 884 | BUG(); |
882 | } | 885 | } |
883 | } | 886 | } |
884 | 887 | ||
885 | #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ | 888 | #endif /* CONFIG_MTD_UBI_DEBUG */ |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 655bbbe415d9..b4cf57db2556 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -161,7 +161,7 @@ struct ubi_work { | |||
161 | int torture; | 161 | int torture; |
162 | }; | 162 | }; |
163 | 163 | ||
164 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | 164 | #ifdef CONFIG_MTD_UBI_DEBUG |
165 | static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec); | 165 | static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec); |
166 | static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, | 166 | static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, |
167 | struct rb_root *root); | 167 | struct rb_root *root); |
@@ -613,7 +613,7 @@ static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) | |||
613 | list_add_tail(&wrk->list, &ubi->works); | 613 | list_add_tail(&wrk->list, &ubi->works); |
614 | ubi_assert(ubi->works_count >= 0); | 614 | ubi_assert(ubi->works_count >= 0); |
615 | ubi->works_count += 1; | 615 | ubi->works_count += 1; |
616 | if (ubi->thread_enabled) | 616 | if (ubi->thread_enabled && !ubi_dbg_is_bgt_disabled()) |
617 | wake_up_process(ubi->bgt_thread); | 617 | wake_up_process(ubi->bgt_thread); |
618 | spin_unlock(&ubi->wl_lock); | 618 | spin_unlock(&ubi->wl_lock); |
619 | } | 619 | } |
@@ -1364,7 +1364,7 @@ int ubi_thread(void *u) | |||
1364 | 1364 | ||
1365 | spin_lock(&ubi->wl_lock); | 1365 | spin_lock(&ubi->wl_lock); |
1366 | if (list_empty(&ubi->works) || ubi->ro_mode || | 1366 | if (list_empty(&ubi->works) || ubi->ro_mode || |
1367 | !ubi->thread_enabled) { | 1367 | !ubi->thread_enabled || ubi_dbg_is_bgt_disabled()) { |
1368 | set_current_state(TASK_INTERRUPTIBLE); | 1368 | set_current_state(TASK_INTERRUPTIBLE); |
1369 | spin_unlock(&ubi->wl_lock); | 1369 | spin_unlock(&ubi->wl_lock); |
1370 | schedule(); | 1370 | schedule(); |
@@ -1561,7 +1561,7 @@ void ubi_wl_close(struct ubi_device *ubi) | |||
1561 | kfree(ubi->lookuptbl); | 1561 | kfree(ubi->lookuptbl); |
1562 | } | 1562 | } |
1563 | 1563 | ||
1564 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | 1564 | #ifdef CONFIG_MTD_UBI_DEBUG |
1565 | 1565 | ||
1566 | /** | 1566 | /** |
1567 | * paranoid_check_ec - make sure that the erase counter of a PEB is correct. | 1567 | * paranoid_check_ec - make sure that the erase counter of a PEB is correct. |
@@ -1578,6 +1578,9 @@ static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec) | |||
1578 | long long read_ec; | 1578 | long long read_ec; |
1579 | struct ubi_ec_hdr *ec_hdr; | 1579 | struct ubi_ec_hdr *ec_hdr; |
1580 | 1580 | ||
1581 | if (!(ubi_chk_flags & UBI_CHK_GEN)) | ||
1582 | return 0; | ||
1583 | |||
1581 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); | 1584 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); |
1582 | if (!ec_hdr) | 1585 | if (!ec_hdr) |
1583 | return -ENOMEM; | 1586 | return -ENOMEM; |
@@ -1614,6 +1617,9 @@ out_free: | |||
1614 | static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, | 1617 | static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, |
1615 | struct rb_root *root) | 1618 | struct rb_root *root) |
1616 | { | 1619 | { |
1620 | if (!(ubi_chk_flags & UBI_CHK_GEN)) | ||
1621 | return 0; | ||
1622 | |||
1617 | if (in_wl_tree(e, root)) | 1623 | if (in_wl_tree(e, root)) |
1618 | return 0; | 1624 | return 0; |
1619 | 1625 | ||
@@ -1636,6 +1642,9 @@ static int paranoid_check_in_pq(struct ubi_device *ubi, struct ubi_wl_entry *e) | |||
1636 | struct ubi_wl_entry *p; | 1642 | struct ubi_wl_entry *p; |
1637 | int i; | 1643 | int i; |
1638 | 1644 | ||
1645 | if (!(ubi_chk_flags & UBI_CHK_GEN)) | ||
1646 | return 0; | ||
1647 | |||
1639 | for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i) | 1648 | for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i) |
1640 | list_for_each_entry(p, &ubi->pq[i], u.list) | 1649 | list_for_each_entry(p, &ubi->pq[i], u.list) |
1641 | if (p == e) | 1650 | if (p == e) |
@@ -1646,4 +1655,5 @@ static int paranoid_check_in_pq(struct ubi_device *ubi, struct ubi_wl_entry *e) | |||
1646 | ubi_dbg_dump_stack(); | 1655 | ubi_dbg_dump_stack(); |
1647 | return -EINVAL; | 1656 | return -EINVAL; |
1648 | } | 1657 | } |
1649 | #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ | 1658 | |
1659 | #endif /* CONFIG_MTD_UBI_DEBUG */ | ||