Revision 26a9e82a

b/usb-linux.c
64 64
typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
65 65
                        int vendor_id, int product_id,
66 66
                        const char *product_name, int speed);
67
static int usb_host_find_device(int *pbus_num, int *paddr,
68
                                char *product_name, int product_name_size,
69
                                const char *devname);
70
//#define DEBUG
67

  
68
#define DEBUG
71 69

  
72 70
#ifdef DEBUG
73 71
#define dprintf printf
......
118 116
    uint8_t  buffer[2048];
119 117
};
120 118

  
119
struct USBAutoFilter {
120
    uint32_t bus_num;
121
    uint32_t addr;
122
    uint32_t vendor_id;
123
    uint32_t product_id;
124
};
125

  
121 126
typedef struct USBHostDevice {
122 127
    USBDevice dev;
123 128
    int       fd;
......
134 139
    /* Host side address */
135 140
    int bus_num;
136 141
    int addr;
142
    struct USBAutoFilter match;
137 143

  
138
    struct USBHostDevice *next;
144
    QTAILQ_ENTRY(USBHostDevice) next;
139 145
} USBHostDevice;
140 146

  
147
static QTAILQ_HEAD(, USBHostDevice) hostdevs = QTAILQ_HEAD_INITIALIZER(hostdevs);
148

  
149
static int usb_host_close(USBHostDevice *dev);
150
static int parse_filter(const char *spec, struct USBAutoFilter *f);
151
static void usb_host_auto_check(void *unused);
152

  
141 153
static int is_isoc(USBHostDevice *s, int ep)
142 154
{
143 155
    return s->endp_table[ep - 1].type == USBDEVFS_URB_TYPE_ISO;
......
158 170
    s->endp_table[ep - 1].halted = 1;
159 171
}
160 172

  
161
static USBHostDevice *hostdev_list;
162

  
163
static void hostdev_link(USBHostDevice *dev)
164
{
165
    dev->next = hostdev_list;
166
    hostdev_list = dev;
167
}
168

  
169
static void hostdev_unlink(USBHostDevice *dev)
170
{
171
    USBHostDevice *pdev = hostdev_list;
172
    USBHostDevice **prev = &hostdev_list;
173

  
174
    while (pdev) {
175
	if (pdev == dev) {
176
            *prev = dev->next;
177
            return;
178
        }
179

  
180
        prev = &pdev->next;
181
        pdev = pdev->next;
182
    }
183
}
184

  
185
static USBHostDevice *hostdev_find(int bus_num, int addr)
186
{
187
    USBHostDevice *s = hostdev_list;
188
    while (s) {
189
        if (s->bus_num == bus_num && s->addr == addr)
190
            return s;
191
        s = s->next;
192
    }
193
    return NULL;
194
}
195

  
196 173
/* 
197 174
 * Async URB state.
198 175
 * We always allocate one isoc descriptor even for bulk transfers
......
252 229

  
253 230
            if (errno == ENODEV && !s->closing) {
254 231
                printf("husb: device %d.%d disconnected\n", s->bus_num, s->addr);
255
	        usb_device_delete_addr(s->bus_num, s->dev.addr);
232
                usb_host_close(s);
233
                usb_host_auto_check(NULL);
256 234
                return;
257 235
            }
258 236

  
......
407 385

  
408 386
static void usb_host_handle_reset(USBDevice *dev)
409 387
{
410
    USBHostDevice *s = (USBHostDevice *) dev;
388
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
411 389

  
412 390
    dprintf("husb: reset device %u.%u\n", s->bus_num, s->addr);
413 391

  
......
420 398
{
421 399
    USBHostDevice *s = (USBHostDevice *)dev;
422 400

  
423
    s->closing = 1;
424

  
425
    qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
426

  
427
    hostdev_unlink(s);
428

  
429
    async_complete(s);
430

  
431
    if (s->fd >= 0)
432
        close(s->fd);
433

  
434
    qemu_free(s);
401
    usb_host_close(s);
402
    QTAILQ_REMOVE(&hostdevs, s, next);
435 403
}
436 404

  
437 405
static int usb_linux_update_endp_table(USBHostDevice *s);
......
891 859
    return 0;
892 860
}
893 861

  
894
static int usb_host_initfn(USBDevice *dev)
895
{
896
    return 0;
897
}
898

  
899
static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *prod_name)
862
static int usb_host_open(USBHostDevice *dev, int bus_num,
863
                         int addr, const char *prod_name)
900 864
{
901 865
    int fd = -1, ret;
902
    USBDevice *d = NULL;
903
    USBHostDevice *dev;
904 866
    struct usbdevfs_connectinfo ci;
905 867
    char buf[1024];
906 868

  
869
    if (dev->fd != -1)
870
        goto fail;
871

  
907 872
    printf("husb: open device %d.%d\n", bus_num, addr);
908 873

  
909 874
    if (!usb_host_device_path) {
......
919 884
    }
920 885
    dprintf("husb: opened %s\n", buf);
921 886

  
922
    d = usb_create(NULL /* FIXME */, "USB Host Device");
