Statistics
| Branch: | Revision:

root / usb-redir.c @ c9c3c80a

History | View | Annotate | Download (42.6 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
    uint8_t bufpq_prefilled;
64
    uint8_t bufpq_dropping_packets;
65
    QTAILQ_HEAD(, buf_packet) bufpq;
66
    int bufpq_size;
67
    int bufpq_target_size;
68
};
69

    
70
struct USBRedirDevice {
71
    USBDevice dev;
72
    /* Properties */
73
    CharDriverState *cs;
74
    uint8_t debug;
75
    /* Data passed from chardev the fd_read cb to the usbredirparser read cb */
76
    const uint8_t *read_buf;
77
    int read_buf_size;
78
    /* For async handling of open/close */
79
    QEMUBH *open_close_bh;
80
    /* To delay the usb attach in case of quick chardev close + open */
81
    QEMUTimer *attach_timer;
82
    int64_t next_attach_time;
83
    struct usbredirparser *parser;
84
    struct endp_data endpoint[MAX_ENDPOINTS];
85
    uint32_t packet_id;
86
    QTAILQ_HEAD(, AsyncURB) asyncq;
87
};
88

    
89
struct AsyncURB {
90
    USBRedirDevice *dev;
91
    USBPacket *packet;
92
    uint32_t packet_id;
93
    int get;
94
    union {
95
        struct usb_redir_control_packet_header control_packet;
96
        struct usb_redir_bulk_packet_header bulk_packet;
97
        struct usb_redir_interrupt_packet_header interrupt_packet;
98
    };
99
    QTAILQ_ENTRY(AsyncURB)next;
100
};
101

    
102
static void usbredir_device_connect(void *priv,
103
    struct usb_redir_device_connect_header *device_connect);
104
static void usbredir_device_disconnect(void *priv);
105
static void usbredir_interface_info(void *priv,
106
    struct usb_redir_interface_info_header *interface_info);
107
static void usbredir_ep_info(void *priv,
108
    struct usb_redir_ep_info_header *ep_info);
109
static void usbredir_configuration_status(void *priv, uint32_t id,
110
    struct usb_redir_configuration_status_header *configuration_status);
111
static void usbredir_alt_setting_status(void *priv, uint32_t id,
112
    struct usb_redir_alt_setting_status_header *alt_setting_status);
113
static void usbredir_iso_stream_status(void *priv, uint32_t id,
114
    struct usb_redir_iso_stream_status_header *iso_stream_status);
115
static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
116
    struct usb_redir_interrupt_receiving_status_header
117
    *interrupt_receiving_status);
118
static void usbredir_bulk_streams_status(void *priv, uint32_t id,
119
    struct usb_redir_bulk_streams_status_header *bulk_streams_status);
120
static void usbredir_control_packet(void *priv, uint32_t id,
121
    struct usb_redir_control_packet_header *control_packet,
122
    uint8_t *data, int data_len);
123
static void usbredir_bulk_packet(void *priv, uint32_t id,
124
    struct usb_redir_bulk_packet_header *bulk_packet,
125
    uint8_t *data, int data_len);
126
static void usbredir_iso_packet(void *priv, uint32_t id,
127
    struct usb_redir_iso_packet_header *iso_packet,
128
    uint8_t *data, int data_len);
129
static void usbredir_interrupt_packet(void *priv, uint32_t id,
130
    struct usb_redir_interrupt_packet_header *interrupt_header,
131
    uint8_t *data, int data_len);
132

    
133
static int usbredir_handle_status(USBRedirDevice *dev,
134
                                       int status, int actual_len);
135

    
136
#define VERSION "qemu usb-redir guest " QEMU_VERSION
137

    
138
/*
139
 * Logging stuff
140
 */
141

    
142
#define ERROR(...) \
143
    do { \
144
        if (dev->debug >= usbredirparser_error) { \
145
            error_report("usb-redir error: " __VA_ARGS__); \
146
        } \
147
    } while (0)
148
#define WARNING(...) \
149
    do { \
150
        if (dev->debug >= usbredirparser_warning) { \
151
            error_report("usb-redir warning: " __VA_ARGS__); \
152
        } \
153
    } while (0)
154
#define INFO(...) \
155
    do { \
156
        if (dev->debug >= usbredirparser_info) { \
157
            error_report("usb-redir: " __VA_ARGS__); \
158
        } \
159
    } while (0)
160
#define DPRINTF(...) \
161
    do { \
162
        if (dev->debug >= usbredirparser_debug) { \
163
            error_report("usb-redir: " __VA_ARGS__); \
164
        } \
165
    } while (0)
166
#define DPRINTF2(...) \
167
    do { \
168
        if (dev->debug >= usbredirparser_debug_data) { \
169
            error_report("usb-redir: " __VA_ARGS__); \
170
        } \
171
    } while (0)
172

    
173
static void usbredir_log(void *priv, int level, const char *msg)
174
{
175
    USBRedirDevice *dev = priv;
176

    
177
    if (dev->debug < level) {
178
        return;
179
    }
180

    
181
    error_report("%s", msg);
182
}
183

    
184
static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
185
    const uint8_t *data, int len)
186
{
187
    int i, j, n;
188

    
189
    if (dev->debug < usbredirparser_debug_data) {
190
        return;
191
    }
192

    
193
    for (i = 0; i < len; i += j) {
194
        char buf[128];
195

    
196
        n = sprintf(buf, "%s", desc);
197
        for (j = 0; j < 8 && i + j < len; j++) {
198
            n += sprintf(buf + n, " %02X", data[i + j]);
199
        }
200
        error_report("%s", buf);
201
    }
202
}
203

    
204
/*
205
 * usbredirparser io functions
206
 */
