Statistics
| Branch: | Revision:

root / usb-linux.c @ 1f3870ab

History | View | Annotate | Download (27.5 kB)

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

    
29
#if defined(__linux__)
30
#include <dirent.h>
31
#include <sys/ioctl.h>
32
#include <linux/usbdevice_fs.h>
33
#include <linux/version.h>
34
#include <signal.h>
35

    
36
/* We redefine it to avoid version problems */
37
struct usb_ctrltransfer {
38
    uint8_t  bRequestType;
39
    uint8_t  bRequest;
40
    uint16_t wValue;
41
    uint16_t wIndex;
42
    uint16_t wLength;
43
    uint32_t timeout;
44
    void *data;
45
};
46

    
47
typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
48
                        int vendor_id, int product_id,
49
                        const char *product_name, int speed);
50
static int usb_host_find_device(int *pbus_num, int *paddr,
51
                                char *product_name, int product_name_size,
52
                                const char *devname);
53

    
54
//#define DEBUG
55
//#define DEBUG_ISOCH
56
//#define USE_ASYNCIO
57

    
58
#define USBDEVFS_PATH "/proc/bus/usb"
59
#define PRODUCT_NAME_SZ 32
60
#define SIG_ISOCOMPLETE (SIGRTMIN+7)
61
#define MAX_ENDPOINTS 16
62

    
63
struct sigaction sigact;
64

    
65
/* endpoint association data */
66
struct endp_data {
67
    uint8_t type;
68
};
69

    
70
/* FIXME: move USBPacket to PendingURB */
71
typedef struct USBHostDevice {
72
    USBDevice dev;
73
    int fd;
74
    int pipe_fds[2];
75
    USBPacket *packet;
76
    struct endp_data endp_table[MAX_ENDPOINTS];
77
    int configuration;
78
    uint8_t descr[1024];
79
    int descr_len;
80
    int urbs_ready;
81
    QEMUTimer *timer;
82
} USBHostDevice;
83

    
84
typedef struct PendingURB {
85
    struct usbdevfs_urb *urb;
86
    int status;
87
    struct PendingURB *next;
88
} PendingURB;
89

    
90
static PendingURB *pending_urbs = NULL;
91

    
92
static int add_pending_urb(struct usbdevfs_urb *urb)
93
{
94
    PendingURB *purb = qemu_mallocz(sizeof(PendingURB));
95
    if (purb) {
96
        purb->urb = urb;
97
        purb->status = 0;
98
        purb->next = pending_urbs;
99
        pending_urbs = purb;
100
        return 1;
101
    }
102
    return 0;
103
}
104

    
105
static int del_pending_urb(struct usbdevfs_urb *urb)
106
{
107
    PendingURB *purb = pending_urbs;
108
    PendingURB *prev = NULL;
109

    
110
    while (purb && purb->urb != urb) {
111
        prev = purb;
112
        purb = purb->next;
113
    }
114

    
115
    if (purb && purb->urb == urb) {
116
        if (prev) {
117
            prev->next = purb->next;
118
        } else {
119
            pending_urbs = purb->next;
120
        }
121
        qemu_free(purb);
122
        return 1;
123
    }
124
    return 0;
125
}
126

    
127
#ifdef USE_ASYNCIO
128
static PendingURB *get_pending_urb(struct usbdevfs_urb *urb)
129
{
130
    PendingURB *purb = pending_urbs;
131

    
132
    while (purb && purb->urb != urb) {
133
        purb = purb->next;
134
    }
135

    
136
    if (purb && purb->urb == urb) {
137
        return purb;
138
    }
139
    return NULL;
140
}
141
#endif
142

    
143
static int usb_host_update_interfaces(USBHostDevice *dev, int configuration)
144
{
145
    int dev_descr_len, config_descr_len;
146
    int interface, nb_interfaces, nb_configurations;
147
    int ret, i;
148

    
149
    if (configuration == 0) /* address state - ignore */
150
        return 1;
151

    
152
    i = 0;
153
    dev_descr_len = dev->descr[0];
154
    if (dev_descr_len > dev->descr_len)
155
        goto fail;
156
    nb_configurations = dev->descr[17];
157

    
158
    i += dev_descr_len;
159
    while (i < dev->descr_len) {
160
#ifdef DEBUG
161
        printf("i is %d, descr_len is %d, dl %d, dt %d\n", i, dev->descr_len,
162
               dev->descr[i], dev->descr[i+1]);
163
#endif
164
        if (dev->descr[i+1] != USB_DT_CONFIG) {
165
            i += dev->descr[i];
166
            continue;
167
        }
168
        config_descr_len = dev->descr[i];
169

    
170
#ifdef DEBUG
171
        printf("config #%d need %d\n", dev->descr[i + 5], configuration); 
172
#endif
173

    
174
        if (configuration < 0 || configuration == dev->descr[i + 5])
175
            break;
176

    
177
        i += config_descr_len;
178
    }
179

    
180
    if (i >= dev->descr_len) {
181
        printf("usb_host: error - device has no matching configuration\n");
182
        goto fail;
183
    }
184
    nb_interfaces = dev->descr[i + 4];
185

    
186
#ifdef USBDEVFS_DISCONNECT
187
    /* earlier Linux 2.4 do not support that */
188
    {
189
        struct usbdevfs_ioctl ctrl;
190
        for (interface = 0; interface < nb_interfaces; interface++) {
191
            ctrl.ioctl_code = USBDEVFS_DISCONNECT;
192
            ctrl.ifno = interface;
193
            ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
194
            if (ret < 0 && errno != ENODATA) {
195
                perror("USBDEVFS_DISCONNECT");
196
                goto fail;
197
            }
198
        }
199
    }
200
#endif
201

    
202
    /* XXX: only grab if all interfaces are free */
203
    for (interface = 0; interface < nb_interfaces; interface++) {
204
        ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
205
        if (ret < 0) {
206
            if (errno == EBUSY) {
207
                fprintf(stderr,
208
                        "usb_host: warning - device already grabbed\n");
209
            } else {
210
                perror("USBDEVFS_CLAIMINTERFACE");
211
            }
212
        fail:
213
            return 0;
214
        }
215
    }
216

    
217
#ifdef DEBUG
218
    printf("usb_host: %d interfaces claimed for configuration %d\n",
219
           nb_interfaces, configuration);
220
#endif
221

    
222
    return 1;
223
}
224

    
225
static void usb_host_handle_reset(USBDevice *dev)
226
{
227
#if 0
228
    USBHostDevice *s = (USBHostDevice *)dev;
229
    /* USBDEVFS_RESET, but not the first time as it has already be
230
       done by the host OS */
231
    ioctl(s->fd, USBDEVFS_RESET);
232
#endif
233
}
234

    
235
static void usb_host_handle_destroy(USBDevice *dev)
236
{
237
    USBHostDevice *s = (USBHostDevice *)dev;
238

    
239
    qemu_del_timer(s->timer);
240

    
241
    if (s->fd >= 0)
242
        close(s->fd);
243

    
244
    qemu_free(s);
245
}
246

    
247
static int usb_linux_update_endp_table(USBHostDevice *s);
248

    
249
static int usb_host_handle_control(USBDevice *dev,
250
                                   int request,
251
                                   int value,
252
                                   int index,
253
                                   int length,
254
                                   uint8_t *data)
