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