diff options
-rw-r--r-- | hw/rtl8139.c | 2 | ||||
-rw-r--r-- | hw/usb/core.c | 6 | ||||
-rw-r--r-- | hw/virtio-balloon.c | 4 | ||||
-rw-r--r-- | hw/virtio-net.c | 4 | ||||
-rw-r--r-- | hw/virtio-serial-bus.c | 6 | ||||
-rw-r--r-- | iov.c | 14 | ||||
-rw-r--r-- | iov.h | 42 | ||||
-rw-r--r-- | net.c | 2 |
8 files changed, 56 insertions, 24 deletions
diff --git a/hw/rtl8139.c b/hw/rtl8139.c index eb22d04fad..8128b64a0f 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -1783,7 +1783,7 @@ static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size, if (iov) { buf2_size = iov_size(iov, 3); buf2 = g_malloc(buf2_size); - iov_to_buf(iov, 3, buf2, 0, buf2_size); + iov_to_buf(iov, 3, 0, buf2, buf2_size); buf = buf2; } diff --git a/hw/usb/core.c b/hw/usb/core.c index 0e02da7601..2641685a32 100644 --- a/hw/usb/core.c +++ b/hw/usb/core.c @@ -522,10 +522,10 @@ void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes) switch (p->pid) { case USB_TOKEN_SETUP: case USB_TOKEN_OUT: - iov_to_buf(p->iov.iov, p->iov.niov, ptr, p->result, bytes); + iov_to_buf(p->iov.iov, p->iov.niov, p->result, ptr, bytes); break; case USB_TOKEN_IN: - iov_from_buf(p->iov.iov, p->iov.niov, ptr, p->result, bytes); + iov_from_buf(p->iov.iov, p->iov.niov, p->result, ptr, bytes); break; default: fprintf(stderr, "%s: invalid pid: %x\n", __func__, p->pid); @@ -539,7 +539,7 @@ void usb_packet_skip(USBPacket *p, size_t bytes) assert(p->result >= 0); assert(p->result + bytes <= p->iov.size); if (p->pid == USB_TOKEN_IN) { - iov_clear(p->iov.iov, p->iov.niov, p->result, bytes); + iov_memset(p->iov.iov, p->iov.niov, p->result, 0, bytes); } p->result += bytes; } diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c index 075ed87e37..23effa40a0 100644 --- a/hw/virtio-balloon.c +++ b/hw/virtio-balloon.c @@ -77,7 +77,7 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) size_t offset = 0; uint32_t pfn; - while (iov_to_buf(elem.out_sg, elem.out_num, &pfn, offset, 4) == 4) { + while (iov_to_buf(elem.out_sg, elem.out_num, offset, &pfn, 4) == 4) { ram_addr_t pa; ram_addr_t addr; @@ -118,7 +118,7 @@ static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq) */ reset_stats(s); - while (iov_to_buf(elem->out_sg, elem->out_num, &stat, offset, sizeof(stat)) + while (iov_to_buf(elem->out_sg, elem->out_num, offset, &stat, sizeof(stat)) == sizeof(stat)) { uint16_t tag = tswap16(stat.tag); uint64_t val = tswap64(stat.val); diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 3f190d417e..533aa3d0f3 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -656,8 +656,8 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_ } /* copy in packet. ugh */ - len = iov_from_buf(sg, elem.in_num, - buf + offset, 0, size - offset); + len = iov_from_buf(sg, elem.in_num, 0, + buf + offset, size - offset); total += len; offset += len; /* If buffers can't be merged, at this point we diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c index 1e477e5a33..728f218dcf 100644 --- a/hw/virtio-serial-bus.c +++ b/hw/virtio-serial-bus.c @@ -106,8 +106,8 @@ static size_t write_to_port(VirtIOSerialPort *port, break; } - len = iov_from_buf(elem.in_sg, elem.in_num, - buf + offset, 0, size - offset); + len = iov_from_buf(elem.in_sg, elem.in_num, 0, + buf + offset, size - offset); offset += len; virtqueue_push(vq, &elem, len); @@ -467,7 +467,7 @@ static void control_out(VirtIODevice *vdev, VirtQueue *vq) buf = g_malloc(cur_len); len = cur_len; } - iov_to_buf(elem.out_sg, elem.out_num, buf, 0, cur_len); + iov_to_buf(elem.out_sg, elem.out_num, 0, buf, cur_len); handle_control_message(vser, buf, cur_len); virtqueue_push(vq, &elem, 0); @@ -17,8 +17,8 @@ #include "iov.h" -size_t iov_from_buf(struct iovec *iov, unsigned int iov_cnt, - const void *buf, size_t iov_off, size_t size) +size_t iov_from_buf(struct iovec *iov, unsigned int iov_cnt, size_t iov_off, + const void *buf, size_t size) { size_t iovec_off, buf_off; unsigned int i; @@ -40,8 +40,8 @@ size_t iov_from_buf(struct iovec *iov, unsigned int iov_cnt, return buf_off; } -size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt, - void *buf, size_t iov_off, size_t size) +size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt, size_t iov_off, + void *buf, size_t size) { uint8_t *ptr; size_t iovec_off, buf_off; @@ -65,8 +65,8 @@ size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt, return buf_off; } -size_t iov_clear(const struct iovec *iov, const unsigned int iov_cnt, - size_t iov_off, size_t size) +size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt, + size_t iov_off, int fillc, size_t size) { size_t iovec_off, buf_off; unsigned int i; @@ -77,7 +77,7 @@ size_t iov_clear(const struct iovec *iov, const unsigned int iov_cnt, if (iov_off < (iovec_off + iov[i].iov_len)) { size_t len = MIN((iovec_off + iov[i].iov_len) - iov_off , size); - memset(iov[i].iov_base + (iov_off - iovec_off), 0, len); + memset(iov[i].iov_base + (iov_off - iovec_off), fillc, len); buf_off += len; iov_off += len; @@ -12,12 +12,44 @@ #include "qemu-common.h" +/** + * count and return data size, in bytes, of an iovec + * starting at `iov' of `iov_cnt' number of elements. + */ +size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt); + +/** + * Copy from single continuous buffer to scatter-gather vector of buffers + * (iovec) and back like memcpy() between two continuous memory regions. + * Data in single continuous buffer starting at address `buf' and + * `bytes' bytes long will be copied to/from an iovec `iov' with + * `iov_cnt' number of elements, starting at byte position `offset' + * within the iovec. If the iovec does not contain enough space, + * only part of data will be copied, up to the end of the iovec. + * Number of bytes actually copied will be returned, which is + * min(bytes, iov_size(iov)-offset) + */ size_t iov_from_buf(struct iovec *iov, unsigned int iov_cnt, - const void *buf, size_t iov_off, size_t size); + size_t offset, const void *buf, size_t bytes); size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt, - void *buf, size_t iov_off, size_t size); -size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt); -size_t iov_clear(const struct iovec *iov, const unsigned int iov_cnt, - size_t iov_off, size_t size); + size_t offset, void *buf, size_t bytes); + +/** + * Set data bytes pointed out by iovec `iov' of size `iov_cnt' elements, + * starting at byte offset `start', to value `fillc', repeating it + * `bytes' number of times. + * If `bytes' is large enough, only last bytes portion of iovec, + * up to the end of it, will be filled with the specified value. + * Function return actual number of bytes processed, which is + * min(size, iov_size(iov) - offset). + */ +size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt, + size_t offset, int fillc, size_t bytes); + +/** + * Produce a text hexdump of iovec `iov' with `iov_cnt' number of elements + * in file `fp', prefixing each line with `prefix' and processing not more + * than `limit' data bytes. + */ void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt, FILE *fp, const char *prefix, size_t limit); @@ -544,7 +544,7 @@ static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov, uint8_t buffer[4096]; size_t offset; - offset = iov_to_buf(iov, iovcnt, buffer, 0, sizeof(buffer)); + offset = iov_to_buf(iov, iovcnt, 0, buffer, sizeof(buffer)); return vc->info->receive(vc, buffer, offset); } |