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