diff options
Diffstat (limited to 'drivers/mtd/mtdpart.c')
-rw-r--r-- | drivers/mtd/mtdpart.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index f22aeccf01e7..77a7123a5c56 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c | |||
@@ -51,12 +51,21 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len, | |||
51 | size_t *retlen, u_char *buf) | 51 | size_t *retlen, u_char *buf) |
52 | { | 52 | { |
53 | struct mtd_part *part = PART(mtd); | 53 | struct mtd_part *part = PART(mtd); |
54 | int res; | ||
55 | |||
54 | if (from >= mtd->size) | 56 | if (from >= mtd->size) |
55 | len = 0; | 57 | len = 0; |
56 | else if (from + len > mtd->size) | 58 | else if (from + len > mtd->size) |
57 | len = mtd->size - from; | 59 | len = mtd->size - from; |
58 | return part->master->read (part->master, from + part->offset, | 60 | res = part->master->read (part->master, from + part->offset, |
59 | len, retlen, buf); | 61 | len, retlen, buf); |
62 | if (unlikely(res)) { | ||
63 | if (res == -EUCLEAN) | ||
64 | mtd->ecc_stats.corrected++; | ||
65 | if (res == -EBADMSG) | ||
66 | mtd->ecc_stats.failed++; | ||
67 | } | ||
68 | return res; | ||
60 | } | 69 | } |
61 | 70 | ||
62 | static int part_point (struct mtd_info *mtd, loff_t from, size_t len, | 71 | static int part_point (struct mtd_info *mtd, loff_t from, size_t len, |
@@ -82,12 +91,21 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from, | |||
82 | struct mtd_oob_ops *ops) | 91 | struct mtd_oob_ops *ops) |
83 | { | 92 | { |
84 | struct mtd_part *part = PART(mtd); | 93 | struct mtd_part *part = PART(mtd); |
94 | int res; | ||
85 | 95 | ||
86 | if (from >= mtd->size) | 96 | if (from >= mtd->size) |
87 | return -EINVAL; | 97 | return -EINVAL; |
88 | if (from + ops->len > mtd->size) | 98 | if (from + ops->len > mtd->size) |
89 | return -EINVAL; | 99 | return -EINVAL; |
90 | return part->master->read_oob(part->master, from + part->offset, ops); | 100 | res = part->master->read_oob(part->master, from + part->offset, ops); |
101 | |||
102 | if (unlikely(res)) { | ||
103 | if (res == -EUCLEAN) | ||
104 | mtd->ecc_stats.corrected++; | ||
105 | if (res == -EBADMSG) | ||
106 | mtd->ecc_stats.failed++; | ||
107 | } | ||
108 | return res; | ||
91 | } | 109 | } |
92 | 110 | ||
93 | static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, | 111 | static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, |
@@ -246,12 +264,17 @@ static int part_block_isbad (struct mtd_info *mtd, loff_t ofs) | |||
246 | static int part_block_markbad (struct mtd_info *mtd, loff_t ofs) | 264 | static int part_block_markbad (struct mtd_info *mtd, loff_t ofs) |
247 | { | 265 | { |
248 | struct mtd_part *part = PART(mtd); | 266 | struct mtd_part *part = PART(mtd); |
267 | int res; | ||
268 | |||
249 | if (!(mtd->flags & MTD_WRITEABLE)) | 269 | if (!(mtd->flags & MTD_WRITEABLE)) |
250 | return -EROFS; | 270 | return -EROFS; |
251 | if (ofs >= mtd->size) | 271 | if (ofs >= mtd->size) |
252 | return -EINVAL; | 272 | return -EINVAL; |
253 | ofs += part->offset; | 273 | ofs += part->offset; |
254 | return part->master->block_markbad(part->master, ofs); | 274 | res = part->master->block_markbad(part->master, ofs); |
275 | if (!res) | ||
276 | mtd->ecc_stats.badblocks++; | ||
277 | return res; | ||
255 | } | 278 | } |
256 | 279 | ||
257 | /* | 280 | /* |
@@ -436,6 +459,16 @@ int add_mtd_partitions(struct mtd_info *master, | |||
436 | } | 459 | } |
437 | 460 | ||
438 | slave->mtd.ecclayout = master->ecclayout; | 461 | slave->mtd.ecclayout = master->ecclayout; |
462 | if (master->block_isbad) { | ||
463 | uint32_t offs = 0; | ||
464 | |||
465 | while(offs < slave->mtd.size) { | ||
466 | if (master->block_isbad(master, | ||
467 | offs + slave->offset)) | ||
468 | slave->mtd.ecc_stats.badblocks++; | ||
469 | offs += slave->mtd.erasesize; | ||
470 | } | ||
471 | } | ||
439 | 472 | ||
440 | if(parts[i].mtdp) | 473 | if(parts[i].mtdp) |
441 | { /* store the object pointer (caller may or may not register it */ | 474 | { /* store the object pointer (caller may or may not register it */ |