Statistics
| Branch: | Revision:

root / usb-redir.c @ 7fc7e584

History | View | Annotate | Download (38.3 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\n", msg);
178
}
179

    
180
static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
181
    const uint8_t *data, int len)
182
{
183
    int i, j, n;
184

    
185
    if (dev->debug < usbredirparser_debug_data) {
186
        return;
187
    }
188

    
189
    for (i = 0; i < len; i += j) {
190
        char buf[128];
191

    
192
        n = sprintf(buf, "%s", desc);
193
        for (j = 0; j < 8 && i + j < len; j++) {
194
            n += sprintf(buf + n, " %02X", data[i + j]);
195
        }
196
        error_report("%s\n", buf);
197
    }
198
}
199

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

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

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

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

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

    
221
    return count;
222
}
223

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

    
228
    return qemu_chr_fe_write(dev->cs, data, count);
229
}
230

    
231
/*
232
 * Async and buffered packets helpers
233
 */
234

    
235
static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
236
{
237
    AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
238
    aurb->dev = dev;
239
    aurb->packet = p;
240
    aurb->packet_id = dev->packet_id;
241
    QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
242
    dev->packet_id++;
243

    
244
    return aurb;
245
}
246

    
247
static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
248
{
249
    QTAILQ_REMOVE(&dev->asyncq, aurb, next);
250
    g_free(aurb);
251
}
252

    
253
static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
254
{
255
    AsyncURB *aurb;
256

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

    
266
static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
267
{
268
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
269
    AsyncURB *aurb;
270

    
271
    QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
272
        if (p != aurb->packet) {
273
            continue;
274
        }
275

    
276
        DPRINTF("async cancel id %u\n", aurb->packet_id);
277
        usbredirparser_send_cancel_data_packet(dev->parser, aurb->packet_id);
278
        usbredirparser_do_write(dev->parser);
279

    
280
        /* Mark it as dead */
281
        aurb->packet = NULL;
282
        break;
283
    }
284
}
285

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

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

    
305
static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
306
{
307
    struct buf_packet *buf, *buf_next;
308

    
309
    QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) {
310
        bufp_free(dev, buf, ep);
311
    }
312
}
313

    
314
/*
315
 * USBDevice callbacks
316
 */
317

    
318
static void usbredir_handle_reset(USBDevice *udev)
319
{
320
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
321

    
322
    DPRINTF("reset device\n");
323
    usbredirparser_send_reset(dev->parser);
324
    usbredirparser_do_write(dev->parser);
325
}
326

    
327
static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
328
                                     uint8_t ep)
329
{
330
    int status, len;
331

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

    
347
    if (ep & USB_DIR_IN) {
348
        struct buf_packet *isop;
349

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

    
361
        status = isop->status;
362
        if (status != usb_redir_success) {
363
            bufp_free(dev, isop, ep);
364
            return usbredir_handle_status(dev, status, 0);
365
        }
366

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

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

    
412
static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
413
                                      uint8_t ep)
414
{
415
    AsyncURB *aurb = async_alloc(dev, p);
416
    struct usb_redir_bulk_packet_header bulk_packet;
417

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

    
421
    bulk_packet.endpoint  = ep;
422
    bulk_packet.length    = p->iov.size;
423
    bulk_packet.stream_id = 0;
424
    aurb->bulk_packet = bulk_packet;
425

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

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

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

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

    
472
        status = intp->status;
473
        if (status != usb_redir_success) {
474
            bufp_free(dev, intp, ep);
475
            return usbredir_handle_status(dev, status, 0);
476
        }
477

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

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

    
496
        interrupt_packet.endpoint  = ep;
497
        interrupt_packet.length    = p->iov.size;
498
        aurb->interrupt_packet     = interrupt_packet;
499

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

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

    
524
static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
525
{
526
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
527
    uint8_t ep;
528

    
529
    ep = p->devep;
530
    if (p->pid == USB_TOKEN_IN) {
531
        ep |= USB_DIR_IN;
532
    }
533

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

    
551
static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
552
                                int config)
553
{
554
    struct usb_redir_set_configuration_header set_config;
555
    AsyncURB *aurb = async_alloc(dev, p);
556
    int i;
557

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

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

    
574
    set_config.configuration = config;
575
    usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
576
                                          &set_config);
577
    usbredirparser_do_write(dev->parser);
578
    return USB_RET_ASYNC;
579
}
580

    
581
static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
582
{
583
    AsyncURB *aurb = async_alloc(dev, p);
584

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

    
587
    aurb->get = 1;
588
    usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
589
    usbredirparser_do_write(dev->parser);
590
    return USB_RET_ASYNC;
591
}
592

    
593
static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
594
                                   int interface, int alt)
