ioctl: add support for ECCGETSTATS and MEMGETREGIONINFO
Support added for ioctl of ECCGETSTATS and MEMGETREGIONINFO. Fix default handling in core.c to return -EINVAL, if request was unknown. Signed-off-by: Alexander Aring <a.aring@phytec.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
9ee3fb9e4a
commit
364c3aadfd
|
@ -116,17 +116,22 @@ out:
|
|||
|
||||
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 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf)
|
|||
/* 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
|
||||
|
|
|
@ -103,15 +103,18 @@ int cdev_flush(struct cdev *cdev)
|
|||
|
||||
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 @@ static int partition_ioctl(struct cdev *cdev, int request, void *buf)
|
|||
/* 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)
|
||||
|
|
Loading…
Reference in New Issue