Statistics
| Branch: | Revision:

root / usb-linux.c @ 0d380648

History | View | Annotate | Download (28.4 kB)

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

    
33
#if defined(__linux__)
34
#include <dirent.h>
35
#include <sys/ioctl.h>
36
#include <linux/usbdevice_fs.h>
37
#include <linux/version.h>
38
#include <signal.h>
39

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

    
51
typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
52
                        int vendor_id, int product_id,
53
                        const char *product_name, int speed);
54
static int usb_host_find_device(int *pbus_num, int *paddr,
55
                                char *product_name, int product_name_size,
56
                                const char *devname);
57

    
58
//#define DEBUG
59

    
60
#ifdef DEBUG
61
#define dprintf printf
62
#else
63
#define dprintf(...)
64
#endif
65

    
66
#define USBDEVFS_PATH "/proc/bus/usb"
67
#define PRODUCT_NAME_SZ 32
68
#define MAX_ENDPOINTS 16
69

    
70
struct sigaction sigact;
71

    
72
/* endpoint association data */
73
struct endp_data {
74
    uint8_t type;
75
    uint8_t halted;
76
};
77

    
78
typedef struct USBHostDevice {
79
    USBDevice dev;
80
    int       fd;
81

    
82
    uint8_t   descr[1024];
83
    int       descr_len;
84
    int       configuration;
85
    int       closing;
86

    
87
    struct endp_data endp_table[MAX_ENDPOINTS];
88

    
89
    /* Host side address */
90
    int bus_num;
91
    int addr;
92

    
93
    struct USBHostDevice *next;
94
} USBHostDevice;
95

    
96
static int is_isoc(USBHostDevice *s, int ep)
97
{
98
    return s->endp_table[ep - 1].type == USBDEVFS_URB_TYPE_ISO;
99
}
100

    
101
static int is_halted(USBHostDevice *s, int ep)
102
{
103
    return s->endp_table[ep - 1].halted;
104
}
105

    
106
static void clear_halt(USBHostDevice *s, int ep)
107
{
108
    s->endp_table[ep - 1].halted = 0;
109
}
110

    
111
static void set_halt(USBHostDevice *s, int ep)
112
{
113
    s->endp_table[ep - 1].halted = 1;
114
}
115

    
116
static USBHostDevice *hostdev_list;
117

    
118
static void hostdev_link(USBHostDevice *dev)
119
{
120
    dev->next = hostdev_list;
121
    hostdev_list = dev;
122
}
123

    
124
static void hostdev_unlink(USBHostDevice *dev)
125
{
126
    USBHostDevice *pdev = hostdev_list;
127
    USBHostDevice **prev = &hostdev_list;
128

    
129
    while (pdev) {
130
        if (pdev == dev) {
131
            *prev = dev->next;
132
            return;
133
        }
134

    
135
        prev = &pdev->next;
136
        pdev = pdev->next;
137
    }
138
}
139

    
140
static USBHostDevice *hostdev_find(int bus_num, int addr)
141
{
142
    USBHostDevice *s = hostdev_list;
143
    while (s) {
144
        if (s->bus_num == bus_num && s->addr == addr)
145
            return s;
146
        s = s->next;
147
    }
148
    return NULL;
149
}
150

    
151
/* 
152
 * Async URB state.
153
 * We always allocate one isoc descriptor even for bulk transfers
154
 * to simplify allocation and casts. 
155
 */
