Revision 4b096fc9

b/hw/usb.h
197 197
    p->cancel_cb(p, p->cancel_opaque);
198 198
}
199 199

  
200
int usb_device_add_dev(USBDevice *dev);
200 201
int usb_device_del_addr(int bus_num, int addr);
201 202
void usb_attach(USBPort *port, USBDevice *dev);
202 203
int usb_generic_handle_packet(USBDevice *s, USBPacket *p);
b/usb-linux.c
3 3
 *
4 4
 * Copyright (c) 2005 Fabrice Bellard
5 5
 *
6
 * Support for host device auto connect & disconnect
7
 *       Copyright (c) 2008 Max Krasnyansky
8
 *
6 9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 10
 * of this software and associated documentation files (the "Software"), to deal
8 11
 * in the Software without restriction, including without limitation the rights
......
67 70
    uint8_t type;
68 71
};
69 72

  
73

  
74

  
70 75
/* FIXME: move USBPacket to PendingURB */
71 76
typedef struct USBHostDevice {
72 77
    USBDevice dev;
......
78 83
    uint8_t descr[1024];
79 84
    int descr_len;
80 85
    int urbs_ready;
86

  
81 87
    QEMUTimer *timer;
88

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

  
93
    struct USBHostDevice *next;
82 94
} USBHostDevice;
83 95

  
96
static USBHostDevice *hostdev_list;
97

  
98
static void hostdev_link(USBHostDevice *dev)
99
{
100
    dev->next = hostdev_list;
101
    hostdev_list = dev;
102
}
103

  
104
static void hostdev_unlink(USBHostDevice *dev)
105
{
106
    USBHostDevice *pdev = hostdev_list;
107
    USBHostDevice **prev = &hostdev_list;
108

  
109
    while (pdev) {
110
	if (pdev == dev) {
111
            *prev = dev->next;
112
            return;
113
        }
114

  
115
        prev = &pdev->next;
116
        pdev = pdev->next;
117
    }
118
}
119

  
120
static USBHostDevice *hostdev_find(int bus_num, int addr)
121
{
122
    USBHostDevice *s = hostdev_list;
123
    while (s) {
124
        if (s->bus_num == bus_num && s->addr == addr)
125
            return s;
126
        s = s->next;
127
    }
128
    return NULL;
129
}
130

  
84 131
typedef struct PendingURB {
85 132
    struct usbdevfs_urb *urb;
86 133
    int status;
......
238 285

  
239 286
    qemu_del_timer(s->timer);
240 287

  
288
    hostdev_unlink(s);
289

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

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

  
622
/* XXX: exclude high speed devices or implement EHCI */
623
USBDevice *usb_host_device_open(const char *devname)
671
static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *prod_name)
624 672
{
625 673
    int fd = -1, ret;
626 674
    USBHostDevice *dev = NULL;
627 675
    struct usbdevfs_connectinfo ci;
628 676
    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 677

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

  
682
    dev->bus_num = bus_num;
683
    dev->addr = addr;
684

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

  
646 689
#ifdef DEBUG
647
    printf("usb_host_device_open %s\n", devname);
690
    printf("usb_host_device_open %d.%d\n", bus_num, addr);
648 691
#endif
649 692

  
650 693
    snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
......
704 747
    dev->dev.handle_data = usb_host_handle_data;
705 748
    dev->dev.handle_destroy = usb_host_handle_destroy;
706 749

  
707
    if (product_name[0] == '\0')
750
    if (!prod_name || prod_name[0] == '\0')
708 751
        snprintf(dev->dev.devname, sizeof(dev->dev.devname),
709
                 "host:%s", devname);
752
                 "host:%d.%d", bus_num, addr);
710 753
    else
711 754
        pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
712
                product_name);
755
                prod_name);
713 756

  
714 757
#ifdef USE_ASYNCIO
715 758
    /* set up the signal handlers */
......
735 778
    /* Start the timer to detect disconnect */
736 779
    qemu_mod_timer(dev->timer, qemu_get_clock(rt_clock) + 1000);
737 780

  
781
    hostdev_link(dev);
782

  
738 783
    dev->urbs_ready = 0;
739 784
    return (USBDevice *)dev;
