Statistics
| Branch: | Revision:

root / usb-redir.c @ 69354a83

History | View | Annotate | Download (37.9 kB)

1
/*
2
 * USB redirector usb-guest
3
 *
4
 * Copyright (c) 2011 Red Hat, Inc.
5
 *
6
 * Red Hat Authors:
7
 * Hans de Goede <hdegoede@redhat.com>
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
10
 * of this software and associated documentation files (the "Software"), to deal
11
 * in the Software without restriction, including without limitation the rights
12
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
 * copies of the Software, and to permit persons to whom the Software is
14
 * furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included in
17
 * all copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
 * THE SOFTWARE.
26
 */
27

    
28
#include "qemu-common.h"
29
#include "qemu-timer.h"
30
#include "monitor.h"
31
#include "sysemu.h"
32

    
33
#include <dirent.h>
34
#include <sys/ioctl.h>
35
#include <signal.h>
36
#include <usbredirparser.h>
37

    
38
#include "hw/usb.h"
39

    
40
#define MAX_ENDPOINTS 32
41
#define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f))
42
#define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f))
43

    
44
typedef struct AsyncURB AsyncURB;
45
typedef struct USBRedirDevice USBRedirDevice;
46

    
47
/* Struct to hold buffered packets (iso or int input packets) */
48
struct buf_packet {
49
    uint8_t *data;
50
    int len;
51
    int status;
52
    QTAILQ_ENTRY(buf_packet)next;
53
};
54

    
55
struct endp_data {
56
    uint8_t type;
57
    uint8_t interval;
58
    uint8_t interface; /* bInterfaceNumber this ep belongs to */
59
    uint8_t iso_started;
60
    uint8_t iso_error; /* For reporting iso errors to the HC */
61
    uint8_t interrupt_started;
62
    uint8_t interrupt_error;
63
    QTAILQ_HEAD(, buf_packet) bufpq;
64
};
65

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

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

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

    
129
static int usbredir_handle_status(USBRedirDevice *dev,
130
                                       int status, int actual_len);
131

    
132
#define VERSION "qemu usb-redir guest " QEMU_VERSION
133

    
134
/*
135
 * Logging stuff
136
 */
137

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

    
169
static void usbredir_log(void *priv, int level, const char *msg)
170
{
171
    USBRedirDevice *dev = priv;
172

    
173
    if (dev->debug < level) {
174
        return;
175
    }
176

    
177
    error_report("%s\n", msg);
178
}
179

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

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

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

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

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

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

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

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

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

    
221
    return count;
222
}
223

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

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

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

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

    
244
    return aurb;
245
}
246

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

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

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

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

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

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

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

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

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

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

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

    
314
/*
315
 * USBDevice callbacks
316
 */
317

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

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

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

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

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

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

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

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

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

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

    
416
    DPRINTF("bulk-out ep %02X len %d id %u\n", ep, p->len, aurb->packet_id);
417

    
418
    bulk_packet.endpoint  = ep;
419
    bulk_packet.length    = p->len;
420
    bulk_packet.stream_id = 0;
421
    aurb->bulk_packet = bulk_packet;
422

    
423
    if (ep & USB_DIR_IN) {
424
        usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
425
                                        &bulk_packet, NULL, 0);
426
    } else {
427
        usbredir_log_data(dev, "bulk data out:", p->data, p->len);
428
        usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
429
                                        &bulk_packet, p->data, p->len);
430
    }
431
    usbredirparser_do_write(dev->parser);
432
    return USB_RET_ASYNC;
433
}
434

    
435
static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
436
                                           USBPacket *p, uint8_t ep)
