mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 15:23:53 -06:00
husb: support for USB host device auto connect (Max Krasnyansky)
QEMU can now automatically grab host USB devices that match the filter. For now I just extended 'host:X.Y' and 'host:VID:PID' syntax to handle wildcards. So for example if you do something like usb_add host:5.* QEMU will automatically grab any non-hub device with host address 5.*. Same with the 'host:PID:*', we grab any device that matches PID. Filtering itself is very generic so we can probably add more elaborate syntax like 'host:BUS.ADDR:VID:PID'. So that we can do 'host:5.*:6000:*'. Anyway, it's implemented using a periodic timer that scans host devices and grabs those that match the filter. Timer is started when the first filter is added. We now keep the list of all host devices that we grabbed to make sure that we do not grab the same device twice. btw It's currently possible to grab the same host device more than once. ie You can just do "usb_add host:1.1" more than once, which of course does not work. So this patch fixes that issue too. Along with auto disconnect patch that I send a minute ago the setup is very seamless now. You can just allocate some usb ports to the VMs and plug/unplug devices at any time. Signed-off-by: Max Krasnyansky <maxk@kernel.org> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5048 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
1f3870ab24
commit
4b096fc9ec
3 changed files with 225 additions and 42 deletions
57
vl.c
57
vl.c
|
@ -5747,6 +5747,32 @@ void qemu_register_usb_port(USBPort *port, void *opaque, int index,
|
|||
free_usb_ports = port;
|
||||
}
|
||||
|
||||
int usb_device_add_dev(USBDevice *dev)
|
||||
{
|
||||
USBPort *port;
|
||||
|
||||
/* Find a USB port to add the device to. */
|
||||
port = free_usb_ports;
|
||||
if (!port->next) {
|
||||
USBDevice *hub;
|
||||
|
||||
/* Create a new hub and chain it on. */
|
||||
free_usb_ports = NULL;
|
||||
port->next = used_usb_ports;
|
||||
used_usb_ports = port;
|
||||
|
||||
hub = usb_hub_init(VM_USB_HUB_SIZE);
|
||||
usb_attach(port, hub);
|
||||
port = free_usb_ports;
|
||||
}
|
||||
|
||||
free_usb_ports = port->next;
|
||||
port->next = used_usb_ports;
|
||||
used_usb_ports = port;
|
||||
usb_attach(port, dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usb_device_add(const char *devname)
|
||||
{
|
||||
const char *p;
|
||||
|
@ -5787,26 +5813,7 @@ static int usb_device_add(const char *devname)
|
|||
if (!dev)
|
||||
return -1;
|
||||
|
||||
/* Find a USB port to add the device to. */
|
||||
port = free_usb_ports;
|
||||
if (!port->next) {
|
||||
USBDevice *hub;
|
||||
|
||||
/* Create a new hub and chain it on. */
|
||||
free_usb_ports = NULL;
|
||||
port->next = used_usb_ports;
|
||||
used_usb_ports = port;
|
||||
|
||||
hub = usb_hub_init(VM_USB_HUB_SIZE);
|
||||
usb_attach(port, hub);
|
||||
port = free_usb_ports;
|
||||
}
|
||||
|
||||
free_usb_ports = port->next;
|
||||
port->next = used_usb_ports;
|
||||
used_usb_ports = port;
|
||||
usb_attach(port, dev);
|
||||
return 0;
|
||||
return usb_device_add_dev(dev);
|
||||
}
|
||||
|
||||
int usb_device_del_addr(int bus_num, int addr)
|
||||
|
@ -5859,18 +5866,12 @@ static int usb_device_del(const char *devname)
|
|||
|
||||
void do_usb_add(const char *devname)
|
||||
{
|
||||
int ret;
|
||||
ret = usb_device_add(devname);
|
||||
if (ret < 0)
|
||||
term_printf("Could not add USB device '%s'\n", devname);
|
||||
usb_device_add(devname);
|
||||
}
|
||||
|
||||
void do_usb_del(const char *devname)
|
||||
{
|
||||
int ret;
|
||||
ret = usb_device_del(devname);
|
||||
if (ret < 0)
|
||||
term_printf("Could not remove USB device '%s'\n", devname);
|
||||
usb_device_del(devname);
|
||||
}
|
||||
|
||||
void usb_info(void)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue