rpmsg: char: Use rpmsg_sendto to specify the message destination address

When the endpoint device is created by the application, a destination
address is specified in the rpmsg_channel_info structure. Since the
rpmsg_endpoint structure does not store the destination address,
this destination address must be specified when sending a message.

Replaces rpmsg_send with rpmsg_sendto to allow to specify the
destination address. This implementation is requested for compatibly with
some rpmsg backends like the virtio backend.

For this, the GLINK an SMD drivers have been updated to support the
rpmsg_sendto, even if the destination address is ignored for these
backends. For these drivers, the rpmsg_send and rpmsg_trysend ops are
preserved to avoid breaking the legacy.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20210311140413.31725-5-arnaud.pouliquen@foss.st.com
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
This commit is contained in:
Arnaud Pouliquen 2021-03-11 15:04:11 +01:00 committed by Bjorn Andersson
parent 809328b40c
commit b4ce7e2ebc
3 changed files with 34 additions and 2 deletions

View File

@ -1332,6 +1332,20 @@ static int qcom_glink_trysend(struct rpmsg_endpoint *ept, void *data, int len)
return __qcom_glink_send(channel, data, len, false); return __qcom_glink_send(channel, data, len, false);
} }
static int qcom_glink_sendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
{
struct glink_channel *channel = to_glink_channel(ept);
return __qcom_glink_send(channel, data, len, true);
}
static int qcom_glink_trysendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
{
struct glink_channel *channel = to_glink_channel(ept);
return __qcom_glink_send(channel, data, len, false);
}
/* /*
* Finds the device_node for the glink child interested in this channel. * Finds the device_node for the glink child interested in this channel.
*/ */
@ -1364,7 +1378,9 @@ static const struct rpmsg_device_ops glink_device_ops = {
static const struct rpmsg_endpoint_ops glink_endpoint_ops = { static const struct rpmsg_endpoint_ops glink_endpoint_ops = {
.destroy_ept = qcom_glink_destroy_ept, .destroy_ept = qcom_glink_destroy_ept,
.send = qcom_glink_send, .send = qcom_glink_send,
.sendto = qcom_glink_sendto,
.trysend = qcom_glink_trysend, .trysend = qcom_glink_trysend,
.trysendto = qcom_glink_trysendto,
}; };
static void qcom_glink_rpdev_release(struct device *dev) static void qcom_glink_rpdev_release(struct device *dev)

View File

@ -974,6 +974,20 @@ static int qcom_smd_trysend(struct rpmsg_endpoint *ept, void *data, int len)
return __qcom_smd_send(qsept->qsch, data, len, false); return __qcom_smd_send(qsept->qsch, data, len, false);
} }
static int qcom_smd_sendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
{
struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept);
return __qcom_smd_send(qsept->qsch, data, len, true);
}
static int qcom_smd_trysendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
{
struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept);
return __qcom_smd_send(qsept->qsch, data, len, false);
}
static __poll_t qcom_smd_poll(struct rpmsg_endpoint *ept, static __poll_t qcom_smd_poll(struct rpmsg_endpoint *ept,
struct file *filp, poll_table *wait) struct file *filp, poll_table *wait)
{ {
@ -1038,7 +1052,9 @@ static const struct rpmsg_device_ops qcom_smd_device_ops = {
static const struct rpmsg_endpoint_ops qcom_smd_endpoint_ops = { static const struct rpmsg_endpoint_ops qcom_smd_endpoint_ops = {
.destroy_ept = qcom_smd_destroy_ept, .destroy_ept = qcom_smd_destroy_ept,
.send = qcom_smd_send, .send = qcom_smd_send,
.sendto = qcom_smd_sendto,
.trysend = qcom_smd_trysend, .trysend = qcom_smd_trysend,
.trysendto = qcom_smd_trysendto,
.poll = qcom_smd_poll, .poll = qcom_smd_poll,
}; };

View File

@ -239,9 +239,9 @@ static ssize_t rpmsg_eptdev_write_iter(struct kiocb *iocb,
} }
if (filp->f_flags & O_NONBLOCK) if (filp->f_flags & O_NONBLOCK)
ret = rpmsg_trysend(eptdev->ept, kbuf, len); ret = rpmsg_trysendto(eptdev->ept, kbuf, len, eptdev->chinfo.dst);
else else
ret = rpmsg_send(eptdev->ept, kbuf, len); ret = rpmsg_sendto(eptdev->ept, kbuf, len, eptdev->chinfo.dst);
unlock_eptdev: unlock_eptdev:
mutex_unlock(&eptdev->ept_lock); mutex_unlock(&eptdev->ept_lock);