On Fri, Oct 26, 2012 at 12:16:36PM +0200, Wolfram Sang wrote: > To make that, we need to shift mtd_erase before mtd_ioctl. > ubi-utils need that, especially ubiformat. > > Signed-off-by: Wolfram Sang <w.s...@pengutronix.de> > --- > drivers/mtd/core.c | 68 > +++++++++++++++++++++++++++------------------------- > fs/devfs-core.c | 3 ++- > 2 files changed, 37 insertions(+), 34 deletions(-) > > diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c > index 7c323a1..aca4f13 100644 > --- a/drivers/mtd/core.c > +++ b/drivers/mtd/core.c > @@ -114,7 +114,37 @@ static ssize_t mtd_write(struct cdev* cdev, const void > *buf, size_t _count, > out: > return ret ? ret : _count; > } > -#endif > + > +static int mtd_erase(struct cdev *cdev, size_t count, loff_t offset) > +{ > + struct mtd_info *mtd = cdev->priv; > + struct erase_info erase; > + int ret; > + > + memset(&erase, 0, sizeof(erase)); > + erase.mtd = mtd; > + erase.addr = offset; > + erase.len = mtd->erasesize; > + > + while (count > 0) { > + dev_dbg(cdev->dev, "erase %d %d\n", erase.addr, erase.len); > + > + ret = mtd->block_isbad(mtd, erase.addr); > + if (ret > 0) { > + printf("Skipping bad block at 0x%08x\n", erase.addr); > + } else { > + ret = mtd->erase(mtd, &erase); > + if (ret) > + return ret; > + } > + > + erase.addr += mtd->erasesize; > + count -= count > mtd->erasesize ? mtd->erasesize : count; > + } > + > + return 0; > +} > +#endif /* CONFIG_MTD_WRITE */ > > int mtd_ioctl(struct cdev *cdev, int request, void *buf) > { > @@ -125,6 +155,7 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf) > struct mtd_ecc_stats *ecc = buf; > #endif > struct region_info_user *reg = buf; > + struct erase_info_user *ei = buf; > loff_t *offset = buf; > > switch (request) { > @@ -137,6 +168,9 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf) > dev_dbg(cdev->dev, "MEMSETBADBLOCK: 0x%08llx\n", *offset); > ret = mtd->block_markbad(mtd, *offset); > break; > + case MEMERASE: > + ret = mtd_erase(cdev, ei->length, ei->start + cdev->offset); > + break;
Please check this compiles with CONFIG_MTD_WRITE disabled. > #endif > case MEMGETINFO: > user->type = mtd->type; > @@ -174,38 +208,6 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf) > return ret; > } > > -#ifdef CONFIG_MTD_WRITE > -static int mtd_erase(struct cdev *cdev, size_t count, loff_t offset) > -{ > - struct mtd_info *mtd = cdev->priv; > - struct erase_info erase; > - int ret; > - > - memset(&erase, 0, sizeof(erase)); > - erase.mtd = mtd; > - erase.addr = offset; > - erase.len = mtd->erasesize; > - > - while (count > 0) { > - dev_dbg(cdev->dev, "erase %d %d\n", erase.addr, erase.len); > - > - ret = mtd->block_isbad(mtd, erase.addr); > - if (ret > 0) { > - printf("Skipping bad block at 0x%08x\n", erase.addr); > - } else { > - ret = mtd->erase(mtd, &erase); > - if (ret) > - return ret; > - } > - > - erase.addr += mtd->erasesize; > - count -= count > mtd->erasesize ? mtd->erasesize : count; > - } > - > - return 0; > -} > -#endif > - > static struct file_operations mtd_ops = { > .read = mtd_read, > #ifdef CONFIG_MTD_WRITE > diff --git a/fs/devfs-core.c b/fs/devfs-core.c > index 0d2f75a..262e0a2 100644 > --- a/fs/devfs-core.c > +++ b/fs/devfs-core.c > @@ -152,13 +152,14 @@ static int partition_ioctl(struct cdev *cdev, int > request, void *buf) > break; > #if (defined(CONFIG_NAND_ECC_HW) || defined(CONFIG_NAND_ECC_SOFT)) > case ECCGETSTATS: > +#endif > + case MEMERASE: > if (!cdev->ops->ioctl) { > ret = -EINVAL; > break; > } > ret = cdev->ops->ioctl(cdev, request, buf); > break; Are you sure this works for partitions? I assume you have to take cdev->offset into account like for example the MEMGETBADBLOCK ioctl does. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox