fs/partition: Support BIOC_PARTINFO

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2021-08-12 21:18:27 +08:00 committed by Gustavo Henrique Nihei
parent 1dfcc6ab49
commit 162893cc3b

View File

@ -43,6 +43,7 @@
struct part_struct_s struct part_struct_s
{ {
FAR struct inode *parent; FAR struct inode *parent;
size_t sectorsize;
size_t firstsector; size_t firstsector;
size_t nsectors; size_t nsectors;
}; };
@ -214,40 +215,58 @@ static int part_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
FAR struct inode *parent = dev->parent; FAR struct inode *parent = dev->parent;
int ret = -ENOTTY; int ret = -ENOTTY;
if (parent->u.i_bops->ioctl) switch (cmd)
{ {
if (cmd == MTDIOC_PROTECT || cmd == MTDIOC_UNPROTECT) case BIOC_PARTINFO:
{ {
FAR struct mtd_protect_s *prot = FAR struct partition_info_s *info =
(FAR struct mtd_protect_s *)ptr_arg; (FAR struct partition_info_s *)ptr_arg;
if (info != NULL)
prot->startblock += dev->firstsector;
}
ret = parent->u.i_bops->ioctl(parent, cmd, arg);
if (ret >= 0)
{
if (cmd == BIOC_XIPBASE)
{ {
FAR void **base = (FAR void **)ptr_arg; info->magic = 0;
struct geometry geo; info->numsectors = dev->nsectors;
info->sectorsize = dev->sectorsize;
info->startsector = dev->firstsector;
ret = parent->u.i_bops->geometry(parent, &geo); strncpy(info->parent, dev->parent->i_name, NAME_MAX);
if (ret >= 0)
{
*(FAR uint8_t *)base +=
dev->firstsector * geo.geo_sectorsize;
}
}
else if (cmd == MTDIOC_GEOMETRY)
{
FAR struct mtd_geometry_s *mgeo =
(FAR struct mtd_geometry_s *)ptr_arg;
uint32_t blkper = mgeo->erasesize / mgeo->blocksize;
mgeo->neraseblocks = dev->nsectors / blkper; ret = OK;
} }
} }
break;
default:
if (parent->u.i_bops->ioctl)
{
if (cmd == MTDIOC_PROTECT || cmd == MTDIOC_UNPROTECT)
{
FAR struct mtd_protect_s *prot =
(FAR struct mtd_protect_s *)ptr_arg;
prot->startblock += dev->firstsector;
}
ret = parent->u.i_bops->ioctl(parent, cmd, arg);
if (ret >= 0)
{
if (cmd == BIOC_XIPBASE)
{
FAR void **base = (FAR void **)ptr_arg;
*(FAR uint8_t *)base +=
dev->firstsector * dev->sectorsize;
}
else if (cmd == MTDIOC_GEOMETRY)
{
FAR struct mtd_geometry_s *mgeo =
(FAR struct mtd_geometry_s *)ptr_arg;
uint32_t blkper = mgeo->erasesize / mgeo->blocksize;
mgeo->neraseblocks = dev->nsectors / blkper;
}
}
}
break;
} }
return ret; return ret;
@ -302,6 +321,7 @@ int register_blockpartition(FAR const char *partition,
size_t firstsector, size_t nsectors) size_t firstsector, size_t nsectors)
{ {
FAR struct part_struct_s *dev; FAR struct part_struct_s *dev;
struct geometry geo;
int ret; int ret;
/* Allocate a partition device structure */ /* Allocate a partition device structure */
@ -331,6 +351,16 @@ int register_blockpartition(FAR const char *partition,
goto errout_free; goto errout_free;
} }
/* Get sector size */
ret = dev->parent->u.i_bops->geometry(dev->parent, &geo);
if (ret < 0)
{
goto errout_free;
}
dev->sectorsize = geo.geo_sectorsize;
/* Inode private data is a reference to the partition device structure */ /* Inode private data is a reference to the partition device structure */
ret = register_blockdriver(partition, &g_part_bops, mode, dev); ret = register_blockdriver(partition, &g_part_bops, mode, dev);