207

    
208
static int usbredir_read(void *priv, uint8_t *data, int count)
209
{
210
    USBRedirDevice *dev = priv;
211

    
212
    if (dev->read_buf_size < count) {
213
        count = dev->read_buf_size;
214
    }
215

    
216
    memcpy(data, dev->read_buf, count);
217

    
218
    dev->read_buf_size -= count;
219
    if (dev->read_buf_size) {
220
        dev->read_buf += count;
221
    } else {
222
        dev->read_buf = NULL;
223
    }
224

    
225
    return count;
226
}
227

    
228
static int usbredir_write(void *priv, uint8_t *data, int count)
229
{
230
    USBRedirDevice *dev = priv;
231

    
232
    if (!dev->cs->opened) {
233
        return 0;
234
    }
235

    
236
    return qemu_chr_fe_write(dev->cs, data, count);
237
}
238

    
239
/*
240
 * Async and buffered packets helpers
241
 */
242

    
243
static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
244
{
245
    AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
246
    aurb->dev = dev;
247
    aurb->packet = p;
248
    aurb->packet_id = dev->packet_id;
249
    QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
250
    dev->packet_id++;
251

    
252
    return aurb;
253
}
254

    
255
static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
256
{
257
    QTAILQ_REMOVE(&dev->asyncq, aurb, next);
258
    g_free(aurb);
259
}
260

    
261
static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
262
{
263
    AsyncURB *aurb;
264

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

    
274
static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
275
{
276
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
277
    AsyncURB *aurb;
278

    
279
    QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
280
        if (p != aurb->packet) {
281
            continue;
282
        }
283

    
284
        DPRINTF("async cancel id %u\n", aurb->packet_id);
285
        usbredirparser_send_cancel_data_packet(dev->parser, aurb->packet_id);
286
        usbredirparser_do_write(dev->parser);
287

    
288
        /* Mark it as dead */
289
        aurb->packet = NULL;
290
        break;
291
    }
292
}
293

    
294
static void bufp_alloc(USBRedirDevice *dev,
295
    uint8_t *data, int len, int status, uint8_t ep)
296
{
297
    struct buf_packet *bufp;
298

    
299
    if (!dev->endpoint[EP2I(ep)].bufpq_dropping_packets &&
300
        dev->endpoint[EP2I(ep)].bufpq_size >
301
            2 * dev->endpoint[EP2I(ep)].bufpq_target_size) {
302
        DPRINTF("bufpq overflow, dropping packets ep %02X\n", ep);
303
        dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 1;
304
    }
305
    /* Since we're interupting the stream anyways, drop enough packets to get
306
       back to our target buffer size */
307
    if (dev->endpoint[EP2I(ep)].bufpq_dropping_packets) {
308
        if (dev->endpoint[EP2I(ep)].bufpq_size >
309
                dev->endpoint[EP2I(ep)].bufpq_target_size) {
310
            free(data);
311
            return;
312
        }
313
        dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
314
    }
315

    
316
    bufp = g_malloc(sizeof(struct buf_packet));
317
    bufp->data   = data;
318
    bufp->len    = len;
319
    bufp->status = status;
320
    QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
321
    dev->endpoint[EP2I(ep)].bufpq_size++;
322
}
323

    
324
static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
325
    uint8_t ep)
326
{
327
    QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
328
    dev->endpoint[EP2I(ep)].bufpq_size--;
329
    free(bufp->data);
330
    g_free(bufp);
331
}
332

    
333
static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
334
{
335
    struct buf_packet *buf, *buf_next;
336

    
337
    QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) {
338
        bufp_free(dev, buf, ep);
339
    }
340
}
341

    
342
/*
343
 * USBDevice callbacks
344
 */
345

    
346
static void usbredir_handle_reset(USBDevice *udev)
347
{
348
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
349

    
350
    DPRINTF("reset device\n");
351
    usbredirparser_send_reset(dev->parser);
352
    usbredirparser_do_write(dev->parser);
353
}
354

    
355
static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
356
                                     uint8_t ep)
