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