hal: Branch 'master' - 2 commits

Kay Sievers kay at kemper.freedesktop.org
Wed Mar 7 10:16:21 PST 2007


 hald/linux/device.c |   94 +++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 75 insertions(+), 19 deletions(-)

New commits:
diff-tree e1c4bad1177ac7578d38bb4b4f242f5c4cdead3c (from parents)
Merge: 5219e873e199eb8e0d555df966fe9cc3061859f4 71770748b84f512e6b98e2dcf0cbaacdfe7f70da
Author: Kay Sievers <kay.sievers at vrfy.org>
Date:   Wed Mar 7 19:16:06 2007 +0100

    Merge branch 'master' of git+ssh://git.freedesktop.org/git/hal

diff-tree 5219e873e199eb8e0d555df966fe9cc3061859f4 (from f21d765994e4db15e43d339fa8c7d7d0e6e36c12)
Author: Kay Sievers <kay.sievers at vrfy.org>
Date:   Wed Mar 7 19:14:55 2007 +0100

    fix scsi_host parent relationship
    
    The new dumb coldplug can't fake class-devices as parents
    of bus-devices, so we need to work around the broken SCSI-sysfs
    now, by synthesizing the host-events when we need it for the
    scsi disks.

diff --git a/hald/linux/device.c b/hald/linux/device.c
index aab6f4f..74e440b 100644
--- a/hald/linux/device.c
+++ b/hald/linux/device.c
@@ -523,6 +523,57 @@ scsi_generic_compute_udi (HalDevice *d)
 
 /*--------------------------------------------------------------------------------------------------------------*/
 
+/* scsi-sysfs totally sucks, we don't get events for the devices in the
+ * devpath, but totally useless class devices; we hook into the scsi_device
+ * event, and synthesize the missing host event
+ */
+static gboolean
+missing_scsi_host (const gchar *sysfs_path, HotplugEvent *device_event, HotplugActionType action)
+{
+	gchar path[HAL_PATH_MAX];
+	HalDevice *d;
+	HotplugEvent *host_event;
+	int rc = FALSE;
+
+	g_strlcpy(path, sysfs_path, sizeof(path));
+	/* skip device */
+	if (!hal_util_path_ascend (path))
+		goto out;
+	/* skip target */
+	if (!hal_util_path_ascend (path))
+		goto out;
+	if (strstr (path, "/host") == NULL)
+		goto out;
+
+	d = hal_device_store_match_key_value_string (hald_get_gdl (),
+						     "linux.sysfs_path",
+						     path);
+	if (action == HOTPLUG_ACTION_ADD && d != NULL)
+		goto out;
+	if (action == HOTPLUG_ACTION_REMOVE && d == NULL)
+		goto out;
+	rc = TRUE;
+
+	host_event = g_new0 (HotplugEvent, 1);
+	host_event->action = action;
+	host_event->type = HOTPLUG_EVENT_SYSFS_DEVICE;
+	g_strlcpy (host_event->sysfs.subsystem, "scsi_host", sizeof (host_event->sysfs.subsystem));
+	g_strlcpy (host_event->sysfs.sysfs_path, path, sizeof (host_event->sysfs.sysfs_path));
+	host_event->sysfs.net_ifindex = -1;
+
+	if (action == HOTPLUG_ACTION_ADD) {
+		hotplug_event_enqueue_at_front (device_event);
+		hotplug_event_enqueue_at_front (host_event);
+		hotplug_event_reposted (device_event);
+		goto out;
+	}
+	if (action == HOTPLUG_ACTION_REMOVE)
+		hotplug_event_enqueue (host_event);
+
+out:
+	return rc;
+}
+
 static HalDevice *
 scsi_host_add (const gchar *sysfs_path, const gchar *device_file, HalDevice *parent_dev, const gchar *parent_path)
 {
@@ -536,20 +587,21 @@ scsi_host_add (const gchar *sysfs_path, 
 		goto out;
 	}
 
+	/* ignore useless class device */
+	if (strstr(sysfs_path, "class/scsi_host") != NULL)
+		goto out;
+
+	last_elem = hal_util_get_last_element (sysfs_path);
+	if (sscanf (last_elem, "host%d", &host_num) != 1)
+		goto out;
+
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	
+	hal_device_property_set_int (d, "scsi_host.host", host_num);
 	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent_dev));
