open -> new rename fallout
[qemu/aliguori.git] / usb-redir.c
blob9802200e44bf99b66e14a8a6e33f8ab631609605
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);
131 static void usbredir_update_handlers(USBRedirDevice *dev);
133 #define VERSION "qemu usb-redir guest " QEMU_VERSION
136 * Logging stuff
139 #define ERROR(...) \
140 do { \
141 if (dev->debug >= usbredirparser_error) { \
142 error_report("usb-redir error: " __VA_ARGS__); \
144 } while (0)
145 #define WARNING(...) \
146 do { \
147 if (dev->debug >= usbredirparser_warning) { \
148 error_report("usb-redir warning: " __VA_ARGS__); \
150 } while (0)
151 #define INFO(...) \
152 do { \
153 if (dev->debug >= usbredirparser_info) { \
154 error_report("usb-redir: " __VA_ARGS__); \
156 } while (0)
157 #define DPRINTF(...) \
158 do { \
159 if (dev->debug >= usbredirparser_debug) { \
160 error_report("usb-redir: " __VA_ARGS__); \
162 } while (0)
163 #define DPRINTF2(...) \
164 do { \
165 if (dev->debug >= usbredirparser_debug_data) { \
166 error_report("usb-redir: " __VA_ARGS__); \
168 } while (0)
170 static void usbredir_log(void *priv, int level, const char *msg)
172 USBRedirDevice *dev = priv;
174 if (dev->debug < level) {
175 return;
178 error_report("%s\n", msg);
181 static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
182 const uint8_t *data, int len)
184 int i, j, n;
186 if (dev->debug < usbredirparser_debug_data) {
187 return;
190 for (i = 0; i < len; i += j) {
191 char buf[128];
193 n = sprintf(buf, "%s", desc);
194 for (j = 0; j < 8 && i + j < len; j++) {
195 n += sprintf(buf + n, " %02X", data[i + j]);
197 error_report("%s\n", buf);
202 * usbredirparser io functions
205 static int usbredir_read(void *priv, uint8_t *data, int count)
207 USBRedirDevice *dev = priv;
209 if (dev->read_buf_size < count) {
210 count = dev->read_buf_size;
213 memcpy(data, dev->read_buf, count);
215 dev->read_buf_size -= count;
216 if (dev->read_buf_size) {
217 dev->read_buf += count;
218 } else {
219 dev->read_buf = NULL;
222 return count;
225 static int usbredir_write(void *priv, uint8_t *data, int count)
227 USBRedirDevice *dev = priv;
229 return qemu_chr_fe_write(dev->cs, data, count);
233 * Async and buffered packets helpers
236 static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
238 AsyncURB *aurb = (AsyncURB *) qemu_mallocz(sizeof(AsyncURB));
239 aurb->dev = dev;
240 aurb->packet = p;
241 aurb->packet_id = dev->packet_id;
242 QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
243 dev->packet_id++;
245 return aurb;
248 static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
250 QTAILQ_REMOVE(&dev->asyncq, aurb, next);
251 qemu_free(aurb);
254 static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
256 AsyncURB *aurb;
258 QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
259 if (aurb->packet_id == packet_id) {
260 return aurb;
263 ERROR("could not find async urb for packet_id %u\n", packet_id);
264 return NULL;
267 static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
269 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
270 AsyncURB *aurb;
272 QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
273 if (p != aurb->packet) {
274 continue;
277 DPRINTF("async cancel id %u\n", aurb->packet_id);
278 usbredirparser_send_cancel_data_packet(dev->parser, aurb->packet_id);
279 usbredirparser_do_write(dev->parser);
281 /* Mark it as dead */
282 aurb->packet = NULL;
283 break;
287 static struct buf_packet *bufp_alloc(USBRedirDevice *dev,
288 uint8_t *data, int len, int status, uint8_t ep)
290 struct buf_packet *bufp = qemu_malloc(sizeof(struct buf_packet));
291 bufp->data = data;
292 bufp->len = len;
293 bufp->status = status;
294 QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
295 return bufp;
298 static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
299 uint8_t ep)
301 QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
302 free(bufp->data);
303 qemu_free(bufp);
306 static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
308 struct buf_packet *buf, *buf_next;
310 QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) {
311 bufp_free(dev, buf, ep);
316 * USBDevice callbacks
319 static void usbredir_handle_reset(USBDevice *udev)
321 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
323 DPRINTF("reset device\n");
324 usbredirparser_send_reset(dev->parser);
325 usbredirparser_do_write(dev->parser);
328 static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
329 uint8_t ep)
331 int status, len;
333 if (!dev->endpoint[EP2I(ep)].iso_started &&
334 !dev->endpoint[EP2I(ep)].iso_error) {
335 struct usb_redir_start_iso_stream_header start_iso = {
336 .endpoint = ep,
337 /* TODO maybe do something with these depending on ep interval? */
338 .pkts_per_urb = 32,
339 .no_urbs = 3,
341 /* No id, we look at the ep when receiving a status back */
342 usbredirparser_send_start_iso_stream(dev->parser, 0, &start_iso);
343 usbredirparser_do_write(dev->parser);
344 DPRINTF("iso stream started ep %02X\n", ep);
345 dev->endpoint[EP2I(ep)].iso_started = 1;
348 if (ep & USB_DIR_IN) {
349 struct buf_packet *isop;
351 isop = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
352 if (isop == NULL) {
353 DPRINTF2("iso-token-in ep %02X, no isop\n", ep);
354 /* Check iso_error for stream errors, otherwise its an underrun */
355 status = dev->endpoint[EP2I(ep)].iso_error;
356 dev->endpoint[EP2I(ep)].iso_error = 0;
357 return usbredir_handle_status(dev, status, 0);
359 DPRINTF2("iso-token-in ep %02X status %d len %d\n", ep, isop->status,
360 isop->len);
362 status = isop->status;
363 if (status != usb_redir_success) {
364 bufp_free(dev, isop, ep);
365 return usbredir_handle_status(dev, status, 0);
368 len = isop->len;
369 if (len > p->iov.size) {
370 ERROR("received iso data is larger then packet ep %02X\n", ep);
371 bufp_free(dev, isop, ep);
372 return USB_RET_NAK;
374 usb_packet_copy(p, isop->data, len);
375 bufp_free(dev, isop, ep);
376 return len;
377 } else {
378 /* If the stream was not started because of a pending error don't
379 send the packet to the usb-host */
380 if (dev->endpoint[EP2I(ep)].iso_started) {
381 struct usb_redir_iso_packet_header iso_packet = {
382 .endpoint = ep,
383 .length = p->iov.size
385 uint8_t buf[p->iov.size];
386 /* No id, we look at the ep when receiving a status back */
387 usb_packet_copy(p, buf, p->iov.size);
388 usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,
389 buf, p->iov.size);
390 usbredirparser_do_write(dev->parser);
392 status = dev->endpoint[EP2I(ep)].iso_error;
393 dev->endpoint[EP2I(ep)].iso_error = 0;
394 DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep, status,
395 p->iov.size);
396 return usbredir_handle_status(dev, status, p->iov.size);
400 static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
402 struct usb_redir_stop_iso_stream_header stop_iso_stream = {
403 .endpoint = ep
405 if (dev->endpoint[EP2I(ep)].iso_started) {
406 usbredirparser_send_stop_iso_stream(dev->parser, 0, &stop_iso_stream);
407 DPRINTF("iso stream stopped ep %02X\n", ep);
408 dev->endpoint[EP2I(ep)].iso_started = 0;
410 usbredir_free_bufpq(dev, ep);
413 static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
414 uint8_t ep)
416 AsyncURB *aurb = async_alloc(dev, p);
417 struct usb_redir_bulk_packet_header bulk_packet;
419 DPRINTF("bulk-out ep %02X len %zd id %u\n", ep,
420 p->iov.size, aurb->packet_id);
422 bulk_packet.endpoint = ep;
423 bulk_packet.length = p->iov.size;
424 bulk_packet.stream_id = 0;
425 aurb->bulk_packet = bulk_packet;
427 if (ep & USB_DIR_IN) {
428 usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
429 &bulk_packet, NULL, 0);
430 } else {
431 uint8_t buf[p->iov.size];
432 usb_packet_copy(p, buf, p->iov.size);
433 usbredir_log_data(dev, "bulk data out:", buf, p->iov.size);
434 usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
435 &bulk_packet, buf, p->iov.size);
437 usbredirparser_do_write(dev->parser);
438 return USB_RET_ASYNC;
441 static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
442 USBPacket *p, uint8_t ep)
444 if (ep & USB_DIR_IN) {
445 /* Input interrupt endpoint, buffered packet input */
446 struct buf_packet *intp;
447 int status, len;
449 if (!dev->endpoint[EP2I(ep)].interrupt_started &&
450 !dev->endpoint[EP2I(ep)].interrupt_error) {
451 struct usb_redir_start_interrupt_receiving_header start_int = {
452 .endpoint = ep,
454 /* No id, we look at the ep when receiving a status back */
455 usbredirparser_send_start_interrupt_receiving(dev->parser, 0,
456 &start_int);
457 usbredirparser_do_write(dev->parser);
458 DPRINTF("interrupt recv started ep %02X\n", ep);
459 dev->endpoint[EP2I(ep)].interrupt_started = 1;
462 intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
463 if (intp == NULL) {
464 DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);
465 /* Check interrupt_error for stream errors */
466 status = dev->endpoint[EP2I(ep)].interrupt_error;
467 dev->endpoint[EP2I(ep)].interrupt_error = 0;
468 return usbredir_handle_status(dev, status, 0);
470 DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,
471 intp->status, intp->len);
473 status = intp->status;
474 if (status != usb_redir_success) {
475 bufp_free(dev, intp, ep);
476 return usbredir_handle_status(dev, status, 0);
479 len = intp->len;
480 if (len > p->iov.size) {
481 ERROR("received int data is larger then packet ep %02X\n", ep);
482 bufp_free(dev, intp, ep);
483 return USB_RET_NAK;
485 usb_packet_copy(p, intp->data, len);
486 bufp_free(dev, intp, ep);
487 return len;
488 } else {
489 /* Output interrupt endpoint, normal async operation */
490 AsyncURB *aurb = async_alloc(dev, p);
491 struct usb_redir_interrupt_packet_header interrupt_packet;
492 uint8_t buf[p->iov.size];
494 DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep, p->iov.size,
495 aurb->packet_id);
497 interrupt_packet.endpoint = ep;
498 interrupt_packet.length = p->iov.size;
499 aurb->interrupt_packet = interrupt_packet;
501 usb_packet_copy(p, buf, p->iov.size);
502 usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);
503 usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
504 &interrupt_packet, buf, p->iov.size);
505 usbredirparser_do_write(dev->parser);
506 return USB_RET_ASYNC;
510 static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev,
511 uint8_t ep)
513 struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv = {
514 .endpoint = ep
516 if (dev->endpoint[EP2I(ep)].interrupt_started) {
517 usbredirparser_send_stop_interrupt_receiving(dev->parser, 0,
518 &stop_interrupt_recv);
519 DPRINTF("interrupt recv stopped ep %02X\n", ep);
520 dev->endpoint[EP2I(ep)].interrupt_started = 0;
522 usbredir_free_bufpq(dev, ep);
525 static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
527 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
528 uint8_t ep;
530 ep = p->devep;
531 if (p->pid == USB_TOKEN_IN) {
532 ep |= USB_DIR_IN;
535 switch (dev->endpoint[EP2I(ep)].type) {
536 case USB_ENDPOINT_XFER_CONTROL:
537 ERROR("handle_data called for control transfer on ep %02X\n", ep);
538 return USB_RET_NAK;
539 case USB_ENDPOINT_XFER_ISOC:
540 return usbredir_handle_iso_data(dev, p, ep);
541 case USB_ENDPOINT_XFER_BULK:
542 return usbredir_handle_bulk_data(dev, p, ep);;
543 case USB_ENDPOINT_XFER_INT:
544 return usbredir_handle_interrupt_data(dev, p, ep);;
545 default:
546 ERROR("handle_data ep %02X has unknown type %d\n", ep,
547 dev->endpoint[EP2I(ep)].type);
548 return USB_RET_NAK;
552 static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
553 int config)
555 struct usb_redir_set_configuration_header set_config;
556 AsyncURB *aurb = async_alloc(dev, p);
557 int i;
559 DPRINTF("set config %d id %u\n", config, aurb->packet_id);
561 for (i = 0; i < MAX_ENDPOINTS; i++) {
562 switch (dev->endpoint[i].type) {
563 case USB_ENDPOINT_XFER_ISOC:
564 usbredir_stop_iso_stream(dev, I2EP(i));
565 break;
566 case USB_ENDPOINT_XFER_INT:
567 if (i & 0x10) {
568 usbredir_stop_interrupt_receiving(dev, I2EP(i));
570 break;
572 usbredir_free_bufpq(dev, I2EP(i));
575 set_config.configuration = config;
576 usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
577 &set_config);
578 usbredirparser_do_write(dev->parser);
579 return USB_RET_ASYNC;
582 static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
584 AsyncURB *aurb = async_alloc(dev, p);
586 DPRINTF("get config id %u\n", aurb->packet_id);
588 aurb->get = 1;
589 usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
590 usbredirparser_do_write(dev->parser);
591 return USB_RET_ASYNC;
594 static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
595 int interface, int alt)
597 struct usb_redir_set_alt_setting_header set_alt;
598 AsyncURB *aurb = async_alloc(dev, p);
599 int i;
601 DPRINTF("set interface %d alt %d id %u\n", interface, alt,
602 aurb->packet_id);
604 for (i = 0; i < MAX_ENDPOINTS; i++) {
605 if (dev->endpoint[i].interface == interface) {
606 switch (dev->endpoint[i].type) {
607 case USB_ENDPOINT_XFER_ISOC:
608 usbredir_stop_iso_stream(dev, I2EP(i));
609 break;
610 case USB_ENDPOINT_XFER_INT:
611 if (i & 0x10) {
612 usbredir_stop_interrupt_receiving(dev, I2EP(i));
614 break;
616 usbredir_free_bufpq(dev, I2EP(i));
620 set_alt.interface = interface;
621 set_alt.alt = alt;
622 usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
623 &set_alt);
624 usbredirparser_do_write(dev->parser);
625 return USB_RET_ASYNC;
628 static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
629 int interface)
631 struct usb_redir_get_alt_setting_header get_alt;
632 AsyncURB *aurb = async_alloc(dev, p);
634 DPRINTF("get interface %d id %u\n", interface, aurb->packet_id);
636 get_alt.interface = interface;
637 aurb->get = 1;
638 usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
639 &get_alt);
640 usbredirparser_do_write(dev->parser);
641 return USB_RET_ASYNC;
644 static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
645 int request, int value, int index, int length, uint8_t *data)
647 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
648 struct usb_redir_control_packet_header control_packet;
649 AsyncURB *aurb;
651 /* Special cases for certain standard device requests */
652 switch (request) {
653 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
654 DPRINTF("set address %d\n", value);
655 dev->dev.addr = value;
656 return 0;
657 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
658 return usbredir_set_config(dev, p, value & 0xff);
659 case DeviceRequest | USB_REQ_GET_CONFIGURATION:
660 return usbredir_get_config(dev, p);
661 case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
662 return usbredir_set_interface(dev, p, index, value);
663 case InterfaceRequest | USB_REQ_GET_INTERFACE:
664 return usbredir_get_interface(dev, p, index);
667 /* "Normal" ctrl requests */
668 aurb = async_alloc(dev, p);
670 /* Note request is (bRequestType << 8) | bRequest */
671 DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
672 request >> 8, request & 0xff, value, index, length,
673 aurb->packet_id);
675 control_packet.request = request & 0xFF;
676 control_packet.requesttype = request >> 8;
677 control_packet.endpoint = control_packet.requesttype & USB_DIR_IN;
678 control_packet.value = value;
679 control_packet.index = index;
680 control_packet.length = length;
681 aurb->control_packet = control_packet;
683 if (control_packet.requesttype & USB_DIR_IN) {
684 usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
685 &control_packet, NULL, 0);
686 } else {
687 usbredir_log_data(dev, "ctrl data out:", data, length);
688 usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
689 &control_packet, data, length);
691 usbredirparser_do_write(dev->parser);
692 return USB_RET_ASYNC;
696 * Close events can be triggered by usbredirparser_do_write which gets called
697 * from within the USBDevice data / control packet callbacks and doing a
698 * usb_detach from within these callbacks is not a good idea.
700 * So we use a bh handler to take care of close events. We also handle
701 * open events from this callback to make sure that a close directly followed
702 * by an open gets handled in the right order.
704 static void usbredir_open_close_bh(void *opaque)
706 USBRedirDevice *dev = opaque;
708 usbredir_device_disconnect(dev);
710 if (dev->parser) {
711 usbredirparser_destroy(dev->parser);
712 dev->parser = NULL;
715 if (dev->cs->opened) {
716 dev->parser = qemu_oom_check(usbredirparser_create());
717 dev->parser->priv = dev;
718 dev->parser->log_func = usbredir_log;
719 dev->parser->read_func = usbredir_read;
720 dev->parser->write_func = usbredir_write;
721 dev->parser->device_connect_func = usbredir_device_connect;
722 dev->parser->device_disconnect_func = usbredir_device_disconnect;
723 dev->parser->interface_info_func = usbredir_interface_info;
724 dev->parser->ep_info_func = usbredir_ep_info;
725 dev->parser->configuration_status_func = usbredir_configuration_status;
726 dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
727 dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
728 dev->parser->interrupt_receiving_status_func =
729 usbredir_interrupt_receiving_status;
730 dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
731 dev->parser->control_packet_func = usbredir_control_packet;
732 dev->parser->bulk_packet_func = usbredir_bulk_packet;
733 dev->parser->iso_packet_func = usbredir_iso_packet;
734 dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
735 dev->read_buf = NULL;
736 dev->read_buf_size = 0;
737 usbredirparser_init(dev->parser, VERSION, NULL, 0, 0);
738 usbredirparser_do_write(dev->parser);
741 usbredir_update_handlers(dev);
744 static void usbredir_do_attach(void *opaque)
746 USBRedirDevice *dev = opaque;
748 usb_device_attach(&dev->dev);
752 * chardev callbacks
755 static void usbredir_chardev_read(void *opaque)
757 USBRedirDevice *dev = opaque;
758 uint8_t buf[1024 * 1024];
759 int size;
761 /* No recursion allowed! */
762 assert(dev->read_buf == NULL);
764 size = qemu_chr_fe_read(dev->chr, buf, sizeof(buf));
766 dev->read_buf = buf;
767 dev->read_buf_size = size;
769 usbredirparser_do_read(dev->parser);
770 /* Send any acks, etc. which may be queued now */
771 usbredirparser_do_write(dev->parser);
774 static void usbredir_chardev_event(void *opaque, int event)
776 USBRedirDevice *dev = opaque;
778 switch (event) {
779 case CHR_EVENT_OPENED:
780 case CHR_EVENT_CLOSED:
781 qemu_bh_schedule(dev->open_close_bh);
782 break;
786 static void usbredir_update_handlers(USBRedirDevice *dev)
788 if (dev->parser) {
789 qemu_chr_fe_set_handlers(dev->cs, usbredir_chardev_read,
790 NULL, usbredir_chardev_event, dev);
791 } else {
792 qemu_chr_fe_set_handlers(dev->cs, NULL, NULL,
793 usbredir_chardev_event, dev);
798 * init + destroy
801 static int usbredir_initfn(USBDevice *udev)
803 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
804 int i;
806 if (dev->cs == NULL) {
807 qerror_report(QERR_MISSING_PARAMETER, "chardev");
808 return -1;
811 dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
812 dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
814 QTAILQ_INIT(&dev->asyncq);
815 for (i = 0; i < MAX_ENDPOINTS; i++) {
816 QTAILQ_INIT(&dev->endpoint[i].bufpq);
819 /* We'll do the attach once we receive the speed from the usb-host */
820 udev->auto_attach = 0;
822 qemu_chr_fe_open(dev->cs);
823 usbredir_update_handlers(dev);
825 return 0;
828 static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
830 AsyncURB *aurb, *next_aurb;
831 int i;
833 QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
834 async_free(dev, aurb);
836 for (i = 0; i < MAX_ENDPOINTS; i++) {
837 usbredir_free_bufpq(dev, I2EP(i));
841 static void usbredir_handle_destroy(USBDevice *udev)
843 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
845 qemu_chr_fe_delete(dev->cs);
846 /* Note must be done after qemu_chr_close, as that causes a close event */
847 qemu_bh_delete(dev->open_close_bh);
849 qemu_del_timer(dev->attach_timer);
850 qemu_free_timer(dev->attach_timer);
852 usbredir_cleanup_device_queues(dev);
854 if (dev->parser) {
855 usbredirparser_destroy(dev->parser);
860 * usbredirparser packet complete callbacks
863 static int usbredir_handle_status(USBRedirDevice *dev,
864 int status, int actual_len)
866 switch (status) {
867 case usb_redir_success:
868 return actual_len;
869 case usb_redir_stall:
870 return USB_RET_STALL;
871 case usb_redir_cancelled:
872 WARNING("returning cancelled packet to HC?\n");
873 case usb_redir_inval:
874 case usb_redir_ioerror:
875 case usb_redir_timeout:
876 default:
877 return USB_RET_NAK;
881 static void usbredir_device_connect(void *priv,
882 struct usb_redir_device_connect_header *device_connect)
884 USBRedirDevice *dev = priv;
886 switch (device_connect->speed) {
887 case usb_redir_speed_low:
888 DPRINTF("attaching low speed device\n");
889 dev->dev.speed = USB_SPEED_LOW;
890 break;
891 case usb_redir_speed_full:
892 DPRINTF("attaching full speed device\n");
893 dev->dev.speed = USB_SPEED_FULL;
894 break;
895 case usb_redir_speed_high:
896 DPRINTF("attaching high speed device\n");
897 dev->dev.speed = USB_SPEED_HIGH;
898 break;
899 case usb_redir_speed_super:
900 DPRINTF("attaching super speed device\n");
901 dev->dev.speed = USB_SPEED_SUPER;
902 break;
903 default:
904 DPRINTF("attaching unknown speed device, assuming full speed\n");
905 dev->dev.speed = USB_SPEED_FULL;
907 dev->dev.speedmask = (1 << dev->dev.speed);
908 qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
911 static void usbredir_device_disconnect(void *priv)
913 USBRedirDevice *dev = priv;
915 /* Stop any pending attaches */
916 qemu_del_timer(dev->attach_timer);
918 if (dev->dev.attached) {
919 usb_device_detach(&dev->dev);
920 usbredir_cleanup_device_queues(dev);
922 * Delay next usb device attach to give the guest a chance to see
923 * see the detach / attach in case of quick close / open succession
925 dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
929 static void usbredir_interface_info(void *priv,
930 struct usb_redir_interface_info_header *interface_info)
932 /* The intention is to allow specifying acceptable interface classes
933 for redirection on the cmdline and in the future verify this here,
934 and disconnect (or never connect) the device if a not accepted
935 interface class is detected */
938 static void usbredir_ep_info(void *priv,
939 struct usb_redir_ep_info_header *ep_info)
941 USBRedirDevice *dev = priv;
942 int i;
944 for (i = 0; i < MAX_ENDPOINTS; i++) {
945 dev->endpoint[i].type = ep_info->type[i];
946 dev->endpoint[i].interval = ep_info->interval[i];
947 dev->endpoint[i].interface = ep_info->interface[i];
948 if (dev->endpoint[i].type != usb_redir_type_invalid) {
949 DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
950 dev->endpoint[i].type, dev->endpoint[i].interface);
955 static void usbredir_configuration_status(void *priv, uint32_t id,
956 struct usb_redir_configuration_status_header *config_status)
958 USBRedirDevice *dev = priv;
959 AsyncURB *aurb;
960 int len = 0;
962 DPRINTF("set config status %d config %d id %u\n", config_status->status,
963 config_status->configuration, id);
965 aurb = async_find(dev, id);
966 if (!aurb) {
967 return;
969 if (aurb->packet) {
970 if (aurb->get) {
971 dev->dev.data_buf[0] = config_status->configuration;
972 len = 1;
974 aurb->packet->result =
975 usbredir_handle_status(dev, config_status->status, len);
976 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
978 async_free(dev, aurb);
981 static void usbredir_alt_setting_status(void *priv, uint32_t id,
982 struct usb_redir_alt_setting_status_header *alt_setting_status)
984 USBRedirDevice *dev = priv;
985 AsyncURB *aurb;
986 int len = 0;
988 DPRINTF("alt status %d intf %d alt %d id: %u\n",
989 alt_setting_status->status,
990 alt_setting_status->interface,
991 alt_setting_status->alt, id);
993 aurb = async_find(dev, id);
994 if (!aurb) {
995 return;
997 if (aurb->packet) {
998 if (aurb->get) {
999 dev->dev.data_buf[0] = alt_setting_status->alt;
1000 len = 1;
1002 aurb->packet->result =
1003 usbredir_handle_status(dev, alt_setting_status->status, len);
1004 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1006 async_free(dev, aurb);
1009 static void usbredir_iso_stream_status(void *priv, uint32_t id,
1010 struct usb_redir_iso_stream_status_header *iso_stream_status)
1012 USBRedirDevice *dev = priv;
1013 uint8_t ep = iso_stream_status->endpoint;
1015 DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1016 ep, id);
1018 dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
1019 if (iso_stream_status->status == usb_redir_stall) {
1020 DPRINTF("iso stream stopped by peer ep %02X\n", ep);
1021 dev->endpoint[EP2I(ep)].iso_started = 0;
1025 static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1026 struct usb_redir_interrupt_receiving_status_header
1027 *interrupt_receiving_status)
1029 USBRedirDevice *dev = priv;
1030 uint8_t ep = interrupt_receiving_status->endpoint;
1032 DPRINTF("interrupt recv status %d ep %02X id %u\n",
1033 interrupt_receiving_status->status, ep, id);
1035 dev->endpoint[EP2I(ep)].interrupt_error =
1036 interrupt_receiving_status->status;
1037 if (interrupt_receiving_status->status == usb_redir_stall) {
1038 DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep);
1039 dev->endpoint[EP2I(ep)].interrupt_started = 0;
1043 static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1044 struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1048 static void usbredir_control_packet(void *priv, uint32_t id,
1049 struct usb_redir_control_packet_header *control_packet,
1050 uint8_t *data, int data_len)
1052 USBRedirDevice *dev = priv;
1053 int len = control_packet->length;
1054 AsyncURB *aurb;
1056 DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1057 len, id);
1059 aurb = async_find(dev, id);
1060 if (!aurb) {
1061 free(data);
1062 return;
1065 aurb->control_packet.status = control_packet->status;
1066 aurb->control_packet.length = control_packet->length;
1067 if (memcmp(&aurb->control_packet, control_packet,
1068 sizeof(*control_packet))) {
1069 ERROR("return control packet mismatch, please report this!\n");
1070 len = USB_RET_NAK;
1073 if (aurb->packet) {
1074 len = usbredir_handle_status(dev, control_packet->status, len);
1075 if (len > 0) {
1076 usbredir_log_data(dev, "ctrl data in:", data, data_len);
1077 if (data_len <= sizeof(dev->dev.data_buf)) {
1078 memcpy(dev->dev.data_buf, data, data_len);
1079 } else {
1080 ERROR("ctrl buffer too small (%d > %zu)\n",
1081 data_len, sizeof(dev->dev.data_buf));
1082 len = USB_RET_STALL;
1085 aurb->packet->result = len;
1086 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1088 async_free(dev, aurb);
1089 free(data);
1092 static void usbredir_bulk_packet(void *priv, uint32_t id,
1093 struct usb_redir_bulk_packet_header *bulk_packet,
1094 uint8_t *data, int data_len)
1096 USBRedirDevice *dev = priv;
1097 uint8_t ep = bulk_packet->endpoint;
1098 int len = bulk_packet->length;
1099 AsyncURB *aurb;
1101 DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1102 ep, len, id);
1104 aurb = async_find(dev, id);
1105 if (!aurb) {
1106 free(data);
1107 return;
1110 if (aurb->bulk_packet.endpoint != bulk_packet->endpoint ||
1111 aurb->bulk_packet.stream_id != bulk_packet->stream_id) {
1112 ERROR("return bulk packet mismatch, please report this!\n");
1113 len = USB_RET_NAK;
1116 if (aurb->packet) {
1117 len = usbredir_handle_status(dev, bulk_packet->status, len);
1118 if (len > 0) {
1119 usbredir_log_data(dev, "bulk data in:", data, data_len);
1120 if (data_len <= aurb->packet->iov.size) {
1121 usb_packet_copy(aurb->packet, data, data_len);
1122 } else {
1123 ERROR("bulk buffer too small (%d > %zd)\n", data_len,
1124 aurb->packet->iov.size);
1125 len = USB_RET_STALL;
1128 aurb->packet->result = len;
1129 usb_packet_complete(&dev->dev, aurb->packet);
1131 async_free(dev, aurb);
1132 free(data);
1135 static void usbredir_iso_packet(void *priv, uint32_t id,
1136 struct usb_redir_iso_packet_header *iso_packet,
1137 uint8_t *data, int data_len)
1139 USBRedirDevice *dev = priv;
1140 uint8_t ep = iso_packet->endpoint;
1142 DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1143 data_len, id);
1145 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1146 ERROR("received iso packet for non iso endpoint %02X\n", ep);
1147 free(data);
1148 return;
1151 if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1152 DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1153 free(data);
1154 return;
1157 /* bufp_alloc also adds the packet to the ep queue */
1158 bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1161 static void usbredir_interrupt_packet(void *priv, uint32_t id,
1162 struct usb_redir_interrupt_packet_header *interrupt_packet,
1163 uint8_t *data, int data_len)
1165 USBRedirDevice *dev = priv;
1166 uint8_t ep = interrupt_packet->endpoint;
1168 DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1169 interrupt_packet->status, ep, data_len, id);
1171 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
1172 ERROR("received int packet for non interrupt endpoint %02X\n", ep);
1173 free(data);
1174 return;
1177 if (ep & USB_DIR_IN) {
1178 if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
1179 DPRINTF("received int packet while not started ep %02X\n", ep);
1180 free(data);
1181 return;
1184 /* bufp_alloc also adds the packet to the ep queue */
1185 bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
1186 } else {
1187 int len = interrupt_packet->length;
1189 AsyncURB *aurb = async_find(dev, id);
1190 if (!aurb) {
1191 return;
1194 if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
1195 ERROR("return int packet mismatch, please report this!\n");
1196 len = USB_RET_NAK;
1199 if (aurb->packet) {
1200 aurb->packet->result = usbredir_handle_status(dev,
1201 interrupt_packet->status, len);
1202 usb_packet_complete(&dev->dev, aurb->packet);
1204 async_free(dev, aurb);
1208 static struct USBDeviceInfo usbredir_dev_info = {
1209 .product_desc = "USB Redirection Device",
1210 .qdev.name = "usb-redir",
1211 .qdev.size = sizeof(USBRedirDevice),
1212 .init = usbredir_initfn,
1213 .handle_destroy = usbredir_handle_destroy,
1214 .handle_packet = usb_generic_handle_packet,
1215 .cancel_packet = usbredir_cancel_packet,
1216 .handle_reset = usbredir_handle_reset,
1217 .handle_data = usbredir_handle_data,
1218 .handle_control = usbredir_handle_control,
1219 .qdev.props = (Property[]) {
1220 DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
1221 DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
1222 DEFINE_PROP_END_OF_LIST(),
1226 static void usbredir_register_devices(void)
1228 usb_qdev_register(&usbredir_dev_info);
1230 device_init(usbredir_register_devices);