923
    dev = DO_UPCAST(USBHostDevice, dev, d);
924

  
925 887
    dev->bus_num = bus_num;
926 888
    dev->addr = addr;
927 889
    dev->fd = fd;
......
980 942
    /* USB devio uses 'write' flag to check for async completions */
981 943
    qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);
982 944

  
983
    hostdev_link(dev);
984

  
985
    if (qdev_init(&d->qdev) < 0)
986
        goto fail_no_qdev;
987
    return (USBDevice *) dev;
945
    usb_device_attach(&dev->dev);
946
    return 0;
988 947

  
989 948
fail:
990
    if (d)
991
        qdev_free(&d->qdev);
992
fail_no_qdev:
949
    dev->fd = -1;
993 950
    if (fd != -1)
994 951
        close(fd);
995
    return NULL;
952
    return -1;
953
}
954

  
955
static int usb_host_close(USBHostDevice *dev)
956
{
957
    if (dev->fd == -1)
958
        return -1;
959

  
960
    qemu_set_fd_handler(dev->fd, NULL, NULL, NULL);
961
    dev->closing = 1;
962
    async_complete(dev);
963
    dev->closing = 0;
964
    usb_device_detach(&dev->dev);
965
    close(dev->fd);
966
    dev->fd = -1;
967
    return 0;
968
}
969

  
970
static int usb_host_initfn(USBDevice *dev)
971
{
972
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
973

  
974
    dev->auto_attach = 0;
975
    s->fd = -1;
976
    QTAILQ_INSERT_TAIL(&hostdevs, s, next);
977
    usb_host_auto_check(NULL);
978
    return 0;
996 979
}
997 980

  
998 981
static struct USBDeviceInfo usb_host_dev_info = {
999 982
    .qdev.name      = "USB Host Device",
983
    .qdev.alias     = "usb-host",
1000 984
    .qdev.size      = sizeof(USBHostDevice),
1001 985
    .init           = usb_host_initfn,
1002 986
    .handle_packet  = usb_host_handle_packet,
1003 987
    .handle_reset   = usb_host_handle_reset,
1004
#if 0
1005
    .handle_control = usb_host_handle_control,
1006
    .handle_data    = usb_host_handle_data,
1007
#endif
1008 988
    .handle_destroy = usb_host_handle_destroy,
989
    .usbdevice_name = "host",
990
    .usbdevice_init = usb_host_device_open,
991
    .qdev.props     = (Property[]) {
992
        DEFINE_PROP_UINT32("hostbus",  USBHostDevice, match.bus_num,    0),
993
        DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr,       0),
994
        DEFINE_PROP_HEX32("vendorid",  USBHostDevice, match.vendor_id,  0),
995
        DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
996
        DEFINE_PROP_END_OF_LIST(),
997
    },
