diff options
| -rw-r--r-- | drivers/mtd/ubi/build.c | 6 | ||||
| -rw-r--r-- | drivers/mtd/ubi/debug.c | 2 | ||||
| -rw-r--r-- | drivers/mtd/ubi/debug.h | 7 | ||||
| -rw-r--r-- | drivers/mtd/ubi/io.c | 157 | ||||
| -rw-r--r-- | drivers/mtd/ubi/scan.c | 14 | ||||
| -rw-r--r-- | drivers/mtd/ubi/scan.h | 2 | ||||
| -rw-r--r-- | drivers/mtd/ubi/ubi-media.h | 12 | ||||
| -rw-r--r-- | drivers/mtd/ubi/ubi.h | 6 | ||||
| -rw-r--r-- | drivers/mtd/ubi/wl.c | 8 |
9 files changed, 116 insertions, 98 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 286ed594e5a0..e1f7d0a78b9d 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
| @@ -657,6 +657,11 @@ static int io_init(struct ubi_device *ubi) | |||
| 657 | if (ubi->mtd->block_isbad && ubi->mtd->block_markbad) | 657 | if (ubi->mtd->block_isbad && ubi->mtd->block_markbad) |
| 658 | ubi->bad_allowed = 1; | 658 | ubi->bad_allowed = 1; |
| 659 | 659 | ||
| 660 | if (ubi->mtd->type == MTD_NORFLASH) { | ||
| 661 | ubi_assert(ubi->mtd->writesize == 1); | ||
| 662 | ubi->nor_flash = 1; | ||
| 663 | } | ||
| 664 | |||
| 660 | ubi->min_io_size = ubi->mtd->writesize; | 665 | ubi->min_io_size = ubi->mtd->writesize; |
| 661 | ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; | 666 | ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; |
| 662 | 667 | ||
| @@ -996,6 +1001,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
| 996 | ubi_msg("number of PEBs reserved for bad PEB handling: %d", | 1001 | ubi_msg("number of PEBs reserved for bad PEB handling: %d", |
| 997 | ubi->beb_rsvd_pebs); | 1002 | ubi->beb_rsvd_pebs); |
| 998 | ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); | 1003 | ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); |
| 1004 | ubi_msg("image sequence number: %d", ubi->image_seq); | ||
| 999 | 1005 | ||
| 1000 | /* | 1006 | /* |
| 1001 | * The below lock makes sure we do not race with 'ubi_thread()' which | 1007 | * The below lock makes sure we do not race with 'ubi_thread()' which |
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index c0ed60e8ade9..54b0186915fb 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c | |||
| @@ -44,6 +44,8 @@ void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) | |||
| 44 | be32_to_cpu(ec_hdr->vid_hdr_offset)); | 44 | be32_to_cpu(ec_hdr->vid_hdr_offset)); |
| 45 | printk(KERN_DEBUG "\tdata_offset %d\n", | 45 | printk(KERN_DEBUG "\tdata_offset %d\n", |
| 46 | be32_to_cpu(ec_hdr->data_offset)); | 46 | be32_to_cpu(ec_hdr->data_offset)); |
| 47 | printk(KERN_DEBUG "\timage_seq %d\n", | ||
| 48 | be32_to_cpu(ec_hdr->image_seq)); | ||
| 47 | printk(KERN_DEBUG "\thdr_crc %#08x\n", | 49 | printk(KERN_DEBUG "\thdr_crc %#08x\n", |
| 48 | be32_to_cpu(ec_hdr->hdr_crc)); | 50 | be32_to_cpu(ec_hdr->hdr_crc)); |
| 49 | printk(KERN_DEBUG "erase counter header hexdump:\n"); | 51 | printk(KERN_DEBUG "erase counter header hexdump:\n"); |
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 13777e5beac9..a4da7a09b949 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 | ||
| 97 | int 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 |
| @@ -167,6 +173,7 @@ static inline int ubi_dbg_is_erase_failure(void) | |||
| 167 | #define ubi_dbg_is_bitflip() 0 | 173 | #define ubi_dbg_is_bitflip() 0 |
| 168 | #define ubi_dbg_is_write_failure() 0 | 174 | #define ubi_dbg_is_write_failure() 0 |
| 169 | #define ubi_dbg_is_erase_failure() 0 | 175 | #define ubi_dbg_is_erase_failure() 0 |
| 176 | #define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0 | ||
| 170 | 177 | ||
| 171 | #endif /* !CONFIG_MTD_UBI_DEBUG */ | 178 | #endif /* !CONFIG_MTD_UBI_DEBUG */ |
| 172 | #endif /* !__UBI_DEBUG_H__ */ | 179 | #endif /* !__UBI_DEBUG_H__ */ |
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index effaff28bab1..4cb69925d8d9 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c | |||
| @@ -98,17 +98,12 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, | |||
| 98 | static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); | 98 | static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); |
| 99 | static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, | 99 | static 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); |
| 101 | static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, | ||
| 102 | int len); | ||
| 103 | static int paranoid_check_empty(struct ubi_device *ubi, int pnum); | ||
| 104 | #else | 101 | #else |
| 105 | #define paranoid_check_not_bad(ubi, pnum) 0 | 102 | #define paranoid_check_not_bad(ubi, pnum) 0 |
| 106 | #define paranoid_check_peb_ec_hdr(ubi, pnum) 0 | 103 | #define paranoid_check_peb_ec_hdr(ubi, pnum) 0 |
| 107 | #define paranoid_check_ec_hdr(ubi, pnum, ec_hdr) 0 | 104 | #define paranoid_check_ec_hdr(ubi, pnum, ec_hdr) 0 |
| 108 | #define paranoid_check_peb_vid_hdr(ubi, pnum) 0 | 105 | #define paranoid_check_peb_vid_hdr(ubi, pnum) 0 |
| 109 | #define paranoid_check_vid_hdr(ubi, pnum, vid_hdr) 0 | 106 | #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 | ||
| 112 | #endif | 107 | #endif |
| 113 | 108 | ||
| 114 | /** | 109 | /** |
| @@ -244,7 +239,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, | |||
| 244 | return err > 0 ? -EINVAL : err; | 239 | return err > 0 ? -EINVAL : err; |
| 245 | 240 | ||
| 246 | /* The area we are writing to has to contain all 0xFF bytes */ | 241 | /* The area we are writing to has to contain all 0xFF bytes */ |
| 247 | err = paranoid_check_all_ff(ubi, pnum, offset, len); | 242 | err = ubi_dbg_check_all_ff(ubi, pnum, offset, len); |
| 248 | if (err) | 243 | if (err) |
| 249 | return err > 0 ? -EINVAL : err; | 244 | return err > 0 ? -EINVAL : err; |
| 250 | 245 | ||
| @@ -271,8 +266,8 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, | |||
| 271 | addr = (loff_t)pnum * ubi->peb_size + offset; | 266 | addr = (loff_t)pnum * ubi->peb_size + offset; |
| 272 | err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf); | 267 | err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf); |
| 273 | if (err) { | 268 | if (err) { |
| 274 | ubi_err("error %d while writing %d bytes to PEB %d:%d, written" | 269 | ubi_err("error %d while writing %d bytes to PEB %d:%d, written " |
| 275 | " %zd bytes", err, len, pnum, offset, written); | 270 | "%zd bytes", err, len, pnum, offset, written); |
| 276 | ubi_dbg_dump_stack(); | 271 | ubi_dbg_dump_stack(); |
| 277 | } else | 272 | } else |
| 278 | ubi_assert(written == len); | 273 | ubi_assert(written == len); |
| @@ -350,7 +345,7 @@ retry: | |||
| 350 | return -EIO; | 345 | return -EIO; |
| 351 | } | 346 | } |
| 352 | 347 | ||
| 353 | err = paranoid_check_all_ff(ubi, pnum, 0, ubi->peb_size); | 348 | err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size); |
| 354 | if (err) | 349 | if (err) |
| 355 | return err > 0 ? -EINVAL : err; | 350 | return err > 0 ? -EINVAL : err; |
| 356 | 351 | ||
| @@ -459,6 +454,54 @@ out: | |||
| 459 | } | 454 | } |
| 460 | 455 | ||
| 461 | /** | 456 | /** |
| 457 | * nor_erase_prepare - prepare a NOR flash PEB for erasure. | ||
| 458 | * @ubi: UBI device description object | ||
| 459 | * @pnum: physical eraseblock number to prepare | ||
| 460 | * | ||
| 461 | * NOR flash, or at least some of them, have peculiar embedded PEB erasure | ||
| 462 | * algorithm: the PEB is first filled with zeroes, then it is erased. And | ||
| 463 | * filling with zeroes starts from the end of the PEB. This was observed with | ||
| 464 | * Spansion S29GL512N NOR flash. | ||
| 465 | * | ||
| 466 | * This means that in case of a power cut we may end up with intact data at the | ||
| 467 | * beginning of the PEB, and all zeroes at the end of PEB. In other words, the | ||
| 468 | * EC and VID headers are OK, but a large chunk of data at the end of PEB is | ||
| 469 | * zeroed. This makes UBI mistakenly treat this PEB as used and associate it | ||
| 470 | * with an LEB, which leads to subsequent failures (e.g., UBIFS fails). | ||
| 471 | * | ||
| 472 | * This function is called before erasing NOR PEBs and it zeroes out EC and VID | ||
| 473 | * magic numbers in order to invalidate them and prevent the failures. Returns | ||
| 474 | * zero in case of success and a negative error code in case of failure. | ||
| 475 | */ | ||
| 476 | static int nor_erase_prepare(struct ubi_device *ubi, int pnum) | ||
| 477 | { | ||
| 478 | int err; | ||
| 479 | size_t written; | ||
| 480 | loff_t addr; | ||
| 481 | uint32_t data = 0; | ||
| 482 | |||
| 483 | addr = (loff_t)pnum * ubi->peb_size; | ||
| 484 | err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); | ||
| 485 | if (err) { | ||
| 486 | ubi_err("error %d while writing 4 bytes to PEB %d:%d, written " | ||
| 487 | "%zd bytes", err, pnum, 0, written); | ||
| 488 | ubi_dbg_dump_stack(); | ||
| 489 | return err; | ||
| 490 | } | ||
| 491 | |||
| 492 | addr += ubi->vid_hdr_aloffset; | ||
| 493 | err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); | ||
| 494 | if (err) { | ||
| 495 | ubi_err("error %d while writing 4 bytes to PEB %d:%d, written " | ||
| 496 | "%zd bytes", err, pnum, ubi->vid_hdr_aloffset, written); | ||
| 497 | ubi_dbg_dump_stack(); | ||
| 498 | return err; | ||
| 499 | } | ||
| 500 | |||
| 501 | return 0; | ||
| 502 | } | ||
| 503 | |||
| 504 | /** | ||
| 462 | * ubi_io_sync_erase - synchronously erase a physical eraseblock. | 505 | * ubi_io_sync_erase - synchronously erase a physical eraseblock. |
| 463 | * @ubi: UBI device description object | 506 | * @ubi: UBI device description object |
| 464 | * @pnum: physical eraseblock number to erase | 507 | * @pnum: physical eraseblock number to erase |
| @@ -489,6 +532,12 @@ int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture) | |||
| 489 | return -EROFS; | 532 | return -EROFS; |
| 490 | } | 533 | } |
| 491 | 534 | ||
| 535 | if (ubi->nor_flash) { | ||
| 536 | err = nor_erase_prepare(ubi, pnum); | ||
| 537 | if (err) | ||
| 538 | return err; | ||
| 539 | } | ||
| 540 | |||
| 492 | if (torture) { | 541 | if (torture) { |
| 493 | ret = torture_peb(ubi, pnum); | 542 | ret = torture_peb(ubi, pnum); |
| 494 | if (ret < 0) | 543 | if (ret < 0) |
| @@ -672,11 +721,6 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, | |||
| 672 | if (read_err != -EBADMSG && | 721 | if (read_err != -EBADMSG && |
| 673 | check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { | 722 | check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { |
| 674 | /* The physical eraseblock is supposedly empty */ | 723 | /* The physical eraseblock is supposedly empty */ |
| 675 | err = paranoid_check_all_ff(ubi, pnum, 0, | ||
| 676 | ubi->peb_size); | ||
| 677 | if (err) | ||
| 678 | return err > 0 ? UBI_IO_BAD_EC_HDR : err; | ||
| 679 | |||
| 680 | if (verbose) | 724 | if (verbose) |
| 681 | ubi_warn("no EC header found at PEB %d, " | 725 | ubi_warn("no EC header found at PEB %d, " |
| 682 | "only 0xFF bytes", pnum); | 726 | "only 0xFF bytes", pnum); |
| @@ -752,6 +796,7 @@ int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, | |||
| 752 | ec_hdr->version = UBI_VERSION; | 796 | ec_hdr->version = UBI_VERSION; |
| 753 | ec_hdr->vid_hdr_offset = cpu_to_be32(ubi->vid_hdr_offset); | 797 | ec_hdr->vid_hdr_offset = cpu_to_be32(ubi->vid_hdr_offset); |
| 754 | ec_hdr->data_offset = cpu_to_be32(ubi->leb_start); | 798 | ec_hdr->data_offset = cpu_to_be32(ubi->leb_start); |
| 799 | ec_hdr->image_seq = cpu_to_be32(ubi->image_seq); | ||
| 755 | crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); | 800 | crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); |
| 756 | ec_hdr->hdr_crc = cpu_to_be32(crc); | 801 | ec_hdr->hdr_crc = cpu_to_be32(crc); |
| 757 | 802 | ||
| @@ -947,15 +992,6 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, | |||
| 947 | if (read_err != -EBADMSG && | 992 | if (read_err != -EBADMSG && |
| 948 | check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) { | 993 | check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) { |
| 949 | /* The physical eraseblock is supposedly free */ | 994 | /* The physical eraseblock is supposedly free */ |
| 950 | |||
| 951 | /* | ||
| 952 | * The below is just a paranoid check, it has to be | ||
| 953 | * compiled out if paranoid checks are disabled. | ||
| 954 | */ | ||
| 955 | err = paranoid_check_empty(ubi, pnum); | ||
| 956 | if (err) | ||
| 957 | return err > 0 ? UBI_IO_BAD_VID_HDR : err; | ||
| 958 | |||
| 959 | if (verbose) | 995 | if (verbose) |
| 960 | ubi_warn("no VID header found at PEB %d, " | 996 | ubi_warn("no VID header found at PEB %d, " |
| 961 | "only 0xFF bytes", pnum); | 997 | "only 0xFF bytes", pnum); |
| @@ -1229,7 +1265,7 @@ exit: | |||
| 1229 | } | 1265 | } |
| 1230 | 1266 | ||
| 1231 | /** | 1267 | /** |
| 1232 | * paranoid_check_all_ff - check that a region of flash is empty. | 1268 | * ubi_dbg_check_all_ff - check that a region of flash is empty. |
| 1233 | * @ubi: UBI device description object | 1269 | * @ubi: UBI device description object |
| 1234 | * @pnum: the physical eraseblock number to check | 1270 | * @pnum: the physical eraseblock number to check |
| 1235 | * @offset: the starting offset within the physical eraseblock to check | 1271 | * @offset: the starting offset within the physical eraseblock to check |
| @@ -1239,8 +1275,7 @@ exit: | |||
| 1239 | * @offset of the physical eraseblock @pnum, %1 if not, and a negative error | 1275 | * @offset of the physical eraseblock @pnum, %1 if not, and a negative error |
| 1240 | * code if an error occurred. | 1276 | * code if an error occurred. |
| 1241 | */ | 1277 | */ |
| 1242 | static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, | 1278 | int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) |
| 1243 | int len) | ||
| 1244 | { | 1279 | { |
| 1245 | size_t read; | 1280 | size_t read; |
| 1246 | int err; | 1281 | int err; |
| @@ -1276,74 +1311,4 @@ error: | |||
| 1276 | return err; | 1311 | return err; |
| 1277 | } | 1312 | } |
| 1278 | 1313 | ||
| 1279 | /** | ||
| 1280 | * paranoid_check_empty - whether a PEB is empty. | ||
| 1281 | * @ubi: UBI device description object | ||
| 1282 | * @pnum: the physical eraseblock number to check | ||
| 1283 | * | ||
| 1284 | * This function makes sure PEB @pnum is empty, which means it contains only | ||
| 1285 | * %0xFF data bytes. Returns zero if the PEB is empty, %1 if not, and a | ||
| 1286 | * negative error code in case of failure. | ||
| 1287 | * | ||
| 1288 | * Empty PEBs have the EC header, and do not have the VID header. The caller of | ||
| 1289 | * this function should have already made sure the PEB does not have the VID | ||
| 1290 | * header. However, this function re-checks that, because it is possible that | ||
| 1291 | * the header and data has already been written to the PEB. | ||
| 1292 | * | ||
| 1293 | * Let's consider a possible scenario. Suppose there are 2 tasks - A and B. | ||
| 1294 | * Task A is in 'wear_leveling_worker()'. It is reading VID header of PEB X to | ||
| 1295 | * find which LEB it corresponds to. PEB X is currently unmapped, and has no | ||
| 1296 | * VID header. Task B is trying to write to PEB X. | ||
| 1297 | * | ||
| 1298 | * Task A: in 'ubi_io_read_vid_hdr()': reads the VID header from PEB X. The | ||
| 1299 | * read data contain all 0xFF bytes; | ||
| 1300 | * Task B: writes VID header and some data to PEB X; | ||
| 1301 | * Task A: assumes PEB X is empty, calls 'paranoid_check_empty()'. And if we | ||
| 1302 | * do not re-read the VID header, and do not cancel the checking if it | ||
| 1303 | * is there, we fail. | ||
| 1304 | */ | ||
| 1305 | static int paranoid_check_empty(struct ubi_device *ubi, int pnum) | ||
| 1306 | { | ||
| 1307 | int err, offs = ubi->vid_hdr_aloffset, len = ubi->vid_hdr_alsize; | ||
| 1308 | size_t read; | ||
| 1309 | uint32_t magic; | ||
| 1310 | const struct ubi_vid_hdr *vid_hdr; | ||
| 1311 | |||
| 1312 | mutex_lock(&ubi->dbg_buf_mutex); | ||
| 1313 | err = ubi->mtd->read(ubi->mtd, offs, len, &read, ubi->dbg_peb_buf); | ||
| 1314 | if (err && err != -EUCLEAN) { | ||
| 1315 | ubi_err("error %d while reading %d bytes from PEB %d:%d, " | ||
| 1316 | "read %zd bytes", err, len, pnum, offs, read); | ||
| 1317 | goto error; | ||
| 1318 | } | ||
| 1319 | |||
| 1320 | vid_hdr = ubi->dbg_peb_buf; | ||
| 1321 | magic = be32_to_cpu(vid_hdr->magic); | ||
| 1322 | if (magic == UBI_VID_HDR_MAGIC) | ||
| 1323 | /* The PEB contains VID header, so it is not empty */ | ||
| 1324 | goto out; | ||
| 1325 | |||
| 1326 | err = check_pattern(ubi->dbg_peb_buf, 0xFF, len); | ||
| 1327 | if (err == 0) { | ||
| 1328 | ubi_err("flash region at PEB %d:%d, length %d does not " | ||
| 1329 | "contain all 0xFF bytes", pnum, offs, len); | ||
| 1330 | goto fail; | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | out: | ||
| 1334 | mutex_unlock(&ubi->dbg_buf_mutex); | ||
| 1335 | return 0; | ||
| 1336 | |||
| 1337 | fail: | ||
| 1338 | ubi_err("paranoid check failed for PEB %d", pnum); | ||
| 1339 | ubi_msg("hex dump of the %d-%d region", offs, offs + len); | ||
| 1340 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, | ||
| 1341 | ubi->dbg_peb_buf, len, 1); | ||
| 1342 | err = 1; | ||
| 1343 | error: | ||
| 1344 | ubi_dbg_dump_stack(); | ||
| 1345 | mutex_unlock(&ubi->dbg_buf_mutex); | ||
| 1346 | return err; | ||
| 1347 | } | ||
| 1348 | |||
| 1349 | #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ | 1314 | #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ |
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index c3d653ba5ca0..f60895ee0aeb 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
| @@ -757,6 +757,8 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
| 757 | si->is_empty = 0; | 757 | si->is_empty = 0; |
| 758 | 758 | ||
| 759 | if (!ec_corr) { | 759 | if (!ec_corr) { |
| 760 | int image_seq; | ||
| 761 | |||
| 760 | /* Make sure UBI version is OK */ | 762 | /* Make sure UBI version is OK */ |
| 761 | if (ech->version != UBI_VERSION) { | 763 | if (ech->version != UBI_VERSION) { |
| 762 | ubi_err("this UBI version is %d, image version is %d", | 764 | ubi_err("this UBI version is %d, image version is %d", |
| @@ -778,6 +780,18 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
| 778 | ubi_dbg_dump_ec_hdr(ech); | 780 | ubi_dbg_dump_ec_hdr(ech); |
| 779 | return -EINVAL; | 781 | return -EINVAL; |
| 780 | } | 782 | } |
| 783 | |||
| 784 | image_seq = be32_to_cpu(ech->ec); | ||
| 785 | if (!si->image_seq_set) { | ||
| 786 | ubi->image_seq = image_seq; | ||
| 787 | si->image_seq_set = 1; | ||
| 788 | } else if (ubi->image_seq != image_seq) { | ||
| 789 | ubi_err("bad image sequence number %d in PEB %d, " | ||
| 790 | "expected %d", image_seq, pnum, ubi->image_seq); | ||
| 791 | ubi_dbg_dump_ec_hdr(ech); | ||
| 792 | return -EINVAL; | ||
| 793 | } | ||
| 794 | |||
| 781 | } | 795 | } |
| 782 | 796 | ||
| 783 | /* OK, we've done with the EC header, let's look at the VID header */ | 797 | /* OK, we've done with the EC header, let's look at the VID header */ |
diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 61df208e2f20..1017cf12def5 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h | |||
| @@ -102,6 +102,7 @@ struct ubi_scan_volume { | |||
| 102 | * @mean_ec: mean erase counter value | 102 | * @mean_ec: mean erase counter value |
| 103 | * @ec_sum: a temporary variable used when calculating @mean_ec | 103 | * @ec_sum: a temporary variable used when calculating @mean_ec |
| 104 | * @ec_count: a temporary variable used when calculating @mean_ec | 104 | * @ec_count: a temporary variable used when calculating @mean_ec |
| 105 | * @image_seq_set: indicates @ubi->image_seq is known | ||
| 105 | * | 106 | * |
| 106 | * This data structure contains the result of scanning and may be used by other | 107 | * This data structure contains the result of scanning and may be used by other |
| 107 | * UBI sub-systems to build final UBI data structures, further error-recovery | 108 | * UBI sub-systems to build final UBI data structures, further error-recovery |
| @@ -124,6 +125,7 @@ struct ubi_scan_info { | |||
| 124 | int mean_ec; | 125 | int mean_ec; |
| 125 | uint64_t ec_sum; | 126 | uint64_t ec_sum; |
| 126 | int ec_count; | 127 | int ec_count; |
| 128 | int image_seq_set; | ||
| 127 | }; | 129 | }; |
| 128 | 130 | ||
| 129 | struct ubi_device; | 131 | struct ubi_device; |
diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h index 8419fdccc79c..503ea9b27309 100644 --- a/drivers/mtd/ubi/ubi-media.h +++ b/drivers/mtd/ubi/ubi-media.h | |||
| @@ -129,6 +129,7 @@ enum { | |||
| 129 | * @ec: the erase counter | 129 | * @ec: the erase counter |
| 130 | * @vid_hdr_offset: where the VID header starts | 130 | * @vid_hdr_offset: where the VID header starts |
| 131 | * @data_offset: where the user data start | 131 | * @data_offset: where the user data start |
| 132 | * @image_seq: image sequence number | ||
| 132 | * @padding2: reserved for future, zeroes | 133 | * @padding2: reserved for future, zeroes |
| 133 | * @hdr_crc: erase counter header CRC checksum | 134 | * @hdr_crc: erase counter header CRC checksum |
| 134 | * | 135 | * |
| @@ -144,6 +145,14 @@ enum { | |||
| 144 | * volume identifier header and user data, relative to the beginning of the | 145 | * volume identifier header and user data, relative to the beginning of the |
| 145 | * physical eraseblock. These values have to be the same for all physical | 146 | * physical eraseblock. These values have to be the same for all physical |
| 146 | * eraseblocks. | 147 | * eraseblocks. |
| 148 | * | ||
| 149 | * The @image_seq field is used to validate a UBI image that has been prepared | ||
| 150 | * for a UBI device. The @image_seq value can be any value, but it must be the | ||
| 151 | * same on all eraseblocks. UBI will ensure that all new erase counter headers | ||
| 152 | * also contain this value, and will check the value when scanning at start-up. | ||
| 153 | * One way to make use of @image_seq is to increase its value by one every time | ||
| 154 | * an image is flashed over an existing image, then, if the flashing does not | ||
| 155 | * complete, UBI will detect the error when scanning. | ||
| 147 | */ | 156 | */ |
| 148 | struct ubi_ec_hdr { | 157 | struct ubi_ec_hdr { |
| 149 | __be32 magic; | 158 | __be32 magic; |
| @@ -152,7 +161,8 @@ struct ubi_ec_hdr { | |||
| 152 | __be64 ec; /* Warning: the current limit is 31-bit anyway! */ | 161 | __be64 ec; /* Warning: the current limit is 31-bit anyway! */ |
| 153 | __be32 vid_hdr_offset; | 162 | __be32 vid_hdr_offset; |
| 154 | __be32 data_offset; | 163 | __be32 data_offset; |
| 155 | __u8 padding2[36]; | 164 | __be32 image_seq; |
| 165 | __u8 padding2[32]; | ||
| 156 | __be32 hdr_crc; | 166 | __be32 hdr_crc; |
| 157 | } __attribute__ ((packed)); | 167 | } __attribute__ ((packed)); |
| 158 | 168 | ||
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 28acd133c997..6a5fe9633783 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
| @@ -301,6 +301,7 @@ struct ubi_wl_entry; | |||
| 301 | * @vol->readers, @vol->writers, @vol->exclusive, | 301 | * @vol->readers, @vol->writers, @vol->exclusive, |
| 302 | * @vol->ref_count, @vol->mapping and @vol->eba_tbl. | 302 | * @vol->ref_count, @vol->mapping and @vol->eba_tbl. |
| 303 | * @ref_count: count of references on the UBI device | 303 | * @ref_count: count of references on the UBI device |
| 304 | * @image_seq: image sequence number recorded on EC headers | ||
| 304 | * | 305 | * |
| 305 | * @rsvd_pebs: count of reserved physical eraseblocks | 306 | * @rsvd_pebs: count of reserved physical eraseblocks |
| 306 | * @avail_pebs: count of available physical eraseblocks | 307 | * @avail_pebs: count of available physical eraseblocks |
| @@ -372,6 +373,7 @@ struct ubi_wl_entry; | |||
| 372 | * @vid_hdr_shift: contains @vid_hdr_offset - @vid_hdr_aloffset | 373 | * @vid_hdr_shift: contains @vid_hdr_offset - @vid_hdr_aloffset |
| 373 | * @bad_allowed: whether the MTD device admits of bad physical eraseblocks or | 374 | * @bad_allowed: whether the MTD device admits of bad physical eraseblocks or |
| 374 | * not | 375 | * not |
| 376 | * @nor_flash: non-zero if working on top of NOR flash | ||
| 375 | * @mtd: MTD device descriptor | 377 | * @mtd: MTD device descriptor |
| 376 | * | 378 | * |
| 377 | * @peb_buf1: a buffer of PEB size used for different purposes | 379 | * @peb_buf1: a buffer of PEB size used for different purposes |
| @@ -390,6 +392,7 @@ struct ubi_device { | |||
| 390 | struct ubi_volume *volumes[UBI_MAX_VOLUMES+UBI_INT_VOL_COUNT]; | 392 | struct ubi_volume *volumes[UBI_MAX_VOLUMES+UBI_INT_VOL_COUNT]; |
| 391 | spinlock_t volumes_lock; | 393 | spinlock_t volumes_lock; |
| 392 | int ref_count; | 394 | int ref_count; |
| 395 | int image_seq; | ||
| 393 | 396 | ||
| 394 | int rsvd_pebs; | 397 | int rsvd_pebs; |
| 395 | int avail_pebs; | 398 | int avail_pebs; |
| @@ -452,7 +455,8 @@ struct ubi_device { | |||
| 452 | int vid_hdr_offset; | 455 | int vid_hdr_offset; |
| 453 | int vid_hdr_aloffset; | 456 | int vid_hdr_aloffset; |
| 454 | int vid_hdr_shift; | 457 | int vid_hdr_shift; |
| 455 | int bad_allowed; | 458 | unsigned int bad_allowed:1; |
| 459 | unsigned int nor_flash:1; | ||
| 456 | struct mtd_info *mtd; | 460 | struct mtd_info *mtd; |
| 457 | 461 | ||
| 458 | void *peb_buf1; | 462 | void *peb_buf1; |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 2b2472300610..600c7229d5cf 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 | ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum); | ||
| 467 | return err > 0 ? -EINVAL : err; | ||
| 468 | } | ||
| 469 | |||
| 462 | return e->pnum; | 470 | return e->pnum; |
| 463 | } | 471 | } |
| 464 | 472 | ||
