X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=drivers%2Fmtd%2Fmtdpart.c;h=633def3fb0875daf3a38bda7dea4cfb5d8adee77;hb=599a52d12629394236d785615808845823875868;hp=a93550ce797806d9bee045f1cbd708f3abbe66e7;hpb=0305c8659ff9cebabf469d5cd0ab8dc384857e10;p=linux-2.6-omap-h63xx.git diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index a93550ce797..633def3fb08 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -51,12 +50,21 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { struct mtd_part *part = PART(mtd); + int res; + if (from >= mtd->size) len = 0; else if (from + len > mtd->size) len = mtd->size - from; - return part->master->read (part->master, from + part->offset, + res = part->master->read (part->master, from + part->offset, len, retlen, buf); + if (unlikely(res)) { + if (res == -EUCLEAN) + mtd->ecc_stats.corrected++; + if (res == -EBADMSG) + mtd->ecc_stats.failed++; + } + return res; } static int part_point (struct mtd_info *mtd, loff_t from, size_t len, @@ -78,16 +86,25 @@ static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_ part->master->unpoint (part->master, addr, from + part->offset, len); } -static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) +static int part_read_oob(struct mtd_info *mtd, loff_t from, + struct mtd_oob_ops *ops) { struct mtd_part *part = PART(mtd); + int res; + if (from >= mtd->size) - len = 0; - else if (from + len > mtd->size) - len = mtd->size - from; - return part->master->read_oob (part->master, from + part->offset, - len, retlen, buf); + return -EINVAL; + if (ops->datbuf && from + ops->len > mtd->size) + return -EINVAL; + res = part->master->read_oob(part->master, from + part->offset, ops); + + if (unlikely(res)) { + if (res == -EUCLEAN) + mtd->ecc_stats.corrected++; + if (res == -EBADMSG) + mtd->ecc_stats.failed++; + } + return res; } static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, @@ -134,18 +151,19 @@ static int part_write (struct mtd_info *mtd, loff_t to, size_t len, len, retlen, buf); } -static int part_write_oob (struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) +static int part_write_oob(struct mtd_info *mtd, loff_t to, + struct mtd_oob_ops *ops) { struct mtd_part *part = PART(mtd); + if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; + if (to >= mtd->size) - len = 0; - else if (to + len > mtd->size) - len = mtd->size - to; - return part->master->write_oob (part->master, to + part->offset, - len, retlen, buf); + return -EINVAL; + if (ops->datbuf && to + ops->len > mtd->size) + return -EINVAL; + return part->master->write_oob(part->master, to + part->offset, ops); } static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, @@ -245,12 +263,17 @@ static int part_block_isbad (struct mtd_info *mtd, loff_t ofs) static int part_block_markbad (struct mtd_info *mtd, loff_t ofs) { struct mtd_part *part = PART(mtd); + int res; + if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; if (ofs >= mtd->size) return -EINVAL; ofs += part->offset; - return part->master->block_markbad(part->master, ofs); + res = part->master->block_markbad(part->master, ofs); + if (!res) + mtd->ecc_stats.badblocks++; + return res; } /* @@ -300,14 +323,13 @@ int add_mtd_partitions(struct mtd_info *master, for (i = 0; i < nbparts; i++) { /* allocate the partition structure */ - slave = kmalloc (sizeof(*slave), GFP_KERNEL); + slave = kzalloc (sizeof(*slave), GFP_KERNEL); if (!slave) { printk ("memory allocation error while creating partitions for \"%s\"\n", master->name); del_mtd_partitions(master); return -ENOMEM; } - memset(slave, 0, sizeof(*slave)); list_add(&slave->list, &mtd_partitions); /* set up the MTD object for this partition */ @@ -316,9 +338,7 @@ int add_mtd_partitions(struct mtd_info *master, slave->mtd.size = parts[i].size; slave->mtd.writesize = master->writesize; slave->mtd.oobsize = master->oobsize; - slave->mtd.oobavail = master->oobavail; - slave->mtd.ecctype = master->ecctype; - slave->mtd.eccsize = master->eccsize; + slave->mtd.subpage_sft = master->subpage_sft; slave->mtd.name = parts[i].name; slave->mtd.bank_size = master->bank_size; @@ -435,8 +455,17 @@ int add_mtd_partitions(struct mtd_info *master, parts[i].name); } - /* copy oobinfo from master */ - memcpy(&slave->mtd.oobinfo, &master->oobinfo, sizeof(slave->mtd.oobinfo)); + slave->mtd.ecclayout = master->ecclayout; + if (master->block_isbad) { + uint32_t offs = 0; + + while(offs < slave->mtd.size) { + if (master->block_isbad(master, + offs + slave->offset)) + slave->mtd.ecc_stats.badblocks++; + offs += slave->mtd.erasesize; + } + } if(parts[i].mtdp) { /* store the object pointer (caller may or may not register it */