Statistics
| Branch: | Revision:

root / usb-redir.c @ c09015dd

History | View | Annotate | Download (38.9 kB)

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", 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", buf);
197
    }
198
}
199

    
200
/*
201
 * usbredirparser io functions
202
 */
203

    
204
static int usbredir_read(void *priv, uint8_t *data, int count)
205
{
206
    USBRedirDevice *dev = priv;
207

    
208
    if (dev->read_buf_size < count) {
209
        count = dev->read_buf_size;
210
    }
211

    
212
    memcpy(data, dev->read_buf, count);
213

    
214
    dev->read_buf_size -= count;
215
    if (dev->read_buf_size) {
216
        dev->read_buf += count;
217
    } else {
218
        dev->read_buf = NULL;
219
    }
220

    
221
    return count;
222
}
223

    
224
static int usbredir_write(void *priv, uint8_t *data, int count)
225
{
226
    USBRedirDevice *dev = priv;
227

    
228
    if (!dev->cs->opened) {
229
        return 0;
230
    }
231

    
232
    return qemu_chr_fe_write(dev->cs, data, count);
233
}
234

    
235
/*
236
 * Async and buffered packets helpers
237
 */
238

    
239
static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
240
{
241
    AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
242
    aurb->dev = dev;
243
    aurb->packet = p;
244
    aurb->packet_id = dev->packet_id;
245
    QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
246
    dev->packet_id++;
247

    
248
    return aurb;
249
}
250

    
251
static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
252
{
253
    QTAILQ_REMOVE(&dev->asyncq, aurb, next);
254
    g_free(aurb);
255
}
256

    
257
static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
258
{
259
    AsyncURB *aurb;
260

    
261
    QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
262
        if (aurb->packet_id == packet_id) {
263
            return aurb;
264
        }
265
    }
266
    ERROR("could not find async urb for packet_id %u\n", packet_id);
267
    return NULL;
268
}
269

    
270
static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
271
{
272
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
273
    AsyncURB *aurb;
274

    
275
    QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
276
        if (p != aurb->packet) {
277
            continue;
278
        }
279

    
280
        DPRINTF("async cancel id %u\n", aurb->packet_id);
281
        usbredirparser_send_cancel_data_packet(dev->parser, aurb->packet_id);
282
        usbredirparser_do_write(dev->parser);
283

    
284
        /* Mark it as dead */
285
        aurb->packet = NULL;
286
        break;
287
    }
288
}
289

    
290
static struct buf_packet *bufp_alloc(USBRedirDevice *dev,
291
    uint8_t *data, int len, int status, uint8_t ep)
292
{
293
    struct buf_packet *bufp = g_malloc(sizeof(struct buf_packet));
294
    bufp->data   = data;
295
    bufp->len    = len;
296
    bufp->status = status;
297
    QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
298
    return bufp;
299
}
300

    
301
static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
302
    uint8_t ep)
303
{
304
    QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
305
    free(bufp->data);
306
    g_free(bufp);
307
}
308

    
309
static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
310
{
311
    struct buf_packet *buf, *buf_next;
312

    
313
    QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) {
314
        bufp_free(dev, buf, ep);
315
    }
316
}
317

    
318
/*
319
 * USBDevice callbacks
320
 */
321

    
322
static void usbredir_handle_reset(USBDevice *udev)
323
{
324
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
325

    
326
    DPRINTF("reset device\n");
327
    usbredirparser_send_reset(dev->parser);
328
    usbredirparser_do_write(dev->parser);
329
}
330

    
331
static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
332
                                     uint8_t ep)