1009 998
};
1010 999

  
1011 1000
static void usb_host_register_devices(void)
......
1014 1003
}
1015 1004
device_init(usb_host_register_devices)
1016 1005

  
1017
static int usb_host_auto_add(const char *spec);
1018
static int usb_host_auto_del(const char *spec);
1019

  
1020 1006
USBDevice *usb_host_device_open(const char *devname)
1021 1007
{
1022
    Monitor *mon = cur_mon;
1023
    int bus_num, addr;
1024
    char product_name[PRODUCT_NAME_SZ];
1008
    struct USBAutoFilter filter = { 0, 0, 0, 0 };
1009
    USBDevice *dev;
1010
    USBHostDevice *s;
1011
    char *p;
1012

  
1013
    dev = usb_create(NULL /* FIXME */, "USB Host Device");
1014
    s = DO_UPCAST(USBHostDevice, dev, dev);
1025 1015

  
1026 1016
    if (strstr(devname, "auto:")) {
1027
        usb_host_auto_add(devname);
1028
        return NULL;
1017
        if (parse_filter(devname+5, &filter) < 0)
1018
            goto fail;
1019
    } else {
1020
        if ((p = strchr(devname, '.'))) {
1021
            filter.bus_num = strtoul(devname, NULL, 0);
1022
            filter.addr    = strtoul(devname, NULL, 0);
1023
        } else if ((p = strchr(devname, ':'))) {
1024
            filter.vendor_id  = strtoul(devname, NULL, 16);
1025
            filter.product_id = strtoul(devname, NULL, 16);
1026
        } else {
1027
            goto fail;
1028
        }
1029 1029
    }
1030 1030

  
1031
    if (usb_host_find_device(&bus_num, &addr, product_name, sizeof(product_name),
1032
                             devname) < 0)
1033
        return NULL;
1031
    qdev_prop_set_uint32(&dev->qdev, "bus",       filter.bus_num);
1032
    qdev_prop_set_uint32(&dev->qdev, "addr",      filter.addr);
1033
    qdev_prop_set_uint32(&dev->qdev, "vendorid",  filter.vendor_id);
1034
    qdev_prop_set_uint32(&dev->qdev, "productid", filter.product_id);
1035
    qdev_init(&dev->qdev);
1036
    return dev;
1034 1037

  
1035
    if (hostdev_find(bus_num, addr)) {
1036
       monitor_printf(mon, "husb: host usb device %d.%d is already open\n",
1037
                      bus_num, addr);
1038
       return NULL;
1039
    }
1040

  
1041
    return usb_host_device_open_addr(bus_num, addr, product_name);
1038
fail:
1039
    qdev_free(&dev->qdev);
1040
    return NULL;
1042 1041
}
1043 1042

  
1044 1043
int usb_host_device_close(const char *devname)
1045 1044
{
1045
#if 0
1046 1046
    char product_name[PRODUCT_NAME_SZ];
1047 1047
    int bus_num, addr;
1048 1048
    USBHostDevice *s;
......
1059 1059
        usb_device_delete_addr(s->bus_num, s->dev.addr);
1060 1060
        return 0;
1061 1061
    }
1062
#endif
1062 1063

  
1063 1064
    return -1;
1064 1065
}
......
1185 1186
 */
1186 1187
static int usb_host_read_file(char *line, size_t line_size, const char *device_file, const char *device_name)
1187 1188
{
1189
#if 0
1188 1190
    Monitor *mon = cur_mon;
1191
#endif
1189 1192
    FILE *f;
1190 1193
    int ret = 0;
1191 1194
    char filename[PATH_MAX];
......
1197 1200
        fgets(line, line_size, f);
1198 1201
        fclose(f);
1199 1202
        ret = 1;
1203
#if 0
1200 1204
    } else {
1201 1205
        monitor_printf(mon, "husb: could not open %s\n", filename);
1206
#endif
1202 1207
    }
1203 1208

  
1204 1209
    return ret;
......
1356 1361
    return ret;
1357 1362
}
1358 1363

  
1359
struct USBAutoFilter {
1360
    struct USBAutoFilter *next;
1361
    int bus_num;
1362
    int addr;
1363
    int vendor_id;
1364
    int product_id;
1365
};
1366

  
1367 1364
static QEMUTimer *usb_auto_timer;
1368
static struct USBAutoFilter *usb_auto_filter;
1369 1365

  
1370 1366
static int usb_host_auto_scan(void *opaque, int bus_num, int addr,
1371
                     int class_id, int vendor_id, int product_id,
1372
                     const char *product_name, int speed)
1367
                              int class_id, int vendor_id, int product_id,
1368
                              const char *product_name, int speed)