595
{
596
    struct usb_redir_set_alt_setting_header set_alt;
597
    AsyncURB *aurb = async_alloc(dev, p);
598
    int i;
599

    
600
    DPRINTF("set interface %d alt %d id %u\n", interface, alt,
601
            aurb->packet_id);
602

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

    
619
    set_alt.interface = interface;
620
    set_alt.alt = alt;
621
    usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
622
                                        &set_alt);
623
    usbredirparser_do_write(dev->parser);
624
    return USB_RET_ASYNC;
625
}
626

    
627
static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
628
                                   int interface)
629
{
630
    struct usb_redir_get_alt_setting_header get_alt;
631
    AsyncURB *aurb = async_alloc(dev, p);
632

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

    
635
    get_alt.interface = interface;
636
    aurb->get = 1;
637
    usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
638
                                        &get_alt);
639
    usbredirparser_do_write(dev->parser);
640
    return USB_RET_ASYNC;
641
}
642

    
643
static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
644
        int request, int value, int index, int length, uint8_t *data)
645
{
646
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
647
    struct usb_redir_control_packet_header control_packet;
648
    AsyncURB *aurb;
649

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

    
666
    /* "Normal" ctrl requests */
667
    aurb = async_alloc(dev, p);
668

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

    
674
    control_packet.request     = request & 0xFF;
675
    control_packet.requesttype = request >> 8;
676
    control_packet.endpoint    = control_packet.requesttype & USB_DIR_IN;
677
    control_packet.value       = value;
678
    control_packet.index       = index;
679
    control_packet.length      = length;
680
    aurb->control_packet       = control_packet;
681

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

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

    
707
    usbredir_device_disconnect(dev);
708

    
709
    if (dev->parser) {
710
        usbredirparser_destroy(dev->parser);
711
        dev->parser = NULL;
712
    }
713

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

    
741
static void usbredir_do_attach(void *opaque)
742
{
743
    USBRedirDevice *dev = opaque;
744

    
745
    usb_device_attach(&dev->dev);
746
}
747

    
748
/*
749
 * chardev callbacks
750
 */
751

    
752
static int usbredir_chardev_can_read(void *opaque)
753
{
754
    USBRedirDevice *dev = opaque;
755

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

    
765
static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
766
{
767
    USBRedirDevice *dev = opaque;
768

    
769
    /* No recursion allowed! */
770
    assert(dev->read_buf == NULL);
771

    
772
    dev->read_buf = buf;
773
    dev->read_buf_size = size;
774

    
775
    usbredirparser_do_read(dev->parser);
776
    /* Send any acks, etc. which may be queued now */
777
    usbredirparser_do_write(dev->parser);
778
}
779

    
780
static void usbredir_chardev_event(void *opaque, int event)
781
{
782
    USBRedirDevice *dev = opaque;
783

    
784
    switch (event) {
785
    case CHR_EVENT_OPENED:
786
    case CHR_EVENT_CLOSED:
787
        qemu_bh_schedule(dev->open_close_bh);
788
        break;
789
    }
790
}
791

    
792
/*
793
 * init + destroy
794
 */
795

    
796
static int usbredir_initfn(USBDevice *udev)
797
{
798
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
799
    int i;
800

    
801
    if (dev->cs == NULL) {
802
        qerror_report(QERR_MISSING_PARAMETER, "chardev");
803
        return -1;
804
    }
805

    
806
    dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
807
    dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
808

    
809
    QTAILQ_INIT(&dev->asyncq);
810
    for (i = 0; i < MAX_ENDPOINTS; i++) {
811
        QTAILQ_INIT(&dev->endpoint[i].bufpq);
812
    }
813

    
814
    /* We'll do the attach once we receive the speed from the usb-host */
815
    udev->auto_attach = 0;
816

    
817
    qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
818
                          usbredir_chardev_read, usbredir_chardev_event, dev);
819

    
820
    return 0;
821
}
822

    
823
static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
824
{
825
    AsyncURB *aurb, *next_aurb;
826
    int i;
827

    
828
    QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
829
        async_free(dev, aurb);
830
    }
831
    for (i = 0; i < MAX_ENDPOINTS; i++) {
832
        usbredir_free_bufpq(dev, I2EP(i));
833
    }
834
}
835

    
836
static void usbredir_handle_destroy(USBDevice *udev)
837
{
838
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
839

    
840
    qemu_chr_delete(dev->cs);
841
    /* Note must be done after qemu_chr_close, as that causes a close event */
842
    qemu_bh_delete(dev->open_close_bh);
843

    
844
    qemu_del_timer(dev->attach_timer);
845
    qemu_free_timer(dev->attach_timer);
846

    
847
    usbredir_cleanup_device_queues(dev);
848

    
849
    if (dev->parser) {
850
        usbredirparser_destroy(dev->parser);
851
    }
852
}
853

    
854
/*
855
 * usbredirparser packet complete callbacks
856
 */
