]> git.proxmox.com Git - qemu.git/blame - usb-redir.c
Merge remote-tracking branch 'spice/spice.v47' into staging
[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;
e1537884 63 uint8_t bufpq_prefilled;
81fd7b74 64 uint8_t bufpq_dropping_packets;
69354a83 65 QTAILQ_HEAD(, buf_packet) bufpq;
e1537884 66 int bufpq_size;
e8a7dd29 67 int bufpq_target_size;
69354a83
HG
68};
69
70struct USBRedirDevice {
71 USBDevice dev;
72 /* Properties */
73 CharDriverState *cs;
74 uint8_t debug;
75 /* Data passed from chardev the fd_read cb to the usbredirparser read cb */
76 const uint8_t *read_buf;
77 int read_buf_size;
78 /* For async handling of open/close */
79 QEMUBH *open_close_bh;
80 /* To delay the usb attach in case of quick chardev close + open */
81 QEMUTimer *attach_timer;
82 int64_t next_attach_time;
83 struct usbredirparser *parser;
84 struct endp_data endpoint[MAX_ENDPOINTS];
85 uint32_t packet_id;
86 QTAILQ_HEAD(, AsyncURB) asyncq;
87};
88
89struct AsyncURB {
90 USBRedirDevice *dev;
91 USBPacket *packet;
92 uint32_t packet_id;
93 int get;
94 union {
95 struct usb_redir_control_packet_header control_packet;
96 struct usb_redir_bulk_packet_header bulk_packet;
97 struct usb_redir_interrupt_packet_header interrupt_packet;
98 };
99 QTAILQ_ENTRY(AsyncURB)next;
100};
101
102static void usbredir_device_connect(void *priv,
103 struct usb_redir_device_connect_header *device_connect);
104static void usbredir_device_disconnect(void *priv);
105static void usbredir_interface_info(void *priv,
106 struct usb_redir_interface_info_header *interface_info);
107static void usbredir_ep_info(void *priv,
108 struct usb_redir_ep_info_header *ep_info);
109static void usbredir_configuration_status(void *priv, uint32_t id,
110 struct usb_redir_configuration_status_header *configuration_status);
111static void usbredir_alt_setting_status(void *priv, uint32_t id,
112 struct usb_redir_alt_setting_status_header *alt_setting_status);
113static void usbredir_iso_stream_status(void *priv, uint32_t id,
114 struct usb_redir_iso_stream_status_header *iso_stream_status);
115static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
116 struct usb_redir_interrupt_receiving_status_header
117 *interrupt_receiving_status);
118static void usbredir_bulk_streams_status(void *priv, uint32_t id,
119 struct usb_redir_bulk_streams_status_header *bulk_streams_status);
120static void usbredir_control_packet(void *priv, uint32_t id,
121 struct usb_redir_control_packet_header *control_packet,
122 uint8_t *data, int data_len);
123static void usbredir_bulk_packet(void *priv, uint32_t id,
124 struct usb_redir_bulk_packet_header *bulk_packet,
125 uint8_t *data, int data_len);
126static void usbredir_iso_packet(void *priv, uint32_t id,
127 struct usb_redir_iso_packet_header *iso_packet,
128 uint8_t *data, int data_len);
129static void usbredir_interrupt_packet(void *priv, uint32_t id,
130 struct usb_redir_interrupt_packet_header *interrupt_header,
131 uint8_t *data, int data_len);
132
133static int usbredir_handle_status(USBRedirDevice *dev,
134 int status, int actual_len);
135
136#define VERSION "qemu usb-redir guest " QEMU_VERSION
137
138/*
139 * Logging stuff
140 */
141
142#define ERROR(...) \
143 do { \
144 if (dev->debug >= usbredirparser_error) { \
145 error_report("usb-redir error: " __VA_ARGS__); \
146 } \
147 } while (0)
148#define WARNING(...) \
149 do { \
150 if (dev->debug >= usbredirparser_warning) { \
151 error_report("usb-redir warning: " __VA_ARGS__); \
152 } \
153 } while (0)
154#define INFO(...) \
155 do { \
156 if (dev->debug >= usbredirparser_info) { \
157 error_report("usb-redir: " __VA_ARGS__); \
158 } \
159 } while (0)
160#define DPRINTF(...) \
161 do { \
162 if (dev->debug >= usbredirparser_debug) { \
163 error_report("usb-redir: " __VA_ARGS__); \
164 } \
165 } while (0)
166#define DPRINTF2(...) \
167 do { \
168 if (dev->debug >= usbredirparser_debug_data) { \
169 error_report("usb-redir: " __VA_ARGS__); \
170 } \
171 } while (0)
172
173static void usbredir_log(void *priv, int level, const char *msg)
174{
175 USBRedirDevice *dev = priv;
176
177 if (dev->debug < level) {
178 return;
179 }
180
be62a2eb 181 error_report("%s", msg);
69354a83
HG
182}
183
184static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
185 const uint8_t *data, int len)
186{
187 int i, j, n;
188
189 if (dev->debug < usbredirparser_debug_data) {
190 return;
191 }
192
193 for (i = 0; i < len; i += j) {
194 char buf[128];
195
196 n = sprintf(buf, "%s", desc);
197 for (j = 0; j < 8 && i + j < len; j++) {
198 n += sprintf(buf + n, " %02X", data[i + j]);
199 }
be62a2eb 200 error_report("%s", buf);
69354a83
HG
201 }
202}
203
204/*
205 * usbredirparser io functions
206 */
207
208static int usbredir_read(void *priv, uint8_t *data, int count)
209{
210 USBRedirDevice *dev = priv;
211
212 if (dev->read_buf_size < count) {
213 count = dev->read_buf_size;
214 }
215
216 memcpy(data, dev->read_buf, count);
217
218 dev->read_buf_size -= count;
219 if (dev->read_buf_size) {
220 dev->read_buf += count;
221 } else {
222 dev->read_buf = NULL;
223 }
224
225 return count;
226}
227
228static int usbredir_write(void *priv, uint8_t *data, int count)
229{
230 USBRedirDevice *dev = priv;
231
c1b71a1d
HG
232 if (!dev->cs->opened) {
233 return 0;
234 }
235
2cc6e0a1 236 return qemu_chr_fe_write(dev->cs, data, count);
69354a83
HG
237}
238
239/*
240 * Async and buffered packets helpers
241 */
242
243static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
244{
7267c094 245 AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
69354a83
HG
246 aurb->dev = dev;
247 aurb->packet = p;
248 aurb->packet_id = dev->packet_id;
249 QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
250 dev->packet_id++;
251
252 return aurb;
253}
254
255static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
256{
257 QTAILQ_REMOVE(&dev->asyncq, aurb, next);
7267c094 258 g_free(aurb);
69354a83
HG
259}
260
261static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
262{
263 AsyncURB *aurb;
264
265 QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
266 if (aurb->packet_id == packet_id) {
267 return aurb;
268 }
269 }
270 ERROR("could not find async urb for packet_id %u\n", packet_id);
271 return NULL;
272}
273
274static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
275{
276 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
277 AsyncURB *aurb;
278
279 QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
280 if (p != aurb->packet) {
281 continue;
282 }
283
284 DPRINTF("async cancel id %u\n", aurb->packet_id);
285 usbredirparser_send_cancel_data_packet(dev->parser, aurb->packet_id);
286 usbredirparser_do_write(dev->parser);
287
288 /* Mark it as dead */
289 aurb->packet = NULL;
290 break;
291 }
292}
293
81fd7b74 294static void bufp_alloc(USBRedirDevice *dev,
69354a83
HG
295 uint8_t *data, int len, int status, uint8_t ep)
296{
81fd7b74
HG
297 struct buf_packet *bufp;
298
299 if (!dev->endpoint[EP2I(ep)].bufpq_dropping_packets &&
300 dev->endpoint[EP2I(ep)].bufpq_size >
301 2 * dev->endpoint[EP2I(ep)].bufpq_target_size) {
302 DPRINTF("bufpq overflow, dropping packets ep %02X\n", ep);
303 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 1;
304 }
305 /* Since we're interupting the stream anyways, drop enough packets to get
306 back to our target buffer size */
307 if (dev->endpoint[EP2I(ep)].bufpq_dropping_packets) {
308 if (dev->endpoint[EP2I(ep)].bufpq_size >
309 dev->endpoint[EP2I(ep)].bufpq_target_size) {
310 free(data);
311 return;
312 }
313 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
314 }
315
316 bufp = g_malloc(sizeof(struct buf_packet));
69354a83
HG
317 bufp->data = data;
318 bufp->len = len;
319 bufp->status = status;
320 QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
e1537884 321 dev->endpoint[EP2I(ep)].bufpq_size++;
69354a83
HG
322}
323
324static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
325 uint8_t ep)
326{
327 QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
e1537884 328 dev->endpoint[EP2I(ep)].bufpq_size--;
69354a83 329 free(bufp->data);
7267c094 330 g_free(bufp);
69354a83
HG
331}
332
333static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
334{
335 struct buf_packet *buf, *buf_next;
336
337 QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) {
338 bufp_free(dev, buf, ep);
339 }
340}
341
342/*
343 * USBDevice callbacks
344 */
345
346static void usbredir_handle_reset(USBDevice *udev)
347{
348 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
349
350 DPRINTF("reset device\n");
351 usbredirparser_send_reset(dev->parser);
352 usbredirparser_do_write(dev->parser);
353}
354
355static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
356 uint8_t ep)
357{
358 int status, len;
69354a83
HG
359 if (!dev->endpoint[EP2I(ep)].iso_started &&
360 !dev->endpoint[EP2I(ep)].iso_error) {
361 struct usb_redir_start_iso_stream_header start_iso = {
362 .endpoint = ep,
69354a83 363 };
e8a7dd29
HG
364 int pkts_per_sec;
365
366 if (dev->dev.speed == USB_SPEED_HIGH) {
367 pkts_per_sec = 8000 / dev->endpoint[EP2I(ep)].interval;
368 } else {
369 pkts_per_sec = 1000 / dev->endpoint[EP2I(ep)].interval;
370 }
371 /* Testing has shown that we need circa 60 ms buffer */
372 dev->endpoint[EP2I(ep)].bufpq_target_size = (pkts_per_sec * 60) / 1000;
373
374 /* Aim for approx 100 interrupts / second on the client to
375 balance latency and interrupt load */
376 start_iso.pkts_per_urb = pkts_per_sec / 100;
377 if (start_iso.pkts_per_urb < 1) {
378 start_iso.pkts_per_urb = 1;
379 } else if (start_iso.pkts_per_urb > 32) {
380 start_iso.pkts_per_urb = 32;
381 }
382
383 start_iso.no_urbs = (dev->endpoint[EP2I(ep)].bufpq_target_size +
384 start_iso.pkts_per_urb - 1) /
385 start_iso.pkts_per_urb;
386 /* Output endpoints pre-fill only 1/2 of the packets, keeping the rest
387 as overflow buffer. Also see the usbredir protocol documentation */
388 if (!(ep & USB_DIR_IN)) {
389 start_iso.no_urbs *= 2;
390 }
391 if (start_iso.no_urbs > 16) {
392 start_iso.no_urbs = 16;
393 }
394
69354a83
HG
395 /* No id, we look at the ep when receiving a status back */
396 usbredirparser_send_start_iso_stream(dev->parser, 0, &start_iso);
397 usbredirparser_do_write(dev->parser);
32213543
HG
398 DPRINTF("iso stream started pkts/sec %d pkts/urb %d urbs %d ep %02X\n",
399 pkts_per_sec, start_iso.pkts_per_urb, start_iso.no_urbs, ep);
69354a83 400 dev->endpoint[EP2I(ep)].iso_started = 1;
e1537884 401 dev->endpoint[EP2I(ep)].bufpq_prefilled = 0;
81fd7b74 402 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
69354a83
HG
403 }
404
405 if (ep & USB_DIR_IN) {
406 struct buf_packet *isop;
407
e1537884
HG
408 if (dev->endpoint[EP2I(ep)].iso_started &&
409 !dev->endpoint[EP2I(ep)].bufpq_prefilled) {
410 if (dev->endpoint[EP2I(ep)].bufpq_size <
411 dev->endpoint[EP2I(ep)].bufpq_target_size) {
412 return usbredir_handle_status(dev, 0, 0);
413 }
414 dev->endpoint[EP2I(ep)].bufpq_prefilled = 1;
415 }
416
69354a83
HG
417 isop = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
418 if (isop == NULL) {
32213543
HG
419 DPRINTF("iso-token-in ep %02X, no isop, iso_error: %d\n",
420 ep, dev->endpoint[EP2I(ep)].iso_error);
e1537884
HG
421 /* Re-fill the buffer */
422 dev->endpoint[EP2I(ep)].bufpq_prefilled = 0;
69354a83
HG
423 /* Check iso_error for stream errors, otherwise its an underrun */
424 status = dev->endpoint[EP2I(ep)].iso_error;
425 dev->endpoint[EP2I(ep)].iso_error = 0;
426 return usbredir_handle_status(dev, status, 0);
427 }
32213543
HG
428 DPRINTF2("iso-token-in ep %02X status %d len %d queue-size: %d\n", ep,
429 isop->status, isop->len, dev->endpoint[EP2I(ep)].bufpq_size);
69354a83
HG
430
431 status = isop->status;
432 if (status != usb_redir_success) {
433 bufp_free(dev, isop, ep);
434 return usbredir_handle_status(dev, status, 0);
435 }
436
437 len = isop->len;
4f4321c1 438 if (len > p->iov.size) {
32213543
HG
439 ERROR("received iso data is larger then packet ep %02X (%d > %d)\n",
440 ep, len, (int)p->iov.size);
69354a83
HG
441 bufp_free(dev, isop, ep);
442 return USB_RET_NAK;
443 }
4f4321c1 444 usb_packet_copy(p, isop->data, len);
69354a83
HG
445 bufp_free(dev, isop, ep);
446 return len;
447 } else {
448 /* If the stream was not started because of a pending error don't
449 send the packet to the usb-host */
450 if (dev->endpoint[EP2I(ep)].iso_started) {
451 struct usb_redir_iso_packet_header iso_packet = {
452 .endpoint = ep,
4f4321c1 453 .length = p->iov.size
69354a83 454 };
4f4321c1 455 uint8_t buf[p->iov.size];
69354a83 456 /* No id, we look at the ep when receiving a status back */
4f4321c1 457 usb_packet_copy(p, buf, p->iov.size);
69354a83 458 usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,
4f4321c1 459 buf, p->iov.size);
69354a83
HG
460 usbredirparser_do_write(dev->parser);
461 }
462 status = dev->endpoint[EP2I(ep)].iso_error;
463 dev->endpoint[EP2I(ep)].iso_error = 0;
4f4321c1
GH
464 DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep, status,
465 p->iov.size);
466 return usbredir_handle_status(dev, status, p->iov.size);
69354a83
HG
467 }
468}
469
470static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
471{
472 struct usb_redir_stop_iso_stream_header stop_iso_stream = {
473 .endpoint = ep
474 };
475 if (dev->endpoint[EP2I(ep)].iso_started) {
476 usbredirparser_send_stop_iso_stream(dev->parser, 0, &stop_iso_stream);
477 DPRINTF("iso stream stopped ep %02X\n", ep);
478 dev->endpoint[EP2I(ep)].iso_started = 0;
479 }
2bd836e5 480 dev->endpoint[EP2I(ep)].iso_error = 0;
69354a83
HG
481 usbredir_free_bufpq(dev, ep);
482}
483
484static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
485 uint8_t ep)
486{
487 AsyncURB *aurb = async_alloc(dev, p);
488 struct usb_redir_bulk_packet_header bulk_packet;
489
4f4321c1
GH
490 DPRINTF("bulk-out ep %02X len %zd id %u\n", ep,
491 p->iov.size, aurb->packet_id);
69354a83
HG
492
493 bulk_packet.endpoint = ep;
4f4321c1 494 bulk_packet.length = p->iov.size;
69354a83
HG
495 bulk_packet.stream_id = 0;
496 aurb->bulk_packet = bulk_packet;
497
498 if (ep & USB_DIR_IN) {
499 usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
500 &bulk_packet, NULL, 0);
501 } else {
4f4321c1
GH
502 uint8_t buf[p->iov.size];
503 usb_packet_copy(p, buf, p->iov.size);
504 usbredir_log_data(dev, "bulk data out:", buf, p->iov.size);
69354a83 505 usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
4f4321c1 506 &bulk_packet, buf, p->iov.size);
69354a83
HG
507 }
508 usbredirparser_do_write(dev->parser);
509 return USB_RET_ASYNC;
510}
511
512static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
513 USBPacket *p, uint8_t ep)
514{
515 if (ep & USB_DIR_IN) {
516 /* Input interrupt endpoint, buffered packet input */
517 struct buf_packet *intp;
518 int status, len;
519
520 if (!dev->endpoint[EP2I(ep)].interrupt_started &&
521 !dev->endpoint[EP2I(ep)].interrupt_error) {
522 struct usb_redir_start_interrupt_receiving_header start_int = {
523 .endpoint = ep,
524 };
525 /* No id, we look at the ep when receiving a status back */
526 usbredirparser_send_start_interrupt_receiving(dev->parser, 0,
527 &start_int);
528 usbredirparser_do_write(dev->parser);
529 DPRINTF("interrupt recv started ep %02X\n", ep);
530 dev->endpoint[EP2I(ep)].interrupt_started = 1;
81fd7b74
HG
531 /* We don't really want to drop interrupt packets ever, but
532 having some upper limit to how much we buffer is good. */
533 dev->endpoint[EP2I(ep)].bufpq_target_size = 1000;
534 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
69354a83
HG
535 }
536
537 intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
538 if (intp == NULL) {
539 DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);
540 /* Check interrupt_error for stream errors */
541 status = dev->endpoint[EP2I(ep)].interrupt_error;
542 dev->endpoint[EP2I(ep)].interrupt_error = 0;
543 return usbredir_handle_status(dev, status, 0);
544 }
545 DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,
546 intp->status, intp->len);
547
548 status = intp->status;
549 if (status != usb_redir_success) {
550 bufp_free(dev, intp, ep);
551 return usbredir_handle_status(dev, status, 0);
552 }
553
554 len = intp->len;
4f4321c1 555 if (len > p->iov.size) {
69354a83
HG
556 ERROR("received int data is larger then packet ep %02X\n", ep);
557 bufp_free(dev, intp, ep);
558 return USB_RET_NAK;
559 }
4f4321c1 560 usb_packet_copy(p, intp->data, len);
69354a83
HG
561 bufp_free(dev, intp, ep);
562 return len;
563 } else {
564 /* Output interrupt endpoint, normal async operation */
565 AsyncURB *aurb = async_alloc(dev, p);
566 struct usb_redir_interrupt_packet_header interrupt_packet;
4f4321c1 567 uint8_t buf[p->iov.size];
69354a83 568
4f4321c1 569 DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep, p->iov.size,
69354a83
HG
570 aurb->packet_id);
571
572 interrupt_packet.endpoint = ep;
4f4321c1 573 interrupt_packet.length = p->iov.size;
69354a83
HG
574 aurb->interrupt_packet = interrupt_packet;
575
4f4321c1
GH
576 usb_packet_copy(p, buf, p->iov.size);
577 usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);
69354a83 578 usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
4f4321c1 579 &interrupt_packet, buf, p->iov.size);
69354a83
HG
580 usbredirparser_do_write(dev->parser);
581 return USB_RET_ASYNC;
582 }
583}
584
585static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev,
586 uint8_t ep)
587{
588 struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv = {
589 .endpoint = ep
590 };
591 if (dev->endpoint[EP2I(ep)].interrupt_started) {
592 usbredirparser_send_stop_interrupt_receiving(dev->parser, 0,
593 &stop_interrupt_recv);
594 DPRINTF("interrupt recv stopped ep %02X\n", ep);
595 dev->endpoint[EP2I(ep)].interrupt_started = 0;
596 }
2bd836e5 597 dev->endpoint[EP2I(ep)].interrupt_error = 0;
69354a83
HG
598 usbredir_free_bufpq(dev, ep);
599}
600
601static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
602{
603 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
604 uint8_t ep;
605
606 ep = p->devep;
607 if (p->pid == USB_TOKEN_IN) {
608 ep |= USB_DIR_IN;
609 }
610
611 switch (dev->endpoint[EP2I(ep)].type) {
612 case USB_ENDPOINT_XFER_CONTROL:
613 ERROR("handle_data called for control transfer on ep %02X\n", ep);
614 return USB_RET_NAK;
615 case USB_ENDPOINT_XFER_ISOC:
616 return usbredir_handle_iso_data(dev, p, ep);
617 case USB_ENDPOINT_XFER_BULK:
3a93113a 618 return usbredir_handle_bulk_data(dev, p, ep);
69354a83 619 case USB_ENDPOINT_XFER_INT:
3a93113a 620 return usbredir_handle_interrupt_data(dev, p, ep);
69354a83
HG
621 default:
622 ERROR("handle_data ep %02X has unknown type %d\n", ep,
623 dev->endpoint[EP2I(ep)].type);
624 return USB_RET_NAK;
625 }
626}
627
628static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
629 int config)
630{
631 struct usb_redir_set_configuration_header set_config;
632 AsyncURB *aurb = async_alloc(dev, p);
633 int i;
634
635 DPRINTF("set config %d id %u\n", config, aurb->packet_id);
636
637 for (i = 0; i < MAX_ENDPOINTS; i++) {
638 switch (dev->endpoint[i].type) {
639 case USB_ENDPOINT_XFER_ISOC:
640 usbredir_stop_iso_stream(dev, I2EP(i));
641 break;
642 case USB_ENDPOINT_XFER_INT:
643 if (i & 0x10) {
644 usbredir_stop_interrupt_receiving(dev, I2EP(i));
645 }
646 break;
647 }
648 usbredir_free_bufpq(dev, I2EP(i));
649 }
650
651 set_config.configuration = config;
652 usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
653 &set_config);
654 usbredirparser_do_write(dev->parser);
655 return USB_RET_ASYNC;
656}
657
658static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
659{
660 AsyncURB *aurb = async_alloc(dev, p);
661
662 DPRINTF("get config id %u\n", aurb->packet_id);
663
664 aurb->get = 1;
665 usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
666 usbredirparser_do_write(dev->parser);
667 return USB_RET_ASYNC;
668}
669
670static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
671 int interface, int alt)
672{
673 struct usb_redir_set_alt_setting_header set_alt;
674 AsyncURB *aurb = async_alloc(dev, p);
675 int i;
676
677 DPRINTF("set interface %d alt %d id %u\n", interface, alt,
678 aurb->packet_id);
679
680 for (i = 0; i < MAX_ENDPOINTS; i++) {
681 if (dev->endpoint[i].interface == interface) {
682 switch (dev->endpoint[i].type) {
683 case USB_ENDPOINT_XFER_ISOC:
684 usbredir_stop_iso_stream(dev, I2EP(i));
685 break;
686 case USB_ENDPOINT_XFER_INT:
687 if (i & 0x10) {
688 usbredir_stop_interrupt_receiving(dev, I2EP(i));
689 }
690 break;
691 }
692 usbredir_free_bufpq(dev, I2EP(i));
693 }
694 }
695
696 set_alt.interface = interface;
697 set_alt.alt = alt;
698 usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
699 &set_alt);
700 usbredirparser_do_write(dev->parser);
701 return USB_RET_ASYNC;
702}
703
704static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
705 int interface)
706{
707 struct usb_redir_get_alt_setting_header get_alt;
708 AsyncURB *aurb = async_alloc(dev, p);
709
710 DPRINTF("get interface %d id %u\n", interface, aurb->packet_id);
711
712 get_alt.interface = interface;
713 aurb->get = 1;
714 usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
715 &get_alt);
716 usbredirparser_do_write(dev->parser);
717 return USB_RET_ASYNC;
718}
719
720static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
721 int request, int value, int index, int length, uint8_t *data)
722{
723 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
724 struct usb_redir_control_packet_header control_packet;
725 AsyncURB *aurb;
726
727 /* Special cases for certain standard device requests */
728 switch (request) {
729 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
730 DPRINTF("set address %d\n", value);
731 dev->dev.addr = value;
732 return 0;
733 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
734 return usbredir_set_config(dev, p, value & 0xff);
735 case DeviceRequest | USB_REQ_GET_CONFIGURATION:
736 return usbredir_get_config(dev, p);
737 case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
738 return usbredir_set_interface(dev, p, index, value);
739 case InterfaceRequest | USB_REQ_GET_INTERFACE:
740 return usbredir_get_interface(dev, p, index);
741 }
742
743 /* "Normal" ctrl requests */
744 aurb = async_alloc(dev, p);
745
746 /* Note request is (bRequestType << 8) | bRequest */
747 DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
748 request >> 8, request & 0xff, value, index, length,
749 aurb->packet_id);
750
751 control_packet.request = request & 0xFF;
752 control_packet.requesttype = request >> 8;
753 control_packet.endpoint = control_packet.requesttype & USB_DIR_IN;
754 control_packet.value = value;
755 control_packet.index = index;
756 control_packet.length = length;
757 aurb->control_packet = control_packet;
758
759 if (control_packet.requesttype & USB_DIR_IN) {
760 usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
761 &control_packet, NULL, 0);
762 } else {
763 usbredir_log_data(dev, "ctrl data out:", data, length);
764 usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
765 &control_packet, data, length);
766 }
767 usbredirparser_do_write(dev->parser);
768 return USB_RET_ASYNC;
769}
770
771/*
772 * Close events can be triggered by usbredirparser_do_write which gets called
773 * from within the USBDevice data / control packet callbacks and doing a
774 * usb_detach from within these callbacks is not a good idea.
775 *
776 * So we use a bh handler to take care of close events. We also handle
777 * open events from this callback to make sure that a close directly followed
778 * by an open gets handled in the right order.
779 */
780static void usbredir_open_close_bh(void *opaque)
781{
782 USBRedirDevice *dev = opaque;
783
784 usbredir_device_disconnect(dev);
785
786 if (dev->parser) {
787 usbredirparser_destroy(dev->parser);
788 dev->parser = NULL;
789 }
790
791 if (dev->cs->opened) {
792 dev->parser = qemu_oom_check(usbredirparser_create());
793 dev->parser->priv = dev;
794 dev->parser->log_func = usbredir_log;
795 dev->parser->read_func = usbredir_read;
796 dev->parser->write_func = usbredir_write;
797 dev->parser->device_connect_func = usbredir_device_connect;
798 dev->parser->device_disconnect_func = usbredir_device_disconnect;
799 dev->parser->interface_info_func = usbredir_interface_info;
800 dev->parser->ep_info_func = usbredir_ep_info;
801 dev->parser->configuration_status_func = usbredir_configuration_status;
802 dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
803 dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
804 dev->parser->interrupt_receiving_status_func =
805 usbredir_interrupt_receiving_status;
806 dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
807 dev->parser->control_packet_func = usbredir_control_packet;
808 dev->parser->bulk_packet_func = usbredir_bulk_packet;
809 dev->parser->iso_packet_func = usbredir_iso_packet;
810 dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
811 dev->read_buf = NULL;
812 dev->read_buf_size = 0;
813 usbredirparser_init(dev->parser, VERSION, NULL, 0, 0);
814 usbredirparser_do_write(dev->parser);
815 }
816}
817
818static void usbredir_do_attach(void *opaque)
819{
820 USBRedirDevice *dev = opaque;
821
822 usb_device_attach(&dev->dev);
823}
824
825/*
826 * chardev callbacks
827 */
828
829static int usbredir_chardev_can_read(void *opaque)
830{
831 USBRedirDevice *dev = opaque;
832
833 if (dev->parser) {
834 /* usbredir_parser_do_read will consume *all* data we give it */
835 return 1024 * 1024;
836 } else {
837 /* usbredir_open_close_bh hasn't handled the open event yet */
838 return 0;
839 }
840}
841
842static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
843{
844 USBRedirDevice *dev = opaque;
845
846 /* No recursion allowed! */
847 assert(dev->read_buf == NULL);
848
849 dev->read_buf = buf;
850 dev->read_buf_size = size;
851
852 usbredirparser_do_read(dev->parser);
853 /* Send any acks, etc. which may be queued now */
854 usbredirparser_do_write(dev->parser);
855}
856
857static void usbredir_chardev_event(void *opaque, int event)
858{
859 USBRedirDevice *dev = opaque;
860
861 switch (event) {
862 case CHR_EVENT_OPENED:
863 case CHR_EVENT_CLOSED:
864 qemu_bh_schedule(dev->open_close_bh);
865 break;
866 }
867}
868
869/*
870 * init + destroy
871 */
872
873static int usbredir_initfn(USBDevice *udev)
874{
875 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
876 int i;
877
878 if (dev->cs == NULL) {
879 qerror_report(QERR_MISSING_PARAMETER, "chardev");
880 return -1;
881 }
882
883 dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
884 dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
885
886 QTAILQ_INIT(&dev->asyncq);
887 for (i = 0; i < MAX_ENDPOINTS; i++) {
888 QTAILQ_INIT(&dev->endpoint[i].bufpq);
889 }
890
891 /* We'll do the attach once we receive the speed from the usb-host */
892 udev->auto_attach = 0;
893
65f9d986
HG
894 /* Let the backend know we are ready */
895 qemu_chr_fe_open(dev->cs);
69354a83
HG
896 qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
897 usbredir_chardev_read, usbredir_chardev_event, dev);
898
899 return 0;
900}
901
902static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
903{
904 AsyncURB *aurb, *next_aurb;
905 int i;
906
907 QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
908 async_free(dev, aurb);
909 }
910 for (i = 0; i < MAX_ENDPOINTS; i++) {
911 usbredir_free_bufpq(dev, I2EP(i));
912 }
913}
914
915static void usbredir_handle_destroy(USBDevice *udev)
916{
917 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
918
65f9d986 919 qemu_chr_fe_close(dev->cs);
70f24fb6 920 qemu_chr_delete(dev->cs);
69354a83
HG
921 /* Note must be done after qemu_chr_close, as that causes a close event */
922 qemu_bh_delete(dev->open_close_bh);
923
924 qemu_del_timer(dev->attach_timer);
925 qemu_free_timer(dev->attach_timer);
926
927 usbredir_cleanup_device_queues(dev);
928
929 if (dev->parser) {
930 usbredirparser_destroy(dev->parser);
931 }
932}
933
934/*
935 * usbredirparser packet complete callbacks
936 */
937
938static int usbredir_handle_status(USBRedirDevice *dev,
939 int status, int actual_len)
940{
941 switch (status) {
942 case usb_redir_success:
943 return actual_len;
944 case usb_redir_stall:
945 return USB_RET_STALL;
946 case usb_redir_cancelled:
947 WARNING("returning cancelled packet to HC?\n");
948 case usb_redir_inval:
949 case usb_redir_ioerror:
950 case usb_redir_timeout:
951 default:
952 return USB_RET_NAK;
953 }
954}
955
956static void usbredir_device_connect(void *priv,
957 struct usb_redir_device_connect_header *device_connect)
958{
959 USBRedirDevice *dev = priv;
960
99f08100
HG
961 if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
962 ERROR("Received device connect while already connected\n");
963 return;
964 }
965
69354a83
HG
966 switch (device_connect->speed) {
967 case usb_redir_speed_low:
968 DPRINTF("attaching low speed device\n");
969 dev->dev.speed = USB_SPEED_LOW;
970 break;
971 case usb_redir_speed_full:
972 DPRINTF("attaching full speed device\n");
973 dev->dev.speed = USB_SPEED_FULL;
974 break;
975 case usb_redir_speed_high:
976 DPRINTF("attaching high speed device\n");
977 dev->dev.speed = USB_SPEED_HIGH;
978 break;
979 case usb_redir_speed_super:
980 DPRINTF("attaching super speed device\n");
981 dev->dev.speed = USB_SPEED_SUPER;
982 break;
983 default:
984 DPRINTF("attaching unknown speed device, assuming full speed\n");
985 dev->dev.speed = USB_SPEED_FULL;
986 }
987 dev->dev.speedmask = (1 << dev->dev.speed);
988 qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
989}
990
991static void usbredir_device_disconnect(void *priv)
992{
993 USBRedirDevice *dev = priv;
99f08100 994 int i;
69354a83
HG
995
996 /* Stop any pending attaches */
997 qemu_del_timer(dev->attach_timer);
998
999 if (dev->dev.attached) {
1000 usb_device_detach(&dev->dev);
69354a83
HG
1001 /*
1002 * Delay next usb device attach to give the guest a chance to see
1003 * see the detach / attach in case of quick close / open succession
1004 */
1005 dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
1006 }
99f08100
HG
1007
1008 /* Reset state so that the next dev connected starts with a clean slate */
1009 usbredir_cleanup_device_queues(dev);
1010 memset(dev->endpoint, 0, sizeof(dev->endpoint));
1011 for (i = 0; i < MAX_ENDPOINTS; i++) {
1012 QTAILQ_INIT(&dev->endpoint[i].bufpq);
1013 }
69354a83
HG
1014}
1015
1016static void usbredir_interface_info(void *priv,
1017 struct usb_redir_interface_info_header *interface_info)
1018{
1019 /* The intention is to allow specifying acceptable interface classes
1020 for redirection on the cmdline and in the future verify this here,
1021 and disconnect (or never connect) the device if a not accepted
1022 interface class is detected */
1023}
1024
1025static void usbredir_ep_info(void *priv,
1026 struct usb_redir_ep_info_header *ep_info)
1027{
1028 USBRedirDevice *dev = priv;
1029 int i;
1030
1031 for (i = 0; i < MAX_ENDPOINTS; i++) {
1032 dev->endpoint[i].type = ep_info->type[i];
1033 dev->endpoint[i].interval = ep_info->interval[i];
1034 dev->endpoint[i].interface = ep_info->interface[i];
e8a7dd29
HG
1035 switch (dev->endpoint[i].type) {
1036 case usb_redir_type_invalid:
1037 break;
1038 case usb_redir_type_iso:
1039 case usb_redir_type_interrupt:
1040 if (dev->endpoint[i].interval == 0) {
1041 ERROR("Received 0 interval for isoc or irq endpoint\n");
1042 usbredir_device_disconnect(dev);
1043 }
1044 /* Fall through */
1045 case usb_redir_type_control:
1046 case usb_redir_type_bulk:
69354a83
HG
1047 DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
1048 dev->endpoint[i].type, dev->endpoint[i].interface);
e8a7dd29
HG
1049 break;
1050 default:
1051 ERROR("Received invalid endpoint type\n");
1052 usbredir_device_disconnect(dev);
69354a83
HG
1053 }
1054 }
1055}
1056
1057static void usbredir_configuration_status(void *priv, uint32_t id,
1058 struct usb_redir_configuration_status_header *config_status)
1059{
1060 USBRedirDevice *dev = priv;
1061 AsyncURB *aurb;
1062 int len = 0;
1063
1064 DPRINTF("set config status %d config %d id %u\n", config_status->status,
1065 config_status->configuration, id);
1066
1067 aurb = async_find(dev, id);
1068 if (!aurb) {
1069 return;
1070 }
1071 if (aurb->packet) {
1072 if (aurb->get) {
1073 dev->dev.data_buf[0] = config_status->configuration;
1074 len = 1;
1075 }
4f4321c1 1076 aurb->packet->result =
69354a83
HG
1077 usbredir_handle_status(dev, config_status->status, len);
1078 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1079 }
1080 async_free(dev, aurb);
1081}
1082
1083static void usbredir_alt_setting_status(void *priv, uint32_t id,
1084 struct usb_redir_alt_setting_status_header *alt_setting_status)
1085{
1086 USBRedirDevice *dev = priv;
1087 AsyncURB *aurb;
1088 int len = 0;
1089
1090 DPRINTF("alt status %d intf %d alt %d id: %u\n",
1091 alt_setting_status->status,
1092 alt_setting_status->interface,
1093 alt_setting_status->alt, id);
1094
1095 aurb = async_find(dev, id);
1096 if (!aurb) {
1097 return;
1098 }
1099 if (aurb->packet) {
1100 if (aurb->get) {
1101 dev->dev.data_buf[0] = alt_setting_status->alt;
1102 len = 1;
1103 }
4f4321c1 1104 aurb->packet->result =
69354a83
HG
1105 usbredir_handle_status(dev, alt_setting_status->status, len);
1106 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1107 }
1108 async_free(dev, aurb);
1109}
1110
1111static void usbredir_iso_stream_status(void *priv, uint32_t id,
1112 struct usb_redir_iso_stream_status_header *iso_stream_status)
1113{
1114 USBRedirDevice *dev = priv;
1115 uint8_t ep = iso_stream_status->endpoint;
1116
1117 DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1118 ep, id);
1119
2bd836e5 1120 if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].iso_started) {
99f08100
HG
1121 return;
1122 }
1123
69354a83
HG
1124 dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
1125 if (iso_stream_status->status == usb_redir_stall) {
1126 DPRINTF("iso stream stopped by peer ep %02X\n", ep);
1127 dev->endpoint[EP2I(ep)].iso_started = 0;
1128 }
1129}
1130
1131static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1132 struct usb_redir_interrupt_receiving_status_header
1133 *interrupt_receiving_status)
1134{
1135 USBRedirDevice *dev = priv;
1136 uint8_t ep = interrupt_receiving_status->endpoint;
1137
1138 DPRINTF("interrupt recv status %d ep %02X id %u\n",
1139 interrupt_receiving_status->status, ep, id);
1140
2bd836e5 1141 if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].interrupt_started) {
99f08100
HG
1142 return;
1143 }
1144
69354a83
HG
1145 dev->endpoint[EP2I(ep)].interrupt_error =
1146 interrupt_receiving_status->status;
1147 if (interrupt_receiving_status->status == usb_redir_stall) {
1148 DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep);
1149 dev->endpoint[EP2I(ep)].interrupt_started = 0;
1150 }
1151}
1152
1153static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1154 struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1155{
1156}
1157
1158static void usbredir_control_packet(void *priv, uint32_t id,
1159 struct usb_redir_control_packet_header *control_packet,
1160 uint8_t *data, int data_len)
1161{
1162 USBRedirDevice *dev = priv;
1163 int len = control_packet->length;
1164 AsyncURB *aurb;
1165
1166 DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1167 len, id);
1168
1169 aurb = async_find(dev, id);
1170 if (!aurb) {
1171 free(data);
1172 return;
1173 }
1174
1175 aurb->control_packet.status = control_packet->status;
1176 aurb->control_packet.length = control_packet->length;
1177 if (memcmp(&aurb->control_packet, control_packet,
1178 sizeof(*control_packet))) {
1179 ERROR("return control packet mismatch, please report this!\n");
1180 len = USB_RET_NAK;
1181 }
1182
1183 if (aurb->packet) {
1184 len = usbredir_handle_status(dev, control_packet->status, len);
1185 if (len > 0) {
1186 usbredir_log_data(dev, "ctrl data in:", data, data_len);
1187 if (data_len <= sizeof(dev->dev.data_buf)) {
1188 memcpy(dev->dev.data_buf, data, data_len);
1189 } else {
1190 ERROR("ctrl buffer too small (%d > %zu)\n",
1191 data_len, sizeof(dev->dev.data_buf));
1192 len = USB_RET_STALL;
1193 }
1194 }
4f4321c1 1195 aurb->packet->result = len;
69354a83
HG
1196 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1197 }
1198 async_free(dev, aurb);
1199 free(data);
1200}
1201
1202static void usbredir_bulk_packet(void *priv, uint32_t id,
1203 struct usb_redir_bulk_packet_header *bulk_packet,
1204 uint8_t *data, int data_len)
1205{
1206 USBRedirDevice *dev = priv;
1207 uint8_t ep = bulk_packet->endpoint;
1208 int len = bulk_packet->length;
1209 AsyncURB *aurb;
1210
1211 DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1212 ep, len, id);
1213
1214 aurb = async_find(dev, id);
1215 if (!aurb) {
1216 free(data);
1217 return;
1218 }
1219
1220 if (aurb->bulk_packet.endpoint != bulk_packet->endpoint ||
1221 aurb->bulk_packet.stream_id != bulk_packet->stream_id) {
1222 ERROR("return bulk packet mismatch, please report this!\n");
1223 len = USB_RET_NAK;
1224 }
1225
1226 if (aurb->packet) {
1227 len = usbredir_handle_status(dev, bulk_packet->status, len);
1228 if (len > 0) {
1229 usbredir_log_data(dev, "bulk data in:", data, data_len);
4f4321c1
GH
1230 if (data_len <= aurb->packet->iov.size) {
1231 usb_packet_copy(aurb->packet, data, data_len);
69354a83 1232 } else {
4f4321c1
GH
1233 ERROR("bulk buffer too small (%d > %zd)\n", data_len,
1234 aurb->packet->iov.size);
69354a83
HG
1235 len = USB_RET_STALL;
1236 }
1237 }
4f4321c1 1238 aurb->packet->result = len;
69354a83
HG
1239 usb_packet_complete(&dev->dev, aurb->packet);
1240 }
1241 async_free(dev, aurb);
1242 free(data);
1243}
1244
1245static void usbredir_iso_packet(void *priv, uint32_t id,
1246 struct usb_redir_iso_packet_header *iso_packet,
1247 uint8_t *data, int data_len)
1248{
1249 USBRedirDevice *dev = priv;
1250 uint8_t ep = iso_packet->endpoint;
1251
1252 DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1253 data_len, id);
1254
1255 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1256 ERROR("received iso packet for non iso endpoint %02X\n", ep);
1257 free(data);
1258 return;
1259 }
1260
1261 if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1262 DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1263 free(data);
1264 return;
1265 }
1266
1267 /* bufp_alloc also adds the packet to the ep queue */
1268 bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1269}
1270
1271static void usbredir_interrupt_packet(void *priv, uint32_t id,
1272 struct usb_redir_interrupt_packet_header *interrupt_packet,
1273 uint8_t *data, int data_len)
1274{
1275 USBRedirDevice *dev = priv;
1276 uint8_t ep = interrupt_packet->endpoint;
1277
1278 DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1279 interrupt_packet->status, ep, data_len, id);
1280
1281 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
1282 ERROR("received int packet for non interrupt endpoint %02X\n", ep);
1283 free(data);
1284 return;
1285 }
1286
1287 if (ep & USB_DIR_IN) {
1288 if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
1289 DPRINTF("received int packet while not started ep %02X\n", ep);
1290 free(data);
1291 return;
1292 }
1293
1294 /* bufp_alloc also adds the packet to the ep queue */
1295 bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
1296 } else {
1297 int len = interrupt_packet->length;
1298
1299 AsyncURB *aurb = async_find(dev, id);
1300 if (!aurb) {
1301 return;
1302 }
1303
1304 if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
1305 ERROR("return int packet mismatch, please report this!\n");
1306 len = USB_RET_NAK;
1307 }
1308
1309 if (aurb->packet) {
4f4321c1 1310 aurb->packet->result = usbredir_handle_status(dev,
69354a83
HG
1311 interrupt_packet->status, len);
1312 usb_packet_complete(&dev->dev, aurb->packet);
1313 }
1314 async_free(dev, aurb);
1315 }
1316}
1317
1318static struct USBDeviceInfo usbredir_dev_info = {
1319 .product_desc = "USB Redirection Device",
1320 .qdev.name = "usb-redir",
1321 .qdev.size = sizeof(USBRedirDevice),
1322 .init = usbredir_initfn,
1323 .handle_destroy = usbredir_handle_destroy,
1324 .handle_packet = usb_generic_handle_packet,
1325 .cancel_packet = usbredir_cancel_packet,
1326 .handle_reset = usbredir_handle_reset,
1327 .handle_data = usbredir_handle_data,
1328 .handle_control = usbredir_handle_control,
1329 .qdev.props = (Property[]) {
1330 DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
1331 DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
1332 DEFINE_PROP_END_OF_LIST(),
1333 },
1334};
1335
1336static void usbredir_register_devices(void)
1337{
1338 usb_qdev_register(&usbredir_dev_info);
1339}
1340device_init(usbredir_register_devices);