156
typedef struct AsyncURB
157
{
158
    struct usbdevfs_urb urb;
159
    struct usbdevfs_iso_packet_desc isocpd;
160

    
161
    USBPacket     *packet;
162
    USBHostDevice *hdev;
163
} AsyncURB;
164

    
165
static AsyncURB *async_alloc(void)
166
{
167
    return (AsyncURB *) qemu_mallocz(sizeof(AsyncURB));
168
}
169

    
170
static void async_free(AsyncURB *aurb)
171
{
172
    qemu_free(aurb);
173
}
174

    
175
static void async_complete(void *opaque)
176
{
177
    USBHostDevice *s = opaque;
178
    AsyncURB *aurb;
179

    
180
    while (1) {
181
            USBPacket *p;
182

    
183
        int r = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &aurb);
184
        if (r < 0) {
185
            if (errno == EAGAIN)
186
                return;
187

    
188
            if (errno == ENODEV && !s->closing) {
189
                printf("husb: device %d.%d disconnected\n", s->bus_num, s->addr);
190
                usb_device_del_addr(0, s->dev.addr);
191
                return;
192
            }
193

    
194
            dprintf("husb: async. reap urb failed errno %d\n", errno);
195
            return;
196
        }
197

    
198
        p = aurb->packet;
199

    
200
        dprintf("husb: async completed. aurb %p status %d alen %d\n", 
201
                aurb, aurb->urb.status, aurb->urb.actual_length);
202

    
203
        if (p) {
204
            switch (aurb->urb.status) {
205
            case 0:
206
                p->len = aurb->urb.actual_length;
207
                break;
208

    
209
            case -EPIPE:
210
                set_halt(s, p->devep);
211
                /* fall through */
212
            default:
213
                p->len = USB_RET_NAK;
214
                break;
215
            }
216

    
217
            usb_packet_complete(p);
218
        }
219

    
220
        async_free(aurb);
221
    }
222
}
223

    
224
static void async_cancel(USBPacket *unused, void *opaque)
225
{
226
    AsyncURB *aurb = opaque;
227
    USBHostDevice *s = aurb->hdev;
228

    
229
    dprintf("husb: async cancel. aurb %p\n", aurb);
230

    
231
    /* Mark it as dead (see async_complete above) */
232
    aurb->packet = NULL;
233

    
234
    int r = ioctl(s->fd, USBDEVFS_DISCARDURB, aurb);
235
    if (r < 0) {
236
        dprintf("husb: async. discard urb failed errno %d\n", errno);
237
    }
238
}
239

    
240
static int usb_host_update_interfaces(USBHostDevice *dev, int configuration)
241
{
242
    int dev_descr_len, config_descr_len;
243
    int interface, nb_interfaces, nb_configurations;
244
    int ret, i;
245

    
246
    if (configuration == 0) /* address state - ignore */
247
        return 1;
248

    
249
    i = 0;
250
    dev_descr_len = dev->descr[0];
251
    if (dev_descr_len > dev->descr_len)
252
        goto fail;
253
    nb_configurations = dev->descr[17];
254

    
255
    i += dev_descr_len;
256
    while (i < dev->descr_len) {
257
        dprintf("husb: i is %d, descr_len is %d, dl %d, dt %d\n", i, dev->descr_len,
258
               dev->descr[i], dev->descr[i+1]);
259

    
260
        if (dev->descr[i+1] != USB_DT_CONFIG) {
261
            i += dev->descr[i];
262
            continue;
263
        }
264
        config_descr_len = dev->descr[i];
265

    
266
        printf("husb: config #%d need %d\n", dev->descr[i + 5], configuration); 
267

    
268
        if (configuration < 0 || configuration == dev->descr[i + 5])
269
            break;
270

    
271
        i += config_descr_len;
272
    }
273

    
274
    if (i >= dev->descr_len) {
275
        fprintf(stderr, "husb: update iface failed. no matching configuration\n");
276
        goto fail;
277
    }
278
    nb_interfaces = dev->descr[i + 4];
279

    
280
#ifdef USBDEVFS_DISCONNECT
281
    /* earlier Linux 2.4 do not support that */
282
    {
283
        struct usbdevfs_ioctl ctrl;
284
        for (interface = 0; interface < nb_interfaces; interface++) {
285
            ctrl.ioctl_code = USBDEVFS_DISCONNECT;
286
            ctrl.ifno = interface;
287
            ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
288
            if (ret < 0 && errno != ENODATA) {
289
                perror("USBDEVFS_DISCONNECT");
290
                goto fail;
291
            }
292
        }
293
    }
294
#endif
295

    
296
    /* XXX: only grab if all interfaces are free */
297
    for (interface = 0; interface < nb_interfaces; interface++) {
298
        ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
299
        if (ret < 0) {
300
            if (errno == EBUSY) {
301
                printf("husb: update iface. device already grabbed\n");
302
            } else {
303
                perror("husb: failed to claim interface");
304
            }
305
        fail:
306
            return 0;
307
        }
308
    }
309

    
310
    printf("husb: %d interfaces claimed for configuration %d\n",
311
           nb_interfaces, configuration);
312

    
313
    return 1;
314
}
315

    
316
static void usb_host_handle_reset(USBDevice *dev)
317
{
318
    USBHostDevice *s = (USBHostDevice *)dev;
319

    
320
    dprintf("husb: reset device %u.%u\n", s->bus_num, s->addr);
321

    
322
    ioctl(s->fd, USBDEVFS_RESET);
323
    usb_host_update_interfaces(s, s->configuration);
324
}
325

    
326
static void usb_host_handle_destroy(USBDevice *dev)
327
{
328
    USBHostDevice *s = (USBHostDevice *)dev;
329

    
330
    s->closing = 1;
331

    
332
    qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
333

    
334
    hostdev_unlink(s);
335

    
336
    async_complete(s);
337

    
338
    if (s->fd >= 0)
339
        close(s->fd);
340

    
341
    qemu_free(s);
342
}
343

    
344
static int usb_linux_update_endp_table(USBHostDevice *s);
345

    
346
static int usb_host_handle_control(USBDevice *dev,
347
                                   int request,
348
                                   int value,
349
                                   int index,
350
                                   int length,
351
                                   uint8_t *data)
