aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/mtdpart.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/mtdpart.c')
-rw-r--r--drivers/mtd/mtdpart.c39
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
62static int part_point (struct mtd_info *mtd, loff_t from, size_t len, 71static 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
93static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 111static 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)
246static int part_block_markbad (struct mtd_info *mtd, loff_t ofs) 264static 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 */