diff --git a/drivers/mtd/partition.c b/drivers/mtd/partition.c index 85f486d0e..d2045cc9c 100644 --- a/drivers/mtd/partition.c +++ b/drivers/mtd/partition.c @@ -4,29 +4,19 @@ #include #include -struct mtd_part { - struct mtd_info mtd; - struct mtd_info *master; - uint64_t offset; - struct list_head list; -}; - -#define PART(x) ((struct mtd_part *)(x)) - static int mtd_part_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { - struct mtd_part *part = PART(mtd); struct mtd_ecc_stats stats; int res; - stats = part->master->ecc_stats; + stats = mtd->master->ecc_stats; if (from >= mtd->size) len = 0; else if (from + len > mtd->size) len = mtd->size - from; - res = part->master->read(part->master, from + part->offset, + res = mtd->master->read(mtd->master, from + mtd->master_offset, len, retlen, buf); return res; } @@ -34,57 +24,52 @@ static int mtd_part_read(struct mtd_info *mtd, loff_t from, size_t len, static int mtd_part_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { - 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(part->master, to + part->offset, + return mtd->master->write(mtd->master, to + mtd->master_offset, len, retlen, buf); } static int mtd_part_erase(struct mtd_info *mtd, struct erase_info *instr) { - struct mtd_part *part = PART(mtd); int ret; if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; if (instr->addr >= mtd->size) return -EINVAL; - instr->addr += part->offset; - ret = part->master->erase(part->master, instr); + instr->addr += mtd->master_offset; + ret = mtd->master->erase(mtd->master, instr); if (ret) { if (instr->fail_addr != 0xffffffff) - instr->fail_addr -= part->offset; - instr->addr -= part->offset; + instr->fail_addr -= mtd->master_offset; + instr->addr -= mtd->master_offset; } return ret; } static int mtd_part_block_isbad(struct mtd_info *mtd, loff_t ofs) { - struct mtd_part *part = PART(mtd); if (ofs >= mtd->size) return -EINVAL; - ofs += part->offset; - return mtd_block_isbad(part->master, ofs); + ofs += mtd->master_offset; + return mtd_block_isbad(mtd->master, ofs); } static int mtd_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; - res = part->master->block_markbad(part->master, ofs); + ofs += mtd->master_offset; + res = mtd->master->block_markbad(mtd->master, ofs); if (!res) mtd->ecc_stats.badblocks++; return res; @@ -93,14 +78,12 @@ static int mtd_part_block_markbad(struct mtd_info *mtd, loff_t ofs) struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset, size_t size, unsigned long flags, const char *name) { - struct mtd_part *slave; - struct mtd_info *slave_mtd; + struct mtd_info *part; int start = 0, end = 0, i; - slave = xzalloc(sizeof(*slave)); - slave_mtd = &slave->mtd; + part = xzalloc(sizeof(*part)); - memcpy(slave_mtd, mtd, sizeof(*slave)); + memcpy(part, mtd, sizeof(*part)); /* * find the number of eraseregions the partition includes. @@ -118,26 +101,29 @@ struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset, size_t si end = i; } - slave_mtd->numeraseregions = end - start; + part->numeraseregions = end - start; - slave_mtd->read = mtd_part_read; - slave_mtd->write = mtd_part_write; - slave_mtd->erase = mtd_part_erase; - slave_mtd->block_isbad = mtd->block_isbad ? mtd_part_block_isbad : NULL; - slave_mtd->block_markbad = mtd->block_markbad ? mtd_part_block_markbad : NULL; - slave_mtd->size = size; - slave_mtd->name = strdup(name); + part->read = mtd_part_read; + part->write = mtd_part_write; + part->erase = mtd_part_erase; + part->block_isbad = mtd->block_isbad ? mtd_part_block_isbad : NULL; + part->block_markbad = mtd->block_markbad ? mtd_part_block_markbad : NULL; + part->size = size; + part->name = strdup(name); - slave->offset = offset; - slave->master = mtd; + part->master_offset = offset; + part->master = mtd; - return slave_mtd; + return part; } -void mtd_del_partition(struct mtd_info *mtd) +int mtd_del_partition(struct mtd_info *part) { - struct mtd_part *part = PART(mtd); + if (!part->master) + return -EINVAL; - free(mtd->name); + free(part->name); free(part); + + return 0; } diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 402e4978b..e02204a50 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -217,6 +217,9 @@ struct mtd_info { /* If true erasing bad blocks is allowed, this is set via a device parameter */ bool allow_erasebad; int p_allow_erasebad; + + struct mtd_info *master; + uint32_t master_offset; }; int mtd_erase(struct mtd_info *mtd, struct erase_info *instr); @@ -272,7 +275,7 @@ struct mtd_notifier { struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset, size_t size, unsigned long flags, const char *name); -void mtd_del_partition(struct mtd_info *mtd); +int mtd_del_partition(struct mtd_info *mtd); extern void register_mtd_user (struct mtd_notifier *new); extern int unregister_mtd_user (struct mtd_notifier *old);