255
{
256
    USBHostDevice *s = (USBHostDevice *)dev;
257
    struct usb_ctrltransfer ct;
258
    struct usbdevfs_setinterface si;
259
    int intf_update_required = 0;
260
    int ret;
261

    
262
    if (request == (DeviceOutRequest | USB_REQ_SET_ADDRESS)) {
263
        /* specific SET_ADDRESS support */
264
        dev->addr = value;
265
        return 0;
266
    } else if (request == ((USB_RECIP_INTERFACE << 8) |
267
                           USB_REQ_SET_INTERFACE)) {
268
        /* set alternate setting for the interface */
269
        si.interface = index;
270
        si.altsetting = value;
271
        ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
272
        usb_linux_update_endp_table(s);
273
    } else if (request == (DeviceOutRequest | USB_REQ_SET_CONFIGURATION)) {
274
#ifdef DEBUG
275
        printf("usb_host_handle_control: SET_CONFIGURATION request - "
276
               "config %d\n", value & 0xff);
277
#endif
278
        if (s->configuration != (value & 0xff)) {
279
            s->configuration = (value & 0xff);
280
            intf_update_required = 1;
281
        }
282
        goto do_request;
283
    } else {
284
    do_request:
285
        ct.bRequestType = request >> 8;
286
        ct.bRequest = request;
287
        ct.wValue = value;
288
        ct.wIndex = index;
289
        ct.wLength = length;
290
        ct.timeout = 50;
291
        ct.data = data;
292
        ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
293
    }
294

    
295
    if (ret < 0) {
296
        switch(errno) {
297
        case ETIMEDOUT:
298
            return USB_RET_NAK;
299
        default:
300
            return USB_RET_STALL;
301
        }
302
    } else {
303
        if (intf_update_required) {
304
#ifdef DEBUG
305
            printf("usb_host_handle_control: updating interfaces\n");
306
#endif
307
            usb_host_update_interfaces(s, value & 0xff);
308
        }
309
        return ret;
310
    }
311
}
312

    
313
static int usb_host_handle_isoch(USBDevice *dev, USBPacket *p);
314

    
315
static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
316
{
317
    USBHostDevice *s = (USBHostDevice *)dev;
318
    struct usbdevfs_bulktransfer bt;
319
    int ret;
320
    uint8_t devep = p->devep;
321

    
322
    if (s->endp_table[p->devep - 1].type == USBDEVFS_URB_TYPE_ISO) {
323
        return usb_host_handle_isoch(dev, p);
324
    }
325

    
326
    /* XXX: optimize and handle all data types by looking at the
327
       config descriptor */
328
    if (p->pid == USB_TOKEN_IN)
329
        devep |= 0x80;
330
    bt.ep = devep;
331
    bt.len = p->len;
332
    bt.timeout = 50;
333
    bt.data = p->data;
334
    ret = ioctl(s->fd, USBDEVFS_BULK, &bt);
335
    if (ret < 0) {
336
        switch(errno) {
337
        case ETIMEDOUT:
338
            return USB_RET_NAK;
339
        case EPIPE:
340
        default:
341
#ifdef DEBUG
342
            printf("handle_data: errno=%d\n", errno);
343
#endif
344
            return USB_RET_STALL;
345
        }
346
    } else {
347
        return ret;
348
    }
349
}
350

    
351
#ifdef USE_ASYNCIO
352
static void urb_completion_pipe_read(void *opaque)
353
{
354
    USBHostDevice *s = opaque;
355
    USBPacket *p = s->packet;
356
    PendingURB *pending_urb = NULL;
357
    struct usbdevfs_urb *purb = NULL;
358
    int len, ret;
359

    
360
    len = read(s->pipe_fds[0], &pending_urb, sizeof(pending_urb));
361
    if (len != sizeof(pending_urb)) {
362
        printf("urb_completion: error reading pending_urb, len=%d\n", len);
363
        return;
364
    }
365

    
366
    /* FIXME: handle pending_urb->status */
367
    del_pending_urb(pending_urb->urb);
368

    
369
    if (!p) {
370
        s->urbs_ready++;
371
        return;
372
    }
373

    
374
    ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);
