]> git.proxmox.com Git - qemu.git/blame - usb-redir.c
char: qemu_chr_open_opts() -> qemu_chr_new_from_opts()
[qemu.git] / usb-redir.c
CommitLineData
69354a83
HG
1/*
2 * USB redirector usb-guest
3 *
4 * Copyright (c) 2011 Red Hat, Inc.
5 *
6 * Red Hat Authors:
7 * Hans de Goede <hdegoede@redhat.com>
8 *
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:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28#include "qemu-common.h"
29#include "qemu-timer.h"
30#include "monitor.h"
31#include "sysemu.h"
32
33#include <dirent.h>
34#include <sys/ioctl.h>
35#include <signal.h>
36#include <usbredirparser.h>
37
38#include "hw/usb.h"
39
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))
43
44typedef struct AsyncURB AsyncURB;
45typedef struct USBRedirDevice USBRedirDevice;
46
47/* Struct to hold buffered packets (iso or int input packets) */
48struct buf_packet {
49 uint8_t *data;
50 int len;
51 int status;
52 QTAILQ_ENTRY(buf_packet)next;
53};
54
55struct endp_data {
56 uint8_t type;
57 uint8_t interval;
58 uint8_t interface; /* bInterfaceNumber this ep belongs to */
59 uint8_t iso_started;
60 uint8_t iso_error; /* For reporting iso errors to the HC */
61 uint8_t interrupt_started;
62 uint8_t interrupt_error;
63 QTAILQ_HEAD(, buf_packet) bufpq;
64};
65
66struct USBRedirDevice {
67 USBDevice dev;
68 /* Properties */
69 CharDriverState *cs;
70 uint8_t debug;
71 /* Data passed from chardev the fd_read cb to the usbredirparser read cb */
72 const uint8_t *read_buf;
73 int read_buf_size;
74 /* For async handling of open/close */
75 QEMUBH *open_close_bh;
76 /* To delay the usb attach in case of quick chardev close + open */
77 QEMUTimer *attach_timer;
78 int64_t next_attach_time;
79 struct usbredirparser *parser;
80 struct endp_data endpoint[MAX_ENDPOINTS];
81 uint32_t packet_id;
82 QTAILQ_HEAD(, AsyncURB) asyncq;
83};
84
85struct AsyncURB {
86 USBRedirDevice *dev;
87 USBPacket *packet;
88 uint32_t packet_id;
89 int get;
90 union {
91 struct usb_redir_control_packet_header control_packet;
92 struct usb_redir_bulk_packet_header bulk_packet;
93 struct usb_redir_interrupt_packet_header interrupt_packet;
94 };
95 QTAILQ_ENTRY(AsyncURB)next;
96};
97
98static void usbredir_device_connect(void *priv,
99 struct usb_redir_device_connect_header *device_connect);
100static void usbredir_device_disconnect(void *priv);
101static void usbredir_interface_info(void *priv,
102 struct usb_redir_interface_info_header *interface_info);
103static void usbredir_ep_info(void *priv,
104 struct usb_redir_ep_info_header *ep_info);
105static void usbredir_configuration_status(void *priv, uint32_t id,
106 struct usb_redir_configuration_status_header *configuration_status);
107static void usbredir_alt_setting_status(void *priv, uint32_t id,
108 struct usb_redir_alt_setting_status_header *alt_setting_status);
109static void usbredir_iso_stream_status(void *priv, uint32_t id,
110 struct usb_redir_iso_stream_status_header *iso_stream_status);
111static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
112 struct usb_redir_interrupt_receiving_status_header
113 *interrupt_receiving_status);
114static void usbredir_bulk_streams_status(void *priv, uint32_t id,
115 struct usb_redir_bulk_streams_status_header *bulk_streams_status);
116static 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);
119static 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);
122static 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);
125static 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);
128
129static int usbredir_handle_status(USBRedirDevice *dev,
130 int status, int actual_len);
131
132#define VERSION "qemu usb-redir guest " QEMU_VERSION
133
134/*
135 * Logging stuff
136 */
137
138#define ERROR(...) \
139 do { \
140 if (dev->debug >= usbredirparser_error) { \
141 error_report("usb-redir error: " __VA_ARGS__); \
142 } \
143 } while (0)
144#define WARNING(...) \
145 do { \
146 if (dev->debug >= usbredirparser_warning) { \
147 error_report("usb-redir warning: " __VA_ARGS__); \
148 } \
149 } while (0)
150#define INFO(...) \
151 do { \
152 if (dev->debug >= usbredirparser_info) { \
153 error_report("usb-redir: " __VA_ARGS__); \
154 } \
155 } while (0)
156#define DPRINTF(...) \
157 do { \
158 if (dev->debug >= usbredirparser_debug) { \
159 error_report("usb-redir: " __VA_ARGS__); \
160 } \
161 } while (0)
162#define DPRINTF2(...) \
163 do { \
164 if (dev->debug >= usbredirparser_debug_data) { \
165 error_report("usb-redir: " __VA_ARGS__); \
166 } \
167 } while (0)
168
169static void usbredir_log(void *priv, int level, const char *msg)
170{
171 USBRedirDevice *dev = priv;
172
173 if (dev->debug < level) {
174 return;
175 }
176
177 error_report("%s\n", msg);
178}
179
180static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
181 const uint8_t *data, int len)
182{
183 int i, j, n;
184
185 if (dev->debug < usbredirparser_debug_data) {
186 return;
187 }
188
189 for (i = 0; i < len; i += j) {
190 char buf[128];
191
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]);
195 }
196 error_report("%s\n", buf);
197 }
198}
199
200/*
201 * usbredirparser io functions
202 */
203
204static int usbredir_read(void *priv, uint8_t *data, int count)
205{
206 USBRedirDevice *dev = priv;
207
208 if (dev->read_buf_size < count) {
209 count = dev->read_buf_size;
210 }
211
212 memcpy(data, dev->read_buf, count);
213
214 dev->read_buf_size -= count;
215 if (dev->read_buf_size) {
216 dev->read_buf += count;
217 } else {
218 dev->read_buf = NULL;
219 }
220
221 return count;
222}
223
224static int usbredir_write(void *priv, uint8_t *data, int count)
225{
226 USBRedirDevice *dev = priv;
227
2cc6e0a1 228 return qemu_chr_fe_write(dev->cs, data, count);
69354a83
HG
229}
230
231/*
232 * Async and buffered packets helpers
233 */
234
235static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
236{
7267c094 237 AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
69354a83
HG
238 aurb->dev = dev;
239 aurb->packet = p;
240 aurb->packet_id = dev->packet_id;
241 QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
242 dev->packet_id++;
243
244 return aurb;
245}
246
247static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
248{
249 QTAILQ_REMOVE(&dev->asyncq, aurb, next);
7267c094 250 g_free(aurb);
69354a83
HG
251}
252
253static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
254{
255 AsyncURB *aurb;
256
257 QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
258 if (aurb->packet_id == packet_id) {
259 return aurb;
260 }
261 }
262 ERROR("could not find async urb for packet_id %u\n", packet_id);
263 return NULL;
264}
265
266static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
267{
268 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
269 AsyncURB *aurb;
270
271 QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
272 if (p != aurb->packet) {
273 continue;
274 }
275
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);
279
280 /* Mark it as dead */
281 aurb->packet = NULL;
282 break;
283 }
284}
285
286static struct buf_packet *bufp_alloc(USBRedirDevice *dev,
287 uint8_t *data, int len, int status, uint8_t ep)
288{
7267c094 289 struct buf_packet *bufp = g_malloc(sizeof(struct buf_packet));
69354a83
HG
290 bufp->data = data;
291 bufp->len = len;
292 bufp->status = status;
293 QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
294 return bufp;
295}
296
297static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
298 uint8_t ep)
299{
300 QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
301 free(bufp->data);
7267c094 302 g_free(bufp);
69354a83
HG
303}
304
305static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
306{
307 struct buf_packet *buf, *buf_next;
308
309 QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) {
310 bufp_free(dev, buf, ep);
311 }
312}
313
314/*
315 * USBDevice callbacks
316 */
317
318static void usbredir_handle_reset(USBDevice *udev)
319{
320 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
321
322 DPRINTF("reset device\n");
323 usbredirparser_send_reset(dev->parser);
324 usbredirparser_do_write(dev->parser);
325}
326
327static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
328 uint8_t ep)
329{
330 int status, len;
331
332 if (!dev->endpoint[EP2I(ep)].iso_started &&
333 !dev->endpoint[EP2I(ep)].iso_error) {
334 struct usb_redir_start_iso_stream_header start_iso = {
335 .endpoint = ep,
336 /* TODO maybe do something with these depending on ep interval? */
337 .pkts_per_urb = 32,
338 .no_urbs = 3,
339 };
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;
345 }
346
347 if (ep & USB_DIR_IN) {
348 struct buf_packet *isop;
349
350 isop = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
351 if (isop == NULL) {
352 DPRINTF2("iso-token-in ep %02X, no isop\n", ep);
353 /* Check iso_error for stream errors, otherwise its an underrun */
354 status = dev->endpoint[EP2I(ep)].iso_error;
355 dev->endpoint[EP2I(ep)].iso_error = 0;
356 return usbredir_handle_status(dev, status, 0);
357 }
358 DPRINTF2("iso-token-in ep %02X status %d len %d\n", ep, isop->status,
359 isop->len);
360
361 status = isop->status;
362 if (status != usb_redir_success) {
363 bufp_free(dev, isop, ep);
364 return usbredir_handle_status(dev, status, 0);
365 }
366
367 len = isop->len;
4f4321c1 368 if (len > p->iov.size) {
69354a83
HG
369 ERROR("received iso data is larger then packet ep %02X\n", ep);
370 bufp_free(dev, isop, ep);
371 return USB_RET_NAK;
372 }
4f4321c1 373 usb_packet_copy(p, isop->data, len);
69354a83
HG
374 bufp_free(dev, isop, ep);
375 return len;
376 } else {
377 /* If the stream was not started because of a pending error don't
378 send the packet to the usb-host */
379 if (dev->endpoint[EP2I(ep)].iso_started) {
380 struct usb_redir_iso_packet_header iso_packet = {
381 .endpoint = ep,
4f4321c1 382 .length = p->iov.size
69354a83 383 };
4f4321c1 384 uint8_t buf[p->iov.size];
69354a83 385 /* No id, we look at the ep when receiving a status back */
4f4321c1 386 usb_packet_copy(p, buf, p->iov.size);
69354a83 387 usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,
4f4321c1 388 buf, p->iov.size);
69354a83
HG
389 usbredirparser_do_write(dev->parser);
390 }
391 status = dev->endpoint[EP2I(ep)].iso_error;
392 dev->endpoint[EP2I(ep)].iso_error = 0;
4f4321c1
GH
393 DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep, status,
394 p->iov.size);
395 return usbredir_handle_status(dev, status, p->iov.size);
69354a83
HG
396 }
397}
398
399static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
400{
401 struct usb_redir_stop_iso_stream_header stop_iso_stream = {
402 .endpoint = ep
403 };
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;
408 }
409 usbredir_free_bufpq(dev, ep);
410}
411
412static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
413 uint8_t ep)
414{
415 AsyncURB *aurb = async_alloc(dev, p);
416 struct usb_redir_bulk_packet_header bulk_packet;
417
4f4321c1
GH
418 DPRINTF("bulk-out ep %02X len %zd id %u\n", ep,
419 p->iov.size, aurb->packet_id);
69354a83
HG
420
421 bulk_packet.endpoint = ep;
4f4321c1 422 bulk_packet.length = p->iov.size;
69354a83
HG
423 bulk_packet.stream_id = 0;
424 aurb->bulk_packet = bulk_packet;
425
426 if (ep & USB_DIR_IN) {
427 usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
428 &bulk_packet, NULL, 0);
429 } else {
4f4321c1
GH
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);
69354a83 433 usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
4f4321c1 434 &bulk_packet, buf, p->iov.size);
69354a83
HG
435 }
436 usbredirparser_do_write(dev->parser);
437 return USB_RET_ASYNC;
438}
439
440static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
441 USBPacket *p, uint8_t ep)
442{
443 if (ep & USB_DIR_IN) {
444 /* Input interrupt endpoint, buffered packet input */
445 struct buf_packet *intp;
446 int status, len;
447
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 = {
451 .endpoint = ep,
452 };
453 /* No id, we look at the ep when receiving a status back */
454 usbredirparser_send_start_interrupt_receiving(dev->parser, 0,
455 &start_int);
456 usbredirparser_do_write(dev->parser);
457 DPRINTF("interrupt recv started ep %02X\n", ep);
458 dev->endpoint[EP2I(ep)].interrupt_started = 1;
459 }
460
461 intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
462 if (intp == NULL) {
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);
468 }
469 DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,
470 intp->status, intp->len);
471
472 status = intp->status;
473 if (status != usb_redir_success) {
474 bufp_free(dev, intp, ep);
475 return usbredir_handle_status(dev, status, 0);
476 }
477
478 len = intp->len;
4f4321c1 479 if (len > p->iov.size) {
69354a83
HG
480 ERROR("received int data is larger then packet ep %02X\n", ep);
481 bufp_free(dev, intp, ep);
482 return USB_RET_NAK;
483 }
4f4321c1 484 usb_packet_copy(p, intp->data, len);
69354a83
HG
485 bufp_free(dev, intp, ep);
486 return len;
487 } else {
488 /* Output interrupt endpoint, normal async operation */
489 AsyncURB *aurb = async_alloc(dev, p);
490 struct usb_redir_interrupt_packet_header interrupt_packet;
4f4321c1 491 uint8_t buf[p->iov.size];
69354a83 492
4f4321c1 493 DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep, p->iov.size,
69354a83
HG
494 aurb->packet_id);
495
496 interrupt_packet.endpoint = ep;
4f4321c1 497 interrupt_packet.length = p->iov.size;
69354a83
HG
498 aurb->interrupt_packet = interrupt_packet;
499
4f4321c1
GH
500 usb_packet_copy(p, buf, p->iov.size);
501 usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);
69354a83 502 usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
4f4321c1 503 &interrupt_packet, buf, p->iov.size);
69354a83
HG
504 usbredirparser_do_write(dev->parser);
505 return USB_RET_ASYNC;
506 }
507}
508
509static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev,
510 uint8_t ep)
511{
512 struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv = {
513 .endpoint = ep
514 };
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;
520 }
521 usbredir_free_bufpq(dev, ep);
522}
523
524static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
525{
526 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
527 uint8_t ep;
528
529 ep = p->devep;
530 if (p->pid == USB_TOKEN_IN) {
531 ep |= USB_DIR_IN;
532 }
533
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);
537 return USB_RET_NAK;
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);;
544 default:
545 ERROR("handle_data ep %02X has unknown type %d\n", ep,
546 dev->endpoint[EP2I(ep)].type);
547 return USB_RET_NAK;
548 }
549}
550
551static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
552 int config)
553{
554 struct usb_redir_set_configuration_header set_config;
555 AsyncURB *aurb = async_alloc(dev, p);
556 int i;
557
558 DPRINTF("set config %d id %u\n", config, aurb->packet_id);
559
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));
564 break;
565 case USB_ENDPOINT_XFER_INT:
566 if (i & 0x10) {
567 usbredir_stop_interrupt_receiving(dev, I2EP(i));
568 }
569 break;
570 }
571 usbredir_free_bufpq(dev, I2EP(i));
572 }
573
574 set_config.configuration = config;
575 usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
576 &set_config);
577 usbredirparser_do_write(dev->parser);
578 return USB_RET_ASYNC;
579}
580
581static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
582{
583 AsyncURB *aurb = async_alloc(dev, p);
584
585 DPRINTF("get config id %u\n", aurb->packet_id);
586
587 aurb->get = 1;
588 usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
589 usbredirparser_do_write(dev->parser);
590 return USB_RET_ASYNC;
591}
592
593static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
594 int interface, int alt)
595{
596 struct usb_redir_set_alt_setting_header set_alt;
597 AsyncURB *aurb = async_alloc(dev, p);
598 int i;
599
600 DPRINTF("set interface %d alt %d id %u\n", interface, alt,
601 aurb->packet_id);
602
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));
608 break;
609 case USB_ENDPOINT_XFER_INT:
610 if (i & 0x10) {
611 usbredir_stop_interrupt_receiving(dev, I2EP(i));
612 }
613 break;
614 }
615 usbredir_free_bufpq(dev, I2EP(i));
616 }
617 }
618
619 set_alt.interface = interface;
620 set_alt.alt = alt;
621 usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
622 &set_alt);
623 usbredirparser_do_write(dev->parser);
624 return USB_RET_ASYNC;
625}
626
627static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
628 int interface)
629{
630 struct usb_redir_get_alt_setting_header get_alt;
631 AsyncURB *aurb = async_alloc(dev, p);
632
633 DPRINTF("get interface %d id %u\n", interface, aurb->packet_id);
634
635 get_alt.interface = interface;
636 aurb->get = 1;
637 usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
638 &get_alt);
639 usbredirparser_do_write(dev->parser);
640 return USB_RET_ASYNC;
641}
642
643static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
644 int request, int value, int index, int length, uint8_t *data)
645{
646 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
647 struct usb_redir_control_packet_header control_packet;
648 AsyncURB *aurb;
649
650 /* Special cases for certain standard device requests */
651 switch (request) {
652 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
653 DPRINTF("set address %d\n", value);
654 dev->dev.addr = value;
655 return 0;
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);
664 }
665
666 /* "Normal" ctrl requests */
667 aurb = async_alloc(dev, p);
668
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,
672 aurb->packet_id);
673
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;
681
682 if (control_packet.requesttype & USB_DIR_IN) {
683 usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
684 &control_packet, NULL, 0);
685 } else {
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);
689 }
690 usbredirparser_do_write(dev->parser);
691 return USB_RET_ASYNC;
692}
693
694/*
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.
698 *
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.
702 */
703static void usbredir_open_close_bh(void *opaque)
704{
705 USBRedirDevice *dev = opaque;
706
707 usbredir_device_disconnect(dev);
708
709 if (dev->parser) {
710 usbredirparser_destroy(dev->parser);
711 dev->parser = NULL;
712 }
713
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);
738 }
739}
740
741static void usbredir_do_attach(void *opaque)
742{
743 USBRedirDevice *dev = opaque;
744
745 usb_device_attach(&dev->dev);
746}
747
748/*
749 * chardev callbacks
750 */
751
752static int usbredir_chardev_can_read(void *opaque)
753{
754 USBRedirDevice *dev = opaque;
755
756 if (dev->parser) {
757 /* usbredir_parser_do_read will consume *all* data we give it */
758 return 1024 * 1024;
759 } else {
760 /* usbredir_open_close_bh hasn't handled the open event yet */
761 return 0;
762 }
763}
764
765static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
766{
767 USBRedirDevice *dev = opaque;
768
769 /* No recursion allowed! */
770 assert(dev->read_buf == NULL);
771
772 dev->read_buf = buf;
773 dev->read_buf_size = size;
774
775 usbredirparser_do_read(dev->parser);
776 /* Send any acks, etc. which may be queued now */
777 usbredirparser_do_write(dev->parser);
778}
779
780static void usbredir_chardev_event(void *opaque, int event)
781{
782 USBRedirDevice *dev = opaque;
783
784 switch (event) {
785 case CHR_EVENT_OPENED:
786 case CHR_EVENT_CLOSED:
787 qemu_bh_schedule(dev->open_close_bh);
788 break;
789 }
790}
791
792/*
793 * init + destroy
794 */
795
796static int usbredir_initfn(USBDevice *udev)
797{
798 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
799 int i;
800
801 if (dev->cs == NULL) {
802 qerror_report(QERR_MISSING_PARAMETER, "chardev");
803 return -1;
804 }
805
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);
808
809 QTAILQ_INIT(&dev->asyncq);
810 for (i = 0; i < MAX_ENDPOINTS; i++) {
811 QTAILQ_INIT(&dev->endpoint[i].bufpq);
812 }
813
814 /* We'll do the attach once we receive the speed from the usb-host */
815 udev->auto_attach = 0;
816
817 qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
818 usbredir_chardev_read, usbredir_chardev_event, dev);
819
820 return 0;
821}
822
823static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
824{
825 AsyncURB *aurb, *next_aurb;
826 int i;
827
828 QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
829 async_free(dev, aurb);
830 }
831 for (i = 0; i < MAX_ENDPOINTS; i++) {
832 usbredir_free_bufpq(dev, I2EP(i));
833 }
834}
835
836static void usbredir_handle_destroy(USBDevice *udev)
837{
838 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
839
840 qemu_chr_close(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);
843
844 qemu_del_timer(dev->attach_timer);
845 qemu_free_timer(dev->attach_timer);
846
847 usbredir_cleanup_device_queues(dev);
848
849 if (dev->parser) {
850 usbredirparser_destroy(dev->parser);
851 }
852}
853
854/*
855 * usbredirparser packet complete callbacks
856 */
857
858static int usbredir_handle_status(USBRedirDevice *dev,
859 int status, int actual_len)
860{
861 switch (status) {
862 case usb_redir_success:
863 return actual_len;
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:
871 default:
872 return USB_RET_NAK;
873 }
874}
875
876static void usbredir_device_connect(void *priv,
877 struct usb_redir_device_connect_header *device_connect)
878{
879 USBRedirDevice *dev = priv;
880
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;
885 break;
886 case usb_redir_speed_full:
887 DPRINTF("attaching full speed device\n");
888 dev->dev.speed = USB_SPEED_FULL;
889 break;
890 case usb_redir_speed_high:
891 DPRINTF("attaching high speed device\n");
892 dev->dev.speed = USB_SPEED_HIGH;
893 break;
894 case usb_redir_speed_super:
895 DPRINTF("attaching super speed device\n");
896 dev->dev.speed = USB_SPEED_SUPER;
897 break;
898 default:
899 DPRINTF("attaching unknown speed device, assuming full speed\n");
900 dev->dev.speed = USB_SPEED_FULL;
901 }
902 dev->dev.speedmask = (1 << dev->dev.speed);
903 qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
904}
905
906static void usbredir_device_disconnect(void *priv)
907{
908 USBRedirDevice *dev = priv;
909
910 /* Stop any pending attaches */
911 qemu_del_timer(dev->attach_timer);
912
913 if (dev->dev.attached) {
914 usb_device_detach(&dev->dev);
915 usbredir_cleanup_device_queues(dev);
916 /*
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
919 */
920 dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
921 }
922}
923
924static void usbredir_interface_info(void *priv,
925 struct usb_redir_interface_info_header *interface_info)
926{
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 */
931}
932
933static void usbredir_ep_info(void *priv,
934 struct usb_redir_ep_info_header *ep_info)
935{
936 USBRedirDevice *dev = priv;
937 int i;
938
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);
946 }
947 }
948}
949
950static void usbredir_configuration_status(void *priv, uint32_t id,
951 struct usb_redir_configuration_status_header *config_status)
952{
953 USBRedirDevice *dev = priv;
954 AsyncURB *aurb;
955 int len = 0;
956
957 DPRINTF("set config status %d config %d id %u\n", config_status->status,
958 config_status->configuration, id);
959
960 aurb = async_find(dev, id);
961 if (!aurb) {
962 return;
963 }
964 if (aurb->packet) {
965 if (aurb->get) {
966 dev->dev.data_buf[0] = config_status->configuration;
967 len = 1;
968 }
4f4321c1 969 aurb->packet->result =
69354a83
HG
970 usbredir_handle_status(dev, config_status->status, len);
971 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
972 }
973 async_free(dev, aurb);
974}
975
976static void usbredir_alt_setting_status(void *priv, uint32_t id,
977 struct usb_redir_alt_setting_status_header *alt_setting_status)
978{
979 USBRedirDevice *dev = priv;
980 AsyncURB *aurb;
981 int len = 0;
982
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);
987
988 aurb = async_find(dev, id);
989 if (!aurb) {
990 return;
991 }
992 if (aurb->packet) {
993 if (aurb->get) {
994 dev->dev.data_buf[0] = alt_setting_status->alt;
995 len = 1;
996 }
4f4321c1 997 aurb->packet->result =
69354a83
HG
998 usbredir_handle_status(dev, alt_setting_status->status, len);
999 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1000 }
1001 async_free(dev, aurb);
1002}
1003
1004static void usbredir_iso_stream_status(void *priv, uint32_t id,
1005 struct usb_redir_iso_stream_status_header *iso_stream_status)
1006{
1007 USBRedirDevice *dev = priv;
1008 uint8_t ep = iso_stream_status->endpoint;
1009
1010 DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1011 ep, id);
1012
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;
1017 }
1018}
1019
1020static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1021 struct usb_redir_interrupt_receiving_status_header
1022 *interrupt_receiving_status)
1023{
1024 USBRedirDevice *dev = priv;
1025 uint8_t ep = interrupt_receiving_status->endpoint;
1026
1027 DPRINTF("interrupt recv status %d ep %02X id %u\n",
1028 interrupt_receiving_status->status, ep, id);
1029
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;
1035 }
1036}
1037
1038static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1039 struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1040{
1041}
1042
1043static 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)
1046{
1047 USBRedirDevice *dev = priv;
1048 int len = control_packet->length;
1049 AsyncURB *aurb;
1050
1051 DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1052 len, id);
1053
1054 aurb = async_find(dev, id);
1055 if (!aurb) {
1056 free(data);
1057 return;
1058 }
1059
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");
1065 len = USB_RET_NAK;
1066 }
1067
1068 if (aurb->packet) {
1069 len = usbredir_handle_status(dev, control_packet->status, len);
1070 if (len > 0) {
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);
1074 } else {
1075 ERROR("ctrl buffer too small (%d > %zu)\n",
1076 data_len, sizeof(dev->dev.data_buf));
1077 len = USB_RET_STALL;
1078 }
1079 }
4f4321c1 1080 aurb->packet->result = len;
69354a83
HG
1081 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1082 }
1083 async_free(dev, aurb);
1084 free(data);
1085}
1086
1087static 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)
1090{
1091 USBRedirDevice *dev = priv;
1092 uint8_t ep = bulk_packet->endpoint;
1093 int len = bulk_packet->length;
1094 AsyncURB *aurb;
1095
1096 DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1097 ep, len, id);
1098
1099 aurb = async_find(dev, id);
1100 if (!aurb) {
1101 free(data);
1102 return;
1103 }
1104
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");
1108 len = USB_RET_NAK;
1109 }
1110
1111 if (aurb->packet) {
1112 len = usbredir_handle_status(dev, bulk_packet->status, len);
1113 if (len > 0) {
1114 usbredir_log_data(dev, "bulk data in:", data, data_len);
4f4321c1
GH
1115 if (data_len <= aurb->packet->iov.size) {
1116 usb_packet_copy(aurb->packet, data, data_len);
69354a83 1117 } else {
4f4321c1
GH
1118 ERROR("bulk buffer too small (%d > %zd)\n", data_len,
1119 aurb->packet->iov.size);
69354a83
HG
1120 len = USB_RET_STALL;
1121 }
1122 }
4f4321c1 1123 aurb->packet->result = len;
69354a83
HG
1124 usb_packet_complete(&dev->dev, aurb->packet);
1125 }
1126 async_free(dev, aurb);
1127 free(data);
1128}
1129
1130static 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)
1133{
1134 USBRedirDevice *dev = priv;
1135 uint8_t ep = iso_packet->endpoint;
1136
1137 DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1138 data_len, id);
1139
1140 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1141 ERROR("received iso packet for non iso endpoint %02X\n", ep);
1142 free(data);
1143 return;
1144 }
1145
1146 if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1147 DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1148 free(data);
1149 return;
1150 }
1151
1152 /* bufp_alloc also adds the packet to the ep queue */
1153 bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1154}
1155
1156static 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)
1159{
1160 USBRedirDevice *dev = priv;
1161 uint8_t ep = interrupt_packet->endpoint;
1162
1163 DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1164 interrupt_packet->status, ep, data_len, id);
1165
1166 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
1167 ERROR("received int packet for non interrupt endpoint %02X\n", ep);
1168 free(data);
1169 return;
1170 }
1171
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);
1175 free(data);
1176 return;
1177 }
1178
1179 /* bufp_alloc also adds the packet to the ep queue */
1180 bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
1181 } else {
1182 int len = interrupt_packet->length;
1183
1184 AsyncURB *aurb = async_find(dev, id);
1185 if (!aurb) {
1186 return;
1187 }
1188
1189 if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
1190 ERROR("return int packet mismatch, please report this!\n");
1191 len = USB_RET_NAK;
1192 }
1193
1194 if (aurb->packet) {
4f4321c1 1195 aurb->packet->result = usbredir_handle_status(dev,
69354a83
HG
1196 interrupt_packet->status, len);
1197 usb_packet_complete(&dev->dev, aurb->packet);
1198 }
1199 async_free(dev, aurb);
1200 }
1201}
1202
1203static 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(),
1218 },
1219};
1220
1221static void usbredir_register_devices(void)
1222{
1223 usb_qdev_register(&usbredir_dev_info);
1224}
1225device_init(usbredir_register_devices);