1373 1369
{
1374 1370
    struct USBAutoFilter *f;
1375
    struct USBDevice *dev;
1371
    struct USBHostDevice *s;
1376 1372

  
1377 1373
    /* Ignore hubs */
1378 1374
    if (class_id == 9)
1379 1375
        return 0;
1380 1376

  
1381
    for (f = usb_auto_filter; f; f = f->next) {
1382
	if (f->bus_num >= 0 && f->bus_num != bus_num)
1377
    QTAILQ_FOREACH(s, &hostdevs, next) {
1378
        f = &s->match;
1379

  
1380
	if (f->bus_num > 0 && f->bus_num != bus_num)
1383 1381
            continue;
1384 1382

  
1385
	if (f->addr >= 0 && f->addr != addr)
1383
	if (f->addr > 0 && f->addr != addr)
1386 1384
            continue;
1387 1385

  
1388
	if (f->vendor_id >= 0 && f->vendor_id != vendor_id)
1386
	if (f->vendor_id > 0 && f->vendor_id != vendor_id)
1389 1387
            continue;
1390 1388

  
1391
	if (f->product_id >= 0 && f->product_id != product_id)
1389
	if (f->product_id > 0 && f->product_id != product_id)
1392 1390
            continue;
1393 1391

  
1394 1392
        /* We got a match */
1395 1393

  
1396 1394
        /* Already attached ? */
1397
        if (hostdev_find(bus_num, addr))
1395
        if (s->fd != -1)
1398 1396
            return 0;
1399 1397

  
1400 1398
        dprintf("husb: auto open: bus_num %d addr %d\n", bus_num, addr);
1401 1399

  
1402
	dev = usb_host_device_open_addr(bus_num, addr, product_name);
1400
	usb_host_open(s, bus_num, addr, product_name);
1403 1401
    }
1404 1402

  
1405 1403
    return 0;
1406 1404
}
1407 1405

  
1408
static void usb_host_auto_timer(void *unused)
1406
static void usb_host_auto_check(void *unused)
1409 1407
{
1408
    struct USBHostDevice *s;
1409
    int unconnected = 0;
1410

  
1410 1411
    usb_host_scan(NULL, usb_host_auto_scan);
1412

  
1413
    QTAILQ_FOREACH(s, &hostdevs, next) {
1414
        if (s->fd == -1)
1415
            unconnected++;
1416
    }
1417

  
1418
    if (unconnected == 0) {
1419
        /* nothing to watch */
1420
        if (usb_auto_timer)
1421
            qemu_del_timer(usb_auto_timer);
1422
        return;
1423
    }
1424

  
1425
    if (!usb_auto_timer) {
1426
        usb_auto_timer = qemu_new_timer(rt_clock, usb_host_auto_check, NULL);
1427
        if (!usb_auto_timer)
1428
            return;
1429
    }
1411 1430
    qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);
1412 1431
}
1413 1432

  
......
1459 1478
    return 0;
1460 1479
}
1461 1480

  
1462
static int match_filter(const struct USBAutoFilter *f1, 
1463
                        const struct USBAutoFilter *f2)
1464
{
1465
    return f1->bus_num    == f2->bus_num &&
1466
           f1->addr       == f2->addr &&
1467
           f1->vendor_id  == f2->vendor_id &&
1468
           f1->product_id == f2->product_id;
1469
}
1470

  
1471
static int usb_host_auto_add(const char *spec)
1472
{
1473
    struct USBAutoFilter filter, *f;
1474

  
1475
    if (parse_filter(spec, &filter) < 0)
1476
        return -1;
1477

  
1478
    f = qemu_mallocz(sizeof(*f));
1479

  
1480
    *f = filter; 
1481

  
1482
    if (!usb_auto_filter) {
1483
        /*
1484
         * First entry. Init and start the monitor.
1485
         * Right now we're using timer to check for new devices.
1486
         * If this turns out to be too expensive we can move that into a 
1487
         * separate thread.
1488
         */
1489
	usb_auto_timer = qemu_new_timer(rt_clock, usb_host_auto_timer, NULL);
1490
	if (!usb_auto_timer) {
1491
            fprintf(stderr, "husb: failed to allocate auto scan timer\n");
1492
            qemu_free(f);
1493
            return -1;
1494
        }
1495

  
1496
        /* Check for new devices every two seconds */
1497
        qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);
1498
    }
1499

  
1500
    dprintf("husb: added auto filter: bus_num %d addr %d vid %d pid %d\n",
1501
	f->bus_num, f->addr, f->vendor_id, f->product_id);
1502

  
1503
    f->next = usb_auto_filter;
1504
    usb_auto_filter = f;
1505

  
1506
    return 0;
1507
}
1508

  
1509
static int usb_host_auto_del(const char *spec)
1510
{
1511
    struct USBAutoFilter *pf = usb_auto_filter;
1512
    struct USBAutoFilter **prev = &usb_auto_filter;
1513
    struct USBAutoFilter filter;
1514

  
1515
    if (parse_filter(spec, &filter) < 0)
1516
        return -1;
1517

  
1518
    while (pf) {
1519
        if (match_filter(pf, &filter)) {
1520
            dprintf("husb: removed auto filter: bus_num %d addr %d vid %d pid %d\n",
1521
	             pf->bus_num, pf->addr, pf->vendor_id, pf->product_id);
1522

  
1523
            *prev = pf->next;
1524

  
1525
	    if (!usb_auto_filter) {
1526
                /* No more filters. Stop scanning. */
1527
                qemu_del_timer(usb_auto_timer);
1528
                qemu_free_timer(usb_auto_timer);
1529
            }
1530

  
1531
            return 0;
1532
        }
1533

  
1534
        prev = &pf->next;
1535
        pf   = pf->next;
1536
    }
1537

  
1538
    return -1;
1539
}
1540

  
1541
typedef struct FindDeviceState {
1542
    int vendor_id;
1543
    int product_id;
1544
    int bus_num;
1545
    int addr;
1546
    char product_name[PRODUCT_NAME_SZ];
1547
} FindDeviceState;
1548

  
1549
static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
1550
                                     int class_id,