375
    if (ret < 0) {
376
        printf("urb_completion: REAPURBNDELAY ioctl=%d errno=%d\n",
377
               ret, errno);
378
        return;
379
    }
380

    
381
#ifdef DEBUG_ISOCH
382
    if (purb == pending_urb->urb) {
383
        printf("urb_completion: urb mismatch reaped=%p pending=%p\n",
384
               purb, urb);
385
    }
386
#endif
387

    
388
    p->len = purb->actual_length;
389
    usb_packet_complete(p);
390
    qemu_free(purb);
391
    s->packet = NULL;
392
}
393

    
394
static void isoch_done(int signum, siginfo_t *info, void *context)
395
{
396
    struct usbdevfs_urb *urb = (struct usbdevfs_urb *)info->si_addr;
397
    USBHostDevice *s = (USBHostDevice *)urb->usercontext;
398
    PendingURB *purb;
399

    
400
    if (info->si_code != SI_ASYNCIO ||
401
        info->si_signo != SIG_ISOCOMPLETE) {
402
        return;
403
    }
404

    
405
    purb = get_pending_urb(urb);
406
    if (purb) {
407
        purb->status = info->si_errno;
408
        write(s->pipe_fds[1], &purb, sizeof(purb));
409
    }
410
}
411
#endif
412

    
413
static int usb_host_handle_isoch(USBDevice *dev, USBPacket *p)
414
{
415
    USBHostDevice *s = (USBHostDevice *)dev;
416
    struct usbdevfs_urb *urb, *purb = NULL;
417
    int ret;
418
    uint8_t devep = p->devep;
419

    
420
    if (p->pid == USB_TOKEN_IN)
421
        devep |= 0x80;
422

    
423
    urb = qemu_mallocz(sizeof(struct usbdevfs_urb) +
424
                       sizeof(struct usbdevfs_iso_packet_desc));
425
    if (!urb) {
426
        printf("usb_host_handle_isoch: malloc failed\n");
427
        return 0;
428
    }
429

    
430
    urb->type = USBDEVFS_URB_TYPE_ISO;
431
    urb->endpoint = devep;
432
    urb->status = 0;
433
    urb->flags = USBDEVFS_URB_ISO_ASAP;
434
    urb->buffer = p->data;
435
    urb->buffer_length = p->len;
436
    urb->actual_length = 0;
437
    urb->start_frame = 0;
438
    urb->error_count = 0;
439
#ifdef USE_ASYNCIO
440
    urb->signr = SIG_ISOCOMPLETE;
441
#else
442
    urb->signr = 0;
443
#endif
444
    urb->usercontext = s;
445
    urb->number_of_packets = 1;
446
    urb->iso_frame_desc[0].length = p->len;
447
    urb->iso_frame_desc[0].actual_length = 0;
448
    urb->iso_frame_desc[0].status = 0;
449
    ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
450
    if (ret == 0) {
451
        if (!add_pending_urb(urb)) {
452
            printf("usb_host_handle_isoch: add_pending_urb failed %p\n", urb);
453
        }
454
    } else {
455
        printf("usb_host_handle_isoch: SUBMITURB ioctl=%d errno=%d\n",
456
               ret, errno);
457
        qemu_free(urb);
458
        switch(errno) {
459
        case ETIMEDOUT:
460
            return USB_RET_NAK;
461
        case EPIPE:
462
        default:
463
            return USB_RET_STALL;
464
        }
465
    }
466
#ifdef USE_ASYNCIO
467
    /* FIXME: handle urbs_ready together with sync io
468
     * workaround for injecting the signaled urbs into current frame */
469
    if (s->urbs_ready > 0) {
470
        ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);
471
        if (ret == 0) {
472
            ret = purb->actual_length;
473
            qemu_free(purb);
474
            s->urbs_ready--;
475
        }
476
        return ret;
477
    }