333
{
334
    int status, len;
335

    
336
    if (!dev->endpoint[EP2I(ep)].iso_started &&
337
            !dev->endpoint[EP2I(ep)].iso_error) {
338
        struct usb_redir_start_iso_stream_header start_iso = {
339
            .endpoint = ep,
340
            /* TODO maybe do something with these depending on ep interval? */
341
            .pkts_per_urb = 32,
342
            .no_urbs = 3,
343
        };
344
        /* No id, we look at the ep when receiving a status back */
345
        usbredirparser_send_start_iso_stream(dev->parser, 0, &start_iso);
346
        usbredirparser_do_write(dev->parser);
347
        DPRINTF("iso stream started ep %02X\n", ep);
348
        dev->endpoint[EP2I(ep)].iso_started = 1;
349
    }
350

    
351
    if (ep & USB_DIR_IN) {
352
        struct buf_packet *isop;
353

    
354
        isop = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
355
        if (isop == NULL) {
356
            DPRINTF2("iso-token-in ep %02X, no isop\n", ep);
357
            /* Check iso_error for stream errors, otherwise its an underrun */
358
            status = dev->endpoint[EP2I(ep)].iso_error;
359
            dev->endpoint[EP2I(ep)].iso_error = 0;
360
            return usbredir_handle_status(dev, status, 0);
361
        }
362
        DPRINTF2("iso-token-in ep %02X status %d len %d\n", ep, isop->status,
363
                 isop->len);
364

    
365
        status = isop->status;
366
        if (status != usb_redir_success) {
367
            bufp_free(dev, isop, ep);
368
            return usbredir_handle_status(dev, status, 0);
369
        }
370

    
371
        len = isop->len;
372
        if (len > p->iov.size) {
373
            ERROR("received iso data is larger then packet ep %02X\n", ep);
374
            bufp_free(dev, isop, ep);
375
            return USB_RET_NAK;
376
        }
377
        usb_packet_copy(p, isop->data, len);
378
        bufp_free(dev, isop, ep);
379
        return len;
380
    } else {
381
        /* If the stream was not started because of a pending error don't
382
           send the packet to the usb-host */
383
        if (dev->endpoint[EP2I(ep)].iso_started) {
384
            struct usb_redir_iso_packet_header iso_packet = {
385
                .endpoint = ep,
386
                .length = p->iov.size
387
            };
388
            uint8_t buf[p->iov.size];
389
            /* No id, we look at the ep when receiving a status back */
390
            usb_packet_copy(p, buf, p->iov.size);
391
            usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,
392
                                           buf, p->iov.size);
393
            usbredirparser_do_write(dev->parser);
394
        }
395
        status = dev->endpoint[EP2I(ep)].iso_error;
396
        dev->endpoint[EP2I(ep)].iso_error = 0;
397
        DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep, status,
398
                 p->iov.size);
399
        return usbredir_handle_status(dev, status, p->iov.size);
400
    }
401
}
402

    
403
static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
404
{
405
    struct usb_redir_stop_iso_stream_header stop_iso_stream = {
406
        .endpoint = ep
407
    };
408
    if (dev->endpoint[EP2I(ep)].iso_started) {
409
        usbredirparser_send_stop_iso_stream(dev->parser, 0, &stop_iso_stream);
410
        DPRINTF("iso stream stopped ep %02X\n", ep);
411
        dev->endpoint[EP2I(ep)].iso_started = 0;
412
    }
413
    usbredir_free_bufpq(dev, ep);
414
}
415

    
416
static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
417
                                      uint8_t ep)
418
{
419
    AsyncURB *aurb = async_alloc(dev, p);
420
    struct usb_redir_bulk_packet_header bulk_packet;
421

    
422
    DPRINTF("bulk-out ep %02X len %zd id %u\n", ep,
423
            p->iov.size, aurb->packet_id);
424

    
425
    bulk_packet.endpoint  = ep;
426
    bulk_packet.length    = p->iov.size;
427
    bulk_packet.stream_id = 0;
428
    aurb->bulk_packet = bulk_packet;
429

    
430
    if (ep & USB_DIR_IN) {
431
        usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
432
                                        &bulk_packet, NULL, 0);
433
    } else {
434
        uint8_t buf[p->iov.size];
435
        usb_packet_copy(p, buf, p->iov.size);
436
        usbredir_log_data(dev, "bulk data out:", buf, p->iov.size);
437
        usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
438
                                        &bulk_packet, buf, p->iov.size);
439
    }
440
    usbredirparser_do_write(dev->parser);
441
    return USB_RET_ASYNC;
442
}
443

    
444
static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
445
                                           USBPacket *p, uint8_t ep)
446
{
447
    if (ep & USB_DIR_IN) {
448
        /* Input interrupt endpoint, buffered packet input */
449
        struct buf_packet *intp;
450
        int status, len;
451

    
452
        if (!dev->endpoint[EP2I(ep)].interrupt_started &&
453
                !dev->endpoint[EP2I(ep)].interrupt_error) {
454
            struct usb_redir_start_interrupt_receiving_header start_int = {
455
                .endpoint = ep,
456
            };
457
            /* No id, we look at the ep when receiving a status back */
458
            usbredirparser_send_start_interrupt_receiving(dev->parser, 0,
459
                                                          &start_int);
460
            usbredirparser_do_write(dev->parser);
461
            DPRINTF("interrupt recv started ep %02X\n", ep);
462
            dev->endpoint[EP2I(ep)].interrupt_started = 1;
463
        }
464

    
465
        intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
466
        if (intp == NULL) {
467
            DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);
468
            /* Check interrupt_error for stream errors */
469
            status = dev->endpoint[EP2I(ep)].interrupt_error;
470
            dev->endpoint[EP2I(ep)].interrupt_error = 0;
471
            return usbredir_handle_status(dev, status, 0);
472
        }
473
        DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,
474
                intp->status, intp->len);
475

    
476
        status = intp->status;
477
        if (status != usb_redir_success) {
478
            bufp_free(dev, intp, ep);
479
            return usbredir_handle_status(dev, status, 0);
480
        }
481

    
482
        len = intp->len;
483
        if (len > p->iov.size) {
484
            ERROR("received int data is larger then packet ep %02X\n", ep);
485
            bufp_free(dev, intp, ep);
486
            return USB_RET_NAK;
487
        }
488
        usb_packet_copy(p, intp->data, len);
489
        bufp_free(dev, intp, ep);
490
        return len;
491
    } else {
492
        /* Output interrupt endpoint, normal async operation */
493
        AsyncURB *aurb = async_alloc(dev, p);
494
        struct usb_redir_interrupt_packet_header interrupt_packet;
495
        uint8_t buf[p->iov.size];
496

    
497
        DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep, p->iov.size,
498
                aurb->packet_id);
499

    
500
        interrupt_packet.endpoint  = ep;
501
        interrupt_packet.length    = p->iov.size;
502
        aurb->interrupt_packet     = interrupt_packet;
503

    
504
        usb_packet_copy(p, buf, p->iov.size);
505
        usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);
506
        usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
507
                                        &interrupt_packet, buf, p->iov.size);
508
        usbredirparser_do_write(dev->parser);
509
        return USB_RET_ASYNC;
510
    }
511
}
512

    
513
static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev,
514
    uint8_t ep)
515
{
516
    struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv = {
517
        .endpoint = ep
518
    };
519
    if (dev->endpoint[EP2I(ep)].interrupt_started) {
520
        usbredirparser_send_stop_interrupt_receiving(dev->parser, 0,
521
                                                     &stop_interrupt_recv);
522
        DPRINTF("interrupt recv stopped ep %02X\n", ep);
523
        dev->endpoint[EP2I(ep)].interrupt_started = 0;
524
    }
525
    usbredir_free_bufpq(dev, ep);
526
}
527

    
528
static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
529
{
530
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
531
    uint8_t ep;
532

    
533
    ep = p->devep;
534
    if (p->pid == USB_TOKEN_IN) {
535
        ep |= USB_DIR_IN;
536
    }
537

    
538
    switch (dev->endpoint[EP2I(ep)].type) {
539
    case USB_ENDPOINT_XFER_CONTROL:
540
        ERROR("handle_data called for control transfer on ep %02X\n", ep);
541
        return USB_RET_NAK;
542
    case USB_ENDPOINT_XFER_ISOC:
543
        return usbredir_handle_iso_data(dev, p, ep);
544
    case USB_ENDPOINT_XFER_BULK:
545
        return usbredir_handle_bulk_data(dev, p, ep);
546
    case USB_ENDPOINT_XFER_INT:
547
        return usbredir_handle_interrupt_data(dev, p, ep);
548
    default:
549
        ERROR("handle_data ep %02X has unknown type %d\n", ep,
550
              dev->endpoint[EP2I(ep)].type);
551
        return USB_RET_NAK;
552
    }
553
}
554

    
555
static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
556
                                int config)
557
{
558
    struct usb_redir_set_configuration_header set_config;
559
    AsyncURB *aurb = async_alloc(dev, p);
560
    int i;
561

    
562
    DPRINTF("set config %d id %u\n", config, aurb->packet_id);
563

    
564
    for (i = 0; i < MAX_ENDPOINTS; i++) {
565
        switch (dev->endpoint[i].type) {
566
        case USB_ENDPOINT_XFER_ISOC:
567
            usbredir_stop_iso_stream(dev, I2EP(i));
568
            break;
569
        case USB_ENDPOINT_XFER_INT:
570
            if (i & 0x10) {
571
                usbredir_stop_interrupt_receiving(dev, I2EP(i));
572
            }
573
            break;
574
        }
575
        usbredir_free_bufpq(dev, I2EP(i));
576
    }
577

    
578
    set_config.configuration = config;
579
    usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
580
                                          &set_config);
581
    usbredirparser_do_write(dev->parser);
582
    return USB_RET_ASYNC;
583
}
584

    
585
static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
586
{
587
    AsyncURB *aurb = async_alloc(dev, p);
588

    
589
    DPRINTF("get config id %u\n", aurb->packet_id);
590

    
591
    aurb->get = 1;
592
    usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
593
    usbredirparser_do_write(dev->parser);
594
    return USB_RET_ASYNC;
595
}
596

    
597
static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
598
                                   int interface, int alt)