357
{
358
    int status, len;
359
    if (!dev->endpoint[EP2I(ep)].iso_started &&
360
            !dev->endpoint[EP2I(ep)].iso_error) {
361
        struct usb_redir_start_iso_stream_header start_iso = {
362
            .endpoint = ep,
363
        };
364
        int pkts_per_sec;
365

    
366
        if (dev->dev.speed == USB_SPEED_HIGH) {
367
            pkts_per_sec = 8000 / dev->endpoint[EP2I(ep)].interval;
368
        } else {
369
            pkts_per_sec = 1000 / dev->endpoint[EP2I(ep)].interval;
370
        }
371
        /* Testing has shown that we need circa 60 ms buffer */
372
        dev->endpoint[EP2I(ep)].bufpq_target_size = (pkts_per_sec * 60) / 1000;
373

    
374
        /* Aim for approx 100 interrupts / second on the client to
375
           balance latency and interrupt load */
376
        start_iso.pkts_per_urb = pkts_per_sec / 100;
377
        if (start_iso.pkts_per_urb < 1) {
378
            start_iso.pkts_per_urb = 1;
379
        } else if (start_iso.pkts_per_urb > 32) {
380
            start_iso.pkts_per_urb = 32;
381
        }
382

    
383
        start_iso.no_urbs = (dev->endpoint[EP2I(ep)].bufpq_target_size +
384
                             start_iso.pkts_per_urb - 1) /
385
                            start_iso.pkts_per_urb;
386
        /* Output endpoints pre-fill only 1/2 of the packets, keeping the rest
387
           as overflow buffer. Also see the usbredir protocol documentation */
388
        if (!(ep & USB_DIR_IN)) {
389
            start_iso.no_urbs *= 2;
390
        }
391
        if (start_iso.no_urbs > 16) {
392
            start_iso.no_urbs = 16;
393
        }
394

    
395
        /* No id, we look at the ep when receiving a status back */
396
        usbredirparser_send_start_iso_stream(dev->parser, 0, &start_iso);
397
        usbredirparser_do_write(dev->parser);
398
        DPRINTF("iso stream started pkts/sec %d pkts/urb %d urbs %d ep %02X\n",
399
                pkts_per_sec, start_iso.pkts_per_urb, start_iso.no_urbs, ep);
400
        dev->endpoint[EP2I(ep)].iso_started = 1;
401
        dev->endpoint[EP2I(ep)].bufpq_prefilled = 0;
402
        dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
403
    }
404

    
405
    if (ep & USB_DIR_IN) {
406
        struct buf_packet *isop;
407

    
408
        if (dev->endpoint[EP2I(ep)].iso_started &&
409
                !dev->endpoint[EP2I(ep)].bufpq_prefilled) {
410
            if (dev->endpoint[EP2I(ep)].bufpq_size <
411
                    dev->endpoint[EP2I(ep)].bufpq_target_size) {
412
                return usbredir_handle_status(dev, 0, 0);
413
            }
414
            dev->endpoint[EP2I(ep)].bufpq_prefilled = 1;
415
        }
416

    
417
        isop = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
418
        if (isop == NULL) {
419
            DPRINTF("iso-token-in ep %02X, no isop, iso_error: %d\n",
420
                    ep, dev->endpoint[EP2I(ep)].iso_error);
421
            /* Re-fill the buffer */
422
            dev->endpoint[EP2I(ep)].bufpq_prefilled = 0;
423
            /* Check iso_error for stream errors, otherwise its an underrun */
424
            status = dev->endpoint[EP2I(ep)].iso_error;
425
            dev->endpoint[EP2I(ep)].iso_error = 0;
426
            return usbredir_handle_status(dev, status, 0);
427
        }
428
        DPRINTF2("iso-token-in ep %02X status %d len %d queue-size: %d\n", ep,
429
                 isop->status, isop->len, dev->endpoint[EP2I(ep)].bufpq_size);
430

    
431
        status = isop->status;
432
        if (status != usb_redir_success) {
433
            bufp_free(dev, isop, ep);
434
            return usbredir_handle_status(dev, status, 0);
435
        }
436

    
437
        len = isop->len;
438
        if (len > p->iov.size) {
439
            ERROR("received iso data is larger then packet ep %02X (%d > %d)\n",
440
                  ep, len, (int)p->iov.size);
441
            bufp_free(dev, isop, ep);
442
            return USB_RET_NAK;
443
        }
444
        usb_packet_copy(p, isop->data, len);
445
        bufp_free(dev, isop, ep);
446
        return len;
447
    } else {
448
        /* If the stream was not started because of a pending error don't
449
           send the packet to the usb-host */
450
        if (dev->endpoint[EP2I(ep)].iso_started) {
451
            struct usb_redir_iso_packet_header iso_packet = {
452
                .endpoint = ep,
453
                .length = p->iov.size
454
            };
455
            uint8_t buf[p->iov.size];
456
            /* No id, we look at the ep when receiving a status back */
457
            usb_packet_copy(p, buf, p->iov.size);
458
            usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,
459
                                           buf, p->iov.size);
460
            usbredirparser_do_write(dev->parser);
461
        }
462
        status = dev->endpoint[EP2I(ep)].iso_error;
463
        dev->endpoint[EP2I(ep)].iso_error = 0;
464
        DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep, status,
465
                 p->iov.size);
466
        return usbredir_handle_status(dev, status, p->iov.size);
467
    }
468
}
469

    
470
static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
471
{
472
    struct usb_redir_stop_iso_stream_header stop_iso_stream = {
473
        .endpoint = ep
474
    };
475
    if (dev->endpoint[EP2I(ep)].iso_started) {
476
        usbredirparser_send_stop_iso_stream(dev->parser, 0, &stop_iso_stream);
477
        DPRINTF("iso stream stopped ep %02X\n", ep);
478
        dev->endpoint[EP2I(ep)].iso_started = 0;
479
    }
480
    dev->endpoint[EP2I(ep)].iso_error = 0;
481
    usbredir_free_bufpq(dev, ep);
482
}
483

    
484
static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
485
                                      uint8_t ep)
486
{
487
    AsyncURB *aurb = async_alloc(dev, p);
488
    struct usb_redir_bulk_packet_header bulk_packet;
489

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

    
493
    bulk_packet.endpoint  = ep;
494
    bulk_packet.length    = p->iov.size;
495
    bulk_packet.stream_id = 0;
496
    aurb->bulk_packet = bulk_packet;
497

    
498
    if (ep & USB_DIR_IN) {
499
        usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
500
                                        &bulk_packet, NULL, 0);
501
    } else {
502
        uint8_t buf[p->iov.size];
503
        usb_packet_copy(p, buf, p->iov.size);
504
        usbredir_log_data(dev, "bulk data out:", buf, p->iov.size);
505
        usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
506
                                        &bulk_packet, buf, p->iov.size);
507
    }
508
    usbredirparser_do_write(dev->parser);
509
    return USB_RET_ASYNC;
510
}
511

    
512
static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
513
                                           USBPacket *p, uint8_t ep)
