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