diff options
author | Robert Tivy <rtivy@ti.com> | 2013-04-05 10:38:52 -0400 |
---|---|---|
committer | Ohad Ben-Cohen <ohad@wizery.com> | 2013-04-15 02:14:09 -0400 |
commit | 1aa7d6a5d0e4c301a7f497d3be26bb7acd749423 (patch) | |
tree | ecf051e2214ec05442e8e00d05abb4648f9f65f6 /drivers/rpmsg | |
parent | f6161aa153581da4a3867a2d1a7caf4be19b6ec9 (diff) |
rpmsg: process _all_ pending messages in rpmsg_recv_done
Change virtqueue callback function rpmsg_recv_done() to process all
available messages instead of just one message.
Signed-off-by: Robert Tivy <rtivy@ti.com>
[split _recv function instead of adding indentation]
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
Diffstat (limited to 'drivers/rpmsg')
-rw-r--r-- | drivers/rpmsg/virtio_rpmsg_bus.c | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index a59684b5fc68..07d5ea2ac77a 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c | |||
@@ -776,23 +776,13 @@ out: | |||
776 | } | 776 | } |
777 | EXPORT_SYMBOL(rpmsg_send_offchannel_raw); | 777 | EXPORT_SYMBOL(rpmsg_send_offchannel_raw); |
778 | 778 | ||
779 | /* called when an rx buffer is used, and it's time to digest a message */ | 779 | static int rpmsg_recv_single(struct virtproc_info *vrp, struct device *dev, |
780 | static 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_buf(vrp->rvq, &sg, 0, 1, msg, GFP_KERNEL); | 832 | err = virtqueue_add_buf(vrp->rvq, &sg, 0, 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 */ | ||
842 | static 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 | /* |