785

  
740 786
fail:
741 787
    if (dev) {
742 788
	if (dev->timer)
......
747 793
    return NULL;
748 794
}
749 795

  
796
USBDevice *usb_host_device_open(const char *devname)
797
{
798
    int bus_num, addr;
799
    char product_name[PRODUCT_NAME_SZ];
800

  
801
    if (usb_host_find_device(&bus_num, &addr,
802
                             product_name, sizeof(product_name),
803
                             devname) < 0)
804
        return NULL;
805

  
806
     if (hostdev_find(bus_num, addr)) {
807
        printf("host usb device %d.%d is already open\n", bus_num, addr);
808
        return NULL;
809
     }
810

  
811
    return usb_host_device_open_addr(bus_num, addr, product_name);
812
}
813
 
750 814
static int get_tag_value(char *buf, int buf_size,
751 815
                         const char *str, const char *tag,
752 816
                         const char *stopchars)
......
846 910
    return ret;
847 911
}
848 912

  
913
struct USBAutoFilter {
914
    struct USBAutoFilter *next;
915
    int bus_num;
916
    int addr;
917
    int vendor_id;
918
    int product_id;
919
};
920

  
921
static QEMUTimer *usb_auto_timer;
922
static struct USBAutoFilter *usb_auto_filter;
923

  
924
static int usb_host_auto_scan(void *opaque, int bus_num, int addr,
925
                     int class_id, int vendor_id, int product_id,
926
                     const char *product_name, int speed)
927
{
928
    struct USBAutoFilter *f;
929
    struct USBDevice *dev;
930

  
931
    /* Ignore hubs */
932
    if (class_id == 9)
933
        return 0;
934

  
935
    for (f = usb_auto_filter; f; f = f->next) {
936
        // printf("Auto match: bus_num %d addr %d vid %d pid %d\n",
937
	//    bus_num, addr, vendor_id, product_id);
938

  
939
	if (f->bus_num >= 0 && f->bus_num != bus_num)
940
            continue;
941

  
942
	if (f->addr >= 0 && f->addr != addr)
943
            continue;
944

  
945
	if (f->vendor_id >= 0 && f->vendor_id != vendor_id)
946
            continue;
947

  
948
	if (f->product_id >= 0 && f->product_id != product_id)
949
            continue;
950

  
951
        /* We got a match */
952

  
953
        /* Allredy attached ? */
954
        if (hostdev_find(bus_num, addr))
955
            return 0;
956

  
957
        printf("Auto open: bus_num %d addr %d\n", bus_num, addr);
958

  
959
	dev = usb_host_device_open_addr(bus_num, addr, product_name);
960
	if (dev)
961
	    usb_device_add_dev(dev);
962
    }
963

  
964
    return 0;
965
}
966

  
967
static void usb_host_auto_timer(void *unused)
968
{
969
    usb_host_scan(NULL, usb_host_auto_scan);
970
    qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);
971
}
972

  
973
/*
974
 * Add autoconnect filter
975
 * -1 means 'any' (device, vendor, etc)
976
 */
977
static void usb_host_auto_add(int bus_num, int addr, int vendor_id, int product_id)
978
{
979
    struct USBAutoFilter *f = qemu_mallocz(sizeof(*f));
980
    if (!f) {
981
        printf("Failed to allocate auto filter\n");
982
	return;
983
    }
984

  
985
    f->bus_num = bus_num;
986
    f->addr    = addr;
987
    f->vendor_id  = vendor_id;
988
    f->product_id = product_id;
989

  
990
    if (!usb_auto_filter) {
991
        /*
992
         * First entry. Init and start the monitor.
993
         * Right now we're using timer to check for new devices.
994
         * If this turns out to be too expensive we can move that into a 
995
         * separate thread.
996
         */
997
	usb_auto_timer = qemu_new_timer(rt_clock, usb_host_auto_timer, NULL);
998
	if (!usb_auto_timer) {
999
            printf("Failed to allocate timer\n");
1000
            qemu_free(f);
1001
            return;
1002
        }
1003

  
1004
        /* Check for new devices every two seconds */
1005
        qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);
1006
    }
1007

  
1008
    printf("Auto filter: bus_num %d addr %d vid %d pid %d\n",
1009
	bus_num, addr, vendor_id, product_id);
1010

  
1011
    f->next = usb_auto_filter;
