Skip to content

Commit

Permalink
rpmsg: process _all_ pending messages in rpmsg_recv_done
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Robert Tivy authored and Ohad Ben-Cohen committed Apr 15, 2013
1 parent f6161aa commit 1aa7d6a
Showing 1 changed file with 35 additions and 14 deletions.
49 changes: 35 additions & 14 deletions drivers/rpmsg/virtio_rpmsg_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -776,23 +776,13 @@ int rpmsg_send_offchannel_raw(struct rpmsg_channel *rpdev, u32 src, u32 dst,
}
EXPORT_SYMBOL(rpmsg_send_offchannel_raw);

/* called when an rx buffer is used, and it's time to digest a message */
static void rpmsg_recv_done(struct virtqueue *rvq)
static int rpmsg_recv_single(struct virtproc_info *vrp, struct device *dev,
struct rpmsg_hdr *msg, unsigned int len)
{
struct rpmsg_hdr *msg;
unsigned int len;
struct rpmsg_endpoint *ept;
struct scatterlist sg;
struct virtproc_info *vrp = rvq->vdev->priv;
struct device *dev = &rvq->vdev->dev;
int err;

msg = virtqueue_get_buf(rvq, &len);
if (!msg) {
dev_err(dev, "uhm, incoming signal, but no used buffer ?\n");
return;
}

dev_dbg(dev, "From: 0x%x, To: 0x%x, Len: %d, Flags: %d, Reserved: %d\n",
msg->src, msg->dst, msg->len,
msg->flags, msg->reserved);
Expand All @@ -806,7 +796,7 @@ static void rpmsg_recv_done(struct virtqueue *rvq)
if (len > RPMSG_BUF_SIZE ||
msg->len > (len - sizeof(struct rpmsg_hdr))) {
dev_warn(dev, "inbound msg too big: (%d, %d)\n", len, msg->len);
return;
return -EINVAL;
}

/* use the dst addr to fetch the callback of the appropriate user */
Expand Down Expand Up @@ -842,11 +832,42 @@ static void rpmsg_recv_done(struct virtqueue *rvq)
err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, msg, GFP_KERNEL);
if (err < 0) {
dev_err(dev, "failed to add a virtqueue buffer: %d\n", err);
return err;
}

return 0;
}

/* called when an rx buffer is used, and it's time to digest a message */
static void rpmsg_recv_done(struct virtqueue *rvq)
{
struct virtproc_info *vrp = rvq->vdev->priv;
struct device *dev = &rvq->vdev->dev;
struct rpmsg_hdr *msg;
unsigned int len, msgs_received = 0;
int err;

msg = virtqueue_get_buf(rvq, &len);
if (!msg) {
dev_err(dev, "uhm, incoming signal, but no used buffer ?\n");
return;
}

while (msg) {
err = rpmsg_recv_single(vrp, dev, msg, len);
if (err)
break;

msgs_received++;

msg = virtqueue_get_buf(rvq, &len);
};

dev_dbg(dev, "Received %u messages\n", msgs_received);

/* tell the remote processor we added another available rx buffer */
virtqueue_kick(vrp->rvq);
if (msgs_received)
virtqueue_kick(vrp->rvq);
}

/*
Expand Down

0 comments on commit 1aa7d6a

Please sign in to comment.