提交 9440b7e5 编写于 作者: G Gerd Hoffmann

usb-serial: iovec support

Add full support for iovecs to usb-serial.
Signed-off-by: NGerd Hoffmann <kraxel@redhat.com>
上级 4f4321c1
...@@ -359,38 +359,42 @@ static int usb_serial_handle_control(USBDevice *dev, USBPacket *p, ...@@ -359,38 +359,42 @@ static int usb_serial_handle_control(USBDevice *dev, USBPacket *p,
static int usb_serial_handle_data(USBDevice *dev, USBPacket *p) static int usb_serial_handle_data(USBDevice *dev, USBPacket *p)
{ {
USBSerialState *s = (USBSerialState *)dev; USBSerialState *s = (USBSerialState *)dev;
int ret = 0; int i, ret = 0;
uint8_t devep = p->devep; uint8_t devep = p->devep;
uint8_t *data = p->iov.iov[0].iov_base; struct iovec *iov;
int len = p->iov.iov[0].iov_len; uint8_t header[2];
int first_len; int first_len, len;
assert(p->iov.niov == 1); /* temporary */
switch (p->pid) { switch (p->pid) {
case USB_TOKEN_OUT: case USB_TOKEN_OUT:
if (devep != 2) if (devep != 2)
goto fail; goto fail;
qemu_chr_write(s->cs, data, len); for (i = 0; i < p->iov.niov; i++) {
iov = p->iov.iov + i;
qemu_chr_write(s->cs, iov->iov_base, iov->iov_len);
}
break; break;
case USB_TOKEN_IN: case USB_TOKEN_IN:
if (devep != 1) if (devep != 1)
goto fail; goto fail;
first_len = RECV_BUF - s->recv_ptr; first_len = RECV_BUF - s->recv_ptr;
len = p->iov.size;
if (len <= 2) { if (len <= 2) {
ret = USB_RET_NAK; ret = USB_RET_NAK;
break; break;
} }
*data++ = usb_get_modem_lines(s) | 1; header[0] = usb_get_modem_lines(s) | 1;
/* We do not have the uart details */ /* We do not have the uart details */
/* handle serial break */ /* handle serial break */
if (s->event_trigger && s->event_trigger & FTDI_BI) { if (s->event_trigger && s->event_trigger & FTDI_BI) {
s->event_trigger &= ~FTDI_BI; s->event_trigger &= ~FTDI_BI;
*data = FTDI_BI; header[1] = FTDI_BI;
usb_packet_copy(p, header, 2);
ret = 2; ret = 2;
break; break;
} else { } else {
*data++ = 0; header[1] = 0;
} }
len -= 2; len -= 2;
if (len > s->recv_used) if (len > s->recv_used)
...@@ -401,9 +405,10 @@ static int usb_serial_handle_data(USBDevice *dev, USBPacket *p) ...@@ -401,9 +405,10 @@ static int usb_serial_handle_data(USBDevice *dev, USBPacket *p)
} }
if (first_len > len) if (first_len > len)
first_len = len; first_len = len;
memcpy(data, s->recv_buf + s->recv_ptr, first_len); usb_packet_copy(p, header, 2);
usb_packet_copy(p, s->recv_buf + s->recv_ptr, first_len);
if (len > first_len) if (len > first_len)
memcpy(data + first_len, s->recv_buf, len - first_len); usb_packet_copy(p, s->recv_buf, len - first_len);
s->recv_used -= len; s->recv_used -= len;
s->recv_ptr = (s->recv_ptr + len) % RECV_BUF; s->recv_ptr = (s->recv_ptr + len) % RECV_BUF;
ret = len + 2; ret = len + 2;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册