dcavalca / rpms / qemu

Forked from rpms/qemu a year ago
Clone

Blame 0017-usb-host-properly-release-port-on-unplug-exit.patch

Justin M. Forbes 45e84a
From c936f649d4a6b87cabe809170874f6b560cc0524 Mon Sep 17 00:00:00 2001
Justin M. Forbes 45e84a
From: Gerd Hoffmann <kraxel@redhat.com>
Justin M. Forbes 45e84a
Date: Thu, 5 Jan 2012 15:49:18 +0100
Justin M. Forbes 45e84a
Subject: [PATCH 17/25] usb-host: properly release port on unplug & exit
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
Factor out port release into a separate function.  Call release function
Justin M. Forbes 45e84a
in exit notifier too.  Add explicit call the USBDEVFS_RELEASE_PORT
Justin M. Forbes 45e84a
ioctl, just closing the hub file handle seems not to be enougth.  Make
Justin M. Forbes 45e84a
sure we release the port before resetting the device, otherwise host
Justin M. Forbes 45e84a
drivers will not re-attach.
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Justin M. Forbes 45e84a
---
Justin M. Forbes 45e84a
 usb-linux.c |   28 ++++++++++++++++++++--------
Justin M. Forbes 45e84a
 1 files changed, 20 insertions(+), 8 deletions(-)
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
diff --git a/usb-linux.c b/usb-linux.c
Justin M. Forbes 45e84a
index ed14bb1..749ce71 100644
Justin M. Forbes 45e84a
--- a/usb-linux.c
Justin M. Forbes 45e84a
+++ b/usb-linux.c
Justin M. Forbes 45e84a
@@ -116,6 +116,7 @@ typedef struct USBHostDevice {
Justin M. Forbes 45e84a
     USBDevice dev;
Justin M. Forbes 45e84a
     int       fd;
Justin M. Forbes 45e84a
     int       hub_fd;
Justin M. Forbes 45e84a
+    int       hub_port;
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
     uint8_t   descr[8192];
Justin M. Forbes 45e84a
     int       descr_len;
Justin M. Forbes 45e84a
@@ -434,7 +435,7 @@ static int usb_host_claim_port(USBHostDevice *s)
Justin M. Forbes 45e84a
 {
Justin M. Forbes 45e84a
 #ifdef USBDEVFS_CLAIM_PORT
Justin M. Forbes 45e84a
     char *h, hub_name[64], line[1024];
Justin M. Forbes 45e84a
-    int hub_addr, portnr, ret;
Justin M. Forbes 45e84a
+    int hub_addr, ret;
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
     snprintf(hub_name, sizeof(hub_name), "%d-%s",
Justin M. Forbes 45e84a
              s->match.bus_num, s->match.port);
Justin M. Forbes 45e84a
@@ -442,13 +443,13 @@ static int usb_host_claim_port(USBHostDevice *s)
Justin M. Forbes 45e84a
     /* try strip off last ".$portnr" to get hub */
Justin M. Forbes 45e84a
     h = strrchr(hub_name, '.');
Justin M. Forbes 45e84a
     if (h != NULL) {
Justin M. Forbes 45e84a
-        portnr = atoi(h+1);
Justin M. Forbes 45e84a
+        s->hub_port = atoi(h+1);
Justin M. Forbes 45e84a
         *h = '\0';
Justin M. Forbes 45e84a
     } else {
Justin M. Forbes 45e84a
         /* no dot in there -> it is the root hub */
Justin M. Forbes 45e84a
         snprintf(hub_name, sizeof(hub_name), "usb%d",
Justin M. Forbes 45e84a
                  s->match.bus_num);
Justin M. Forbes 45e84a
-        portnr = atoi(s->match.port);
Justin M. Forbes 45e84a
+        s->hub_port = atoi(s->match.port);
Justin M. Forbes 45e84a
     }
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
     if (!usb_host_read_file(line, sizeof(line), "devnum",
Justin M. Forbes 45e84a
@@ -469,20 +470,32 @@ static int usb_host_claim_port(USBHostDevice *s)
Justin M. Forbes 45e84a
         return -1;
Justin M. Forbes 45e84a
     }
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
-    ret = ioctl(s->hub_fd, USBDEVFS_CLAIM_PORT, &portnr);
Justin M. Forbes 45e84a
+    ret = ioctl(s->hub_fd, USBDEVFS_CLAIM_PORT, &s->hub_port);
Justin M. Forbes 45e84a
     if (ret < 0) {
Justin M. Forbes 45e84a
         close(s->hub_fd);
Justin M. Forbes 45e84a
         s->hub_fd = -1;
Justin M. Forbes 45e84a
         return -1;
Justin M. Forbes 45e84a
     }
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
-    trace_usb_host_claim_port(s->match.bus_num, hub_addr, portnr);
Justin M. Forbes 45e84a
+    trace_usb_host_claim_port(s->match.bus_num, hub_addr, s->hub_port);
Justin M. Forbes 45e84a
     return 0;
Justin M. Forbes 45e84a
 #else
Justin M. Forbes 45e84a
     return -1;
Justin M. Forbes 45e84a
 #endif
Justin M. Forbes 45e84a
 }
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
+static void usb_host_release_port(USBHostDevice *s)
Justin M. Forbes 45e84a
+{
Justin M. Forbes 45e84a
+    if (s->hub_fd == -1) {
Justin M. Forbes 45e84a
+        return;
Justin M. Forbes 45e84a
+    }
Justin M. Forbes 45e84a
+#ifdef USBDEVFS_RELEASE_PORT
Justin M. Forbes 45e84a
+    ioctl(s->hub_fd, USBDEVFS_RELEASE_PORT, &s->hub_port);
Justin M. Forbes 45e84a
+#endif
Justin M. Forbes 45e84a
+    close(s->hub_fd);
Justin M. Forbes 45e84a
+    s->hub_fd = -1;
Justin M. Forbes 45e84a
+}
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
 static int usb_host_disconnect_ifaces(USBHostDevice *dev, int nb_interfaces)
Justin M. Forbes 45e84a
 {
Justin M. Forbes 45e84a
     /* earlier Linux 2.4 do not support that */
Justin M. Forbes 45e84a
@@ -635,10 +648,8 @@ static void usb_host_handle_destroy(USBDevice *dev)
Justin M. Forbes 45e84a
 {
Justin M. Forbes 45e84a
     USBHostDevice *s = (USBHostDevice *)dev;
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
+    usb_host_release_port(s);
Justin M. Forbes 45e84a
     usb_host_close(s);
Justin M. Forbes 45e84a
-    if (s->hub_fd != -1) {
Justin M. Forbes 45e84a
-        close(s->hub_fd);
Justin M. Forbes 45e84a
-    }
Justin M. Forbes 45e84a
     QTAILQ_REMOVE(&hostdevs, s, next);
Justin M. Forbes 45e84a
     qemu_remove_exit_notifier(&s->exit);
Justin M. Forbes 45e84a
 }
Justin M. Forbes 45e84a
@@ -1402,6 +1413,7 @@ static void usb_host_exit_notifier(struct Notifier *n, void *data)
Justin M. Forbes 45e84a
 {
Justin M. Forbes 45e84a
     USBHostDevice *s = container_of(n, USBHostDevice, exit);
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
+    usb_host_release_port(s);
Justin M. Forbes 45e84a
     if (s->fd != -1) {
Justin M. Forbes 45e84a
         usb_host_do_reset(s);;
Justin M. Forbes 45e84a
     }
Justin M. Forbes 45e84a
-- 
Justin M. Forbes 45e84a
1.7.7.5
Justin M. Forbes 45e84a