aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-06-28 12:16:55 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-07-05 11:47:03 -0400
commit40a71a87fa8e0cb3ec0fca4d152263734b203eb2 (patch)
tree8bdd27304fc4d28c850c76f2b1f4a32c802612f8 /drivers/mtd/ubi
parent8e4a718ff38d8539938ec3421935904c27e00c39 (diff)
UBI: add empty eraseblocks verification
This patch adds code which makes sure eraseblocks contain all 0xFF bytes before starting using them. The verification is done only when debugging checks are enabled. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers/mtd/ubi')
-rw-r--r--drivers/mtd/ubi/debug.h6
-rw-r--r--drivers/mtd/ubi/io.c17
-rw-r--r--drivers/mtd/ubi/wl.c8
3 files changed, 21 insertions, 10 deletions
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
index 13777e5beac9..6fc7fda2ab91 100644
--- a/drivers/mtd/ubi/debug.h
+++ b/drivers/mtd/ubi/debug.h
@@ -93,6 +93,12 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req);
93#define UBI_IO_DEBUG 0 93#define UBI_IO_DEBUG 0
94#endif 94#endif
95 95
96#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
97int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len);
98#else
99#define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0
100#endif
101
96#ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT 102#ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT
97#define DBG_DISABLE_BGT 1 103#define DBG_DISABLE_BGT 1
98#else 104#else
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index effaff28bab1..6c5441e8791d 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -98,8 +98,6 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
98static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); 98static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum);
99static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, 99static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum,
100 const struct ubi_vid_hdr *vid_hdr); 100 const struct ubi_vid_hdr *vid_hdr);
101static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset,
102 int len);
103static int paranoid_check_empty(struct ubi_device *ubi, int pnum); 101static int paranoid_check_empty(struct ubi_device *ubi, int pnum);
104#else 102#else
105#define paranoid_check_not_bad(ubi, pnum) 0 103#define paranoid_check_not_bad(ubi, pnum) 0
@@ -107,7 +105,6 @@ static int paranoid_check_empty(struct ubi_device *ubi, int pnum);
107#define paranoid_check_ec_hdr(ubi, pnum, ec_hdr) 0 105#define paranoid_check_ec_hdr(ubi, pnum, ec_hdr) 0
108#define paranoid_check_peb_vid_hdr(ubi, pnum) 0 106#define paranoid_check_peb_vid_hdr(ubi, pnum) 0
109#define paranoid_check_vid_hdr(ubi, pnum, vid_hdr) 0 107#define paranoid_check_vid_hdr(ubi, pnum, vid_hdr) 0
110#define paranoid_check_all_ff(ubi, pnum, offset, len) 0
111#define paranoid_check_empty(ubi, pnum) 0 108#define paranoid_check_empty(ubi, pnum) 0
112#endif 109#endif
113 110
@@ -244,7 +241,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
244 return err > 0 ? -EINVAL : err; 241 return err > 0 ? -EINVAL : err;
245 242
246 /* The area we are writing to has to contain all 0xFF bytes */ 243 /* The area we are writing to has to contain all 0xFF bytes */
247 err = paranoid_check_all_ff(ubi, pnum, offset, len); 244 err = ubi_dbg_check_all_ff(ubi, pnum, offset, len);
248 if (err) 245 if (err)
249 return err > 0 ? -EINVAL : err; 246 return err > 0 ? -EINVAL : err;
250 247
@@ -350,7 +347,7 @@ retry:
350 return -EIO; 347 return -EIO;
351 } 348 }
352 349
353 err = paranoid_check_all_ff(ubi, pnum, 0, ubi->peb_size); 350 err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size);
354 if (err) 351 if (err)
355 return err > 0 ? -EINVAL : err; 352 return err > 0 ? -EINVAL : err;
356 353
@@ -672,8 +669,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
672 if (read_err != -EBADMSG && 669 if (read_err != -EBADMSG &&
673 check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { 670 check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) {
674 /* The physical eraseblock is supposedly empty */ 671 /* The physical eraseblock is supposedly empty */
675 err = paranoid_check_all_ff(ubi, pnum, 0, 672 err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size);
676 ubi->peb_size);
677 if (err) 673 if (err)
678 return err > 0 ? UBI_IO_BAD_EC_HDR : err; 674 return err > 0 ? UBI_IO_BAD_EC_HDR : err;
679 675
@@ -1229,7 +1225,7 @@ exit:
1229} 1225}
1230 1226
1231/** 1227/**
1232 * paranoid_check_all_ff - check that a region of flash is empty. 1228 * ubi_dbg_check_all_ff - check that a region of flash is empty.
1233 * @ubi: UBI device description object 1229 * @ubi: UBI device description object
1234 * @pnum: the physical eraseblock number to check 1230 * @pnum: the physical eraseblock number to check
1235 * @offset: the starting offset within the physical eraseblock to check 1231 * @offset: the starting offset within the physical eraseblock to check
@@ -1239,13 +1235,14 @@ exit:
1239 * @offset of the physical eraseblock @pnum, %1 if not, and a negative error 1235 * @offset of the physical eraseblock @pnum, %1 if not, and a negative error
1240 * code if an error occurred. 1236 * code if an error occurred.
1241 */ 1237 */
1242static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, 1238int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
1243 int len)
1244{ 1239{
1245 size_t read; 1240 size_t read;
1246 int err; 1241 int err;
1247 loff_t addr = (loff_t)pnum * ubi->peb_size + offset; 1242 loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
1248 1243
1244 ubi_assert(!mutex_is_locked(&ubi->dbg_buf_mutex));
1245
1249 mutex_lock(&ubi->dbg_buf_mutex); 1246 mutex_lock(&ubi->dbg_buf_mutex);
1250 err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf); 1247 err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf);
1251 if (err && err != -EUCLEAN) { 1248 if (err && err != -EUCLEAN) {
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 2b2472300610..e4be446e05ed 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -459,6 +459,14 @@ retry:
459 dbg_wl("PEB %d EC %d", e->pnum, e->ec); 459 dbg_wl("PEB %d EC %d", e->pnum, e->ec);
460 prot_queue_add(ubi, e); 460 prot_queue_add(ubi, e);
461 spin_unlock(&ubi->wl_lock); 461 spin_unlock(&ubi->wl_lock);
462
463 err = ubi_dbg_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset,
464 ubi->peb_size - ubi->vid_hdr_aloffset);
465 if (err) {
466 dbg_err("new PEB does not contain all 0xFF bytes");
467 return err > 0 ? -EINVAL : err;
468 }
469
462 return e->pnum; 470 return e->pnum;
463} 471}
464 472