summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2014-12-04 14:59:18 +0000
committerRichard Hughes <richard@hughsie.com>2014-12-04 15:00:24 +0000
commitd80a9c35ab0483ef5ed61146bc441042467b94ed (patch)
tree5ec3116c0afee69db7276dee6c85d635def33ac8
parent2f5dbc0d5247d8fe330fce4dc96b6ea3e121f398 (diff)
downloadgusb-d80a9c35ab0483ef5ed61146bc441042467b94ed.tar.gz
Make the platform ID persistent across re-plug
This was technically a regression since the gudev days as some tools require the platform ID to be persistent across re-plug.
-rw-r--r--gusb/gusb-context.c31
-rw-r--r--gusb/gusb-device.c5
-rw-r--r--tools/gusb-main.c3
3 files changed, 33 insertions, 6 deletions
diff --git a/gusb/gusb-context.c b/gusb/gusb-context.c
index 81f0eaa..4c1cbfc 100644
--- a/gusb/gusb-context.c
+++ b/gusb/gusb-context.c
@@ -259,6 +259,24 @@ g_usb_context_emit_device_remove (GUsbContext *context, GUsbDevice *device)
}
/**
+ * g_usb_context_build_platform_id:
+ **/
+static void
+g_usb_context_build_platform_id (GString *str, libusb_device *dev)
+{
+ libusb_device *parent;
+ parent = libusb_get_parent (dev);
+ if (parent != NULL)
+ g_usb_context_build_platform_id (str, parent);
+ if (str->len == 0) {
+ g_string_append_printf (str, "%02x:",
+ libusb_get_bus_number (dev));
+ }
+ g_string_append_printf (str, "%02x:",
+ libusb_get_port_number (dev));
+}
+
+/**
* g_usb_context_add_device:
**/
static void
@@ -266,13 +284,14 @@ g_usb_context_add_device (GUsbContext *context, struct libusb_device *dev)
{
GUsbDevice *device = NULL;
GUsbContextPrivate *priv = context->priv;
- gchar *platform_id = NULL;
+ GString *platform_id = NULL;
guint8 bus;
guint8 address;
/* does any existing device exist */
bus = libusb_get_bus_number (dev);
address = libusb_get_device_address (dev);
+
if (priv->done_enumerate)
device = g_usb_context_find_by_bus_address (context, bus, address, NULL);
if (device != NULL) {
@@ -280,9 +299,13 @@ g_usb_context_add_device (GUsbContext *context, struct libusb_device *dev)
goto out;
}
+ /* build a topology of the device */
+ platform_id = g_string_new ("usb:");
+ g_usb_context_build_platform_id (platform_id, dev);
+ g_string_truncate (platform_id, platform_id->len - 1);
+
/* add the device */
- platform_id = g_strdup_printf ("usb[%02x:%02x]", bus, address);
- device = _g_usb_device_new (context, dev, platform_id);
+ device = _g_usb_device_new (context, dev, platform_id->str);
if (g_usb_device_get_device_class (device) == 0x09) {
g_debug ("%02x:%02x is a hub, ignoring", bus, address);
goto out;
@@ -292,7 +315,7 @@ g_usb_context_add_device (GUsbContext *context, struct libusb_device *dev)
out:
if (device != NULL)
g_object_unref (device);
- g_free (platform_id);
+ g_string_free (platform_id, TRUE);
}
/**
diff --git a/gusb/gusb-device.c b/gusb/gusb-device.c
index d0d5c4a..51b0c87 100644
--- a/gusb/gusb-device.c
+++ b/gusb/gusb-device.c
@@ -1329,7 +1329,10 @@ _g_usb_device_get_device (GUsbDevice *device)
* Gets the platform identifier for the device.
* On Linux, this is the full sysfs path of the device
*
- * Return value: The platform ID, e.g. "usb[03:03]"
+ * When the device is removed and then replugged, this value is not expected to
+ * be different.
+ *
+ * Return value: The platform ID, e.g. "usb:02:00:03:01"
*
* Since: 0.1.1
**/
diff --git a/tools/gusb-main.c b/tools/gusb-main.c
index 6676af4..a291ccd 100644
--- a/tools/gusb-main.c
+++ b/tools/gusb-main.c
@@ -223,7 +223,8 @@ gusb_cmd_watch (GUsbCmdPrivate *priv, gchar **values, GError **error)
devices = g_usb_context_get_devices (priv->usb_ctx);
for (i = 0; i < devices->len; i++) {
device = g_ptr_array_index (devices, i);
- g_print ("device already present %x:%x\n",
+ g_print ("device %s already present %x:%x\n",
+ g_usb_device_get_platform_id (device),
g_usb_device_get_bus (device),
g_usb_device_get_address (device));
}