diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2011-07-12 15:22:25 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2011-08-04 15:51:22 +0200 |
commit | 4f4321c11ff6e98583846bfd6f0e81954924b003 (patch) | |
tree | 5b4c7f185539ed6a91b1c63c0841de7cff6a3ac5 /usb-linux.c | |
parent | d35bf9ade5293171f13bc5fd1460920a258e3e39 (diff) | |
download | qemu-4f4321c11ff6e98583846bfd6f0e81954924b003.tar.gz qemu-4f4321c11ff6e98583846bfd6f0e81954924b003.tar.bz2 qemu-4f4321c11ff6e98583846bfd6f0e81954924b003.zip |
usb: use iovecs in USBPacket
Zap data pointer from USBPacket, add a QEMUIOVector instead.
Add a bunch of helper functions to manage USBPacket data.
Switch over users to the new interface.
Note that USBPacket->len was used for two purposes: First to
pass in the buffer size and second to return the number of
transfered bytes or the status code on async transfers. There
is a new result variable for the latter. A new status code
was added to catch uninitialized result.
Nobody creates iovecs with more than one element (yet).
Some users are (temporarely) limited to iovecs with a single
element to keep the patch size as small as possible.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'usb-linux.c')
-rw-r--r-- | usb-linux.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/usb-linux.c b/usb-linux.c index 53cc5fc00e..184f56f499 100644 --- a/usb-linux.c +++ b/usb-linux.c @@ -341,16 +341,16 @@ static void async_complete(void *opaque) if (p) { switch (aurb->urb.status) { case 0: - p->len += aurb->urb.actual_length; + p->result += aurb->urb.actual_length; break; case -EPIPE: set_halt(s, p->devep); - p->len = USB_RET_STALL; + p->result = USB_RET_STALL; break; default: - p->len = USB_RET_NAK; + p->result = USB_RET_NAK; break; } @@ -604,6 +604,7 @@ static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in) { AsyncURB *aurb; int i, j, ret, max_packet_size, offset, len = 0; + uint8_t *buf; max_packet_size = get_max_packet_size(s, p->devep); if (max_packet_size == 0) @@ -628,19 +629,19 @@ static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in) len = urb_status_to_usb_ret( aurb[i].urb.iso_frame_desc[j].status); /* Check the frame fits */ - } else if (aurb[i].urb.iso_frame_desc[j].actual_length > p->len) { + } else if (aurb[i].urb.iso_frame_desc[j].actual_length + > p->iov.size) { printf("husb: received iso data is larger then packet\n"); len = USB_RET_NAK; /* All good copy data over */ } else { len = aurb[i].urb.iso_frame_desc[j].actual_length; - memcpy(p->data, - aurb[i].urb.buffer + - j * aurb[i].urb.iso_frame_desc[0].length, - len); + buf = aurb[i].urb.buffer + + j * aurb[i].urb.iso_frame_desc[0].length; + usb_packet_copy(p, buf, len); } } else { - len = p->len; + len = p->iov.size; offset = (j == 0) ? 0 : get_iso_buffer_used(s, p->devep); /* Check the frame fits */ @@ -650,7 +651,7 @@ static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in) } /* All good copy data over */ - memcpy(aurb[i].urb.buffer + offset, p->data, len); + usb_packet_copy(p, aurb[i].urb.buffer + offset, len); aurb[i].urb.iso_frame_desc[j].length = len; offset += len; set_iso_buffer_used(s, p->devep, offset); @@ -734,9 +735,9 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p) return usb_host_handle_iso_data(s, p, p->pid == USB_TOKEN_IN); } - rem = p->len; - pbuf = p->data; - p->len = 0; + assert(p->iov.niov == 1); /* temporary */ + rem = p->iov.iov[0].iov_len; + pbuf = p->iov.iov[0].iov_base; while (rem) { aurb = async_alloc(s); aurb->packet = p; |