352
{
353
    USBHostDevice *s = (USBHostDevice *)dev;
354
    struct usb_ctrltransfer ct;
355
    struct usbdevfs_setinterface si;
356
    int intf_update_required = 0;
357
    int ret;
358

    
359
    if (request == (DeviceOutRequest | USB_REQ_SET_ADDRESS)) {
360
        /* specific SET_ADDRESS support */
361
        dev->addr = value;
362
        return 0;
363
    } else if (request == ((USB_RECIP_INTERFACE << 8) |
364
                           USB_REQ_SET_INTERFACE)) {
365
        /* set alternate setting for the interface */
366
        si.interface = index;
367
        si.altsetting = value;
368
        ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
369
        usb_linux_update_endp_table(s);
370
    } else if (request == (DeviceOutRequest | USB_REQ_SET_CONFIGURATION)) {
371
        dprintf("husb: ctrl set config %d\n", value & 0xff);
372
        if (s->configuration != (value & 0xff)) {
373
            s->configuration = (value & 0xff);
374
            intf_update_required = 1;
375
        }
376
        goto do_request;
377
    } else {
378
    do_request:
379
        ct.bRequestType = request >> 8;
380
        ct.bRequest = request;
381
        ct.wValue = value;
382
        ct.wIndex = index;
383
        ct.wLength = length;
384
        ct.timeout = 50;
385
        ct.data = data;
386
        ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
387

    
388
        dprintf("husb: ctrl req 0x%x val 0x%x index %u len %u ret %d\n",
389
            ct.bRequest, ct.wValue, ct.wIndex, ct.wLength, ret);
390
    }
391

    
392
    if (ret < 0) {
393
        switch(errno) {
394
        case ETIMEDOUT:
395
            return USB_RET_NAK;
396
        default:
397
            return USB_RET_STALL;
398
        }
399
    } else {
400
        if (intf_update_required) {
401
            dprintf("husb: updating interfaces\n");
402
            usb_host_update_interfaces(s, value & 0xff);
403
        }
404
        return ret;
405
    }
406
}
407

    
408
static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
409
{
410
    USBHostDevice *s = (USBHostDevice *) dev;
411
    AsyncURB *aurb;
412
    struct usbdevfs_urb *urb;
413
    int ret;
414

    
415
    aurb = async_alloc();
416
    if (!aurb) {
417
        dprintf("husb: async malloc failed\n");
418
        return USB_RET_NAK;
419
    }
420
    aurb->hdev   = s;
421
    aurb->packet = p;
422

    
423
    urb = &aurb->urb;
424

    
425
    if (p->pid == USB_TOKEN_IN)
426
            urb->endpoint = p->devep | 0x80;
427
    else
428
            urb->endpoint = p->devep;
429

    
430
    if (is_halted(s, p->devep)) {
431
        ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &urb->endpoint);
432
        if (ret < 0) {
433
            dprintf("husb: failed to clear halt. ep 0x%x errno %d\n", 
434
                   urb->endpoint, errno);
435
            return USB_RET_NAK;
436
        }
437
        clear_halt(s, p->devep);
438
    }
