X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fmtd%2Fmtdpart.c;h=c3369e0aa5c34c01b5611c6af68993291b85c057;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=460d56f70bec9a317dff600355b3df7b9ea37b47;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 460d56f70..c3369e0aa 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -5,7 +5,7 @@ * * This code is GPL * - * $Id: mtdpart.c,v 1.41 2003/06/18 14:53:02 dwmw2 Exp $ + * $Id: mtdpart.c,v 1.50 2004/08/10 16:18:34 dwmw2 Exp $ * * 02-21-2002 Thomas Gleixner * added support for read_oob, write_oob @@ -182,7 +182,7 @@ static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t l len, retlen, buf); } -static int part_writev (struct mtd_info *mtd, const struct iovec *vecs, +static int part_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen) { struct mtd_part *part = PART(mtd); @@ -197,7 +197,7 @@ static int part_writev (struct mtd_info *mtd, const struct iovec *vecs, NULL, &mtd->oobinfo); } -static int part_readv (struct mtd_info *mtd, struct iovec *vecs, +static int part_readv (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen) { struct mtd_part *part = PART(mtd); @@ -210,7 +210,7 @@ static int part_readv (struct mtd_info *mtd, struct iovec *vecs, NULL, &mtd->oobinfo); } -static int part_writev_ecc (struct mtd_info *mtd, const struct iovec *vecs, +static int part_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) { @@ -224,7 +224,7 @@ static int part_writev_ecc (struct mtd_info *mtd, const struct iovec *vecs, eccbuf, oobsel); } -static int part_readv_ecc (struct mtd_info *mtd, struct iovec *vecs, +static int part_readv_ecc (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) { @@ -239,13 +239,29 @@ static int part_readv_ecc (struct mtd_info *mtd, struct iovec *vecs, static int 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; - return part->master->erase(part->master, instr); + ret = part->master->erase(part->master, instr); + return ret; +} + +void mtd_erase_callback(struct erase_info *instr) +{ + if (instr->mtd->erase == part_erase) { + struct mtd_part *part = PART(instr->mtd); + + if (instr->fail_addr != 0xffffffff) + instr->fail_addr -= part->offset; + instr->addr -= part->offset; + } + if (instr->callback) + instr->callback(instr); } +EXPORT_SYMBOL_GPL(mtd_erase_callback); static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len) { @@ -281,6 +297,26 @@ static void part_resume(struct mtd_info *mtd) part->master->resume(part->master); } +static int 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 part->master->block_isbad(part->master, ofs); +} + +static int part_block_markbad (struct mtd_info *mtd, loff_t ofs) +{ + struct mtd_part *part = PART(mtd); + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + if (ofs >= mtd->size) + return -EINVAL; + ofs += part->offset; + return part->master->block_markbad(part->master, ofs); +} + /* * This function unregisters and destroy all slave MTD objects which are * attached to the given master MTD object. @@ -316,7 +352,7 @@ int del_mtd_partitions(struct mtd_info *master) */ int add_mtd_partitions(struct mtd_info *master, - struct mtd_partition *parts, + const struct mtd_partition *parts, int nbparts) { struct mtd_part *slave; @@ -391,6 +427,10 @@ int add_mtd_partitions(struct mtd_info *master, slave->mtd.lock = part_lock; if (master->unlock) slave->mtd.unlock = part_unlock; + if (master->block_isbad) + slave->mtd.block_isbad = part_block_isbad; + if (master->block_markbad) + slave->mtd.block_markbad = part_block_markbad; slave->mtd.erase = part_erase; slave->master = master; slave->offset = parts[i].offset; @@ -461,6 +501,9 @@ 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)); + if(parts[i].mtdp) { /* store the object pointer (caller may or may not register it */ *parts[i].mtdp = &slave->mtd;