514
{
515
    if (ep & USB_DIR_IN) {
516
        /* Input interrupt endpoint, buffered packet input */
517
        struct buf_packet *intp;
518
        int status, len;
519

    
520
        if (!dev->endpoint[EP2I(ep)].interrupt_started &&
521
                !dev->endpoint[EP2I(ep)].interrupt_error) {
522
            struct usb_redir_start_interrupt_receiving_header start_int = {
523
                .endpoint = ep,
524
            };
525
            /* No id, we look at the ep when receiving a status back */
526
            usbredirparser_send_start_interrupt_receiving(dev->parser, 0,
527
                                                          &start_int);
528
            usbredirparser_do_write(dev->parser);
529
            DPRINTF("interrupt recv started ep %02X\n", ep);
530
            dev->endpoint[EP2I(ep)].interrupt_started = 1;
531
            /* We don't really want to drop interrupt packets ever, but
532
               having some upper limit to how much we buffer is good. */
533
            dev->endpoint[EP2I(ep)].bufpq_target_size = 1000;
534
            dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
535
        }
536

    
537
        intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
538
        if (intp == NULL) {
539
            DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);
540
            /* Check interrupt_error for stream errors */
541
            status = dev->endpoint[EP2I(ep)].interrupt_error;
542
            dev->endpoint[EP2I(ep)].interrupt_error = 0;
543
            return usbredir_handle_status(dev, status, 0);
544
        }
545
        DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,
546
                intp->status, intp->len);
547

    
548
        status = intp->status;
549
        if (status != usb_redir_success) {
550
            bufp_free(dev, intp, ep);
551
            return usbredir_handle_status(dev, status, 0);
552
        }
553

    
554
        len = intp->len;
555
        if (len > p->iov.size) {
556
            ERROR("received int data is larger then packet ep %02X\n", ep);
557
            bufp_free(dev, intp, ep);
558
            return USB_RET_NAK;
559
        }
560
        usb_packet_copy(p, intp->data, len);
561
        bufp_free(dev, intp, ep);
562
        return len;
563
    } else {
564
        /* Output interrupt endpoint, normal async operation */
565
        AsyncURB *aurb = async_alloc(dev, p);
566
        struct usb_redir_interrupt_packet_header interrupt_packet;
567
        uint8_t buf[p->iov.size];
568

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

    
572
        interrupt_packet.endpoint  = ep;
573
        interrupt_packet.length    = p->iov.size;
574
        aurb->interrupt_packet     = interrupt_packet;
575

    
576
        usb_packet_copy(p, buf, p->iov.size);
577
        usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);
578
        usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
579
                                        &interrupt_packet, buf, p->iov.size);
580
        usbredirparser_do_write(dev->parser);
581
        return USB_RET_ASYNC;
582
    }
583
}
584

    
585
static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev,
586
    uint8_t ep)
587
{
588
    struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv = {
589
        .endpoint = ep
590
    };
591
    if (dev->endpoint[EP2I(ep)].interrupt_started) {
592
        usbredirparser_send_stop_interrupt_receiving(dev->parser, 0,
593
                                                     &stop_interrupt_recv);
594
        DPRINTF("interrupt recv stopped ep %02X\n", ep);
595
        dev->endpoint[EP2I(ep)].interrupt_started = 0;
596
    }
597
    dev->endpoint[EP2I(ep)].interrupt_error = 0;
598
    usbredir_free_bufpq(dev, ep);
599
}
600

    
601
static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
602
{
603
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
604
    uint8_t ep;
605

    
606
    ep = p->devep;
607
    if (p->pid == USB_TOKEN_IN) {
608
        ep |= USB_DIR_IN;
609
    }
610

    
611
    switch (dev->endpoint[EP2I(ep)].type) {
612
    case USB_ENDPOINT_XFER_CONTROL:
613
        ERROR("handle_data called for control transfer on ep %02X\n", ep);
614
        return USB_RET_NAK;
615
    case USB_ENDPOINT_XFER_ISOC:
616
        return usbredir_handle_iso_data(dev, p, ep);
617
    case USB_ENDPOINT_XFER_BULK:
618
        return usbredir_handle_bulk_data(dev, p, ep);
619
    case USB_ENDPOINT_XFER_INT:
620
        return usbredir_handle_interrupt_data(dev, p, ep);
621
    default:
622
        ERROR("handle_data ep %02X has unknown type %d\n", ep,
623
              dev->endpoint[EP2I(ep)].type);
624
        return USB_RET_NAK;
625
    }
626
}
627

    
628
static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
629
                                int config)
630
{
631
    struct usb_redir_set_configuration_header set_config;
632
    AsyncURB *aurb = async_alloc(dev, p);
633
    int i;
634

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

    
637
    for (i = 0; i < MAX_ENDPOINTS; i++) {
638
        switch (dev->endpoint[i].type) {
639
        case USB_ENDPOINT_XFER_ISOC:
640
            usbredir_stop_iso_stream(dev, I2EP(i));
641
            break;
642
        case USB_ENDPOINT_XFER_INT:
643
            if (i & 0x10) {
644
                usbredir_stop_interrupt_receiving(dev, I2EP(i));
645
            }
646
            break;
647
        }
648
        usbredir_free_bufpq(dev, I2EP(i));
649
    }
650

    
651
    set_config.configuration = config;
652
    usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
653
                                          &set_config);
654
    usbredirparser_do_write(dev->parser);
655
    return USB_RET_ASYNC;
656
}
657

    
658
static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
659
{
660
    AsyncURB *aurb = async_alloc(dev, p);
661

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

    
664
    aurb->get = 1;
665
    usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
666
    usbredirparser_do_write(dev->parser);
667
    return USB_RET_ASYNC;
668
}
669

    
670
static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
671
                                   int interface, int alt)
672
{
673
    struct usb_redir_set_alt_setting_header set_alt;
674
    AsyncURB *aurb = async_alloc(dev, p);
675
    int i;
676

    
677
    DPRINTF("set interface %d alt %d id %u\n", interface, alt,
678
            aurb->packet_id);
679

    
680
    for (i = 0; i < MAX_ENDPOINTS; i++) {
681
        if (dev->endpoint[i].interface == interface) {
682
            switch (dev->endpoint[i].type) {
683
            case USB_ENDPOINT_XFER_ISOC:
684
                usbredir_stop_iso_stream(dev, I2EP(i));
685
                break;
686
            case USB_ENDPOINT_XFER_INT:
687
                if (i & 0x10) {
688
                    usbredir_stop_interrupt_receiving(dev, I2EP(i));
689
                }
690
                break;
691
            }
692
            usbredir_free_bufpq(dev, I2EP(i));
693
        }
694
    }
695

    
696
    set_alt.interface = interface;
697
    set_alt.alt = alt;
698
    usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
699
                                        &set_alt);
