[Spice-commits] 9 commits - gtk/usb-device-manager.c gtk/usb-device-manager-priv.h gtk/win-usb-dev.c

Uri Lublin uril at kemper.freedesktop.org
Thu Apr 4 07:27:15 PDT 2013


 gtk/usb-device-manager-priv.h |    8 -
 gtk/usb-device-manager.c      |  175 ++++++++++++++++++++++++++++++++++--------
 gtk/win-usb-dev.c             |   20 +++-
 3 files changed, 163 insertions(+), 40 deletions(-)

New commits:
commit 33e6217fc395f50d5b7f7e34bc66abf85ab39897
Author: Uri Lublin <uril at redhat.com>
Date:   Sun Mar 24 15:49:15 2013 +0200

    usb-device-manager: fix log messages to match vid:pid change
    
    On Windows clients now USB devices are identified by their vid:pid
    (sometimes these values are being held by variables "bus" and "addr")
    Change log messages accordingly.

diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index 7c59012..92d4615 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -50,6 +50,12 @@
 
 #include <glib/gi18n.h>
 
+#ifndef G_OS_WIN32 /* Linux -- device id is bus.addr */
+#define DEV_ID_FMT "at %d.%d"
+#else /* Windows -- device id is vid:pid */
+#define DEV_ID_FMT "0x%04x:0x%04x"
+#endif
+
 /**
  * SECTION:usb-device-manager
  * @short_description: USB device management
@@ -788,7 +794,11 @@ static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager  *self,
 
     device = spice_usb_device_manager_find_device(self, bus, address);
     if (device) {
-        SPICE_DEBUG("USB device at %d.%d already exists, ignored", bus, address);
+        SPICE_DEBUG("USB device 0x%04x:0x%04x at %d.%d already exists, ignored",
+                    spice_usb_device_get_vid(device),
+                    spice_usb_device_get_pid(device),
+                    spice_usb_device_get_busnum(device),
+                    spice_usb_device_get_devaddr(device));
         return;
     }
 
@@ -818,7 +828,7 @@ static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager  *self,
         libusb_free_device_list(dev_list, 1);
 
     if (!device) {
-        g_warning("Could not find USB device to add at busnum %d devaddr %d",
+        g_warning("Could not find USB device to add " DEV_ID_FMT,
                   bus, address);
         return;
     }
@@ -854,7 +864,7 @@ static void spice_usb_device_manager_remove_dev(SpiceUsbDeviceManager  *self,
 
     device = spice_usb_device_manager_find_device(self, bus, address);
     if (!device) {
-        g_warning("Could not find USB device to remove at busnum %d devaddr %d",
+        g_warning("Could not find USB device to remove " DEV_ID_FMT,
                   bus, address);
         return;
     }
@@ -863,7 +873,7 @@ static void spice_usb_device_manager_remove_dev(SpiceUsbDeviceManager  *self,
     const guint8 state = spice_usb_device_get_state(device);
     if ((state == SPICE_USB_DEVICE_STATE_INSTALLING) ||
         (state == SPICE_USB_DEVICE_STATE_UNINSTALLING)) {
-        SPICE_DEBUG("skipping device at %d.%d. It is un/installing it's driver",
+        SPICE_DEBUG("skipping " DEV_ID_FMT ". It is un/installing its driver",
                     bus, address);
         return;
     }
commit 76e94509cf29a78aa39740c81dcdd2eee355c7b9
Author: Uri Lublin <uril at redhat.com>
Date:   Sun Mar 24 15:31:55 2013 +0200

    usb-device-manager: Windows: identify devices by vid:pid instead of bus.address
    
    rhbz#842816
    
    Sometimes bus.address of a USB device changes upon WinUSB driver installation
    for that device. This makes bus.address not a good identifier to use when
    running on Windows machines.
    
    Instead this patch makes usb-device-manager, when running on a Windows client,
    identify devices by their vid:pid.
    
    What changes were made in this patch (in addition to previous patches):
    - vid:pid are asked from the udev.
    - match functions that compare vid:pid were added
    - when comparing devices vid:pid are used.
    
    This also means that a scenario where two USB devices with the same vid:pid
    on a Windows client is not supported. However there was a problem with this
    scenario before as on Windows drivers for (specific) USB devices are
    installed based on their vid:pid.

diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index a1399ee..7c59012 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -597,8 +597,13 @@ static gboolean spice_usb_device_manager_get_udev_bus_n_address(
 
     *bus = *address = 0;
 
+#ifndef G_OS_WIN32
     bus_str = g_udev_device_get_property(udev, "BUSNUM");
     address_str = g_udev_device_get_property(udev, "DEVNUM");
+#else /* Windows -- request vid:pid instead */
+    bus_str = g_udev_device_get_property(udev, "VID");
+    address_str = g_udev_device_get_property(udev, "PID");
+#endif
     if (bus_str)
         *bus = atoi(bus_str);
     if (address_str)