437
{
438
    if (ep & USB_DIR_IN) {
439
        /* Input interrupt endpoint, buffered packet input */
440
        struct buf_packet *intp;
441
        int status, len;
442

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

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

    
467
        status = intp->status;
468
        if (status != usb_redir_success) {
469
            bufp_free(dev, intp, ep);
470
            return usbredir_handle_status(dev, status, 0);
471
        }
472

    
473
        len = intp->len;
474
        if (len > p->len) {
475
            ERROR("received int data is larger then packet ep %02X\n", ep);
476
            bufp_free(dev, intp, ep);
477
            return USB_RET_NAK;
478
        }
479
        memcpy(p->data, intp->data, len);
480
        bufp_free(dev, intp, ep);
481
        return len;
482
    } else {
483
        /* Output interrupt endpoint, normal async operation */
484
        AsyncURB *aurb = async_alloc(dev, p);
485
        struct usb_redir_interrupt_packet_header interrupt_packet;
486

    
487
        DPRINTF("interrupt-out ep %02X len %d id %u\n", ep, p->len,
488
                aurb->packet_id);
489

    
490
        interrupt_packet.endpoint  = ep;
491
        interrupt_packet.length    = p->len;
492
        aurb->interrupt_packet     = interrupt_packet;
493

    
494
        usbredir_log_data(dev, "interrupt data out:", p->data, p->len);
495
        usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
496
                                        &interrupt_packet, p->data, p->len);
497
        usbredirparser_do_write(dev->parser);
498
        return USB_RET_ASYNC;
499
    }
500
}
501

    
502
static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev,
503
    uint8_t ep)
504
{
505
    struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv = {
506
        .endpoint = ep
507
    };
508
    if (dev->endpoint[EP2I(ep)].interrupt_started) {
509
        usbredirparser_send_stop_interrupt_receiving(dev->parser, 0,
510
                                                     &stop_interrupt_recv);
511
        DPRINTF("interrupt recv stopped ep %02X\n", ep);
512
        dev->endpoint[EP2I(ep)].interrupt_started = 0;
513
    }
514
    usbredir_free_bufpq(dev, ep);
515
}
516

    
517
static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
518
{
519
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
520
    uint8_t ep;
521

    
522
    ep = p->devep;
523
    if (p->pid == USB_TOKEN_IN) {
524
        ep |= USB_DIR_IN;
525
    }
526

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

    
544
static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
545
                                int config)
546
{
547
    struct usb_redir_set_configuration_header set_config;
548
    AsyncURB *aurb = async_alloc(dev, p);
549
    int i;
550

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

    
553
    for (i = 0; i < MAX_ENDPOINTS; i++) {
554
        switch (dev->endpoint[i].type) {
555
        case USB_ENDPOINT_XFER_ISOC:
556
            usbredir_stop_iso_stream(dev, I2EP(i));
557
            break;
558
        case USB_ENDPOINT_XFER_INT:
559
            if (i & 0x10) {
560
                usbredir_stop_interrupt_receiving(dev, I2EP(i));
561
            }
562
            break;
563
        }
564
        usbredir_free_bufpq(dev, I2EP(i));
565
    }
566

    
567
    set_config.configuration = config;
568
    usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
569
                                          &set_config);
570
    usbredirparser_do_write(dev->parser);
571
    return USB_RET_ASYNC;
572
}
573

    
574
static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
575
{
576
    AsyncURB *aurb = async_alloc(dev, p);
577

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

    
580
    aurb->get = 1;
581
    usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
582
    usbredirparser_do_write(dev->parser);
583
    return USB_RET_ASYNC;
584
}
585

    
586
static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
587
                                   int interface, int alt)
588
{
589
    struct usb_redir_set_alt_setting_header set_alt;
590
    AsyncURB *aurb = async_alloc(dev, p);
591
    int i;
592

    
593
    DPRINTF("set interface %d alt %d id %u\n", interface, alt,
594
            aurb->packet_id);
595

    
596
    for (i = 0; i < MAX_ENDPOINTS; i++) {
597
        if (dev->endpoint[i].interface == interface) {
598
            switch (dev->endpoint[i].type) {
599
            case USB_ENDPOINT_XFER_ISOC:
600
                usbredir_stop_iso_stream(dev, I2EP(i));
601
                break;
602
            case USB_ENDPOINT_XFER_INT:
603
                if (i & 0x10) {
604
                    usbredir_stop_interrupt_receiving(dev, I2EP(i));
605
                }
606
                break;
607
            }
608
            usbredir_free_bufpq(dev, I2EP(i));
609
        }
610
    }
611

    
612
    set_alt.interface = interface;
613
    set_alt.alt = alt;
614
    usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
615
                                        &set_alt);