857

    
858
static int usbredir_handle_status(USBRedirDevice *dev,
859
                                       int status, int actual_len)
860
{
861
    switch (status) {
862
    case usb_redir_success:
863
        return actual_len;
864
    case usb_redir_stall:
865
        return USB_RET_STALL;
866
    case usb_redir_cancelled:
867
        WARNING("returning cancelled packet to HC?\n");
868
    case usb_redir_inval:
869
    case usb_redir_ioerror:
870
    case usb_redir_timeout:
871
    default:
872
        return USB_RET_NAK;
873
    }
874
}
875

    
876
static void usbredir_device_connect(void *priv,
877
    struct usb_redir_device_connect_header *device_connect)
878
{
879
    USBRedirDevice *dev = priv;
880

    
881
    switch (device_connect->speed) {
882
    case usb_redir_speed_low:
883
        DPRINTF("attaching low speed device\n");
884
        dev->dev.speed = USB_SPEED_LOW;
885
        break;
886
    case usb_redir_speed_full:
887
        DPRINTF("attaching full speed device\n");
888
        dev->dev.speed = USB_SPEED_FULL;
889
        break;
890
    case usb_redir_speed_high:
891
        DPRINTF("attaching high speed device\n");
892
        dev->dev.speed = USB_SPEED_HIGH;
893
        break;
894
    case usb_redir_speed_super:
895
        DPRINTF("attaching super speed device\n");
896
        dev->dev.speed = USB_SPEED_SUPER;
897
        break;
898
    default:
899
        DPRINTF("attaching unknown speed device, assuming full speed\n");
900
        dev->dev.speed = USB_SPEED_FULL;
901
    }
902
    dev->dev.speedmask = (1 << dev->dev.speed);
903
    qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
904
}
905

    
906
static void usbredir_device_disconnect(void *priv)
907
{
908
    USBRedirDevice *dev = priv;
909

    
910
    /* Stop any pending attaches */
911
    qemu_del_timer(dev->attach_timer);
912

    
913
    if (dev->dev.attached) {
914
        usb_device_detach(&dev->dev);
915
        usbredir_cleanup_device_queues(dev);
916
        /*
917
         * Delay next usb device attach to give the guest a chance to see
918
         * see the detach / attach in case of quick close / open succession
919
         */
920
        dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
921
    }
922
}
923

    
924
static void usbredir_interface_info(void *priv,
925
    struct usb_redir_interface_info_header *interface_info)
926
{
927
    /* The intention is to allow specifying acceptable interface classes
928
       for redirection on the cmdline and in the future verify this here,
929
       and disconnect (or never connect) the device if a not accepted
930
       interface class is detected */
931
}
932

    
933
static void usbredir_ep_info(void *priv,
934
    struct usb_redir_ep_info_header *ep_info)
935
{
936
    USBRedirDevice *dev = priv;
937
    int i;
938

    
939
    for (i = 0; i < MAX_ENDPOINTS; i++) {
940
        dev->endpoint[i].type = ep_info->type[i];
941
        dev->endpoint[i].interval = ep_info->interval[i];
942
        dev->endpoint[i].interface = ep_info->interface[i];
943
        if (dev->endpoint[i].type != usb_redir_type_invalid) {
944
            DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
945
                    dev->endpoint[i].type, dev->endpoint[i].interface);
946
        }
947
    }
948
}
949

    
950
static void usbredir_configuration_status(void *priv, uint32_t id,
951
    struct usb_redir_configuration_status_header *config_status)
952
{
953
    USBRedirDevice *dev = priv;
954
    AsyncURB *aurb;
955
    int len = 0;
956

    
957
    DPRINTF("set config status %d config %d id %u\n", config_status->status,
958
            config_status->configuration, id);
959

    
960
    aurb = async_find(dev, id);
961
    if (!aurb) {
962
        return;
963
    }
964
    if (aurb->packet) {
965
        if (aurb->get) {
966
            dev->dev.data_buf[0] = config_status->configuration;
967
            len = 1;
968
        }
969
        aurb->packet->result =
970
            usbredir_handle_status(dev, config_status->status, len);
971
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
972
    }
973
    async_free(dev, aurb);
974
}
975

    
976
static void usbredir_alt_setting_status(void *priv, uint32_t id,
977
    struct usb_redir_alt_setting_status_header *alt_setting_status)
