aboutsummaryrefslogtreecommitdiff
path: root/usb-linux.c
diff options
context:
space:
mode:
authorShahar Havivi <shaharh@redhat.com>2010-06-16 15:16:11 +0300
committerAurelien Jarno <aurelien@aurel32.net>2010-06-30 22:51:17 +0200
commitb373a63a2eb3a8354de2f75670484bd98966ccb4 (patch)
tree40e61b905c6fb197afe1b3302c2a0abb74edece3 /usb-linux.c
parent00ff227a328f02cdb0913c51bc46457c50351c79 (diff)
Return usb device to host on exit
Signed-off-by: Shahar Havivi <shaharh@redhat.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'usb-linux.c')
-rw-r--r--usb-linux.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/usb-linux.c b/usb-linux.c
index 22a85e3101..c3c38ec249 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -33,6 +33,7 @@
#include "qemu-common.h"
#include "qemu-timer.h"
#include "monitor.h"
+#include "sysemu.h"
#include <dirent.h>
#include <sys/ioctl.h>
@@ -132,6 +133,7 @@ typedef struct USBHostDevice {
int configuration;
int ninterfaces;
int closing;
+ Notifier exit;
struct ctrl_struct ctrl;
struct endp_data endp_table[MAX_ENDPOINTS];
@@ -404,6 +406,7 @@ static void usb_host_handle_destroy(USBDevice *dev)
usb_host_close(s);
QTAILQ_REMOVE(&hostdevs, s, next);
+ qemu_remove_exit_notifier(&s->exit);
}
static int usb_linux_update_endp_table(USBHostDevice *s);
@@ -997,6 +1000,15 @@ static int usb_host_close(USBHostDevice *dev)
return 0;
}
+static void usb_host_exit_notifier(struct Notifier* n)
+{
+ USBHostDevice *s = container_of(n, USBHostDevice, exit);
+
+ if (s->fd != -1) {
+ ioctl(s->fd, USBDEVFS_RESET);
+ }
+}
+
static int usb_host_initfn(USBDevice *dev)
{
USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
@@ -1004,6 +1016,8 @@ static int usb_host_initfn(USBDevice *dev)
dev->auto_attach = 0;
s->fd = -1;
QTAILQ_INSERT_TAIL(&hostdevs, s, next);
+ s->exit.notify = usb_host_exit_notifier;
+ qemu_add_exit_notifier(&s->exit);
usb_host_auto_check(NULL);
return 0;
}