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
);
131 static void usbredir_update_handlers(USBRedirDevice
*dev
);
133 #define VERSION "qemu usb-redir guest " QEMU_VERSION
141 if (dev->debug >= usbredirparser_error) { \
142 error_report("usb-redir error: " __VA_ARGS__); \
145 #define WARNING(...) \
147 if (dev->debug >= usbredirparser_warning) { \
148 error_report("usb-redir warning: " __VA_ARGS__); \
153 if (dev->debug >= usbredirparser_info) { \
154 error_report("usb-redir: " __VA_ARGS__); \
157 #define DPRINTF(...) \
159 if (dev->debug >= usbredirparser_debug) { \
160 error_report("usb-redir: " __VA_ARGS__); \
163 #define DPRINTF2(...) \
165 if (dev->debug >= usbredirparser_debug_data) { \
166 error_report("usb-redir: " __VA_ARGS__); \
170 static void usbredir_log(void *priv
, int level
, const char *msg
)
172 USBRedirDevice
*dev
= priv
;
174 if (dev
->debug
< level
) {
178 error_report("%s\n", msg
);
181 static void usbredir_log_data(USBRedirDevice
*dev
, const char *desc
,
182 const uint8_t *data
, int len
)
186 if (dev
->debug
< usbredirparser_debug_data
) {
190 for (i
= 0; i
< len
; i
+= j
) {
193 n
= sprintf(buf
, "%s", desc
);
194 for (j
= 0; j
< 8 && i
+ j
< len
; j
++) {
195 n
+= sprintf(buf
+ n
, " %02X", data
[i
+ j
]);
197 error_report("%s\n", buf
);
202 * usbredirparser io functions
205 static int usbredir_read(void *priv
, uint8_t *data
, int count
)
207 USBRedirDevice
*dev
= priv
;
209 if (dev
->read_buf_size
< count
) {
210 count
= dev
->read_buf_size
;
213 memcpy(data
, dev
->read_buf
, count
);
215 dev
->read_buf_size
-= count
;
216 if (dev
->read_buf_size
) {
217 dev
->read_buf
+= count
;
219 dev
->read_buf
= NULL
;
225 static int usbredir_write(void *priv
, uint8_t *data
, int count
)
227 USBRedirDevice
*dev
= priv
;
229 return qemu_chr_fe_write(dev
->cs
, data
, count
);
233 * Async and buffered packets helpers
236 static AsyncURB
*async_alloc(USBRedirDevice
*dev
, USBPacket
*p
)
238 AsyncURB
*aurb
= (AsyncURB
*) qemu_mallocz(sizeof(AsyncURB
));
241 aurb
->packet_id
= dev
->packet_id
;
242 QTAILQ_INSERT_TAIL(&dev
->asyncq
, aurb
, next
);
248 static void async_free(USBRedirDevice
*dev
, AsyncURB
*aurb
)
250 QTAILQ_REMOVE(&dev
->asyncq
, aurb
, next
);
254 static AsyncURB
*async_find(USBRedirDevice
*dev
, uint32_t packet_id
)
258 QTAILQ_FOREACH(aurb
, &dev
->asyncq
, next
) {
259 if (aurb
->packet_id
== packet_id
) {
263 ERROR("could not find async urb for packet_id %u\n", packet_id
);
267 static void usbredir_cancel_packet(USBDevice
*udev
, USBPacket
*p
)
269 USBRedirDevice
*dev
= DO_UPCAST(USBRedirDevice
, dev
, udev
);
272 QTAILQ_FOREACH(aurb
, &dev
->asyncq
, next
) {
273 if (p
!= aurb
->packet
) {
277 DPRINTF("async cancel id %u\n", aurb
->packet_id
);
278 usbredirparser_send_cancel_data_packet(dev
->parser
, aurb
->packet_id
);
279 usbredirparser_do_write(dev
->parser
);
281 /* Mark it as dead */
287 static struct buf_packet
*bufp_alloc(USBRedirDevice
*dev
,
288 uint8_t *data
, int len
, int status
, uint8_t ep
)
290 struct buf_packet
*bufp
= qemu_malloc(sizeof(struct buf_packet
));
293 bufp
->status
= status
;
294 QTAILQ_INSERT_TAIL(&dev
->endpoint
[EP2I(ep
)].bufpq
, bufp
, next
);
298 static void bufp_free(USBRedirDevice
*dev
, struct buf_packet
*bufp
,
301 QTAILQ_REMOVE(&dev
->endpoint
[EP2I(ep
)].bufpq
, bufp
, next
);
306 static void usbredir_free_bufpq(USBRedirDevice
*dev
, uint8_t ep
)
308 struct buf_packet
*buf
, *buf_next
;
310 QTAILQ_FOREACH_SAFE(buf
, &dev
->endpoint
[EP2I(ep
)].bufpq
, next
, buf_next
) {
311 bufp_free(dev
, buf
, ep
);
316 * USBDevice callbacks
319 static void usbredir_handle_reset(USBDevice
*udev
)
321 USBRedirDevice
*dev
= DO_UPCAST(USBRedirDevice
, dev
, udev
);
323 DPRINTF("reset device\n");
324 usbredirparser_send_reset(dev
->parser
);
325 usbredirparser_do_write(dev
->parser
);
328 static int usbredir_handle_iso_data(USBRedirDevice
*dev
, USBPacket
*p
,
333 if (!dev
->endpoint
[EP2I(ep
)].iso_started
&&
334 !dev
->endpoint
[EP2I(ep
)].iso_error
) {
335 struct usb_redir_start_iso_stream_header start_iso
= {
337 /* TODO maybe do something with these depending on ep interval? */
341 /* No id, we look at the ep when receiving a status back */
342 usbredirparser_send_start_iso_stream(dev
->parser
, 0, &start_iso
);
343 usbredirparser_do_write(dev
->parser
);
344 DPRINTF("iso stream started ep %02X\n", ep
);
345 dev
->endpoint
[EP2I(ep
)].iso_started
= 1;
348 if (ep
& USB_DIR_IN
) {
349 struct buf_packet
*isop
;
351 isop
= QTAILQ_FIRST(&dev
->endpoint
[EP2I(ep
)].bufpq
);
353 DPRINTF2("iso-token-in ep %02X, no isop\n", ep
);
354 /* Check iso_error for stream errors, otherwise its an underrun */
355 status
= dev
->endpoint
[EP2I(ep
)].iso_error
;
356 dev
->endpoint
[EP2I(ep
)].iso_error
= 0;
357 return usbredir_handle_status(dev
, status
, 0);
359 DPRINTF2("iso-token-in ep %02X status %d len %d\n", ep
, isop
->status
,
362 status
= isop
->status
;
363 if (status
!= usb_redir_success
) {
364 bufp_free(dev
, isop
, ep
);
365 return usbredir_handle_status(dev
, status
, 0);
369 if (len
> p
->iov
.size
) {
370 ERROR("received iso data is larger then packet ep %02X\n", ep
);
371 bufp_free(dev
, isop
, ep
);
374 usb_packet_copy(p
, isop
->data
, len
);
375 bufp_free(dev
, isop
, ep
);
378 /* If the stream was not started because of a pending error don't
379 send the packet to the usb-host */
380 if (dev
->endpoint
[EP2I(ep
)].iso_started
) {
381 struct usb_redir_iso_packet_header iso_packet
= {
383 .length
= p
->iov
.size
385 uint8_t buf
[p
->iov
.size
];
386 /* No id, we look at the ep when receiving a status back */
387 usb_packet_copy(p
, buf
, p
->iov
.size
);
388 usbredirparser_send_iso_packet(dev
->parser
, 0, &iso_packet
,
390 usbredirparser_do_write(dev
->parser
);
392 status
= dev
->endpoint
[EP2I(ep
)].iso_error
;
393 dev
->endpoint
[EP2I(ep
)].iso_error
= 0;
394 DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep
, status
,
396 return usbredir_handle_status(dev
, status
, p
->iov
.size
);
400 static void usbredir_stop_iso_stream(USBRedirDevice
*dev
, uint8_t ep
)
402 struct usb_redir_stop_iso_stream_header stop_iso_stream
= {
405 if (dev
->endpoint
[EP2I(ep
)].iso_started
) {
406 usbredirparser_send_stop_iso_stream(dev
->parser
, 0, &stop_iso_stream
);
407 DPRINTF("iso stream stopped ep %02X\n", ep
);
408 dev
->endpoint
[EP2I(ep
)].iso_started
= 0;
410 usbredir_free_bufpq(dev
, ep
);
413 static int usbredir_handle_bulk_data(USBRedirDevice
*dev
, USBPacket
*p
,
416 AsyncURB
*aurb
= async_alloc(dev
, p
);
417 struct usb_redir_bulk_packet_header bulk_packet
;
419 DPRINTF("bulk-out ep %02X len %zd id %u\n", ep
,
420 p
->iov
.size
, aurb
->packet_id
);
422 bulk_packet
.endpoint
= ep
;
423 bulk_packet
.length
= p
->iov
.size
;
424 bulk_packet
.stream_id
= 0;
425 aurb
->bulk_packet
= bulk_packet
;
427 if (ep
& USB_DIR_IN
) {
428 usbredirparser_send_bulk_packet(dev
->parser
, aurb
->packet_id
,
429 &bulk_packet
, NULL
, 0);
431 uint8_t buf
[p
->iov
.size
];
432 usb_packet_copy(p
, buf
, p
->iov
.size
);
433 usbredir_log_data(dev
, "bulk data out:", buf
, p
->iov
.size
);
434 usbredirparser_send_bulk_packet(dev
->parser
, aurb
->packet_id
,
435 &bulk_packet
, buf
, p
->iov
.size
);
437 usbredirparser_do_write(dev
->parser
);
438 return USB_RET_ASYNC
;
441 static int usbredir_handle_interrupt_data(USBRedirDevice
*dev
,
442 USBPacket
*p
, uint8_t ep
)
444 if (ep
& USB_DIR_IN
) {
445 /* Input interrupt endpoint, buffered packet input */
446 struct buf_packet
*intp
;
449 if (!dev
->endpoint
[EP2I(ep
)].interrupt_started
&&
450 !dev
->endpoint
[EP2I(ep
)].interrupt_error
) {
451 struct usb_redir_start_interrupt_receiving_header start_int
= {
454 /* No id, we look at the ep when receiving a status back */
455 usbredirparser_send_start_interrupt_receiving(dev
->parser
, 0,
457 usbredirparser_do_write(dev
->parser
);
458 DPRINTF("interrupt recv started ep %02X\n", ep
);
459 dev
->endpoint
[EP2I(ep
)].interrupt_started
= 1;
462 intp
= QTAILQ_FIRST(&dev
->endpoint
[EP2I(ep
)].bufpq
);
464 DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep
);
465 /* Check interrupt_error for stream errors */
466 status
= dev
->endpoint
[EP2I(ep
)].interrupt_error
;
467 dev
->endpoint
[EP2I(ep
)].interrupt_error
= 0;
468 return usbredir_handle_status(dev
, status
, 0);
470 DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep
,
471 intp
->status
, intp
->len
);
473 status
= intp
->status
;
474 if (status
!= usb_redir_success
) {
475 bufp_free(dev
, intp
, ep
);
476 return usbredir_handle_status(dev
, status
, 0);
480 if (len
> p
->iov
.size
) {
481 ERROR("received int data is larger then packet ep %02X\n", ep
);
482 bufp_free(dev
, intp
, ep
);
485 usb_packet_copy(p
, intp
->data
, len
);
486 bufp_free(dev
, intp
, ep
);
489 /* Output interrupt endpoint, normal async operation */
490 AsyncURB
*aurb
= async_alloc(dev
, p
);
491 struct usb_redir_interrupt_packet_header interrupt_packet
;
492 uint8_t buf
[p
->iov
.size
];
494 DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep
, p
->iov
.size
,
497 interrupt_packet
.endpoint
= ep
;
498 interrupt_packet
.length
= p
->iov
.size
;
499 aurb
->interrupt_packet
= interrupt_packet
;
501 usb_packet_copy(p
, buf
, p
->iov
.size
);
502 usbredir_log_data(dev
, "interrupt data out:", buf
, p
->iov
.size
);
503 usbredirparser_send_interrupt_packet(dev
->parser
, aurb
->packet_id
,
504 &interrupt_packet
, buf
, p
->iov
.size
);
505 usbredirparser_do_write(dev
->parser
);
506 return USB_RET_ASYNC
;
510 static void usbredir_stop_interrupt_receiving(USBRedirDevice
*dev
,
513 struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv
= {
516 if (dev
->endpoint
[EP2I(ep
)].interrupt_started
) {
517 usbredirparser_send_stop_interrupt_receiving(dev
->parser
, 0,
518 &stop_interrupt_recv
);
519 DPRINTF("interrupt recv stopped ep %02X\n", ep
);
520 dev
->endpoint
[EP2I(ep
)].interrupt_started
= 0;
522 usbredir_free_bufpq(dev
, ep
);
525 static int usbredir_handle_data(USBDevice
*udev
, USBPacket
*p
)
527 USBRedirDevice
*dev
= DO_UPCAST(USBRedirDevice
, dev
, udev
);
531 if (p
->pid
== USB_TOKEN_IN
) {
535 switch (dev
->endpoint
[EP2I(ep
)].type
) {
536 case USB_ENDPOINT_XFER_CONTROL
:
537 ERROR("handle_data called for control transfer on ep %02X\n", ep
);
539 case USB_ENDPOINT_XFER_ISOC
:
540 return usbredir_handle_iso_data(dev
, p
, ep
);
541 case USB_ENDPOINT_XFER_BULK
:
542 return usbredir_handle_bulk_data(dev
, p
, ep
);;
543 case USB_ENDPOINT_XFER_INT
:
544 return usbredir_handle_interrupt_data(dev
, p
, ep
);;
546 ERROR("handle_data ep %02X has unknown type %d\n", ep
,
547 dev
->endpoint
[EP2I(ep
)].type
);
552 static int usbredir_set_config(USBRedirDevice
*dev
, USBPacket
*p
,
555 struct usb_redir_set_configuration_header set_config
;
556 AsyncURB
*aurb
= async_alloc(dev
, p
);
559 DPRINTF("set config %d id %u\n", config
, aurb
->packet_id
);
561 for (i
= 0; i
< MAX_ENDPOINTS
; i
++) {
562 switch (dev
->endpoint
[i
].type
) {
563 case USB_ENDPOINT_XFER_ISOC
:
564 usbredir_stop_iso_stream(dev
, I2EP(i
));
566 case USB_ENDPOINT_XFER_INT
:
568 usbredir_stop_interrupt_receiving(dev
, I2EP(i
));
572 usbredir_free_bufpq(dev
, I2EP(i
));
575 set_config
.configuration
= config
;
576 usbredirparser_send_set_configuration(dev
->parser
, aurb
->packet_id
,
578 usbredirparser_do_write(dev
->parser
);
579 return USB_RET_ASYNC
;
582 static int usbredir_get_config(USBRedirDevice
*dev
, USBPacket
*p
)
584 AsyncURB
*aurb
= async_alloc(dev
, p
);
586 DPRINTF("get config id %u\n", aurb
->packet_id
);
589 usbredirparser_send_get_configuration(dev
->parser
, aurb
->packet_id
);
590 usbredirparser_do_write(dev
->parser
);
591 return USB_RET_ASYNC
;
594 static int usbredir_set_interface(USBRedirDevice
*dev
, USBPacket
*p
,
595 int interface
, int alt
)
597 struct usb_redir_set_alt_setting_header set_alt
;
598 AsyncURB
*aurb
= async_alloc(dev
, p
);
601 DPRINTF("set interface %d alt %d id %u\n", interface
, alt
,
604 for (i
= 0; i
< MAX_ENDPOINTS
; i
++) {
605 if (dev
->endpoint
[i
].interface
== interface
) {
606 switch (dev
->endpoint
[i
].type
) {
607 case USB_ENDPOINT_XFER_ISOC
:
608 usbredir_stop_iso_stream(dev
, I2EP(i
));
610 case USB_ENDPOINT_XFER_INT
:
612 usbredir_stop_interrupt_receiving(dev
, I2EP(i
));
616 usbredir_free_bufpq(dev
, I2EP(i
));
620 set_alt
.interface
= interface
;
622 usbredirparser_send_set_alt_setting(dev
->parser
, aurb
->packet_id
,
624 usbredirparser_do_write(dev
->parser
);
625 return USB_RET_ASYNC
;
628 static int usbredir_get_interface(USBRedirDevice
*dev
, USBPacket
*p
,
631 struct usb_redir_get_alt_setting_header get_alt
;
632 AsyncURB
*aurb
= async_alloc(dev
, p
);
634 DPRINTF("get interface %d id %u\n", interface
, aurb
->packet_id
);
636 get_alt
.interface
= interface
;
638 usbredirparser_send_get_alt_setting(dev
->parser
, aurb
->packet_id
,
640 usbredirparser_do_write(dev
->parser
);
641 return USB_RET_ASYNC
;
644 static int usbredir_handle_control(USBDevice
*udev
, USBPacket
*p
,
645 int request
, int value
, int index
, int length
, uint8_t *data
)
647 USBRedirDevice
*dev
= DO_UPCAST(USBRedirDevice
, dev
, udev
);
648 struct usb_redir_control_packet_header control_packet
;
651 /* Special cases for certain standard device requests */
653 case DeviceOutRequest
| USB_REQ_SET_ADDRESS
:
654 DPRINTF("set address %d\n", value
);
655 dev
->dev
.addr
= value
;
657 case DeviceOutRequest
| USB_REQ_SET_CONFIGURATION
:
658 return usbredir_set_config(dev
, p
, value
& 0xff);
659 case DeviceRequest
| USB_REQ_GET_CONFIGURATION
:
660 return usbredir_get_config(dev
, p
);
661 case InterfaceOutRequest
| USB_REQ_SET_INTERFACE
:
662 return usbredir_set_interface(dev
, p
, index
, value
);
663 case InterfaceRequest
| USB_REQ_GET_INTERFACE
:
664 return usbredir_get_interface(dev
, p
, index
);
667 /* "Normal" ctrl requests */
668 aurb
= async_alloc(dev
, p
);
670 /* Note request is (bRequestType << 8) | bRequest */
671 DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
672 request
>> 8, request
& 0xff, value
, index
, length
,
675 control_packet
.request
= request
& 0xFF;
676 control_packet
.requesttype
= request
>> 8;
677 control_packet
.endpoint
= control_packet
.requesttype
& USB_DIR_IN
;
678 control_packet
.value
= value
;
679 control_packet
.index
= index
;
680 control_packet
.length
= length
;
681 aurb
->control_packet
= control_packet
;
683 if (control_packet
.requesttype
& USB_DIR_IN
) {
684 usbredirparser_send_control_packet(dev
->parser
, aurb
->packet_id
,
685 &control_packet
, NULL
, 0);
687 usbredir_log_data(dev
, "ctrl data out:", data
, length
);
688 usbredirparser_send_control_packet(dev
->parser
, aurb
->packet_id
,
689 &control_packet
, data
, length
);
691 usbredirparser_do_write(dev
->parser
);
692 return USB_RET_ASYNC
;
696 * Close events can be triggered by usbredirparser_do_write which gets called
697 * from within the USBDevice data / control packet callbacks and doing a
698 * usb_detach from within these callbacks is not a good idea.
700 * So we use a bh handler to take care of close events. We also handle
701 * open events from this callback to make sure that a close directly followed
702 * by an open gets handled in the right order.
704 static void usbredir_open_close_bh(void *opaque
)
706 USBRedirDevice
*dev
= opaque
;
708 usbredir_device_disconnect(dev
);
711 usbredirparser_destroy(dev
->parser
);
715 if (dev
->cs
->opened
) {
716 dev
->parser
= qemu_oom_check(usbredirparser_create());
717 dev
->parser
->priv
= dev
;
718 dev
->parser
->log_func
= usbredir_log
;
719 dev
->parser
->read_func
= usbredir_read
;
720 dev
->parser
->write_func
= usbredir_write
;
721 dev
->parser
->device_connect_func
= usbredir_device_connect
;
722 dev
->parser
->device_disconnect_func
= usbredir_device_disconnect
;
723 dev
->parser
->interface_info_func
= usbredir_interface_info
;
724 dev
->parser
->ep_info_func
= usbredir_ep_info
;
725 dev
->parser
->configuration_status_func
= usbredir_configuration_status
;
726 dev
->parser
->alt_setting_status_func
= usbredir_alt_setting_status
;
727 dev
->parser
->iso_stream_status_func
= usbredir_iso_stream_status
;
728 dev
->parser
->interrupt_receiving_status_func
=
729 usbredir_interrupt_receiving_status
;
730 dev
->parser
->bulk_streams_status_func
= usbredir_bulk_streams_status
;
731 dev
->parser
->control_packet_func
= usbredir_control_packet
;
732 dev
->parser
->bulk_packet_func
= usbredir_bulk_packet
;
733 dev
->parser
->iso_packet_func
= usbredir_iso_packet
;
734 dev
->parser
->interrupt_packet_func
= usbredir_interrupt_packet
;
735 dev
->read_buf
= NULL
;
736 dev
->read_buf_size
= 0;
737 usbredirparser_init(dev
->parser
, VERSION
, NULL
, 0, 0);
738 usbredirparser_do_write(dev
->parser
);
741 usbredir_update_handlers(dev
);
744 static void usbredir_do_attach(void *opaque
)
746 USBRedirDevice
*dev
= opaque
;
748 usb_device_attach(&dev
->dev
);
755 static void usbredir_chardev_read(void *opaque
)
757 USBRedirDevice
*dev
= opaque
;
758 uint8_t buf
[1024 * 1024];
761 /* No recursion allowed! */
762 assert(dev
->read_buf
== NULL
);
764 size
= qemu_chr_fe_read(dev
->chr
, buf
, sizeof(buf
));
767 dev
->read_buf_size
= size
;
769 usbredirparser_do_read(dev
->parser
);
770 /* Send any acks, etc. which may be queued now */
771 usbredirparser_do_write(dev
->parser
);
774 static void usbredir_chardev_event(void *opaque
, int event
)
776 USBRedirDevice
*dev
= opaque
;
779 case CHR_EVENT_OPENED
:
780 case CHR_EVENT_CLOSED
:
781 qemu_bh_schedule(dev
->open_close_bh
);
786 static void usbredir_update_handlers(USBRedirDevice
*dev
)
789 qemu_chr_fe_set_handlers(dev
->cs
, usbredir_chardev_read
,
790 NULL
, usbredir_chardev_event
, dev
);
792 qemu_chr_fe_set_handlers(dev
->cs
, NULL
, NULL
,
793 usbredir_chardev_event
, dev
);
801 static int usbredir_initfn(USBDevice
*udev
)
803 USBRedirDevice
*dev
= DO_UPCAST(USBRedirDevice
, dev
, udev
);
806 if (dev
->cs
== NULL
) {
807 qerror_report(QERR_MISSING_PARAMETER
, "chardev");
811 dev
->open_close_bh
= qemu_bh_new(usbredir_open_close_bh
, dev
);
812 dev
->attach_timer
= qemu_new_timer_ms(vm_clock
, usbredir_do_attach
, dev
);
814 QTAILQ_INIT(&dev
->asyncq
);
815 for (i
= 0; i
< MAX_ENDPOINTS
; i
++) {
816 QTAILQ_INIT(&dev
->endpoint
[i
].bufpq
);
819 /* We'll do the attach once we receive the speed from the usb-host */
820 udev
->auto_attach
= 0;
822 qemu_chr_fe_open(dev
->cs
);
823 usbredir_update_handlers(dev
);
828 static void usbredir_cleanup_device_queues(USBRedirDevice
*dev
)
830 AsyncURB
*aurb
, *next_aurb
;
833 QTAILQ_FOREACH_SAFE(aurb
, &dev
->asyncq
, next
, next_aurb
) {
834 async_free(dev
, aurb
);
836 for (i
= 0; i
< MAX_ENDPOINTS
; i
++) {
837 usbredir_free_bufpq(dev
, I2EP(i
));
841 static void usbredir_handle_destroy(USBDevice
*udev
)
843 USBRedirDevice
*dev
= DO_UPCAST(USBRedirDevice
, dev
, udev
);
845 qemu_chr_fe_delete(dev
->cs
);
846 /* Note must be done after qemu_chr_close, as that causes a close event */
847 qemu_bh_delete(dev
->open_close_bh
);
849 qemu_del_timer(dev
->attach_timer
);
850 qemu_free_timer(dev
->attach_timer
);
852 usbredir_cleanup_device_queues(dev
);
855 usbredirparser_destroy(dev
->parser
);
860 * usbredirparser packet complete callbacks
863 static int usbredir_handle_status(USBRedirDevice
*dev
,
864 int status
, int actual_len
)
867 case usb_redir_success
:
869 case usb_redir_stall
:
870 return USB_RET_STALL
;
871 case usb_redir_cancelled
:
872 WARNING("returning cancelled packet to HC?\n");
873 case usb_redir_inval
:
874 case usb_redir_ioerror
:
875 case usb_redir_timeout
:
881 static void usbredir_device_connect(void *priv
,
882 struct usb_redir_device_connect_header
*device_connect
)
884 USBRedirDevice
*dev
= priv
;
886 switch (device_connect
->speed
) {
887 case usb_redir_speed_low
:
888 DPRINTF("attaching low speed device\n");
889 dev
->dev
.speed
= USB_SPEED_LOW
;
891 case usb_redir_speed_full
:
892 DPRINTF("attaching full speed device\n");
893 dev
->dev
.speed
= USB_SPEED_FULL
;
895 case usb_redir_speed_high
:
896 DPRINTF("attaching high speed device\n");
897 dev
->dev
.speed
= USB_SPEED_HIGH
;
899 case usb_redir_speed_super
:
900 DPRINTF("attaching super speed device\n");
901 dev
->dev
.speed
= USB_SPEED_SUPER
;
904 DPRINTF("attaching unknown speed device, assuming full speed\n");
905 dev
->dev
.speed
= USB_SPEED_FULL
;
907 dev
->dev
.speedmask
= (1 << dev
->dev
.speed
);
908 qemu_mod_timer(dev
->attach_timer
, dev
->next_attach_time
);
911 static void usbredir_device_disconnect(void *priv
)
913 USBRedirDevice
*dev
= priv
;
915 /* Stop any pending attaches */
916 qemu_del_timer(dev
->attach_timer
);
918 if (dev
->dev
.attached
) {
919 usb_device_detach(&dev
->dev
);
920 usbredir_cleanup_device_queues(dev
);
922 * Delay next usb device attach to give the guest a chance to see
923 * see the detach / attach in case of quick close / open succession
925 dev
->next_attach_time
= qemu_get_clock_ms(vm_clock
) + 200;
929 static void usbredir_interface_info(void *priv
,
930 struct usb_redir_interface_info_header
*interface_info
)
932 /* The intention is to allow specifying acceptable interface classes
933 for redirection on the cmdline and in the future verify this here,
934 and disconnect (or never connect) the device if a not accepted
935 interface class is detected */
938 static void usbredir_ep_info(void *priv
,
939 struct usb_redir_ep_info_header
*ep_info
)
941 USBRedirDevice
*dev
= priv
;
944 for (i
= 0; i
< MAX_ENDPOINTS
; i
++) {
945 dev
->endpoint
[i
].type
= ep_info
->type
[i
];
946 dev
->endpoint
[i
].interval
= ep_info
->interval
[i
];
947 dev
->endpoint
[i
].interface
= ep_info
->interface
[i
];
948 if (dev
->endpoint
[i
].type
!= usb_redir_type_invalid
) {
949 DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i
),
950 dev
->endpoint
[i
].type
, dev
->endpoint
[i
].interface
);
955 static void usbredir_configuration_status(void *priv
, uint32_t id
,
956 struct usb_redir_configuration_status_header
*config_status
)
958 USBRedirDevice
*dev
= priv
;
962 DPRINTF("set config status %d config %d id %u\n", config_status
->status
,
963 config_status
->configuration
, id
);
965 aurb
= async_find(dev
, id
);
971 dev
->dev
.data_buf
[0] = config_status
->configuration
;
974 aurb
->packet
->result
=
975 usbredir_handle_status(dev
, config_status
->status
, len
);
976 usb_generic_async_ctrl_complete(&dev
->dev
, aurb
->packet
);
978 async_free(dev
, aurb
);
981 static void usbredir_alt_setting_status(void *priv
, uint32_t id
,
982 struct usb_redir_alt_setting_status_header
*alt_setting_status
)
984 USBRedirDevice
*dev
= priv
;
988 DPRINTF("alt status %d intf %d alt %d id: %u\n",
989 alt_setting_status
->status
,
990 alt_setting_status
->interface
,
991 alt_setting_status
->alt
, id
);
993 aurb
= async_find(dev
, id
);
999 dev
->dev
.data_buf
[0] = alt_setting_status
->alt
;
1002 aurb
->packet
->result
=
1003 usbredir_handle_status(dev
, alt_setting_status
->status
, len
);
1004 usb_generic_async_ctrl_complete(&dev
->dev
, aurb
->packet
);
1006 async_free(dev
, aurb
);
1009 static void usbredir_iso_stream_status(void *priv
, uint32_t id
,
1010 struct usb_redir_iso_stream_status_header
*iso_stream_status
)
1012 USBRedirDevice
*dev
= priv
;
1013 uint8_t ep
= iso_stream_status
->endpoint
;
1015 DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status
->status
,
1018 dev
->endpoint
[EP2I(ep
)].iso_error
= iso_stream_status
->status
;
1019 if (iso_stream_status
->status
== usb_redir_stall
) {
1020 DPRINTF("iso stream stopped by peer ep %02X\n", ep
);
1021 dev
->endpoint
[EP2I(ep
)].iso_started
= 0;
1025 static void usbredir_interrupt_receiving_status(void *priv
, uint32_t id
,
1026 struct usb_redir_interrupt_receiving_status_header
1027 *interrupt_receiving_status
)
1029 USBRedirDevice
*dev
= priv
;
1030 uint8_t ep
= interrupt_receiving_status
->endpoint
;
1032 DPRINTF("interrupt recv status %d ep %02X id %u\n",
1033 interrupt_receiving_status
->status
, ep
, id
);
1035 dev
->endpoint
[EP2I(ep
)].interrupt_error
=
1036 interrupt_receiving_status
->status
;
1037 if (interrupt_receiving_status
->status
== usb_redir_stall
) {
1038 DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep
);
1039 dev
->endpoint
[EP2I(ep
)].interrupt_started
= 0;
1043 static void usbredir_bulk_streams_status(void *priv
, uint32_t id
,
1044 struct usb_redir_bulk_streams_status_header
*bulk_streams_status
)
1048 static void usbredir_control_packet(void *priv
, uint32_t id
,
1049 struct usb_redir_control_packet_header
*control_packet
,
1050 uint8_t *data
, int data_len
)
1052 USBRedirDevice
*dev
= priv
;
1053 int len
= control_packet
->length
;
1056 DPRINTF("ctrl-in status %d len %d id %u\n", control_packet
->status
,
1059 aurb
= async_find(dev
, id
);
1065 aurb
->control_packet
.status
= control_packet
->status
;
1066 aurb
->control_packet
.length
= control_packet
->length
;
1067 if (memcmp(&aurb
->control_packet
, control_packet
,
1068 sizeof(*control_packet
))) {
1069 ERROR("return control packet mismatch, please report this!\n");
1074 len
= usbredir_handle_status(dev
, control_packet
->status
, len
);
1076 usbredir_log_data(dev
, "ctrl data in:", data
, data_len
);
1077 if (data_len
<= sizeof(dev
->dev
.data_buf
)) {
1078 memcpy(dev
->dev
.data_buf
, data
, data_len
);
1080 ERROR("ctrl buffer too small (%d > %zu)\n",
1081 data_len
, sizeof(dev
->dev
.data_buf
));
1082 len
= USB_RET_STALL
;
1085 aurb
->packet
->result
= len
;
1086 usb_generic_async_ctrl_complete(&dev
->dev
, aurb
->packet
);
1088 async_free(dev
, aurb
);
1092 static void usbredir_bulk_packet(void *priv
, uint32_t id
,
1093 struct usb_redir_bulk_packet_header
*bulk_packet
,
1094 uint8_t *data
, int data_len
)
1096 USBRedirDevice
*dev
= priv
;
1097 uint8_t ep
= bulk_packet
->endpoint
;
1098 int len
= bulk_packet
->length
;
1101 DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet
->status
,
1104 aurb
= async_find(dev
, id
);
1110 if (aurb
->bulk_packet
.endpoint
!= bulk_packet
->endpoint
||
1111 aurb
->bulk_packet
.stream_id
!= bulk_packet
->stream_id
) {
1112 ERROR("return bulk packet mismatch, please report this!\n");
1117 len
= usbredir_handle_status(dev
, bulk_packet
->status
, len
);
1119 usbredir_log_data(dev
, "bulk data in:", data
, data_len
);
1120 if (data_len
<= aurb
->packet
->iov
.size
) {
1121 usb_packet_copy(aurb
->packet
, data
, data_len
);
1123 ERROR("bulk buffer too small (%d > %zd)\n", data_len
,
1124 aurb
->packet
->iov
.size
);
1125 len
= USB_RET_STALL
;
1128 aurb
->packet
->result
= len
;
1129 usb_packet_complete(&dev
->dev
, aurb
->packet
);
1131 async_free(dev
, aurb
);
1135 static void usbredir_iso_packet(void *priv
, uint32_t id
,
1136 struct usb_redir_iso_packet_header
*iso_packet
,
1137 uint8_t *data
, int data_len
)
1139 USBRedirDevice
*dev
= priv
;
1140 uint8_t ep
= iso_packet
->endpoint
;
1142 DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet
->status
, ep
,
1145 if (dev
->endpoint
[EP2I(ep
)].type
!= USB_ENDPOINT_XFER_ISOC
) {
1146 ERROR("received iso packet for non iso endpoint %02X\n", ep
);
1151 if (dev
->endpoint
[EP2I(ep
)].iso_started
== 0) {
1152 DPRINTF("received iso packet for non started stream ep %02X\n", ep
);
1157 /* bufp_alloc also adds the packet to the ep queue */
1158 bufp_alloc(dev
, data
, data_len
, iso_packet
->status
, ep
);
1161 static void usbredir_interrupt_packet(void *priv
, uint32_t id
,
1162 struct usb_redir_interrupt_packet_header
*interrupt_packet
,
1163 uint8_t *data
, int data_len
)
1165 USBRedirDevice
*dev
= priv
;
1166 uint8_t ep
= interrupt_packet
->endpoint
;
1168 DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1169 interrupt_packet
->status
, ep
, data_len
, id
);
1171 if (dev
->endpoint
[EP2I(ep
)].type
!= USB_ENDPOINT_XFER_INT
) {
1172 ERROR("received int packet for non interrupt endpoint %02X\n", ep
);
1177 if (ep
& USB_DIR_IN
) {
1178 if (dev
->endpoint
[EP2I(ep
)].interrupt_started
== 0) {
1179 DPRINTF("received int packet while not started ep %02X\n", ep
);
1184 /* bufp_alloc also adds the packet to the ep queue */
1185 bufp_alloc(dev
, data
, data_len
, interrupt_packet
->status
, ep
);
1187 int len
= interrupt_packet
->length
;
1189 AsyncURB
*aurb
= async_find(dev
, id
);
1194 if (aurb
->interrupt_packet
.endpoint
!= interrupt_packet
->endpoint
) {
1195 ERROR("return int packet mismatch, please report this!\n");
1200 aurb
->packet
->result
= usbredir_handle_status(dev
,
1201 interrupt_packet
->status
, len
);
1202 usb_packet_complete(&dev
->dev
, aurb
->packet
);
1204 async_free(dev
, aurb
);
1208 static struct USBDeviceInfo usbredir_dev_info
= {
1209 .product_desc
= "USB Redirection Device",
1210 .qdev
.name
= "usb-redir",
1211 .qdev
.size
= sizeof(USBRedirDevice
),
1212 .init
= usbredir_initfn
,
1213 .handle_destroy
= usbredir_handle_destroy
,
1214 .handle_packet
= usb_generic_handle_packet
,
1215 .cancel_packet
= usbredir_cancel_packet
,
1216 .handle_reset
= usbredir_handle_reset
,
1217 .handle_data
= usbredir_handle_data
,
1218 .handle_control
= usbredir_handle_control
,
1219 .qdev
.props
= (Property
[]) {
1220 DEFINE_PROP_CHR("chardev", USBRedirDevice
, cs
),
1221 DEFINE_PROP_UINT8("debug", USBRedirDevice
, debug
, 0),
1222 DEFINE_PROP_END_OF_LIST(),
1226 static void usbredir_register_devices(void)
1228 usb_qdev_register(&usbredir_dev_info
);
1230 device_init(usbredir_register_devices
);