1012
    usb_auto_filter = f;
1013
}
1014

  
849 1015
typedef struct FindDeviceState {
850 1016
    int vendor_id;
851 1017
    int product_id;
......
887 1053
    p = strchr(devname, '.');
888 1054
    if (p) {
889 1055
        *pbus_num = strtoul(devname, NULL, 0);
1056

  
1057
        if (*(p + 1) == '*') {
1058
            usb_host_auto_add(*pbus_num, -1, -1, -1);
1059
	    return -1;
1060
	}
1061

  
890 1062
        *paddr = strtoul(p + 1, NULL, 0);
891 1063
        fs.bus_num = *pbus_num;
892 1064
        fs.addr = *paddr;
......
898 1070
    p = strchr(devname, ':');
899 1071
    if (p) {
900 1072
        fs.vendor_id = strtoul(devname, NULL, 16);
1073

  
1074
        if (*(p + 1) == '*') {
1075
            usb_host_auto_add(-1, -1, fs.vendor_id, -1);
1076
	    return -1;
1077
	}
1078

  
901 1079
        fs.product_id = strtoul(p + 1, NULL, 16);
902 1080
        ret = usb_host_scan(&fs, usb_host_find_device_scan);
903 1081
        if (ret) {
......
996 1174
    usb_host_scan(NULL, usb_host_info_device);
997 1175
}
998 1176

  
1177

  
1178

  
1179

  
999 1180
#else
1000 1181

  
1001 1182
void usb_host_info(void)
b/vl.c
5747 5747
    free_usb_ports = port;
5748 5748
}
5749 5749

  
5750
int usb_device_add_dev(USBDevice *dev)
5751
{
5752
    USBPort *port;
5753

  
5754
    /* Find a USB port to add the device to.  */
5755
    port = free_usb_ports;
5756
    if (!port->next) {
5757
        USBDevice *hub;
5758

  
5759
        /* Create a new hub and chain it on.  */
5760
        free_usb_ports = NULL;
5761
        port->next = used_usb_ports;
5762
        used_usb_ports = port;
5763

  
5764
        hub = usb_hub_init(VM_USB_HUB_SIZE);
5765
        usb_attach(port, hub);
5766
        port = free_usb_ports;
5767
    }
5768

  
5769
    free_usb_ports = port->next;
5770
    port->next = used_usb_ports;
5771
    used_usb_ports = port;
5772
    usb_attach(port, dev);
5773
    return 0;
5774
}
5775

  
5750 5776
static int usb_device_add(const char *devname)
5751 5777
{
5752 5778
    const char *p;
......
5787 5813
    if (!dev)
5788 5814
        return -1;
5789 5815

  
5790
    /* Find a USB port to add the device to.  */
5791
    port = free_usb_ports;
5792
    if (!port->next) {
5793
        USBDevice *hub;
5794

  
5795
        /* Create a new hub and chain it on.  */
5796
        free_usb_ports = NULL;
5797
        port->next = used_usb_ports;
5798
        used_usb_ports = port;
5799

  
5800
        hub = usb_hub_init(VM_USB_HUB_SIZE);
5801
        usb_attach(port, hub);
5802
        port = free_usb_ports;
5803
    }
5804

  
5805
    free_usb_ports = port->next;
5806
    port->next = used_usb_ports;
5807
    used_usb_ports = port;
5808
    usb_attach(port, dev);
5809
    return 0;
5816
    return usb_device_add_dev(dev);
5810 5817
}
5811 5818

  
5812 5819
int usb_device_del_addr(int bus_num, int addr)
......
5859 5866

  
5860 5867
void do_usb_add(const char *devname)
5861 5868
{
5862
    int ret;
5863
    ret = usb_device_add(devname);
5864
    if (ret < 0)
5865
        term_printf("Could not add USB device '%s'\n", devname);
5869
    usb_device_add(devname);
5866 5870
}
5867 5871

  
5868 5872
void do_usb_del(const char *devname)
5869 5873
{
5870
    int ret;
5871
    ret = usb_device_del(devname);
5872
    if (ret < 0)
5873
        term_printf("Could not remove USB device '%s'\n", devname);
5874
    usb_device_del(devname);
5874 5875
}
5875 5876

  
5876 5877
void usb_info(void)

Also available in: Unified diff