usb-redir: Clear iso / irq error when stopping the stream
[qemu.git] / usb-redir.c
blob81a35c60bd2ebba396679e2545f33bce8cb5ea48
1 /*
2 * USB redirector usb-guest
4 * Copyright (c) 2011 Red Hat, Inc.
6 * Red Hat Authors:
7 * Hans de Goede <hdegoede@redhat.com>
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
28 #include "qemu-common.h"
29 #include "qemu-timer.h"
30 #include "monitor.h"
31 #include "sysemu.h"
33 #include <dirent.h>
34 #include <sys/ioctl.h>
35 #include <signal.h>
36 #include <usbredirparser.h>
38 #include "hw/usb.h"
40 #define MAX_ENDPOINTS 32
41 #define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f))
42 #define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f))
44 typedef struct AsyncURB AsyncURB;
45 typedef struct USBRedirDevice USBRedirDevice;
47 /* Struct to hold buffered packets (iso or int input packets) */
48 struct buf_packet {
49 uint8_t *data;
50 int len;
51 int status;
52 QTAILQ_ENTRY(buf_packet)next;
55 struct endp_data {
56 uint8_t type;
57 uint8_t interval;
58 uint8_t interface; /* bInterfaceNumber this ep belongs to */
59 uint8_t iso_started;
60 uint8_t iso_error; /* For reporting iso errors to the HC */
61 uint8_t interrupt_started;
62 uint8_t interrupt_error;
63 QTAILQ_HEAD(, buf_packet) bufpq;
66 struct USBRedirDevice {
67 USBDevice dev;
68 /* Properties */
69 CharDriverState *cs;
70 uint8_t debug;
71 /* Data passed from chardev the fd_read cb to the usbredirparser read cb */
72 const uint8_t *read_buf;
73 int read_buf_size;
74 /* For async handling of open/close */
75 QEMUBH *open_close_bh;
76 /* To delay the usb attach in case of quick chardev close + open */
77 QEMUTimer *attach_timer;
78 int64_t next_attach_time;
79 struct usbredirparser *parser;
80 struct endp_data endpoint[MAX_ENDPOINTS];
81 uint32_t packet_id;
82 QTAILQ_HEAD(, AsyncURB) asyncq;
85 struct AsyncURB {
86 USBRedirDevice *dev;
87 USBPacket *packet;
88 uint32_t packet_id;
89 int get;
90 union {
91 struct usb_redir_control_packet_header control_packet;
92 struct usb_redir_bulk_packet_header bulk_packet;
93 struct usb_redir_interrupt_packet_header interrupt_packet;
95 QTAILQ_ENTRY(AsyncURB)next;
98 static void usbredir_device_connect(void *priv,
99 struct usb_redir_device_connect_header *device_connect);
100 static void usbredir_device_disconnect(void *priv);
101 static void usbredir_interface_info(void *priv,
102 struct usb_redir_interface_info_header *interface_info);
103 static void usbredir_ep_info(void *priv,
104 struct usb_redir_ep_info_header *ep_info);
105 static void usbredir_configuration_status(void *priv, uint32_t id,
106 struct usb_redir_configuration_status_header *configuration_status);
107 static void usbredir_alt_setting_status(void *priv, uint32_t id,
108 struct usb_redir_alt_setting_status_header *alt_setting_status);
109 static void usbredir_iso_stream_status(void *priv, uint32_t id,
110 struct usb_redir_iso_stream_status_header *iso_stream_status);
111 static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
112 struct usb_redir_interrupt_receiving_status_header
113 *interrupt_receiving_status);
114 static void usbredir_bulk_streams_status(void *priv, uint32_t id,
115 struct usb_redir_bulk_streams_status_header *bulk_streams_status);
116 static void usbredir_control_packet(void *priv, uint32_t id,
117 struct usb_redir_control_packet_header *control_packet,
118 uint8_t *data, int data_len);
119 static void usbredir_bulk_packet(void *priv, uint32_t id,
120 struct usb_redir_bulk_packet_header *bulk_packet,
121 uint8_t *data, int data_len);
122 static void usbredir_iso_packet(void *priv, uint32_t id,
123 struct usb_redir_iso_packet_header *iso_packet,
124 uint8_t *data, int data_len);
125 static void usbredir_interrupt_packet(void *priv, uint32_t id,
126 struct usb_redir_interrupt_packet_header *interrupt_header,
127 uint8_t *data, int data_len);
129 static int usbredir_handle_status(USBRedirDevice *dev,
130 int status, int actual_len);
132 #define VERSION "qemu usb-redir guest " QEMU_VERSION
135 * Logging stuff
138 #define ERROR(...) \
139 do { \
140 if (dev->debug >= usbredirparser_error) { \
141 error_report("usb-redir error: " __VA_ARGS__); \
143 } while (0)
144 #define WARNING(...) \
145 do { \
146 if (dev->debug >= usbredirparser_warning) { \
147 error_report("usb-redir warning: " __VA_ARGS__); \
149 } while (0)
150 #define INFO(...) \
151 do { \
152 if (dev->debug >= usbredirparser_info) { \
153 error_report("usb-redir: " __VA_ARGS__); \
155 } while (0)
156 #define DPRINTF(...) \
157 do { \
158 if (dev->debug >= usbredirparser_debug) { \
159 error_report("usb-redir: " __VA_ARGS__); \
161 } while (0)
162 #define DPRINTF2(...) \
163 do { \
164 if (dev->debug >= usbredirparser_debug_data) { \
165 error_report("usb-redir: " __VA_ARGS__); \
167 } while (0)
169 static void usbredir_log(void *priv, int level, const char *msg)
171 USBRedirDevice *dev = priv;
173 if (dev->debug < level) {
174 return;
177 error_report("%s", msg);
180 static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
181 const uint8_t *data, int len)
183 int i, j, n;
185 if (dev->debug < usbredirparser_debug_data) {
186 return;
189 for (i = 0; i < len; i += j) {
190 char buf[128];
192 n = sprintf(buf, "%s", desc);
193 for (j = 0; j < 8 && i + j < len; j++) {
194 n += sprintf(buf + n, " %02X", data[i + j]);
196 error_report("%s", buf);
201 * usbredirparser io functions
204 static int usbredir_read(void *priv, uint8_t *data, int count)
206 USBRedirDevice *dev = priv;
208 if (dev->read_buf_size < count) {
209 count = dev->read_buf_size;
212 memcpy(data, dev->read_buf, count);
214 dev->read_buf_size -= count;
215 if (dev->read_buf_size) {
216 dev->read_buf += count;
217 } else {
218 dev->read_buf = NULL;
221 return count;
224 static int usbredir_write(void *priv, uint8_t *data, int count)
226 USBRedirDevice *dev = priv;
228 if (!dev->cs->opened) {
229 return 0;
232 return qemu_chr_fe_write(dev->cs, data, count);
236 * Async and buffered packets helpers
239 static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
241 AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
242 aurb->dev = dev;
243 aurb->packet = p;
244 aurb->packet_id = dev->packet_id;
245 QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
246 dev->packet_id++;
248 return aurb;
251 static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
253 QTAILQ_REMOVE(&dev->asyncq, aurb, next);
254 g_free(aurb);
257 static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
259 AsyncURB *aurb;
261 QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
262 if (aurb->packet_id == packet_id) {
263 return aurb;
266 ERROR("could not find async urb for packet_id %u\n", packet_id);
267 return NULL;
270 static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
272 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
273 AsyncURB *aurb;
275 QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
276 if (p != aurb->packet) {
277 continue;
280 DPRINTF("async cancel id %u\n", aurb->packet_id);
281 usbredirparser_send_cancel_data_packet(dev->parser, aurb->packet_id);
282 usbredirparser_do_write(dev->parser);
284 /* Mark it as dead */
285 aurb->packet = NULL;
286 break;
290 static struct buf_packet *bufp_alloc(USBRedirDevice *dev,
291 uint8_t *data, int len, int status, uint8_t ep)
293 struct buf_packet *bufp = g_malloc(sizeof(struct buf_packet));
294 bufp->data = data;
295 bufp->len = len;
296 bufp->status = status;
297 QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
298 return bufp;
301 static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
302 uint8_t ep)
304 QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
305 free(bufp->data);
306 g_free(bufp);
309 static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
311 struct buf_packet *buf, *buf_next;
313 QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) {
314 bufp_free(dev, buf, ep);
319 * USBDevice callbacks
322 static void usbredir_handle_reset(USBDevice *udev)
324 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
326 DPRINTF("reset device\n");
327 usbredirparser_send_reset(dev->parser);
328 usbredirparser_do_write(dev->parser);
331 static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
332 uint8_t ep)
334 int status, len;
336 if (!dev->endpoint[EP2I(ep)].iso_started &&
337 !dev->endpoint[EP2I(ep)].iso_error) {
338 struct usb_redir_start_iso_stream_header start_iso = {
339 .endpoint = ep,
340 /* TODO maybe do something with these depending on ep interval? */
341 .pkts_per_urb = 32,
342 .no_urbs = 3,
344 /* No id, we look at the ep when receiving a status back */
345 usbredirparser_send_start_iso_stream(dev->parser, 0, &start_iso);
346 usbredirparser_do_write(dev->parser);
347 DPRINTF("iso stream started ep %02X\n", ep);
348 dev->endpoint[EP2I(ep)].iso_started = 1;
351 if (ep & USB_DIR_IN) {
352 struct buf_packet *isop;
354 isop = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
355 if (isop == NULL) {
356 DPRINTF2("iso-token-in ep %02X, no isop\n", ep);
357 /* Check iso_error for stream errors, otherwise its an underrun */
358 status = dev->endpoint[EP2I(ep)].iso_error;
359 dev->endpoint[EP2I(ep)].iso_error = 0;
360 return usbredir_handle_status(dev, status, 0);
362 DPRINTF2("iso-token-in ep %02X status %d len %d\n", ep, isop->status,
363 isop->len);
365 status = isop->status;
366 if (status != usb_redir_success) {
367 bufp_free(dev, isop, ep);
368 return usbredir_handle_status(dev, status, 0);
371 len = isop->len;
372 if (len > p->iov.size) {
373 ERROR("received iso data is larger then packet ep %02X\n", ep);
374 bufp_free(dev, isop, ep);
375 return USB_RET_NAK;
377 usb_packet_copy(p, isop->data, len);
378 bufp_free(dev, isop, ep);
379 return len;
380 } else {
381 /* If the stream was not started because of a pending error don't
382 send the packet to the usb-host */
383 if (dev->endpoint[EP2I(ep)].iso_started) {
384 struct usb_redir_iso_packet_header iso_packet = {
385 .endpoint = ep,
386 .length = p->iov.size
388 uint8_t buf[p->iov.size];
389 /* No id, we look at the ep when receiving a status back */
390 usb_packet_copy(p, buf, p->iov.size);
391 usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,
392 buf, p->iov.size);
393 usbredirparser_do_write(dev->parser);
395 status = dev->endpoint[EP2I(ep)].iso_error;
396 dev->endpoint[EP2I(ep)].iso_error = 0;
397 DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep, status,
398 p->iov.size);
399 return usbredir_handle_status(dev, status, p->iov.size);
403 static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
405 struct usb_redir_stop_iso_stream_header stop_iso_stream = {
406 .endpoint = ep
408 if (dev->endpoint[EP2I(ep)].iso_started) {
409 usbredirparser_send_stop_iso_stream(dev->parser, 0, &stop_iso_stream);
410 DPRINTF("iso stream stopped ep %02X\n", ep);
411 dev->endpoint[EP2I(ep)].iso_started = 0;
413 dev->endpoint[EP2I(ep)].iso_error = 0;
414 usbredir_free_bufpq(dev, ep);
417 static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
418 uint8_t ep)
420 AsyncURB *aurb = async_alloc(dev, p);
421 struct usb_redir_bulk_packet_header bulk_packet;
423 DPRINTF("bulk-out ep %02X len %zd id %u\n", ep,
424 p->iov.size, aurb->packet_id);
426 bulk_packet.endpoint = ep;
427 bulk_packet.length = p->iov.size;
428 bulk_packet.stream_id = 0;
429 aurb->bulk_packet = bulk_packet;
431 if (ep & USB_DIR_IN) {
432 usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
433 &bulk_packet, NULL, 0);
434 } else {
435 uint8_t buf[p->iov.size];
436 usb_packet_copy(p, buf, p->iov.size);
437 usbredir_log_data(dev, "bulk data out:", buf, p->iov.size);
438 usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
439 &bulk_packet, buf, p->iov.size);
441 usbredirparser_do_write(dev->parser);
442 return USB_RET_ASYNC;
445 static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
446 USBPacket *p, uint8_t ep)
448 if (ep & USB_DIR_IN) {
449 /* Input interrupt endpoint, buffered packet input */
450 struct buf_packet *intp;
451 int status, len;
453 if (!dev->endpoint[EP2I(ep)].interrupt_started &&
454 !dev->endpoint[EP2I(ep)].interrupt_error) {
455 struct usb_redir_start_interrupt_receiving_header start_int = {
456 .endpoint = ep,
458 /* No id, we look at the ep when receiving a status back */
459 usbredirparser_send_start_interrupt_receiving(dev->parser, 0,
460 &start_int);
461 usbredirparser_do_write(dev->parser);
462 DPRINTF("interrupt recv started ep %02X\n", ep);
463 dev->endpoint[EP2I(ep)].interrupt_started = 1;
466 intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
467 if (intp == NULL) {
468 DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);
469 /* Check interrupt_error for stream errors */
470 status = dev->endpoint[EP2I(ep)].interrupt_error;
471 dev->endpoint[EP2I(ep)].interrupt_error = 0;
472 return usbredir_handle_status(dev, status, 0);
474 DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,
475 intp->status, intp->len);
477 status = intp->status;
478 if (status != usb_redir_success) {
479 bufp_free(dev, intp, ep);
480 return usbredir_handle_status(dev, status, 0);
483 len = intp->len;
484 if (len > p->iov.size) {
485 ERROR("received int data is larger then packet ep %02X\n", ep);
486 bufp_free(dev, intp, ep);
487 return USB_RET_NAK;
489 usb_packet_copy(p, intp->data, len);
490 bufp_free(dev, intp, ep);
491 return len;
492 } else {
493 /* Output interrupt endpoint, normal async operation */
494 AsyncURB *aurb = async_alloc(dev, p);
495 struct usb_redir_interrupt_packet_header interrupt_packet;
496 uint8_t buf[p->iov.size];
498 DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep, p->iov.size,
499 aurb->packet_id);
501 interrupt_packet.endpoint = ep;
502 interrupt_packet.length = p->iov.size;
503 aurb->interrupt_packet = interrupt_packet;
505 usb_packet_copy(p, buf, p->iov.size);
506 usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);
507 usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
508 &interrupt_packet, buf, p->iov.size);
509 usbredirparser_do_write(dev->parser);
510 return USB_RET_ASYNC;
514 static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev,
515 uint8_t ep)
517 struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv = {
518 .endpoint = ep
520 if (dev->endpoint[EP2I(ep)].interrupt_started) {
521 usbredirparser_send_stop_interrupt_receiving(dev->parser, 0,
522 &stop_interrupt_recv);
523 DPRINTF("interrupt recv stopped ep %02X\n", ep);
524 dev->endpoint[EP2I(ep)].interrupt_started = 0;
526 dev->endpoint[EP2I(ep)].interrupt_error = 0;
527 usbredir_free_bufpq(dev, ep);
530 static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
532 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
533 uint8_t ep;
535 ep = p->devep;
536 if (p->pid == USB_TOKEN_IN) {
537 ep |= USB_DIR_IN;
540 switch (dev->endpoint[EP2I(ep)].type) {
541 case USB_ENDPOINT_XFER_CONTROL:
542 ERROR("handle_data called for control transfer on ep %02X\n", ep);
543 return USB_RET_NAK;
544 case USB_ENDPOINT_XFER_ISOC:
545 return usbredir_handle_iso_data(dev, p, ep);
546 case USB_ENDPOINT_XFER_BULK:
547 return usbredir_handle_bulk_data(dev, p, ep);
548 case USB_ENDPOINT_XFER_INT:
549 return usbredir_handle_interrupt_data(dev, p, ep);
550 default:
551 ERROR("handle_data ep %02X has unknown type %d\n", ep,
552 dev->endpoint[EP2I(ep)].type);
553 return USB_RET_NAK;
557 static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
558 int config)
560 struct usb_redir_set_configuration_header set_config;
561 AsyncURB *aurb = async_alloc(dev, p);
562 int i;
564 DPRINTF("set config %d id %u\n", config, aurb->packet_id);
566 for (i = 0; i < MAX_ENDPOINTS; i++) {
567 switch (dev->endpoint[i].type) {
568 case USB_ENDPOINT_XFER_ISOC:
569 usbredir_stop_iso_stream(dev, I2EP(i));
570 break;
571 case USB_ENDPOINT_XFER_INT:
572 if (i & 0x10) {
573 usbredir_stop_interrupt_receiving(dev, I2EP(i));
575 break;
577 usbredir_free_bufpq(dev, I2EP(i));
580 set_config.configuration = config;
581 usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
582 &set_config);
583 usbredirparser_do_write(dev->parser);
584 return USB_RET_ASYNC;
587 static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
589 AsyncURB *aurb = async_alloc(dev, p);
591 DPRINTF("get config id %u\n", aurb->packet_id);
593 aurb->get = 1;
594 usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
595 usbredirparser_do_write(dev->parser);
596 return USB_RET_ASYNC;
599 static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
600 int interface, int alt)
602 struct usb_redir_set_alt_setting_header set_alt;
603 AsyncURB *aurb = async_alloc(dev, p);
604 int i;
606 DPRINTF("set interface %d alt %d id %u\n", interface, alt,
607 aurb->packet_id);
609 for (i = 0; i < MAX_ENDPOINTS; i++) {
610 if (dev->endpoint[i].interface == interface) {
611 switch (dev->endpoint[i].type) {
612 case USB_ENDPOINT_XFER_ISOC:
613 usbredir_stop_iso_stream(dev, I2EP(i));
614 break;
615 case USB_ENDPOINT_XFER_INT:
616 if (i & 0x10) {
617 usbredir_stop_interrupt_receiving(dev, I2EP(i));
619 break;
621 usbredir_free_bufpq(dev, I2EP(i));
625 set_alt.interface = interface;
626 set_alt.alt = alt;
627 usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
628 &set_alt);
629 usbredirparser_do_write(dev->parser);
630 return USB_RET_ASYNC;
633 static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
634 int interface)
636 struct usb_redir_get_alt_setting_header get_alt;
637 AsyncURB *aurb = async_alloc(dev, p);
639 DPRINTF("get interface %d id %u\n", interface, aurb->packet_id);
641 get_alt.interface = interface;
642 aurb->get = 1;
643 usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
644 &get_alt);
645 usbredirparser_do_write(dev->parser);
646 return USB_RET_ASYNC;
649 static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
650 int request, int value, int index, int length, uint8_t *data)
652 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
653 struct usb_redir_control_packet_header control_packet;
654 AsyncURB *aurb;
656 /* Special cases for certain standard device requests */
657 switch (request) {
658 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
659 DPRINTF("set address %d\n", value);
660 dev->dev.addr = value;
661 return 0;
662 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
663 return usbredir_set_config(dev, p, value & 0xff);
664 case DeviceRequest | USB_REQ_GET_CONFIGURATION:
665 return usbredir_get_config(dev, p);
666 case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
667 return usbredir_set_interface(dev, p, index, value);
668 case InterfaceRequest | USB_REQ_GET_INTERFACE:
669 return usbredir_get_interface(dev, p, index);
672 /* "Normal" ctrl requests */
673 aurb = async_alloc(dev, p);
675 /* Note request is (bRequestType << 8) | bRequest */
676 DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
677 request >> 8, request & 0xff, value, index, length,
678 aurb->packet_id);
680 control_packet.request = request & 0xFF;
681 control_packet.requesttype = request >> 8;
682 control_packet.endpoint = control_packet.requesttype & USB_DIR_IN;
683 control_packet.value = value;
684 control_packet.index = index;
685 control_packet.length = length;
686 aurb->control_packet = control_packet;
688 if (control_packet.requesttype & USB_DIR_IN) {
689 usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
690 &control_packet, NULL, 0);
691 } else {
692 usbredir_log_data(dev, "ctrl data out:", data, length);
693 usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
694 &control_packet, data, length);
696 usbredirparser_do_write(dev->parser);
697 return USB_RET_ASYNC;
701 * Close events can be triggered by usbredirparser_do_write which gets called
702 * from within the USBDevice data / control packet callbacks and doing a
703 * usb_detach from within these callbacks is not a good idea.
705 * So we use a bh handler to take care of close events. We also handle
706 * open events from this callback to make sure that a close directly followed
707 * by an open gets handled in the right order.
709 static void usbredir_open_close_bh(void *opaque)
711 USBRedirDevice *dev = opaque;
713 usbredir_device_disconnect(dev);
715 if (dev->parser) {
716 usbredirparser_destroy(dev->parser);
717 dev->parser = NULL;
720 if (dev->cs->opened) {
721 dev->parser = qemu_oom_check(usbredirparser_create());
722 dev->parser->priv = dev;
723 dev->parser->log_func = usbredir_log;
724 dev->parser->read_func = usbredir_read;
725 dev->parser->write_func = usbredir_write;
726 dev->parser->device_connect_func = usbredir_device_connect;
727 dev->parser->device_disconnect_func = usbredir_device_disconnect;
728 dev->parser->interface_info_func = usbredir_interface_info;
729 dev->parser->ep_info_func = usbredir_ep_info;
730 dev->parser->configuration_status_func = usbredir_configuration_status;
731 dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
732 dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
733 dev->parser->interrupt_receiving_status_func =
734 usbredir_interrupt_receiving_status;
735 dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
736 dev->parser->control_packet_func = usbredir_control_packet;
737 dev->parser->bulk_packet_func = usbredir_bulk_packet;
738 dev->parser->iso_packet_func = usbredir_iso_packet;
739 dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
740 dev->read_buf = NULL;
741 dev->read_buf_size = 0;
742 usbredirparser_init(dev->parser, VERSION, NULL, 0, 0);
743 usbredirparser_do_write(dev->parser);
747 static void usbredir_do_attach(void *opaque)
749 USBRedirDevice *dev = opaque;
751 usb_device_attach(&dev->dev);
755 * chardev callbacks
758 static int usbredir_chardev_can_read(void *opaque)
760 USBRedirDevice *dev = opaque;
762 if (dev->parser) {
763 /* usbredir_parser_do_read will consume *all* data we give it */
764 return 1024 * 1024;
765 } else {
766 /* usbredir_open_close_bh hasn't handled the open event yet */
767 return 0;
771 static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
773 USBRedirDevice *dev = opaque;
775 /* No recursion allowed! */
776 assert(dev->read_buf == NULL);
778 dev->read_buf = buf;
779 dev->read_buf_size = size;
781 usbredirparser_do_read(dev->parser);
782 /* Send any acks, etc. which may be queued now */
783 usbredirparser_do_write(dev->parser);
786 static void usbredir_chardev_event(void *opaque, int event)
788 USBRedirDevice *dev = opaque;
790 switch (event) {
791 case CHR_EVENT_OPENED:
792 case CHR_EVENT_CLOSED:
793 qemu_bh_schedule(dev->open_close_bh);
794 break;
799 * init + destroy
802 static int usbredir_initfn(USBDevice *udev)
804 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
805 int i;
807 if (dev->cs == NULL) {
808 qerror_report(QERR_MISSING_PARAMETER, "chardev");
809 return -1;
812 dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
813 dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
815 QTAILQ_INIT(&dev->asyncq);
816 for (i = 0; i < MAX_ENDPOINTS; i++) {
817 QTAILQ_INIT(&dev->endpoint[i].bufpq);
820 /* We'll do the attach once we receive the speed from the usb-host */
821 udev->auto_attach = 0;
823 /* Let the backend know we are ready */
824 qemu_chr_fe_open(dev->cs);
825 qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
826 usbredir_chardev_read, usbredir_chardev_event, dev);
828 return 0;
831 static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
833 AsyncURB *aurb, *next_aurb;
834 int i;
836 QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
837 async_free(dev, aurb);
839 for (i = 0; i < MAX_ENDPOINTS; i++) {
840 usbredir_free_bufpq(dev, I2EP(i));
844 static void usbredir_handle_destroy(USBDevice *udev)
846 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
848 qemu_chr_fe_close(dev->cs);
849 qemu_chr_delete(dev->cs);
850 /* Note must be done after qemu_chr_close, as that causes a close event */
851 qemu_bh_delete(dev->open_close_bh);
853 qemu_del_timer(dev->attach_timer);
854 qemu_free_timer(dev->attach_timer);
856 usbredir_cleanup_device_queues(dev);
858 if (dev->parser) {
859 usbredirparser_destroy(dev->parser);
864 * usbredirparser packet complete callbacks
867 static int usbredir_handle_status(USBRedirDevice *dev,
868 int status, int actual_len)
870 switch (status) {
871 case usb_redir_success:
872 return actual_len;
873 case usb_redir_stall:
874 return USB_RET_STALL;
875 case usb_redir_cancelled:
876 WARNING("returning cancelled packet to HC?\n");
877 case usb_redir_inval:
878 case usb_redir_ioerror:
879 case usb_redir_timeout:
880 default:
881 return USB_RET_NAK;
885 static void usbredir_device_connect(void *priv,
886 struct usb_redir_device_connect_header *device_connect)
888 USBRedirDevice *dev = priv;
890 if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
891 ERROR("Received device connect while already connected\n");
892 return;
895 switch (device_connect->speed) {
896 case usb_redir_speed_low:
897 DPRINTF("attaching low speed device\n");
898 dev->dev.speed = USB_SPEED_LOW;
899 break;
900 case usb_redir_speed_full:
901 DPRINTF("attaching full speed device\n");
902 dev->dev.speed = USB_SPEED_FULL;
903 break;
904 case usb_redir_speed_high:
905 DPRINTF("attaching high speed device\n");
906 dev->dev.speed = USB_SPEED_HIGH;
907 break;
908 case usb_redir_speed_super:
909 DPRINTF("attaching super speed device\n");
910 dev->dev.speed = USB_SPEED_SUPER;
911 break;
912 default:
913 DPRINTF("attaching unknown speed device, assuming full speed\n");
914 dev->dev.speed = USB_SPEED_FULL;
916 dev->dev.speedmask = (1 << dev->dev.speed);
917 qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
920 static void usbredir_device_disconnect(void *priv)
922 USBRedirDevice *dev = priv;
923 int i;
925 /* Stop any pending attaches */
926 qemu_del_timer(dev->attach_timer);
928 if (dev->dev.attached) {
929 usb_device_detach(&dev->dev);
931 * Delay next usb device attach to give the guest a chance to see
932 * see the detach / attach in case of quick close / open succession
934 dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
937 /* Reset state so that the next dev connected starts with a clean slate */
938 usbredir_cleanup_device_queues(dev);
939 memset(dev->endpoint, 0, sizeof(dev->endpoint));
940 for (i = 0; i < MAX_ENDPOINTS; i++) {
941 QTAILQ_INIT(&dev->endpoint[i].bufpq);
945 static void usbredir_interface_info(void *priv,
946 struct usb_redir_interface_info_header *interface_info)
948 /* The intention is to allow specifying acceptable interface classes
949 for redirection on the cmdline and in the future verify this here,
950 and disconnect (or never connect) the device if a not accepted
951 interface class is detected */
954 static void usbredir_ep_info(void *priv,
955 struct usb_redir_ep_info_header *ep_info)
957 USBRedirDevice *dev = priv;
958 int i;
960 for (i = 0; i < MAX_ENDPOINTS; i++) {
961 dev->endpoint[i].type = ep_info->type[i];
962 dev->endpoint[i].interval = ep_info->interval[i];
963 dev->endpoint[i].interface = ep_info->interface[i];
964 if (dev->endpoint[i].type != usb_redir_type_invalid) {
965 DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
966 dev->endpoint[i].type, dev->endpoint[i].interface);
971 static void usbredir_configuration_status(void *priv, uint32_t id,
972 struct usb_redir_configuration_status_header *config_status)
974 USBRedirDevice *dev = priv;
975 AsyncURB *aurb;
976 int len = 0;
978 DPRINTF("set config status %d config %d id %u\n", config_status->status,
979 config_status->configuration, id);
981 aurb = async_find(dev, id);
982 if (!aurb) {
983 return;
985 if (aurb->packet) {
986 if (aurb->get) {
987 dev->dev.data_buf[0] = config_status->configuration;
988 len = 1;
990 aurb->packet->result =
991 usbredir_handle_status(dev, config_status->status, len);
992 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
994 async_free(dev, aurb);
997 static void usbredir_alt_setting_status(void *priv, uint32_t id,
998 struct usb_redir_alt_setting_status_header *alt_setting_status)
1000 USBRedirDevice *dev = priv;
1001 AsyncURB *aurb;
1002 int len = 0;
1004 DPRINTF("alt status %d intf %d alt %d id: %u\n",
1005 alt_setting_status->status,
1006 alt_setting_status->interface,
1007 alt_setting_status->alt, id);
1009 aurb = async_find(dev, id);
1010 if (!aurb) {
1011 return;
1013 if (aurb->packet) {
1014 if (aurb->get) {
1015 dev->dev.data_buf[0] = alt_setting_status->alt;
1016 len = 1;
1018 aurb->packet->result =
1019 usbredir_handle_status(dev, alt_setting_status->status, len);
1020 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1022 async_free(dev, aurb);
1025 static void usbredir_iso_stream_status(void *priv, uint32_t id,
1026 struct usb_redir_iso_stream_status_header *iso_stream_status)
1028 USBRedirDevice *dev = priv;
1029 uint8_t ep = iso_stream_status->endpoint;
1031 DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1032 ep, id);
1034 if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].iso_started) {
1035 return;
1038 dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
1039 if (iso_stream_status->status == usb_redir_stall) {
1040 DPRINTF("iso stream stopped by peer ep %02X\n", ep);
1041 dev->endpoint[EP2I(ep)].iso_started = 0;
1045 static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1046 struct usb_redir_interrupt_receiving_status_header
1047 *interrupt_receiving_status)
1049 USBRedirDevice *dev = priv;
1050 uint8_t ep = interrupt_receiving_status->endpoint;
1052 DPRINTF("interrupt recv status %d ep %02X id %u\n",
1053 interrupt_receiving_status->status, ep, id);
1055 if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].interrupt_started) {
1056 return;
1059 dev->endpoint[EP2I(ep)].interrupt_error =
1060 interrupt_receiving_status->status;
1061 if (interrupt_receiving_status->status == usb_redir_stall) {
1062 DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep);
1063 dev->endpoint[EP2I(ep)].interrupt_started = 0;
1067 static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1068 struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1072 static void usbredir_control_packet(void *priv, uint32_t id,
1073 struct usb_redir_control_packet_header *control_packet,
1074 uint8_t *data, int data_len)
1076 USBRedirDevice *dev = priv;
1077 int len = control_packet->length;
1078 AsyncURB *aurb;
1080 DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1081 len, id);
1083 aurb = async_find(dev, id);
1084 if (!aurb) {
1085 free(data);
1086 return;
1089 aurb->control_packet.status = control_packet->status;
1090 aurb->control_packet.length = control_packet->length;
1091 if (memcmp(&aurb->control_packet, control_packet,
1092 sizeof(*control_packet))) {
1093 ERROR("return control packet mismatch, please report this!\n");
1094 len = USB_RET_NAK;
1097 if (aurb->packet) {
1098 len = usbredir_handle_status(dev, control_packet->status, len);
1099 if (len > 0) {
1100 usbredir_log_data(dev, "ctrl data in:", data, data_len);
1101 if (data_len <= sizeof(dev->dev.data_buf)) {
1102 memcpy(dev->dev.data_buf, data, data_len);
1103 } else {
1104 ERROR("ctrl buffer too small (%d > %zu)\n",
1105 data_len, sizeof(dev->dev.data_buf));
1106 len = USB_RET_STALL;
1109 aurb->packet->result = len;
1110 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1112 async_free(dev, aurb);
1113 free(data);
1116 static void usbredir_bulk_packet(void *priv, uint32_t id,
1117 struct usb_redir_bulk_packet_header *bulk_packet,
1118 uint8_t *data, int data_len)
1120 USBRedirDevice *dev = priv;
1121 uint8_t ep = bulk_packet->endpoint;
1122 int len = bulk_packet->length;
1123 AsyncURB *aurb;
1125 DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1126 ep, len, id);
1128 aurb = async_find(dev, id);
1129 if (!aurb) {
1130 free(data);
1131 return;
1134 if (aurb->bulk_packet.endpoint != bulk_packet->endpoint ||
1135 aurb->bulk_packet.stream_id != bulk_packet->stream_id) {
1136 ERROR("return bulk packet mismatch, please report this!\n");
1137 len = USB_RET_NAK;
1140 if (aurb->packet) {
1141 len = usbredir_handle_status(dev, bulk_packet->status, len);
1142 if (len > 0) {
1143 usbredir_log_data(dev, "bulk data in:", data, data_len);
1144 if (data_len <= aurb->packet->iov.size) {
1145 usb_packet_copy(aurb->packet, data, data_len);
1146 } else {
1147 ERROR("bulk buffer too small (%d > %zd)\n", data_len,
1148 aurb->packet->iov.size);
1149 len = USB_RET_STALL;
1152 aurb->packet->result = len;
1153 usb_packet_complete(&dev->dev, aurb->packet);
1155 async_free(dev, aurb);
1156 free(data);
1159 static void usbredir_iso_packet(void *priv, uint32_t id,
1160 struct usb_redir_iso_packet_header *iso_packet,
1161 uint8_t *data, int data_len)
1163 USBRedirDevice *dev = priv;
1164 uint8_t ep = iso_packet->endpoint;
1166 DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1167 data_len, id);
1169 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1170 ERROR("received iso packet for non iso endpoint %02X\n", ep);
1171 free(data);
1172 return;
1175 if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1176 DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1177 free(data);
1178 return;
1181 /* bufp_alloc also adds the packet to the ep queue */
1182 bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1185 static void usbredir_interrupt_packet(void *priv, uint32_t id,
1186 struct usb_redir_interrupt_packet_header *interrupt_packet,
1187 uint8_t *data, int data_len)
1189 USBRedirDevice *dev = priv;
1190 uint8_t ep = interrupt_packet->endpoint;
1192 DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1193 interrupt_packet->status, ep, data_len, id);
1195 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
1196 ERROR("received int packet for non interrupt endpoint %02X\n", ep);
1197 free(data);
1198 return;
1201 if (ep & USB_DIR_IN) {
1202 if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
1203 DPRINTF("received int packet while not started ep %02X\n", ep);
1204 free(data);
1205 return;
1208 /* bufp_alloc also adds the packet to the ep queue */
1209 bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
1210 } else {
1211 int len = interrupt_packet->length;
1213 AsyncURB *aurb = async_find(dev, id);
1214 if (!aurb) {
1215 return;
1218 if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
1219 ERROR("return int packet mismatch, please report this!\n");
1220 len = USB_RET_NAK;
1223 if (aurb->packet) {
1224 aurb->packet->result = usbredir_handle_status(dev,
1225 interrupt_packet->status, len);
1226 usb_packet_complete(&dev->dev, aurb->packet);
1228 async_free(dev, aurb);
1232 static struct USBDeviceInfo usbredir_dev_info = {
1233 .product_desc = "USB Redirection Device",
1234 .qdev.name = "usb-redir",
1235 .qdev.size = sizeof(USBRedirDevice),
1236 .init = usbredir_initfn,
1237 .handle_destroy = usbredir_handle_destroy,
1238 .handle_packet = usb_generic_handle_packet,
1239 .cancel_packet = usbredir_cancel_packet,
1240 .handle_reset = usbredir_handle_reset,
1241 .handle_data = usbredir_handle_data,
1242 .handle_control = usbredir_handle_control,
1243 .qdev.props = (Property[]) {
1244 DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
1245 DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
1246 DEFINE_PROP_END_OF_LIST(),
1250 static void usbredir_register_devices(void)
1252 usb_qdev_register(&usbredir_dev_info);
1254 device_init(usbredir_register_devices);