478
    s->packet = p;
479
    return USB_RET_ASYNC;
480
#else
481
    ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);
482
    if (ret == 0) {
483
        if (del_pending_urb(purb)) {
484
            ret = purb->actual_length;
485
            qemu_free(purb);
486
        } else {
487
            printf("usb_host_handle_isoch: del_pending_urb failed %p\n", purb);
488
        }
489
    } else {
490
#ifdef DEBUG_ISOCH
491
        printf("usb_host_handle_isoch: REAPURBNDELAY ioctl=%d errno=%d\n",
492
               ret, errno);
493
#endif
494
    }
495
    return ret;
496
#endif
497
}
498

    
499
/* returns 1 on problem encountered or 0 for success */
500
static int usb_linux_update_endp_table(USBHostDevice *s)
501
{
502
    uint8_t *descriptors;
503
    uint8_t devep, type, configuration, alt_interface;
504
    struct usb_ctrltransfer ct;
505
    int interface, ret, length, i;
506

    
507
    ct.bRequestType = USB_DIR_IN;
508
    ct.bRequest = USB_REQ_GET_CONFIGURATION;
509
    ct.wValue = 0;
510
    ct.wIndex = 0;
511
    ct.wLength = 1;
512
    ct.data = &configuration;
513
    ct.timeout = 50;
514

    
515
    ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
516
    if (ret < 0) {
517
        perror("usb_linux_update_endp_table");
518
        return 1;
519
    }
520

    
521
    /* in address state */
522
    if (configuration == 0)
523
        return 1;
524

    
525
    /* get the desired configuration, interface, and endpoint descriptors
526
     * from device description */
527
    descriptors = &s->descr[18];
528
    length = s->descr_len - 18;
529
    i = 0;
530

    
531
    if (descriptors[i + 1] != USB_DT_CONFIG ||
532
        descriptors[i + 5] != configuration) {
533
        printf("invalid descriptor data - configuration\n");
534
        return 1;
535
    }
536
    i += descriptors[i];
537

    
538
    while (i < length) {
539
        if (descriptors[i + 1] != USB_DT_INTERFACE ||
540
            (descriptors[i + 1] == USB_DT_INTERFACE &&
541
             descriptors[i + 4] == 0)) {
542
            i += descriptors[i];
543
            continue;
544
        }
545

    
546
        interface = descriptors[i + 2];
547

    
548
        ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
549
        ct.bRequest = USB_REQ_GET_INTERFACE;
550
        ct.wValue = 0;
551
        ct.wIndex = interface;
552
        ct.wLength = 1;
553
        ct.data = &alt_interface;
554
        ct.timeout = 50;
555

    
556
        ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
557
        if (ret < 0) {
558
            perror("usb_linux_update_endp_table");
559
            return 1;
560
        }
561

    
562
        /* the current interface descriptor is the active interface
563
         * and has endpoints */
564
        if (descriptors[i + 3] != alt_interface) {
565
            i += descriptors[i];
566
            continue;
567
        }
568

    
569
        /* advance to the endpoints */
570
        while (i < length && descriptors[i +1] != USB_DT_ENDPOINT)
571
            i += descriptors[i];
572

    
573
        if (i >= length)
574
            break;
575

    
576
        while (i < length) {
577
            if (descriptors[i + 1] != USB_DT_ENDPOINT)
578
                break;
579

    
580
            devep = descriptors[i + 2];
581
            switch (descriptors[i + 3] & 0x3) {
582
            case 0x00:
583
                type = USBDEVFS_URB_TYPE_CONTROL;
584
                break;
585
            case 0x01:
586
                type = USBDEVFS_URB_TYPE_ISO;
587
                break;
588
            case 0x02:
589
                type = USBDEVFS_URB_TYPE_BULK;
590
                break;
591
            case 0x03:
592
                type = USBDEVFS_URB_TYPE_INTERRUPT;
593
                break;
594
            default:
595
                printf("usb_host: malformed endpoint type\n");
596
                type = USBDEVFS_URB_TYPE_BULK;
597
            }
598
            s->endp_table[(devep & 0xf) - 1].type = type;
599

    
600
            i += descriptors[i];
601
        }
602
    }
603
    return 0;
604
}
605

    
606
static void usb_host_device_check(void *priv)
607
{
608
    USBHostDevice *s = priv;
609
    struct usbdevfs_connectinfo ci;
610
    int err;
611

    
612
    err = ioctl(s->fd, USBDEVFS_CONNECTINFO, &ci);
613
    if (err < 0) {
614
        printf("usb device %d.%d disconnected\n", 0, s->dev.addr);
615
        usb_device_del_addr(0, s->dev.addr);
616
        return;
617
    }
618

    
619
    qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 1000);