599
{
600
    struct usb_redir_set_alt_setting_header set_alt;
601
    AsyncURB *aurb = async_alloc(dev, p);
602
    int i;
603

    
604
    DPRINTF("set interface %d alt %d id %u\n", interface, alt,
605
            aurb->packet_id);
606

    
607
    for (i = 0; i < MAX_ENDPOINTS; i++) {
608
        if (dev->endpoint[i].interface == interface) {
609
            switch (dev->endpoint[i].type) {
610
            case USB_ENDPOINT_XFER_ISOC:
611
                usbredir_stop_iso_stream(dev, I2EP(i));
612
                break;
613
            case USB_ENDPOINT_XFER_INT:
614
                if (i & 0x10) {
615
                    usbredir_stop_interrupt_receiving(dev, I2EP(i));
616
                }
617
                break;
618
            }
619
            usbredir_free_bufpq(dev, I2EP(i));
620
        }
621
    }
622

    
623
    set_alt.interface = interface;
624
    set_alt.alt = alt;
625
    usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
626
                                        &set_alt);
627
    usbredirparser_do_write(dev->parser);
628
    return USB_RET_ASYNC;
629
}
630

    
631
static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
632
                                   int interface)
633
{
634
    struct usb_redir_get_alt_setting_header get_alt;
635
    AsyncURB *aurb = async_alloc(dev, p);
636

    
637
    DPRINTF("get interface %d id %u\n", interface, aurb->packet_id);
638

    
639
    get_alt.interface = interface;
640
    aurb->get = 1;
641
    usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
642
                                        &get_alt);
643
    usbredirparser_do_write(dev->parser);
644
    return USB_RET_ASYNC;
645
}
646

    
647
static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
648
        int request, int value, int index, int length, uint8_t *data)
649
{
650
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
651
    struct usb_redir_control_packet_header control_packet;
652
    AsyncURB *aurb;
653

    
654
    /* Special cases for certain standard device requests */
655
    switch (request) {
656
    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
657
        DPRINTF("set address %d\n", value);
658
        dev->dev.addr = value;
659
        return 0;
660
    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
661
        return usbredir_set_config(dev, p, value & 0xff);
662
    case DeviceRequest | USB_REQ_GET_CONFIGURATION:
663
        return usbredir_get_config(dev, p);
664
    case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
665
        return usbredir_set_interface(dev, p, index, value);
666
    case InterfaceRequest | USB_REQ_GET_INTERFACE:
667
        return usbredir_get_interface(dev, p, index);
668
    }
669

    
670
    /* "Normal" ctrl requests */
671
    aurb = async_alloc(dev, p);
672

    
673
    /* Note request is (bRequestType << 8) | bRequest */
674
    DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
675
            request >> 8, request & 0xff, value, index, length,
676
            aurb->packet_id);
677

    
678
    control_packet.request     = request & 0xFF;
679
    control_packet.requesttype = request >> 8;
680
    control_packet.endpoint    = control_packet.requesttype & USB_DIR_IN;
681
    control_packet.value       = value;
682
    control_packet.index       = index;
683
    control_packet.length      = length;
684
    aurb->control_packet       = control_packet;
685

    
686
    if (control_packet.requesttype & USB_DIR_IN) {
687
        usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
688
                                           &control_packet, NULL, 0);
689
    } else {
690
        usbredir_log_data(dev, "ctrl data out:", data, length);
691
        usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
692
                                           &control_packet, data, length);
693
    }
694
    usbredirparser_do_write(dev->parser);
695
    return USB_RET_ASYNC;
696
}
697

    
698
/*
699
 * Close events can be triggered by usbredirparser_do_write which gets called
700
 * from within the USBDevice data / control packet callbacks and doing a
701
 * usb_detach from within these callbacks is not a good idea.
702
 *
703
 * So we use a bh handler to take care of close events. We also handle
704
 * open events from this callback to make sure that a close directly followed
705
 * by an open gets handled in the right order.
706
 */
