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 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
));
240 aurb
->packet_id
= dev
->packet_id
;
241 QTAILQ_INSERT_TAIL(&dev
->asyncq
, aurb
, next
);
247 static void async_free(USBRedirDevice
*dev
, AsyncURB
*aurb
)
249 QTAILQ_REMOVE(&dev
->asyncq
, aurb
, next
);
253 static AsyncURB
*async_find(USBRedirDevice
*dev
, uint32_t packet_id
)
257 QTAILQ_FOREACH(aurb
, &dev
->asyncq
, next
) {
258 if (aurb
->packet_id
== packet_id
) {
262 ERROR("could not find async urb for packet_id %u\n", packet_id
);
266 static void usbredir_cancel_packet(USBDevice
*udev
, USBPacket
*p
)
268 USBRedirDevice
*dev
= DO_UPCAST(USBRedirDevice
, dev
, udev
);
271 QTAILQ_FOREACH(aurb
, &dev
->asyncq
, next
) {
272 if (p
!= aurb
->packet
) {
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 */
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
));
292 bufp
->status
= status
;
293 QTAILQ_INSERT_TAIL(&dev
->endpoint
[EP2I(ep
)].bufpq
, bufp
, next
);
297 static void bufp_free(USBRedirDevice
*dev
, struct buf_packet
*bufp
,
300 QTAILQ_REMOVE(&dev
->endpoint
[EP2I(ep
)].bufpq
, bufp
, next
);
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
,
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
= {
336 /* TODO maybe do something with these depending on ep interval? */
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
);
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
,
361 status
= isop
->status
;
362 if (status
!= usb_redir_success
) {
363 bufp_free(dev
, isop
, ep
);
364 return usbredir_handle_status(dev
, status
, 0);
369 ERROR("received iso data is larger then packet ep %02X\n", ep
);
370 bufp_free(dev
, isop
, ep
);
373 memcpy(p
->data
, isop
->data
, len
);
374 bufp_free(dev
, isop
, ep
);
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
= {
384 /* No id, we look at the ep when receiving a status back */
385 usbredirparser_send_iso_packet(dev
->parser
, 0, &iso_packet
,
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
,
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
= {
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
,
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);
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
;
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
= {
448 /* No id, we look at the ep when receiving a status back */
449 usbredirparser_send_start_interrupt_receiving(dev
->parser
, 0,
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
);
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);
475 ERROR("received int data is larger then packet ep %02X\n", ep
);
476 bufp_free(dev
, intp
, ep
);
479 memcpy(p
->data
, intp
->data
, len
);
480 bufp_free(dev
, intp
, ep
);
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
,
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
,
505 struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv
= {
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
);
523 if (p
->pid
== USB_TOKEN_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
);
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
);;
538 ERROR("handle_data ep %02X has unknown type %d\n", ep
,
539 dev
->endpoint
[EP2I(ep
)].type
);
544 static int usbredir_set_config(USBRedirDevice
*dev
, USBPacket
*p
,
547 struct usb_redir_set_configuration_header set_config
;
548 AsyncURB
*aurb
= async_alloc(dev
, p
);
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
));
558 case USB_ENDPOINT_XFER_INT
:
560 usbredir_stop_interrupt_receiving(dev
, I2EP(i
));
564 usbredir_free_bufpq(dev
, I2EP(i
));
567 set_config
.configuration
= config
;
568 usbredirparser_send_set_configuration(dev
->parser
, aurb
->packet_id
,
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
);
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
);
593 DPRINTF("set interface %d alt %d id %u\n", interface
, alt
,
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
));
602 case USB_ENDPOINT_XFER_INT
:
604 usbredir_stop_interrupt_receiving(dev
, I2EP(i
));
608 usbredir_free_bufpq(dev
, I2EP(i
));
612 set_alt
.interface
= interface
;
614 usbredirparser_send_set_alt_setting(dev
->parser
, aurb
->packet_id
,
616 usbredirparser_do_write(dev
->parser
);
617 return USB_RET_ASYNC
;
620 static int usbredir_get_interface(USBRedirDevice
*dev
, USBPacket
*p
,
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
;
630 usbredirparser_send_get_alt_setting(dev
->parser
, aurb
->packet_id
,
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
;
643 /* Special cases for certain standard device requests */
645 case DeviceOutRequest
| USB_REQ_SET_ADDRESS
:
646 DPRINTF("set address %d\n", value
);
647 dev
->dev
.addr
= value
;
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
,
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);
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
);
703 usbredirparser_destroy(dev
->parser
);
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
);
745 static int usbredir_chardev_can_read(void *opaque
)
747 USBRedirDevice
*dev
= opaque
;
750 /* usbredir_parser_do_read will consume *all* data we give it */
753 /* usbredir_open_close_bh hasn't handled the open event yet */
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
);
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
;
778 case CHR_EVENT_OPENED
:
779 case CHR_EVENT_CLOSED
:
780 qemu_bh_schedule(dev
->open_close_bh
);
789 static int usbredir_initfn(USBDevice
*udev
)
791 USBRedirDevice
*dev
= DO_UPCAST(USBRedirDevice
, dev
, udev
);
794 if (dev
->cs
== NULL
) {
795 qerror_report(QERR_MISSING_PARAMETER
, "chardev");
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
);
816 static void usbredir_cleanup_device_queues(USBRedirDevice
*dev
)
818 AsyncURB
*aurb
, *next_aurb
;
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
);
843 usbredirparser_destroy(dev
->parser
);
848 * usbredirparser packet complete callbacks
851 static int usbredir_handle_status(USBRedirDevice
*dev
,
852 int status
, int actual_len
)
855 case usb_redir_success
:
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
:
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
;
879 case usb_redir_speed_full
:
880 DPRINTF("attaching full speed device\n");
881 dev
->dev
.speed
= USB_SPEED_FULL
;
883 case usb_redir_speed_high
:
884 DPRINTF("attaching high speed device\n");
885 dev
->dev
.speed
= USB_SPEED_HIGH
;
887 case usb_redir_speed_super
:
888 DPRINTF("attaching super speed device\n");
889 dev
->dev
.speed
= USB_SPEED_SUPER
;
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
;
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
;
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
);
959 dev
->dev
.data_buf
[0] = config_status
->configuration
;
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
;
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
);
987 dev
->dev
.data_buf
[0] = alt_setting_status
->alt
;
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
,
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
;
1044 DPRINTF("ctrl-in status %d len %d id %u\n", control_packet
->status
,
1047 aurb
= async_find(dev
, id
);
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");
1062 len
= usbredir_handle_status(dev
, control_packet
->status
, len
);
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
);
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
);
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
;
1089 DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet
->status
,
1092 aurb
= async_find(dev
, id
);
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");
1105 len
= usbredir_handle_status(dev
, bulk_packet
->status
, len
);
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
);
1111 ERROR("bulk buffer too small (%d > %d)\n", data_len
,
1113 len
= USB_RET_STALL
;
1116 aurb
->packet
->len
= len
;
1117 usb_packet_complete(&dev
->dev
, aurb
->packet
);
1119 async_free(dev
, aurb
);
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
,
1133 if (dev
->endpoint
[EP2I(ep
)].type
!= USB_ENDPOINT_XFER_ISOC
) {
1134 ERROR("received iso packet for non iso endpoint %02X\n", ep
);
1139 if (dev
->endpoint
[EP2I(ep
)].iso_started
== 0) {
1140 DPRINTF("received iso packet for non started stream ep %02X\n", ep
);
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
);
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
);
1172 /* bufp_alloc also adds the packet to the ep queue */
1173 bufp_alloc(dev
, data
, data_len
, interrupt_packet
->status
, ep
);
1175 int len
= interrupt_packet
->length
;
1177 AsyncURB
*aurb
= async_find(dev
, id
);
1182 if (aurb
->interrupt_packet
.endpoint
!= interrupt_packet
->endpoint
) {
1183 ERROR("return int packet mismatch, please report this!\n");
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
);