]> git.proxmox.com Git - mirror_qemu.git/blame - usb-redir.c
usb-redir: Call qemu_chr_fe_open/close
[mirror_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
65f9d986
HG
817 /* Let the backend know we are ready */
818 qemu_chr_fe_open(dev->cs);
69354a83
HG
819 qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
820 usbredir_chardev_read, usbredir_chardev_event, dev);
821
822 return 0;
823}
824
825static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
826{
827 AsyncURB *aurb, *next_aurb;
828 int i;
829
830 QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
831 async_free(dev, aurb);
832 }
833 for (i = 0; i < MAX_ENDPOINTS; i++) {
834 usbredir_free_bufpq(dev, I2EP(i));
835 }
836}
837
838static void usbredir_handle_destroy(USBDevice *udev)
839{
840 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
841
65f9d986 842 qemu_chr_fe_close(dev->cs);
70f24fb6 843 qemu_chr_delete(dev->cs);
69354a83
HG
844 /* Note must be done after qemu_chr_close, as that causes a close event */
845 qemu_bh_delete(dev->open_close_bh);
846
847 qemu_del_timer(dev->attach_timer);
848 qemu_free_timer(dev->attach_timer);
849
850 usbredir_cleanup_device_queues(dev);
851
852 if (dev->parser) {
853 usbredirparser_destroy(dev->parser);
854 }
855}
856
857/*
858 * usbredirparser packet complete callbacks
859 */
860
861static int usbredir_handle_status(USBRedirDevice *dev,
862 int status, int actual_len)
863{
864 switch (status) {
865 case usb_redir_success:
866 return actual_len;
867 case usb_redir_stall:
868 return USB_RET_STALL;
869 case usb_redir_cancelled:
870 WARNING("returning cancelled packet to HC?\n");
871 case usb_redir_inval:
872 case usb_redir_ioerror:
873 case usb_redir_timeout:
874 default:
875 return USB_RET_NAK;
876 }
877}
878
879static void usbredir_device_connect(void *priv,
880 struct usb_redir_device_connect_header *device_connect)
881{
882 USBRedirDevice *dev = priv;
883
884 switch (device_connect->speed) {
885 case usb_redir_speed_low:
886 DPRINTF("attaching low speed device\n");
887 dev->dev.speed = USB_SPEED_LOW;
888 break;
889 case usb_redir_speed_full:
890 DPRINTF("attaching full speed device\n");
891 dev->dev.speed = USB_SPEED_FULL;
892 break;
893 case usb_redir_speed_high:
894 DPRINTF("attaching high speed device\n");
895 dev->dev.speed = USB_SPEED_HIGH;
896 break;
897 case usb_redir_speed_super:
898 DPRINTF("attaching super speed device\n");
899 dev->dev.speed = USB_SPEED_SUPER;
900 break;
901 default:
902 DPRINTF("attaching unknown speed device, assuming full speed\n");
903 dev->dev.speed = USB_SPEED_FULL;
904 }
905 dev->dev.speedmask = (1 << dev->dev.speed);
906 qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
907}
908
909static void usbredir_device_disconnect(void *priv)
910{
911 USBRedirDevice *dev = priv;
912
913 /* Stop any pending attaches */
914 qemu_del_timer(dev->attach_timer);
915
916 if (dev->dev.attached) {
917 usb_device_detach(&dev->dev);
918 usbredir_cleanup_device_queues(dev);
919 /*
920 * Delay next usb device attach to give the guest a chance to see
921 * see the detach / attach in case of quick close / open succession
922 */
923 dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
924 }
925}
926
927static void usbredir_interface_info(void *priv,
928 struct usb_redir_interface_info_header *interface_info)
929{
930 /* The intention is to allow specifying acceptable interface classes
931 for redirection on the cmdline and in the future verify this here,
932 and disconnect (or never connect) the device if a not accepted
933 interface class is detected */
934}
935
936static void usbredir_ep_info(void *priv,
937 struct usb_redir_ep_info_header *ep_info)
938{
939 USBRedirDevice *dev = priv;
940 int i;
941
942 for (i = 0; i < MAX_ENDPOINTS; i++) {
943 dev->endpoint[i].type = ep_info->type[i];
944 dev->endpoint[i].interval = ep_info->interval[i];
945 dev->endpoint[i].interface = ep_info->interface[i];
946 if (dev->endpoint[i].type != usb_redir_type_invalid) {
947 DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
948 dev->endpoint[i].type, dev->endpoint[i].interface);
949 }
950 }
951}
952
953static void usbredir_configuration_status(void *priv, uint32_t id,
954 struct usb_redir_configuration_status_header *config_status)
955{
956 USBRedirDevice *dev = priv;
957 AsyncURB *aurb;
958 int len = 0;
959
960 DPRINTF("set config status %d config %d id %u\n", config_status->status,
961 config_status->configuration, id);
962
963 aurb = async_find(dev, id);
964 if (!aurb) {
965 return;
966 }
967 if (aurb->packet) {
968 if (aurb->get) {
969 dev->dev.data_buf[0] = config_status->configuration;
970 len = 1;
971 }
4f4321c1 972 aurb->packet->result =
69354a83
HG
973 usbredir_handle_status(dev, config_status->status, len);
974 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
975 }
976 async_free(dev, aurb);
977}
978
979static void usbredir_alt_setting_status(void *priv, uint32_t id,
980 struct usb_redir_alt_setting_status_header *alt_setting_status)
981{
982 USBRedirDevice *dev = priv;
983 AsyncURB *aurb;
984 int len = 0;
985
986 DPRINTF("alt status %d intf %d alt %d id: %u\n",
987 alt_setting_status->status,
988 alt_setting_status->interface,
989 alt_setting_status->alt, id);
990
991 aurb = async_find(dev, id);
992 if (!aurb) {
993 return;
994 }
995 if (aurb->packet) {
996 if (aurb->get) {
997 dev->dev.data_buf[0] = alt_setting_status->alt;
998 len = 1;
999 }
4f4321c1 1000 aurb->packet->result =
69354a83
HG
1001 usbredir_handle_status(dev, alt_setting_status->status, len);
1002 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1003 }
1004 async_free(dev, aurb);
1005}
1006
1007static void usbredir_iso_stream_status(void *priv, uint32_t id,
1008 struct usb_redir_iso_stream_status_header *iso_stream_status)
1009{
1010 USBRedirDevice *dev = priv;
1011 uint8_t ep = iso_stream_status->endpoint;
1012
1013 DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1014 ep, id);
1015
1016 dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
1017 if (iso_stream_status->status == usb_redir_stall) {
1018 DPRINTF("iso stream stopped by peer ep %02X\n", ep);
1019 dev->endpoint[EP2I(ep)].iso_started = 0;
1020 }
1021}
1022
1023static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1024 struct usb_redir_interrupt_receiving_status_header
1025 *interrupt_receiving_status)
1026{
1027 USBRedirDevice *dev = priv;
1028 uint8_t ep = interrupt_receiving_status->endpoint;
1029
1030 DPRINTF("interrupt recv status %d ep %02X id %u\n",
1031 interrupt_receiving_status->status, ep, id);
1032
1033 dev->endpoint[EP2I(ep)].interrupt_error =
1034 interrupt_receiving_status->status;
1035 if (interrupt_receiving_status->status == usb_redir_stall) {
1036 DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep);
1037 dev->endpoint[EP2I(ep)].interrupt_started = 0;
1038 }
1039}
1040
1041static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1042 struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1043{
1044}
1045
1046static void usbredir_control_packet(void *priv, uint32_t id,
1047 struct usb_redir_control_packet_header *control_packet,
1048 uint8_t *data, int data_len)
1049{
1050 USBRedirDevice *dev = priv;
1051 int len = control_packet->length;
1052 AsyncURB *aurb;
1053
1054 DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1055 len, id);
1056
1057 aurb = async_find(dev, id);
1058 if (!aurb) {
1059 free(data);
1060 return;
1061 }
1062
1063 aurb->control_packet.status = control_packet->status;
1064 aurb->control_packet.length = control_packet->length;
1065 if (memcmp(&aurb->control_packet, control_packet,
1066 sizeof(*control_packet))) {
1067 ERROR("return control packet mismatch, please report this!\n");
1068 len = USB_RET_NAK;
1069 }
1070
1071 if (aurb->packet) {
1072 len = usbredir_handle_status(dev, control_packet->status, len);
1073 if (len > 0) {
1074 usbredir_log_data(dev, "ctrl data in:", data, data_len);
1075 if (data_len <= sizeof(dev->dev.data_buf)) {
1076 memcpy(dev->dev.data_buf, data, data_len);
1077 } else {
1078 ERROR("ctrl buffer too small (%d > %zu)\n",
1079 data_len, sizeof(dev->dev.data_buf));
1080 len = USB_RET_STALL;
1081 }
1082 }
4f4321c1 1083 aurb->packet->result = len;
69354a83
HG
1084 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1085 }
1086 async_free(dev, aurb);
1087 free(data);
1088}
1089
1090static void usbredir_bulk_packet(void *priv, uint32_t id,
1091 struct usb_redir_bulk_packet_header *bulk_packet,
1092 uint8_t *data, int data_len)
1093{
1094 USBRedirDevice *dev = priv;
1095 uint8_t ep = bulk_packet->endpoint;
1096 int len = bulk_packet->length;
1097 AsyncURB *aurb;
1098
1099 DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1100 ep, len, id);
1101
1102 aurb = async_find(dev, id);
1103 if (!aurb) {
1104 free(data);
1105 return;
1106 }
1107
1108 if (aurb->bulk_packet.endpoint != bulk_packet->endpoint ||
1109 aurb->bulk_packet.stream_id != bulk_packet->stream_id) {
1110 ERROR("return bulk packet mismatch, please report this!\n");
1111 len = USB_RET_NAK;
1112 }
1113
1114 if (aurb->packet) {
1115 len = usbredir_handle_status(dev, bulk_packet->status, len);
1116 if (len > 0) {
1117 usbredir_log_data(dev, "bulk data in:", data, data_len);
4f4321c1
GH
1118 if (data_len <= aurb->packet->iov.size) {
1119 usb_packet_copy(aurb->packet, data, data_len);
69354a83 1120 } else {
4f4321c1
GH
1121 ERROR("bulk buffer too small (%d > %zd)\n", data_len,
1122 aurb->packet->iov.size);
69354a83
HG
1123 len = USB_RET_STALL;
1124 }
1125 }
4f4321c1 1126 aurb->packet->result = len;
69354a83
HG
1127 usb_packet_complete(&dev->dev, aurb->packet);
1128 }
1129 async_free(dev, aurb);
1130 free(data);
1131}
1132
1133static void usbredir_iso_packet(void *priv, uint32_t id,
1134 struct usb_redir_iso_packet_header *iso_packet,
1135 uint8_t *data, int data_len)
1136{
1137 USBRedirDevice *dev = priv;
1138 uint8_t ep = iso_packet->endpoint;
1139
1140 DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1141 data_len, id);
1142
1143 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1144 ERROR("received iso packet for non iso endpoint %02X\n", ep);
1145 free(data);
1146 return;
1147 }
1148
1149 if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1150 DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1151 free(data);
1152 return;
1153 }
1154
1155 /* bufp_alloc also adds the packet to the ep queue */
1156 bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1157}
1158
1159static void usbredir_interrupt_packet(void *priv, uint32_t id,
1160 struct usb_redir_interrupt_packet_header *interrupt_packet,
1161 uint8_t *data, int data_len)
1162{
1163 USBRedirDevice *dev = priv;
1164 uint8_t ep = interrupt_packet->endpoint;
1165
1166 DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1167 interrupt_packet->status, ep, data_len, id);
1168
1169 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
1170 ERROR("received int packet for non interrupt endpoint %02X\n", ep);
1171 free(data);
1172 return;
1173 }
1174
1175 if (ep & USB_DIR_IN) {
1176 if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
1177 DPRINTF("received int packet while not started ep %02X\n", ep);
1178 free(data);
1179 return;
1180 }
1181
1182 /* bufp_alloc also adds the packet to the ep queue */
1183 bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
1184 } else {
1185 int len = interrupt_packet->length;
1186
1187 AsyncURB *aurb = async_find(dev, id);
1188 if (!aurb) {
1189 return;
1190 }
1191
1192 if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
1193 ERROR("return int packet mismatch, please report this!\n");
1194 len = USB_RET_NAK;
1195 }
1196
1197 if (aurb->packet) {
4f4321c1 1198 aurb->packet->result = usbredir_handle_status(dev,
69354a83
HG
1199 interrupt_packet->status, len);
1200 usb_packet_complete(&dev->dev, aurb->packet);
1201 }
1202 async_free(dev, aurb);
1203 }
1204}
1205
1206static struct USBDeviceInfo usbredir_dev_info = {
1207 .product_desc = "USB Redirection Device",
1208 .qdev.name = "usb-redir",
1209 .qdev.size = sizeof(USBRedirDevice),
1210 .init = usbredir_initfn,
1211 .handle_destroy = usbredir_handle_destroy,
1212 .handle_packet = usb_generic_handle_packet,
1213 .cancel_packet = usbredir_cancel_packet,
1214 .handle_reset = usbredir_handle_reset,
1215 .handle_data = usbredir_handle_data,
1216 .handle_control = usbredir_handle_control,
1217 .qdev.props = (Property[]) {
1218 DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
1219 DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
1220 DEFINE_PROP_END_OF_LIST(),
1221 },
1222};
1223
1224static void usbredir_register_devices(void)
1225{
1226 usb_qdev_register(&usbredir_dev_info);
1227}
1228device_init(usbredir_register_devices);