700
    usbredirparser_do_write(dev->parser);
701
    return USB_RET_ASYNC;
702
}
703

    
704
static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
705
                                   int interface)
706
{
707
    struct usb_redir_get_alt_setting_header get_alt;
708
    AsyncURB *aurb = async_alloc(dev, p);
709

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

    
712
    get_alt.interface = interface;
713
    aurb->get = 1;
714
    usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
715
                                        &get_alt);
716
    usbredirparser_do_write(dev->parser);
717
    return USB_RET_ASYNC;
718
}
719

    
720
static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
721
        int request, int value, int index, int length, uint8_t *data)
722
{
723
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
724
    struct usb_redir_control_packet_header control_packet;
725
    AsyncURB *aurb;
726

    
727
    /* Special cases for certain standard device requests */
728
    switch (request) {
729
    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
730
        DPRINTF("set address %d\n", value);
731
        dev->dev.addr = value;
732
        return 0;
733
    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
734
        return usbredir_set_config(dev, p, value & 0xff);
735
    case DeviceRequest | USB_REQ_GET_CONFIGURATION:
736
        return usbredir_get_config(dev, p);
737
    case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
738
        return usbredir_set_interface(dev, p, index, value);
739
    case InterfaceRequest | USB_REQ_GET_INTERFACE:
740
        return usbredir_get_interface(dev, p, index);
741
    }
742

    
743
    /* "Normal" ctrl requests */
744
    aurb = async_alloc(dev, p);
745

    
746
    /* Note request is (bRequestType << 8) | bRequest */
747
    DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
748
            request >> 8, request & 0xff, value, index, length,
749
            aurb->packet_id);
750

    
751
    control_packet.request     = request & 0xFF;
752
    control_packet.requesttype = request >> 8;
753
    control_packet.endpoint    = control_packet.requesttype & USB_DIR_IN;
754
    control_packet.value       = value;
755
    control_packet.index       = index;
756
    control_packet.length      = length;
757
    aurb->control_packet       = control_packet;
758

    
759
    if (control_packet.requesttype & USB_DIR_IN) {
760
        usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
761
                                           &control_packet, NULL, 0);
762
    } else {
763
        usbredir_log_data(dev, "ctrl data out:", data, length);
764
        usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
765
                                           &control_packet, data, length);
766
    }
767
    usbredirparser_do_write(dev->parser);
768
    return USB_RET_ASYNC;
769
}
770

    
771
/*
772
 * Close events can be triggered by usbredirparser_do_write which gets called
773
 * from within the USBDevice data / control packet callbacks and doing a
774
 * usb_detach from within these callbacks is not a good idea.
775
 *
776
 * So we use a bh handler to take care of close events. We also handle
777
 * open events from this callback to make sure that a close directly followed
778
 * by an open gets handled in the right order.
779
 */
780
static void usbredir_open_close_bh(void *opaque)
781
{
782
    USBRedirDevice *dev = opaque;
783

    
784
    usbredir_device_disconnect(dev);
785

    
786
    if (dev->parser) {
787
        usbredirparser_destroy(dev->parser);
788
        dev->parser = NULL;
789
    }
790

    
791
    if (dev->cs->opened) {
792
        dev->parser = qemu_oom_check(usbredirparser_create());
793
        dev->parser->priv = dev;
794
        dev->parser->log_func = usbredir_log;
795
        dev->parser->read_func = usbredir_read;
796
        dev->parser->write_func = usbredir_write;
797
        dev->parser->device_connect_func = usbredir_device_connect;
798
        dev->parser->device_disconnect_func = usbredir_device_disconnect;
799
        dev->parser->interface_info_func = usbredir_interface_info;
800
        dev->parser->ep_info_func = usbredir_ep_info;
801
        dev->parser->configuration_status_func = usbredir_configuration_status;
802
        dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
803
        dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
804
        dev->parser->interrupt_receiving_status_func =
805
            usbredir_interrupt_receiving_status;
806
        dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
807
        dev->parser->control_packet_func = usbredir_control_packet;
808
        dev->parser->bulk_packet_func = usbredir_bulk_packet;
809
        dev->parser->iso_packet_func = usbredir_iso_packet;
810
        dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
811
        dev->read_buf = NULL;
812
        dev->read_buf_size = 0;
813
        usbredirparser_init(dev->parser, VERSION, NULL, 0, 0);
814
        usbredirparser_do_write(dev->parser);
815
    }
816
}
817

    
818
static void usbredir_do_attach(void *opaque)
819
{
820
    USBRedirDevice *dev = opaque;
821

    
822
    usb_device_attach(&dev->dev);
823
}
824

    
825
/*
826
 * chardev callbacks
827
 */