439

    
440
    urb->buffer        = p->data;
441
    urb->buffer_length = p->len;
442

    
443
    if (is_isoc(s, p->devep)) {
444
        /* Setup ISOC transfer */
445
        urb->type     = USBDEVFS_URB_TYPE_ISO;
446
        urb->flags    = USBDEVFS_URB_ISO_ASAP;
447
        urb->number_of_packets = 1;
448
        urb->iso_frame_desc[0].length = p->len;
449
    } else {
450
        /* Setup bulk transfer */
451
        urb->type     = USBDEVFS_URB_TYPE_BULK;
452
    }
453

    
454
    urb->usercontext = s;
455

    
456
    ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
457

    
458
    dprintf("husb: data submit. ep 0x%x len %u aurb %p\n", urb->endpoint, p->len, aurb);
459

    
460
    if (ret < 0) {
461
        dprintf("husb: submit failed. errno %d\n", errno);
462
        async_free(aurb);
463

    
464
        switch(errno) {
465
        case ETIMEDOUT:
466
            return USB_RET_NAK;
467
        case EPIPE:
468
        default:
469
            return USB_RET_STALL;
470
        }
471
    }
472

    
473
    usb_defer_packet(p, async_cancel, aurb);
474
    return USB_RET_ASYNC;
475
}
476

    
477
/* returns 1 on problem encountered or 0 for success */
478
static int usb_linux_update_endp_table(USBHostDevice *s)
479
{
480
    uint8_t *descriptors;
481
    uint8_t devep, type, configuration, alt_interface;
482
    struct usb_ctrltransfer ct;
483
    int interface, ret, length, i;
484

    
485
    ct.bRequestType = USB_DIR_IN;
486
    ct.bRequest = USB_REQ_GET_CONFIGURATION;
487
    ct.wValue = 0;
488
    ct.wIndex = 0;
489
    ct.wLength = 1;
490
    ct.data = &configuration;
491
    ct.timeout = 50;
492

    
493
    ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
494
    if (ret < 0) {
495
        perror("usb_linux_update_endp_table");
496
        return 1;
497
    }
498

    
499
    /* in address state */
500
    if (configuration == 0)
501
        return 1;
502

    
503
    /* get the desired configuration, interface, and endpoint descriptors
504
     * from device description */
505
    descriptors = &s->descr[18];
506
    length = s->descr_len - 18;
507
    i = 0;
508

    
509
    if (descriptors[i + 1] != USB_DT_CONFIG ||
510
        descriptors[i + 5] != configuration) {
511
        dprintf("invalid descriptor data - configuration\n");
512
        return 1;
513
    }
514
    i += descriptors[i];
515

    
516
    while (i < length) {
517
        if (descriptors[i + 1] != USB_DT_INTERFACE ||
518
            (descriptors[i + 1] == USB_DT_INTERFACE &&
519
             descriptors[i + 4] == 0)) {
520
            i += descriptors[i];
521
            continue;
522
        }
523

    
524
        interface = descriptors[i + 2];
525

    
526
        ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
527
        ct.bRequest = USB_REQ_GET_INTERFACE;
528
        ct.wValue = 0;
529
        ct.wIndex = interface;
530
        ct.wLength = 1;
531
        ct.data = &alt_interface;
532
        ct.timeout = 50;
533

    
534
        ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
535
        if (ret < 0) {
536
            perror("usb_linux_update_endp_table");
537
            return 1;
538
        }
539

    
540
        /* the current interface descriptor is the active interface
541
         * and has endpoints */
542
        if (descriptors[i + 3] != alt_interface) {
543
            i += descriptors[i];
544
            continue;
545
        }
546

    
547
        /* advance to the endpoints */
548
        while (i < length && descriptors[i +1] != USB_DT_ENDPOINT)
549
            i += descriptors[i];
550

    
551
        if (i >= length)
552
            break;
553

    
554
        while (i < length) {
555
            if (descriptors[i + 1] != USB_DT_ENDPOINT)
556
                break;
557

    
558
            devep = descriptors[i + 2];
559
            switch (descriptors[i + 3] & 0x3) {
560
            case 0x00:
561
                type = USBDEVFS_URB_TYPE_CONTROL;
562
                break;
563
            case 0x01:
564
                type = USBDEVFS_URB_TYPE_ISO;
565
                break;
566
            case 0x02:
567
                type = USBDEVFS_URB_TYPE_BULK;
568
                break;
569
            case 0x03:
570
                type = USBDEVFS_URB_TYPE_INTERRUPT;
571
                break;
572
            default:
573
                dprintf("usb_host: malformed endpoint type\n");
574
                type = USBDEVFS_URB_TYPE_BULK;
575
            }
576
            s->endp_table[(devep & 0xf) - 1].type = type;
577
            s->endp_table[(devep & 0xf) - 1].halted = 0;
578

    
579
            i += descriptors[i];
580
        }
581
    }
582
    return 0;
583
}
584

    
585
static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *prod_name)
586
{
587
    int fd = -1, ret;
588
    USBHostDevice *dev = NULL;
589
    struct usbdevfs_connectinfo ci;
590
    char buf[1024];
591

    
592
    dev = qemu_mallocz(sizeof(USBHostDevice));
593
    if (!dev)
594
        goto fail;
595

    
596
    dev->bus_num = bus_num;
597
    dev->addr = addr;
598

    
599
    printf("husb: open device %d.%d\n", bus_num, addr);
600

    
601
    snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
602
             bus_num, addr);
