summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2010-10-04 19:52:52 +0200
committerAlon Levy <alevy@redhat.com>2010-10-05 18:38:31 +0200
commitcd917ad066ad839037f6f098482cba331318fb9a (patch)
treef567e8978af416e97c9bf26c114f3665aec1ae28
parentbc4fe7915d349a86a311e732afe2e4cc24bf1c14 (diff)
monitor: add usb_detachspice.kvm.v18.usb-ccid.v6
-rw-r--r--qemu-monitor.hx17
-rw-r--r--sysemu.h1
-rw-r--r--vl.c41
3 files changed, 59 insertions, 0 deletions
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index ba4e1afd7..9373ce025 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -681,6 +681,23 @@ command @code{info usb} to see the devices you can remove.
ETEXI
{
+ .name = "usb_detach",
+ .args_type = "devname:s",
+ .params = "device",
+ .help = "remove 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 7542bf680..3003b430d 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -188,6 +188,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 6c1dd94ee..4cd21a943 100644
--- a/vl.c
+++ b/vl.c
@@ -899,6 +899,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 */