1551
                                     int vendor_id, int product_id,
1552
                                     const char *product_name, int speed)
1553
{
1554
    FindDeviceState *s = opaque;
1555
    if ((vendor_id == s->vendor_id &&
1556
        product_id == s->product_id) ||
1557
        (bus_num == s->bus_num &&
1558
        addr == s->addr)) {
1559
        pstrcpy(s->product_name, PRODUCT_NAME_SZ, product_name);
1560
        s->bus_num = bus_num;
1561
        s->addr = addr;
1562
        return 1;
1563
    } else {
1564
        return 0;
1565
    }
1566
}
1567

  
1568
/* the syntax is :
1569
   'bus.addr' (decimal numbers) or
1570
   'vendor_id:product_id' (hexa numbers) */
1571
static int usb_host_find_device(int *pbus_num, int *paddr,
1572
                                char *product_name, int product_name_size,
1573
                                const char *devname)
1574
{
1575
    const char *p;
1576
    int ret;
1577
    FindDeviceState fs;
1578

  
1579
    p = strchr(devname, '.');
1580
    if (p) {
1581
        *pbus_num = strtoul(devname, NULL, 0);
1582
        *paddr = strtoul(p + 1, NULL, 0);
1583
        fs.bus_num = *pbus_num;
1584
        fs.addr = *paddr;
1585
        ret = usb_host_scan(&fs, usb_host_find_device_scan);
1586
        if (ret)
1587
            pstrcpy(product_name, product_name_size, fs.product_name);
1588
        return 0;
1589
    }
1590

  
1591
    p = strchr(devname, ':');
1592
    if (p) {
1593
        fs.vendor_id = strtoul(devname, NULL, 16);
1594
        fs.product_id = strtoul(p + 1, NULL, 16);
1595
        ret = usb_host_scan(&fs, usb_host_find_device_scan);
1596
        if (ret) {
1597
            *pbus_num = fs.bus_num;
1598
            *paddr = fs.addr;
1599
            pstrcpy(product_name, product_name_size, fs.product_name);
1600
            return 0;
1601
        }
1602
    }
1603
    return -1;
1604
}
1605

  
1606 1481
/**********************/
1607 1482
/* USB host device info */
1608 1483

  
......
1688 1563

  
1689 1564
static void dec2str(int val, char *str, size_t size)
1690 1565
{
1691
    if (val == -1)
1566
    if (val == 0)
1692 1567
        snprintf(str, size, "*");
1693 1568
    else
1694 1569
        snprintf(str, size, "%d", val); 
......
1696 1571

  
1697 1572
static void hex2str(int val, char *str, size_t size)
1698 1573
{
1699
    if (val == -1)
1574
    if (val == 0)
1700 1575
        snprintf(str, size, "*");
1701 1576
    else
1702
        snprintf(str, size, "%x", val);
1577
        snprintf(str, size, "%04x", val);
1703 1578
}
1704 1579

  
1705 1580
void usb_host_info(Monitor *mon)
1706 1581
{
1707 1582
    struct USBAutoFilter *f;
1583
    struct USBHostDevice *s;
1708 1584

  
1709 1585
    usb_host_scan(mon, usb_host_info_device);
1710 1586

  
1711
    if (usb_auto_filter)
1712
        monitor_printf(mon, "  Auto filters:\n");
1713
    for (f = usb_auto_filter; f; f = f->next) {
1587
    if (QTAILQ_EMPTY(&hostdevs))
1588
        return;
1589
    monitor_printf(mon, "  Auto filters:\n");
1590
    QTAILQ_FOREACH(s, &hostdevs, next) {
1714 1591
        char bus[10], addr[10], vid[10], pid[10];
1592
        f = &s->match;
1715 1593
        dec2str(f->bus_num, bus, sizeof(bus));
1716 1594
        dec2str(f->addr, addr, sizeof(addr));
1717 1595
        hex2str(f->vendor_id, vid, sizeof(vid));

Also available in: Unified diff