@@ -699,6 +704,7 @@ static void spice_usb_device_manager_auto_connect_cb(GObject      *gobject,
     spice_usb_device_unref(device);
 }
 
+#ifndef G_OS_WIN32 /* match functions for Linux -- match by bus.addr */
 static gboolean
 spice_usb_device_manager_device_match(SpiceUsbDevice *device,
                                       const int bus, const int address)
@@ -715,6 +721,28 @@ spice_usb_device_manager_libdev_match(libusb_device *libdev,
             libusb_get_device_address(libdev) == address);
 }
 
+#else /* Win32 -- match functions for Windows -- match by vid:pid */
+static gboolean
+spice_usb_device_manager_device_match(SpiceUsbDevice *device,
+                                      const int vid, const int pid)
+{
+    return (spice_usb_device_get_vid(device) == vid &&
+            spice_usb_device_get_pid(device) == pid);
+}
+
+static gboolean
+spice_usb_device_manager_libdev_match(libusb_device *libdev,
+                                      const int vid, const int pid)
+{
+    int vid2, pid2;
+
+    if (!spice_usb_device_manager_get_libdev_vid_pid(libdev, &vid2, &pid2)) {
+        return FALSE;
+    }
+    return (vid == vid2 && pid == pid2);
+}
+#endif /* of Win32 -- match functions */
+
 static SpiceUsbDevice*
 spice_usb_device_manager_find_device(SpiceUsbDeviceManager *self,
                                      const int bus, const int address)
@@ -1663,8 +1691,13 @@ spice_usb_device_manager_device_to_libdev(SpiceUsbDeviceManager *self,
     g_return_val_if_fail(self->priv != NULL, NULL);
     g_return_val_if_fail(self->priv->context != NULL, NULL);
 
+#ifndef G_OS_WIN32
     bus  = spice_usb_device_get_busnum(device);
     addr = spice_usb_device_get_devaddr(device);
+#else
+    bus  = spice_usb_device_get_vid(device);
+    addr = spice_usb_device_get_pid(device);
+#endif
 
     libusb_get_device_list(self->priv->context, &devlist);
     if (!devlist)
commit d614078f6b9a10f81c5693190a3211f7dab66d08
Author: Uri Lublin <uril at redhat.com>
Date:   Sun Mar 24 15:22:37 2013 +0200

    usb-device-manager: Windows: spice_usb_device_equal_libdev: compare vid:pid
    
    When comparing spice_usb_device with a libusb_device on Windows clients,
    use vid:pid instead of bus.address
    
    It seems that a device bus.address may change when WinUSB driver
    is being installed.

diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index 0a561f1..a1399ee 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -1608,6 +1608,7 @@ static void spice_usb_device_unref(SpiceUsbDevice *device)
     }
 }
 
