aboutsummaryrefslogtreecommitdiff
path: root/dma-helpers.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2011-07-06 08:02:14 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2012-02-22 13:29:07 +0100
commit8171ee35e2ff3cea6c76280e361cf628b3a8c8df (patch)
treefcee5ccf9fc1a5a8f2f3e6db3e02dc1a6d224cdb /dma-helpers.c
parentfead0c24106993bc0ca87b7788bf2d9fd24e0a33 (diff)
dma-helpers: add dma_buf_read and dma_buf_write
These helpers do a full transfer from an in-memory buffer to target memory, with support for scatter/gather lists. It will be used to store the reply of an emulated command into a QEMUSGList provided by the adapter. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'dma-helpers.c')
-rw-r--r--dma-helpers.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/dma-helpers.c b/dma-helpers.c
index f08cdb5454..df0a42172f 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -204,3 +204,34 @@ BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
{
return dma_bdrv_io(bs, sg, sector, bdrv_aio_writev, cb, opaque, true);
}
+
+
+static uint64_t dma_buf_rw(uint8_t *ptr, int32_t len, QEMUSGList *sg, bool to_dev)
+{
+ uint64_t resid;
+ int sg_cur_index;
+
+ resid = sg->size;
+ sg_cur_index = 0;
+ len = MIN(len, resid);
+ while (len > 0) {
+ ScatterGatherEntry entry = sg->sg[sg_cur_index++];
+ int32_t xfer = MIN(len, entry.len);
+ cpu_physical_memory_rw(entry.base, ptr, xfer, !to_dev);
+ ptr += xfer;
+ len -= xfer;
+ resid -= xfer;
+ }
+
+ return resid;
+}
+
+uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg)
+{
+ return dma_buf_rw(ptr, len, sg, 0);
+}
+
+uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg)
+{
+ return dma_buf_rw(ptr, len, sg, 1);
+}