9
0
Fork 0

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:
Alexander Aring 2012-01-05 12:03:29 +01:00 committed by Sascha Hauer
parent 9ee3fb9e4a
commit 364c3aadfd
2 changed files with 60 additions and 10 deletions

View File

@ -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

View File

@ -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)