620
}
621

    
622
/* XXX: exclude high speed devices or implement EHCI */
623
USBDevice *usb_host_device_open(const char *devname)
624
{
625
    int fd = -1, ret;
626
    USBHostDevice *dev = NULL;
627
    struct usbdevfs_connectinfo ci;
628
    char buf[1024];
629
    int bus_num, addr;
630
    char product_name[PRODUCT_NAME_SZ];
631

    
632
    if (usb_host_find_device(&bus_num, &addr,
633
                             product_name, sizeof(product_name),
634
                             devname) < 0)
635
        return NULL;
636

    
637

    
638
    dev = qemu_mallocz(sizeof(USBHostDevice));
639
    if (!dev)
640
        goto fail;
641

    
642
    dev->timer = qemu_new_timer(rt_clock, usb_host_device_check, (void *) dev);
643
    if (!dev->timer)
644
        goto fail;
645

    
646
#ifdef DEBUG
647
    printf("usb_host_device_open %s\n", devname);
648
#endif
649

    
650
    snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
651
             bus_num, addr);
652
    fd = open(buf, O_RDWR | O_NONBLOCK);
653
    if (fd < 0) {
654
        perror(buf);
655
        goto fail;
656
    }
657

    
658
    /* read the device description */
659
    dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
660
    if (dev->descr_len <= 0) {
661
        perror("usb_host_device_open: reading device data failed");
662
        goto fail;
663
    }