978
{
979
    USBRedirDevice *dev = priv;
980
    AsyncURB *aurb;
981
    int len = 0;
982

    
983
    DPRINTF("alt status %d intf %d alt %d id: %u\n",
984
            alt_setting_status->status,
985
            alt_setting_status->interface,
986
            alt_setting_status->alt, id);
987

    
988
    aurb = async_find(dev, id);
989
    if (!aurb) {
990
        return;
991
    }
992
    if (aurb->packet) {
993
        if (aurb->get) {
994
            dev->dev.data_buf[0] = alt_setting_status->alt;
995
            len = 1;
996
        }
997
        aurb->packet->result =
998
            usbredir_handle_status(dev, alt_setting_status->status, len);
999
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1000
    }
1001
    async_free(dev, aurb);
1002
}
1003

    
1004
static void usbredir_iso_stream_status(void *priv, uint32_t id,
1005
    struct usb_redir_iso_stream_status_header *iso_stream_status)
1006
{
1007
    USBRedirDevice *dev = priv;
1008
    uint8_t ep = iso_stream_status->endpoint;
1009

    
1010
    DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1011
            ep, id);
1012

    
1013
    dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
1014
    if (iso_stream_status->status == usb_redir_stall) {
1015
        DPRINTF("iso stream stopped by peer ep %02X\n", ep);
1016
        dev->endpoint[EP2I(ep)].iso_started = 0;
1017
    }
1018
}
1019

    
1020
static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1021
    struct usb_redir_interrupt_receiving_status_header
1022
    *interrupt_receiving_status)
1023
{
1024
    USBRedirDevice *dev = priv;
1025
    uint8_t ep = interrupt_receiving_status->endpoint;
1026

    
1027
    DPRINTF("interrupt recv status %d ep %02X id %u\n",
1028
            interrupt_receiving_status->status, ep, id);
1029

    
1030
    dev->endpoint[EP2I(ep)].interrupt_error =
1031
        interrupt_receiving_status->status;
1032
    if (interrupt_receiving_status->status == usb_redir_stall) {
1033
        DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep);
1034
        dev->endpoint[EP2I(ep)].interrupt_started = 0;
1035
    }
1036
}
1037

    
1038
static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1039
    struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1040
{
1041
}
1042

    
1043
static void usbredir_control_packet(void *priv, uint32_t id,
1044
    struct usb_redir_control_packet_header *control_packet,
1045
    uint8_t *data, int data_len)
1046
{
1047
    USBRedirDevice *dev = priv;
1048
    int len = control_packet->length;
1049
    AsyncURB *aurb;
1050

    
1051
    DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1052
            len, id);
1053

    
1054
    aurb = async_find(dev, id);
1055
    if (!aurb) {
1056
        free(data);
1057
        return;
1058
    }
1059

    
1060
    aurb->control_packet.status = control_packet->status;
1061
    aurb->control_packet.length = control_packet->length;
1062
    if (memcmp(&aurb->control_packet, control_packet,
1063
               sizeof(*control_packet))) {
1064
        ERROR("return control packet mismatch, please report this!\n");
1065
        len = USB_RET_NAK;
1066
    }
1067

    
1068
    if (aurb->packet) {
1069
        len = usbredir_handle_status(dev, control_packet->status, len);
1070
        if (len > 0) {
1071
            usbredir_log_data(dev, "ctrl data in:", data, data_len);
1072
            if (data_len <= sizeof(dev->dev.data_buf)) {
1073
                memcpy(dev->dev.data_buf, data, data_len);
1074
            } else {
1075
                ERROR("ctrl buffer too small (%d > %zu)\n",
1076
                      data_len, sizeof(dev->dev.data_buf));
1077
                len = USB_RET_STALL;
1078
            }
1079
        }
1080
        aurb->packet->result = len;
1081
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1082
    }
1083
    async_free(dev, aurb);
1084
    free(data);
1085
}
1086

    
1087
static void usbredir_bulk_packet(void *priv, uint32_t id,
1088
    struct usb_redir_bulk_packet_header *bulk_packet,
1089
    uint8_t *data, int data_len)