-
 	hal_device_property_set_string (d, "info.category", "scsi_host");
 	hal_device_add_capability (d, "scsi_host");
-
 	hal_device_property_set_string (d, "info.product", "SCSI Host Adapter");
-
-	last_elem = hal_util_get_last_element (sysfs_path);
-	sscanf (last_elem, "host%d", &host_num);
-	hal_device_property_set_int (d, "scsi_host.host", host_num);
-
 out:
 	return d;
 }
@@ -1852,24 +1904,23 @@ pcmcia_compute_udi (HalDevice *d)
 static HalDevice *
 scsi_add (const gchar *sysfs_path, const gchar *device_file, HalDevice *parent_dev, const gchar *parent_path)
 {
-	HalDevice *d;
+	HalDevice *d = NULL;
 	const gchar *bus_id;
 	gint host_num, bus_num, target_num, lun_num;
 	int type;
 
-	if (parent_dev == NULL) {
-		d = NULL;
+	if (parent_dev == NULL)
+		goto out;
+
+	bus_id = hal_util_get_last_element (sysfs_path);
+	if (sscanf (bus_id, "%d:%d:%d:%d", &host_num, &bus_num, &target_num, &lun_num) != 4)
 		goto out;
-	}
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	hal_device_property_set_string (d, "info.subsystem", "scsi");
 	hal_device_property_set_string (d, "info.bus", "scsi");
 	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent_dev));
-
-	bus_id = hal_util_get_last_element (sysfs_path);
-	sscanf (bus_id, "%d:%d:%d:%d", &host_num, &bus_num, &target_num, &lun_num);
 	hal_device_property_set_int (d, "scsi.host", host_num);
 	hal_device_property_set_int (d, "scsi.bus", bus_num);
 	hal_device_property_set_int (d, "scsi.target", target_num);
@@ -3462,6 +3513,10 @@ hotplug_event_begin_add_dev (const gchar
 		if (strcmp (handler->subsystem, subsystem) == 0) {
 			HalDevice *d;
 
+			if (strcmp (subsystem, "scsi") == 0)
+				if (missing_scsi_host(sysfs_path, (HotplugEvent *)end_token, HOTPLUG_ACTION_ADD))
+					goto out;
+
 			/* attempt to add the device */
 			d = handler->add (sysfs_path, device_file, parent_dev, parent_path);
 			if (d == NULL) {
@@ -3472,7 +3527,7 @@ hotplug_event_begin_add_dev (const gchar
 
 			hal_device_property_set_int (d, "linux.hotplug_type", HOTPLUG_EVENT_SYSFS_DEVICE);
 			hal_device_property_set_string (d, "linux.subsystem", subsystem);
-			
+
 			if (device_file != NULL && strlen (device_file) > 0)
 				hal_device_property_set_string (d, "linux.device_file", device_file);
 
@@ -3507,14 +3562,15 @@ hotplug_event_begin_remove_dev (const gc
 	if (d == NULL) {
 		HAL_WARNING (("Error removing device"));
 	} else {
-
 		for (i = 0; dev_handlers [i] != NULL; i++) {
 			DevHandler *handler;
-			
+
 			handler = dev_handlers[i];
 			if (strcmp (handler->subsystem, subsystem) == 0) {
-				handler->remove (d);
+				if (strcmp (subsystem, "scsi") == 0)
+					missing_scsi_host(sysfs_path, (HotplugEvent *)end_token, HOTPLUG_ACTION_REMOVE);
 
+				handler->remove (d);
 				hal_util_callout_device_remove (d, dev_callouts_remove_done, end_token, NULL);
 				goto out;
 			}


More information about the hal-commit mailing list