707
static void usbredir_open_close_bh(void *opaque)
708
{
709
    USBRedirDevice *dev = opaque;
710

    
711
    usbredir_device_disconnect(dev);
712

    
713
    if (dev->parser) {
714
        usbredirparser_destroy(dev->parser);
715
        dev->parser = NULL;
716
    }
717

    
718
    if (dev->cs->opened) {
719
        dev->parser = qemu_oom_check(usbredirparser_create());
720
        dev->parser->priv = dev;
721
        dev->parser->log_func = usbredir_log;
722
        dev->parser->read_func = usbredir_read;
723
        dev->parser->write_func = usbredir_write;
724
        dev->parser->device_connect_func = usbredir_device_connect;
725
        dev->parser->device_disconnect_func = usbredir_device_disconnect;
726
        dev->parser->interface_info_func = usbredir_interface_info;
727
        dev->parser->ep_info_func = usbredir_ep_info;
728
        dev->parser->configuration_status_func = usbredir_configuration_status;
729
        dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
730
        dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
731
        dev->parser->interrupt_receiving_status_func =
732
            usbredir_interrupt_receiving_status;
733
        dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
734
        dev->parser->control_packet_func = usbredir_control_packet;
735
        dev->parser->bulk_packet_func = usbredir_bulk_packet;
736
        dev->parser->iso_packet_func = usbredir_iso_packet;
737
        dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
738
        dev->read_buf = NULL;
739
        dev->read_buf_size = 0;
740
        usbredirparser_init(dev->parser, VERSION, NULL, 0, 0);
741
        usbredirparser_do_write(dev->parser);
742
    }
743
}
744

    
745
static void usbredir_do_attach(void *opaque)
746
{
747
    USBRedirDevice *dev = opaque;
748

    
749
    usb_device_attach(&dev->dev);
750
}
751

    
752
/*
753
 * chardev callbacks
754
 */
755

    
756
static int usbredir_chardev_can_read(void *opaque)
757
{
758
    USBRedirDevice *dev = opaque;
759

    
760
    if (dev->parser) {
761
        /* usbredir_parser_do_read will consume *all* data we give it */
762
        return 1024 * 1024;
763
    } else {
764
        /* usbredir_open_close_bh hasn't handled the open event yet */
765
        return 0;
766
    }
767
}
768

    
769
static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
770
{
771
    USBRedirDevice *dev = opaque;
772

    
773
    /* No recursion allowed! */
774
    assert(dev->read_buf == NULL);
775

    
776
    dev->read_buf = buf;
777
    dev->read_buf_size = size;
778

    
779
    usbredirparser_do_read(dev->parser);
780
    /* Send any acks, etc. which may be queued now */
781
    usbredirparser_do_write(dev->parser);
782
}
783

    
784
static void usbredir_chardev_event(void *opaque, int event)
785
{
786
    USBRedirDevice *dev = opaque;
787

    
788
    switch (event) {
789
    case CHR_EVENT_OPENED:
790
    case CHR_EVENT_CLOSED:
791
        qemu_bh_schedule(dev->open_close_bh);
792
        break;
793
    }
794
}
795

    
796
/*
797
 * init + destroy
798
 */
799

    
800
static int usbredir_initfn(USBDevice *udev)
801
{
802
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
803
    int i;
804

    
805
    if (dev->cs == NULL) {
806
        qerror_report(QERR_MISSING_PARAMETER, "chardev");
807
        return -1;
808
    }
809

    
810
    dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
811
    dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
812

    
813
    QTAILQ_INIT(&dev->asyncq);
814
    for (i = 0; i < MAX_ENDPOINTS; i++) {
815
        QTAILQ_INIT(&dev->endpoint[i].bufpq);
816
    }
817

    
818
    /* We'll do the attach once we receive the speed from the usb-host */
819
    udev->auto_attach = 0;
820

    
821
    /* Let the backend know we are ready */
822
    qemu_chr_fe_open(dev->cs);
823
    qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
824
                          usbredir_chardev_read, usbredir_chardev_event, dev);
825

    
826
    return 0;
827
}
828

    
829
static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
830
{
831
    AsyncURB *aurb, *next_aurb;
832
    int i;
833

    
834
    QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
835
        async_free(dev, aurb);
836
    }
837
    for (i = 0; i < MAX_ENDPOINTS; i++) {
838
        usbredir_free_bufpq(dev, I2EP(i));
839
    }
840
}
841

    
842
static void usbredir_handle_destroy(USBDevice *udev)
843
{
844
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
845

    
846
    qemu_chr_fe_close(dev->cs);
847
    qemu_chr_delete(dev->cs);
848
    /* Note must be done after qemu_chr_close, as that causes a close event */
849
    qemu_bh_delete(dev->open_close_bh);
850

    
851
    qemu_del_timer(dev->attach_timer);
852
    qemu_free_timer(dev->attach_timer);
853

    
854
    usbredir_cleanup_device_queues(dev);
855

    
856
    if (dev->parser) {
857
        usbredirparser_destroy(dev->parser);
858
    }
859
}
860

    
861
/*
862
 * usbredirparser packet complete callbacks
863
 */
864

    
865
static int usbredir_handle_status(USBRedirDevice *dev,
866
                                       int status, int actual_len)