828

    
829
static int usbredir_chardev_can_read(void *opaque)
830
{
831
    USBRedirDevice *dev = opaque;
832

    
833
    if (dev->parser) {
834
        /* usbredir_parser_do_read will consume *all* data we give it */
835
        return 1024 * 1024;
836
    } else {
837
        /* usbredir_open_close_bh hasn't handled the open event yet */
838
        return 0;
839
    }
840
}
841

    
842
static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
843
{
844
    USBRedirDevice *dev = opaque;
845

    
846
    /* No recursion allowed! */
847
    assert(dev->read_buf == NULL);
848

    
849
    dev->read_buf = buf;
850
    dev->read_buf_size = size;
851

    
852
    usbredirparser_do_read(dev->parser);
853
    /* Send any acks, etc. which may be queued now */
854
    usbredirparser_do_write(dev->parser);
855
}
856

    
857
static void usbredir_chardev_event(void *opaque, int event)
858
{
859
    USBRedirDevice *dev = opaque;
860

    
861
    switch (event) {
862
    case CHR_EVENT_OPENED:
863
    case CHR_EVENT_CLOSED:
864
        qemu_bh_schedule(dev->open_close_bh);
865
        break;
866
    }
867
}
868

    
869
/*
870
 * init + destroy
871
 */
872

    
873
static int usbredir_initfn(USBDevice *udev)
874
{
875
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
876
    int i;
877

    
878
    if (dev->cs == NULL) {
879
        qerror_report(QERR_MISSING_PARAMETER, "chardev");
880
        return -1;
881
    }
882

    
883
    dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
884
    dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
885

    
886
    QTAILQ_INIT(&dev->asyncq);
887
    for (i = 0; i < MAX_ENDPOINTS; i++) {
888
        QTAILQ_INIT(&dev->endpoint[i].bufpq);
889
    }
890

    
891
    /* We'll do the attach once we receive the speed from the usb-host */
892
    udev->auto_attach = 0;
893

    
894
    /* Let the backend know we are ready */
895
    qemu_chr_fe_open(dev->cs);
896
    qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
897
                          usbredir_chardev_read, usbredir_chardev_event, dev);
898

    
899
    return 0;
900
}
901

    
902
static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
903
{
904
    AsyncURB *aurb, *next_aurb;
905
    int i;
906

    
907
    QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
908
        async_free(dev, aurb);
909
    }
910
    for (i = 0; i < MAX_ENDPOINTS; i++) {
911
        usbredir_free_bufpq(dev, I2EP(i));
912
    }
913
}
914

    
915
static void usbredir_handle_destroy(USBDevice *udev)
916
{
917
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
918

    
919
    qemu_chr_fe_close(dev->cs);
920
    qemu_chr_delete(dev->cs);
921
    /* Note must be done after qemu_chr_close, as that causes a close event */
922
    qemu_bh_delete(dev->open_close_bh);
923

    
924
    qemu_del_timer(dev->attach_timer);
925
    qemu_free_timer(dev->attach_timer);
926

    
927
    usbredir_cleanup_device_queues(dev);
928

    
929
    if (dev->parser) {
930
        usbredirparser_destroy(dev->parser);
931
    }
932
}
933

    
934
/*
935
 * usbredirparser packet complete callbacks
936
 */
937

    
938
static int usbredir_handle_status(USBRedirDevice *dev,
939
                                       int status, int actual_len)
940
{
941
    switch (status) {
942
    case usb_redir_success:
943
        return actual_len;
944
    case usb_redir_stall:
945
        return USB_RET_STALL;
946
    case usb_redir_cancelled:
947
        WARNING("returning cancelled packet to HC?\n");
948
    case usb_redir_inval:
949
    case usb_redir_ioerror:
950
    case usb_redir_timeout:
951
    default:
952
        return USB_RET_NAK;
953
    }
954
}
955

    
956
static void usbredir_device_connect(void *priv,
957
    struct usb_redir_device_connect_header *device_connect)
958
{
959
    USBRedirDevice *dev = priv;
960

    
961
    if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
962
        ERROR("Received device connect while already connected\n");
963
        return;
964
    }
965

    
966
    switch (device_connect->speed) {
967
    case usb_redir_speed_low:
968
        DPRINTF("attaching low speed device\n");
969
        dev->dev.speed = USB_SPEED_LOW;
970
        break;
971
    case usb_redir_speed_full:
972
        DPRINTF("attaching full speed device\n");
973
        dev->dev.speed = USB_SPEED_FULL;
974
        break;
975
    case usb_redir_speed_high:
976
        DPRINTF("attaching high speed device\n");
977
        dev->dev.speed = USB_SPEED_HIGH;
978
        break;
979
    case usb_redir_speed_super:
980
        DPRINTF("attaching super speed device\n");
981
        dev->dev.speed = USB_SPEED_SUPER;
982
        break;
983
    default:
984
        DPRINTF("attaching unknown speed device, assuming full speed\n");
985
        dev->dev.speed = USB_SPEED_FULL;
986
    }
987
    dev->dev.speedmask = (1 << dev->dev.speed);
988
    qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
989
}
990

    
991
static void usbredir_device_disconnect(void *priv)
992
{
993
    USBRedirDevice *dev = priv;
994
    int i;
995

    
996
    /* Stop any pending attaches */
997
    qemu_del_timer(dev->attach_timer);
998

    
999
    if (dev->dev.attached) {
1000
        usb_device_detach(&dev->dev);
1001
        /*
1002
         * Delay next usb device attach to give the guest a chance to see
1003
         * see the detach / attach in case of quick close / open succession
1004
         */
1005
        dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
1006
    }
1007

    
1008
    /* Reset state so that the next dev connected starts with a clean slate */
1009
    usbredir_cleanup_device_queues(dev);
1010
    memset(dev->endpoint, 0, sizeof(dev->endpoint));
1011
    for (i = 0; i < MAX_ENDPOINTS; i++) {
1012
        QTAILQ_INIT(&dev->endpoint[i].bufpq);
1013
    }
1014
}
1015

    
1016
static void usbredir_interface_info(void *priv,
1017
    struct usb_redir_interface_info_header *interface_info)
1018
{
1019
    /* The intention is to allow specifying acceptable interface classes
1020
       for redirection on the cmdline and in the future verify this here,
1021
       and disconnect (or never connect) the device if a not accepted
1022
       interface class is detected */
1023
}
1024

    
1025
static void usbredir_ep_info(void *priv,
1026
    struct usb_redir_ep_info_header *ep_info)