664

    
665
#ifdef DEBUG
666
    {
667
        int x;
668
        printf("=== begin dumping device descriptor data ===\n");
669
        for (x = 0; x < dev->descr_len; x++)
670
            printf("%02x ", dev->descr[x]);
671
        printf("\n=== end dumping device descriptor data ===\n");
672
    }
673
#endif
674

    
675
    dev->fd = fd;
676
    dev->configuration = 1;
677

    
678
    /* XXX - do something about initial configuration */
679
    if (!usb_host_update_interfaces(dev, -1))
680
        goto fail;
681

    
682
    ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
683
    if (ret < 0) {
684
        perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
685
        goto fail;
686
    }
687

    
688
#ifdef DEBUG
689
    printf("host USB device %d.%d grabbed\n", bus_num, addr);
690
#endif
691

    
692
    ret = usb_linux_update_endp_table(dev);
693
    if (ret)
694
        goto fail;
695

    
696
    if (ci.slow)
697
        dev->dev.speed = USB_SPEED_LOW;
698
    else
699
        dev->dev.speed = USB_SPEED_HIGH;
700
    dev->dev.handle_packet = usb_generic_handle_packet;
701

    
702
    dev->dev.handle_reset = usb_host_handle_reset;
703
    dev->dev.handle_control = usb_host_handle_control;
704
    dev->dev.handle_data = usb_host_handle_data;
705
    dev->dev.handle_destroy = usb_host_handle_destroy;
706

    
707
    if (product_name[0] == '\0')
708
        snprintf(dev->dev.devname, sizeof(dev->dev.devname),
709
                 "host:%s", devname);
710
    else
711
        pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
712
                product_name);
713

    
714
#ifdef USE_ASYNCIO
715
    /* set up the signal handlers */
716
    sigemptyset(&sigact.sa_mask);
717
    sigact.sa_sigaction = isoch_done;
718
    sigact.sa_flags = SA_SIGINFO;
719
    sigact.sa_restorer = 0;
720
    ret = sigaction(SIG_ISOCOMPLETE, &sigact, NULL);
721
    if (ret < 0) {
722
        perror("usb_host_device_open: sigaction failed");
723
        goto fail;
724
    }
725

    
726
    if (pipe(dev->pipe_fds) < 0) {
727
        perror("usb_host_device_open: pipe creation failed");
728
        goto fail;
729
    }
730
    fcntl(dev->pipe_fds[0], F_SETFL, O_NONBLOCK | O_ASYNC);
731
    fcntl(dev->pipe_fds[1], F_SETFL, O_NONBLOCK);
732
    qemu_set_fd_handler(dev->pipe_fds[0], urb_completion_pipe_read, NULL, dev);
733
#endif
734

    
735
    /* Start the timer to detect disconnect */
736
    qemu_mod_timer(dev->timer, qemu_get_clock(rt_clock) + 1000);
737

    
738
    dev->urbs_ready = 0;
739
    return (USBDevice *)dev;
740
fail:
741
    if (dev) {
742
        if (dev->timer)
743
                qemu_del_timer(dev->timer);
744
        qemu_free(dev);
745
    }
746
    close(fd);
747
    return NULL;
748
}
749

    
750
static int get_tag_value(char *buf, int buf_size,
751
                         const char *str, const char *tag,
752
                         const char *stopchars)
