qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] monitor: add usb_detach


From: Alon Levy
Subject: [Qemu-devel] [PATCH] monitor: add usb_detach
Date: Tue, 5 Oct 2010 16:40:29 +0200

Signed-off-by: Alon Levy <address@hidden>

---
 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
address@hidden usb_detach @var{devname}
address@hidden 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 <address@hidden>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]