aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2011-03-14 12:17:40 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2011-03-16 07:50:16 -0400
commit92d124f5314913a21f7fa98b22ee457dab171edd (patch)
tree8a8c187f12290424419f0a05caeb202cd73253cc /drivers/mtd/ubi
parentb342efd4a49cef9cf1a260c1814aad97722f38f8 (diff)
UBI: make self-checks dynamic
This patch adds a possibility to dynamically switch UBI self-checks on and off, instead of toggling them compile-time from the configuration menu. This is much more flexible, and consistent with UBIFS, and this also simplifies UBI Kconfig menu and the code. This patch introduces two levels of self-checks - general, which includes all self-checks which are relatively fast, and I/O, which includes write-verify checks and erase-verify checks, which are relatively slow and involve flash I/O. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers/mtd/ubi')
-rw-r--r--drivers/mtd/ubi/Kconfig.debug6
-rw-r--r--drivers/mtd/ubi/debug.c3
-rw-r--r--drivers/mtd/ubi/debug.h18
-rw-r--r--drivers/mtd/ubi/io.c27
-rw-r--r--drivers/mtd/ubi/scan.c9
-rw-r--r--drivers/mtd/ubi/vmt.c7
-rw-r--r--drivers/mtd/ubi/vtbl.c9
-rw-r--r--drivers/mtd/ubi/wl.c16
8 files changed, 70 insertions, 25 deletions
diff --git a/drivers/mtd/ubi/Kconfig.debug b/drivers/mtd/ubi/Kconfig.debug
index d40134e9d572..d8d33ddf567d 100644
--- a/drivers/mtd/ubi/Kconfig.debug
+++ b/drivers/mtd/ubi/Kconfig.debug
@@ -10,12 +10,6 @@ config MTD_UBI_DEBUG
10 10
11if MTD_UBI_DEBUG 11if MTD_UBI_DEBUG
12 12
13config MTD_UBI_DEBUG_PARANOID
14 bool "Extra self-checks"
15 help
16 This option enables extra checks in UBI code. Note this slows UBI down
17 significantly.
18
19config MTD_UBI_DEBUG_DISABLE_BGT 13config MTD_UBI_DEBUG_DISABLE_BGT
20 bool "Do not enable the UBI background thread" 14 bool "Do not enable the UBI background thread"
21 help 15 help
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index 8ae0bc7401ca..4c7a3f67156b 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -31,10 +31,13 @@
31#include <linux/moduleparam.h> 31#include <linux/moduleparam.h>
32 32
33unsigned int ubi_msg_flags; 33unsigned int ubi_msg_flags;
34unsigned int ubi_chk_flags;
34 35
35module_param_named(debug_msgs, ubi_msg_flags, uint, S_IRUGO | S_IWUSR); 36module_param_named(debug_msgs, ubi_msg_flags, uint, S_IRUGO | S_IWUSR);
37module_param_named(debug_chks, ubi_chk_flags, uint, S_IRUGO | S_IWUSR);
36 38
37MODULE_PARM_DESC(debug_msgs, "Debug message type flags"); 39MODULE_PARM_DESC(debug_msgs, "Debug message type flags");
40MODULE_PARM_DESC(debug_chks, "Debug check flags");
38 41
39/** 42/**
40 * ubi_dbg_dump_ec_hdr - dump an erase counter header. 43 * 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 bee6fa1e5147..2511b586490a 100644
--- a/drivers/mtd/ubi/debug.h
+++ b/drivers/mtd/ubi/debug.h
@@ -99,14 +99,22 @@ enum {
99/* Initialization and build messages */ 99/* Initialization and build messages */
100#define dbg_bld(fmt, ...) dbg_do_msg(UBI_MSG_BLD, fmt, ##__VA_ARGS__) 100#define dbg_bld(fmt, ...) dbg_do_msg(UBI_MSG_BLD, fmt, ##__VA_ARGS__)
101 101
102#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID 102extern unsigned int ubi_chk_flags;
103
104/*
105 * Debugging check flags.
106 *
107 * UBI_CHK_GEN: general checks
108 * UBI_CHK_IO: check writes and erases
109 */
110enum {
111 UBI_CHK_GEN = 0x1,
112 UBI_CHK_IO = 0x2,
113};
114
103int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); 115int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len);
104int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, 116int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
105 int offset, int len); 117 int offset, int len);
106#else
107#define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0
108#define ubi_dbg_check_write(ubi, buf, pnum, offset, len) 0
109#endif
110 118
111#ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT 119#ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT
112#define DBG_DISABLE_BGT 1 120#define DBG_DISABLE_BGT 1
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index b1ad1ec812ad..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
95static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum); 95static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum);
96static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum); 96static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum);
97static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, 97static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
@@ -1126,7 +1126,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
1126 return err; 1126 return err;
1127} 1127}
1128 1128
1129#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID 1129#ifdef CONFIG_MTD_UBI_DEBUG
1130 1130
1131/** 1131/**
1132 * 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.
@@ -1140,6 +1140,9 @@ static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum)
1140{ 1140{
1141 int err; 1141 int err;
1142 1142
1143 if (!(ubi_chk_flags & UBI_CHK_IO))
1144 return 0;
1145
1143 err = ubi_io_is_bad(ubi, pnum); 1146 err = ubi_io_is_bad(ubi, pnum);
1144 if (!err) 1147 if (!err)
1145 return err; 1148 return err;
@@ -1164,6 +1167,9 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
1164 int err; 1167 int err;
1165 uint32_t magic; 1168 uint32_t magic;
1166 1169
1170 if (!(ubi_chk_flags & UBI_CHK_IO))
1171 return 0;
1172
1167 magic = be32_to_cpu(ec_hdr->magic); 1173 magic = be32_to_cpu(ec_hdr->magic);
1168 if (magic != UBI_EC_HDR_MAGIC) { 1174 if (magic != UBI_EC_HDR_MAGIC) {
1169 ubi_err("bad magic %#08x, must be %#08x", 1175 ubi_err("bad magic %#08x, must be %#08x",
@@ -1199,6 +1205,9 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum)
1199 uint32_t crc, hdr_crc; 1205 uint32_t crc, hdr_crc;
1200 struct ubi_ec_hdr *ec_hdr; 1206 struct ubi_ec_hdr *ec_hdr;
1201 1207
1208 if (!(ubi_chk_flags & UBI_CHK_IO))
1209 return 0;
1210
1202 ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); 1211 ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS);
1203 if (!ec_hdr) 1212 if (!ec_hdr)
1204 return -ENOMEM; 1213 return -ENOMEM;
@@ -1240,6 +1249,9 @@ static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum,
1240 int err; 1249 int err;
1241 uint32_t magic; 1250 uint32_t magic;
1242 1251
1252 if (!(ubi_chk_flags & UBI_CHK_IO))
1253 return 0;
1254
1243 magic = be32_to_cpu(vid_hdr->magic); 1255 magic = be32_to_cpu(vid_hdr->magic);
1244 if (magic != UBI_VID_HDR_MAGIC) { 1256 if (magic != UBI_VID_HDR_MAGIC) {
1245 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",
@@ -1278,6 +1290,9 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
1278 struct ubi_vid_hdr *vid_hdr; 1290 struct ubi_vid_hdr *vid_hdr;
1279 void *p; 1291 void *p;
1280 1292
1293 if (!(ubi_chk_flags & UBI_CHK_IO))
1294 return 0;
1295
1281 vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); 1296 vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
1282 if (!vid_hdr) 1297 if (!vid_hdr)
1283 return -ENOMEM; 1298 return -ENOMEM;
@@ -1327,6 +1342,9 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
1327 void *buf1; 1342 void *buf1;
1328 loff_t addr = (loff_t)pnum * ubi->peb_size + offset; 1343 loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
1329 1344
1345 if (!(ubi_chk_flags & UBI_CHK_IO))
1346 return 0;
1347
1330 buf1 = __vmalloc(len, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); 1348 buf1 = __vmalloc(len, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL);
1331 if (!buf1) { 1349 if (!buf1) {
1332 ubi_err("cannot allocate memory to check writes"); 1350 ubi_err("cannot allocate memory to check writes");
@@ -1388,6 +1406,9 @@ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
1388 void *buf; 1406 void *buf;
1389 loff_t addr = (loff_t)pnum * ubi->peb_size + offset; 1407 loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
1390 1408
1409 if (!(ubi_chk_flags & UBI_CHK_IO))
1410 return 0;
1411
1391 buf = __vmalloc(len, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); 1412 buf = __vmalloc(len, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL);
1392 if (!buf) { 1413 if (!buf) {
1393 ubi_err("cannot allocate memory to check for 0xFFs"); 1414 ubi_err("cannot allocate memory to check for 0xFFs");
@@ -1422,4 +1443,4 @@ error:
1422 return err; 1443 return err;
1423} 1444}
1424 1445
1425#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 b65cc088fde5..11eb8ef12485 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -88,7 +88,7 @@
88#include <linux/random.h> 88#include <linux/random.h>
89#include "ubi.h" 89#include "ubi.h"
90 90
91#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID 91#ifdef CONFIG_MTD_UBI_DEBUG
92static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si); 92static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si);
93#else 93#else
94#define paranoid_check_si(ubi, si) 0 94#define paranoid_check_si(ubi, si) 0
@@ -1329,7 +1329,7 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si)
1329 kfree(si); 1329 kfree(si);
1330} 1330}
1331 1331
1332#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID 1332#ifdef CONFIG_MTD_UBI_DEBUG
1333 1333
1334/** 1334/**
1335 * paranoid_check_si - check the scanning information. 1335 * paranoid_check_si - check the scanning information.
@@ -1347,6 +1347,9 @@ static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si)
1347 struct ubi_scan_leb *seb, *last_seb; 1347 struct ubi_scan_leb *seb, *last_seb;
1348 uint8_t *buf; 1348 uint8_t *buf;
1349 1349
1350 if (!(ubi_chk_flags & UBI_CHK_GEN))
1351 return 0;
1352
1350 /* 1353 /*
1351 * At first, check that scanning information is OK. 1354 * At first, check that scanning information is OK.
1352 */ 1355 */
@@ -1599,4 +1602,4 @@ out:
1599 return -EINVAL; 1602 return -EINVAL;
1600} 1603}
1601 1604
1602#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ 1605#endif /* CONFIG_MTD_UBI_DEBUG */
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
32static int paranoid_check_volumes(struct ubi_device *ubi); 32static 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 fcdb7f65fe0b..0b81c5527357 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
66static void paranoid_vtbl_check(const struct ubi_device *ubi); 66static 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)
@@ -870,7 +870,7 @@ out_free:
870 return err; 870 return err;
871} 871}
872 872
873#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID 873#ifdef CONFIG_MTD_UBI_DEBUG
874 874
875/** 875/**
876 * paranoid_vtbl_check - check volume table. 876 * paranoid_vtbl_check - check volume table.
@@ -878,10 +878,13 @@ out_free:
878 */ 878 */
879static void paranoid_vtbl_check(const struct ubi_device *ubi) 879static void paranoid_vtbl_check(const struct ubi_device *ubi)
880{ 880{
881 if (!(ubi_chk_flags & UBI_CHK_GEN))
882 return;
883
881 if (vtbl_check(ubi, ubi->vtbl)) { 884 if (vtbl_check(ubi, ubi->vtbl)) {
882 ubi_err("paranoid check failed"); 885 ubi_err("paranoid check failed");
883 BUG(); 886 BUG();
884 } 887 }
885} 888}
886 889
887#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ 890#endif /* CONFIG_MTD_UBI_DEBUG */
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 655bbbe415d9..4e5529014c9b 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
165static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec); 165static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec);
166static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, 166static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e,
167 struct rb_root *root); 167 struct rb_root *root);
@@ -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:
1614static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, 1617static 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 */