diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c index f25863d..ab4babd 100644 --- a/drivers/mtd/core.c +++ b/drivers/mtd/core.c @@ -116,17 +116,22 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf) { + int ret = 0; struct mtd_info *mtd = cdev->priv; struct mtd_info_user *user = buf; + struct mtd_ecc_stats *ecc = buf; + struct region_info_user *reg = buf; switch (request) { case MEMGETBADBLOCK: dev_dbg(cdev->dev, "MEMGETBADBLOCK: 0x%08lx\n", (off_t)buf); - return mtd->block_isbad(mtd, (off_t)buf); + ret = mtd->block_isbad(mtd, (off_t)buf); + break; #ifdef CONFIG_MTD_WRITE case MEMSETBADBLOCK: dev_dbg(cdev->dev, "MEMSETBADBLOCK: 0x%08lx\n", (off_t)buf); - return mtd->block_markbad(mtd, (off_t)buf); + ret = mtd->block_markbad(mtd, (off_t)buf); + break; #endif case MEMGETINFO: user->type = mtd->type; @@ -138,10 +143,28 @@ /* The below fields are obsolete */ user->ecctype = -1; user->eccsize = 0; - return 0; + break; +#if (defined(CONFIG_NAND_ECC_HW) || defined(CONFIG_NAND_ECC_SOFT)) + case ECCGETSTATS: + ecc->corrected = mtd->ecc_stats.corrected; + ecc->failed = mtd->ecc_stats.failed; + ecc->badblocks = mtd->ecc_stats.badblocks; + ecc->bbtblocks = mtd->ecc_stats.bbtblocks; + break; +#endif + case MEMGETREGIONINFO: + if (cdev->mtd) { + reg->offset = cdev->offset; + reg->erasesize = cdev->mtd->erasesize; + reg->numblocks = cdev->size/reg->erasesize; + reg->regionindex = cdev->mtd->index; + } + break; + default: + ret = -EINVAL; } - return 0; + return ret; } #ifdef CONFIG_MTD_WRITE diff --git a/fs/devfs-core.c b/fs/devfs-core.c index 5f22ce7..e11fea2 100644 --- a/fs/devfs-core.c +++ b/fs/devfs-core.c @@ -103,15 +103,18 @@ static int partition_ioctl(struct cdev *cdev, int request, void *buf) { + int ret = 0; size_t offset; struct mtd_info_user *user = buf; + struct region_info_user *reg = buf; switch (request) { case MEMSETBADBLOCK: case MEMGETBADBLOCK: offset = (off_t)buf; offset += cdev->offset; - return cdev->ops->ioctl(cdev, request, (void *)offset); + ret = cdev->ops->ioctl(cdev, request, (void *)offset); + break; case MEMGETINFO: if (cdev->mtd) { user->type = cdev->mtd->type; @@ -123,14 +126,38 @@ /* The below fields are obsolete */ user->ecctype = -1; user->eccsize = 0; - return 0; + break; } - if (!cdev->ops->ioctl) - return -EINVAL; - return cdev->ops->ioctl(cdev, request, buf); + if (!cdev->ops->ioctl) { + ret = -EINVAL; + break; + } + ret = cdev->ops->ioctl(cdev, request, buf); + break; +#if (defined(CONFIG_NAND_ECC_HW) || defined(CONFIG_NAND_ECC_SOFT)) + case ECCGETSTATS: + if (!cdev->ops->ioctl) { + ret = -EINVAL; + break; + } + ret = cdev->ops->ioctl(cdev, request, buf); + break; +#endif +#ifdef CONFIG_PARTITION + case MEMGETREGIONINFO: + if (cdev->mtd) { + reg->offset = cdev->offset; + reg->erasesize = cdev->mtd->erasesize; + reg->numblocks = cdev->size/reg->erasesize; + reg->regionindex = cdev->mtd->index; + } + break; +#endif default: - return -EINVAL; + ret = -EINVAL; } + + return ret; } int cdev_ioctl(struct cdev *cdev, int request, void *buf)