603
    fd = open(buf, O_RDWR | O_NONBLOCK);
604
    if (fd < 0) {
605
        perror(buf);
606
        goto fail;
607
    }
608

    
609
    /* read the device description */
610
    dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
611
    if (dev->descr_len <= 0) {
612
        perror("husb: reading device data failed");
613
        goto fail;
614
    }
615

    
616
#ifdef DEBUG
617
    {
618
        int x;
619
        printf("=== begin dumping device descriptor data ===\n");
620
        for (x = 0; x < dev->descr_len; x++)
621
            printf("%02x ", dev->descr[x]);
622
        printf("\n=== end dumping device descriptor data ===\n");
623
    }
624
#endif
625

    
626
    dev->fd = fd;
627
    dev->configuration = 1;
628

    
629
    /* XXX - do something about initial configuration */
630
    if (!usb_host_update_interfaces(dev, -1))
631
        goto fail;
632

    
633
    ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
634
    if (ret < 0) {
635
        perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
636
        goto fail;
637
    }
638

    
639
    printf("husb: grabbed usb device %d.%d\n", bus_num, addr);
640

    
641
    ret = usb_linux_update_endp_table(dev);
642
    if (ret)
643
        goto fail;
644

    
645
    if (ci.slow)
646
        dev->dev.speed = USB_SPEED_LOW;
647
    else
648
        dev->dev.speed = USB_SPEED_HIGH;
649
    dev->dev.handle_packet = usb_generic_handle_packet;
650

    
651
    dev->dev.handle_reset = usb_host_handle_reset;
652
    dev->dev.handle_control = usb_host_handle_control;
653
    dev->dev.handle_data = usb_host_handle_data;
654
    dev->dev.handle_destroy = usb_host_handle_destroy;
655

    
656
    if (!prod_name || prod_name[0] == '\0')
657
        snprintf(dev->dev.devname, sizeof(dev->dev.devname),
658
                 "host:%d.%d", bus_num, addr);
659
    else
660
        pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
661
                prod_name);
662

    
663
    /* USB devio uses 'write' flag to check for async completions */
664
    qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);
665

    
666
    hostdev_link(dev);
667

    
668
    return (USBDevice *) dev;
669

    
670
fail:
671
    if (dev)
672
        qemu_free(dev);
673

    
674
    close(fd);
675
    return NULL;
676
}
677

    
678
USBDevice *usb_host_device_open(const char *devname)
679
{
680
    int bus_num, addr;
681
    char product_name[PRODUCT_NAME_SZ];
682

    
683
    if (usb_host_find_device(&bus_num, &addr,
684
                             product_name, sizeof(product_name),
685
                             devname) < 0)
686
        return NULL;
687

    
688
     if (hostdev_find(bus_num, addr)) {
689
        term_printf("husb: host usb device %d.%d is already open\n", bus_num, addr);
690
        return NULL;
691
     }
692

    
693
    return usb_host_device_open_addr(bus_num, addr, product_name);
694
}
695
 
