Signed-off-by: Alon Levy <al...@redhat.com> --- qemu-monitor.hx | 17 +++++++++++++++++ sysemu.h | 1 + vl.c | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 0 deletions(-)
diff --git a/qemu-monitor.hx b/qemu-monitor.hx index 49bcd8d..9c792a9 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -711,6 +711,23 @@ command @code{info usb} to see the devices you can remove. ETEXI { + .name = "usb_detach", + .args_type = "devname:s", + .params = "device", + .help = "detach USB device 'bus.addr'", + .mhandler.cmd = do_usb_detach, + }, + +STEXI +...@item usb_detach @var{devname} +...@findex usb_detach + +Detach the USB device @var{devname} from the QEMU virtual USB +hub. @var{devname} has the syntax @code{bus.addr}. Use the monitor +command @code{info usb} to see the devices you can detach. +ETEXI + + { .name = "device_add", .args_type = "device:O", .params = "driver[,prop=value][,...]", diff --git a/sysemu.h b/sysemu.h index a1f6466..ac68863 100644 --- a/sysemu.h +++ b/sysemu.h @@ -183,6 +183,7 @@ extern struct soundhw soundhw[]; void do_usb_add(Monitor *mon, const QDict *qdict); void do_usb_del(Monitor *mon, const QDict *qdict); +void do_usb_detach(Monitor *mon, const QDict *qdict); void usb_info(Monitor *mon); void rtc_change_mon_event(struct tm *tm); diff --git a/vl.c b/vl.c index d352d18..6cfa009 100644 --- a/vl.c +++ b/vl.c @@ -891,6 +891,47 @@ void do_usb_del(Monitor *mon, const QDict *qdict) } } +static USBDevice *usb_device_from_bus_dot_addr(const char *devname) +{ + int bus_num, addr; + const char *p; + USBBus *bus; + USBPort *port; + + if (!usb_enabled) { + return NULL; + } + p = strchr(devname, '.'); + if (!p) { + return NULL; + } + bus_num = strtoul(devname, NULL, 0); + addr = strtoul(p + 1, NULL, 0); + bus = usb_bus_find(bus_num); + if (!bus) { + return NULL; + } + QTAILQ_FOREACH(port, &bus->used, next) { + if (port->dev->addr == addr) { + break; + } + } + if (!port) { + return NULL; + } + return port->dev; +} + +void do_usb_detach(Monitor *mon, const QDict *qdict) +{ + const char *devname = qdict_get_str(qdict, "devname"); + USBDevice *dev = usb_device_from_bus_dot_addr(devname); + + if (dev == NULL || usb_device_detach(dev) < 0) { + error_report("could not detach USB device '%s'", devname); + } +} + /***********************************************************/ /* PCMCIA/Cardbus */ -- 1.7.3.1 -- Alon Levy <al...@redhat.com>