Sparc: fix non-faulting unassigned memory accesses
[qemu/mdroth.git] / usb-redir.c
blobe2129931a07582b8edd15aa2a17bb62a7f9ce4a4
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\n", 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\n", 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 return qemu_chr_write(dev->cs, data, count);
232 * Async and buffered packets helpers
235 static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
237 AsyncURB *aurb = (AsyncURB *) qemu_mallocz(sizeof(AsyncURB));
238 aurb->dev = dev;
239 aurb->packet = p;
240 aurb->packet_id = dev->packet_id;
241 QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
242 dev->packet_id++;
244 return aurb;
247 static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
249 QTAILQ_REMOVE(&dev->asyncq, aurb, next);
250 qemu_free(aurb);
253 static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
255 AsyncURB *aurb;
257 QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
258 if (aurb->packet_id == packet_id) {
259 return aurb;
262 ERROR("could not find async urb for packet_id %u\n", packet_id);
263 return NULL;
266 static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
268 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
269 AsyncURB *aurb;
271 QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
272 if (p != aurb->packet) {
273 continue;
276 DPRINTF("async cancel id %u\n", aurb->packet_id);
277 usbredirparser_send_cancel_data_packet(dev->parser, aurb->packet_id);
278 usbredirparser_do_write(dev->parser);
280 /* Mark it as dead */
281 aurb->packet = NULL;
282 break;
286 static struct buf_packet *bufp_alloc(USBRedirDevice *dev,
287 uint8_t *data, int len, int status, uint8_t ep)
289 struct buf_packet *bufp = qemu_malloc(sizeof(struct buf_packet));
290 bufp->data = data;
291 bufp->len = len;
292 bufp->status = status;
293 QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
294 return bufp;
297 static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
298 uint8_t ep)
300 QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
301 free(bufp->data);
302 qemu_free(bufp);
305 static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
307 struct buf_packet *buf, *buf_next;
309 QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) {
310 bufp_free(dev, buf, ep);
315 * USBDevice callbacks
318 static void usbredir_handle_reset(USBDevice *udev)
320 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
322 DPRINTF("reset device\n");
323 usbredirparser_send_reset(dev->parser);
324 usbredirparser_do_write(dev->parser);
327 static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
328 uint8_t ep)
330 int status, len;
332 if (!dev->endpoint[EP2I(ep)].iso_started &&
333 !dev->endpoint[EP2I(ep)].iso_error) {
334 struct usb_redir_start_iso_stream_header start_iso = {
335 .endpoint = ep,
336 /* TODO maybe do something with these depending on ep interval? */
337 .pkts_per_urb = 32,
338 .no_urbs = 3,
340 /* No id, we look at the ep when receiving a status back */
341 usbredirparser_send_start_iso_stream(dev->parser, 0, &start_iso);
342 usbredirparser_do_write(dev->parser);
343 DPRINTF("iso stream started ep %02X\n", ep);
344 dev->endpoint[EP2I(ep)].iso_started = 1;
347 if (ep & USB_DIR_IN) {
348 struct buf_packet *isop;
350 isop = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
351 if (isop == NULL) {
352 DPRINTF2("iso-token-in ep %02X, no isop\n", ep);
353 /* Check iso_error for stream errors, otherwise its an underrun */
354 status = dev->endpoint[EP2I(ep)].iso_error;
355 dev->endpoint[EP2I(ep)].iso_error = 0;
356 return usbredir_handle_status(dev, status, 0);
358 DPRINTF2("iso-token-in ep %02X status %d len %d\n", ep, isop->status,
359 isop->len);
361 status = isop->status;
362 if (status != usb_redir_success) {
363 bufp_free(dev, isop, ep);
364 return usbredir_handle_status(dev, status, 0);
367 len = isop->len;
368 if (len > p->len) {
369 ERROR("received iso data is larger then packet ep %02X\n", ep);
370 bufp_free(dev, isop, ep);
371 return USB_RET_NAK;
373 memcpy(p->data, isop->data, len);
374 bufp_free(dev, isop, ep);
375 return len;
376 } else {
377 /* If the stream was not started because of a pending error don't
378 send the packet to the usb-host */
379 if (dev->endpoint[EP2I(ep)].iso_started) {
380 struct usb_redir_iso_packet_header iso_packet = {
381 .endpoint = ep,
382 .length = p->len
384 /* No id, we look at the ep when receiving a status back */
385 usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,
386 p->data, p->len);
387 usbredirparser_do_write(dev->parser);
389 status = dev->endpoint[EP2I(ep)].iso_error;
390 dev->endpoint[EP2I(ep)].iso_error = 0;
391 DPRINTF2("iso-token-out ep %02X status %d len %d\n", ep, status,
392 p->len);
393 return usbredir_handle_status(dev, status, p->len);
397 static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
399 struct usb_redir_stop_iso_stream_header stop_iso_stream = {
400 .endpoint = ep
402 if (dev->endpoint[EP2I(ep)].iso_started) {
403 usbredirparser_send_stop_iso_stream(dev->parser, 0, &stop_iso_stream);
404 DPRINTF("iso stream stopped ep %02X\n", ep);
405 dev->endpoint[EP2I(ep)].iso_started = 0;
407 usbredir_free_bufpq(dev, ep);
410 static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
411 uint8_t ep)
413 AsyncURB *aurb = async_alloc(dev, p);
414 struct usb_redir_bulk_packet_header bulk_packet;
416 DPRINTF("bulk-out ep %02X len %d id %u\n", ep, p->len, aurb->packet_id);
418 bulk_packet.endpoint = ep;
419 bulk_packet.length = p->len;
420 bulk_packet.stream_id = 0;
421 aurb->bulk_packet = bulk_packet;
423 if (ep & USB_DIR_IN) {
424 usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
425 &bulk_packet, NULL, 0);
426 } else {
427 usbredir_log_data(dev, "bulk data out:", p->data, p->len);
428 usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
429 &bulk_packet, p->data, p->len);
431 usbredirparser_do_write(dev->parser);
432 return USB_RET_ASYNC;
435 static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
436 USBPacket *p, uint8_t ep)
438 if (ep & USB_DIR_IN) {
439 /* Input interrupt endpoint, buffered packet input */
440 struct buf_packet *intp;
441 int status, len;
443 if (!dev->endpoint[EP2I(ep)].interrupt_started &&
444 !dev->endpoint[EP2I(ep)].interrupt_error) {
445 struct usb_redir_start_interrupt_receiving_header start_int = {
446 .endpoint = ep,
448 /* No id, we look at the ep when receiving a status back */
449 usbredirparser_send_start_interrupt_receiving(dev->parser, 0,
450 &start_int);
451 usbredirparser_do_write(dev->parser);
452 DPRINTF("interrupt recv started ep %02X\n", ep);
453 dev->endpoint[EP2I(ep)].interrupt_started = 1;
456 intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
457 if (intp == NULL) {
458 DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);
459 /* Check interrupt_error for stream errors */
460 status = dev->endpoint[EP2I(ep)].interrupt_error;
461 dev->endpoint[EP2I(ep)].interrupt_error = 0;
462 return usbredir_handle_status(dev, status, 0);
464 DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,
465 intp->status, intp->len);
467 status = intp->status;
468 if (status != usb_redir_success) {
469 bufp_free(dev, intp, ep);
470 return usbredir_handle_status(dev, status, 0);
473 len = intp->len;
474 if (len > p->len) {
475 ERROR("received int data is larger then packet ep %02X\n", ep);
476 bufp_free(dev, intp, ep);
477 return USB_RET_NAK;
479 memcpy(p->data, intp->data, len);
480 bufp_free(dev, intp, ep);
481 return len;
482 } else {
483 /* Output interrupt endpoint, normal async operation */
484 AsyncURB *aurb = async_alloc(dev, p);
485 struct usb_redir_interrupt_packet_header interrupt_packet;
487 DPRINTF("interrupt-out ep %02X len %d id %u\n", ep, p->len,
488 aurb->packet_id);
490 interrupt_packet.endpoint = ep;
491 interrupt_packet.length = p->len;
492 aurb->interrupt_packet = interrupt_packet;
494 usbredir_log_data(dev, "interrupt data out:", p->data, p->len);
495 usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
496 &interrupt_packet, p->data, p->len);
497 usbredirparser_do_write(dev->parser);
498 return USB_RET_ASYNC;
502 static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev,
503 uint8_t ep)
505 struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv = {
506 .endpoint = ep
508 if (dev->endpoint[EP2I(ep)].interrupt_started) {
509 usbredirparser_send_stop_interrupt_receiving(dev->parser, 0,
510 &stop_interrupt_recv);
511 DPRINTF("interrupt recv stopped ep %02X\n", ep);
512 dev->endpoint[EP2I(ep)].interrupt_started = 0;
514 usbredir_free_bufpq(dev, ep);
517 static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
519 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
520 uint8_t ep;
522 ep = p->devep;
523 if (p->pid == USB_TOKEN_IN) {
524 ep |= USB_DIR_IN;
527 switch (dev->endpoint[EP2I(ep)].type) {
528 case USB_ENDPOINT_XFER_CONTROL:
529 ERROR("handle_data called for control transfer on ep %02X\n", ep);
530 return USB_RET_NAK;
531 case USB_ENDPOINT_XFER_ISOC:
532 return usbredir_handle_iso_data(dev, p, ep);
533 case USB_ENDPOINT_XFER_BULK:
534 return usbredir_handle_bulk_data(dev, p, ep);;
535 case USB_ENDPOINT_XFER_INT:
536 return usbredir_handle_interrupt_data(dev, p, ep);;
537 default:
538 ERROR("handle_data ep %02X has unknown type %d\n", ep,
539 dev->endpoint[EP2I(ep)].type);
540 return USB_RET_NAK;
544 static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
545 int config)
547 struct usb_redir_set_configuration_header set_config;
548 AsyncURB *aurb = async_alloc(dev, p);
549 int i;
551 DPRINTF("set config %d id %u\n", config, aurb->packet_id);
553 for (i = 0; i < MAX_ENDPOINTS; i++) {
554 switch (dev->endpoint[i].type) {
555 case USB_ENDPOINT_XFER_ISOC:
556 usbredir_stop_iso_stream(dev, I2EP(i));
557 break;
558 case USB_ENDPOINT_XFER_INT:
559 if (i & 0x10) {
560 usbredir_stop_interrupt_receiving(dev, I2EP(i));
562 break;
564 usbredir_free_bufpq(dev, I2EP(i));
567 set_config.configuration = config;
568 usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
569 &set_config);
570 usbredirparser_do_write(dev->parser);
571 return USB_RET_ASYNC;
574 static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
576 AsyncURB *aurb = async_alloc(dev, p);
578 DPRINTF("get config id %u\n", aurb->packet_id);
580 aurb->get = 1;
581 usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
582 usbredirparser_do_write(dev->parser);
583 return USB_RET_ASYNC;
586 static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
587 int interface, int alt)
589 struct usb_redir_set_alt_setting_header set_alt;
590 AsyncURB *aurb = async_alloc(dev, p);
591 int i;
593 DPRINTF("set interface %d alt %d id %u\n", interface, alt,
594 aurb->packet_id);
596 for (i = 0; i < MAX_ENDPOINTS; i++) {
597 if (dev->endpoint[i].interface == interface) {
598 switch (dev->endpoint[i].type) {
599 case USB_ENDPOINT_XFER_ISOC:
600 usbredir_stop_iso_stream(dev, I2EP(i));
601 break;
602 case USB_ENDPOINT_XFER_INT:
603 if (i & 0x10) {
604 usbredir_stop_interrupt_receiving(dev, I2EP(i));
606 break;
608 usbredir_free_bufpq(dev, I2EP(i));
612 set_alt.interface = interface;
613 set_alt.alt = alt;
614 usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
615 &set_alt);
616 usbredirparser_do_write(dev->parser);
617 return USB_RET_ASYNC;
620 static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
621 int interface)
623 struct usb_redir_get_alt_setting_header get_alt;
624 AsyncURB *aurb = async_alloc(dev, p);
626 DPRINTF("get interface %d id %u\n", interface, aurb->packet_id);
628 get_alt.interface = interface;
629 aurb->get = 1;
630 usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
631 &get_alt);
632 usbredirparser_do_write(dev->parser);
633 return USB_RET_ASYNC;
636 static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
637 int request, int value, int index, int length, uint8_t *data)
639 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
640 struct usb_redir_control_packet_header control_packet;
641 AsyncURB *aurb;
643 /* Special cases for certain standard device requests */
644 switch (request) {
645 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
646 DPRINTF("set address %d\n", value);
647 dev->dev.addr = value;
648 return 0;
649 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
650 return usbredir_set_config(dev, p, value & 0xff);
651 case DeviceRequest | USB_REQ_GET_CONFIGURATION:
652 return usbredir_get_config(dev, p);
653 case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
654 return usbredir_set_interface(dev, p, index, value);
655 case InterfaceRequest | USB_REQ_GET_INTERFACE:
656 return usbredir_get_interface(dev, p, index);
659 /* "Normal" ctrl requests */
660 aurb = async_alloc(dev, p);
662 /* Note request is (bRequestType << 8) | bRequest */
663 DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
664 request >> 8, request & 0xff, value, index, length,
665 aurb->packet_id);
667 control_packet.request = request & 0xFF;
668 control_packet.requesttype = request >> 8;
669 control_packet.endpoint = control_packet.requesttype & USB_DIR_IN;
670 control_packet.value = value;
671 control_packet.index = index;
672 control_packet.length = length;
673 aurb->control_packet = control_packet;
675 if (control_packet.requesttype & USB_DIR_IN) {
676 usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
677 &control_packet, NULL, 0);
678 } else {
679 usbredir_log_data(dev, "ctrl data out:", data, length);
680 usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
681 &control_packet, data, length);
683 usbredirparser_do_write(dev->parser);
684 return USB_RET_ASYNC;
688 * Close events can be triggered by usbredirparser_do_write which gets called
689 * from within the USBDevice data / control packet callbacks and doing a
690 * usb_detach from within these callbacks is not a good idea.
692 * So we use a bh handler to take care of close events. We also handle
693 * open events from this callback to make sure that a close directly followed
694 * by an open gets handled in the right order.
696 static void usbredir_open_close_bh(void *opaque)
698 USBRedirDevice *dev = opaque;
700 usbredir_device_disconnect(dev);
702 if (dev->parser) {
703 usbredirparser_destroy(dev->parser);
704 dev->parser = NULL;
707 if (dev->cs->opened) {
708 dev->parser = qemu_oom_check(usbredirparser_create());
709 dev->parser->priv = dev;
710 dev->parser->log_func = usbredir_log;
711 dev->parser->read_func = usbredir_read;
712 dev->parser->write_func = usbredir_write;
713 dev->parser->device_connect_func = usbredir_device_connect;
714 dev->parser->device_disconnect_func = usbredir_device_disconnect;
715 dev->parser->interface_info_func = usbredir_interface_info;
716 dev->parser->ep_info_func = usbredir_ep_info;
717 dev->parser->configuration_status_func = usbredir_configuration_status;
718 dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
719 dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
720 dev->parser->interrupt_receiving_status_func =
721 usbredir_interrupt_receiving_status;
722 dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
723 dev->parser->control_packet_func = usbredir_control_packet;
724 dev->parser->bulk_packet_func = usbredir_bulk_packet;
725 dev->parser->iso_packet_func = usbredir_iso_packet;
726 dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
727 dev->read_buf = NULL;
728 dev->read_buf_size = 0;
729 usbredirparser_init(dev->parser, VERSION, NULL, 0, 0);
730 usbredirparser_do_write(dev->parser);
734 static void usbredir_do_attach(void *opaque)
736 USBRedirDevice *dev = opaque;
738 usb_device_attach(&dev->dev);
742 * chardev callbacks
745 static int usbredir_chardev_can_read(void *opaque)
747 USBRedirDevice *dev = opaque;
749 if (dev->parser) {
750 /* usbredir_parser_do_read will consume *all* data we give it */
751 return 1024 * 1024;
752 } else {
753 /* usbredir_open_close_bh hasn't handled the open event yet */
754 return 0;
758 static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
760 USBRedirDevice *dev = opaque;
762 /* No recursion allowed! */
763 assert(dev->read_buf == NULL);
765 dev->read_buf = buf;
766 dev->read_buf_size = size;
768 usbredirparser_do_read(dev->parser);
769 /* Send any acks, etc. which may be queued now */
770 usbredirparser_do_write(dev->parser);
773 static void usbredir_chardev_event(void *opaque, int event)
775 USBRedirDevice *dev = opaque;
777 switch (event) {
778 case CHR_EVENT_OPENED:
779 case CHR_EVENT_CLOSED:
780 qemu_bh_schedule(dev->open_close_bh);
781 break;
786 * init + destroy
789 static int usbredir_initfn(USBDevice *udev)
791 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
792 int i;
794 if (dev->cs == NULL) {
795 qerror_report(QERR_MISSING_PARAMETER, "chardev");
796 return -1;
799 dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
800 dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
802 QTAILQ_INIT(&dev->asyncq);
803 for (i = 0; i < MAX_ENDPOINTS; i++) {
804 QTAILQ_INIT(&dev->endpoint[i].bufpq);
807 /* We'll do the attach once we receive the speed from the usb-host */
808 udev->auto_attach = 0;
810 qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
811 usbredir_chardev_read, usbredir_chardev_event, dev);
813 return 0;
816 static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
818 AsyncURB *aurb, *next_aurb;
819 int i;
821 QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
822 async_free(dev, aurb);
824 for (i = 0; i < MAX_ENDPOINTS; i++) {
825 usbredir_free_bufpq(dev, I2EP(i));
829 static void usbredir_handle_destroy(USBDevice *udev)
831 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
833 qemu_chr_close(dev->cs);
834 /* Note must be done after qemu_chr_close, as that causes a close event */
835 qemu_bh_delete(dev->open_close_bh);
837 qemu_del_timer(dev->attach_timer);
838 qemu_free_timer(dev->attach_timer);
840 usbredir_cleanup_device_queues(dev);
842 if (dev->parser) {
843 usbredirparser_destroy(dev->parser);
848 * usbredirparser packet complete callbacks
851 static int usbredir_handle_status(USBRedirDevice *dev,
852 int status, int actual_len)
854 switch (status) {
855 case usb_redir_success:
856 return actual_len;
857 case usb_redir_stall:
858 return USB_RET_STALL;
859 case usb_redir_cancelled:
860 WARNING("returning cancelled packet to HC?\n");
861 case usb_redir_inval:
862 case usb_redir_ioerror:
863 case usb_redir_timeout:
864 default:
865 return USB_RET_NAK;
869 static void usbredir_device_connect(void *priv,
870 struct usb_redir_device_connect_header *device_connect)
872 USBRedirDevice *dev = priv;
874 switch (device_connect->speed) {
875 case usb_redir_speed_low:
876 DPRINTF("attaching low speed device\n");
877 dev->dev.speed = USB_SPEED_LOW;
878 break;
879 case usb_redir_speed_full:
880 DPRINTF("attaching full speed device\n");
881 dev->dev.speed = USB_SPEED_FULL;
882 break;
883 case usb_redir_speed_high:
884 DPRINTF("attaching high speed device\n");
885 dev->dev.speed = USB_SPEED_HIGH;
886 break;
887 case usb_redir_speed_super:
888 DPRINTF("attaching super speed device\n");
889 dev->dev.speed = USB_SPEED_SUPER;
890 break;
891 default:
892 DPRINTF("attaching unknown speed device, assuming full speed\n");
893 dev->dev.speed = USB_SPEED_FULL;
895 dev->dev.speedmask = (1 << dev->dev.speed);
896 qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
899 static void usbredir_device_disconnect(void *priv)
901 USBRedirDevice *dev = priv;
903 /* Stop any pending attaches */
904 qemu_del_timer(dev->attach_timer);
906 if (dev->dev.attached) {
907 usb_device_detach(&dev->dev);
908 usbredir_cleanup_device_queues(dev);
910 * Delay next usb device attach to give the guest a chance to see
911 * see the detach / attach in case of quick close / open succession
913 dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
917 static void usbredir_interface_info(void *priv,
918 struct usb_redir_interface_info_header *interface_info)
920 /* The intention is to allow specifying acceptable interface classes
921 for redirection on the cmdline and in the future verify this here,
922 and disconnect (or never connect) the device if a not accepted
923 interface class is detected */
926 static void usbredir_ep_info(void *priv,
927 struct usb_redir_ep_info_header *ep_info)
929 USBRedirDevice *dev = priv;
930 int i;
932 for (i = 0; i < MAX_ENDPOINTS; i++) {
933 dev->endpoint[i].type = ep_info->type[i];
934 dev->endpoint[i].interval = ep_info->interval[i];
935 dev->endpoint[i].interface = ep_info->interface[i];
936 if (dev->endpoint[i].type != usb_redir_type_invalid) {
937 DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
938 dev->endpoint[i].type, dev->endpoint[i].interface);
943 static void usbredir_configuration_status(void *priv, uint32_t id,
944 struct usb_redir_configuration_status_header *config_status)
946 USBRedirDevice *dev = priv;
947 AsyncURB *aurb;
948 int len = 0;
950 DPRINTF("set config status %d config %d id %u\n", config_status->status,
951 config_status->configuration, id);
953 aurb = async_find(dev, id);
954 if (!aurb) {
955 return;
957 if (aurb->packet) {
958 if (aurb->get) {
959 dev->dev.data_buf[0] = config_status->configuration;
960 len = 1;
962 aurb->packet->len =
963 usbredir_handle_status(dev, config_status->status, len);
964 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
966 async_free(dev, aurb);
969 static void usbredir_alt_setting_status(void *priv, uint32_t id,
970 struct usb_redir_alt_setting_status_header *alt_setting_status)
972 USBRedirDevice *dev = priv;
973 AsyncURB *aurb;
974 int len = 0;
976 DPRINTF("alt status %d intf %d alt %d id: %u\n",
977 alt_setting_status->status,
978 alt_setting_status->interface,
979 alt_setting_status->alt, 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] = alt_setting_status->alt;
988 len = 1;
990 aurb->packet->len =
991 usbredir_handle_status(dev, alt_setting_status->status, len);
992 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
994 async_free(dev, aurb);
997 static void usbredir_iso_stream_status(void *priv, uint32_t id,
998 struct usb_redir_iso_stream_status_header *iso_stream_status)
1000 USBRedirDevice *dev = priv;
1001 uint8_t ep = iso_stream_status->endpoint;
1003 DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1004 ep, id);
1006 dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
1007 if (iso_stream_status->status == usb_redir_stall) {
1008 DPRINTF("iso stream stopped by peer ep %02X\n", ep);
1009 dev->endpoint[EP2I(ep)].iso_started = 0;
1013 static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1014 struct usb_redir_interrupt_receiving_status_header
1015 *interrupt_receiving_status)
1017 USBRedirDevice *dev = priv;
1018 uint8_t ep = interrupt_receiving_status->endpoint;
1020 DPRINTF("interrupt recv status %d ep %02X id %u\n",
1021 interrupt_receiving_status->status, ep, id);
1023 dev->endpoint[EP2I(ep)].interrupt_error =
1024 interrupt_receiving_status->status;
1025 if (interrupt_receiving_status->status == usb_redir_stall) {
1026 DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep);
1027 dev->endpoint[EP2I(ep)].interrupt_started = 0;
1031 static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1032 struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1036 static void usbredir_control_packet(void *priv, uint32_t id,
1037 struct usb_redir_control_packet_header *control_packet,
1038 uint8_t *data, int data_len)
1040 USBRedirDevice *dev = priv;
1041 int len = control_packet->length;
1042 AsyncURB *aurb;
1044 DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1045 len, id);
1047 aurb = async_find(dev, id);
1048 if (!aurb) {
1049 free(data);
1050 return;
1053 aurb->control_packet.status = control_packet->status;
1054 aurb->control_packet.length = control_packet->length;
1055 if (memcmp(&aurb->control_packet, control_packet,
1056 sizeof(*control_packet))) {
1057 ERROR("return control packet mismatch, please report this!\n");
1058 len = USB_RET_NAK;
1061 if (aurb->packet) {
1062 len = usbredir_handle_status(dev, control_packet->status, len);
1063 if (len > 0) {
1064 usbredir_log_data(dev, "ctrl data in:", data, data_len);
1065 if (data_len <= sizeof(dev->dev.data_buf)) {
1066 memcpy(dev->dev.data_buf, data, data_len);
1067 } else {
1068 ERROR("ctrl buffer too small (%d > %zu)\n",
1069 data_len, sizeof(dev->dev.data_buf));
1070 len = USB_RET_STALL;
1073 aurb->packet->len = len;
1074 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1076 async_free(dev, aurb);
1077 free(data);
1080 static void usbredir_bulk_packet(void *priv, uint32_t id,
1081 struct usb_redir_bulk_packet_header *bulk_packet,
1082 uint8_t *data, int data_len)
1084 USBRedirDevice *dev = priv;
1085 uint8_t ep = bulk_packet->endpoint;
1086 int len = bulk_packet->length;
1087 AsyncURB *aurb;
1089 DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1090 ep, len, id);
1092 aurb = async_find(dev, id);
1093 if (!aurb) {
1094 free(data);
1095 return;
1098 if (aurb->bulk_packet.endpoint != bulk_packet->endpoint ||
1099 aurb->bulk_packet.stream_id != bulk_packet->stream_id) {
1100 ERROR("return bulk packet mismatch, please report this!\n");
1101 len = USB_RET_NAK;
1104 if (aurb->packet) {
1105 len = usbredir_handle_status(dev, bulk_packet->status, len);
1106 if (len > 0) {
1107 usbredir_log_data(dev, "bulk data in:", data, data_len);
1108 if (data_len <= aurb->packet->len) {
1109 memcpy(aurb->packet->data, data, data_len);
1110 } else {
1111 ERROR("bulk buffer too small (%d > %d)\n", data_len,
1112 aurb->packet->len);
1113 len = USB_RET_STALL;
1116 aurb->packet->len = len;
1117 usb_packet_complete(&dev->dev, aurb->packet);
1119 async_free(dev, aurb);
1120 free(data);
1123 static void usbredir_iso_packet(void *priv, uint32_t id,
1124 struct usb_redir_iso_packet_header *iso_packet,
1125 uint8_t *data, int data_len)
1127 USBRedirDevice *dev = priv;
1128 uint8_t ep = iso_packet->endpoint;
1130 DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1131 data_len, id);
1133 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1134 ERROR("received iso packet for non iso endpoint %02X\n", ep);
1135 free(data);
1136 return;
1139 if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1140 DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1141 free(data);
1142 return;
1145 /* bufp_alloc also adds the packet to the ep queue */
1146 bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1149 static void usbredir_interrupt_packet(void *priv, uint32_t id,
1150 struct usb_redir_interrupt_packet_header *interrupt_packet,
1151 uint8_t *data, int data_len)
1153 USBRedirDevice *dev = priv;
1154 uint8_t ep = interrupt_packet->endpoint;
1156 DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1157 interrupt_packet->status, ep, data_len, id);
1159 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
1160 ERROR("received int packet for non interrupt endpoint %02X\n", ep);
1161 free(data);
1162 return;
1165 if (ep & USB_DIR_IN) {
1166 if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
1167 DPRINTF("received int packet while not started ep %02X\n", ep);
1168 free(data);
1169 return;
1172 /* bufp_alloc also adds the packet to the ep queue */
1173 bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
1174 } else {
1175 int len = interrupt_packet->length;
1177 AsyncURB *aurb = async_find(dev, id);
1178 if (!aurb) {
1179 return;
1182 if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
1183 ERROR("return int packet mismatch, please report this!\n");
1184 len = USB_RET_NAK;
1187 if (aurb->packet) {
1188 aurb->packet->len = usbredir_handle_status(dev,
1189 interrupt_packet->status, len);
1190 usb_packet_complete(&dev->dev, aurb->packet);
1192 async_free(dev, aurb);
1196 static struct USBDeviceInfo usbredir_dev_info = {
1197 .product_desc = "USB Redirection Device",
1198 .qdev.name = "usb-redir",
1199 .qdev.size = sizeof(USBRedirDevice),
1200 .init = usbredir_initfn,
1201 .handle_destroy = usbredir_handle_destroy,
1202 .handle_packet = usb_generic_handle_packet,
1203 .cancel_packet = usbredir_cancel_packet,
1204 .handle_reset = usbredir_handle_reset,
1205 .handle_data = usbredir_handle_data,
1206 .handle_control = usbredir_handle_control,
1207 .qdev.props = (Property[]) {
1208 DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
1209 DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
1210 DEFINE_PROP_END_OF_LIST(),
1214 static void usbredir_register_devices(void)
1216 usb_qdev_register(&usbredir_dev_info);
1218 device_init(usbredir_register_devices);