696
static int get_tag_value(char *buf, int buf_size,
697
                         const char *str, const char *tag,
698
                         const char *stopchars)
699
{
700
    const char *p;
701
    char *q;
702
    p = strstr(str, tag);
703
    if (!p)
704
        return -1;
705
    p += strlen(tag);
706
    while (isspace(*p))
707
        p++;
708
    q = buf;
709
    while (*p != '\0' && !strchr(stopchars, *p)) {
710
        if ((q - buf) < (buf_size - 1))
711
            *q++ = *p;
712
        p++;
713
    }
714
    *q = '\0';
715
    return q - buf;
716
}
717

    
718
static int usb_host_scan(void *opaque, USBScanFunc *func)
719
{
720
    FILE *f;
721
    char line[1024];
722
    char buf[1024];
723
    int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
724
    int ret;
725
    char product_name[512];
726

    
727
    f = fopen(USBDEVFS_PATH "/devices", "r");
728
    if (!f) {
729
        term_printf("husb: could not open %s\n", USBDEVFS_PATH "/devices");
730
        return 0;
731
    }
732
    device_count = 0;
733
    bus_num = addr = speed = class_id = product_id = vendor_id = 0;
734
    ret = 0;
735
    for(;;) {
736
        if (fgets(line, sizeof(line), f) == NULL)
737
            break;
738
        if (strlen(line) > 0)
739
            line[strlen(line) - 1] = '\0';
740
        if (line[0] == 'T' && line[1] == ':') {
741
            if (device_count && (vendor_id || product_id)) {
742
                /* New device.  Add the previously discovered device.  */
743
                ret = func(opaque, bus_num, addr, class_id, vendor_id,
744
                           product_id, product_name, speed);
745
                if (ret)
746
                    goto the_end;
747
            }
748
            if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0)
749
                goto fail;
750
            bus_num = atoi(buf);
751
            if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0)
752
                goto fail;
753
            addr = atoi(buf);
754
            if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0)
755
                goto fail;
756
            if (!strcmp(buf, "480"))
757
                speed = USB_SPEED_HIGH;
758
            else if (!strcmp(buf, "1.5"))
759
                speed = USB_SPEED_LOW;
760
            else
761
                speed = USB_SPEED_FULL;
762
            product_name[0] = '\0';
763
            class_id = 0xff;
764
            device_count++;
765
            product_id = 0;
766
            vendor_id = 0;
767
        } else if (line[0] == 'P' && line[1] == ':') {
768
            if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0)
769
                goto fail;
770
            vendor_id = strtoul(buf, NULL, 16);
771
            if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0)
772
                goto fail;
773
            product_id = strtoul(buf, NULL, 16);
774
        } else if (line[0] == 'S' && line[1] == ':') {
775
            if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0)
776
                goto fail;
777
            pstrcpy(product_name, sizeof(product_name), buf);
778
        } else if (line[0] == 'D' && line[1] == ':') {
779
            if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0)
780
                goto fail;
781
            class_id = strtoul(buf, NULL, 16);
782
        }
783
    fail: ;
784
    }
785
    if (device_count && (vendor_id || product_id)) {
786
        /* Add the last device.  */
787
        ret = func(opaque, bus_num, addr, class_id, vendor_id,
788
                   product_id, product_name, speed);
789
    }
790
 the_end:
791
    fclose(f);
792
    return ret;
793
}
794

    
795
struct USBAutoFilter {
796
    struct USBAutoFilter *next;
797
    int bus_num;
798
    int addr;
799
    int vendor_id;
800
    int product_id;
801
};
802

    
803
static QEMUTimer *usb_auto_timer;
804
static struct USBAutoFilter *usb_auto_filter;
805

    
806
static int usb_host_auto_scan(void *opaque, int bus_num, int addr,
807
                     int class_id, int vendor_id, int product_id,
808
                     const char *product_name, int speed)
