diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2011-07-06 08:02:14 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2012-02-22 13:29:07 +0100 |
commit | 8171ee35e2ff3cea6c76280e361cf628b3a8c8df (patch) | |
tree | fcee5ccf9fc1a5a8f2f3e6db3e02dc1a6d224cdb /dma-helpers.c | |
parent | fead0c24106993bc0ca87b7788bf2d9fd24e0a33 (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.c | 31 |
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); +} |