867
{
868
    switch (status) {
869
    case usb_redir_success:
870
        return actual_len;
871
    case usb_redir_stall:
872
        return USB_RET_STALL;
873
    case usb_redir_cancelled:
874
        WARNING("returning cancelled packet to HC?\n");
875
    case usb_redir_inval:
876
    case usb_redir_ioerror:
877
    case usb_redir_timeout:
878
    default:
879
        return USB_RET_NAK;
880
    }
881
}
882

    
883
static void usbredir_device_connect(void *priv,
884
    struct usb_redir_device_connect_header *device_connect)
885
{
886
    USBRedirDevice *dev = priv;
887

    
888
    if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
889
        ERROR("Received device connect while already connected\n");
890
        return;
891
    }
892

    
893
    switch (device_connect->speed) {
894
    case usb_redir_speed_low:
895
        DPRINTF("attaching low speed device\n");
896
        dev->dev.speed = USB_SPEED_LOW;
897
        break;
898
    case usb_redir_speed_full:
899
        DPRINTF("attaching full speed device\n");
900
        dev->dev.speed = USB_SPEED_FULL;
901
        break;
902
    case usb_redir_speed_high:
903
        DPRINTF("attaching high speed device\n");
904
        dev->dev.speed = USB_SPEED_HIGH;
905
        break;
906
    case usb_redir_speed_super:
907
        DPRINTF("attaching super speed device\n");
908
        dev->dev.speed = USB_SPEED_SUPER;
909
        break;
910
    default:
911
        DPRINTF("attaching unknown speed device, assuming full speed\n");
912
        dev->dev.speed = USB_SPEED_FULL;
913
    }
914
    dev->dev.speedmask = (1 << dev->dev.speed);
915
    qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
916
}
917

    
918
static void usbredir_device_disconnect(void *priv)
919
{
920
    USBRedirDevice *dev = priv;
921
    int i;
922

    
923
    /* Stop any pending attaches */
924
    qemu_del_timer(dev->attach_timer);
925

    
926
    if (dev->dev.attached) {
927
        usb_device_detach(&dev->dev);
928
        /*
929
         * Delay next usb device attach to give the guest a chance to see
930
         * see the detach / attach in case of quick close / open succession
931
         */
932
        dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
933
    }
934

    
935
    /* Reset state so that the next dev connected starts with a clean slate */
936
    usbredir_cleanup_device_queues(dev);
937
    memset(dev->endpoint, 0, sizeof(dev->endpoint));
938
    for (i = 0; i < MAX_ENDPOINTS; i++) {
939
        QTAILQ_INIT(&dev->endpoint[i].bufpq);
940
    }
941
}
942

    
943
static void usbredir_interface_info(void *priv,
944
    struct usb_redir_interface_info_header *interface_info)
945
{
946
    /* The intention is to allow specifying acceptable interface classes
947
       for redirection on the cmdline and in the future verify this here,
948
       and disconnect (or never connect) the device if a not accepted
949
       interface class is detected */
950
}
951

    
952
static void usbredir_ep_info(void *priv,
953
    struct usb_redir_ep_info_header *ep_info)
954
{
955
    USBRedirDevice *dev = priv;
956
    int i;
957

    
958
    for (i = 0; i < MAX_ENDPOINTS; i++) {
959
        dev->endpoint[i].type = ep_info->type[i];
960
        dev->endpoint[i].interval = ep_info->interval[i];
961
        dev->endpoint[i].interface = ep_info->interface[i];
962
        if (dev->endpoint[i].type != usb_redir_type_invalid) {
963
            DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
964
                    dev->endpoint[i].type, dev->endpoint[i].interface);
965
        }
966
    }
967
}
968

    
969
static void usbredir_configuration_status(void *priv, uint32_t id,
970
    struct usb_redir_configuration_status_header *config_status)
971
{
972
    USBRedirDevice *dev = priv;
973
    AsyncURB *aurb;
974
    int len = 0;
975

    
976
    DPRINTF("set config status %d config %d id %u\n", config_status->status,
977
            config_status->configuration, id);
978

    
979
    aurb = async_find(dev, id);
980
    if (!aurb) {
981
        return;
982
    }
983
    if (aurb->packet) {
984
        if (aurb->get) {
985
            dev->dev.data_buf[0] = config_status->configuration;
986
            len = 1;
987
        }
988
        aurb->packet->result =
989
            usbredir_handle_status(dev, config_status->status, len);
990
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
991
    }
992
    async_free(dev, aurb);
993
}
994

    
995
static void usbredir_alt_setting_status(void *priv, uint32_t id,
996
    struct usb_redir_alt_setting_status_header *alt_setting_status)
