diff options
Diffstat (limited to 'drivers/mtd/ubi/io.c')
-rw-r--r-- | drivers/mtd/ubi/io.c | 66 |
1 files changed, 29 insertions, 37 deletions
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index ba5bc4a5379e..52476d884c48 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c | |||
@@ -98,8 +98,8 @@ 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(const struct ubi_device *ubi, int pnum, | 101 | static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, |
102 | int offset, int len); | 102 | int len); |
103 | #else | 103 | #else |
104 | #define paranoid_check_not_bad(ubi, pnum) 0 | 104 | #define paranoid_check_not_bad(ubi, pnum) 0 |
105 | #define paranoid_check_peb_ec_hdr(ubi, pnum) 0 | 105 | #define paranoid_check_peb_ec_hdr(ubi, pnum) 0 |
@@ -202,8 +202,8 @@ retry: | |||
202 | * Note, in case of an error, it is possible that something was still written | 202 | * Note, in case of an error, it is possible that something was still written |
203 | * to the flash media, but may be some garbage. | 203 | * to the flash media, but may be some garbage. |
204 | */ | 204 | */ |
205 | int ubi_io_write(const struct ubi_device *ubi, const void *buf, int pnum, | 205 | int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, |
206 | int offset, int len) | 206 | int len) |
207 | { | 207 | { |
208 | int err; | 208 | int err; |
209 | size_t written; | 209 | size_t written; |
@@ -285,7 +285,7 @@ static void erase_callback(struct erase_info *ei) | |||
285 | * zero in case of success and a negative error code in case of failure. If | 285 | * zero in case of success and a negative error code in case of failure. If |
286 | * %-EIO is returned, the physical eraseblock most probably went bad. | 286 | * %-EIO is returned, the physical eraseblock most probably went bad. |
287 | */ | 287 | */ |
288 | static int do_sync_erase(const struct ubi_device *ubi, int pnum) | 288 | static int do_sync_erase(struct ubi_device *ubi, int pnum) |
289 | { | 289 | { |
290 | int err, retries = 0; | 290 | int err, retries = 0; |
291 | struct erase_info ei; | 291 | struct erase_info ei; |
@@ -377,29 +377,25 @@ static uint8_t patterns[] = {0xa5, 0x5a, 0x0}; | |||
377 | * test, a positive number of erase operations done if the test was | 377 | * test, a positive number of erase operations done if the test was |
378 | * successfully passed, and other negative error codes in case of other errors. | 378 | * successfully passed, and other negative error codes in case of other errors. |
379 | */ | 379 | */ |
380 | static int torture_peb(const struct ubi_device *ubi, int pnum) | 380 | static int torture_peb(struct ubi_device *ubi, int pnum) |
381 | { | 381 | { |
382 | void *buf; | ||
383 | int err, i, patt_count; | 382 | int err, i, patt_count; |
384 | 383 | ||
385 | buf = vmalloc(ubi->peb_size); | ||
386 | if (!buf) | ||
387 | return -ENOMEM; | ||
388 | |||
389 | patt_count = ARRAY_SIZE(patterns); | 384 | patt_count = ARRAY_SIZE(patterns); |
390 | ubi_assert(patt_count > 0); | 385 | ubi_assert(patt_count > 0); |
391 | 386 | ||
387 | mutex_lock(&ubi->buf_mutex); | ||
392 | for (i = 0; i < patt_count; i++) { | 388 | for (i = 0; i < patt_count; i++) { |
393 | err = do_sync_erase(ubi, pnum); | 389 | err = do_sync_erase(ubi, pnum); |
394 | if (err) | 390 | if (err) |
395 | goto out; | 391 | goto out; |
396 | 392 | ||
397 | /* Make sure the PEB contains only 0xFF bytes */ | 393 | /* Make sure the PEB contains only 0xFF bytes */ |
398 | err = ubi_io_read(ubi, buf, pnum, 0, ubi->peb_size); | 394 | err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); |
399 | if (err) | 395 | if (err) |
400 | goto out; | 396 | goto out; |
401 | 397 | ||
402 | err = check_pattern(buf, 0xFF, ubi->peb_size); | 398 | err = check_pattern(ubi->peb_buf1, 0xFF, ubi->peb_size); |
403 | if (err == 0) { | 399 | if (err == 0) { |
404 | ubi_err("erased PEB %d, but a non-0xFF byte found", | 400 | ubi_err("erased PEB %d, but a non-0xFF byte found", |
405 | pnum); | 401 | pnum); |
@@ -408,17 +404,17 @@ static int torture_peb(const struct ubi_device *ubi, int pnum) | |||
408 | } | 404 | } |
409 | 405 | ||
410 | /* Write a pattern and check it */ | 406 | /* Write a pattern and check it */ |
411 | memset(buf, patterns[i], ubi->peb_size); | 407 | memset(ubi->peb_buf1, patterns[i], ubi->peb_size); |
412 | err = ubi_io_write(ubi, buf, pnum, 0, ubi->peb_size); | 408 | err = ubi_io_write(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); |
413 | if (err) | 409 | if (err) |
414 | goto out; | 410 | goto out; |
415 | 411 | ||
416 | memset(buf, ~patterns[i], ubi->peb_size); | 412 | memset(ubi->peb_buf1, ~patterns[i], ubi->peb_size); |
417 | err = ubi_io_read(ubi, buf, pnum, 0, ubi->peb_size); | 413 | err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); |
418 | if (err) | 414 | if (err) |
419 | goto out; | 415 | goto out; |
420 | 416 | ||
421 | err = check_pattern(buf, patterns[i], ubi->peb_size); | 417 | err = check_pattern(ubi->peb_buf1, patterns[i], ubi->peb_size); |
422 | if (err == 0) { | 418 | if (err == 0) { |
423 | ubi_err("pattern %x checking failed for PEB %d", | 419 | ubi_err("pattern %x checking failed for PEB %d", |
424 | patterns[i], pnum); | 420 | patterns[i], pnum); |
@@ -430,6 +426,7 @@ static int torture_peb(const struct ubi_device *ubi, int pnum) | |||
430 | err = patt_count; | 426 | err = patt_count; |
431 | 427 | ||
432 | out: | 428 | out: |
429 | mutex_unlock(&ubi->buf_mutex); | ||
433 | if (err == UBI_IO_BITFLIPS || err == -EBADMSG) { | 430 | if (err == UBI_IO_BITFLIPS || err == -EBADMSG) { |
434 | /* | 431 | /* |
435 | * If a bit-flip or data integrity error was detected, the test | 432 | * If a bit-flip or data integrity error was detected, the test |
@@ -440,7 +437,6 @@ out: | |||
440 | pnum); | 437 | pnum); |
441 | err = -EIO; | 438 | err = -EIO; |
442 | } | 439 | } |
443 | vfree(buf); | ||
444 | return err; | 440 | return err; |
445 | } | 441 | } |
446 | 442 | ||
@@ -460,7 +456,7 @@ out: | |||
460 | * codes in case of other errors. Note, %-EIO means that the physical | 456 | * codes in case of other errors. Note, %-EIO means that the physical |
461 | * eraseblock is bad. | 457 | * eraseblock is bad. |
462 | */ | 458 | */ |
463 | int ubi_io_sync_erase(const struct ubi_device *ubi, int pnum, int torture) | 459 | int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture) |
464 | { | 460 | { |
465 | int err, ret = 0; | 461 | int err, ret = 0; |
466 | 462 | ||
@@ -617,7 +613,7 @@ bad: | |||
617 | * o %UBI_IO_PEB_EMPTY if the physical eraseblock is empty; | 613 | * o %UBI_IO_PEB_EMPTY if the physical eraseblock is empty; |
618 | * o a negative error code in case of failure. | 614 | * o a negative error code in case of failure. |
619 | */ | 615 | */ |
620 | int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum, | 616 | int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, |
621 | struct ubi_ec_hdr *ec_hdr, int verbose) | 617 | struct ubi_ec_hdr *ec_hdr, int verbose) |
622 | { | 618 | { |
623 | int err, read_err = 0; | 619 | int err, read_err = 0; |
@@ -723,7 +719,7 @@ int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum, | |||
723 | * case of failure. If %-EIO is returned, the physical eraseblock most probably | 719 | * case of failure. If %-EIO is returned, the physical eraseblock most probably |
724 | * went bad. | 720 | * went bad. |
725 | */ | 721 | */ |
726 | int ubi_io_write_ec_hdr(const struct ubi_device *ubi, int pnum, | 722 | int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, |
727 | struct ubi_ec_hdr *ec_hdr) | 723 | struct ubi_ec_hdr *ec_hdr) |
728 | { | 724 | { |
729 | int err; | 725 | int err; |
@@ -889,7 +885,7 @@ bad: | |||
889 | * header there); | 885 | * header there); |
890 | * o a negative error code in case of failure. | 886 | * o a negative error code in case of failure. |
891 | */ | 887 | */ |
892 | int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum, | 888 | int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, |
893 | struct ubi_vid_hdr *vid_hdr, int verbose) | 889 | struct ubi_vid_hdr *vid_hdr, int verbose) |
894 | { | 890 | { |
895 | int err, read_err = 0; | 891 | int err, read_err = 0; |
@@ -996,7 +992,7 @@ int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum, | |||
996 | * case of failure. If %-EIO is returned, the physical eraseblock probably went | 992 | * case of failure. If %-EIO is returned, the physical eraseblock probably went |
997 | * bad. | 993 | * bad. |
998 | */ | 994 | */ |
999 | int ubi_io_write_vid_hdr(const struct ubi_device *ubi, int pnum, | 995 | int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, |
1000 | struct ubi_vid_hdr *vid_hdr) | 996 | struct ubi_vid_hdr *vid_hdr) |
1001 | { | 997 | { |
1002 | int err; | 998 | int err; |
@@ -1219,44 +1215,40 @@ exit: | |||
1219 | * @offset of the physical eraseblock @pnum, %1 if not, and a negative error | 1215 | * @offset of the physical eraseblock @pnum, %1 if not, and a negative error |
1220 | * code if an error occurred. | 1216 | * code if an error occurred. |
1221 | */ | 1217 | */ |
1222 | static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum, | 1218 | static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, |
1223 | int offset, int len) | 1219 | int len) |
1224 | { | 1220 | { |
1225 | size_t read; | 1221 | size_t read; |
1226 | int err; | 1222 | int err; |
1227 | void *buf; | ||
1228 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; | 1223 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; |
1229 | 1224 | ||
1230 | buf = vmalloc(len); | 1225 | mutex_lock(&ubi->dbg_buf_mutex); |
1231 | if (!buf) | 1226 | err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf); |
1232 | return -ENOMEM; | ||
1233 | memset(buf, 0, len); | ||
1234 | |||
1235 | err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); | ||
1236 | if (err && err != -EUCLEAN) { | 1227 | if (err && err != -EUCLEAN) { |
1237 | ubi_err("error %d while reading %d bytes from PEB %d:%d, " | 1228 | ubi_err("error %d while reading %d bytes from PEB %d:%d, " |
1238 | "read %zd bytes", err, len, pnum, offset, read); | 1229 | "read %zd bytes", err, len, pnum, offset, read); |
1239 | goto error; | 1230 | goto error; |
1240 | } | 1231 | } |
1241 | 1232 | ||
1242 | err = check_pattern(buf, 0xFF, len); | 1233 | err = check_pattern(ubi->dbg_peb_buf, 0xFF, len); |
1243 | if (err == 0) { | 1234 | if (err == 0) { |
1244 | ubi_err("flash region at PEB %d:%d, length %d does not " | 1235 | ubi_err("flash region at PEB %d:%d, length %d does not " |
1245 | "contain all 0xFF bytes", pnum, offset, len); | 1236 | "contain all 0xFF bytes", pnum, offset, len); |
1246 | goto fail; | 1237 | goto fail; |
1247 | } | 1238 | } |
1239 | mutex_unlock(&ubi->dbg_buf_mutex); | ||
1248 | 1240 | ||
1249 | vfree(buf); | ||
1250 | return 0; | 1241 | return 0; |
1251 | 1242 | ||
1252 | fail: | 1243 | fail: |
1253 | ubi_err("paranoid check failed for PEB %d", pnum); | 1244 | ubi_err("paranoid check failed for PEB %d", pnum); |
1254 | dbg_msg("hex dump of the %d-%d region", offset, offset + len); | 1245 | dbg_msg("hex dump of the %d-%d region", offset, offset + len); |
1255 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, buf, len, 1); | 1246 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, |
1247 | ubi->dbg_peb_buf, len, 1); | ||
1256 | err = 1; | 1248 | err = 1; |
1257 | error: | 1249 | error: |
1258 | ubi_dbg_dump_stack(); | 1250 | ubi_dbg_dump_stack(); |
1259 | vfree(buf); | 1251 | mutex_unlock(&ubi->dbg_buf_mutex); |
1260 | return err; | 1252 | return err; |
1261 | } | 1253 | } |
1262 | 1254 | ||