rpmsg_virtio/rptun: support fallback cpuname when VIRTIO_RPMSG_F_CPUNAME not set

When the VIRTIO_RPMSG_F_CPUNAME feature is not negotiated, the driver
previously would crash due to DEBUGASSERT. This commit adds support
for a fallback mechanism:

1. Add rpmsg_virtio_probe_cpuname() API that accepts an optional cpuname
   parameter to be used when VIRTIO_RPMSG_F_CPUNAME is not available.

2. Modify rptun driver to pass the cpuname from rptun device config
   to rpmsg_virtio_probe_cpuname().

3. Refactor rptun device register/unregister to prioritize RPMSG device
   handling before other virtio device types.

This ensures the system works correctly in scenarios where the remote
side does not support the VIRTIO_RPMSG_F_CPUNAME feature.

Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
This commit is contained in:
Bowen Wang
2026-02-04 20:36:59 +08:00
committed by Alan C. Assis
parent 1653db7ddc
commit 877a9af2d1
3 changed files with 58 additions and 33 deletions
+37 -20
View File
@@ -603,10 +603,11 @@ static int rpmsg_virtio_thread(int argc, FAR char *argv[])
****************************************************************************/
/****************************************************************************
* Name: rpmsg_virtio_probe
* Name: rpmsg_virtio_probe_cpuname
****************************************************************************/
int rpmsg_virtio_probe(FAR struct virtio_device *vdev)
int rpmsg_virtio_probe_cpuname(FAR struct virtio_device *vdev,
FAR const char *cpuname)
{
FAR struct rpmsg_virtio_priv_s *priv;
FAR char *argv[3];
@@ -639,28 +640,35 @@ int rpmsg_virtio_probe(FAR struct virtio_device *vdev)
/* Read the virtio rpmsg config to get the local/remote cpu name */
DEBUGASSERT(virtio_has_feature(vdev, VIRTIO_RPMSG_F_CPUNAME));
if (vdev->role == VIRTIO_DEV_DRIVER)
if (virtio_has_feature(vdev, VIRTIO_RPMSG_F_CPUNAME))
{
virtio_read_config_bytes(vdev, offsetof(struct fw_rsc_config,
host_cpuname),
priv->rpmsg.local_cpuname,
VIRTIO_RPMSG_CPUNAME_SIZE);
virtio_read_config_bytes(vdev, offsetof(struct fw_rsc_config,
remote_cpuname),
priv->rpmsg.cpuname,
VIRTIO_RPMSG_CPUNAME_SIZE);
if (vdev->role == VIRTIO_DEV_DRIVER)
{
virtio_read_config_bytes(vdev, offsetof(struct fw_rsc_config,
host_cpuname),
priv->rpmsg.local_cpuname,
VIRTIO_RPMSG_CPUNAME_SIZE);
virtio_read_config_bytes(vdev, offsetof(struct fw_rsc_config,
remote_cpuname),
priv->rpmsg.cpuname,
VIRTIO_RPMSG_CPUNAME_SIZE);
}
else
{
virtio_read_config_bytes(vdev, offsetof(struct fw_rsc_config,
host_cpuname),
priv->rpmsg.cpuname,
VIRTIO_RPMSG_CPUNAME_SIZE);
virtio_read_config_bytes(vdev, offsetof(struct fw_rsc_config,
remote_cpuname),
priv->rpmsg.local_cpuname,
VIRTIO_RPMSG_CPUNAME_SIZE);
}
}
else
{
virtio_read_config_bytes(vdev, offsetof(struct fw_rsc_config,
host_cpuname),
priv->rpmsg.cpuname,
VIRTIO_RPMSG_CPUNAME_SIZE);
virtio_read_config_bytes(vdev, offsetof(struct fw_rsc_config,
remote_cpuname),
priv->rpmsg.local_cpuname,
VIRTIO_RPMSG_CPUNAME_SIZE);
DEBUGASSERT(cpuname != NULL);
strlcpy(priv->rpmsg.cpuname, cpuname, VIRTIO_RPMSG_CPUNAME_SIZE);
}
/* Register the rpmsg to rpmsg framework */
@@ -705,6 +713,15 @@ err:
return ret;
}
/****************************************************************************
* Name: rpmsg_virtio_probe
****************************************************************************/
int rpmsg_virtio_probe(FAR struct virtio_device *vdev)
{
return rpmsg_virtio_probe_cpuname(vdev, NULL);
}
/****************************************************************************
* Name: rpmsg_virtio_remove
****************************************************************************/
+19 -13
View File
@@ -544,10 +544,20 @@ static void rptun_remove_device(FAR struct rptun_priv_s *priv,
* Name: rptun_register_device
****************************************************************************/
static int rptun_register_device(FAR struct virtio_device *vdev)
static int rptun_register_device(FAR struct rptun_priv_s *priv,
FAR struct virtio_device *vdev)
{
int ret = -ENODEV;
if (vdev->id.device == VIRTIO_ID_RPMSG)
{
ret = rpmsg_virtio_probe_cpuname(vdev, RPTUN_GET_CPUNAME(priv->dev));
if (ret < 0)
{
rptunerr("rpmsg_virtio_probe failed, ret=%d\n", ret);
}
}
else
#ifdef CONFIG_DRIVERS_VIRTIO
if (vdev->role == VIRTIO_DEV_DRIVER)
{
@@ -572,15 +582,6 @@ static int rptun_register_device(FAR struct virtio_device *vdev)
}
else
#endif
if (vdev->id.device == VIRTIO_ID_RPMSG)
{
ret = rpmsg_virtio_probe(vdev);
if (ret < 0)
{
rptunerr("rpmsg_virtio_probe failed, ret=%d\n", ret);
}
}
else
{
rptunerr("virtio device id = %"PRIu32" not supported\n",
vdev->id.device);
@@ -595,6 +596,11 @@ static int rptun_register_device(FAR struct virtio_device *vdev)
static void rptun_unregister_device(FAR struct virtio_device *vdev)
{
if (vdev->id.device == VIRTIO_ID_RPMSG)
{
rpmsg_virtio_remove(vdev);
}
else
#ifdef CONFIG_DRIVERS_VIRTIO
if (vdev->role == VIRTIO_DEV_DRIVER)
{
@@ -609,9 +615,9 @@ static void rptun_unregister_device(FAR struct virtio_device *vdev)
}
else
#endif
if (vdev->id.device == VIRTIO_ID_RPMSG)
{
rpmsg_virtio_remove(vdev);
rptunerr("virtio device id = %"PRIu32" not supported\n",
vdev->id.device);
}
}
@@ -670,7 +676,7 @@ static int rptun_create_devices(FAR struct rptun_priv_s *priv)
goto err;
}
ret = rptun_register_device(vdev);
ret = rptun_register_device(priv, vdev);
if (ret < 0)
{
rptunerr("rptun_register_device failed, ret=%d i=%d\n", ret, i);
+2
View File
@@ -51,6 +51,8 @@ extern "C"
* Public Function Prototypes
****************************************************************************/
int rpmsg_virtio_probe_cpuname(FAR struct virtio_device *vdev,
FAR const char *cpuname);
int rpmsg_virtio_probe(FAR struct virtio_device *vdev);
void rpmsg_virtio_remove(FAR struct virtio_device *vdev);