+#ifndef G_OS_WIN32 /* Linux -- compare bus.addr */
 static gboolean
 spice_usb_device_equal_libdev(SpiceUsbDevice *device,
                               libusb_device  *libdev)
@@ -1624,6 +1625,26 @@ spice_usb_device_equal_libdev(SpiceUsbDevice *device,
 
     return ((bus1 == bus2) && (addr1 == addr2));
 }
+#else /* Windows -- compare vid:pid of device and libdev */
+static gboolean
+spice_usb_device_equal_libdev(SpiceUsbDevice *device,
+                              libusb_device  *libdev)
+{
+    int vid1, vid2, pid1, pid2;
+
+    if ((device == NULL) || (libdev == NULL))
+        return FALSE;
+
+    vid1 = spice_usb_device_get_vid(device);
+    pid1 = spice_usb_device_get_pid(device);
+
+    if (!spice_usb_device_manager_get_libdev_vid_pid(libdev, &vid2, &pid2)) {
+        return FALSE;
+    }
+
+    return ((vid1 == vid2) && (pid1 == pid2));
+}
+#endif
 
 /*
  * Caller must libusb_unref_device the libusb_device returned by this function.
commit 65fff9ffbef4c1fd7b00497a319d8e89eb5267a9
Author: Uri Lublin <uril at redhat.com>
Date:   Sun Mar 24 14:10:41 2013 +0200

    usb-device-manager: use a function to get vid:pid from a libusb_device
    
    To be reused later.
    
    Also implemented a get_device_descriptor function (in case it will be
    needed in the future).

diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index b4320af..0a561f1 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -607,6 +607,50 @@ static gboolean spice_usb_device_manager_get_udev_bus_n_address(
     return *bus && *address;
 }
 
+static gboolean spice_usb_device_manager_get_device_descriptor(
+    libusb_device *libdev,
+    struct libusb_device_descriptor *desc)
+{
+    int errcode;
+    const gchar *errstr;
+
+    g_return_val_if_fail(libdev != NULL, FALSE);
+    g_return_val_if_fail(desc   != NULL, FALSE);
+
+    errcode = libusb_get_device_descriptor(libdev, desc);
+    if (errcode < 0) {
+        int bus, addr;
+
+        bus = libusb_get_bus_number(libdev);
+        addr = libusb_get_device_address(libdev);
+        errstr = spice_usbutil_libusb_strerror(errcode);
+        g_warning("cannot get device descriptor for (%p) %d.%d -- %s(%d)",
+                  libdev, bus, addr, errstr, errcode);
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static gboolean spice_usb_device_manager_get_libdev_vid_pid(
+    libusb_device *libdev, int *vid, int *pid)
+{
+    struct libusb_device_descriptor desc;
+
+    g_return_val_if_fail(libdev != NULL, FALSE);
+    g_return_val_if_fail(vid != NULL, FALSE);
+    g_return_val_if_fail(pid != NULL, FALSE);
+
+    *vid = *pid = 0;
+
+    if (!spice_usb_device_manager_get_device_descriptor(libdev, &desc)) {
+        return FALSE;
+    }
+    *vid = desc.idVendor;
+    *pid = desc.idProduct;
+
+    return TRUE;
+}
+
 /* ------------------------------------------------------------------ */
 /* callbacks                                                          */
 