616
    usbredirparser_do_write(dev->parser);
617
    return USB_RET_ASYNC;
618
}
619

    
620
static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
621
                                   int interface)
622
{
623
    struct usb_redir_get_alt_setting_header get_alt;
624
    AsyncURB *aurb = async_alloc(dev, p);
625

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

    
628
    get_alt.interface = interface;
629
    aurb->get = 1;
630
    usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
631
                                        &get_alt);
632
    usbredirparser_do_write(dev->parser);
633
    return USB_RET_ASYNC;
634
}
635

    
636
static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
637
        int request, int value, int index, int length, uint8_t *data)
638
{
639
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
640
    struct usb_redir_control_packet_header control_packet;
641
    AsyncURB *aurb;
642

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

    
659
    /* "Normal" ctrl requests */
660
    aurb = async_alloc(dev, p);
661

    
662
    /* Note request is (bRequestType << 8) | bRequest */
663
    DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
664
            request >> 8, request & 0xff, value, index, length,
665
            aurb->packet_id);
666

    
667
    control_packet.request     = request & 0xFF;
668
    control_packet.requesttype = request >> 8;
669
    control_packet.endpoint    = control_packet.requesttype & USB_DIR_IN;
670
    control_packet.value       = value;
671
    control_packet.index       = index;
672
    control_packet.length      = length;
673
    aurb->control_packet       = control_packet;
674

    
675
    if (control_packet.requesttype & USB_DIR_IN) {
676
        usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
677
                                           &control_packet, NULL, 0);
678
    } else {
679
        usbredir_log_data(dev, "ctrl data out:", data, length);
680
        usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
681
                                           &control_packet, data, length);
682
    }
683
    usbredirparser_do_write(dev->parser);
684
    return USB_RET_ASYNC;
685
}
686

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

    
700
    usbredir_device_disconnect(dev);
701

    
702
    if (dev->parser) {
703
        usbredirparser_destroy(dev->parser);
704
        dev->parser = NULL;
705
    }
706

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

    
734
static void usbredir_do_attach(void *opaque)
735
{
736
    USBRedirDevice *dev = opaque;
737

    
738
    usb_device_attach(&dev->dev);
739
}
740

    
741
/*
742
 * chardev callbacks
743
 */
744

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

    
749
    if (dev->parser) {
750
        /* usbredir_parser_do_read will consume *all* data we give it */
751
        return 1024 * 1024;
752
    } else {
753
        /* usbredir_open_close_bh hasn't handled the open event yet */
754
        return 0;
755
    }
756
}
757

    
758
static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
759
{
760
    USBRedirDevice *dev = opaque;
761

    
762
    /* No recursion allowed! */
763
    assert(dev->read_buf == NULL);
764

    
765
    dev->read_buf = buf;
766
    dev->read_buf_size = size;
767

    
768
    usbredirparser_do_read(dev->parser);
769
    /* Send any acks, etc. which may be queued now */
770
    usbredirparser_do_write(dev->parser);
771
}
772

    
773
static void usbredir_chardev_event(void *opaque, int event)
774
{
775
    USBRedirDevice *dev = opaque;
776

    
777
    switch (event) {
778
    case CHR_EVENT_OPENED:
779
    case CHR_EVENT_CLOSED:
780
        qemu_bh_schedule(dev->open_close_bh);
781
        break;
782
    }
783
}
784

    
785
/*
786
 * init + destroy
787
 */
788

    
789
static int usbredir_initfn(USBDevice *udev)
790
{
791
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
792
    int i;
793

    
794
    if (dev->cs == NULL) {
795
        qerror_report(QERR_MISSING_PARAMETER, "chardev");
796
        return -1;
797
    }
798

    
799
    dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
800
    dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
801

    
802
    QTAILQ_INIT(&dev->asyncq);
803
    for (i = 0; i < MAX_ENDPOINTS; i++) {
804
        QTAILQ_INIT(&dev->endpoint[i].bufpq);
805
    }
806

    
807
    /* We'll do the attach once we receive the speed from the usb-host */
808
    udev->auto_attach = 0;
809

    
810
    qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
811
                          usbredir_chardev_read, usbredir_chardev_event, dev);
