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

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

unix.superglobalmegacorp.com