aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/mtdconcat.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/mtdconcat.c')
-rw-r--r--drivers/mtd/mtdconcat.c51
1 files changed, 35 insertions, 16 deletions
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 3c8d5e6fa010..1fea631b5852 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -56,7 +56,7 @@ concat_read(struct mtd_info *mtd, loff_t from, size_t len,
56 size_t * retlen, u_char * buf) 56 size_t * retlen, u_char * buf)
57{ 57{
58 struct mtd_concat *concat = CONCAT(mtd); 58 struct mtd_concat *concat = CONCAT(mtd);
59 int ret = 0, err = -EINVAL; 59 int ret = 0, err;
60 int i; 60 int i;
61 61
62 *retlen = 0; 62 *retlen = 0;
@@ -80,28 +80,29 @@ concat_read(struct mtd_info *mtd, loff_t from, size_t len,
80 80
81 err = subdev->read(subdev, from, size, &retsize, buf); 81 err = subdev->read(subdev, from, size, &retsize, buf);
82 82
83 if (err && (err != -EBADMSG) && (err != -EUCLEAN))
84 break;
85
86 /* Save information about bitflips! */ 83 /* Save information about bitflips! */
87 if (err) { 84 if (unlikely(err)) {
88 if (err == -EBADMSG) 85 if (err == -EBADMSG) {
89 ret = err; 86 mtd->ecc_stats.failed++;
90 else if (!ret)
91 ret = err; 87 ret = err;
92 err = 0; 88 } else if (err == -EUCLEAN) {
89 mtd->ecc_stats.corrected++;
90 /* Do not overwrite -EBADMSG !! */
91 if (!ret)
92 ret = err;
93 } else
94 return err;
93 } 95 }
94 96
95 *retlen += retsize; 97 *retlen += retsize;
96 len -= size; 98 len -= size;
97 if (len == 0) 99 if (len == 0)
98 break; 100 return ret;
99 101
100 err = -EINVAL;
101 buf += size; 102 buf += size;
102 from = 0; 103 from = 0;
103 } 104 }
104 return err ? err : ret; 105 return -EINVAL;
105} 106}
106 107
107static int 108static int
@@ -244,7 +245,7 @@ concat_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
244{ 245{
245 struct mtd_concat *concat = CONCAT(mtd); 246 struct mtd_concat *concat = CONCAT(mtd);
246 struct mtd_oob_ops devops = *ops; 247 struct mtd_oob_ops devops = *ops;
247 int i, err; 248 int i, err, ret = 0;
248 249
249 ops->retlen = 0; 250 ops->retlen = 0;
250 251
@@ -262,12 +263,24 @@ concat_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
262 263
263 err = subdev->read_oob(subdev, from, &devops); 264 err = subdev->read_oob(subdev, from, &devops);
264 ops->retlen += devops.retlen; 265 ops->retlen += devops.retlen;
265 if (err) 266
266 return err; 267 /* Save information about bitflips! */
268 if (unlikely(err)) {
269 if (err == -EBADMSG) {
270 mtd->ecc_stats.failed++;
271 ret = err;
272 } else if (err == -EUCLEAN) {
273 mtd->ecc_stats.corrected++;
274 /* Do not overwrite -EBADMSG !! */
275 if (!ret)
276 ret = err;
277 } else
278 return err;
279 }
267 280
268 devops.len = ops->len - ops->retlen; 281 devops.len = ops->len - ops->retlen;
269 if (!devops.len) 282 if (!devops.len)
270 return 0; 283 return ret;
271 284
272 if (devops.datbuf) 285 if (devops.datbuf)
273 devops.datbuf += devops.retlen; 286 devops.datbuf += devops.retlen;
@@ -655,6 +668,8 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs)
655 } 668 }
656 669
657 err = subdev->block_markbad(subdev, ofs); 670 err = subdev->block_markbad(subdev, ofs);
671 if (!err)
672 mtd->ecc_stats.badblocks++;
658 break; 673 break;
659 } 674 }
660 675
@@ -717,6 +732,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
717 if (subdev[0]->block_markbad) 732 if (subdev[0]->block_markbad)
718 concat->mtd.block_markbad = concat_block_markbad; 733 concat->mtd.block_markbad = concat_block_markbad;
719 734
735 concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks;
736
720 concat->subdev[0] = subdev[0]; 737 concat->subdev[0] = subdev[0];
721 738
722 for (i = 1; i < num_devs; i++) { 739 for (i = 1; i < num_devs; i++) {
@@ -744,6 +761,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
744 subdev[i]->flags & MTD_WRITEABLE; 761 subdev[i]->flags & MTD_WRITEABLE;
745 } 762 }
746 concat->mtd.size += subdev[i]->size; 763 concat->mtd.size += subdev[i]->size;
764 concat->mtd.ecc_stats.badblocks +=
765 subdev[i]->ecc_stats.badblocks;
747 if (concat->mtd.writesize != subdev[i]->writesize || 766 if (concat->mtd.writesize != subdev[i]->writesize ||
748 concat->mtd.oobsize != subdev[i]->oobsize || 767 concat->mtd.oobsize != subdev[i]->oobsize ||
749 concat->mtd.ecctype != subdev[i]->ecctype || 768 concat->mtd.ecctype != subdev[i]->ecctype ||