Annotation of qemu/usb-redir.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * USB redirector usb-guest
                      3:  *
                      4:  * Copyright (c) 2011 Red Hat, Inc.
                      5:  *
                      6:  * Red Hat Authors:
                      7:  * Hans de Goede <hdegoede@redhat.com>
                      8:  *
                      9:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                     10:  * of this software and associated documentation files (the "Software"), to deal
                     11:  * in the Software without restriction, including without limitation the rights
                     12:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     13:  * copies of the Software, and to permit persons to whom the Software is
                     14:  * furnished to do so, subject to the following conditions:
                     15:  *
                     16:  * The above copyright notice and this permission notice shall be included in
                     17:  * all copies or substantial portions of the Software.
                     18:  *
                     19:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     20:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     21:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     22:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     23:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     24:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     25:  * THE SOFTWARE.
                     26:  */
                     27: 
                     28: #include "qemu-common.h"
                     29: #include "qemu-timer.h"
                     30: #include "monitor.h"
                     31: #include "sysemu.h"
                     32: 
                     33: #include <dirent.h>
                     34: #include <sys/ioctl.h>
                     35: #include <signal.h>
                     36: #include <usbredirparser.h>
                     37: 
                     38: #include "hw/usb.h"
                     39: 
                     40: #define MAX_ENDPOINTS 32
                     41: #define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f))
                     42: #define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f))
                     43: 
                     44: typedef struct AsyncURB AsyncURB;
                     45: typedef struct USBRedirDevice USBRedirDevice;
                     46: 
                     47: /* Struct to hold buffered packets (iso or int input packets) */
                     48: struct buf_packet {
                     49:     uint8_t *data;
                     50:     int len;
                     51:     int status;
                     52:     QTAILQ_ENTRY(buf_packet)next;
                     53: };
                     54: 
                     55: struct endp_data {
                     56:     uint8_t type;
                     57:     uint8_t interval;
                     58:     uint8_t interface; /* bInterfaceNumber this ep belongs to */
                     59:     uint8_t iso_started;
                     60:     uint8_t iso_error; /* For reporting iso errors to the HC */
                     61:     uint8_t interrupt_started;
                     62:     uint8_t interrupt_error;
                     63:     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);

unix.superglobalmegacorp.com