812

    
813
    return 0;
814
}
815

    
816
static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
817
{
818
    AsyncURB *aurb, *next_aurb;
819
    int i;
820

    
821
    QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
822
        async_free(dev, aurb);
823
    }
824
    for (i = 0; i < MAX_ENDPOINTS; i++) {
825
        usbredir_free_bufpq(dev, I2EP(i));
826
    }
827
}
828

    
829
static void usbredir_handle_destroy(USBDevice *udev)
830
{
831
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
832

    
833
    qemu_chr_close(dev->cs);
834
    /* Note must be done after qemu_chr_close, as that causes a close event */
835
    qemu_bh_delete(dev->open_close_bh);
836

    
837
    qemu_del_timer(dev->attach_timer);
838
    qemu_free_timer(dev->attach_timer);
839

    
840
    usbredir_cleanup_device_queues(dev);
841

    
842
    if (dev->parser) {
843
        usbredirparser_destroy(dev->parser);
844
    }
845
}
846

    
847
/*
848
 * usbredirparser packet complete callbacks
849
 */
850

    
851
static int usbredir_handle_status(USBRedirDevice *dev,
852
                                       int status, int actual_len)
853
{
854
    switch (status) {
855
    case usb_redir_success:
856
        return actual_len;
857
    case usb_redir_stall:
858
        return USB_RET_STALL;
859
    case usb_redir_cancelled:
860
        WARNING("returning cancelled packet to HC?\n");
861
    case usb_redir_inval:
862
    case usb_redir_ioerror:
863
    case usb_redir_timeout:
864
    default:
865
        return USB_RET_NAK;
866
    }
867
}
868

    
869
static void usbredir_device_connect(void *priv,
870
    struct usb_redir_device_connect_header *device_connect)
871
{
872
    USBRedirDevice *dev = priv;
873

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

    
899
static void usbredir_device_disconnect(void *priv)
900
{
901
    USBRedirDevice *dev = priv;
902

    
903
    /* Stop any pending attaches */
904
    qemu_del_timer(dev->attach_timer);
905

    
906
    if (dev->dev.attached) {
907
        usb_device_detach(&dev->dev);
908
        usbredir_cleanup_device_queues(dev);
909
        /*
910
         * Delay next usb device attach to give the guest a chance to see
911
         * see the detach / attach in case of quick close / open succession
912
         */
913
        dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
914
    }
915
}
916

    
917
static void usbredir_interface_info(void *priv,
918
    struct usb_redir_interface_info_header *interface_info)
919
{
920
    /* The intention is to allow specifying acceptable interface classes
921
       for redirection on the cmdline and in the future verify this here,
922
       and disconnect (or never connect) the device if a not accepted
923
       interface class is detected */
924
}
925

    
926
static void usbredir_ep_info(void *priv,
927
    struct usb_redir_ep_info_header *ep_info)
928
{
929
    USBRedirDevice *dev = priv;
930
    int i;
931

    
932
    for (i = 0; i < MAX_ENDPOINTS; i++) {
933
        dev->endpoint[i].type = ep_info->type[i];
934
        dev->endpoint[i].interval = ep_info->interval[i];
935
        dev->endpoint[i].interface = ep_info->interface[i];
936
        if (dev->endpoint[i].type != usb_redir_type_invalid) {
937
            DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
938
                    dev->endpoint[i].type, dev->endpoint[i].interface);
939
        }
940
    }
941
}
942

    
943
static void usbredir_configuration_status(void *priv, uint32_t id,
944
    struct usb_redir_configuration_status_header *config_status)