1027
{
1028
    USBRedirDevice *dev = priv;
1029
    int i;
1030

    
1031
    for (i = 0; i < MAX_ENDPOINTS; i++) {
1032
        dev->endpoint[i].type = ep_info->type[i];
1033
        dev->endpoint[i].interval = ep_info->interval[i];
1034
        dev->endpoint[i].interface = ep_info->interface[i];
1035
        switch (dev->endpoint[i].type) {
1036
        case usb_redir_type_invalid:
1037
            break;
1038
        case usb_redir_type_iso:
1039
        case usb_redir_type_interrupt:
1040
            if (dev->endpoint[i].interval == 0) {
1041
                ERROR("Received 0 interval for isoc or irq endpoint\n");
1042
                usbredir_device_disconnect(dev);
1043
            }
1044
            /* Fall through */
1045
        case usb_redir_type_control:
1046
        case usb_redir_type_bulk:
1047
            DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
1048
                    dev->endpoint[i].type, dev->endpoint[i].interface);
1049
            break;
1050
        default:
1051
            ERROR("Received invalid endpoint type\n");
1052
            usbredir_device_disconnect(dev);
1053
        }
1054
    }
1055
}
1056

    
1057
static void usbredir_configuration_status(void *priv, uint32_t id,
1058
    struct usb_redir_configuration_status_header *config_status)
1059
{
1060
    USBRedirDevice *dev = priv;
1061
    AsyncURB *aurb;
1062
    int len = 0;
1063

    
1064
    DPRINTF("set config status %d config %d id %u\n", config_status->status,
1065
            config_status->configuration, id);
1066

    
1067
    aurb = async_find(dev, id);
1068
    if (!aurb) {
1069
        return;
1070
    }
1071
    if (aurb->packet) {
1072
        if (aurb->get) {
1073
            dev->dev.data_buf[0] = config_status->configuration;
1074
            len = 1;
1075
        }
1076
        aurb->packet->result =
1077
            usbredir_handle_status(dev, config_status->status, len);
1078
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1079
    }
1080
    async_free(dev, aurb);
1081
}
1082

    
1083
static void usbredir_alt_setting_status(void *priv, uint32_t id,
1084
    struct usb_redir_alt_setting_status_header *alt_setting_status)
1085
{
1086
    USBRedirDevice *dev = priv;
1087
    AsyncURB *aurb;
1088
    int len = 0;
1089

    
1090
    DPRINTF("alt status %d intf %d alt %d id: %u\n",
1091
            alt_setting_status->status,
1092
            alt_setting_status->interface,
1093
            alt_setting_status->alt, id);
1094

    
1095
    aurb = async_find(dev, id);
1096
    if (!aurb) {
1097
        return;
1098
    }
1099
    if (aurb->packet) {
1100
        if (aurb->get) {
1101
            dev->dev.data_buf[0] = alt_setting_status->alt;
1102
            len = 1;
1103
        }
1104
        aurb->packet->result =
1105
            usbredir_handle_status(dev, alt_setting_status->status, len);
1106
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1107
    }
1108
    async_free(dev, aurb);
1109
}
1110

    
1111
static void usbredir_iso_stream_status(void *priv, uint32_t id,
1112
    struct usb_redir_iso_stream_status_header *iso_stream_status)
1113
{
1114
    USBRedirDevice *dev = priv;
1115
    uint8_t ep = iso_stream_status->endpoint;
1116

    
1117
    DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1118
            ep, id);
1119

    
1120
    if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].iso_started) {
1121
        return;
1122
    }
1123

    
1124
    dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
1125
    if (iso_stream_status->status == usb_redir_stall) {
1126
        DPRINTF("iso stream stopped by peer ep %02X\n", ep);
1127
        dev->endpoint[EP2I(ep)].iso_started = 0;
1128
    }
1129
}
1130

    
1131
static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1132
    struct usb_redir_interrupt_receiving_status_header
1133
    *interrupt_receiving_status)
1134
{
1135
    USBRedirDevice *dev = priv;
1136
    uint8_t ep = interrupt_receiving_status->endpoint;
1137

    
1138
    DPRINTF("interrupt recv status %d ep %02X id %u\n",
1139
            interrupt_receiving_status->status, ep, id);
1140

    
1141
    if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].interrupt_started) {
1142
        return;
1143
    }
1144

    
1145
    dev->endpoint[EP2I(ep)].interrupt_error =
1146
        interrupt_receiving_status->status;
1147
    if (interrupt_receiving_status->status == usb_redir_stall) {
1148
        DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep);
1149
        dev->endpoint[EP2I(ep)].interrupt_started = 0;
1150
    }
1151
}
1152

    
1153
static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1154
    struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1155
{
1156
}
1157

    
1158
static void usbredir_control_packet(void *priv, uint32_t id,
1159
    struct usb_redir_control_packet_header *control_packet,
1160
    uint8_t *data, int data_len)
1161
{
1162
    USBRedirDevice *dev = priv;
1163
    int len = control_packet->length;
1164
    AsyncURB *aurb;
1165

    
1166
    DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1167
            len, id);
1168

    
1169
    aurb = async_find(dev, id);
1170
    if (!aurb) {
1171
        free(data);
1172
        return;
1173
    }
1174

    
1175
    aurb->control_packet.status = control_packet->status;
1176
    aurb->control_packet.length = control_packet->length;
1177
    if (memcmp(&aurb->control_packet, control_packet,
1178
               sizeof(*control_packet))) {
1179
        ERROR("return control packet mismatch, please report this!\n");
1180
        len = USB_RET_NAK;
1181
    }