997
{
998
    USBRedirDevice *dev = priv;
999
    AsyncURB *aurb;
1000
    int len = 0;
1001

    
1002
    DPRINTF("alt status %d intf %d alt %d id: %u\n",
1003
            alt_setting_status->status,
1004
            alt_setting_status->interface,
1005
            alt_setting_status->alt, id);
1006

    
1007
    aurb = async_find(dev, id);
1008
    if (!aurb) {
1009
        return;
1010
    }
1011
    if (aurb->packet) {
1012
        if (aurb->get) {
1013
            dev->dev.data_buf[0] = alt_setting_status->alt;
1014
            len = 1;
1015
        }
1016
        aurb->packet->result =
1017
            usbredir_handle_status(dev, alt_setting_status->status, len);
1018
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1019
    }
1020
    async_free(dev, aurb);
1021
}
1022

    
1023
static void usbredir_iso_stream_status(void *priv, uint32_t id,
1024
    struct usb_redir_iso_stream_status_header *iso_stream_status)
1025
{
1026
    USBRedirDevice *dev = priv;
1027
    uint8_t ep = iso_stream_status->endpoint;
1028

    
1029
    DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1030
            ep, id);
1031

    
1032
    if (!dev->dev.attached) {
1033
        return;
1034
    }
1035

    
1036
    dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
1037
    if (iso_stream_status->status == usb_redir_stall) {
1038
        DPRINTF("iso stream stopped by peer ep %02X\n", ep);
1039
        dev->endpoint[EP2I(ep)].iso_started = 0;
1040
    }
1041
}
1042

    
1043
static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1044
    struct usb_redir_interrupt_receiving_status_header
1045
    *interrupt_receiving_status)
1046
{
1047
    USBRedirDevice *dev = priv;
1048
    uint8_t ep = interrupt_receiving_status->endpoint;
1049

    
1050
    DPRINTF("interrupt recv status %d ep %02X id %u\n",
1051
            interrupt_receiving_status->status, ep, id);
1052

    
1053
    if (!dev->dev.attached) {
1054
        return;
1055
    }
1056

    
1057
    dev->endpoint[EP2I(ep)].interrupt_error =
1058
        interrupt_receiving_status->status;
1059
    if (interrupt_receiving_status->status == usb_redir_stall) {
1060
        DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep);
1061
        dev->endpoint[EP2I(ep)].interrupt_started = 0;
1062
    }
1063
}
1064

    
1065
static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1066
    struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1067
{
1068
}
1069

    
1070
static void usbredir_control_packet(void *priv, uint32_t id,
1071
    struct usb_redir_control_packet_header *control_packet,
1072
    uint8_t *data, int data_len)
1073
{
1074
    USBRedirDevice *dev = priv;
1075
    int len = control_packet->length;
1076
    AsyncURB *aurb;
1077

    
1078
    DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1079
            len, id);
1080

    
1081
    aurb = async_find(dev, id);
1082
    if (!aurb) {
1083
        free(data);
1084
        return;
1085
    }
1086

    
1087
    aurb->control_packet.status = control_packet->status;
1088
    aurb->control_packet.length = control_packet->length;
1089
    if (memcmp(&aurb->control_packet, control_packet,
1090
               sizeof(*control_packet))) {
1091
        ERROR("return control packet mismatch, please report this!\n");
1092
        len = USB_RET_NAK;
1093
    }
1094

    
1095
    if (aurb->packet) {
1096
        len = usbredir_handle_status(dev, control_packet->status, len);
1097
        if (len > 0) {
1098
            usbredir_log_data(dev, "ctrl data in:", data, data_len);
1099
            if (data_len <= sizeof(dev->dev.data_buf)) {
1100
                memcpy(dev->dev.data_buf, data, data_len);
1101
            } else {
1102
                ERROR("ctrl buffer too small (%d > %zu)\n",
1103
                      data_len, sizeof(dev->dev.data_buf));
1104
                len = USB_RET_STALL;
1105
            }
1106
        }
1107
        aurb->packet->result = len;
1108
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1109
    }
1110
    async_free(dev, aurb);
1111
    free(data);
1112
}
1113

    
1114
static void usbredir_bulk_packet(void *priv, uint32_t id,
1115
    struct usb_redir_bulk_packet_header *bulk_packet,
1116
    uint8_t *data, int data_len)
1117
{
1118
    USBRedirDevice *dev = priv;
1119
    uint8_t ep = bulk_packet->endpoint;
1120
    int len = bulk_packet->length;
1121
    AsyncURB *aurb;
1122

    
1123
    DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1124
            ep, len, id);