809
{
810
    struct USBAutoFilter *f;
811
    struct USBDevice *dev;
812

    
813
    /* Ignore hubs */
814
    if (class_id == 9)
815
        return 0;
816

    
817
    for (f = usb_auto_filter; f; f = f->next) {
818
        if (f->bus_num >= 0 && f->bus_num != bus_num)
819
            continue;
820

    
821
        if (f->addr >= 0 && f->addr != addr)
822
            continue;
823

    
824
        if (f->vendor_id >= 0 && f->vendor_id != vendor_id)
825
            continue;
826

    
827
        if (f->product_id >= 0 && f->product_id != product_id)
828
            continue;
829

    
830
        /* We got a match */
831

    
832
        /* Allredy attached ? */
833
        if (hostdev_find(bus_num, addr))
834
            return 0;
835

    
836
        dprintf("husb: auto open: bus_num %d addr %d\n", bus_num, addr);
837

    
838
        dev = usb_host_device_open_addr(bus_num, addr, product_name);
839
        if (dev)
840
            usb_device_add_dev(dev);
841
    }
842

    
843
    return 0;
844
}
845

    
846
static void usb_host_auto_timer(void *unused)
847
{
848
    usb_host_scan(NULL, usb_host_auto_scan);
849
    qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);
850
}
851

    
852
/*
853
 * Add autoconnect filter
854
 * -1 means 'any' (device, vendor, etc)
855
 */
856
static void usb_host_auto_add(int bus_num, int addr, int vendor_id, int product_id)
857
{
858
    struct USBAutoFilter *f = qemu_mallocz(sizeof(*f));
859
    if (!f) {
860
        fprintf(stderr, "husb: failed to allocate auto filter\n");
861
        return;
862
    }
863

    
864
    f->bus_num = bus_num;
865
    f->addr    = addr;
866
    f->vendor_id  = vendor_id;
867
    f->product_id = product_id;
868

    
869
    if (!usb_auto_filter) {
870
        /*
871
         * First entry. Init and start the monitor.
872
         * Right now we're using timer to check for new devices.
873
         * If this turns out to be too expensive we can move that into a 
874
         * separate thread.
875
         */
876
        usb_auto_timer = qemu_new_timer(rt_clock, usb_host_auto_timer, NULL);
877
        if (!usb_auto_timer) {
878
            fprintf(stderr, "husb: failed to allocate auto scan timer\n");
879
            qemu_free(f);
880
            return;
881
        }
882

    
883
        /* Check for new devices every two seconds */
884
        qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);
885
    }
886

    
887
    dprintf("husb: auto filter: bus_num %d addr %d vid %d pid %d\n",
888
        bus_num, addr, vendor_id, product_id);
889

    
890
    f->next = usb_auto_filter;
891
    usb_auto_filter = f;
892
}
893

    
894
typedef struct FindDeviceState {
895
    int vendor_id;
896
    int product_id;
897
    int bus_num;
898
    int addr;
899
    char product_name[PRODUCT_NAME_SZ];
900
} FindDeviceState;
901

    
902
static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
903
                                     int class_id,
904
                                     int vendor_id, int product_id,
905
                                     const char *product_name, int speed)
906
{
907
    FindDeviceState *s = opaque;
908
    if ((vendor_id == s->vendor_id &&
909
        product_id == s->product_id) ||
910
        (bus_num == s->bus_num &&
911
        addr == s->addr)) {
912
        pstrcpy(s->product_name, PRODUCT_NAME_SZ, product_name);
913
        s->bus_num = bus_num;
914
        s->addr = addr;
915
        return 1;
916
    } else {
917
        return 0;
918
    }
919
}
920

    
921
/* the syntax is :
922
   'bus.addr' (decimal numbers) or
923
   'vendor_id:product_id' (hexa numbers) */
924
static int usb_host_find_device(int *pbus_num, int *paddr,
925
                                char *product_name, int product_name_size,
926
                                const char *devname)