1090
{
1091
    USBRedirDevice *dev = priv;
1092
    uint8_t ep = bulk_packet->endpoint;
1093
    int len = bulk_packet->length;
1094
    AsyncURB *aurb;
1095

    
1096
    DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1097
            ep, len, id);
1098

    
1099
    aurb = async_find(dev, id);
1100
    if (!aurb) {
1101
        free(data);
1102
        return;
1103
    }
1104

    
1105
    if (aurb->bulk_packet.endpoint != bulk_packet->endpoint ||
1106
            aurb->bulk_packet.stream_id != bulk_packet->stream_id) {
1107
        ERROR("return bulk packet mismatch, please report this!\n");
1108
        len = USB_RET_NAK;
1109
    }
1110

    
1111
    if (aurb->packet) {
1112
        len = usbredir_handle_status(dev, bulk_packet->status, len);
1113
        if (len > 0) {
1114
            usbredir_log_data(dev, "bulk data in:", data, data_len);
1115
            if (data_len <= aurb->packet->iov.size) {
1116
                usb_packet_copy(aurb->packet, data, data_len);
1117
            } else {
1118
                ERROR("bulk buffer too small (%d > %zd)\n", data_len,
1119
                      aurb->packet->iov.size);
1120
                len = USB_RET_STALL;
1121
            }
1122
        }
1123
        aurb->packet->result = len;
1124
        usb_packet_complete(&dev->dev, aurb->packet);
1125
    }
1126
    async_free(dev, aurb);
1127
    free(data);
1128
}
1129

    
1130
static void usbredir_iso_packet(void *priv, uint32_t id,
1131
    struct usb_redir_iso_packet_header *iso_packet,
1132
    uint8_t *data, int data_len)
1133
{
1134
    USBRedirDevice *dev = priv;
1135
    uint8_t ep = iso_packet->endpoint;
1136

    
1137
    DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1138
             data_len, id);
1139

    
1140
    if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1141
        ERROR("received iso packet for non iso endpoint %02X\n", ep);
1142
        free(data);
1143
        return;
1144
    }
1145

    
1146
    if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1147
        DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1148
        free(data);
1149
        return;
1150
    }
1151

    
1152
    /* bufp_alloc also adds the packet to the ep queue */
1153
    bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1154
}
1155

    
1156
static void usbredir_interrupt_packet(void *priv, uint32_t id,
1157
    struct usb_redir_interrupt_packet_header *interrupt_packet,
1158
    uint8_t *data, int data_len)
1159
{
1160
    USBRedirDevice *dev = priv;
1161
    uint8_t ep = interrupt_packet->endpoint;
1162

    
1163
    DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1164
            interrupt_packet->status, ep, data_len, id);
1165

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

    
1172
    if (ep & USB_DIR_IN) {
1173
        if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
1174
            DPRINTF("received int packet while not started 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, interrupt_packet->status, ep);
1181
    } else {
1182
        int len = interrupt_packet->length;
1183

    
1184
        AsyncURB *aurb = async_find(dev, id);
1185
        if (!aurb) {
1186
            return;
1187
        }
1188

    
1189
        if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
1190
            ERROR("return int packet mismatch, please report this!\n");
1191
            len = USB_RET_NAK;
1192
        }
1193

    
1194
        if (aurb->packet) {
1195
            aurb->packet->result = usbredir_handle_status(dev,
1196
                                               interrupt_packet->status, len);
1197
            usb_packet_complete(&dev->dev, aurb->packet);
1198
        }
1199
        async_free(dev, aurb);
1200
    }
1201
}
1202

    
1203
static struct USBDeviceInfo usbredir_dev_info = {
1204
    .product_desc   = "USB Redirection Device",
1205
    .qdev.name      = "usb-redir",
1206
    .qdev.size      = sizeof(USBRedirDevice),
1207
    .init           = usbredir_initfn,
1208
    .handle_destroy = usbredir_handle_destroy,
1209
    .handle_packet  = usb_generic_handle_packet,
1210
    .cancel_packet  = usbredir_cancel_packet,
1211
    .handle_reset   = usbredir_handle_reset,
1212
    .handle_data    = usbredir_handle_data,
1213
    .handle_control = usbredir_handle_control,
1214
    .qdev.props     = (Property[]) {
1215
        DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
1216
        DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
1217
        DEFINE_PROP_END_OF_LIST(),
1218
    },
1219
};
1220

    
1221
static void usbredir_register_devices(void)
1222
{
1223
    usb_qdev_register(&usbredir_dev_info);
1224
}
1225
device_init(usbredir_register_devices);