945
{
946
    USBRedirDevice *dev = priv;
947
    AsyncURB *aurb;
948
    int len = 0;
949

    
950
    DPRINTF("set config status %d config %d id %u\n", config_status->status,
951
            config_status->configuration, id);
952

    
953
    aurb = async_find(dev, id);
954
    if (!aurb) {
955
        return;
956
    }
957
    if (aurb->packet) {
958
        if (aurb->get) {
959
            dev->dev.data_buf[0] = config_status->configuration;
960
            len = 1;
961
        }
962
        aurb->packet->len =
963
            usbredir_handle_status(dev, config_status->status, len);
964
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
965
    }
966
    async_free(dev, aurb);
967
}
968

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

    
976
    DPRINTF("alt status %d intf %d alt %d id: %u\n",
977
            alt_setting_status->status,
978
            alt_setting_status->interface,
979
            alt_setting_status->alt, id);
980

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

    
997
static void usbredir_iso_stream_status(void *priv, uint32_t id,
998
    struct usb_redir_iso_stream_status_header *iso_stream_status)
999
{
1000
    USBRedirDevice *dev = priv;
1001
    uint8_t ep = iso_stream_status->endpoint;
1002

    
1003
    DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1004
            ep, id);
1005

    
1006
    dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
1007
    if (iso_stream_status->status == usb_redir_stall) {
1008
        DPRINTF("iso stream stopped by peer ep %02X\n", ep);
1009
        dev->endpoint[EP2I(ep)].iso_started = 0;
1010
    }
1011
}
1012

    
1013
static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1014
    struct usb_redir_interrupt_receiving_status_header
1015
    *interrupt_receiving_status)
1016
{
1017
    USBRedirDevice *dev = priv;
1018
    uint8_t ep = interrupt_receiving_status->endpoint;
1019

    
1020
    DPRINTF("interrupt recv status %d ep %02X id %u\n",
1021
            interrupt_receiving_status->status, ep, id);
1022

    
1023
    dev->endpoint[EP2I(ep)].interrupt_error =
1024
        interrupt_receiving_status->status;
1025
    if (interrupt_receiving_status->status == usb_redir_stall) {
1026
        DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep);
1027
        dev->endpoint[EP2I(ep)].interrupt_started = 0;
1028
    }
1029
}
1030

    
1031
static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1032
    struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1033
{
1034
}
1035

    
1036
static void usbredir_control_packet(void *priv, uint32_t id,
1037
    struct usb_redir_control_packet_header *control_packet,
1038
    uint8_t *data, int data_len)
1039
{
1040
    USBRedirDevice *dev = priv;
1041
    int len = control_packet->length;
1042
    AsyncURB *aurb;
1043

    
1044
    DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1045
            len, id);
1046

    
1047
    aurb = async_find(dev, id);
1048
    if (!aurb) {
1049
        free(data);
1050
        return;
1051
    }
1052

    
1053
    aurb->control_packet.status = control_packet->status;
1054
    aurb->control_packet.length = control_packet->length;
1055
    if (memcmp(&aurb->control_packet, control_packet,
1056
               sizeof(*control_packet))) {
1057
        ERROR("return control packet mismatch, please report this!\n");
1058
        len = USB_RET_NAK;
1059
    }
1060

    
1061
    if (aurb->packet) {
1062
        len = usbredir_handle_status(dev, control_packet->status, len);
1063
        if (len > 0) {
1064
            usbredir_log_data(dev, "ctrl data in:", data, data_len);
1065
            if (data_len <= sizeof(dev->dev.data_buf)) {
1066
                memcpy(dev->dev.data_buf, data, data_len);
1067
            } else {
1068
                ERROR("ctrl buffer too small (%d > %zu)\n",
1069
                      data_len, sizeof(dev->dev.data_buf));
1070
                len = USB_RET_STALL;
1071
            }
1072
        }
1073
        aurb->packet->len = len;
1074
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1075
    }
1076
    async_free(dev, aurb);
1077
    free(data);
1078
}
1079

    
1080
static void usbredir_bulk_packet(void *priv, uint32_t id,
1081
    struct usb_redir_bulk_packet_header *bulk_packet,
1082
    uint8_t *data, int data_len)