@@ -1462,9 +1506,7 @@ gchar *spice_usb_device_get_description(SpiceUsbDevice *device, const gchar *for
 static SpiceUsbDeviceInfo *spice_usb_device_new(libusb_device *libdev)
 {
     SpiceUsbDeviceInfo *info;
-    struct libusb_device_descriptor desc;
-    int errcode;
-    const gchar *errstr;
+    int vid, pid;
     guint8 bus, addr;
 
     g_return_val_if_fail(libdev != NULL, NULL);
@@ -1472,11 +1514,7 @@ static SpiceUsbDeviceInfo *spice_usb_device_new(libusb_device *libdev)
     bus = libusb_get_bus_number(libdev);
     addr = libusb_get_device_address(libdev);
 
-    errcode = libusb_get_device_descriptor(libdev, &desc);
-    if (errcode < 0) {
-        errstr = spice_usbutil_libusb_strerror(errcode);
-        g_warning("cannot get device descriptor for (%p) %d.%d -- %s(%d)",
-                  libdev, bus, addr, errstr, errcode);
+    if (!spice_usb_device_manager_get_libdev_vid_pid(libdev, &vid, &pid)) {
         return NULL;
     }
 
@@ -1484,8 +1522,8 @@ static SpiceUsbDeviceInfo *spice_usb_device_new(libusb_device *libdev)
 
     info->busnum  = bus;
     info->devaddr = addr;
-    info->vid = desc.idVendor;
-    info->pid = desc.idProduct;
+    info->vid = vid;
+    info->pid = pid;
     info->ref = 1;
 
     return info;
commit df8543af51d7b0d71edee3b50b7fc5af0931d816
Author: Uri Lublin <uril at redhat.com>
Date:   Sun Mar 24 12:37:37 2013 +0200

    usb-device-manager: find_libdev: use a match function
    
    Instead of comparing directly against <bus, address>.
    
    In preparation of comparing against vid:pid for Windows clients.

diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index d58fb72..b4320af 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -663,6 +663,14 @@ spice_usb_device_manager_device_match(SpiceUsbDevice *device,
             spice_usb_device_get_devaddr(device) == address);
 }
 
+static gboolean
+spice_usb_device_manager_libdev_match(libusb_device *libdev,
+                                      const int bus, const int address)
+{
+    return (libusb_get_bus_number(libdev) == bus &&
+            libusb_get_device_address(libdev) == address);
+}
+
 static SpiceUsbDevice*
 spice_usb_device_manager_find_device(SpiceUsbDeviceManager *self,
                                      const int bus, const int address)
@@ -718,8 +726,7 @@ static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager  *self,
         libusb_get_device_list(priv->context, &dev_list);
 
     for (i = 0; dev_list && dev_list[i]; i++) {
-        if (libusb_get_bus_number(dev_list[i]) == bus &&
-            libusb_get_device_address(dev_list[i]) == address) {
+        if (spice_usb_device_manager_libdev_match(dev_list[i], bus, address)) {
             libdev = dev_list[i];
             break;
         }
@@ -1589,7 +1596,7 @@ spice_usb_device_manager_device_to_libdev(SpiceUsbDeviceManager *self,
                                           SpiceUsbDevice *device)
 {
     libusb_device *d, **devlist;
-    guint8 bus, addr;
+    int bus, addr;
     int i;
 
     g_return_val_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self), NULL);
@@ -1605,8 +1612,7 @@ spice_usb_device_manager_device_to_libdev(SpiceUsbDeviceManager *self,
         return NULL;
 
     for (i = 0; (d = devlist[i]) != NULL; i++) {
-        if ((libusb_get_bus_number(d) == bus) &&
-            (libusb_get_device_address(d) == addr)) {
+        if (spice_usb_device_manager_libdev_match(d, bus, addr)) {
             libusb_ref_device(d);
             break;
         }
commit 6a2c10d27802b33ee75f67c422199054966e553c
Author: Uri Lublin <uril at redhat.com>
Date:   Sun Mar 24 12:34:28 2013 +0200

    usb-device-manager: find_device: use a match function
    
    Instead of comparing directly against <bus, address>
    
    In preparation of comparing against vid:pid for Windows clients.

diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index 4421c48..d58fb72 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -655,9 +655,17 @@ static void spice_usb_device_manager_auto_connect_cb(GObject      *gobject,
     spice_usb_device_unref(device);
 }
 
+static gboolean
+spice_usb_device_manager_device_match(SpiceUsbDevice *device,
+                                      const int bus, const int address)
+{
+    return (spice_usb_device_get_busnum(device) == bus &&
+            spice_usb_device_get_devaddr(device) == address);
+}
+
 static SpiceUsbDevice*
 spice_usb_device_manager_find_device(SpiceUsbDeviceManager *self,
-                                     guint8 bus, guint8 address)
+                                     const int bus, const int address)
 {
     SpiceUsbDeviceManagerPrivate *priv = self->priv;
     SpiceUsbDevice *curr, *device = NULL;
@@ -665,8 +673,7 @@ spice_usb_device_manager_find_device(SpiceUsbDeviceManager *self,
 
     for (i = 0; i < priv->devices->len; i++) {
         curr = g_ptr_array_index(priv->devices, i);
-        if (spice_usb_device_get_busnum(curr) == bus &&
-               spice_usb_device_get_devaddr(curr) == address) {
+        if (spice_usb_device_manager_device_match(curr, bus, address)) {
             device = curr;
             break;
         }
commit 79c7d4641ee41bbfdd24d202187d33d5eea63cd9
Author: Uri Lublin <uril at redhat.com>
Date:   Thu Mar 7 14:45:04 2013 +0200

    usb-device-manager: constify spice_usb_device_get_ functions

diff --git a/gtk/usb-device-manager-priv.h b/gtk/usb-device-manager-priv.h
index 51a38df..b6fa9c9 100644
--- a/gtk/usb-device-manager-priv.h
+++ b/gtk/usb-device-manager-priv.h
@@ -36,10 +36,10 @@ void spice_usb_device_manager_stop_event_listening(
 void spice_usb_device_manager_device_error(
     SpiceUsbDeviceManager *manager, SpiceUsbDevice *device, GError *err);
 
-guint8 spice_usb_device_get_busnum(SpiceUsbDevice *device);
-guint8 spice_usb_device_get_devaddr(SpiceUsbDevice *device);
-guint16 spice_usb_device_get_vid(SpiceUsbDevice *device);
-guint16 spice_usb_device_get_pid(SpiceUsbDevice *device);
+guint8 spice_usb_device_get_busnum(const SpiceUsbDevice *device);
+guint8 spice_usb_device_get_devaddr(const SpiceUsbDevice *device);
+guint16 spice_usb_device_get_vid(const SpiceUsbDevice *device);
+guint16 spice_usb_device_get_pid(const SpiceUsbDevice *device);
 
 #endif
 
diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index eafed7c..4421c48 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -1477,36 +1477,36 @@ static SpiceUsbDeviceInfo *spice_usb_device_new(libusb_device *libdev)
     return info;
 }
 
-guint8 spice_usb_device_get_busnum(SpiceUsbDevice *device)
+guint8 spice_usb_device_get_busnum(const SpiceUsbDevice *device)
 {
-    SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+    const SpiceUsbDeviceInfo *info = (const SpiceUsbDeviceInfo *)device;
 
     g_return_val_if_fail(info != NULL, 0);
 
     return info->busnum;
 }
 
-guint8 spice_usb_device_get_devaddr(SpiceUsbDevice *device)
+guint8 spice_usb_device_get_devaddr(const SpiceUsbDevice *device)
 {
-    SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+    const SpiceUsbDeviceInfo *info = (const SpiceUsbDeviceInfo *)device;
 
     g_return_val_if_fail(info != NULL, 0);
 
     return info->devaddr;
 }
 
-guint16 spice_usb_device_get_vid(SpiceUsbDevice *device)
+guint16 spice_usb_device_get_vid(const SpiceUsbDevice *device)
 {
-    SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+    const SpiceUsbDeviceInfo *info = (const SpiceUsbDeviceInfo *)device;
 
     g_return_val_if_fail(info != NULL, 0);
 
     return info->vid;
 }
 
-guint16 spice_usb_device_get_pid(SpiceUsbDevice *device)
+guint16 spice_usb_device_get_pid(const SpiceUsbDevice *device)
 {
-    SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+    const SpiceUsbDeviceInfo *info = (const SpiceUsbDeviceInfo *)device;
 
     g_return_val_if_fail(info != NULL, 0);
 
commit f9631cd6f8a8c8bbfb2c95047b9e11272c02552b
Author: Uri Lublin <uril at redhat.com>
Date:   Sun Mar 24 14:36:35 2013 +0200

    win-usb-dev: compare vid:pid instead of bus.addr (Windows)
    
    It seems that sometimes, on Win7 clients, bus.addr is changing
    when WinUSB driver is being installed (e.g. 4.1 -> 4.2).
    
    So compare vid:pid instead.

diff --git a/gtk/win-usb-dev.c b/gtk/win-usb-dev.c
index 0bccc7c..9c95ac4 100644
--- a/gtk/win-usb-dev.c
+++ b/gtk/win-usb-dev.c
@@ -320,20 +320,20 @@ static gboolean get_usb_dev_info(libusb_device *dev, GUdevDeviceInfo *udevinfo)
     return TRUE;
 }
 
-/* Only bus,addr are compared */
+/* Only vid:pid are compared */
 static gboolean gudev_devices_are_equal(GUdevDevice *a, GUdevDevice *b)
 {
     GUdevDeviceInfo *ai, *bi;
-    gboolean same_bus;
-    gboolean same_addr;
+    gboolean same_vid;
+    gboolean same_pid;
 
     ai = a->priv->udevinfo;
     bi = b->priv->udevinfo;
 
-    same_bus  = (ai->bus  == bi->bus);
-    same_addr = (ai->addr == bi->addr);
+    same_vid  = (ai->vid == bi->vid);
+    same_pid  = (ai->pid == bi->pid);
 
-    return (same_bus && same_addr);
+    return (same_pid && same_vid);
 }
 
 
commit 6a3206479f1822a31619d282a7caf544e0cfe440
Author: Uri Lublin <uril at redhat.com>
Date:   Sun Mar 24 14:31:17 2013 +0200

    win-usb-dev: make VID and PID available via get_property (Windows)

diff --git a/gtk/win-usb-dev.c b/gtk/win-usb-dev.c
index c188807..0bccc7c 100644
--- a/gtk/win-usb-dev.c
+++ b/gtk/win-usb-dev.c
@@ -60,6 +60,8 @@ struct _GUdevDeviceInfo {
     gchar sclass[4];
     gchar sbus[4];
     gchar saddr[4];
+    gchar svid[8];
+    gchar spid[8];
 };
 
 struct _GUdevDevicePrivate
@@ -313,6 +315,8 @@ static gboolean get_usb_dev_info(libusb_device *dev, GUdevDeviceInfo *udevinfo)
     snprintf(udevinfo->sclass, sizeof(udevinfo->sclass), "%d", udevinfo->class);
     snprintf(udevinfo->sbus,   sizeof(udevinfo->sbus),   "%d", udevinfo->bus);
     snprintf(udevinfo->saddr,  sizeof(udevinfo->saddr),  "%d", udevinfo->addr);
+    snprintf(udevinfo->svid,   sizeof(udevinfo->svid),   "%d", udevinfo->vid);
+    snprintf(udevinfo->spid,   sizeof(udevinfo->spid),   "%d", udevinfo->pid);
     return TRUE;
 }
 
@@ -466,6 +470,10 @@ const gchar *g_udev_device_get_property(GUdevDevice *udev, const gchar *property
         return udevinfo->saddr;
     } else if (g_strcmp0(property, "DEVTYPE") == 0) {
         return "usb_device";
+    } else if (g_strcmp0(property, "VID") == 0) {
+        return udevinfo->svid;
+    } else if (g_strcmp0(property, "PID") == 0) {
+        return udevinfo->spid;
     }
 
     g_warn_if_reached();


More information about the Spice-commits mailing list