753
{
754
    const char *p;
755
    char *q;
756
    p = strstr(str, tag);
757
    if (!p)
758
        return -1;
759
    p += strlen(tag);
760
    while (isspace(*p))
761
        p++;
762
    q = buf;
763
    while (*p != '\0' && !strchr(stopchars, *p)) {
764
        if ((q - buf) < (buf_size - 1))
765
            *q++ = *p;
766
        p++;
767
    }
768
    *q = '\0';
769
    return q - buf;
770
}
771

    
772
static int usb_host_scan(void *opaque, USBScanFunc *func)
773
{
774
    FILE *f;
775
    char line[1024];
776
    char buf[1024];
777
    int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
778
    int ret;
779
    char product_name[512];
780

    
781
    f = fopen(USBDEVFS_PATH "/devices", "r");
782
    if (!f) {
783
        term_printf("Could not open %s\n", USBDEVFS_PATH "/devices");
784
        return 0;
785
    }
786
    device_count = 0;
787
    bus_num = addr = speed = class_id = product_id = vendor_id = 0;
788
    ret = 0;
789
    for(;;) {
790
        if (fgets(line, sizeof(line), f) == NULL)
791
            break;
792
        if (strlen(line) > 0)
793
            line[strlen(line) - 1] = '\0';
794
        if (line[0] == 'T' && line[1] == ':') {
795
            if (device_count && (vendor_id || product_id)) {
796
                /* New device.  Add the previously discovered device.  */
797
                ret = func(opaque, bus_num, addr, class_id, vendor_id,
798
                           product_id, product_name, speed);
799
                if (ret)
800
                    goto the_end;
801
            }
802
            if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0)
803
                goto fail;
804
            bus_num = atoi(buf);
805
            if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0)
806
                goto fail;
807
            addr = atoi(buf);
808
            if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0)
809
                goto fail;
810
            if (!strcmp(buf, "480"))
811
                speed = USB_SPEED_HIGH;
812
            else if (!strcmp(buf, "1.5"))
813
                speed = USB_SPEED_LOW;
814
            else
815
                speed = USB_SPEED_FULL;
816
            product_name[0] = '\0';
817
            class_id = 0xff;
818
            device_count++;
819
            product_id = 0;
820
            vendor_id = 0;
821
        } else if (line[0] == 'P' && line[1] == ':') {
822
            if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0)
823
                goto fail;
824
            vendor_id = strtoul(buf, NULL, 16);
825
            if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0)
826
                goto fail;
827
            product_id = strtoul(buf, NULL, 16);
828
        } else if (line[0] == 'S' && line[1] == ':') {
829
            if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0)
830
                goto fail;
831
            pstrcpy(product_name, sizeof(product_name), buf);
832
        } else if (line[0] == 'D' && line[1] == ':') {
833
            if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0)
834
                goto fail;
835
            class_id = strtoul(buf, NULL, 16);
836
        }
837
    fail: ;
838
    }
839
    if (device_count && (vendor_id || product_id)) {
840
        /* Add the last device.  */
841
        ret = func(opaque, bus_num, addr, class_id, vendor_id,
842
                   product_id, product_name, speed);
843
    }
844
 the_end:
845
    fclose(f);
846
    return ret;
847
}
848

    
849
typedef struct FindDeviceState {
850
    int vendor_id;
851
    int product_id;
852
    int bus_num;
853
    int addr;
854
    char product_name[PRODUCT_NAME_SZ];
855
} FindDeviceState;
856

    
857
static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
858
                                     int class_id,
859
                                     int vendor_id, int product_id,
860
                                     const char *product_name, int speed)
861
{
862
    FindDeviceState *s = opaque;
863
    if ((vendor_id == s->vendor_id &&
864
        product_id == s->product_id) ||
865
        (bus_num == s->bus_num &&
866
        addr == s->addr)) {
867
        pstrcpy(s->product_name, PRODUCT_NAME_SZ, product_name);
868
        s->bus_num = bus_num;
869
        s->addr = addr;
870
        return 1;
871
    } else {
872
        return 0;
873
    }
874
}
875

    
876
/* the syntax is :
877
   'bus.addr' (decimal numbers) or
878
   'vendor_id:product_id' (hexa numbers) */
879
static int usb_host_find_device(int *pbus_num, int *paddr,
880
                                char *product_name, int product_name_size,
881
                                const char *devname)
