aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/rpmsg/Kconfig1
-rw-r--r--drivers/rpmsg/virtio_rpmsg_bus.c49
2 files changed, 36 insertions, 14 deletions
diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
index f6e0ea6ffda5..69a219387582 100644
--- a/drivers/rpmsg/Kconfig
+++ b/drivers/rpmsg/Kconfig
@@ -4,5 +4,6 @@ menu "Rpmsg drivers"
4config RPMSG 4config RPMSG
5 tristate 5 tristate
6 select VIRTIO 6 select VIRTIO
7 select VIRTUALIZATION
7 8
8endmenu 9endmenu
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
index 56fceafec9ec..b6135d4d54eb 100644
--- a/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -776,23 +776,13 @@ out:
776} 776}
777EXPORT_SYMBOL(rpmsg_send_offchannel_raw); 777EXPORT_SYMBOL(rpmsg_send_offchannel_raw);
778 778
779/* called when an rx buffer is used, and it's time to digest a message */ 779static int rpmsg_recv_single(struct virtproc_info *vrp, struct device *dev,
780static void rpmsg_recv_done(struct virtqueue *rvq) 780 struct rpmsg_hdr *msg, unsigned int len)
781{ 781{
782 struct rpmsg_hdr *msg;
783 unsigned int len;
784 struct rpmsg_endpoint *ept; 782 struct rpmsg_endpoint *ept;
785 struct scatterlist sg; 783 struct scatterlist sg;
786 struct virtproc_info *vrp = rvq->vdev->priv;
787 struct device *dev = &rvq->vdev->dev;
788 int err; 784 int err;
789 785
790 msg = virtqueue_get_buf(rvq, &len);
791 if (!msg) {
792 dev_err(dev, "uhm, incoming signal, but no used buffer ?\n");
793 return;
794 }
795
796 dev_dbg(dev, "From: 0x%x, To: 0x%x, Len: %d, Flags: %d, Reserved: %d\n", 786 dev_dbg(dev, "From: 0x%x, To: 0x%x, Len: %d, Flags: %d, Reserved: %d\n",
797 msg->src, msg->dst, msg->len, 787 msg->src, msg->dst, msg->len,
798 msg->flags, msg->reserved); 788 msg->flags, msg->reserved);
@@ -806,7 +796,7 @@ static void rpmsg_recv_done(struct virtqueue *rvq)
806 if (len > RPMSG_BUF_SIZE || 796 if (len > RPMSG_BUF_SIZE ||
807 msg->len > (len - sizeof(struct rpmsg_hdr))) { 797 msg->len > (len - sizeof(struct rpmsg_hdr))) {
808 dev_warn(dev, "inbound msg too big: (%d, %d)\n", len, msg->len); 798 dev_warn(dev, "inbound msg too big: (%d, %d)\n", len, msg->len);
809 return; 799 return -EINVAL;
810 } 800 }
811 801
812 /* use the dst addr to fetch the callback of the appropriate user */ 802 /* use the dst addr to fetch the callback of the appropriate user */
@@ -842,11 +832,42 @@ static void rpmsg_recv_done(struct virtqueue *rvq)
842 err = virtqueue_add_inbuf(vrp->rvq, &sg, 1, msg, GFP_KERNEL); 832 err = virtqueue_add_inbuf(vrp->rvq, &sg, 1, msg, GFP_KERNEL);
843 if (err < 0) { 833 if (err < 0) {
844 dev_err(dev, "failed to add a virtqueue buffer: %d\n", err); 834 dev_err(dev, "failed to add a virtqueue buffer: %d\n", err);
835 return err;
836 }
837
838 return 0;
839}
840
841/* called when an rx buffer is used, and it's time to digest a message */
842static void rpmsg_recv_done(struct virtqueue *rvq)
843{
844 struct virtproc_info *vrp = rvq->vdev->priv;
845 struct device *dev = &rvq->vdev->dev;
846 struct rpmsg_hdr *msg;
847 unsigned int len, msgs_received = 0;
848 int err;
849
850 msg = virtqueue_get_buf(rvq, &len);
851 if (!msg) {
852 dev_err(dev, "uhm, incoming signal, but no used buffer ?\n");
845 return; 853 return;
846 } 854 }
847 855
856 while (msg) {
857 err = rpmsg_recv_single(vrp, dev, msg, len);
858 if (err)
859 break;
860
861 msgs_received++;
862
863 msg = virtqueue_get_buf(rvq, &len);
864 };
865
866 dev_dbg(dev, "Received %u messages\n", msgs_received);
867
848 /* tell the remote processor we added another available rx buffer */ 868 /* tell the remote processor we added another available rx buffer */
849 virtqueue_kick(vrp->rvq); 869 if (msgs_received)
870 virtqueue_kick(vrp->rvq);
850} 871}
851 872
852/* 873/*