2
* USB redirector usb-guest
4
* Copyright (c) 2011 Red Hat, Inc.
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
28
#include "qemu-common.h"
29
#include "qemu-timer.h"
34
#include <sys/ioctl.h>
36
#include <usbredirparser.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) */
52
QTAILQ_ENTRY(buf_packet)next;
58
uint8_t interface; /* bInterfaceNumber this ep belongs to */
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 {
71
/* Data passed from chardev the fd_read cb to the usbredirparser read cb */
72
const uint8_t *read_buf;
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];
82
QTAILQ_HEAD(, AsyncURB) asyncq;
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
140
if (dev->debug >= usbredirparser_error) { \
141
error_report("usb-redir error: " __VA_ARGS__); \
144
#define WARNING(...) \
146
if (dev->debug >= usbredirparser_warning) { \
147
error_report("usb-redir warning: " __VA_ARGS__); \
152
if (dev->debug >= usbredirparser_info) { \
153
error_report("usb-redir: " __VA_ARGS__); \
156
#define DPRINTF(...) \
158
if (dev->debug >= usbredirparser_debug) { \
159
error_report("usb-redir: " __VA_ARGS__); \
162
#define DPRINTF2(...) \
164
if (dev->debug >= usbredirparser_debug_data) { \
165
error_report("usb-redir: " __VA_ARGS__); \
169
static void usbredir_log(void *priv, int level, const char *msg)
171
USBRedirDevice *dev = priv;
173
if (dev->debug < level) {
177
error_report("%s\n", msg);
180
static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
181
const uint8_t *data, int len)
185
if (dev->debug < usbredirparser_debug_data) {
189
for (i = 0; i < len; i += j) {
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;
218
dev->read_buf = NULL;
224
static int usbredir_write(void *priv, uint8_t *data, int count)
226
USBRedirDevice *dev = priv;
228
if (!dev->cs->opened) {
232
return qemu_chr_fe_write(dev->cs, data, count);
236
* Async and buffered packets helpers
239
static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
241
AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
244
aurb->packet_id = dev->packet_id;
245
QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
251
static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
253
QTAILQ_REMOVE(&dev->asyncq, aurb, next);
257
static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
261
QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
262
if (aurb->packet_id == packet_id) {
266
ERROR("could not find async urb for packet_id %u\n", packet_id);
270
static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
272
USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
275
QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
276
if (p != aurb->packet) {
280
DPRINTF("async cancel id %u\n", aurb->packet_id);
281
usbredirparser_send_cancel_data_packet(dev->parser, aurb->packet_id);
282
usbredirparser_do_write(dev->parser);
284
/* Mark it as dead */
290
static struct buf_packet *bufp_alloc(USBRedirDevice *dev,
291
uint8_t *data, int len, int status, uint8_t ep)
293
struct buf_packet *bufp = g_malloc(sizeof(struct buf_packet));
296
bufp->status = status;
297
QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
301
static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
304
QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
309
static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
311
struct buf_packet *buf, *buf_next;
313
QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) {
314
bufp_free(dev, buf, ep);
319
* USBDevice callbacks
322
static void usbredir_handle_reset(USBDevice *udev)
324
USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
326
DPRINTF("reset device\n");
327
usbredirparser_send_reset(dev->parser);
328
usbredirparser_do_write(dev->parser);
331
static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
336
if (!dev->endpoint[EP2I(ep)].iso_started &&
337
!dev->endpoint[EP2I(ep)].iso_error) {
338
struct usb_redir_start_iso_stream_header start_iso = {
340
/* TODO maybe do something with these depending on ep interval? */
344
/* No id, we look at the ep when receiving a status back */
345
usbredirparser_send_start_iso_stream(dev->parser, 0, &start_iso);
346
usbredirparser_do_write(dev->parser);
347
DPRINTF("iso stream started ep %02X\n", ep);
348
dev->endpoint[EP2I(ep)].iso_started = 1;
351
if (ep & USB_DIR_IN) {
352
struct buf_packet *isop;
354
isop = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
356
DPRINTF2("iso-token-in ep %02X, no isop\n", ep);
357
/* Check iso_error for stream errors, otherwise its an underrun */
358
status = dev->endpoint[EP2I(ep)].iso_error;
359
dev->endpoint[EP2I(ep)].iso_error = 0;
360
return usbredir_handle_status(dev, status, 0);
362
DPRINTF2("iso-token-in ep %02X status %d len %d\n", ep, isop->status,
365
status = isop->status;
366
if (status != usb_redir_success) {
367
bufp_free(dev, isop, ep);
368
return usbredir_handle_status(dev, status, 0);
372
if (len > p->iov.size) {
373
ERROR("received iso data is larger then packet ep %02X\n", ep);
374
bufp_free(dev, isop, ep);
377
usb_packet_copy(p, isop->data, len);
378
bufp_free(dev, isop, ep);
381
/* If the stream was not started because of a pending error don't
382
send the packet to the usb-host */
383
if (dev->endpoint[EP2I(ep)].iso_started) {
384
struct usb_redir_iso_packet_header iso_packet = {
386
.length = p->iov.size
388
uint8_t buf[p->iov.size];
389
/* No id, we look at the ep when receiving a status back */
390
usb_packet_copy(p, buf, p->iov.size);
391
usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,
393
usbredirparser_do_write(dev->parser);
395
status = dev->endpoint[EP2I(ep)].iso_error;
396
dev->endpoint[EP2I(ep)].iso_error = 0;
397
DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep, status,
399
return usbredir_handle_status(dev, status, p->iov.size);
403
static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
405
struct usb_redir_stop_iso_stream_header stop_iso_stream = {
408
if (dev->endpoint[EP2I(ep)].iso_started) {
409
usbredirparser_send_stop_iso_stream(dev->parser, 0, &stop_iso_stream);
410
DPRINTF("iso stream stopped ep %02X\n", ep);
411
dev->endpoint[EP2I(ep)].iso_started = 0;
413
usbredir_free_bufpq(dev, ep);
416
static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
419
AsyncURB *aurb = async_alloc(dev, p);
420
struct usb_redir_bulk_packet_header bulk_packet;
422
DPRINTF("bulk-out ep %02X len %zd id %u\n", ep,
423
p->iov.size, aurb->packet_id);
425
bulk_packet.endpoint = ep;
426
bulk_packet.length = p->iov.size;
427
bulk_packet.stream_id = 0;
428
aurb->bulk_packet = bulk_packet;
430
if (ep & USB_DIR_IN) {
431
usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
432
&bulk_packet, NULL, 0);
434
uint8_t buf[p->iov.size];
435
usb_packet_copy(p, buf, p->iov.size);
436
usbredir_log_data(dev, "bulk data out:", buf, p->iov.size);
437
usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
438
&bulk_packet, buf, p->iov.size);
440
usbredirparser_do_write(dev->parser);
441
return USB_RET_ASYNC;
444
static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
445
USBPacket *p, uint8_t ep)
447
if (ep & USB_DIR_IN) {
448
/* Input interrupt endpoint, buffered packet input */
449
struct buf_packet *intp;
452
if (!dev->endpoint[EP2I(ep)].interrupt_started &&
453
!dev->endpoint[EP2I(ep)].interrupt_error) {
454
struct usb_redir_start_interrupt_receiving_header start_int = {
457
/* No id, we look at the ep when receiving a status back */
458
usbredirparser_send_start_interrupt_receiving(dev->parser, 0,
460
usbredirparser_do_write(dev->parser);
461
DPRINTF("interrupt recv started ep %02X\n", ep);
462
dev->endpoint[EP2I(ep)].interrupt_started = 1;
465
intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
467
DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);
468
/* Check interrupt_error for stream errors */
469
status = dev->endpoint[EP2I(ep)].interrupt_error;
470
dev->endpoint[EP2I(ep)].interrupt_error = 0;
471
return usbredir_handle_status(dev, status, 0);
473
DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,
474
intp->status, intp->len);
476
status = intp->status;
477
if (status != usb_redir_success) {
478
bufp_free(dev, intp, ep);
479
return usbredir_handle_status(dev, status, 0);
483
if (len > p->iov.size) {
484
ERROR("received int data is larger then packet ep %02X\n", ep);
485
bufp_free(dev, intp, ep);
488
usb_packet_copy(p, intp->data, len);
489
bufp_free(dev, intp, ep);
492
/* Output interrupt endpoint, normal async operation */
493
AsyncURB *aurb = async_alloc(dev, p);
494
struct usb_redir_interrupt_packet_header interrupt_packet;
495
uint8_t buf[p->iov.size];
497
DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep, p->iov.size,
500
interrupt_packet.endpoint = ep;
501
interrupt_packet.length = p->iov.size;
502
aurb->interrupt_packet = interrupt_packet;
504
usb_packet_copy(p, buf, p->iov.size);
505
usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);
506
usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
507
&interrupt_packet, buf, p->iov.size);
508
usbredirparser_do_write(dev->parser);
509
return USB_RET_ASYNC;
513
static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev,
516
struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv = {
519
if (dev->endpoint[EP2I(ep)].interrupt_started) {
520
usbredirparser_send_stop_interrupt_receiving(dev->parser, 0,
521
&stop_interrupt_recv);
522
DPRINTF("interrupt recv stopped ep %02X\n", ep);
523
dev->endpoint[EP2I(ep)].interrupt_started = 0;
525
usbredir_free_bufpq(dev, ep);
528
static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
530
USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
534
if (p->pid == USB_TOKEN_IN) {
538
switch (dev->endpoint[EP2I(ep)].type) {
539
case USB_ENDPOINT_XFER_CONTROL:
540
ERROR("handle_data called for control transfer on ep %02X\n", ep);
542
case USB_ENDPOINT_XFER_ISOC:
543
return usbredir_handle_iso_data(dev, p, ep);
544
case USB_ENDPOINT_XFER_BULK:
545
return usbredir_handle_bulk_data(dev, p, ep);;
546
case USB_ENDPOINT_XFER_INT:
547
return usbredir_handle_interrupt_data(dev, p, ep);;
549
ERROR("handle_data ep %02X has unknown type %d\n", ep,
550
dev->endpoint[EP2I(ep)].type);
555
static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
558
struct usb_redir_set_configuration_header set_config;
559
AsyncURB *aurb = async_alloc(dev, p);
562
DPRINTF("set config %d id %u\n", config, aurb->packet_id);
564
for (i = 0; i < MAX_ENDPOINTS; i++) {
565
switch (dev->endpoint[i].type) {
566
case USB_ENDPOINT_XFER_ISOC:
567
usbredir_stop_iso_stream(dev, I2EP(i));
569
case USB_ENDPOINT_XFER_INT:
571
usbredir_stop_interrupt_receiving(dev, I2EP(i));
575
usbredir_free_bufpq(dev, I2EP(i));
578
set_config.configuration = config;
579
usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
581
usbredirparser_do_write(dev->parser);
582
return USB_RET_ASYNC;
585
static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
587
AsyncURB *aurb = async_alloc(dev, p);
589
DPRINTF("get config id %u\n", aurb->packet_id);
592
usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
593
usbredirparser_do_write(dev->parser);
594
return USB_RET_ASYNC;
597
static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
598
int interface, int alt)
600
struct usb_redir_set_alt_setting_header set_alt;
601
AsyncURB *aurb = async_alloc(dev, p);
604
DPRINTF("set interface %d alt %d id %u\n", interface, alt,
607
for (i = 0; i < MAX_ENDPOINTS; i++) {
608
if (dev->endpoint[i].interface == interface) {
609
switch (dev->endpoint[i].type) {
610
case USB_ENDPOINT_XFER_ISOC:
611
usbredir_stop_iso_stream(dev, I2EP(i));
613
case USB_ENDPOINT_XFER_INT:
615
usbredir_stop_interrupt_receiving(dev, I2EP(i));
619
usbredir_free_bufpq(dev, I2EP(i));
623
set_alt.interface = interface;
625
usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
627
usbredirparser_do_write(dev->parser);
628
return USB_RET_ASYNC;
631
static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
634
struct usb_redir_get_alt_setting_header get_alt;
635
AsyncURB *aurb = async_alloc(dev, p);
637
DPRINTF("get interface %d id %u\n", interface, aurb->packet_id);
639
get_alt.interface = interface;
641
usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
643
usbredirparser_do_write(dev->parser);
644
return USB_RET_ASYNC;
647
static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
648
int request, int value, int index, int length, uint8_t *data)
650
USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
651
struct usb_redir_control_packet_header control_packet;
654
/* Special cases for certain standard device requests */
656
case DeviceOutRequest | USB_REQ_SET_ADDRESS:
657
DPRINTF("set address %d\n", value);
658
dev->dev.addr = value;
660
case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
661
return usbredir_set_config(dev, p, value & 0xff);
662
case DeviceRequest | USB_REQ_GET_CONFIGURATION:
663
return usbredir_get_config(dev, p);
664
case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
665
return usbredir_set_interface(dev, p, index, value);
666
case InterfaceRequest | USB_REQ_GET_INTERFACE:
667
return usbredir_get_interface(dev, p, index);
670
/* "Normal" ctrl requests */
671
aurb = async_alloc(dev, p);
673
/* Note request is (bRequestType << 8) | bRequest */
674
DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
675
request >> 8, request & 0xff, value, index, length,
678
control_packet.request = request & 0xFF;
679
control_packet.requesttype = request >> 8;
680
control_packet.endpoint = control_packet.requesttype & USB_DIR_IN;
681
control_packet.value = value;
682
control_packet.index = index;
683
control_packet.length = length;
684
aurb->control_packet = control_packet;
686
if (control_packet.requesttype & USB_DIR_IN) {
687
usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
688
&control_packet, NULL, 0);
690
usbredir_log_data(dev, "ctrl data out:", data, length);
691
usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
692
&control_packet, data, length);
694
usbredirparser_do_write(dev->parser);
695
return USB_RET_ASYNC;
699
* Close events can be triggered by usbredirparser_do_write which gets called
700
* from within the USBDevice data / control packet callbacks and doing a
701
* usb_detach from within these callbacks is not a good idea.
703
* So we use a bh handler to take care of close events. We also handle
704
* open events from this callback to make sure that a close directly followed
705
* by an open gets handled in the right order.
707
static void usbredir_open_close_bh(void *opaque)
709
USBRedirDevice *dev = opaque;
711
usbredir_device_disconnect(dev);
714
usbredirparser_destroy(dev->parser);
718
if (dev->cs->opened) {
719
dev->parser = qemu_oom_check(usbredirparser_create());
720
dev->parser->priv = dev;
721
dev->parser->log_func = usbredir_log;
722
dev->parser->read_func = usbredir_read;
723
dev->parser->write_func = usbredir_write;
724
dev->parser->device_connect_func = usbredir_device_connect;
725
dev->parser->device_disconnect_func = usbredir_device_disconnect;
726
dev->parser->interface_info_func = usbredir_interface_info;
727
dev->parser->ep_info_func = usbredir_ep_info;
728
dev->parser->configuration_status_func = usbredir_configuration_status;
729
dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
730
dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
731
dev->parser->interrupt_receiving_status_func =
732
usbredir_interrupt_receiving_status;
733
dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
734
dev->parser->control_packet_func = usbredir_control_packet;
735
dev->parser->bulk_packet_func = usbredir_bulk_packet;
736
dev->parser->iso_packet_func = usbredir_iso_packet;
737
dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
738
dev->read_buf = NULL;
739
dev->read_buf_size = 0;
740
usbredirparser_init(dev->parser, VERSION, NULL, 0, 0);
741
usbredirparser_do_write(dev->parser);
745
static void usbredir_do_attach(void *opaque)
747
USBRedirDevice *dev = opaque;
749
usb_device_attach(&dev->dev);
756
static int usbredir_chardev_can_read(void *opaque)
758
USBRedirDevice *dev = opaque;
761
/* usbredir_parser_do_read will consume *all* data we give it */
764
/* usbredir_open_close_bh hasn't handled the open event yet */
769
static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
771
USBRedirDevice *dev = opaque;
773
/* No recursion allowed! */
774
assert(dev->read_buf == NULL);
777
dev->read_buf_size = size;
779
usbredirparser_do_read(dev->parser);
780
/* Send any acks, etc. which may be queued now */
781
usbredirparser_do_write(dev->parser);
784
static void usbredir_chardev_event(void *opaque, int event)
786
USBRedirDevice *dev = opaque;
789
case CHR_EVENT_OPENED:
790
case CHR_EVENT_CLOSED:
791
qemu_bh_schedule(dev->open_close_bh);
800
static int usbredir_initfn(USBDevice *udev)
802
USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
805
if (dev->cs == NULL) {
806
qerror_report(QERR_MISSING_PARAMETER, "chardev");
810
dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
811
dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
813
QTAILQ_INIT(&dev->asyncq);
814
for (i = 0; i < MAX_ENDPOINTS; i++) {
815
QTAILQ_INIT(&dev->endpoint[i].bufpq);
818
/* We'll do the attach once we receive the speed from the usb-host */
819
udev->auto_attach = 0;
821
/* Let the backend know we are ready */
822
qemu_chr_fe_open(dev->cs);
823
qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
824
usbredir_chardev_read, usbredir_chardev_event, dev);
829
static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
831
AsyncURB *aurb, *next_aurb;
834
QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
835
async_free(dev, aurb);
837
for (i = 0; i < MAX_ENDPOINTS; i++) {
838
usbredir_free_bufpq(dev, I2EP(i));
842
static void usbredir_handle_destroy(USBDevice *udev)
844
USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
846
qemu_chr_fe_close(dev->cs);
847
qemu_chr_delete(dev->cs);
848
/* Note must be done after qemu_chr_close, as that causes a close event */
849
qemu_bh_delete(dev->open_close_bh);
851
qemu_del_timer(dev->attach_timer);
852
qemu_free_timer(dev->attach_timer);
854
usbredir_cleanup_device_queues(dev);
857
usbredirparser_destroy(dev->parser);
862
* usbredirparser packet complete callbacks
865
static int usbredir_handle_status(USBRedirDevice *dev,
866
int status, int actual_len)
869
case usb_redir_success:
871
case usb_redir_stall:
872
return USB_RET_STALL;
873
case usb_redir_cancelled:
874
WARNING("returning cancelled packet to HC?\n");
875
case usb_redir_inval:
876
case usb_redir_ioerror:
877
case usb_redir_timeout:
883
static void usbredir_device_connect(void *priv,
884
struct usb_redir_device_connect_header *device_connect)
886
USBRedirDevice *dev = priv;
888
if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
889
ERROR("Received device connect while already connected\n");
893
switch (device_connect->speed) {
894
case usb_redir_speed_low:
895
DPRINTF("attaching low speed device\n");
896
dev->dev.speed = USB_SPEED_LOW;
898
case usb_redir_speed_full:
899
DPRINTF("attaching full speed device\n");
900
dev->dev.speed = USB_SPEED_FULL;
902
case usb_redir_speed_high:
903
DPRINTF("attaching high speed device\n");
904
dev->dev.speed = USB_SPEED_HIGH;
906
case usb_redir_speed_super:
907
DPRINTF("attaching super speed device\n");
908
dev->dev.speed = USB_SPEED_SUPER;
911
DPRINTF("attaching unknown speed device, assuming full speed\n");
912
dev->dev.speed = USB_SPEED_FULL;
914
dev->dev.speedmask = (1 << dev->dev.speed);
915
qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
918
static void usbredir_device_disconnect(void *priv)
920
USBRedirDevice *dev = priv;
923
/* Stop any pending attaches */
924
qemu_del_timer(dev->attach_timer);
926
if (dev->dev.attached) {
927
usb_device_detach(&dev->dev);
929
* Delay next usb device attach to give the guest a chance to see
930
* see the detach / attach in case of quick close / open succession
932
dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
935
/* Reset state so that the next dev connected starts with a clean slate */
936
usbredir_cleanup_device_queues(dev);
937
memset(dev->endpoint, 0, sizeof(dev->endpoint));
938
for (i = 0; i < MAX_ENDPOINTS; i++) {
939
QTAILQ_INIT(&dev->endpoint[i].bufpq);
943
static void usbredir_interface_info(void *priv,
944
struct usb_redir_interface_info_header *interface_info)
946
/* The intention is to allow specifying acceptable interface classes
947
for redirection on the cmdline and in the future verify this here,
948
and disconnect (or never connect) the device if a not accepted
949
interface class is detected */
952
static void usbredir_ep_info(void *priv,
953
struct usb_redir_ep_info_header *ep_info)
955
USBRedirDevice *dev = priv;
958
for (i = 0; i < MAX_ENDPOINTS; i++) {
959
dev->endpoint[i].type = ep_info->type[i];
960
dev->endpoint[i].interval = ep_info->interval[i];
961
dev->endpoint[i].interface = ep_info->interface[i];
962
if (dev->endpoint[i].type != usb_redir_type_invalid) {
963
DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
964
dev->endpoint[i].type, dev->endpoint[i].interface);
969
static void usbredir_configuration_status(void *priv, uint32_t id,
970
struct usb_redir_configuration_status_header *config_status)
972
USBRedirDevice *dev = priv;
976
DPRINTF("set config status %d config %d id %u\n", config_status->status,
977
config_status->configuration, id);
979
aurb = async_find(dev, id);
985
dev->dev.data_buf[0] = config_status->configuration;
988
aurb->packet->result =
989
usbredir_handle_status(dev, config_status->status, len);
990
usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
992
async_free(dev, aurb);
995
static void usbredir_alt_setting_status(void *priv, uint32_t id,
996
struct usb_redir_alt_setting_status_header *alt_setting_status)
998
USBRedirDevice *dev = priv;
1002
DPRINTF("alt status %d intf %d alt %d id: %u\n",
1003
alt_setting_status->status,
1004
alt_setting_status->interface,
1005
alt_setting_status->alt, id);
1007
aurb = async_find(dev, id);
1013
dev->dev.data_buf[0] = alt_setting_status->alt;
1016
aurb->packet->result =
1017
usbredir_handle_status(dev, alt_setting_status->status, len);
1018
usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1020
async_free(dev, aurb);
1023
static void usbredir_iso_stream_status(void *priv, uint32_t id,
1024
struct usb_redir_iso_stream_status_header *iso_stream_status)
1026
USBRedirDevice *dev = priv;
1027
uint8_t ep = iso_stream_status->endpoint;
1029
DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1032
if (!dev->dev.attached) {
1036
dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
1037
if (iso_stream_status->status == usb_redir_stall) {
1038
DPRINTF("iso stream stopped by peer ep %02X\n", ep);
1039
dev->endpoint[EP2I(ep)].iso_started = 0;
1043
static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1044
struct usb_redir_interrupt_receiving_status_header
1045
*interrupt_receiving_status)
1047
USBRedirDevice *dev = priv;
1048
uint8_t ep = interrupt_receiving_status->endpoint;
1050
DPRINTF("interrupt recv status %d ep %02X id %u\n",
1051
interrupt_receiving_status->status, ep, id);
1053
if (!dev->dev.attached) {
1057
dev->endpoint[EP2I(ep)].interrupt_error =
1058
interrupt_receiving_status->status;
1059
if (interrupt_receiving_status->status == usb_redir_stall) {
1060
DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep);
1061
dev->endpoint[EP2I(ep)].interrupt_started = 0;
1065
static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1066
struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1070
static void usbredir_control_packet(void *priv, uint32_t id,
1071
struct usb_redir_control_packet_header *control_packet,
1072
uint8_t *data, int data_len)
1074
USBRedirDevice *dev = priv;
1075
int len = control_packet->length;
1078
DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1081
aurb = async_find(dev, id);
1087
aurb->control_packet.status = control_packet->status;
1088
aurb->control_packet.length = control_packet->length;
1089
if (memcmp(&aurb->control_packet, control_packet,
1090
sizeof(*control_packet))) {
1091
ERROR("return control packet mismatch, please report this!\n");
1096
len = usbredir_handle_status(dev, control_packet->status, len);
1098
usbredir_log_data(dev, "ctrl data in:", data, data_len);
1099
if (data_len <= sizeof(dev->dev.data_buf)) {
1100
memcpy(dev->dev.data_buf, data, data_len);
1102
ERROR("ctrl buffer too small (%d > %zu)\n",
1103
data_len, sizeof(dev->dev.data_buf));
1104
len = USB_RET_STALL;
1107
aurb->packet->result = len;
1108
usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1110
async_free(dev, aurb);
1114
static void usbredir_bulk_packet(void *priv, uint32_t id,
1115
struct usb_redir_bulk_packet_header *bulk_packet,
1116
uint8_t *data, int data_len)
1118
USBRedirDevice *dev = priv;
1119
uint8_t ep = bulk_packet->endpoint;
1120
int len = bulk_packet->length;
1123
DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1126
aurb = async_find(dev, id);
1132
if (aurb->bulk_packet.endpoint != bulk_packet->endpoint ||
1133
aurb->bulk_packet.stream_id != bulk_packet->stream_id) {
1134
ERROR("return bulk packet mismatch, please report this!\n");
1139
len = usbredir_handle_status(dev, bulk_packet->status, len);
1141
usbredir_log_data(dev, "bulk data in:", data, data_len);
1142
if (data_len <= aurb->packet->iov.size) {
1143
usb_packet_copy(aurb->packet, data, data_len);
1145
ERROR("bulk buffer too small (%d > %zd)\n", data_len,
1146
aurb->packet->iov.size);
1147
len = USB_RET_STALL;
1150
aurb->packet->result = len;
1151
usb_packet_complete(&dev->dev, aurb->packet);
1153
async_free(dev, aurb);
1157
static void usbredir_iso_packet(void *priv, uint32_t id,
1158
struct usb_redir_iso_packet_header *iso_packet,
1159
uint8_t *data, int data_len)
1161
USBRedirDevice *dev = priv;
1162
uint8_t ep = iso_packet->endpoint;
1164
DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1167
if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1168
ERROR("received iso packet for non iso endpoint %02X\n", ep);
1173
if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1174
DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1179
/* bufp_alloc also adds the packet to the ep queue */
1180
bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1183
static void usbredir_interrupt_packet(void *priv, uint32_t id,
1184
struct usb_redir_interrupt_packet_header *interrupt_packet,
1185
uint8_t *data, int data_len)
1187
USBRedirDevice *dev = priv;
1188
uint8_t ep = interrupt_packet->endpoint;
1190
DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1191
interrupt_packet->status, ep, data_len, id);
1193
if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
1194
ERROR("received int packet for non interrupt endpoint %02X\n", ep);
1199
if (ep & USB_DIR_IN) {
1200
if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
1201
DPRINTF("received int packet while not started ep %02X\n", ep);
1206
/* bufp_alloc also adds the packet to the ep queue */
1207
bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
1209
int len = interrupt_packet->length;
1211
AsyncURB *aurb = async_find(dev, id);
1216
if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
1217
ERROR("return int packet mismatch, please report this!\n");
1222
aurb->packet->result = usbredir_handle_status(dev,
1223
interrupt_packet->status, len);
1224
usb_packet_complete(&dev->dev, aurb->packet);
1226
async_free(dev, aurb);
1230
static struct USBDeviceInfo usbredir_dev_info = {
1231
.product_desc = "USB Redirection Device",
1232
.qdev.name = "usb-redir",
1233
.qdev.size = sizeof(USBRedirDevice),
1234
.init = usbredir_initfn,
1235
.handle_destroy = usbredir_handle_destroy,
1236
.handle_packet = usb_generic_handle_packet,
1237
.cancel_packet = usbredir_cancel_packet,
1238
.handle_reset = usbredir_handle_reset,
1239
.handle_data = usbredir_handle_data,
1240
.handle_control = usbredir_handle_control,
1241
.qdev.props = (Property[]) {
1242
DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
1243
DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
1244
DEFINE_PROP_END_OF_LIST(),
1248
static void usbredir_register_devices(void)
1250
usb_qdev_register(&usbredir_dev_info);
1252
device_init(usbredir_register_devices);