1125

    
1126
    aurb = async_find(dev, id);
1127
    if (!aurb) {
1128
        free(data);
1129
        return;
1130
    }
1131

    
1132
    if (aurb->bulk_packet.endpoint != bulk_packet->endpoint ||
1133
            aurb->bulk_packet.stream_id != bulk_packet->stream_id) {
1134
        ERROR("return bulk packet mismatch, please report this!\n");
1135
        len = USB_RET_NAK;
1136
    }
1137

    
1138
    if (aurb->packet) {
1139
        len = usbredir_handle_status(dev, bulk_packet->status, len);
1140
        if (len > 0) {
1141
            usbredir_log_data(dev, "bulk data in:", data, data_len);
1142
            if (data_len <= aurb->packet->iov.size) {
1143
                usb_packet_copy(aurb->packet, data, data_len);
1144
            } else {
1145
                ERROR("bulk buffer too small (%d > %zd)\n", data_len,
1146
                      aurb->packet->iov.size);
1147
                len = USB_RET_STALL;
1148
            }
1149
        }
1150
        aurb->packet->result = len;
1151
        usb_packet_complete(&dev->dev, aurb->packet);
1152
    }
1153
    async_free(dev, aurb);
1154
    free(data);
1155
}
1156

    
1157
static void usbredir_iso_packet(void *priv, uint32_t id,
1158
    struct usb_redir_iso_packet_header *iso_packet,
1159
    uint8_t *data, int data_len)
1160
{
1161
    USBRedirDevice *dev = priv;
1162
    uint8_t ep = iso_packet->endpoint;
1163

    
1164
    DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1165
             data_len, id);
1166

    
1167
    if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1168
        ERROR("received iso packet for non iso endpoint %02X\n", ep);
1169
        free(data);
1170
        return;
1171
    }
1172

    
1173
    if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1174
        DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1175
        free(data);
1176
        return;
1177
    }
1178

    
1179
    /* bufp_alloc also adds the packet to the ep queue */
1180
    bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1181
}
1182

    
1183
static void usbredir_interrupt_packet(void *priv, uint32_t id,
1184
    struct usb_redir_interrupt_packet_header *interrupt_packet,
1185
    uint8_t *data, int data_len)
1186
{
1187
    USBRedirDevice *dev = priv;
1188
    uint8_t ep = interrupt_packet->endpoint;
1189

    
1190
    DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1191
            interrupt_packet->status, ep, data_len, id);
1192

    
1193
    if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
1194
        ERROR("received int packet for non interrupt endpoint %02X\n", ep);
1195
        free(data);
1196
        return;
1197
    }
1198

    
1199
    if (ep & USB_DIR_IN) {
1200
        if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
1201
            DPRINTF("received int packet while not started ep %02X\n", ep);
1202
            free(data);
1203
            return;
1204
        }
1205

    
1206
        /* bufp_alloc also adds the packet to the ep queue */
1207
        bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
1208
    } else {
1209
        int len = interrupt_packet->length;
1210

    
1211
        AsyncURB *aurb = async_find(dev, id);
1212
        if (!aurb) {
1213
            return;
1214
        }
1215

    
1216
        if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
1217
            ERROR("return int packet mismatch, please report this!\n");
1218
            len = USB_RET_NAK;
1219
        }
1220

    
1221
        if (aurb->packet) {
1222
            aurb->packet->result = usbredir_handle_status(dev,
1223
                                               interrupt_packet->status, len);
1224
            usb_packet_complete(&dev->dev, aurb->packet);
1225
        }
1226
        async_free(dev, aurb);
1227
    }
1228
}
1229

    
1230
static struct USBDeviceInfo usbredir_dev_info = {
1231
    .product_desc   = "USB Redirection Device",
1232
    .qdev.name      = "usb-redir",
1233
    .qdev.size      = sizeof(USBRedirDevice),
1234
    .init           = usbredir_initfn,
1235
    .handle_destroy = usbredir_handle_destroy,
1236
    .handle_packet  = usb_generic_handle_packet,
1237
    .cancel_packet  = usbredir_cancel_packet,
1238
    .handle_reset   = usbredir_handle_reset,
1239
    .handle_data    = usbredir_handle_data,
1240
    .handle_control = usbredir_handle_control,
1241
    .qdev.props     = (Property[]) {
1242
        DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
1243
        DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
1244
        DEFINE_PROP_END_OF_LIST(),
1245
    },
1246
};
1247

    
1248
static void usbredir_register_devices(void)
1249
{
1250
    usb_qdev_register(&usbredir_dev_info);
1251
}
1252
device_init(usbredir_register_devices);