./configure: request pkg-config to provide private libs when static linking
[qemu/ar7.git] / usb-redir.c
blob8f4a29a218f4f8ac7bdd35c7815d7436b5972887
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 uint8_t bufpq_prefilled;
64 uint8_t bufpq_dropping_packets;
65 QTAILQ_HEAD(, buf_packet) bufpq;
66 int bufpq_size;
67 int bufpq_target_size;
70 struct USBRedirDevice {
71 USBDevice dev;
72 /* Properties */
73 CharDriverState *cs;
74 uint8_t debug;
75 /* Data passed from chardev the fd_read cb to the usbredirparser read cb */
76 const uint8_t *read_buf;
77 int read_buf_size;
78 /* For async handling of open/close */
79 QEMUBH *open_close_bh;
80 /* To delay the usb attach in case of quick chardev close + open */
81 QEMUTimer *attach_timer;
82 int64_t next_attach_time;
83 struct usbredirparser *parser;
84 struct endp_data endpoint[MAX_ENDPOINTS];
85 uint32_t packet_id;
86 QTAILQ_HEAD(, AsyncURB) asyncq;
89 struct AsyncURB {
90 USBRedirDevice *dev;
91 USBPacket *packet;
92 uint32_t packet_id;
93 int get;
94 union {
95 struct usb_redir_control_packet_header control_packet;
96 struct usb_redir_bulk_packet_header bulk_packet;
97 struct usb_redir_interrupt_packet_header interrupt_packet;
99 QTAILQ_ENTRY(AsyncURB)next;
102 static void usbredir_device_connect(void *priv,
103 struct usb_redir_device_connect_header *device_connect);
104 static void usbredir_device_disconnect(void *priv);
105 static void usbredir_interface_info(void *priv,
106 struct usb_redir_interface_info_header *interface_info);
107 static void usbredir_ep_info(void *priv,
108 struct usb_redir_ep_info_header *ep_info);
109 static void usbredir_configuration_status(void *priv, uint32_t id,
110 struct usb_redir_configuration_status_header *configuration_status);
111 static void usbredir_alt_setting_status(void *priv, uint32_t id,
112 struct usb_redir_alt_setting_status_header *alt_setting_status);
113 static void usbredir_iso_stream_status(void *priv, uint32_t id,
114 struct usb_redir_iso_stream_status_header *iso_stream_status);
115 static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
116 struct usb_redir_interrupt_receiving_status_header
117 *interrupt_receiving_status);
118 static void usbredir_bulk_streams_status(void *priv, uint32_t id,
119 struct usb_redir_bulk_streams_status_header *bulk_streams_status);
120 static void usbredir_control_packet(void *priv, uint32_t id,
121 struct usb_redir_control_packet_header *control_packet,
122 uint8_t *data, int data_len);
123 static void usbredir_bulk_packet(void *priv, uint32_t id,
124 struct usb_redir_bulk_packet_header *bulk_packet,
125 uint8_t *data, int data_len);
126 static void usbredir_iso_packet(void *priv, uint32_t id,
127 struct usb_redir_iso_packet_header *iso_packet,
128 uint8_t *data, int data_len);
129 static void usbredir_interrupt_packet(void *priv, uint32_t id,
130 struct usb_redir_interrupt_packet_header *interrupt_header,
131 uint8_t *data, int data_len);
133 static int usbredir_handle_status(USBRedirDevice *dev,
134 int status, int actual_len);
136 #define VERSION "qemu usb-redir guest " QEMU_VERSION
139 * Logging stuff
142 #define ERROR(...) \
143 do { \
144 if (dev->debug >= usbredirparser_error) { \
145 error_report("usb-redir error: " __VA_ARGS__); \
147 } while (0)
148 #define WARNING(...) \
149 do { \
150 if (dev->debug >= usbredirparser_warning) { \
151 error_report("usb-redir warning: " __VA_ARGS__); \
153 } while (0)
154 #define INFO(...) \
155 do { \
156 if (dev->debug >= usbredirparser_info) { \
157 error_report("usb-redir: " __VA_ARGS__); \
159 } while (0)
160 #define DPRINTF(...) \
161 do { \
162 if (dev->debug >= usbredirparser_debug) { \
163 error_report("usb-redir: " __VA_ARGS__); \
165 } while (0)
166 #define DPRINTF2(...) \
167 do { \
168 if (dev->debug >= usbredirparser_debug_data) { \
169 error_report("usb-redir: " __VA_ARGS__); \
171 } while (0)
173 static void usbredir_log(void *priv, int level, const char *msg)
175 USBRedirDevice *dev = priv;
177 if (dev->debug < level) {
178 return;
181 error_report("%s", msg);
184 static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
185 const uint8_t *data, int len)
187 int i, j, n;
189 if (dev->debug < usbredirparser_debug_data) {
190 return;
193 for (i = 0; i < len; i += j) {
194 char buf[128];
196 n = sprintf(buf, "%s", desc);
197 for (j = 0; j < 8 && i + j < len; j++) {
198 n += sprintf(buf + n, " %02X", data[i + j]);
200 error_report("%s", buf);
205 * usbredirparser io functions
208 static int usbredir_read(void *priv, uint8_t *data, int count)
210 USBRedirDevice *dev = priv;
212 if (dev->read_buf_size < count) {
213 count = dev->read_buf_size;
216 memcpy(data, dev->read_buf, count);
218 dev->read_buf_size -= count;
219 if (dev->read_buf_size) {
220 dev->read_buf += count;
221 } else {
222 dev->read_buf = NULL;
225 return count;
228 static int usbredir_write(void *priv, uint8_t *data, int count)
230 USBRedirDevice *dev = priv;
232 if (!dev->cs->opened) {
233 return 0;
236 return qemu_chr_fe_write(dev->cs, data, count);
240 * Async and buffered packets helpers
243 static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
245 AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
246 aurb->dev = dev;
247 aurb->packet = p;
248 aurb->packet_id = dev->packet_id;
249 QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
250 dev->packet_id++;
252 return aurb;
255 static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
257 QTAILQ_REMOVE(&dev->asyncq, aurb, next);
258 g_free(aurb);
261 static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
263 AsyncURB *aurb;
265 QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
266 if (aurb->packet_id == packet_id) {
267 return aurb;
270 ERROR("could not find async urb for packet_id %u\n", packet_id);
271 return NULL;
274 static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
276 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
277 AsyncURB *aurb;
279 QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
280 if (p != aurb->packet) {
281 continue;
284 DPRINTF("async cancel id %u\n", aurb->packet_id);
285 usbredirparser_send_cancel_data_packet(dev->parser, aurb->packet_id);
286 usbredirparser_do_write(dev->parser);
288 /* Mark it as dead */
289 aurb->packet = NULL;
290 break;
294 static void bufp_alloc(USBRedirDevice *dev,
295 uint8_t *data, int len, int status, uint8_t ep)
297 struct buf_packet *bufp;
299 if (!dev->endpoint[EP2I(ep)].bufpq_dropping_packets &&
300 dev->endpoint[EP2I(ep)].bufpq_size >
301 2 * dev->endpoint[EP2I(ep)].bufpq_target_size) {
302 DPRINTF("bufpq overflow, dropping packets ep %02X\n", ep);
303 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 1;
305 /* Since we're interupting the stream anyways, drop enough packets to get
306 back to our target buffer size */
307 if (dev->endpoint[EP2I(ep)].bufpq_dropping_packets) {
308 if (dev->endpoint[EP2I(ep)].bufpq_size >
309 dev->endpoint[EP2I(ep)].bufpq_target_size) {
310 free(data);
311 return;
313 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
316 bufp = g_malloc(sizeof(struct buf_packet));
317 bufp->data = data;
318 bufp->len = len;
319 bufp->status = status;
320 QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
321 dev->endpoint[EP2I(ep)].bufpq_size++;
324 static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
325 uint8_t ep)
327 QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
328 dev->endpoint[EP2I(ep)].bufpq_size--;
329 free(bufp->data);
330 g_free(bufp);
333 static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
335 struct buf_packet *buf, *buf_next;
337 QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) {
338 bufp_free(dev, buf, ep);
343 * USBDevice callbacks
346 static void usbredir_handle_reset(USBDevice *udev)
348 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
350 DPRINTF("reset device\n");
351 usbredirparser_send_reset(dev->parser);
352 usbredirparser_do_write(dev->parser);
355 static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
356 uint8_t ep)
358 int status, len;
359 if (!dev->endpoint[EP2I(ep)].iso_started &&
360 !dev->endpoint[EP2I(ep)].iso_error) {
361 struct usb_redir_start_iso_stream_header start_iso = {
362 .endpoint = ep,
364 int pkts_per_sec;
366 if (dev->dev.speed == USB_SPEED_HIGH) {
367 pkts_per_sec = 8000 / dev->endpoint[EP2I(ep)].interval;
368 } else {
369 pkts_per_sec = 1000 / dev->endpoint[EP2I(ep)].interval;
371 /* Testing has shown that we need circa 60 ms buffer */
372 dev->endpoint[EP2I(ep)].bufpq_target_size = (pkts_per_sec * 60) / 1000;
374 /* Aim for approx 100 interrupts / second on the client to
375 balance latency and interrupt load */
376 start_iso.pkts_per_urb = pkts_per_sec / 100;
377 if (start_iso.pkts_per_urb < 1) {
378 start_iso.pkts_per_urb = 1;
379 } else if (start_iso.pkts_per_urb > 32) {
380 start_iso.pkts_per_urb = 32;
383 start_iso.no_urbs = (dev->endpoint[EP2I(ep)].bufpq_target_size +
384 start_iso.pkts_per_urb - 1) /
385 start_iso.pkts_per_urb;
386 /* Output endpoints pre-fill only 1/2 of the packets, keeping the rest
387 as overflow buffer. Also see the usbredir protocol documentation */
388 if (!(ep & USB_DIR_IN)) {
389 start_iso.no_urbs *= 2;
391 if (start_iso.no_urbs > 16) {
392 start_iso.no_urbs = 16;
395 /* No id, we look at the ep when receiving a status back */
396 usbredirparser_send_start_iso_stream(dev->parser, 0, &start_iso);
397 usbredirparser_do_write(dev->parser);
398 DPRINTF("iso stream started pkts/sec %d pkts/urb %d urbs %d ep %02X\n",
399 pkts_per_sec, start_iso.pkts_per_urb, start_iso.no_urbs, ep);
400 dev->endpoint[EP2I(ep)].iso_started = 1;
401 dev->endpoint[EP2I(ep)].bufpq_prefilled = 0;
402 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
405 if (ep & USB_DIR_IN) {
406 struct buf_packet *isop;
408 if (dev->endpoint[EP2I(ep)].iso_started &&
409 !dev->endpoint[EP2I(ep)].bufpq_prefilled) {
410 if (dev->endpoint[EP2I(ep)].bufpq_size <
411 dev->endpoint[EP2I(ep)].bufpq_target_size) {
412 return usbredir_handle_status(dev, 0, 0);
414 dev->endpoint[EP2I(ep)].bufpq_prefilled = 1;
417 isop = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
418 if (isop == NULL) {
419 DPRINTF("iso-token-in ep %02X, no isop, iso_error: %d\n",
420 ep, dev->endpoint[EP2I(ep)].iso_error);
421 /* Re-fill the buffer */
422 dev->endpoint[EP2I(ep)].bufpq_prefilled = 0;
423 /* Check iso_error for stream errors, otherwise its an underrun */
424 status = dev->endpoint[EP2I(ep)].iso_error;
425 dev->endpoint[EP2I(ep)].iso_error = 0;
426 return usbredir_handle_status(dev, status, 0);
428 DPRINTF2("iso-token-in ep %02X status %d len %d queue-size: %d\n", ep,
429 isop->status, isop->len, dev->endpoint[EP2I(ep)].bufpq_size);
431 status = isop->status;
432 if (status != usb_redir_success) {
433 bufp_free(dev, isop, ep);
434 return usbredir_handle_status(dev, status, 0);
437 len = isop->len;
438 if (len > p->iov.size) {
439 ERROR("received iso data is larger then packet ep %02X (%d > %d)\n",
440 ep, len, (int)p->iov.size);
441 bufp_free(dev, isop, ep);
442 return USB_RET_NAK;
444 usb_packet_copy(p, isop->data, len);
445 bufp_free(dev, isop, ep);
446 return len;
447 } else {
448 /* If the stream was not started because of a pending error don't
449 send the packet to the usb-host */
450 if (dev->endpoint[EP2I(ep)].iso_started) {
451 struct usb_redir_iso_packet_header iso_packet = {
452 .endpoint = ep,
453 .length = p->iov.size
455 uint8_t buf[p->iov.size];
456 /* No id, we look at the ep when receiving a status back */
457 usb_packet_copy(p, buf, p->iov.size);
458 usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,
459 buf, p->iov.size);
460 usbredirparser_do_write(dev->parser);
462 status = dev->endpoint[EP2I(ep)].iso_error;
463 dev->endpoint[EP2I(ep)].iso_error = 0;
464 DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep, status,
465 p->iov.size);
466 return usbredir_handle_status(dev, status, p->iov.size);
470 static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
472 struct usb_redir_stop_iso_stream_header stop_iso_stream = {
473 .endpoint = ep
475 if (dev->endpoint[EP2I(ep)].iso_started) {
476 usbredirparser_send_stop_iso_stream(dev->parser, 0, &stop_iso_stream);
477 DPRINTF("iso stream stopped ep %02X\n", ep);
478 dev->endpoint[EP2I(ep)].iso_started = 0;
480 dev->endpoint[EP2I(ep)].iso_error = 0;
481 usbredir_free_bufpq(dev, ep);
484 static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
485 uint8_t ep)
487 AsyncURB *aurb = async_alloc(dev, p);
488 struct usb_redir_bulk_packet_header bulk_packet;
490 DPRINTF("bulk-out ep %02X len %zd id %u\n", ep,
491 p->iov.size, aurb->packet_id);
493 bulk_packet.endpoint = ep;
494 bulk_packet.length = p->iov.size;
495 bulk_packet.stream_id = 0;
496 aurb->bulk_packet = bulk_packet;
498 if (ep & USB_DIR_IN) {
499 usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
500 &bulk_packet, NULL, 0);
501 } else {
502 uint8_t buf[p->iov.size];
503 usb_packet_copy(p, buf, p->iov.size);
504 usbredir_log_data(dev, "bulk data out:", buf, p->iov.size);
505 usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
506 &bulk_packet, buf, p->iov.size);
508 usbredirparser_do_write(dev->parser);
509 return USB_RET_ASYNC;
512 static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
513 USBPacket *p, uint8_t ep)
515 if (ep & USB_DIR_IN) {
516 /* Input interrupt endpoint, buffered packet input */
517 struct buf_packet *intp;
518 int status, len;
520 if (!dev->endpoint[EP2I(ep)].interrupt_started &&
521 !dev->endpoint[EP2I(ep)].interrupt_error) {
522 struct usb_redir_start_interrupt_receiving_header start_int = {
523 .endpoint = ep,
525 /* No id, we look at the ep when receiving a status back */
526 usbredirparser_send_start_interrupt_receiving(dev->parser, 0,
527 &start_int);
528 usbredirparser_do_write(dev->parser);
529 DPRINTF("interrupt recv started ep %02X\n", ep);
530 dev->endpoint[EP2I(ep)].interrupt_started = 1;
531 /* We don't really want to drop interrupt packets ever, but
532 having some upper limit to how much we buffer is good. */
533 dev->endpoint[EP2I(ep)].bufpq_target_size = 1000;
534 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
537 intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
538 if (intp == NULL) {
539 DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);
540 /* Check interrupt_error for stream errors */
541 status = dev->endpoint[EP2I(ep)].interrupt_error;
542 dev->endpoint[EP2I(ep)].interrupt_error = 0;
543 return usbredir_handle_status(dev, status, 0);
545 DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,
546 intp->status, intp->len);
548 status = intp->status;
549 if (status != usb_redir_success) {
550 bufp_free(dev, intp, ep);
551 return usbredir_handle_status(dev, status, 0);
554 len = intp->len;
555 if (len > p->iov.size) {
556 ERROR("received int data is larger then packet ep %02X\n", ep);
557 bufp_free(dev, intp, ep);
558 return USB_RET_NAK;
560 usb_packet_copy(p, intp->data, len);
561 bufp_free(dev, intp, ep);
562 return len;
563 } else {
564 /* Output interrupt endpoint, normal async operation */
565 AsyncURB *aurb = async_alloc(dev, p);
566 struct usb_redir_interrupt_packet_header interrupt_packet;
567 uint8_t buf[p->iov.size];
569 DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep, p->iov.size,
570 aurb->packet_id);
572 interrupt_packet.endpoint = ep;
573 interrupt_packet.length = p->iov.size;
574 aurb->interrupt_packet = interrupt_packet;
576 usb_packet_copy(p, buf, p->iov.size);
577 usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);
578 usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
579 &interrupt_packet, buf, p->iov.size);
580 usbredirparser_do_write(dev->parser);
581 return USB_RET_ASYNC;
585 static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev,
586 uint8_t ep)
588 struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv = {
589 .endpoint = ep
591 if (dev->endpoint[EP2I(ep)].interrupt_started) {
592 usbredirparser_send_stop_interrupt_receiving(dev->parser, 0,
593 &stop_interrupt_recv);
594 DPRINTF("interrupt recv stopped ep %02X\n", ep);
595 dev->endpoint[EP2I(ep)].interrupt_started = 0;
597 dev->endpoint[EP2I(ep)].interrupt_error = 0;
598 usbredir_free_bufpq(dev, ep);
601 static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
603 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
604 uint8_t ep;
606 ep = p->devep;
607 if (p->pid == USB_TOKEN_IN) {
608 ep |= USB_DIR_IN;
611 switch (dev->endpoint[EP2I(ep)].type) {
612 case USB_ENDPOINT_XFER_CONTROL:
613 ERROR("handle_data called for control transfer on ep %02X\n", ep);
614 return USB_RET_NAK;
615 case USB_ENDPOINT_XFER_ISOC:
616 return usbredir_handle_iso_data(dev, p, ep);
617 case USB_ENDPOINT_XFER_BULK:
618 return usbredir_handle_bulk_data(dev, p, ep);
619 case USB_ENDPOINT_XFER_INT:
620 return usbredir_handle_interrupt_data(dev, p, ep);
621 default:
622 ERROR("handle_data ep %02X has unknown type %d\n", ep,
623 dev->endpoint[EP2I(ep)].type);
624 return USB_RET_NAK;
628 static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
629 int config)
631 struct usb_redir_set_configuration_header set_config;
632 AsyncURB *aurb = async_alloc(dev, p);
633 int i;
635 DPRINTF("set config %d id %u\n", config, aurb->packet_id);
637 for (i = 0; i < MAX_ENDPOINTS; i++) {
638 switch (dev->endpoint[i].type) {
639 case USB_ENDPOINT_XFER_ISOC:
640 usbredir_stop_iso_stream(dev, I2EP(i));
641 break;
642 case USB_ENDPOINT_XFER_INT:
643 if (i & 0x10) {
644 usbredir_stop_interrupt_receiving(dev, I2EP(i));
646 break;
648 usbredir_free_bufpq(dev, I2EP(i));
651 set_config.configuration = config;
652 usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
653 &set_config);
654 usbredirparser_do_write(dev->parser);
655 return USB_RET_ASYNC;
658 static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
660 AsyncURB *aurb = async_alloc(dev, p);
662 DPRINTF("get config id %u\n", aurb->packet_id);
664 aurb->get = 1;
665 usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
666 usbredirparser_do_write(dev->parser);
667 return USB_RET_ASYNC;
670 static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
671 int interface, int alt)
673 struct usb_redir_set_alt_setting_header set_alt;
674 AsyncURB *aurb = async_alloc(dev, p);
675 int i;
677 DPRINTF("set interface %d alt %d id %u\n", interface, alt,
678 aurb->packet_id);
680 for (i = 0; i < MAX_ENDPOINTS; i++) {
681 if (dev->endpoint[i].interface == interface) {
682 switch (dev->endpoint[i].type) {
683 case USB_ENDPOINT_XFER_ISOC:
684 usbredir_stop_iso_stream(dev, I2EP(i));
685 break;
686 case USB_ENDPOINT_XFER_INT:
687 if (i & 0x10) {
688 usbredir_stop_interrupt_receiving(dev, I2EP(i));
690 break;
692 usbredir_free_bufpq(dev, I2EP(i));
696 set_alt.interface = interface;
697 set_alt.alt = alt;
698 usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
699 &set_alt);
700 usbredirparser_do_write(dev->parser);
701 return USB_RET_ASYNC;
704 static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
705 int interface)
707 struct usb_redir_get_alt_setting_header get_alt;
708 AsyncURB *aurb = async_alloc(dev, p);
710 DPRINTF("get interface %d id %u\n", interface, aurb->packet_id);
712 get_alt.interface = interface;
713 aurb->get = 1;
714 usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
715 &get_alt);
716 usbredirparser_do_write(dev->parser);
717 return USB_RET_ASYNC;
720 static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
721 int request, int value, int index, int length, uint8_t *data)
723 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
724 struct usb_redir_control_packet_header control_packet;
725 AsyncURB *aurb;
727 /* Special cases for certain standard device requests */
728 switch (request) {
729 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
730 DPRINTF("set address %d\n", value);
731 dev->dev.addr = value;
732 return 0;
733 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
734 return usbredir_set_config(dev, p, value & 0xff);
735 case DeviceRequest | USB_REQ_GET_CONFIGURATION:
736 return usbredir_get_config(dev, p);
737 case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
738 return usbredir_set_interface(dev, p, index, value);
739 case InterfaceRequest | USB_REQ_GET_INTERFACE:
740 return usbredir_get_interface(dev, p, index);
743 /* "Normal" ctrl requests */
744 aurb = async_alloc(dev, p);
746 /* Note request is (bRequestType << 8) | bRequest */
747 DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
748 request >> 8, request & 0xff, value, index, length,
749 aurb->packet_id);
751 control_packet.request = request & 0xFF;
752 control_packet.requesttype = request >> 8;
753 control_packet.endpoint = control_packet.requesttype & USB_DIR_IN;
754 control_packet.value = value;
755 control_packet.index = index;
756 control_packet.length = length;
757 aurb->control_packet = control_packet;
759 if (control_packet.requesttype & USB_DIR_IN) {
760 usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
761 &control_packet, NULL, 0);
762 } else {
763 usbredir_log_data(dev, "ctrl data out:", data, length);
764 usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
765 &control_packet, data, length);
767 usbredirparser_do_write(dev->parser);
768 return USB_RET_ASYNC;
772 * Close events can be triggered by usbredirparser_do_write which gets called
773 * from within the USBDevice data / control packet callbacks and doing a
774 * usb_detach from within these callbacks is not a good idea.
776 * So we use a bh handler to take care of close events. We also handle
777 * open events from this callback to make sure that a close directly followed
778 * by an open gets handled in the right order.
780 static void usbredir_open_close_bh(void *opaque)
782 USBRedirDevice *dev = opaque;
784 usbredir_device_disconnect(dev);
786 if (dev->parser) {
787 usbredirparser_destroy(dev->parser);
788 dev->parser = NULL;
791 if (dev->cs->opened) {
792 dev->parser = qemu_oom_check(usbredirparser_create());
793 dev->parser->priv = dev;
794 dev->parser->log_func = usbredir_log;
795 dev->parser->read_func = usbredir_read;
796 dev->parser->write_func = usbredir_write;
797 dev->parser->device_connect_func = usbredir_device_connect;
798 dev->parser->device_disconnect_func = usbredir_device_disconnect;
799 dev->parser->interface_info_func = usbredir_interface_info;
800 dev->parser->ep_info_func = usbredir_ep_info;
801 dev->parser->configuration_status_func = usbredir_configuration_status;
802 dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
803 dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
804 dev->parser->interrupt_receiving_status_func =
805 usbredir_interrupt_receiving_status;
806 dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
807 dev->parser->control_packet_func = usbredir_control_packet;
808 dev->parser->bulk_packet_func = usbredir_bulk_packet;
809 dev->parser->iso_packet_func = usbredir_iso_packet;
810 dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
811 dev->read_buf = NULL;
812 dev->read_buf_size = 0;
813 usbredirparser_init(dev->parser, VERSION, NULL, 0, 0);
814 usbredirparser_do_write(dev->parser);
818 static void usbredir_do_attach(void *opaque)
820 USBRedirDevice *dev = opaque;
822 usb_device_attach(&dev->dev);
826 * chardev callbacks
829 static int usbredir_chardev_can_read(void *opaque)
831 USBRedirDevice *dev = opaque;
833 if (dev->parser) {
834 /* usbredir_parser_do_read will consume *all* data we give it */
835 return 1024 * 1024;
836 } else {
837 /* usbredir_open_close_bh hasn't handled the open event yet */
838 return 0;
842 static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
844 USBRedirDevice *dev = opaque;
846 /* No recursion allowed! */
847 assert(dev->read_buf == NULL);
849 dev->read_buf = buf;
850 dev->read_buf_size = size;
852 usbredirparser_do_read(dev->parser);
853 /* Send any acks, etc. which may be queued now */
854 usbredirparser_do_write(dev->parser);
857 static void usbredir_chardev_event(void *opaque, int event)
859 USBRedirDevice *dev = opaque;
861 switch (event) {
862 case CHR_EVENT_OPENED:
863 case CHR_EVENT_CLOSED:
864 qemu_bh_schedule(dev->open_close_bh);
865 break;
870 * init + destroy
873 static int usbredir_initfn(USBDevice *udev)
875 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
876 int i;
878 if (dev->cs == NULL) {
879 qerror_report(QERR_MISSING_PARAMETER, "chardev");
880 return -1;
883 dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
884 dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
886 QTAILQ_INIT(&dev->asyncq);
887 for (i = 0; i < MAX_ENDPOINTS; i++) {
888 QTAILQ_INIT(&dev->endpoint[i].bufpq);
891 /* We'll do the attach once we receive the speed from the usb-host */
892 udev->auto_attach = 0;
894 /* Let the backend know we are ready */
895 qemu_chr_fe_open(dev->cs);
896 qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
897 usbredir_chardev_read, usbredir_chardev_event, dev);
899 return 0;
902 static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
904 AsyncURB *aurb, *next_aurb;
905 int i;
907 QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
908 async_free(dev, aurb);
910 for (i = 0; i < MAX_ENDPOINTS; i++) {
911 usbredir_free_bufpq(dev, I2EP(i));
915 static void usbredir_handle_destroy(USBDevice *udev)
917 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
919 qemu_chr_fe_close(dev->cs);
920 qemu_chr_delete(dev->cs);
921 /* Note must be done after qemu_chr_close, as that causes a close event */
922 qemu_bh_delete(dev->open_close_bh);
924 qemu_del_timer(dev->attach_timer);
925 qemu_free_timer(dev->attach_timer);
927 usbredir_cleanup_device_queues(dev);
929 if (dev->parser) {
930 usbredirparser_destroy(dev->parser);
935 * usbredirparser packet complete callbacks
938 static int usbredir_handle_status(USBRedirDevice *dev,
939 int status, int actual_len)
941 switch (status) {
942 case usb_redir_success:
943 return actual_len;
944 case usb_redir_stall:
945 return USB_RET_STALL;
946 case usb_redir_cancelled:
947 WARNING("returning cancelled packet to HC?\n");
948 case usb_redir_inval:
949 case usb_redir_ioerror:
950 case usb_redir_timeout:
951 default:
952 return USB_RET_NAK;
956 static void usbredir_device_connect(void *priv,
957 struct usb_redir_device_connect_header *device_connect)
959 USBRedirDevice *dev = priv;
961 if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
962 ERROR("Received device connect while already connected\n");
963 return;
966 switch (device_connect->speed) {
967 case usb_redir_speed_low:
968 DPRINTF("attaching low speed device\n");
969 dev->dev.speed = USB_SPEED_LOW;
970 break;
971 case usb_redir_speed_full:
972 DPRINTF("attaching full speed device\n");
973 dev->dev.speed = USB_SPEED_FULL;
974 break;
975 case usb_redir_speed_high:
976 DPRINTF("attaching high speed device\n");
977 dev->dev.speed = USB_SPEED_HIGH;
978 break;
979 case usb_redir_speed_super:
980 DPRINTF("attaching super speed device\n");
981 dev->dev.speed = USB_SPEED_SUPER;
982 break;
983 default:
984 DPRINTF("attaching unknown speed device, assuming full speed\n");
985 dev->dev.speed = USB_SPEED_FULL;
987 dev->dev.speedmask = (1 << dev->dev.speed);
988 qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
991 static void usbredir_device_disconnect(void *priv)
993 USBRedirDevice *dev = priv;
994 int i;
996 /* Stop any pending attaches */
997 qemu_del_timer(dev->attach_timer);
999 if (dev->dev.attached) {
1000 usb_device_detach(&dev->dev);
1002 * Delay next usb device attach to give the guest a chance to see
1003 * see the detach / attach in case of quick close / open succession
1005 dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
1008 /* Reset state so that the next dev connected starts with a clean slate */
1009 usbredir_cleanup_device_queues(dev);
1010 memset(dev->endpoint, 0, sizeof(dev->endpoint));
1011 for (i = 0; i < MAX_ENDPOINTS; i++) {
1012 QTAILQ_INIT(&dev->endpoint[i].bufpq);
1016 static void usbredir_interface_info(void *priv,
1017 struct usb_redir_interface_info_header *interface_info)
1019 /* The intention is to allow specifying acceptable interface classes
1020 for redirection on the cmdline and in the future verify this here,
1021 and disconnect (or never connect) the device if a not accepted
1022 interface class is detected */
1025 static void usbredir_ep_info(void *priv,
1026 struct usb_redir_ep_info_header *ep_info)
1028 USBRedirDevice *dev = priv;
1029 int i;
1031 for (i = 0; i < MAX_ENDPOINTS; i++) {
1032 dev->endpoint[i].type = ep_info->type[i];
1033 dev->endpoint[i].interval = ep_info->interval[i];
1034 dev->endpoint[i].interface = ep_info->interface[i];
1035 switch (dev->endpoint[i].type) {
1036 case usb_redir_type_invalid:
1037 break;
1038 case usb_redir_type_iso:
1039 case usb_redir_type_interrupt:
1040 if (dev->endpoint[i].interval == 0) {
1041 ERROR("Received 0 interval for isoc or irq endpoint\n");
1042 usbredir_device_disconnect(dev);
1044 /* Fall through */
1045 case usb_redir_type_control:
1046 case usb_redir_type_bulk:
1047 DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
1048 dev->endpoint[i].type, dev->endpoint[i].interface);
1049 break;
1050 default:
1051 ERROR("Received invalid endpoint type\n");
1052 usbredir_device_disconnect(dev);
1057 static void usbredir_configuration_status(void *priv, uint32_t id,
1058 struct usb_redir_configuration_status_header *config_status)
1060 USBRedirDevice *dev = priv;
1061 AsyncURB *aurb;
1062 int len = 0;
1064 DPRINTF("set config status %d config %d id %u\n", config_status->status,
1065 config_status->configuration, id);
1067 aurb = async_find(dev, id);
1068 if (!aurb) {
1069 return;
1071 if (aurb->packet) {
1072 if (aurb->get) {
1073 dev->dev.data_buf[0] = config_status->configuration;
1074 len = 1;
1076 aurb->packet->result =
1077 usbredir_handle_status(dev, config_status->status, len);
1078 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1080 async_free(dev, aurb);
1083 static void usbredir_alt_setting_status(void *priv, uint32_t id,
1084 struct usb_redir_alt_setting_status_header *alt_setting_status)
1086 USBRedirDevice *dev = priv;
1087 AsyncURB *aurb;
1088 int len = 0;
1090 DPRINTF("alt status %d intf %d alt %d id: %u\n",
1091 alt_setting_status->status,
1092 alt_setting_status->interface,
1093 alt_setting_status->alt, id);
1095 aurb = async_find(dev, id);
1096 if (!aurb) {
1097 return;
1099 if (aurb->packet) {
1100 if (aurb->get) {
1101 dev->dev.data_buf[0] = alt_setting_status->alt;
1102 len = 1;
1104 aurb->packet->result =
1105 usbredir_handle_status(dev, alt_setting_status->status, len);
1106 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1108 async_free(dev, aurb);
1111 static void usbredir_iso_stream_status(void *priv, uint32_t id,
1112 struct usb_redir_iso_stream_status_header *iso_stream_status)
1114 USBRedirDevice *dev = priv;
1115 uint8_t ep = iso_stream_status->endpoint;
1117 DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1118 ep, id);
1120 if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].iso_started) {
1121 return;
1124 dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
1125 if (iso_stream_status->status == usb_redir_stall) {
1126 DPRINTF("iso stream stopped by peer ep %02X\n", ep);
1127 dev->endpoint[EP2I(ep)].iso_started = 0;
1131 static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1132 struct usb_redir_interrupt_receiving_status_header
1133 *interrupt_receiving_status)
1135 USBRedirDevice *dev = priv;
1136 uint8_t ep = interrupt_receiving_status->endpoint;
1138 DPRINTF("interrupt recv status %d ep %02X id %u\n",
1139 interrupt_receiving_status->status, ep, id);
1141 if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].interrupt_started) {
1142 return;
1145 dev->endpoint[EP2I(ep)].interrupt_error =
1146 interrupt_receiving_status->status;
1147 if (interrupt_receiving_status->status == usb_redir_stall) {
1148 DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep);
1149 dev->endpoint[EP2I(ep)].interrupt_started = 0;
1153 static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1154 struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1158 static void usbredir_control_packet(void *priv, uint32_t id,
1159 struct usb_redir_control_packet_header *control_packet,
1160 uint8_t *data, int data_len)
1162 USBRedirDevice *dev = priv;
1163 int len = control_packet->length;
1164 AsyncURB *aurb;
1166 DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1167 len, id);
1169 aurb = async_find(dev, id);
1170 if (!aurb) {
1171 free(data);
1172 return;
1175 aurb->control_packet.status = control_packet->status;
1176 aurb->control_packet.length = control_packet->length;
1177 if (memcmp(&aurb->control_packet, control_packet,
1178 sizeof(*control_packet))) {
1179 ERROR("return control packet mismatch, please report this!\n");
1180 len = USB_RET_NAK;
1183 if (aurb->packet) {
1184 len = usbredir_handle_status(dev, control_packet->status, len);
1185 if (len > 0) {
1186 usbredir_log_data(dev, "ctrl data in:", data, data_len);
1187 if (data_len <= sizeof(dev->dev.data_buf)) {
1188 memcpy(dev->dev.data_buf, data, data_len);
1189 } else {
1190 ERROR("ctrl buffer too small (%d > %zu)\n",
1191 data_len, sizeof(dev->dev.data_buf));
1192 len = USB_RET_STALL;
1195 aurb->packet->result = len;
1196 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1198 async_free(dev, aurb);
1199 free(data);
1202 static void usbredir_bulk_packet(void *priv, uint32_t id,
1203 struct usb_redir_bulk_packet_header *bulk_packet,
1204 uint8_t *data, int data_len)
1206 USBRedirDevice *dev = priv;
1207 uint8_t ep = bulk_packet->endpoint;
1208 int len = bulk_packet->length;
1209 AsyncURB *aurb;
1211 DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1212 ep, len, id);
1214 aurb = async_find(dev, id);
1215 if (!aurb) {
1216 free(data);
1217 return;
1220 if (aurb->bulk_packet.endpoint != bulk_packet->endpoint ||
1221 aurb->bulk_packet.stream_id != bulk_packet->stream_id) {
1222 ERROR("return bulk packet mismatch, please report this!\n");
1223 len = USB_RET_NAK;
1226 if (aurb->packet) {
1227 len = usbredir_handle_status(dev, bulk_packet->status, len);
1228 if (len > 0) {
1229 usbredir_log_data(dev, "bulk data in:", data, data_len);
1230 if (data_len <= aurb->packet->iov.size) {
1231 usb_packet_copy(aurb->packet, data, data_len);
1232 } else {
1233 ERROR("bulk buffer too small (%d > %zd)\n", data_len,
1234 aurb->packet->iov.size);
1235 len = USB_RET_STALL;
1238 aurb->packet->result = len;
1239 usb_packet_complete(&dev->dev, aurb->packet);
1241 async_free(dev, aurb);
1242 free(data);
1245 static void usbredir_iso_packet(void *priv, uint32_t id,
1246 struct usb_redir_iso_packet_header *iso_packet,
1247 uint8_t *data, int data_len)
1249 USBRedirDevice *dev = priv;
1250 uint8_t ep = iso_packet->endpoint;
1252 DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1253 data_len, id);
1255 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1256 ERROR("received iso packet for non iso endpoint %02X\n", ep);
1257 free(data);
1258 return;
1261 if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1262 DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1263 free(data);
1264 return;
1267 /* bufp_alloc also adds the packet to the ep queue */
1268 bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1271 static void usbredir_interrupt_packet(void *priv, uint32_t id,
1272 struct usb_redir_interrupt_packet_header *interrupt_packet,
1273 uint8_t *data, int data_len)
1275 USBRedirDevice *dev = priv;
1276 uint8_t ep = interrupt_packet->endpoint;
1278 DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1279 interrupt_packet->status, ep, data_len, id);
1281 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
1282 ERROR("received int packet for non interrupt endpoint %02X\n", ep);
1283 free(data);
1284 return;
1287 if (ep & USB_DIR_IN) {
1288 if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
1289 DPRINTF("received int packet while not started ep %02X\n", ep);
1290 free(data);
1291 return;
1294 /* bufp_alloc also adds the packet to the ep queue */
1295 bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
1296 } else {
1297 int len = interrupt_packet->length;
1299 AsyncURB *aurb = async_find(dev, id);
1300 if (!aurb) {
1301 return;
1304 if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
1305 ERROR("return int packet mismatch, please report this!\n");
1306 len = USB_RET_NAK;
1309 if (aurb->packet) {
1310 aurb->packet->result = usbredir_handle_status(dev,
1311 interrupt_packet->status, len);
1312 usb_packet_complete(&dev->dev, aurb->packet);
1314 async_free(dev, aurb);
1318 static void usbredir_class_initfn(ObjectClass *klass, void *data)
1320 USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
1322 uc->init = usbredir_initfn;
1323 uc->product_desc = "USB Redirection Device";
1324 uc->handle_destroy = usbredir_handle_destroy;
1325 uc->handle_packet = usb_generic_handle_packet;
1326 uc->cancel_packet = usbredir_cancel_packet;
1327 uc->handle_reset = usbredir_handle_reset;
1328 uc->handle_data = usbredir_handle_data;
1329 uc->handle_control = usbredir_handle_control;
1332 static struct DeviceInfo usbredir_dev_info = {
1333 .name = "usb-redir",
1334 .size = sizeof(USBRedirDevice),
1335 .class_init= usbredir_class_initfn,
1336 .props = (Property[]) {
1337 DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
1338 DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
1339 DEFINE_PROP_END_OF_LIST(),
1343 static void usbredir_register_devices(void)
1345 usb_qdev_register(&usbredir_dev_info, NULL, NULL);
1347 device_init(usbredir_register_devices);