882
{
883
    const char *p;
884
    int ret;
885
    FindDeviceState fs;
886

    
887
    p = strchr(devname, '.');
888
    if (p) {
889
        *pbus_num = strtoul(devname, NULL, 0);
890
        *paddr = strtoul(p + 1, NULL, 0);
891
        fs.bus_num = *pbus_num;
892
        fs.addr = *paddr;
893
        ret = usb_host_scan(&fs, usb_host_find_device_scan);
894
        if (ret)
895
            pstrcpy(product_name, product_name_size, fs.product_name);
896
        return 0;
897
    }
898
    p = strchr(devname, ':');
899
    if (p) {
900
        fs.vendor_id = strtoul(devname, NULL, 16);
901
        fs.product_id = strtoul(p + 1, NULL, 16);
902
        ret = usb_host_scan(&fs, usb_host_find_device_scan);
903
        if (ret) {
904
            *pbus_num = fs.bus_num;
905
            *paddr = fs.addr;
906
            pstrcpy(product_name, product_name_size, fs.product_name);
907
            return 0;
908
        }
909
    }
910
    return -1;
911
}
912

    
913
/**********************/
914
/* USB host device info */
915

    
916
struct usb_class_info {
917
    int class;
918
    const char *class_name;
919
};
920

    
921
static const struct usb_class_info usb_class_info[] = {
922
    { USB_CLASS_AUDIO, "Audio"},
923
    { USB_CLASS_COMM, "Communication"},
924
    { USB_CLASS_HID, "HID"},
925
    { USB_CLASS_HUB, "Hub" },
926
    { USB_CLASS_PHYSICAL, "Physical" },
927
    { USB_CLASS_PRINTER, "Printer" },
928
    { USB_CLASS_MASS_STORAGE, "Storage" },
929
    { USB_CLASS_CDC_DATA, "Data" },
930
    { USB_CLASS_APP_SPEC, "Application Specific" },
931
    { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
932
    { USB_CLASS_STILL_IMAGE, "Still Image" },
933
    { USB_CLASS_CSCID, "Smart Card" },
934
    { USB_CLASS_CONTENT_SEC, "Content Security" },
935
    { -1, NULL }
936
};
937

    
938
static const char *usb_class_str(uint8_t class)
939
{
940
    const struct usb_class_info *p;
941
    for(p = usb_class_info; p->class != -1; p++) {
942
        if (p->class == class)
943
            break;
944
    }
945
    return p->class_name;
946
}
947

    
948
static void usb_info_device(int bus_num, int addr, int class_id,
949
                            int vendor_id, int product_id,
950
                            const char *product_name,
951
                            int speed)
952
{
953
    const char *class_str, *speed_str;
954

    
955
    switch(speed) {
956
    case USB_SPEED_LOW:
957
        speed_str = "1.5";
958
        break;
959
    case USB_SPEED_FULL:
960
        speed_str = "12";
961
        break;
962
    case USB_SPEED_HIGH:
963
        speed_str = "480";
964
        break;
965
    default:
966
        speed_str = "?";
967
        break;
968
    }
969

    
970
    term_printf("  Device %d.%d, speed %s Mb/s\n",
971
                bus_num, addr, speed_str);
972
    class_str = usb_class_str(class_id);
973
    if (class_str)
974
        term_printf("    %s:", class_str);
975
    else
976
        term_printf("    Class %02x:", class_id);
977
    term_printf(" USB device %04x:%04x", vendor_id, product_id);
978
    if (product_name[0] != '\0')
979
        term_printf(", %s", product_name);
980
    term_printf("\n");
981
}
982

    
983
static int usb_host_info_device(void *opaque, int bus_num, int addr,
984
                                int class_id,
985
                                int vendor_id, int product_id,
986
                                const char *product_name,
987
                                int speed)
988
{
989
    usb_info_device(bus_num, addr, class_id, vendor_id, product_id,
990
                    product_name, speed);
991
    return 0;
992
}
993

    
994
void usb_host_info(void)
995
{
996
    usb_host_scan(NULL, usb_host_info_device);
997
}
998

    
999
#else
1000

    
1001
void usb_host_info(void)
1002
{
1003
    term_printf("USB host devices not supported\n");
1004
}
1005

    
1006
/* XXX: modify configure to compile the right host driver */
1007
USBDevice *usb_host_device_open(const char *devname)
1008
{
1009
    return NULL;
1010
}
1011

    
1012
#endif