summary refs log tree commit diff
path: root/libnm-glib/nm-device.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-glib/nm-device.c')
-rw-r--r--libnm-glib/nm-device.c105
1 files changed, 43 insertions, 62 deletions
diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c
index 5f492e2c..1c4fd736 100644
--- a/libnm-glib/nm-device.c
+++ b/libnm-glib/nm-device.c
@@ -205,6 +205,11 @@ device_state_change_reloaded (GObject *object,
 	NMDevice *self = NM_DEVICE (object);
 	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
 	StateChangeData *data = user_data;
+	NMDeviceState old_state = data->old_state;
+	NMDeviceState new_state = data->new_state;
+	NMDeviceStateReason reason = data->reason;
+
+	g_slice_free (StateChangeData, data);
 
 	_nm_object_reload_properties_finish (NM_OBJECT (object), result, NULL);
 
@@ -213,17 +218,16 @@ device_state_change_reloaded (GObject *object,
 	 * they'll finish in the right order. In that case, only emit the signal
 	 * for the last one.
 	 */
-	if (priv->last_seen_state != data->new_state)
+	if (priv->last_seen_state != new_state)
 		return;
 
 	/* Ensure that nm_device_get_state() will return the right value even if
 	 * we haven't processed the corresponding PropertiesChanged yet.
 	 */
-	priv->state = data->new_state;
+	priv->state = new_state;
 
 	g_signal_emit (self, signals[STATE_CHANGED], 0,
-	               data->new_state, data->old_state, data->reason);
-	g_slice_free (StateChangeData, data);
+	               new_state, old_state, reason);
 }
 
 static void
@@ -1252,7 +1256,7 @@ nm_device_get_state (NMDevice *device)
 /**
  * nm_device_get_state_reason:
  * @device: a #NMDevice
- * @reason: (out) (allow-none): location to store reason (#NMDeviceStateReason), or NULL
+ * @reason: (out) (allow-none): location to store reason (#NMDeviceStateReason), or %NULL
  *
  * Gets the current #NMDevice state (return value) and the reason for entering
  * the state (@reason argument).
@@ -1364,39 +1368,33 @@ get_decoded_property (GUdevDevice *device, const char *property)
 	return unescaped;
 }
 
-static void
-_device_update_description (NMDevice *device)
+static char *
+_get_udev_property (NMDevice *device,
+                    const char *enc_prop,  /* ID_XXX_ENC */
+                    const char *db_prop)   /* ID_XXX_FROM_DATABASE */
 {
-	NMDevicePrivate *priv;
+	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
 	const char *subsys[3] = { "net", "tty", NULL };
 	GUdevDevice *udev_device = NULL, *tmpdev, *olddev;
 	const char *ifname;
 	guint32 count = 0;
-	const char *vendor, *model;
-
-	g_return_if_fail (NM_IS_DEVICE (device));
-	priv = NM_DEVICE_GET_PRIVATE (device);
+	char *enc_value = NULL, *db_value = NULL;
 
 	if (!priv->client) {
 		priv->client = g_udev_client_new (subsys);
 		if (!priv->client)
-			return;
+			return NULL;
 	}
 
 	ifname = nm_device_get_iface (device);
 	if (!ifname)
-		return;
+		return NULL;
 
 	udev_device = g_udev_client_query_by_subsystem_and_name (priv->client, "net", ifname);
 	if (!udev_device)
 		udev_device = g_udev_client_query_by_subsystem_and_name (priv->client, "tty", ifname);
 	if (!udev_device)
-		return;
-
-	g_free (priv->product);
-	priv->product = NULL;
-	g_free (priv->vendor);
-	priv->vendor = NULL;
+		return NULL;
 
 	/* Walk up the chain of the device and its parents a few steps to grab
 	 * vendor and device ID information off it.
@@ -1406,12 +1404,11 @@ _device_update_description (NMDevice *device)
 	 * as g_udev_device_get_parent() returns a ref-ed object.
 	 */
 	tmpdev = g_object_ref (udev_device);
-	while ((count++ < 3) && tmpdev && (!priv->vendor || !priv->product)) {
-		if (!priv->vendor)
-			priv->vendor = get_decoded_property (tmpdev, "ID_VENDOR_ENC");
-
-		if (!priv->product)
-			priv->product = get_decoded_property (tmpdev, "ID_MODEL_ENC");
+	while ((count++ < 3) && tmpdev && !enc_value) {
+		if (!enc_value)
+			enc_value = get_decoded_property (tmpdev, enc_prop);
+		if (!db_value)
+			db_value = g_strdup (g_udev_device_get_property (tmpdev, db_prop));
 
 		olddev = tmpdev;
 		tmpdev = g_udev_device_get_parent (tmpdev);
@@ -1424,42 +1421,18 @@ _device_update_description (NMDevice *device)
 	if (tmpdev)
 		g_object_unref (tmpdev);
 
-	/* If we didn't get strings directly from the device, try database strings */
+	/* Balance the initial g_udev_client_query_by_subsystem_and_name() */
+	g_object_unref (udev_device);
 
-	/* Again, ref the original device as we need to unref it every iteration
-	 * since g_udev_device_get_parent() returns a refed object.
+	/* Prefer the the encoded value which comes directly from the device
+	 * over the hwdata database value.
 	 */
-	tmpdev = g_object_ref (udev_device);
-	count = 0;
-	while ((count++ < 3) && tmpdev && (!priv->vendor || !priv->product)) {
-		if (!priv->vendor) {
-			vendor = g_udev_device_get_property (tmpdev, "ID_VENDOR_FROM_DATABASE");
-			if (vendor)
-				priv->vendor = g_strdup (vendor);
-		}
-
-		if (!priv->product) {
-			model = g_udev_device_get_property (tmpdev, "ID_MODEL_FROM_DATABASE");
-			if (model)
-				priv->product = g_strdup (model);
-		}
-
-		olddev = tmpdev;
-		tmpdev = g_udev_device_get_parent (tmpdev);
-		g_object_unref (olddev);
+	if (enc_value) {
+		g_free (db_value);
+		return enc_value;
 	}
 
-	/* Unref the last device if we found what we needed before running out
-	 * of parents.
-	 */
-	if (tmpdev)
-		g_object_unref (tmpdev);
-
-	/* Balance the initial g_udev_client_query_by_subsystem_and_name() */
-	g_object_unref (udev_device);
-
-	_nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_VENDOR);
-	_nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_PRODUCT);
+	return db_value;
 }
 
 /**
@@ -1479,8 +1452,14 @@ nm_device_get_product (NMDevice *device)
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 
 	priv = NM_DEVICE_GET_PRIVATE (device);
-	if (!priv->product)
-		_device_update_description (device);
+	if (!priv->product) {
+		priv->product = _get_udev_property (device, "ID_MODEL_ENC", "ID_MODEL_FROM_DATABASE");
+		if (!priv->product) {
+			/* Sometimes ID_PRODUCT_FROM_DATABASE is used? */
+			priv->product = _get_udev_property (device, "ID_MODEL_ENC", "ID_PRODUCT_FROM_DATABASE");
+		}
+		_nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_PRODUCT);
+	}
 	return priv->product;
 }
 
@@ -1501,8 +1480,10 @@ nm_device_get_vendor (NMDevice *device)
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 
 	priv = NM_DEVICE_GET_PRIVATE (device);
-	if (!priv->vendor)
-		_device_update_description (device);
+	if (!priv->vendor) {
+		priv->vendor = _get_udev_property (device, "ID_VENDOR_ENC", "ID_VENDOR_FROM_DATABASE");
+		_nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_VENDOR);
+	}
 	return priv->vendor;
 }