1083
{
1084
    USBRedirDevice *dev = priv;
1085
    uint8_t ep = bulk_packet->endpoint;
1086
    int len = bulk_packet->length;
1087
    AsyncURB *aurb;
1088

    
1089
    DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1090
            ep, len, id);
1091

    
1092
    aurb = async_find(dev, id);
1093
    if (!aurb) {
1094
        free(data);
1095
        return;
1096
    }
1097

    
1098
    if (aurb->bulk_packet.endpoint != bulk_packet->endpoint ||
1099
            aurb->bulk_packet.stream_id != bulk_packet->stream_id) {
1100
        ERROR("return bulk packet mismatch, please report this!\n");
1101
        len = USB_RET_NAK;
1102
    }
1103

    
1104
    if (aurb->packet) {
1105
        len = usbredir_handle_status(dev, bulk_packet->status, len);
1106
        if (len > 0) {
1107
            usbredir_log_data(dev, "bulk data in:", data, data_len);
1108
            if (data_len <= aurb->packet->len) {
1109
                memcpy(aurb->packet->data, data, data_len);
1110
            } else {
1111
                ERROR("bulk buffer too small (%d > %d)\n", data_len,
1112
                      aurb->packet->len);
1113
                len = USB_RET_STALL;
1114
            }
1115
        }
1116
        aurb->packet->len = len;
1117
        usb_packet_complete(&dev->dev, aurb->packet);
1118
    }
1119
    async_free(dev, aurb);
1120
    free(data);
1121
}
1122

    
1123
static void usbredir_iso_packet(void *priv, uint32_t id,
1124
    struct usb_redir_iso_packet_header *iso_packet,
1125
    uint8_t *data, int data_len)
1126
{
1127
    USBRedirDevice *dev = priv;
1128
    uint8_t ep = iso_packet->endpoint;
1129

    
1130
    DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1131
             data_len, id);
1132

    
1133
    if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1134
        ERROR("received iso packet for non iso endpoint %02X\n", ep);
1135
        free(data);
1136
        return;
1137
    }
1138

    
1139
    if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1140
        DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1141
        free(data);
1142
        return;
1143
    }
1144

    
1145
    /* bufp_alloc also adds the packet to the ep queue */
1146
    bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1147
}
1148

    
1149
static void usbredir_interrupt_packet(void *priv, uint32_t id,
1150
    struct usb_redir_interrupt_packet_header *interrupt_packet,
1151
    uint8_t *data, int data_len)
1152
{
1153
    USBRedirDevice *dev = priv;
1154
    uint8_t ep = interrupt_packet->endpoint;
1155

    
1156
    DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1157
            interrupt_packet->status, ep, data_len, id);
1158

    
1159
    if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
1160
        ERROR("received int packet for non interrupt endpoint %02X\n", ep);
1161
        free(data);
1162
        return;
1163
    }
1164

    
1165
    if (ep & USB_DIR_IN) {
1166
        if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
1167
            DPRINTF("received int packet while not started ep %02X\n", ep);
1168
            free(data);
1169
            return;
1170
        }
1171

    
1172
        /* bufp_alloc also adds the packet to the ep queue */
1173
        bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
1174
    } else {
1175
        int len = interrupt_packet->length;
1176

    
1177
        AsyncURB *aurb = async_find(dev, id);
1178
        if (!aurb) {
1179
            return;
1180
        }
1181

    
1182
        if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
1183
            ERROR("return int packet mismatch, please report this!\n");
1184
            len = USB_RET_NAK;
1185
        }
1186

    
1187
        if (aurb->packet) {
1188
            aurb->packet->len = usbredir_handle_status(dev,
1189
                                               interrupt_packet->status, len);
1190
            usb_packet_complete(&dev->dev, aurb->packet);
1191
        }
1192
        async_free(dev, aurb);
1193
    }
1194
}
1195

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

    
1214
static void usbredir_register_devices(void)
1215
{
1216
    usb_qdev_register(&usbredir_dev_info);
1217
}
1218
device_init(usbredir_register_devices);