Revision 69354a83

b/Makefile.objs
205 205
hw-obj-$(CONFIG_APPLESMC) += applesmc.o
206 206
hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
207 207
hw-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
208
hw-obj-$(CONFIG_USB_REDIR) += usb-redir.o
208 209

  
209 210
# PPC devices
210 211
hw-obj-$(CONFIG_OPENPIC) += openpic.o
b/configure
177 177
rbd=""
178 178
smartcard=""
179 179
smartcard_nss=""
180
usb_redir=""
180 181
opengl=""
181 182

  
182 183
# parse CC options first
......
743 744
  ;;
744 745
  --enable-smartcard-nss) smartcard_nss="yes"
745 746
  ;;
747
  --disable-usb-redir) usb_redir="no"
748
  ;;
749
  --enable-usb-redir) usb_redir="yes"
750
  ;;
746 751
  *) echo "ERROR: unknown option $opt"; show_help="yes"
747 752
  ;;
748 753
  esac
......
1018 1023
echo "  --enable-smartcard       enable smartcard support"
1019 1024
echo "  --disable-smartcard-nss  disable smartcard nss support"
1020 1025
echo "  --enable-smartcard-nss   enable smartcard nss support"
1026
echo "  --disable-usb-redir      disable usb network redirection support"
1027
echo "  --enable-usb-redir       enable usb network redirection support"
1021 1028
echo ""
1022 1029
echo "NOTE: The object files are built at the place where configure is launched"
1023 1030
exit 1
......
2371 2378
    smartcard_nss="no"
2372 2379
fi
2373 2380

  
2381
# check for usbredirparser for usb network redirection support
2382
if test "$usb_redir" != "no" ; then
2383
    if $pkg_config libusbredirparser >/dev/null 2>&1 ; then
2384
        usb_redir="yes"
2385
        usb_redir_cflags=$($pkg_config --cflags libusbredirparser 2>/dev/null)
2386
        usb_redir_libs=$($pkg_config --libs libusbredirparser 2>/dev/null)
2387
        QEMU_CFLAGS="$QEMU_CFLAGS $usb_redir_cflags"
2388
        LIBS="$LIBS $usb_redir_libs"
2389
    else
2390
        if test "$usb_redir" = "yes"; then
2391
            feature_not_found "usb-redir"
2392
        fi
2393
        usb_redir="no"
2394
    fi
2395
fi
2396

  
2374 2397
##########################################
2375 2398

  
2376 2399
##########################################
......
2617 2640
echo "rbd support       $rbd"
2618 2641
echo "xfsctl support    $xfs"
2619 2642
echo "nss used          $smartcard_nss"
2643
echo "usb net redir     $usb_redir"
2620 2644
echo "OpenGL support    $opengl"
2621 2645

  
2622 2646
if test $sdl_too_old = "yes"; then
......
2910 2934
  echo "CONFIG_SMARTCARD_NSS=y" >> $config_host_mak
2911 2935
fi
2912 2936

  
2937
if test "$usb_redir" = "yes" ; then
2938
  echo "CONFIG_USB_REDIR=y" >> $config_host_mak
2939
fi
2940

  
2913 2941
if test "$opengl" = "yes" ; then
2914 2942
  echo "CONFIG_OPENGL=y" >> $config_host_mak
2915 2943
fi
b/usb-redir.c
1
/*
2
 * USB redirector usb-guest
3
 *
4
 * Copyright (c) 2011 Red Hat, Inc.
5
 *
6
 * Red Hat Authors:
7
 * Hans de Goede <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);

Also available in: Unified diff