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