927
{
928
    const char *p;
929
    int ret;
930
    FindDeviceState fs;
931

    
932
    p = strchr(devname, '.');
933
    if (p) {
934
        *pbus_num = strtoul(devname, NULL, 0);
935

    
936
        if (*(p + 1) == '*') {
937
            usb_host_auto_add(*pbus_num, -1, -1, -1);
938
            return -1;
939
        }
940

    
941
        *paddr = strtoul(p + 1, NULL, 0);
942
        fs.bus_num = *pbus_num;
943
        fs.addr = *paddr;
944
        ret = usb_host_scan(&fs, usb_host_find_device_scan);
945
        if (ret)
946
            pstrcpy(product_name, product_name_size, fs.product_name);
947
        return 0;
948
    }
949
    p = strchr(devname, ':');
950
    if (p) {
951
        fs.vendor_id = strtoul(devname, NULL, 16);
952

    
953
        if (*(p + 1) == '*') {
954
            usb_host_auto_add(-1, -1, fs.vendor_id, -1);
955
            return -1;
956
        }
957

    
958
        fs.product_id = strtoul(p + 1, NULL, 16);
959
        ret = usb_host_scan(&fs, usb_host_find_device_scan);
960
        if (ret) {
961
            *pbus_num = fs.bus_num;
962
            *paddr = fs.addr;
963
            pstrcpy(product_name, product_name_size, fs.product_name);
964
            return 0;
965
        }
966
    }
967
    return -1;
968
}
969

    
970
/**********************/
971
/* USB host device info */
972

    
973
struct usb_class_info {
974
    int class;
975
    const char *class_name;
976
};
977

    
978
static const struct usb_class_info usb_class_info[] = {
979
    { USB_CLASS_AUDIO, "Audio"},
980
    { USB_CLASS_COMM, "Communication"},
981
    { USB_CLASS_HID, "HID"},
982
    { USB_CLASS_HUB, "Hub" },
983
    { USB_CLASS_PHYSICAL, "Physical" },
984
    { USB_CLASS_PRINTER, "Printer" },
985
    { USB_CLASS_MASS_STORAGE, "Storage" },
986
    { USB_CLASS_CDC_DATA, "Data" },
987
    { USB_CLASS_APP_SPEC, "Application Specific" },
988
    { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
989
    { USB_CLASS_STILL_IMAGE, "Still Image" },
990
    { USB_CLASS_CSCID, "Smart Card" },
991
    { USB_CLASS_CONTENT_SEC, "Content Security" },
992
    { -1, NULL }
993
};
994

    
995
static const char *usb_class_str(uint8_t class)
996
{
997
    const struct usb_class_info *p;
998
    for(p = usb_class_info; p->class != -1; p++) {
999
        if (p->class == class)
1000
            break;
1001
    }
1002
    return p->class_name;
1003
}
1004

    
1005
static void usb_info_device(int bus_num, int addr, int class_id,
1006
                            int vendor_id, int product_id,
1007
                            const char *product_name,
1008
                            int speed)
1009
{
1010
    const char *class_str, *speed_str;
1011

    
1012
    switch(speed) {
1013
    case USB_SPEED_LOW:
1014
        speed_str = "1.5";
1015
        break;
1016
    case USB_SPEED_FULL:
1017
        speed_str = "12";
1018
        break;
1019
    case USB_SPEED_HIGH:
1020
        speed_str = "480";
1021
        break;
1022
    default:
1023
        speed_str = "?";
1024
        break;
1025
    }
1026

    
1027
    term_printf("  Device %d.%d, speed %s Mb/s\n",
1028
                bus_num, addr, speed_str);
1029
    class_str = usb_class_str(class_id);
1030
    if (class_str)
1031
        term_printf("    %s:", class_str);
1032
    else
1033
        term_printf("    Class %02x:", class_id);
1034
    term_printf(" USB device %04x:%04x", vendor_id, product_id);
1035
    if (product_name[0] != '\0')
1036
        term_printf(", %s", product_name);
1037
    term_printf("\n");
1038
}
1039

    
1040
static int usb_host_info_device(void *opaque, int bus_num, int addr,
1041
                                int class_id,
1042
                                int vendor_id, int product_id,
1043
                                const char *product_name,
1044
                                int speed)
1045
{
1046
    usb_info_device(bus_num, addr, class_id, vendor_id, product_id,
1047
                    product_name, speed);
1048
    return 0;
1049
}
1050

    
1051
void usb_host_info(void)
1052
{
1053
    usb_host_scan(NULL, usb_host_info_device);
1054
}
1055

    
1056
#else
1057

    
1058
void usb_host_info(void)
1059
{
1060
    term_printf("USB host devices not supported\n");
1061
}
1062

    
1063
/* XXX: modify configure to compile the right host driver */
1064
USBDevice *usb_host_device_open(const char *devname)
1065
{
1066
    return NULL;
1067
}
1068

    
1069
#endif