summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: acdb379)
raw | patch | inline | side by side (parent: acdb379)
author | Wendy Liang <jliang@xilinx.com> | |
Tue, 2 Aug 2016 22:50:47 +0000 (15:50 -0700) | ||
committer | Wendy Liang <jliang@xilinx.com> | |
Thu, 13 Oct 2016 05:01:46 +0000 (22:01 -0700) |
Use libmetal scatter/gather list to replace the llist buffers.
Signed-off-by: Wendy Liang <jliang@xilinx.com>
Signed-off-by: Wendy Liang <jliang@xilinx.com>
index 790df874749975aea19eded7ac0eed948ffd0c5a..0962a9f37ec58a7f2ff4f4f77ac1c866113deef0 100644 (file)
#include "openamp/virtio.h"
#include "openamp/hil.h"
#include "openamp/sh_mem.h"
-#include "openamp/llist.h"
#include "openamp/rpmsg.h"
#include "metal/mutex.h"
#include "metal/list.h"
index 83d2fb54f551797b4a38c43df23d76c319d4930b..2ab53717f1ee571e01b4c5614478518ffa1f755c 100644 (file)
#include "openamp/virtio_ring.h"
#include "openamp/env.h"
-#include "openamp/llist.h"
+#include "metal/dma.h"
/*Error Codes*/
#define VQ_ERROR_BASE -3000
void (*notify) (struct virtqueue * vq),
struct virtqueue **v_queue);
-int virtqueue_add_buffer(struct virtqueue *vq, struct llist *buffer,
+int virtqueue_add_buffer(struct virtqueue *vq, struct metal_sg *sg,
int readable, int writable, void *cookie);
int virtqueue_add_single_buffer(struct virtqueue *vq, void *cookie,
- void *buffer_addr, uint32_t len, int writable,
+ struct metal_sg *sg, int writable,
boolean has_next);
void *virtqueue_get_buffer(struct virtqueue *vq, uint32_t * len);
index ed132fc9cf72b9c1f40b8202992b2ac743da33e6..9187d69af0964eb6e59dec8d2ea436bd9477a4ab 100644 (file)
@@ -384,7 +384,7 @@ int rpmsg_rdev_create_virtqueues(struct virtio_device *dev, int flags, int nvqs,
struct virtqueue *vqs[RPMSG_MAX_VQ_PER_RDEV];
struct proc_vring *vring_table;
void *buffer;
- struct llist node;
+ struct metal_sg sg;
int idx, num_vrings, status;
(void)flags;
@@ -429,6 +429,8 @@ int rpmsg_rdev_create_virtqueues(struct virtio_device *dev, int flags, int nvqs,
}
if (rdev->role == RPMSG_REMOTE) {
+ sg.io = rdev->proc->sh_buff.io;
+ sg.len = RPMSG_BUFFER_SIZE;
for (idx = 0; ((idx < rdev->rvq->vq_nentries)
&& (idx < rdev->mem_pool->total_buffs / 2));
idx++) {
@@ -440,13 +442,11 @@ int rpmsg_rdev_create_virtqueues(struct virtio_device *dev, int flags, int nvqs,
return RPMSG_ERR_NO_BUFF;
}
- node.data = buffer;
- node.attr = RPMSG_BUFFER_SIZE;
- node.next = RPMSG_NULL;
+ sg.virt = buffer;
memset(buffer, 0x00, RPMSG_BUFFER_SIZE);
status =
- virtqueue_add_buffer(rdev->rvq, &node, 0, 1,
+ virtqueue_add_buffer(rdev->rvq, &sg, 0, 1,
buffer);
if (status != RPMSG_SUCCESS) {
diff --git a/lib/rpmsg/rpmsg_core.c b/lib/rpmsg/rpmsg_core.c
index 6245b3f64dfb32f1868923008caf8982c15be61c..cd11dcabce761d958ee8d115330853e14ba02c17 100644 (file)
--- a/lib/rpmsg/rpmsg_core.c
+++ b/lib/rpmsg/rpmsg_core.c
int rpmsg_enqueue_buffer(struct remote_device *rdev, void *buffer,
unsigned long len, unsigned short idx)
{
- struct llist node;
int status;
+ struct metal_sg sg;
struct metal_io_region *io;
- /* Initialize buffer node */
- node.data = buffer;
- node.attr = len;
- node.next = RPMSG_NULL;
- node.prev = RPMSG_NULL;
-
io = rdev->proc->sh_buff.io;
if (io) {
if (! (io->mem_flags & METAL_UNCACHED))
metal_cache_flush(buffer, (unsigned int)len);
}
if (rdev->role == RPMSG_REMOTE) {
- status = virtqueue_add_buffer(rdev->tvq, &node, 0, 1, buffer);
+ /* Initialize buffer node */
+ sg.virt = buffer;
+ sg.len = len;
+ sg.io = io;
+ status = virtqueue_add_buffer(rdev->tvq, &sg, 0, 1, buffer);
} else {
+ (void)sg;
status = virtqueue_add_consumed_buffer(rdev->tvq, idx, len);
}
void rpmsg_return_buffer(struct remote_device *rdev, void *buffer,
unsigned long len, unsigned short idx)
{
- struct llist node;
-
- /* Initialize buffer node */
- node.data = buffer;
- node.attr = len;
- node.next = RPMSG_NULL;
- node.prev = RPMSG_NULL;
+ struct metal_sg sg;
if (rdev->role == RPMSG_REMOTE) {
- virtqueue_add_buffer(rdev->rvq, &node, 0, 1, buffer);
+ /* Initialize buffer node */
+ sg.virt = buffer;
+ sg.len = len;
+ sg.io = rdev->proc->sh_buff.io;
+ virtqueue_add_buffer(rdev->rvq, &sg, 0, 1, buffer);
} else {
+ (void)sg;
virtqueue_add_consumed_buffer(rdev->rvq, idx, len);
}
}
diff --git a/lib/virtio/virtqueue.c b/lib/virtio/virtqueue.c
index 3e1639be9be9b900e36199de490cee866124c06f..fcabeab349fee686e46493957f5bb01ecc8f61ed 100644 (file)
--- a/lib/virtio/virtqueue.c
+++ b/lib/virtio/virtqueue.c
#include <string.h>
#include "openamp/virtqueue.h"
#include "metal/atomic.h"
+#include "metal/dma.h"
+#include "metal/io.h"
/* Prototype for internal functions. */
static void vq_ring_init(struct virtqueue *);
static void vq_ring_update_avail(struct virtqueue *, uint16_t);
static uint16_t vq_ring_add_buffer(struct virtqueue *, struct vring_desc *,
- uint16_t, struct llist *, int, int);
+ uint16_t, struct metal_sg *, int, int);
static int vq_ring_enable_interrupt(struct virtqueue *, uint16_t);
static void vq_ring_free_chain(struct virtqueue *, uint16_t);
static int vq_ring_must_notify_host(struct virtqueue *vq);
* inserted before writable buffers
*
* @param vq - Pointer to VirtIO queue control block.
- * @param buffer - Pointer to buffer list
+ * @param sg - Pointer to buffer scatter/gather list
* @param readable - Number of readable buffers
* @param writable - Number of writable buffers
* @param cookie - Pointer to hold call back data
*
* @return - Function status
*/
-int virtqueue_add_buffer(struct virtqueue *vq, struct llist *buffer,
+int virtqueue_add_buffer(struct virtqueue *vq, struct metal_sg *sg,
int readable, int writable, void *cookie)
{
dxp->ndescs = needed;
/* Enqueue buffer onto the ring. */
- idx = vq_ring_add_buffer(vq, vq->vq_ring.desc, head_idx, buffer,
+ idx = vq_ring_add_buffer(vq, vq->vq_ring.desc, head_idx, sg,
readable, writable);
vq->vq_desc_head_idx = idx;
*
* @param vq - Pointer to VirtIO queue control block
* @param cookie - Pointer to hold call back data
- * @param buffer_addr - Address of buffer
- * @param len - Length of buffer
+ * @param sg - metal_scatter/gather struct element
* @param writable - If buffer writable
* @param has_next - If buffers for subsequent call are
* to be chained
* @return - Function status
*/
int virtqueue_add_single_buffer(struct virtqueue *vq, void *cookie,
- void *buffer_addr, uint32_t len, int writable,
+ struct metal_sg *sg, int writable,
boolean has_next)
{
idx = head_idx;
dp = &vq->vq_ring.desc[idx];
- dp->addr = env_map_vatopa(buffer_addr);
- dp->len = len;
+ dp->addr = metal_io_virt_to_phys(sg->io, sg->virt);
+ dp->len = sg->len;
dp->flags = 0;
idx = dp->next;
*/
static uint16_t vq_ring_add_buffer(struct virtqueue *vq,
struct vring_desc *desc, uint16_t head_idx,
- struct llist *buffer, int readable,
+ struct metal_sg *sg, int readable,
int writable)
{
needed = readable + writable;
- for (i = 0, idx = head_idx; (i < needed && buffer != VQ_NULL);
- i++, idx = dp->next, buffer = buffer->next) {
+ for (i = 0, idx = head_idx; i < needed; i++, idx = dp->next) {
VQASSERT(vq, idx != VQ_RING_DESC_CHAIN_END,
"premature end of free desc chain");
dp = &desc[idx];
- dp->addr = env_map_vatopa(buffer->data);
- dp->len = buffer->attr;
+ dp->addr = metal_io_virt_to_phys(sg[i].io, sg[i].virt);
+ dp->len = sg[i].len;
dp->flags = 0;
if (i < needed - 1)