1182

    
1183
    if (aurb->packet) {
1184
        len = usbredir_handle_status(dev, control_packet->status, len);
1185
        if (len > 0) {
1186
            usbredir_log_data(dev, "ctrl data in:", data, data_len);
1187
            if (data_len <= sizeof(dev->dev.data_buf)) {
1188
                memcpy(dev->dev.data_buf, data, data_len);
1189
            } else {
1190
                ERROR("ctrl buffer too small (%d > %zu)\n",
1191
                      data_len, sizeof(dev->dev.data_buf));
1192
                len = USB_RET_STALL;
1193
            }
1194
        }
1195
        aurb->packet->result = len;
1196
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1197
    }
1198
    async_free(dev, aurb);
1199
    free(data);
1200
}
1201

    
1202
static void usbredir_bulk_packet(void *priv, uint32_t id,
1203
    struct usb_redir_bulk_packet_header *bulk_packet,
1204
    uint8_t *data, int data_len)
1205
{
1206
    USBRedirDevice *dev = priv;
1207
    uint8_t ep = bulk_packet->endpoint;
1208
    int len = bulk_packet->length;
1209
    AsyncURB *aurb;
1210

    
1211
    DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1212
            ep, len, id);
1213

    
1214
    aurb = async_find(dev, id);
1215
    if (!aurb) {
1216
        free(data);
1217
        return;
1218
    }
1219

    
1220
    if (aurb->bulk_packet.endpoint != bulk_packet->endpoint ||
1221
            aurb->bulk_packet.stream_id != bulk_packet->stream_id) {
1222
        ERROR("return bulk packet mismatch, please report this!\n");
1223
        len = USB_RET_NAK;
1224
    }
1225

    
1226
    if (aurb->packet) {
1227
        len = usbredir_handle_status(dev, bulk_packet->status, len);
1228
        if (len > 0) {
1229
            usbredir_log_data(dev, "bulk data in:", data, data_len);
1230
            if (data_len <= aurb->packet->iov.size) {
1231
                usb_packet_copy(aurb->packet, data, data_len);
1232
            } else {
1233
                ERROR("bulk buffer too small (%d > %zd)\n", data_len,
1234
                      aurb->packet->iov.size);
1235
                len = USB_RET_STALL;
1236
            }
1237
        }
1238
        aurb->packet->result = len;
1239
        usb_packet_complete(&dev->dev, aurb->packet);
1240
    }
1241
    async_free(dev, aurb);
1242
    free(data);
1243
}
1244

    
1245
static void usbredir_iso_packet(void *priv, uint32_t id,
1246
    struct usb_redir_iso_packet_header *iso_packet,
1247
    uint8_t *data, int data_len)
1248
{
1249
    USBRedirDevice *dev = priv;
1250
    uint8_t ep = iso_packet->endpoint;
1251

    
1252
    DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1253
             data_len, id);
1254

    
1255
    if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1256
        ERROR("received iso packet for non iso endpoint %02X\n", ep);
1257
        free(data);
1258
        return;
1259
    }
1260

    
1261
    if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1262
        DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1263
        free(data);
1264
        return;
1265
    }
1266

    
1267
    /* bufp_alloc also adds the packet to the ep queue */
1268
    bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1269
}
1270

    
1271
static void usbredir_interrupt_packet(void *priv, uint32_t id,
1272
    struct usb_redir_interrupt_packet_header *interrupt_packet,
1273
    uint8_t *data, int data_len)
1274
{
1275
    USBRedirDevice *dev = priv;
1276
    uint8_t ep = interrupt_packet->endpoint;
1277

    
1278
    DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1279
            interrupt_packet->status, ep, data_len, id);
1280

    
1281
    if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
1282
        ERROR("received int packet for non interrupt endpoint %02X\n", ep);
1283
        free(data);
1284
        return;
1285
    }
1286

    
1287
    if (ep & USB_DIR_IN) {
1288
        if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
1289
            DPRINTF("received int packet while not started ep %02X\n", ep);
1290
            free(data);
1291
            return;
1292
        }
1293

    
1294
        /* bufp_alloc also adds the packet to the ep queue */
1295
        bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
1296
    } else {
1297
        int len = interrupt_packet->length;
1298

    
1299
        AsyncURB *aurb = async_find(dev, id);
1300
        if (!aurb) {
1301
            return;
1302
        }
1303

    
1304
        if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
1305
            ERROR("return int packet mismatch, please report this!\n");
1306
            len = USB_RET_NAK;
1307
        }
1308

    
1309
        if (aurb->packet) {
1310
            aurb->packet->result = usbredir_handle_status(dev,
1311
                                               interrupt_packet->status, len);
1312
            usb_packet_complete(&dev->dev, aurb->packet);
1313
        }
1314
        async_free(dev, aurb);
1315
    }
1316
}
1317

    
1318
static struct USBDeviceInfo usbredir_dev_info = {
1319
    .product_desc   = "USB Redirection Device",
1320
    .qdev.name      = "usb-redir",
1321
    .qdev.size      = sizeof(USBRedirDevice),
1322
    .init           = usbredir_initfn,
1323
    .handle_destroy = usbredir_handle_destroy,
1324
    .handle_packet  = usb_generic_handle_packet,
1325
    .cancel_packet  = usbredir_cancel_packet,
1326
    .handle_reset   = usbredir_handle_reset,
1327
    .handle_data    = usbredir_handle_data,
1328
    .handle_control = usbredir_handle_control,
1329
    .qdev.props     = (Property[]) {
1330
        DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
1331
        DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
1332
        DEFINE_PROP_END_OF_LIST(),
1333
    },
1334
};
1335

    
1336
static void usbredir_register_devices(void)
1337
{
1338
    usb_qdev_register(&usbredir_dev_info);
1339
}
1340
device_init(usbredir_register_devices);