Skip to content

Commit

Permalink
rpmsgblk: split mmc_ioc_multi_cmd to mmc_ioc_cmd for less share memor…
Browse files Browse the repository at this point in the history
…y allocation

Signed-off-by: liaoao <[email protected]>
  • Loading branch information
leo11261 authored and xiaoxiang781216 committed Nov 22, 2023
1 parent cf27a84 commit ea0be3b
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 137 deletions.
230 changes: 114 additions & 116 deletions drivers/misc/rpmsgblk.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static ssize_t rpmsgblk_write(FAR struct inode *inode,
blkcnt_t start_sector, unsigned int nsectors);
static int rpmsgblk_geometry(FAR struct inode *inode,
FAR struct geometry *geometry);
static ssize_t rpmsgblk_ioctl_arglen(int cmd, unsigned long arg);
static ssize_t rpmsgblk_ioctl_arglen(int cmd);
static int rpmsgblk_ioctl(FAR struct inode *inode, int cmd,
unsigned long arg);
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
Expand Down Expand Up @@ -491,7 +491,7 @@ static int rpmsgblk_geometry(FAR struct inode *inode,
*
****************************************************************************/

static ssize_t rpmsgblk_ioctl_arglen(int cmd, unsigned long arg)
static ssize_t rpmsgblk_ioctl_arglen(int cmd)
{
switch (cmd)
{
Expand All @@ -516,74 +516,102 @@ static ssize_t rpmsgblk_ioctl_arglen(int cmd, unsigned long arg)
return sizeof(struct partition_info_s);
case BIOC_BLKSSZGET:
return sizeof(blksize_t);
case MMC_IOC_CMD:
{
FAR struct mmc_ioc_cmd *ioc =
(FAR struct mmc_ioc_cmd *)(uintptr_t)arg;

return sizeof(struct mmc_ioc_cmd) + ioc->blksz * ioc->blocks;
}

case MMC_IOC_MULTI_CMD:
{
FAR struct mmc_ioc_multi_cmd *mioc =
(FAR struct mmc_ioc_multi_cmd *)(uintptr_t)arg;
uint64_t num = mioc->num_of_cmds;
uint64_t i;
ssize_t arglen;

arglen = sizeof(struct mmc_ioc_multi_cmd) +
num * sizeof(struct mmc_ioc_cmd);
for (i = 0; i < num; i++)
{
arglen += mioc->cmds[i].blksz * mioc->cmds[i].blocks;
}

return arglen;
}

default:
return -ENOTTY;
}
}

/****************************************************************************
* Name: rpmsgblk_ioctl
* Name: rpmsgblk_mmc_cmd_ioctl
*
* Description:
* Rpmsg-blk ioctl operation
*
* Parameters:
* inode - the blk device inode
* cmd - the ioctl command
* arg - the ioctl arguments
*
* Returned Values:
* OK on success; A negated errno value is returned on any failure.
* If args include a usrspace buffer pointer, then the content of this
* pointer should also be copied into share memory and set after args.
*
****************************************************************************/

static int rpmsgblk_ioctl(FAR struct inode *inode, int cmd,
unsigned long arg)
static int rpmsgblk_mmc_cmd_ioctl(FAR struct inode *inode, unsigned long arg)
{
FAR struct rpmsgblk_s *priv = inode->i_private;
FAR struct mmc_ioc_cmd *ioc = (FAR struct mmc_ioc_cmd *)(uintptr_t)arg;
FAR struct rpmsgblk_ioctl_s *msg;
uint32_t space;
ssize_t arglen;
size_t msglen;
ssize_t msglen;

/* Sanity checks */
msglen = sizeof(*msg) + sizeof(struct mmc_ioc_cmd) +
ioc->blksz * ioc->blocks - 1;

DEBUGASSERT(priv != NULL);
msg = rpmsgblk_get_tx_payload_buffer(priv, &space);
if (msg == NULL)
{
return -ENOMEM;
}

DEBUGASSERT(space > msglen);

msg->request = MMC_IOC_CMD;
msg->arg = arg;
msg->arglen = sizeof(struct mmc_ioc_cmd) + ioc->blksz * ioc->blocks;

memcpy(msg->buf, ioc, sizeof(*ioc));
if (ioc->data_ptr)
{
memcpy(msg->buf + sizeof(*ioc), (FAR void *)(uintptr_t)ioc->data_ptr,
ioc->blksz * ioc->blocks);
}

return rpmsgblk_send_recv(priv, RPMSGBLK_IOCTL, false, &msg->header,
msglen, ioc);
}

/****************************************************************************
* Name: rpmsgblk_mmc_multi_cmd_ioctl
*
* Description:
* The size of MMC_IOC_MILTI_CMD's memory occupation is likely to be
* larger than that allocated by rpmsgblk_get_tx_payload_buffer, which
* is not allowed by current implement. So split the mmc_ioc_multi_cmd
* into mmc_ioc_cmds to transfer.
*
****************************************************************************/

static int rpmsgblk_mmc_multi_cmd_ioctl(FAR struct inode *inode,
unsigned long arg)
{
FAR struct mmc_ioc_multi_cmd *mioc =
(FAR struct mmc_ioc_multi_cmd *)(uintptr_t)arg;
int ret = 0;
uint64_t i;

if (cmd == BIOC_GEOMETRY)
for (i = 0; i < mioc->num_of_cmds; i++)
{
return rpmsgblk_geometry(inode, (FAR struct geometry *)arg);
ret = rpmsgblk_mmc_cmd_ioctl(inode,
(unsigned long)(uintptr_t)&mioc->cmds[i]);
if (ret < 0)
{
return ret;
}
}

return ret;
}

/****************************************************************************
* Name: rpmsgblk_default_ioctl
****************************************************************************/

static int rpmsgblk_default_ioctl(FAR struct inode *inode, int cmd,
unsigned long arg)
{
FAR struct rpmsgblk_s *priv = inode->i_private;
FAR struct rpmsgblk_ioctl_s *msg;
uint32_t space;
ssize_t arglen;
size_t msglen;

/* Call our internal routine to perform the ioctl */

arglen = rpmsgblk_ioctl_arglen(cmd, arg);
arglen = rpmsgblk_ioctl_arglen(cmd);
if (arglen < 0)
{
return arglen;
Expand All @@ -605,54 +633,51 @@ static int rpmsgblk_ioctl(FAR struct inode *inode, int cmd,

if (arglen > 0)
{
/* If args include a usrspace buffer pointer, then the content of this
* pointer should also be copied into share memory and set after args.
*/

if (cmd == MMC_IOC_CMD)
{
FAR struct mmc_ioc_cmd *ioc =
(FAR struct mmc_ioc_cmd *)(uintptr_t)arg;

memcpy(msg->buf, (FAR void *)(uintptr_t)arg, sizeof(*ioc));
if (ioc->data_ptr)
{
memcpy(msg->buf + sizeof(*ioc),
(FAR void *)(uintptr_t)ioc->data_ptr,
ioc->blksz * ioc->blocks);
}
}
else if (cmd == MMC_IOC_MULTI_CMD)
{
FAR struct mmc_ioc_multi_cmd *mioc =
(FAR struct mmc_ioc_multi_cmd *)(uintptr_t)arg;
uint64_t num = mioc->num_of_cmds;
ssize_t copy = sizeof(struct mmc_ioc_multi_cmd) +
num * sizeof(struct mmc_ioc_cmd);
uint64_t i;

memcpy(msg->buf, (FAR void *)(uintptr_t)arg, copy);
for (i = 0; i < num; i++)
{
if (mioc->cmds[i].data_ptr)
{
memcpy(msg->buf + copy,
(FAR void *)(uintptr_t)mioc->cmds[i].data_ptr,
mioc->cmds[i].blksz * mioc->cmds[i].blocks);
copy += mioc->cmds[i].blksz * mioc->cmds[i].blocks;
}
}
}
else
{
memcpy(msg->buf, (FAR void *)(uintptr_t)arg, arglen);
}
memcpy(msg->buf, (FAR void *)(uintptr_t)arg, arglen);
}

return rpmsgblk_send_recv(priv, RPMSGBLK_IOCTL, false, &msg->header,
msglen, arglen > 0 ? (FAR void *)arg : NULL);
}

/****************************************************************************
* Name: rpmsgblk_ioctl
*
* Description:
* Rpmsg-blk ioctl operation
*
* Parameters:
* inode - the blk device inode
* cmd - the ioctl command
* arg - the ioctl arguments
*
* Returned Values:
* OK on success; A negated errno value is returned on any failure.
*
****************************************************************************/

static int rpmsgblk_ioctl(FAR struct inode *inode, int cmd,
unsigned long arg)
{
FAR struct rpmsgblk_s *priv = inode->i_private;

/* Sanity checks */

DEBUGASSERT(priv != NULL);

switch (cmd)
{
case BIOC_GEOMETRY:
return rpmsgblk_geometry(inode, (FAR struct geometry *)arg);
case MMC_IOC_CMD:
return rpmsgblk_mmc_cmd_ioctl(inode, arg);
case MMC_IOC_MULTI_CMD:
return rpmsgblk_mmc_multi_cmd_ioctl(inode, arg);
default:
return rpmsgblk_default_ioctl(inode, cmd, arg);
}
}

/****************************************************************************
* Name: rpmsgblk_unlink
*
Expand Down Expand Up @@ -952,33 +977,6 @@ static int rpmsgblk_ioctl_handler(FAR struct rpmsg_endpoint *ept,
}
break;

case MMC_IOC_MULTI_CMD:
{
FAR struct mmc_ioc_multi_cmd *mioc =
(FAR struct mmc_ioc_multi_cmd *)(uintptr_t)cookie->data;
FAR struct mmc_ioc_multi_cmd *mioc_rsp =
(FAR struct mmc_ioc_multi_cmd *)(uintptr_t)rsp->buf;
uint64_t num = mioc->num_of_cmds;
size_t off = sizeof(struct mmc_ioc_multi_cmd) +
num * sizeof(struct mmc_ioc_cmd);
uint64_t i;

for (i = 0; i < num; i++)
{
memcpy(&mioc->cmds[i], &mioc_rsp->cmds[i],
sizeof(struct mmc_ioc_cmd) -
sizeof(mioc->cmds[i].data_ptr));
if (mioc->cmds[i].data_ptr)
{
memcpy((FAR void *)(uintptr_t)mioc->cmds[i].data_ptr,
rsp->buf + off,
mioc->cmds[i].blksz * mioc->cmds[i].blocks);
off += mioc->cmds[i].blksz * mioc->cmds[i].blocks;
}
}
}
break;

default:
memcpy(cookie->data, rsp->buf, rsp->arglen);
break;
Expand Down
21 changes: 0 additions & 21 deletions drivers/misc/rpmsgblk_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,27 +345,6 @@ static int rpmsgblk_ioctl_handler(FAR struct rpmsg_endpoint *ept,
}
break;

case MMC_IOC_MULTI_CMD:
{
FAR struct mmc_ioc_multi_cmd *mioc =
(FAR struct mmc_ioc_multi_cmd *)(uintptr_t)msg->buf;
uint64_t num = mioc->num_of_cmds;
size_t off = sizeof(struct mmc_ioc_multi_cmd) +
num * sizeof(struct mmc_ioc_cmd);
uint64_t i;

for (i = 0; i < num; i++)
{
if (mioc->cmds[i].data_ptr)
{
mioc->cmds[i].data_ptr = (uint64_t)(uintptr_t)
((FAR uint8_t *)mioc + off);
off += mioc->cmds[i].blksz * mioc->cmds[i].blocks;
}
}
}
break;

default:
break;
}
Expand Down

0 comments on commit ea0be3b

Please sign in to comment.