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_fe_write(dev
->cs
, data
, count
);
232 * Async and buffered packets helpers
235 static AsyncURB
*async_alloc(USBRedirDevice
*dev
, USBPacket
*p
)
237 AsyncURB
*aurb
= (AsyncURB
*) g_malloc0(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
= g_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);
368 if (len
> p
->iov
.size
) {
369 ERROR("received iso data is larger then packet ep %02X\n", ep
);
370 bufp_free(dev
, isop
, ep
);
373 usb_packet_copy(p
, 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
= {
382 .length
= p
->iov
.size
384 uint8_t buf
[p
->iov
.size
];
385 /* No id, we look at the ep when receiving a status back */
386 usb_packet_copy(p
, buf
, p
->iov
.size
);
387 usbredirparser_send_iso_packet(dev
->parser
, 0, &iso_packet
,
389 usbredirparser_do_write(dev
->parser
);
391 status
= dev
->endpoint
[EP2I(ep
)].iso_error
;
392 dev
->endpoint
[EP2I(ep
)].iso_error
= 0;
393 DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep
, status
,
395 return usbredir_handle_status(dev
, status
, p
->iov
.size
);
399 static void usbredir_stop_iso_stream(USBRedirDevice
*dev
, uint8_t ep
)
401 struct usb_redir_stop_iso_stream_header stop_iso_stream
= {
404 if (dev
->endpoint
[EP2I(ep
)].iso_started
) {
405 usbredirparser_send_stop_iso_stream(dev
->parser
, 0, &stop_iso_stream
);
406 DPRINTF("iso stream stopped ep %02X\n", ep
);
407 dev
->endpoint
[EP2I(ep
)].iso_started
= 0;
409 usbredir_free_bufpq(dev
, ep
);
412 static int usbredir_handle_bulk_data(USBRedirDevice
*dev
, USBPacket
*p
,
415 AsyncURB
*aurb
= async_alloc(dev
, p
);
416 struct usb_redir_bulk_packet_header bulk_packet
;
418 DPRINTF("bulk-out ep %02X len %zd id %u\n", ep
,
419 p
->iov
.size
, aurb
->packet_id
);
421 bulk_packet
.endpoint
= ep
;
422 bulk_packet
.length
= p
->iov
.size
;
423 bulk_packet
.stream_id
= 0;
424 aurb
->bulk_packet
= bulk_packet
;
426 if (ep
& USB_DIR_IN
) {
427 usbredirparser_send_bulk_packet(dev
->parser
, aurb
->packet_id
,
428 &bulk_packet
, NULL
, 0);
430 uint8_t buf
[p
->iov
.size
];
431 usb_packet_copy(p
, buf
, p
->iov
.size
);
432 usbredir_log_data(dev
, "bulk data out:", buf
, p
->iov
.size
);
433 usbredirparser_send_bulk_packet(dev
->parser
, aurb
->packet_id
,
434 &bulk_packet
, buf
, p
->iov
.size
);
436 usbredirparser_do_write(dev
->parser
);
437 return USB_RET_ASYNC
;
440 static int usbredir_handle_interrupt_data(USBRedirDevice
*dev
,
441 USBPacket
*p
, uint8_t ep
)
443 if (ep
& USB_DIR_IN
) {
444 /* Input interrupt endpoint, buffered packet input */
445 struct buf_packet
*intp
;
448 if (!dev
->endpoint
[EP2I(ep
)].interrupt_started
&&
449 !dev
->endpoint
[EP2I(ep
)].interrupt_error
) {
450 struct usb_redir_start_interrupt_receiving_header start_int
= {
453 /* No id, we look at the ep when receiving a status back */
454 usbredirparser_send_start_interrupt_receiving(dev
->parser
, 0,
456 usbredirparser_do_write(dev
->parser
);
457 DPRINTF("interrupt recv started ep %02X\n", ep
);
458 dev
->endpoint
[EP2I(ep
)].interrupt_started
= 1;
461 intp
= QTAILQ_FIRST(&dev
->endpoint
[EP2I(ep
)].bufpq
);
463 DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep
);
464 /* Check interrupt_error for stream errors */
465 status
= dev
->endpoint
[EP2I(ep
)].interrupt_error
;
466 dev
->endpoint
[EP2I(ep
)].interrupt_error
= 0;
467 return usbredir_handle_status(dev
, status
, 0);
469 DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep
,
470 intp
->status
, intp
->len
);
472 status
= intp
->status
;
473 if (status
!= usb_redir_success
) {
474 bufp_free(dev
, intp
, ep
);
475 return usbredir_handle_status(dev
, status
, 0);
479 if (len
> p
->iov
.size
) {
480 ERROR("received int data is larger then packet ep %02X\n", ep
);
481 bufp_free(dev
, intp
, ep
);
484 usb_packet_copy(p
, intp
->data
, len
);
485 bufp_free(dev
, intp
, ep
);
488 /* Output interrupt endpoint, normal async operation */
489 AsyncURB
*aurb
= async_alloc(dev
, p
);
490 struct usb_redir_interrupt_packet_header interrupt_packet
;
491 uint8_t buf
[p
->iov
.size
];
493 DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep
, p
->iov
.size
,
496 interrupt_packet
.endpoint
= ep
;
497 interrupt_packet
.length
= p
->iov
.size
;
498 aurb
->interrupt_packet
= interrupt_packet
;
500 usb_packet_copy(p
, buf
, p
->iov
.size
);
501 usbredir_log_data(dev
, "interrupt data out:", buf
, p
->iov
.size
);
502 usbredirparser_send_interrupt_packet(dev
->parser
, aurb
->packet_id
,
503 &interrupt_packet
, buf
, p
->iov
.size
);
504 usbredirparser_do_write(dev
->parser
);
505 return USB_RET_ASYNC
;
509 static void usbredir_stop_interrupt_receiving(USBRedirDevice
*dev
,
512 struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv
= {
515 if (dev
->endpoint
[EP2I(ep
)].interrupt_started
) {
516 usbredirparser_send_stop_interrupt_receiving(dev
->parser
, 0,
517 &stop_interrupt_recv
);
518 DPRINTF("interrupt recv stopped ep %02X\n", ep
);
519 dev
->endpoint
[EP2I(ep
)].interrupt_started
= 0;
521 usbredir_free_bufpq(dev
, ep
);
524 static int usbredir_handle_data(USBDevice
*udev
, USBPacket
*p
)
526 USBRedirDevice
*dev
= DO_UPCAST(USBRedirDevice
, dev
, udev
);
530 if (p
->pid
== USB_TOKEN_IN
) {
534 switch (dev
->endpoint
[EP2I(ep
)].type
) {
535 case USB_ENDPOINT_XFER_CONTROL
:
536 ERROR("handle_data called for control transfer on ep %02X\n", ep
);
538 case USB_ENDPOINT_XFER_ISOC
:
539 return usbredir_handle_iso_data(dev
, p
, ep
);
540 case USB_ENDPOINT_XFER_BULK
:
541 return usbredir_handle_bulk_data(dev
, p
, ep
);;
542 case USB_ENDPOINT_XFER_INT
:
543 return usbredir_handle_interrupt_data(dev
, p
, ep
);;
545 ERROR("handle_data ep %02X has unknown type %d\n", ep
,
546 dev
->endpoint
[EP2I(ep
)].type
);
551 static int usbredir_set_config(USBRedirDevice
*dev
, USBPacket
*p
,
554 struct usb_redir_set_configuration_header set_config
;
555 AsyncURB
*aurb
= async_alloc(dev
, p
);
558 DPRINTF("set config %d id %u\n", config
, aurb
->packet_id
);
560 for (i
= 0; i
< MAX_ENDPOINTS
; i
++) {
561 switch (dev
->endpoint
[i
].type
) {
562 case USB_ENDPOINT_XFER_ISOC
:
563 usbredir_stop_iso_stream(dev
, I2EP(i
));
565 case USB_ENDPOINT_XFER_INT
:
567 usbredir_stop_interrupt_receiving(dev
, I2EP(i
));
571 usbredir_free_bufpq(dev
, I2EP(i
));
574 set_config
.configuration
= config
;
575 usbredirparser_send_set_configuration(dev
->parser
, aurb
->packet_id
,
577 usbredirparser_do_write(dev
->parser
);
578 return USB_RET_ASYNC
;
581 static int usbredir_get_config(USBRedirDevice
*dev
, USBPacket
*p
)
583 AsyncURB
*aurb
= async_alloc(dev
, p
);
585 DPRINTF("get config id %u\n", aurb
->packet_id
);
588 usbredirparser_send_get_configuration(dev
->parser
, aurb
->packet_id
);
589 usbredirparser_do_write(dev
->parser
);
590 return USB_RET_ASYNC
;
593 static int usbredir_set_interface(USBRedirDevice
*dev
, USBPacket
*p
,
594 int interface
, int alt
)
596 struct usb_redir_set_alt_setting_header set_alt
;
597 AsyncURB
*aurb
= async_alloc(dev
, p
);
600 DPRINTF("set interface %d alt %d id %u\n", interface
, alt
,
603 for (i
= 0; i
< MAX_ENDPOINTS
; i
++) {
604 if (dev
->endpoint
[i
].interface
== interface
) {
605 switch (dev
->endpoint
[i
].type
) {
606 case USB_ENDPOINT_XFER_ISOC
:
607 usbredir_stop_iso_stream(dev
, I2EP(i
));
609 case USB_ENDPOINT_XFER_INT
:
611 usbredir_stop_interrupt_receiving(dev
, I2EP(i
));
615 usbredir_free_bufpq(dev
, I2EP(i
));
619 set_alt
.interface
= interface
;
621 usbredirparser_send_set_alt_setting(dev
->parser
, aurb
->packet_id
,
623 usbredirparser_do_write(dev
->parser
);
624 return USB_RET_ASYNC
;
627 static int usbredir_get_interface(USBRedirDevice
*dev
, USBPacket
*p
,
630 struct usb_redir_get_alt_setting_header get_alt
;
631 AsyncURB
*aurb
= async_alloc(dev
, p
);
633 DPRINTF("get interface %d id %u\n", interface
, aurb
->packet_id
);
635 get_alt
.interface
= interface
;
637 usbredirparser_send_get_alt_setting(dev
->parser
, aurb
->packet_id
,
639 usbredirparser_do_write(dev
->parser
);
640 return USB_RET_ASYNC
;
643 static int usbredir_handle_control(USBDevice
*udev
, USBPacket
*p
,
644 int request
, int value
, int index
, int length
, uint8_t *data
)
646 USBRedirDevice
*dev
= DO_UPCAST(USBRedirDevice
, dev
, udev
);
647 struct usb_redir_control_packet_header control_packet
;
650 /* Special cases for certain standard device requests */
652 case DeviceOutRequest
| USB_REQ_SET_ADDRESS
:
653 DPRINTF("set address %d\n", value
);
654 dev
->dev
.addr
= value
;
656 case DeviceOutRequest
| USB_REQ_SET_CONFIGURATION
:
657 return usbredir_set_config(dev
, p
, value
& 0xff);
658 case DeviceRequest
| USB_REQ_GET_CONFIGURATION
:
659 return usbredir_get_config(dev
, p
);
660 case InterfaceOutRequest
| USB_REQ_SET_INTERFACE
:
661 return usbredir_set_interface(dev
, p
, index
, value
);
662 case InterfaceRequest
| USB_REQ_GET_INTERFACE
:
663 return usbredir_get_interface(dev
, p
, index
);
666 /* "Normal" ctrl requests */
667 aurb
= async_alloc(dev
, p
);
669 /* Note request is (bRequestType << 8) | bRequest */
670 DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
671 request
>> 8, request
& 0xff, value
, index
, length
,
674 control_packet
.request
= request
& 0xFF;
675 control_packet
.requesttype
= request
>> 8;
676 control_packet
.endpoint
= control_packet
.requesttype
& USB_DIR_IN
;
677 control_packet
.value
= value
;
678 control_packet
.index
= index
;
679 control_packet
.length
= length
;
680 aurb
->control_packet
= control_packet
;
682 if (control_packet
.requesttype
& USB_DIR_IN
) {
683 usbredirparser_send_control_packet(dev
->parser
, aurb
->packet_id
,
684 &control_packet
, NULL
, 0);
686 usbredir_log_data(dev
, "ctrl data out:", data
, length
);
687 usbredirparser_send_control_packet(dev
->parser
, aurb
->packet_id
,
688 &control_packet
, data
, length
);
690 usbredirparser_do_write(dev
->parser
);
691 return USB_RET_ASYNC
;
695 * Close events can be triggered by usbredirparser_do_write which gets called
696 * from within the USBDevice data / control packet callbacks and doing a
697 * usb_detach from within these callbacks is not a good idea.
699 * So we use a bh handler to take care of close events. We also handle
700 * open events from this callback to make sure that a close directly followed
701 * by an open gets handled in the right order.
703 static void usbredir_open_close_bh(void *opaque
)
705 USBRedirDevice
*dev
= opaque
;
707 usbredir_device_disconnect(dev
);
710 usbredirparser_destroy(dev
->parser
);
714 if (dev
->cs
->opened
) {
715 dev
->parser
= qemu_oom_check(usbredirparser_create());
716 dev
->parser
->priv
= dev
;
717 dev
->parser
->log_func
= usbredir_log
;
718 dev
->parser
->read_func
= usbredir_read
;
719 dev
->parser
->write_func
= usbredir_write
;
720 dev
->parser
->device_connect_func
= usbredir_device_connect
;
721 dev
->parser
->device_disconnect_func
= usbredir_device_disconnect
;
722 dev
->parser
->interface_info_func
= usbredir_interface_info
;
723 dev
->parser
->ep_info_func
= usbredir_ep_info
;
724 dev
->parser
->configuration_status_func
= usbredir_configuration_status
;
725 dev
->parser
->alt_setting_status_func
= usbredir_alt_setting_status
;
726 dev
->parser
->iso_stream_status_func
= usbredir_iso_stream_status
;
727 dev
->parser
->interrupt_receiving_status_func
=
728 usbredir_interrupt_receiving_status
;
729 dev
->parser
->bulk_streams_status_func
= usbredir_bulk_streams_status
;
730 dev
->parser
->control_packet_func
= usbredir_control_packet
;
731 dev
->parser
->bulk_packet_func
= usbredir_bulk_packet
;
732 dev
->parser
->iso_packet_func
= usbredir_iso_packet
;
733 dev
->parser
->interrupt_packet_func
= usbredir_interrupt_packet
;
734 dev
->read_buf
= NULL
;
735 dev
->read_buf_size
= 0;
736 usbredirparser_init(dev
->parser
, VERSION
, NULL
, 0, 0);
737 usbredirparser_do_write(dev
->parser
);
741 static void usbredir_do_attach(void *opaque
)
743 USBRedirDevice
*dev
= opaque
;
745 usb_device_attach(&dev
->dev
);
752 static int usbredir_chardev_can_read(void *opaque
)
754 USBRedirDevice
*dev
= opaque
;
757 /* usbredir_parser_do_read will consume *all* data we give it */
760 /* usbredir_open_close_bh hasn't handled the open event yet */
765 static void usbredir_chardev_read(void *opaque
, const uint8_t *buf
, int size
)
767 USBRedirDevice
*dev
= opaque
;
769 /* No recursion allowed! */
770 assert(dev
->read_buf
== NULL
);
773 dev
->read_buf_size
= size
;
775 usbredirparser_do_read(dev
->parser
);
776 /* Send any acks, etc. which may be queued now */
777 usbredirparser_do_write(dev
->parser
);
780 static void usbredir_chardev_event(void *opaque
, int event
)
782 USBRedirDevice
*dev
= opaque
;
785 case CHR_EVENT_OPENED
:
786 case CHR_EVENT_CLOSED
:
787 qemu_bh_schedule(dev
->open_close_bh
);
796 static int usbredir_initfn(USBDevice
*udev
)
798 USBRedirDevice
*dev
= DO_UPCAST(USBRedirDevice
, dev
, udev
);
801 if (dev
->cs
== NULL
) {
802 qerror_report(QERR_MISSING_PARAMETER
, "chardev");
806 dev
->open_close_bh
= qemu_bh_new(usbredir_open_close_bh
, dev
);
807 dev
->attach_timer
= qemu_new_timer_ms(vm_clock
, usbredir_do_attach
, dev
);
809 QTAILQ_INIT(&dev
->asyncq
);
810 for (i
= 0; i
< MAX_ENDPOINTS
; i
++) {
811 QTAILQ_INIT(&dev
->endpoint
[i
].bufpq
);
814 /* We'll do the attach once we receive the speed from the usb-host */
815 udev
->auto_attach
= 0;
817 qemu_chr_add_handlers(dev
->cs
, usbredir_chardev_can_read
,
818 usbredir_chardev_read
, usbredir_chardev_event
, dev
);
823 static void usbredir_cleanup_device_queues(USBRedirDevice
*dev
)
825 AsyncURB
*aurb
, *next_aurb
;
828 QTAILQ_FOREACH_SAFE(aurb
, &dev
->asyncq
, next
, next_aurb
) {
829 async_free(dev
, aurb
);
831 for (i
= 0; i
< MAX_ENDPOINTS
; i
++) {
832 usbredir_free_bufpq(dev
, I2EP(i
));
836 static void usbredir_handle_destroy(USBDevice
*udev
)
838 USBRedirDevice
*dev
= DO_UPCAST(USBRedirDevice
, dev
, udev
);
840 qemu_chr_delete(dev
->cs
);
841 /* Note must be done after qemu_chr_close, as that causes a close event */
842 qemu_bh_delete(dev
->open_close_bh
);
844 qemu_del_timer(dev
->attach_timer
);
845 qemu_free_timer(dev
->attach_timer
);
847 usbredir_cleanup_device_queues(dev
);
850 usbredirparser_destroy(dev
->parser
);
855 * usbredirparser packet complete callbacks
858 static int usbredir_handle_status(USBRedirDevice
*dev
,
859 int status
, int actual_len
)
862 case usb_redir_success
:
864 case usb_redir_stall
:
865 return USB_RET_STALL
;
866 case usb_redir_cancelled
:
867 WARNING("returning cancelled packet to HC?\n");
868 case usb_redir_inval
:
869 case usb_redir_ioerror
:
870 case usb_redir_timeout
:
876 static void usbredir_device_connect(void *priv
,
877 struct usb_redir_device_connect_header
*device_connect
)
879 USBRedirDevice
*dev
= priv
;
881 switch (device_connect
->speed
) {
882 case usb_redir_speed_low
:
883 DPRINTF("attaching low speed device\n");
884 dev
->dev
.speed
= USB_SPEED_LOW
;
886 case usb_redir_speed_full
:
887 DPRINTF("attaching full speed device\n");
888 dev
->dev
.speed
= USB_SPEED_FULL
;
890 case usb_redir_speed_high
:
891 DPRINTF("attaching high speed device\n");
892 dev
->dev
.speed
= USB_SPEED_HIGH
;
894 case usb_redir_speed_super
:
895 DPRINTF("attaching super speed device\n");
896 dev
->dev
.speed
= USB_SPEED_SUPER
;
899 DPRINTF("attaching unknown speed device, assuming full speed\n");
900 dev
->dev
.speed
= USB_SPEED_FULL
;
902 dev
->dev
.speedmask
= (1 << dev
->dev
.speed
);
903 qemu_mod_timer(dev
->attach_timer
, dev
->next_attach_time
);
906 static void usbredir_device_disconnect(void *priv
)
908 USBRedirDevice
*dev
= priv
;
910 /* Stop any pending attaches */
911 qemu_del_timer(dev
->attach_timer
);
913 if (dev
->dev
.attached
) {
914 usb_device_detach(&dev
->dev
);
915 usbredir_cleanup_device_queues(dev
);
917 * Delay next usb device attach to give the guest a chance to see
918 * see the detach / attach in case of quick close / open succession
920 dev
->next_attach_time
= qemu_get_clock_ms(vm_clock
) + 200;
924 static void usbredir_interface_info(void *priv
,
925 struct usb_redir_interface_info_header
*interface_info
)
927 /* The intention is to allow specifying acceptable interface classes
928 for redirection on the cmdline and in the future verify this here,
929 and disconnect (or never connect) the device if a not accepted
930 interface class is detected */
933 static void usbredir_ep_info(void *priv
,
934 struct usb_redir_ep_info_header
*ep_info
)
936 USBRedirDevice
*dev
= priv
;
939 for (i
= 0; i
< MAX_ENDPOINTS
; i
++) {
940 dev
->endpoint
[i
].type
= ep_info
->type
[i
];
941 dev
->endpoint
[i
].interval
= ep_info
->interval
[i
];
942 dev
->endpoint
[i
].interface
= ep_info
->interface
[i
];
943 if (dev
->endpoint
[i
].type
!= usb_redir_type_invalid
) {
944 DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i
),
945 dev
->endpoint
[i
].type
, dev
->endpoint
[i
].interface
);
950 static void usbredir_configuration_status(void *priv
, uint32_t id
,
951 struct usb_redir_configuration_status_header
*config_status
)
953 USBRedirDevice
*dev
= priv
;
957 DPRINTF("set config status %d config %d id %u\n", config_status
->status
,
958 config_status
->configuration
, id
);
960 aurb
= async_find(dev
, id
);
966 dev
->dev
.data_buf
[0] = config_status
->configuration
;
969 aurb
->packet
->result
=
970 usbredir_handle_status(dev
, config_status
->status
, len
);
971 usb_generic_async_ctrl_complete(&dev
->dev
, aurb
->packet
);
973 async_free(dev
, aurb
);
976 static void usbredir_alt_setting_status(void *priv
, uint32_t id
,
977 struct usb_redir_alt_setting_status_header
*alt_setting_status
)
979 USBRedirDevice
*dev
= priv
;
983 DPRINTF("alt status %d intf %d alt %d id: %u\n",
984 alt_setting_status
->status
,
985 alt_setting_status
->interface
,
986 alt_setting_status
->alt
, id
);
988 aurb
= async_find(dev
, id
);
994 dev
->dev
.data_buf
[0] = alt_setting_status
->alt
;
997 aurb
->packet
->result
=
998 usbredir_handle_status(dev
, alt_setting_status
->status
, len
);
999 usb_generic_async_ctrl_complete(&dev
->dev
, aurb
->packet
);
1001 async_free(dev
, aurb
);
1004 static void usbredir_iso_stream_status(void *priv
, uint32_t id
,
1005 struct usb_redir_iso_stream_status_header
*iso_stream_status
)
1007 USBRedirDevice
*dev
= priv
;
1008 uint8_t ep
= iso_stream_status
->endpoint
;
1010 DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status
->status
,
1013 dev
->endpoint
[EP2I(ep
)].iso_error
= iso_stream_status
->status
;
1014 if (iso_stream_status
->status
== usb_redir_stall
) {
1015 DPRINTF("iso stream stopped by peer ep %02X\n", ep
);
1016 dev
->endpoint
[EP2I(ep
)].iso_started
= 0;
1020 static void usbredir_interrupt_receiving_status(void *priv
, uint32_t id
,
1021 struct usb_redir_interrupt_receiving_status_header
1022 *interrupt_receiving_status
)
1024 USBRedirDevice
*dev
= priv
;
1025 uint8_t ep
= interrupt_receiving_status
->endpoint
;
1027 DPRINTF("interrupt recv status %d ep %02X id %u\n",
1028 interrupt_receiving_status
->status
, ep
, id
);
1030 dev
->endpoint
[EP2I(ep
)].interrupt_error
=
1031 interrupt_receiving_status
->status
;
1032 if (interrupt_receiving_status
->status
== usb_redir_stall
) {
1033 DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep
);
1034 dev
->endpoint
[EP2I(ep
)].interrupt_started
= 0;
1038 static void usbredir_bulk_streams_status(void *priv
, uint32_t id
,
1039 struct usb_redir_bulk_streams_status_header
*bulk_streams_status
)
1043 static void usbredir_control_packet(void *priv
, uint32_t id
,
1044 struct usb_redir_control_packet_header
*control_packet
,
1045 uint8_t *data
, int data_len
)
1047 USBRedirDevice
*dev
= priv
;
1048 int len
= control_packet
->length
;
1051 DPRINTF("ctrl-in status %d len %d id %u\n", control_packet
->status
,
1054 aurb
= async_find(dev
, id
);
1060 aurb
->control_packet
.status
= control_packet
->status
;
1061 aurb
->control_packet
.length
= control_packet
->length
;
1062 if (memcmp(&aurb
->control_packet
, control_packet
,
1063 sizeof(*control_packet
))) {
1064 ERROR("return control packet mismatch, please report this!\n");
1069 len
= usbredir_handle_status(dev
, control_packet
->status
, len
);
1071 usbredir_log_data(dev
, "ctrl data in:", data
, data_len
);
1072 if (data_len
<= sizeof(dev
->dev
.data_buf
)) {
1073 memcpy(dev
->dev
.data_buf
, data
, data_len
);
1075 ERROR("ctrl buffer too small (%d > %zu)\n",
1076 data_len
, sizeof(dev
->dev
.data_buf
));
1077 len
= USB_RET_STALL
;
1080 aurb
->packet
->result
= len
;
1081 usb_generic_async_ctrl_complete(&dev
->dev
, aurb
->packet
);
1083 async_free(dev
, aurb
);
1087 static void usbredir_bulk_packet(void *priv
, uint32_t id
,
1088 struct usb_redir_bulk_packet_header
*bulk_packet
,
1089 uint8_t *data
, int data_len
)
1091 USBRedirDevice
*dev
= priv
;
1092 uint8_t ep
= bulk_packet
->endpoint
;
1093 int len
= bulk_packet
->length
;
1096 DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet
->status
,
1099 aurb
= async_find(dev
, id
);
1105 if (aurb
->bulk_packet
.endpoint
!= bulk_packet
->endpoint
||
1106 aurb
->bulk_packet
.stream_id
!= bulk_packet
->stream_id
) {
1107 ERROR("return bulk packet mismatch, please report this!\n");
1112 len
= usbredir_handle_status(dev
, bulk_packet
->status
, len
);
1114 usbredir_log_data(dev
, "bulk data in:", data
, data_len
);
1115 if (data_len
<= aurb
->packet
->iov
.size
) {
1116 usb_packet_copy(aurb
->packet
, data
, data_len
);
1118 ERROR("bulk buffer too small (%d > %zd)\n", data_len
,
1119 aurb
->packet
->iov
.size
);
1120 len
= USB_RET_STALL
;
1123 aurb
->packet
->result
= len
;
1124 usb_packet_complete(&dev
->dev
, aurb
->packet
);
1126 async_free(dev
, aurb
);
1130 static void usbredir_iso_packet(void *priv
, uint32_t id
,
1131 struct usb_redir_iso_packet_header
*iso_packet
,
1132 uint8_t *data
, int data_len
)
1134 USBRedirDevice
*dev
= priv
;
1135 uint8_t ep
= iso_packet
->endpoint
;
1137 DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet
->status
, ep
,
1140 if (dev
->endpoint
[EP2I(ep
)].type
!= USB_ENDPOINT_XFER_ISOC
) {
1141 ERROR("received iso packet for non iso endpoint %02X\n", ep
);
1146 if (dev
->endpoint
[EP2I(ep
)].iso_started
== 0) {
1147 DPRINTF("received iso packet for non started stream ep %02X\n", ep
);
1152 /* bufp_alloc also adds the packet to the ep queue */
1153 bufp_alloc(dev
, data
, data_len
, iso_packet
->status
, ep
);
1156 static void usbredir_interrupt_packet(void *priv
, uint32_t id
,
1157 struct usb_redir_interrupt_packet_header
*interrupt_packet
,
1158 uint8_t *data
, int data_len
)
1160 USBRedirDevice
*dev
= priv
;
1161 uint8_t ep
= interrupt_packet
->endpoint
;
1163 DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1164 interrupt_packet
->status
, ep
, data_len
, id
);
1166 if (dev
->endpoint
[EP2I(ep
)].type
!= USB_ENDPOINT_XFER_INT
) {
1167 ERROR("received int packet for non interrupt endpoint %02X\n", ep
);
1172 if (ep
& USB_DIR_IN
) {
1173 if (dev
->endpoint
[EP2I(ep
)].interrupt_started
== 0) {
1174 DPRINTF("received int packet while not started ep %02X\n", ep
);
1179 /* bufp_alloc also adds the packet to the ep queue */
1180 bufp_alloc(dev
, data
, data_len
, interrupt_packet
->status
, ep
);
1182 int len
= interrupt_packet
->length
;
1184 AsyncURB
*aurb
= async_find(dev
, id
);
1189 if (aurb
->interrupt_packet
.endpoint
!= interrupt_packet
->endpoint
) {
1190 ERROR("return int packet mismatch, please report this!\n");
1195 aurb
->packet
->result
= usbredir_handle_status(dev
,
1196 interrupt_packet
->status
, len
);
1197 usb_packet_complete(&dev
->dev
, aurb
->packet
);
1199 async_free(dev
, aurb
);
1203 static struct USBDeviceInfo usbredir_dev_info
= {
1204 .product_desc
= "USB Redirection Device",
1205 .qdev
.name
= "usb-redir",
1206 .qdev
.size
= sizeof(USBRedirDevice
),
1207 .init
= usbredir_initfn
,
1208 .handle_destroy
= usbredir_handle_destroy
,
1209 .handle_packet
= usb_generic_handle_packet
,
1210 .cancel_packet
= usbredir_cancel_packet
,
1211 .handle_reset
= usbredir_handle_reset
,
1212 .handle_data
= usbredir_handle_data
,
1213 .handle_control
= usbredir_handle_control
,
1214 .qdev
.props
= (Property
[]) {
1215 DEFINE_PROP_CHR("chardev", USBRedirDevice
, cs
),
1216 DEFINE_PROP_UINT8("debug", USBRedirDevice
, debug
, 0),
1217 DEFINE_PROP_END_OF_LIST(),
1221 static void usbredir_register_devices(void)
1223 usb_qdev_register(&usbredir_dev_info
);
1225 device_init(usbredir_register_devices
);