hal/hald/linux2 acpi.c, 1.1, 1.2 acpi.h, 1.1, 1.2 classdev.c, 1.5, 1.6 classdev.h, 1.2, 1.3 coldplug.c, 1.4, 1.5 hotplug.c, 1.4, 1.5 hotplug.h, 1.1, 1.2 osspec.c, 1.4, 1.5 physdev.c, 1.4, 1.5 physdev.h, 1.1, 1.2

David Zeuthen david at freedesktop.org
Wed Feb 2 12:44:27 PST 2005


Update of /cvs/hal/hal/hald/linux2
In directory gabe:/tmp/cvs-serv29310/hald/linux2

Modified Files:
	acpi.c acpi.h classdev.c classdev.h coldplug.c hotplug.c 
	hotplug.h osspec.c physdev.c physdev.h 
Log Message:
2005-02-02  David Zeuthen  <david at fubar.dk>

	* hald/linux2/osspec.c: Adjust for changes in hotplug.h.
	(osspec_device_rescan): New function
	(osspec_device_reprobe): New function

	* hald/linux2/hotplug.h: Extend HotplugEvent struct to also be used
	for coldplugging/fake hotplugging (via Reprobe()) of ACPI devices.
	Add prototypes for hotplug_reprobe_tree() and hotplug_rescan_device().

	* hald/linux2/hotplug.c: Adjust to changes in hotplug.h
	(hotplug_event_begin_sysfs): New function; what used to be the
	function hotplug_event_begin().
	(hotplug_event_begin_acpi): New function
	(hotplug_event_begin): Now a simple dispatcher according to hotplug
	type; e.g. sysfs or acpi
	(hotplug_rescan_device): New function
	(hotplug_reprobe_generate_remove_events): New function
	(hotplug_reprobe_generate_add_events): New function
	(hotplug_reprobe_tree): New function

	* hald/linux2/coldplug.c: Adjust to changes in hotplug.h

	* hald/linux2/classdev.h: Add prototypes for classdev_generate_
	[add|remove]_hotplug_event() and classdev_rescan_device().

	* hald/linux2/classdev.c (hotplug_event_begin_add_classdev): Add
	some properties so we can reconstruct the hotplug event
	(classdev_rescan_device): New function
	(classdev_generate_add_hotplug_event): New function
	(classdev_generate_remove_hotplug_event): New function

	* hald/linux2/acpi.[ch]: Yikes, rewrite must of this to conform to
	the hotplug model so we can do Rescan() and Reprobe()

	* hald/osspec.h: Add prototypes for osspec_device_[rescan|reprobe]

	* hald/hald_test_libhal.c (send_tests_done): New function
	(check_libhal): Add some more tests and report back

	* hald/hald_test.c (check_properties): Fixup wrong failure reports
	(server_message_handler): Add new methods on the org.freedesktop.Hal.
	Tests interfaces to signal that a test is done
	(wait_for_external_test): New function; pretty ugly but it works
	for now. As noted: Patches are Welcome(tm)
	(main): Enable libhal tests

	* hald/hald_dbus.c (device_rescan): New function
	(device_reprobe): New function
	(hald_dbus_filter_function): Add checks for Rescan() and Reprobe()
	methods on the org.freedesktop.Hal.Device interface



Index: acpi.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/acpi.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- acpi.c	1 Feb 2005 05:17:55 -0000	1.1
+++ acpi.c	2 Feb 2005 20:44:25 -0000	1.2
@@ -27,50 +27,38 @@
 #include <string.h>
 
 #include "../callout.h"
+#include "../device_info.h"
 #include "../logger.h"
 #include "../hald_dbus.h"
 #include "util.h"
 
 #include "acpi.h"
+#include "hotplug.h"
 
-static void
-acpi_refresh_ac_adapter (HalDevice *d, const gchar *path)
-{
-	hal_device_property_set_string (d, "info.product", "AC Adapter");
-	hal_device_property_set_string (d, "info.category", "system.ac_adapter");
-	hal_device_add_capability (d, "system.ac_adapter");
-	hal_util_set_bool_elem_from_file (d, "system.ac_adapter.present", path, "state", "state", 0, "on-line");
-}
+enum {
+	ACPI_TYPE_BATTERY,
+	ACPI_TYPE_AC_ADAPTER,
+	ACPI_TYPE_BUTTON
+};
 
-static void
-acpi_refresh_button (HalDevice *d, const gchar *path)
+typedef struct ACPIDevHandler_s
 {
-	gchar *parent_path = hal_util_get_parent_path (path);
-	const gchar *button_type = hal_util_get_last_element (parent_path);
-
-	hal_device_property_set_string (d, "system.button.type", button_type);
-
-	if (strcmp (button_type, "power") == 0)   
-		hal_device_property_set_string (d, "info.product", "Power Button");
-	else if (strcmp (button_type, "lid") == 0)   
-		hal_device_property_set_string (d, "info.product", "Lid Switch");
-	else if (strcmp (button_type, "sleep") == 0)   
-		hal_device_property_set_string (d, "info.product", "Sleep Button");
+	int acpi_type;
+	HalDevice *(*add) (const gchar *acpi_path, HalDevice *parent, struct ACPIDevHandler_s *handler);
+	gboolean (*compute_udi) (HalDevice *d, struct ACPIDevHandler_s *handler);
+	gboolean (*remove) (HalDevice *d, struct ACPIDevHandler_s *handler);
+	gboolean (*refresh) (HalDevice *d, struct ACPIDevHandler_s *handler);
+} ACPIDevHandler;
 
-	hal_device_property_set_string (d, "info.category", "system.button");
-	hal_device_add_capability (d, "system.button");
-	if (!hal_util_set_bool_elem_from_file (d, "system.button.state.value", path, "state", "state", 0, "closed")) {
-		hal_device_property_set_bool (d, "system.button.has_state", FALSE);
-	} else {
-		hal_device_property_set_bool (d, "system.button.has_state", TRUE);
-	}
+static gboolean
+battery_refresh (HalDevice *d, ACPIDevHandler *handler)
+{
+	const char *path;
 
-	g_free (parent_path);
-}
+	path = hal_device_property_get_string (d, "linux.acpi_path");
+	if (path == NULL)
+		return FALSE;
 
-static void
-acpi_refresh_battery (HalDevice *d, const gchar *path)
-{
 	hal_device_property_set_string (d, "info.product", "Battery Bay");
 	hal_device_property_set_string (d, "battery.type", "primary");
 	hal_device_property_set_string (d, "info.category", "battery");
@@ -114,10 +102,66 @@
 						 "info", "design capacity", 0);
 		device_property_atomic_update_end ();
 	}
+
+	return TRUE;
+}
+
+static gboolean
+ac_adapter_refresh (HalDevice *d, ACPIDevHandler *handler)
+{
+	const char *path;
+
+	path = hal_device_property_get_string (d, "linux.acpi_path");
+	if (path == NULL)
+		return FALSE;
+
+	hal_device_property_set_string (d, "info.product", "AC Adapter");
+	hal_device_property_set_string (d, "info.category", "system.ac_adapter");
+	hal_device_add_capability (d, "system.ac_adapter");
+	hal_util_set_bool_elem_from_file (d, "system.ac_adapter.present", path, "state", "state", 0, "on-line");
+
+	return TRUE;
 }
 
+static gboolean
+button_refresh (HalDevice *d, ACPIDevHandler *handler)
+{
+	const char *path;
+	gchar *parent_path;
+	const gchar *button_type;
+
+	path = hal_device_property_get_string (d, "linux.acpi_path");
+	if (path == NULL)
+		return FALSE;
+
+	parent_path = hal_util_get_parent_path (path);
+	button_type = hal_util_get_last_element (parent_path);
+
+	hal_device_property_set_string (d, "system.button.type", button_type);
+
+	if (strcmp (button_type, "power") == 0)   
+		hal_device_property_set_string (d, "info.product", "Power Button");
+	else if (strcmp (button_type, "lid") == 0)   
+		hal_device_property_set_string (d, "info.product", "Lid Switch");
+	else if (strcmp (button_type, "sleep") == 0)   
+		hal_device_property_set_string (d, "info.product", "Sleep Button");
+
+	hal_device_property_set_string (d, "info.category", "system.button");
+	hal_device_add_capability (d, "system.button");
+	if (!hal_util_set_bool_elem_from_file (d, "system.button.state.value", path, "state", "state", 0, "closed")) {
+		hal_device_property_set_bool (d, "system.button.has_state", FALSE);
+	} else {
+		hal_device_property_set_bool (d, "system.button.has_state", TRUE);
+	}
+
+	g_free (parent_path);
+
+	return TRUE;
+}
+
+
 static void
-acpi_add_objects (const gchar *path, void (*refresh_handler)(HalDevice *d, const gchar *path))
+acpi_synthesize (const gchar *path, int acpi_type)
 {
 	const gchar *f;
 	GDir *dir;
@@ -130,23 +174,19 @@
 	}
 
 	while ((f = g_dir_read_name (dir)) != NULL) {
+		HotplugEvent *hotplug_event;
 		gchar buf[HAL_PATH_MAX];
-		gchar buf2[HAL_PATH_MAX];
-		HalDevice *d;
 
 		snprintf (buf, sizeof (buf), "%s/%s", path, f);
 		HAL_INFO (("Processing %s", buf));
 
-		d = hal_device_new ();
-		snprintf (buf2, sizeof (buf2), "/org/freedesktop/Hal/devices/acpi_%s", f);
-		hal_device_set_udi (d, buf2);
-		hal_device_property_set_string (d, "info.udi", buf2);
-		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
-		hal_device_property_set_string (d, "linux.acpi_path", buf);
-
-		refresh_handler (d, buf);
+		hotplug_event = g_new0 (HotplugEvent, 1);
+		hotplug_event->is_add = TRUE;
+		hotplug_event->type = HOTPLUG_EVENT_ACPI;
+		g_strlcpy (hotplug_event->acpi.acpi_path, buf, sizeof (hotplug_event->acpi.acpi_path));
+		hotplug_event->acpi.acpi_type = acpi_type;
 
-		hal_device_store_add (hald_get_gdl (), d);
+		hotplug_event_enqueue (hotplug_event);
 	}
 
 	/* close directory */
@@ -156,41 +196,11 @@
 	;
 }
 
-static gboolean
-poll_acpi_device (HalDeviceStore *store,
-		  HalDevice      *device,
-		  gpointer        user_data)
-{
-	if (hal_device_has_property (device, "linux.acpi_path")) {
-		const char *path;
-
-		path = hal_device_property_get_string (device, "linux.acpi_path");
-
-		if (hal_device_has_capability (device, "battery"))
-			acpi_refresh_battery (device, path);
-		else if (hal_device_has_capability (device, "system.button"))
-			acpi_refresh_button (device, path);
-		else if (hal_device_has_capability (device, "system.ac_adapter"))
-			acpi_refresh_ac_adapter (device, path);
-	}
-
-	return TRUE;
-}
-
-
-static gboolean
-poll_acpi (gpointer data)
-{
-	hal_device_store_foreach (hald_get_gdl (), poll_acpi_device, NULL);
-	return TRUE;
-}
-
-
-/** Scan the data structures exported by the kernel and build
- *  device objects representing ACPI objects
+/** Scan the data structures exported by the kernel and add hotplug
+ *  events for adding ACPI objects.
  */
 void
-acpi_probe (void)
+acpi_synthesize_hotplug_events (void)
 {
 	HalDevice *computer;
 	gchar path[HAL_PATH_MAX];
@@ -198,14 +208,12 @@
 	if (!g_file_test ("/proc/acpi/info", G_FILE_TEST_EXISTS))
 		goto out;
 
-	HAL_INFO (("Adding device objects for ACPI"));
-
 	if ((computer = hal_device_store_find (hald_get_gdl (), "/org/freedesktop/Hal/devices/computer")) == NULL) {
 		HAL_ERROR (("No computer object?"));
 		goto out;
 	}
 
-	/* only do ACPI specific options */
+	/* Set appropriate properties on the computer object */
 	hal_device_property_set_bool (computer, "power_management.is_enabled", TRUE);
 	hal_device_property_set_string (computer, "power_management.type", "acpi");
 	hal_util_set_string_elem_from_file (computer, "power_management.acpi.linux.version", 
@@ -213,28 +221,240 @@
 
 	/* collect batteries */
 	snprintf (path, sizeof (path), "%s/acpi/battery", hal_proc_path);
-	acpi_add_objects (path, acpi_refresh_battery);
+	acpi_synthesize (path, ACPI_TYPE_BATTERY);
 
 	/* collect AC adapters */
 	snprintf (path, sizeof (path), "%s/acpi/ac_adapter", hal_proc_path);
-	acpi_add_objects (path, acpi_refresh_ac_adapter);
+	acpi_synthesize (path, ACPI_TYPE_AC_ADAPTER);
 
 	/* collect buttons */
 	snprintf (path, sizeof (path), "%s/acpi/button/lid", hal_proc_path);
-	acpi_add_objects (path, acpi_refresh_button);
+	acpi_synthesize (path, ACPI_TYPE_BUTTON);
 	snprintf (path, sizeof (path), "%s/acpi/button/power", hal_proc_path);
-	acpi_add_objects (path, acpi_refresh_button);
+	acpi_synthesize (path, ACPI_TYPE_BUTTON);
 	snprintf (path, sizeof (path), "%s/acpi/button/sleep", hal_proc_path);
-	acpi_add_objects (path, acpi_refresh_button);
+	acpi_synthesize (path, ACPI_TYPE_BUTTON);
 
-	/* For fun, poll the objects..
-	 *
-	 * This needs to be replaced with listening to the ACPI socket! Uhm, also
-	 * because this is the only way to catch when someone presses a button
-	 * without state.
-	 */
-	g_timeout_add (2000, poll_acpi, NULL);	
+out:
+	;
+}
+
+static HalDevice *
+acpi_generic_add (const gchar *acpi_path, HalDevice *parent, ACPIDevHandler *handler)
+{
+	HalDevice *d;
+	d = hal_device_new ();
+	hal_device_property_set_string (d, "linux.acpi_path", acpi_path);
+	hal_device_property_set_int (d, "linux.acpi_type", handler->acpi_type);
+	if (parent != NULL)
+		hal_device_property_set_string (d, "info.parent", parent->udi);
+	else
+		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
+	if (handler->refresh == NULL || !handler->refresh (d, handler)) {
+		g_object_unref (d);
+		d = NULL;
+	}
+	return d;
+}
+
+static gboolean
+acpi_generic_compute_udi (HalDevice *d, ACPIDevHandler *handler)
+{
+	gchar udi[256];
+	hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
+			      "/org/freedesktop/Hal/devices/acpi_%s",
+			      hal_util_get_last_element (hal_device_property_get_string (d, "linux.acpi_path")));
+	hal_device_set_udi (d, udi);
+	hal_device_property_set_string (d, "info.udi", udi);
+	return TRUE;
+}
+
+static gboolean
+acpi_generic_remove (HalDevice *d, ACPIDevHandler *handler)
+{
+	if (!hal_device_store_remove (hald_get_gdl (), d)) {
+		HAL_WARNING (("Error removing device"));
+	}
+
+	return TRUE;
+}
+
+
+static ACPIDevHandler acpidev_handler_battery = { 
+	.acpi_type   = ACPI_TYPE_BATTERY,
+	.add         = acpi_generic_add,
+	.compute_udi = acpi_generic_compute_udi,
+	.refresh     = battery_refresh,
+	.remove      = acpi_generic_remove
+};
+
+static ACPIDevHandler acpidev_handler_button = { 
+	.acpi_type   = ACPI_TYPE_BUTTON,
+	.add         = acpi_generic_add,
+	.compute_udi = acpi_generic_compute_udi,
+	.refresh     = button_refresh,
+	.remove      = acpi_generic_remove
+};
+
+static ACPIDevHandler acpidev_handler_ac_adapter = { 
+	.acpi_type   = ACPI_TYPE_AC_ADAPTER,
+	.add         = acpi_generic_add,
+	.compute_udi = acpi_generic_compute_udi,
+	.refresh     = ac_adapter_refresh,
+	.remove      = acpi_generic_remove
+};
+
+static ACPIDevHandler *acpi_handlers[] = {
+	&acpidev_handler_battery,
+	&acpidev_handler_button,
+	&acpidev_handler_ac_adapter,
+	NULL
+};
+
+void
+hotplug_event_begin_add_acpi (const gchar *acpi_path, int acpi_type, HalDevice *parent, void *end_token)
+{
+	guint i;
 
+	HAL_INFO (("acpi_add: acpi_path=%s acpi_type=%d, parent=0x%08x", acpi_path, acpi_type, parent));
+
+	for (i = 0; acpi_handlers [i] != NULL; i++) {
+		ACPIDevHandler *handler;
+
+		handler = acpi_handlers[i];
+		if (handler->acpi_type == acpi_type) {
+			HalDevice *d;
+
+			d = handler->add (acpi_path, parent, handler);
+			if (d == NULL) {
+				/* didn't find anything - thus, ignore this hotplug event */
+				hotplug_event_end (end_token);
+				goto out;
+			}
+
+			hal_device_property_set_int (d, "linux.hotplug_type", HOTPLUG_EVENT_ACPI);
+
+			/* Add to temporary device store */
+			hal_device_store_add (hald_get_tdl (), d);
+
+			/* Merge properties from .fdi files */
+			di_search_and_merge (d);
+
+			/* TODO: Run callouts */
+			
+			/* Compute UDI */
+			if (!handler->compute_udi (d, handler)) {
+				hal_device_store_remove (hald_get_tdl (), d);
+				hotplug_event_end (end_token);
+				goto out;
+			}
+
+			/* Move from temporary to global device store */
+			hal_device_store_remove (hald_get_tdl (), d);
+			hal_device_store_add (hald_get_gdl (), d);
+			
+			hotplug_event_end (end_token);
+			goto out;
+		}
+	}
+	
+	/* didn't find anything - thus, ignore this hotplug event */
+	hotplug_event_end (end_token);
 out:
 	;
 }
+
+void
+hotplug_event_begin_remove_acpi (const gchar *acpi_path, int acpi_type, void *end_token)
+{
+	guint i;
+	HalDevice *d;
+
+	HAL_INFO (("acpi_rem: acpi_path=%s acpi_type=%d", acpi_path, acpi_type));
+
+	d = hal_device_store_match_key_value_string (hald_get_gdl (), "linux.acpi_path", acpi_path);
+	if (d == NULL) {
+		HAL_WARNING (("Couldn't remove device with acpi path %s - not found", acpi_path));
+		goto out;
+	}
+
+	for (i = 0; acpi_handlers [i] != NULL; i++) {
+		ACPIDevHandler *handler;
+
+		handler = acpi_handlers[i];
+		if (handler->acpi_type == acpi_type) {
+			if (handler->remove (d, handler)) {
+				hotplug_event_end (end_token);
+				goto out2;
+			}
+		}
+	}
+out:
+	/* didn't find anything - thus, ignore this hotplug event */
+	hotplug_event_end (end_token);
+out2:
+	;
+}
+
+gboolean
+acpi_rescan_device (HalDevice *d)
+{
+	guint i;
+	gboolean ret;
+	int acpi_type;
+
+	ret = FALSE;
+
+	acpi_type = hal_device_property_get_int (d, "linux.acpi_type");
+
+	for (i = 0; acpi_handlers [i] != NULL; i++) {
+		ACPIDevHandler *handler;
+
+		handler = acpi_handlers[i];
+		if (handler->acpi_type == acpi_type) {
+			ret = handler->refresh (d, handler);
+			goto out;
+		}
+	}
+
+	HAL_WARNING (("Didn't find a rescan handler for udi %s", d->udi));
+
+out:
+	return ret;
+}
+
+HotplugEvent *
+acpi_generate_add_hotplug_event (HalDevice *d)
+{
+	int acpi_type;
+	const char *acpi_path;
+	HotplugEvent *hotplug_event;
+
+	acpi_path = hal_device_property_get_string (d, "linux.acpi_path");
+	acpi_type = hal_device_property_get_int (d, "linux.acpi_type");
+
+	hotplug_event = g_new0 (HotplugEvent, 1);
+	hotplug_event->is_add = TRUE;
+	hotplug_event->type = HOTPLUG_EVENT_ACPI;
+	g_strlcpy (hotplug_event->acpi.acpi_path, acpi_path, sizeof (hotplug_event->acpi.acpi_path));
+	hotplug_event->acpi.acpi_type = acpi_type;
+	return hotplug_event;
+}
+
+HotplugEvent *
+acpi_generate_remove_hotplug_event (HalDevice *d)
+{
+	int acpi_type;
+	const char *acpi_path;
+	HotplugEvent *hotplug_event;
+
+	acpi_path = hal_device_property_get_string (d, "linux.acpi_path");
+	acpi_type = hal_device_property_get_int (d, "linux.acpi_type");
+
+	hotplug_event = g_new0 (HotplugEvent, 1);
+	hotplug_event->is_add = FALSE;
+	hotplug_event->type = HOTPLUG_EVENT_ACPI;
+	g_strlcpy (hotplug_event->acpi.acpi_path, acpi_path, sizeof (hotplug_event->acpi.acpi_path));
+	hotplug_event->acpi.acpi_type = acpi_type;
+	return hotplug_event;
+}

Index: acpi.h
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/acpi.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- acpi.h	1 Feb 2005 05:17:55 -0000	1.1
+++ acpi.h	2 Feb 2005 20:44:25 -0000	1.2
@@ -24,7 +24,18 @@
 #define ACPI_H
 
 #include "../hald.h"
+#include "hotplug.h"
 
-void acpi_probe (void);
+void acpi_synthesize_hotplug_events (void);
+
+void hotplug_event_begin_add_acpi (const gchar *acpi_path, int acpi_type, HalDevice *parent, void *end_token);
+
+void hotplug_event_begin_remove_acpi (const gchar *acpi_path, int acpi_type, void *end_token);
+
+gboolean acpi_rescan_device (HalDevice *d);
+
+HotplugEvent *acpi_generate_add_hotplug_event (HalDevice *d);
+
+HotplugEvent *acpi_generate_remove_hotplug_event (HalDevice *d);
 
 #endif /* ACPI_H */

Index: classdev.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/classdev.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- classdev.c	26 Jan 2005 20:14:58 -0000	1.5
+++ classdev.c	2 Feb 2005 20:44:25 -0000	1.6
@@ -511,6 +511,10 @@
 				goto out;
 			}
 
+			hal_device_property_set_int (d, "linux.hotplug_type", HOTPLUG_EVENT_SYSFS_CLASS);
+			hal_device_property_set_string (d, "linux.subsystem", subsystem);
+			hal_device_property_set_string (d, "linux.device_file", device_file);
+
 			/* Add to temporary device store */
 			hal_device_store_add (hald_get_tdl (), d);
 
@@ -567,3 +571,59 @@
 out:
 	;
 }
+
+gboolean
+classdev_rescan_device (HalDevice *d)
+{
+	return FALSE;
+}
+
+
+HotplugEvent *
+classdev_generate_add_hotplug_event (HalDevice *d)
+{
+	const char *subsystem;
+	const char *sysfs_path;
+	const char *device_file;
+	HotplugEvent *hotplug_event;
+
+	subsystem = hal_device_property_get_string (d, "linux.subsystem");
+	sysfs_path = hal_device_property_get_string (d, "linux.sysfs_path");
+	device_file = hal_device_property_get_string (d, "linux.device_file");
+
+	hotplug_event = g_new0 (HotplugEvent, 1);
+	hotplug_event->is_add = TRUE;
+	hotplug_event->type = HOTPLUG_EVENT_SYSFS;
+	g_strlcpy (hotplug_event->sysfs.subsystem, subsystem, sizeof (hotplug_event->sysfs.subsystem));
+	g_strlcpy (hotplug_event->sysfs.sysfs_path, sysfs_path, sizeof (hotplug_event->sysfs.sysfs_path));
+	if (device_file != NULL)
+		g_strlcpy (hotplug_event->sysfs.device_file, device_file, sizeof (hotplug_event->sysfs.device_file));
+	else
+		hotplug_event->sysfs.device_file[0] = '\0';
+	hotplug_event->sysfs.net_ifindex = -1;
+
+	return hotplug_event;
+}
+
+HotplugEvent *
+classdev_generate_remove_hotplug_event (HalDevice *d)
+{
+	const char *subsystem;
+	const char *sysfs_path;
+	const char *device_file;
+	HotplugEvent *hotplug_event;
+
+	subsystem = hal_device_property_get_string (d, "linux.subsystem");
+	sysfs_path = hal_device_property_get_string (d, "linux.sysfs_path");
+	device_file = hal_device_property_get_string (d, "linux.device_file");
+
+	hotplug_event = g_new0 (HotplugEvent, 1);
+	hotplug_event->is_add = FALSE;
+	hotplug_event->type = HOTPLUG_EVENT_SYSFS;
+	g_strlcpy (hotplug_event->sysfs.subsystem, subsystem, sizeof (hotplug_event->sysfs.subsystem));
+	g_strlcpy (hotplug_event->sysfs.sysfs_path, sysfs_path, sizeof (hotplug_event->sysfs.sysfs_path));
+	hotplug_event->sysfs.device_file[0] = '\0';
+	hotplug_event->sysfs.net_ifindex = -1;
+
+	return hotplug_event;
+}

Index: classdev.h
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/classdev.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- classdev.h	23 Jan 2005 23:11:59 -0000	1.2
+++ classdev.h	2 Feb 2005 20:44:25 -0000	1.3
@@ -27,10 +27,16 @@
 #define CLASSDEV_H
 
 #include <glib.h>
+#include "hotplug.h"
 
 void hotplug_event_begin_add_classdev (const gchar *subsystem, const gchar *sysfs_path, const gchar *device_file, HalDevice *physdev, const gchar *sysfs_path_in_devices, void *end_token);
 
 void hotplug_event_begin_remove_classdev (const gchar *subsystem, const gchar *sysfs_path, void *end_token);
 
+gboolean classdev_rescan_device (HalDevice *d);
+
+HotplugEvent *classdev_generate_add_hotplug_event (HalDevice *d);
+
+HotplugEvent *classdev_generate_remove_hotplug_event (HalDevice *d);
 
 #endif /* CLASSDEV_H */

Index: coldplug.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/coldplug.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- coldplug.c	1 Feb 2005 05:17:55 -0000	1.4
+++ coldplug.c	2 Feb 2005 20:44:25 -0000	1.5
@@ -273,10 +273,11 @@
 #endif
 		hotplug_event = g_new0 (HotplugEvent, 1);
 		hotplug_event->is_add = TRUE;
-		g_strlcpy (hotplug_event->subsystem, subsystem, sizeof (hotplug_event->subsystem));
-		g_strlcpy (hotplug_event->sysfs_path, sysfs_path, sizeof (hotplug_event->sysfs_path));
-		hal_util_get_device_file (sysfs_path, hotplug_event->device_file, sizeof (hotplug_event->device_file));
-		hotplug_event->net_ifindex = -1;
+		hotplug_event->type = HOTPLUG_EVENT_SYSFS;
+		g_strlcpy (hotplug_event->sysfs.subsystem, subsystem, sizeof (hotplug_event->sysfs.subsystem));
+		g_strlcpy (hotplug_event->sysfs.sysfs_path, sysfs_path, sizeof (hotplug_event->sysfs.sysfs_path));
+		hal_util_get_device_file (sysfs_path, hotplug_event->sysfs.device_file, sizeof (hotplug_event->sysfs.device_file));
+		hotplug_event->sysfs.net_ifindex = -1;
 		
 		hotplug_event_enqueue (hotplug_event);
 	}
@@ -311,14 +312,15 @@
 
 		hotplug_event = g_new0 (HotplugEvent, 1);
 		hotplug_event->is_add = TRUE;
-		g_strlcpy (hotplug_event->subsystem, "block", sizeof (hotplug_event->subsystem));
-		g_strlcpy (hotplug_event->sysfs_path, path, sizeof (hotplug_event->sysfs_path));
-		hal_util_get_device_file (path, hotplug_event->device_file, sizeof (hotplug_event->device_file));
+		hotplug_event->type = HOTPLUG_EVENT_SYSFS;
+		g_strlcpy (hotplug_event->sysfs.subsystem, "block", sizeof (hotplug_event->sysfs.subsystem));
+		g_strlcpy (hotplug_event->sysfs.sysfs_path, path, sizeof (hotplug_event->sysfs.sysfs_path));
+		hal_util_get_device_file (path, hotplug_event->sysfs.device_file, sizeof (hotplug_event->sysfs.device_file));
 		if (normalized_target != NULL)
-			g_strlcpy (hotplug_event->wait_for_sysfs_path, normalized_target, sizeof (hotplug_event->wait_for_sysfs_path));
+			g_strlcpy (hotplug_event->sysfs.wait_for_sysfs_path, normalized_target, sizeof (hotplug_event->sysfs.wait_for_sysfs_path));
 		else
-			hotplug_event->wait_for_sysfs_path[0] = '\0';
-		hotplug_event->net_ifindex = -1;
+			hotplug_event->sysfs.wait_for_sysfs_path[0] = '\0';
+		hotplug_event->sysfs.net_ifindex = -1;
 		hotplug_event_enqueue (hotplug_event);
 		g_free (normalized_target);
 
@@ -338,11 +340,12 @@
 
 				hotplug_event = g_new0 (HotplugEvent, 1);
 				hotplug_event->is_add = TRUE;
-				g_strlcpy (hotplug_event->subsystem, "block", sizeof (hotplug_event->subsystem));
-				g_strlcpy (hotplug_event->sysfs_path, path1, sizeof (hotplug_event->sysfs_path));
-				g_strlcpy (hotplug_event->wait_for_sysfs_path, path, sizeof (hotplug_event->wait_for_sysfs_path));
-				hal_util_get_device_file (path1, hotplug_event->device_file, sizeof (hotplug_event->device_file));
-				hotplug_event->net_ifindex = -1;
+				hotplug_event->type = HOTPLUG_EVENT_SYSFS;
+				g_strlcpy (hotplug_event->sysfs.subsystem, "block", sizeof (hotplug_event->sysfs.subsystem));
+				g_strlcpy (hotplug_event->sysfs.sysfs_path, path1, sizeof (hotplug_event->sysfs.sysfs_path));
+				g_strlcpy (hotplug_event->sysfs.wait_for_sysfs_path, path, sizeof (hotplug_event->sysfs.wait_for_sysfs_path));
+				hal_util_get_device_file (path1, hotplug_event->sysfs.device_file, sizeof (hotplug_event->sysfs.device_file));
+				hotplug_event->sysfs.net_ifindex = -1;
 				hotplug_event_enqueue (hotplug_event);
 			}
 		}
@@ -380,15 +383,16 @@
 
 		hotplug_event = g_new0 (HotplugEvent, 1);
 		hotplug_event->is_add = TRUE;
-		g_strlcpy (hotplug_event->subsystem, bus, sizeof (hotplug_event->subsystem));
-		g_strlcpy (hotplug_event->sysfs_path, path, sizeof (hotplug_event->sysfs_path));
-		hotplug_event->net_ifindex = -1;
+		hotplug_event->type = HOTPLUG_EVENT_SYSFS;
+		g_strlcpy (hotplug_event->sysfs.subsystem, bus, sizeof (hotplug_event->sysfs.subsystem));
+		g_strlcpy (hotplug_event->sysfs.sysfs_path, path, sizeof (hotplug_event->sysfs.sysfs_path));
+		hotplug_event->sysfs.net_ifindex = -1;
 
 		parent_sysfs_path = hal_util_get_parent_path (path);
-		g_strlcpy (hotplug_event->wait_for_sysfs_path, parent_sysfs_path, sizeof (hotplug_event->wait_for_sysfs_path));
+		g_strlcpy (hotplug_event->sysfs.wait_for_sysfs_path, parent_sysfs_path, sizeof (hotplug_event->sysfs.wait_for_sysfs_path));
 		g_free (parent_sysfs_path);
 
-		hotplug_event->device_file[0] = '\0';
+		hotplug_event->sysfs.device_file[0] = '\0';
 
 		hotplug_event_enqueue (hotplug_event);
 	}
@@ -408,14 +412,15 @@
 #endif
 		hotplug_event = g_new0 (HotplugEvent, 1);
 		hotplug_event->is_add = TRUE;
-		g_strlcpy (hotplug_event->subsystem, subsystem, sizeof (hotplug_event->subsystem));
-		g_strlcpy (hotplug_event->sysfs_path, sysfs_path, sizeof (hotplug_event->sysfs_path));
-		hal_util_get_device_file (sysfs_path, hotplug_event->device_file, sizeof (hotplug_event->device_file));
+		hotplug_event->type = HOTPLUG_EVENT_SYSFS;
+		g_strlcpy (hotplug_event->sysfs.subsystem, subsystem, sizeof (hotplug_event->sysfs.subsystem));
+		g_strlcpy (hotplug_event->sysfs.sysfs_path, sysfs_path, sizeof (hotplug_event->sysfs.sysfs_path));
+		hal_util_get_device_file (sysfs_path, hotplug_event->sysfs.device_file, sizeof (hotplug_event->sysfs.device_file));
 		if (path != NULL)
-			g_strlcpy (hotplug_event->wait_for_sysfs_path, path, sizeof (hotplug_event->wait_for_sysfs_path));
+			g_strlcpy (hotplug_event->sysfs.wait_for_sysfs_path, path, sizeof (hotplug_event->sysfs.wait_for_sysfs_path));
 		else
-			hotplug_event->wait_for_sysfs_path[0] = '\0';
-		hotplug_event->net_ifindex = -1;
+			hotplug_event->sysfs.wait_for_sysfs_path[0] = '\0';
+		hotplug_event->sysfs.net_ifindex = -1;
 		
 		hotplug_event_enqueue (hotplug_event);
 	}

Index: hotplug.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/hotplug.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- hotplug.c	1 Feb 2005 05:17:55 -0000	1.4
+++ hotplug.c	2 Feb 2005 20:44:25 -0000	1.5
@@ -50,9 +50,11 @@
 #include "../hald_conf.h"
 
 #include "hotplug.h"
+
 #include "physdev.h"
 #include "classdev.h"
 #include "blockdev.h"
+#include "acpi.h"
 
 
 /** Queue of ordered hotplug events */
@@ -77,11 +79,11 @@
 fixup_net_device_for_renaming (HotplugEvent *hotplug_event)
 {
 	/* fixup net devices by looking at ifindex */
-	if (strcmp (hotplug_event->subsystem, "net") == 0 && hotplug_event->net_ifindex != -1) {
+	if (strcmp (hotplug_event->sysfs.subsystem, "net") == 0 && hotplug_event->sysfs.net_ifindex != -1) {
 		int ifindex;
 		
-		if (!hal_util_get_int_from_file (hotplug_event->sysfs_path, "ifindex", &ifindex, 10) ||
-		    (ifindex != hotplug_event->net_ifindex)) {
+		if (!hal_util_get_int_from_file (hotplug_event->sysfs.sysfs_path, "ifindex", &ifindex, 10) ||
+		    (ifindex != hotplug_event->sysfs.net_ifindex)) {
 			GDir *dir;
 			char path[HAL_PATH_MAX];
 			char path1[HAL_PATH_MAX];
@@ -90,7 +92,7 @@
 			
 			/* search for new name */
 			HAL_WARNING (("Net interface @ %s with ifindex %d was probably renamed",
-				      hotplug_event->sysfs_path, hotplug_event->net_ifindex));
+				      hotplug_event->sysfs.sysfs_path, hotplug_event->sysfs.net_ifindex));
 			
 			
 			g_snprintf (path, HAL_PATH_MAX, "%s/class/net" , hal_sysfs_path);
@@ -102,9 +104,9 @@
 			while ((f = g_dir_read_name (dir)) != NULL) {
 				g_snprintf (path1, HAL_PATH_MAX, "%s/class/net/%s" , hal_sysfs_path, f);
 				if (hal_util_get_int_from_file (path1, "ifindex", &ifindex, 10)) {
-					if (ifindex == hotplug_event->net_ifindex) {
+					if (ifindex == hotplug_event->sysfs.net_ifindex) {
 						HAL_INFO (("Using sysfs path %s for ifindex %d", path1, ifindex));
-						strncpy (hotplug_event->sysfs_path, path1, HAL_PATH_MAX);
+						strncpy (hotplug_event->sysfs.sysfs_path, path1, HAL_PATH_MAX);
 						g_dir_close (dir);
 						goto out;
 					}
@@ -120,7 +122,7 @@
 
 
 static void
-hotplug_event_begin (HotplugEvent *hotplug_event)
+hotplug_event_begin_sysfs (HotplugEvent *hotplug_event)
 {
 	static char sys_devices_path[HAL_PATH_MAX];
 	static char sys_class_path[HAL_PATH_MAX];
@@ -136,20 +138,20 @@
 	}
 
 
-	if (strncmp (hotplug_event->sysfs_path, sys_devices_path, sys_devices_path_len) == 0) {		
+	if (strncmp (hotplug_event->sysfs.sysfs_path, sys_devices_path, sys_devices_path_len) == 0) {		
 		if (hotplug_event->is_add) {
 			HalDevice *parent;
-			parent = hal_util_find_closest_ancestor (hotplug_event->sysfs_path);
-			hotplug_event_begin_add_physdev (hotplug_event->subsystem, 
-							 hotplug_event->sysfs_path, 
+			parent = hal_util_find_closest_ancestor (hotplug_event->sysfs.sysfs_path);
+			hotplug_event_begin_add_physdev (hotplug_event->sysfs.subsystem, 
+							 hotplug_event->sysfs.sysfs_path, 
 							 parent,
 							 (void *) hotplug_event);
 		} else {
-			hotplug_event_begin_remove_physdev (hotplug_event->subsystem, 
-							    hotplug_event->sysfs_path, 
+			hotplug_event_begin_remove_physdev (hotplug_event->sysfs.subsystem, 
+							    hotplug_event->sysfs.sysfs_path, 
 							    (void *) hotplug_event);
 		}
-	} else if (strncmp (hotplug_event->sysfs_path, sys_class_path, sys_class_path_len) == 0) {
+	} else if (strncmp (hotplug_event->sysfs.sysfs_path, sys_class_path, sys_class_path_len) == 0) {
 		if (hotplug_event->is_add) {
 			gchar *target;
 			HalDevice *physdev;
@@ -163,11 +165,11 @@
 			 */
 			fixup_net_device_for_renaming (hotplug_event);
 			
-			g_snprintf (physdevpath, HAL_PATH_MAX, "%s/device", hotplug_event->sysfs_path);
+			g_snprintf (physdevpath, HAL_PATH_MAX, "%s/device", hotplug_event->sysfs.sysfs_path);
 			if (((target = g_file_read_link (physdevpath, NULL)) != NULL)) {
 				gchar *normalized_target;
 
-				normalized_target = hal_util_get_normalized_path (hotplug_event->sysfs_path, target);
+				normalized_target = hal_util_get_normalized_path (hotplug_event->sysfs.sysfs_path, target);
 				g_free (target);
 
 				sysfs_path_in_devices = g_strdup (normalized_target);
@@ -191,9 +193,9 @@
 				physdev = NULL;
 			}
 
-			hotplug_event_begin_add_classdev (hotplug_event->subsystem,
-							  hotplug_event->sysfs_path,
-							  hotplug_event->device_file,
+			hotplug_event_begin_add_classdev (hotplug_event->sysfs.subsystem,
+							  hotplug_event->sysfs.sysfs_path,
+							  hotplug_event->sysfs.device_file,
 							  physdev,
 							  sysfs_path_in_devices,
 							  (void *) hotplug_event);
@@ -201,15 +203,15 @@
 			g_free (sysfs_path_in_devices);
 
 		} else {
-			hotplug_event_begin_remove_classdev (hotplug_event->subsystem,
-							     hotplug_event->sysfs_path,
+			hotplug_event_begin_remove_classdev (hotplug_event->sysfs.subsystem,
+							     hotplug_event->sysfs.sysfs_path,
 							     (void *) hotplug_event);
 		}
-	} else if (strncmp (hotplug_event->sysfs_path, sys_block_path, sys_block_path_len) == 0) {
+	} else if (strncmp (hotplug_event->sysfs.sysfs_path, sys_block_path, sys_block_path_len) == 0) {
 		gchar *parent_path;
 		gboolean is_partition;
 		
-		parent_path = hal_util_get_parent_path (hotplug_event->sysfs_path);
+		parent_path = hal_util_get_parent_path (hotplug_event->sysfs.sysfs_path);
 		is_partition = (strcmp (parent_path, sys_block_path) != 0);
 		
 		if (hotplug_event->is_add) {
@@ -223,11 +225,11 @@
 				gchar *target;
 				char physdevpath[256];
 				
-				g_snprintf (physdevpath, HAL_PATH_MAX, "%s/device", hotplug_event->sysfs_path);
+				g_snprintf (physdevpath, HAL_PATH_MAX, "%s/device", hotplug_event->sysfs.sysfs_path);
 				if (((target = g_file_read_link (physdevpath, NULL)) != NULL)) {
 					gchar *normalized_target;
 
-					normalized_target = hal_util_get_normalized_path (hotplug_event->sysfs_path, target);
+					normalized_target = hal_util_get_normalized_path (hotplug_event->sysfs.sysfs_path, target);
 					g_free (target);
 					parent = hal_device_store_match_key_value_string (hald_get_gdl (), 
 											  "linux.sysfs_path_device", 
@@ -238,13 +240,13 @@
 				}
 			}
 			
-			hotplug_event_begin_add_blockdev (hotplug_event->sysfs_path,
-							  hotplug_event->device_file,
+			hotplug_event_begin_add_blockdev (hotplug_event->sysfs.sysfs_path,
+							  hotplug_event->sysfs.device_file,
 							  is_partition,
 							  parent,
 							  (void *) hotplug_event);
 		} else {
-			hotplug_event_begin_remove_blockdev (hotplug_event->sysfs_path,
+			hotplug_event_begin_remove_blockdev (hotplug_event->sysfs.sysfs_path,
 							     is_partition,
 							     (void *) hotplug_event);
 		}
@@ -254,6 +256,45 @@
 	}
 }
 
+static void
+hotplug_event_begin_acpi (HotplugEvent *hotplug_event)
+{
+	if (hotplug_event->is_add) {
+		hotplug_event_begin_add_acpi (hotplug_event->acpi.acpi_path, 
+					      hotplug_event->acpi.acpi_type,
+					      NULL,
+					      (void *) hotplug_event);
+	} else {
+		hotplug_event_begin_remove_acpi (hotplug_event->acpi.acpi_path, 
+						 hotplug_event->acpi.acpi_type,
+						 (void *) hotplug_event);
+	}
+}
+
+static void
+hotplug_event_begin (HotplugEvent *hotplug_event)
+{
+	switch (hotplug_event->type) {
+
+	/* explicit fallthrough */
+	case HOTPLUG_EVENT_SYSFS:
+	case HOTPLUG_EVENT_SYSFS_BUS:
+	case HOTPLUG_EVENT_SYSFS_CLASS:
+	case HOTPLUG_EVENT_SYSFS_BLOCK:
+		hotplug_event_begin_sysfs (hotplug_event);
+		break;
+
+	case HOTPLUG_EVENT_ACPI:
+		hotplug_event_begin_acpi (hotplug_event);
+		break;
+
+	default:
+		HAL_ERROR (("Unknown hotplug event type %d", hotplug_event->type));
+		hotplug_event_end ((void *) hotplug_event);
+		break;
+	}
+}
+
 void 
 hotplug_event_enqueue (HotplugEvent *hotplug_event)
 {
@@ -290,3 +331,135 @@
 out:
 	;	
 }
+
+gboolean 
+hotplug_rescan_device (HalDevice *d)
+{
+	gboolean ret;
+
+	switch (hal_device_property_get_int (d, "linux.hotplug_type")) {
+	case HOTPLUG_EVENT_SYSFS_BUS:
+		ret = physdev_rescan_device (d);
+		break;
+
+	case HOTPLUG_EVENT_SYSFS_CLASS:
+		ret = classdev_rescan_device (d);
+		break;
+
+	case HOTPLUG_EVENT_SYSFS_BLOCK:
+		ret = FALSE; /* TODO */
+		break;
+
+	case HOTPLUG_EVENT_ACPI:
+		ret = acpi_rescan_device (d);
+		break;
+
+	default:
+		HAL_INFO (("Unknown hotplug type for udi=%s", d->udi));
+		ret = FALSE;
+		break;
+	}
+
+	return ret;
+}
+
+static void
+hotplug_reprobe_generate_remove_events (HalDevice *d)
+{
+	GSList *i;
+	GSList *childs;
+	HotplugEvent *e;
+
+	/* first remove childs */
+	childs = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), "info.parent", d->udi);
+	for (i = childs; i != NULL; i = g_slist_next (i)) {
+		HalDevice *child;
+
+		child = HAL_DEVICE (i->data);
+		hotplug_reprobe_generate_remove_events (child);
+	}
+
+	/* then remove self */
+	HAL_INFO (("Generate remove event for udi %s", d->udi));
+	switch (hal_device_property_get_int (d, "linux.hotplug_type")) {
+	case HOTPLUG_EVENT_SYSFS_BUS:
+		e = physdev_generate_remove_hotplug_event (d);
+		break;
+
+	case HOTPLUG_EVENT_SYSFS_CLASS:
+		e = classdev_generate_remove_hotplug_event (d);
+		break;
+
+	case HOTPLUG_EVENT_SYSFS_BLOCK:
+		e = NULL; /* TODO */
+		break;
+
+	case HOTPLUG_EVENT_ACPI:
+		e = acpi_generate_remove_hotplug_event (d);
+		break;
+
+	default:
+		e = NULL;
+		HAL_INFO (("Unknown hotplug type for udi=%s", d->udi));
+		break;
+	}
+
+	if (e != NULL) {
+		hotplug_event_enqueue (e);
+	}
+}
+
+static void
+hotplug_reprobe_generate_add_events (HalDevice *d)
+{
+	GSList *i;
+	GSList *childs;
+	HotplugEvent *e;
+
+	/* first add self */
+	HAL_INFO (("Generate add event for udi %s", d->udi));
+	switch (hal_device_property_get_int (d, "linux.hotplug_type")) {
+	case HOTPLUG_EVENT_SYSFS_BUS:
+		e = physdev_generate_add_hotplug_event (d);
+		break;
+
+	case HOTPLUG_EVENT_SYSFS_CLASS:
+		e = classdev_generate_add_hotplug_event (d);
+		break;
+
+	case HOTPLUG_EVENT_SYSFS_BLOCK:
+		e = NULL; /* TODO */
+		break;
+
+	case HOTPLUG_EVENT_ACPI:
+		e = acpi_generate_add_hotplug_event (d);
+		break;
+
+	default:
+		e = NULL;
+		HAL_INFO (("Unknown hotplug type for udi=%s", d->udi));
+		break;
+	}
+
+	if (e != NULL) {
+		hotplug_event_enqueue (e);
+	}
+
+	/* then add childs */
+	childs = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), "info.parent", d->udi);
+	for (i = childs; i != NULL; i = g_slist_next (i)) {
+		HalDevice *child;
+
+		child = HAL_DEVICE (i->data);
+		hotplug_reprobe_generate_add_events (child);
+	}
+}
+
+gboolean
+hotplug_reprobe_tree (HalDevice *d)
+{
+	hotplug_reprobe_generate_remove_events (d);
+	hotplug_reprobe_generate_add_events (d);
+	hotplug_event_process_queue ();
+	return FALSE;
+}

Index: hotplug.h
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/hotplug.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- hotplug.h	18 Jan 2005 19:48:13 -0000	1.1
+++ hotplug.h	2 Feb 2005 20:44:25 -0000	1.2
@@ -29,6 +29,15 @@
 #include <glib.h>
 
 #include "util.h"
+#include "../device.h"
+
+typedef enum {
+	HOTPLUG_EVENT_SYSFS       = 0,
+	HOTPLUG_EVENT_SYSFS_BUS   = 1,
+	HOTPLUG_EVENT_SYSFS_CLASS = 2,
+	HOTPLUG_EVENT_SYSFS_BLOCK = 3,
+	HOTPLUG_EVENT_ACPI        = 4
+} HotplugEventType;
 
 /** Data structure representing a hotplug event; also used for
  *  coldplugging.
@@ -36,15 +45,29 @@
 typedef struct
 {
 	gboolean is_add;                        /**< Whether the event is add or remove */
-	char subsystem[HAL_PATH_MAX];           /**< Subsystem e.g. usb, pci (only for hotplug msg) */
-	char sysfs_path[HAL_PATH_MAX];          /**< Path into sysfs e.g. /sys/block/sda */
 
-	char wait_for_sysfs_path[HAL_PATH_MAX];	/**< Wait for completion of events that a) comes before this one; AND
-						 *   b) has a sysfs path that is contained in or equals this */
+	HotplugEventType type;                  /**< Type of hotplug event */
 
-	char device_file [HAL_PATH_MAX];        /**< Path to special device (may be NULL) */
+	union {
+		struct {
+			char subsystem[HAL_PATH_MAX];           /**< Subsystem e.g. usb, pci (only for hotplug msg) */
+			char sysfs_path[HAL_PATH_MAX];          /**< Path into sysfs e.g. /sys/block/sda */
+		
+			char wait_for_sysfs_path[HAL_PATH_MAX];	/**< Wait for completion of events that a) comes 
+								 *   before this one ; AND b) has a sysfs path that
+								 *   is contained in or equals this */
+			
+			char device_file [HAL_PATH_MAX];        /**< Path to special device file (may be NULL) */
+			
+			int net_ifindex;                        /**< For network only; the value of the ifindex file */
+		} sysfs;
+
+		struct {
+			int  acpi_type;                         /**< Type of ACPI object; see acpi.c */
+			char acpi_path[HAL_PATH_MAX];           /**< Path into procfs, e.g. /proc/acpi/battery/BAT0/ */
+		} acpi;
+	};
 
-	int net_ifindex;                        /**< For network class devices only; the value of the ifindex file */
 } HotplugEvent;
 
 void hotplug_event_enqueue (HotplugEvent *event);
@@ -53,4 +76,8 @@
 
 void hotplug_event_end (void *end_token);
 
+gboolean hotplug_rescan_device (HalDevice *d);
+
+gboolean hotplug_reprobe_tree (HalDevice *d);
+
 #endif /* HOTPLUG_H */

Index: osspec.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/osspec.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- osspec.c	1 Feb 2005 05:17:55 -0000	1.4
+++ osspec.c	2 Feb 2005 20:44:25 -0000	1.5
@@ -334,12 +334,13 @@
 
 		hotplug_event = g_new0 (HotplugEvent, 1);
 		hotplug_event->is_add = TRUE;
-		g_strlcpy (hotplug_event->subsystem, msg.subsystem, sizeof (hotplug_event->subsystem));
-		g_snprintf (hotplug_event->sysfs_path, sizeof (hotplug_event->sysfs_path), "%s%s", 
+		hotplug_event->type = HOTPLUG_EVENT_SYSFS;
+		g_strlcpy (hotplug_event->sysfs.subsystem, msg.subsystem, sizeof (hotplug_event->sysfs.subsystem));
+		g_snprintf (hotplug_event->sysfs.sysfs_path, sizeof (hotplug_event->sysfs.sysfs_path), "%s%s", 
 			    hal_sysfs_path, msg.sysfs_path);
-		g_strlcpy (hotplug_event->device_file, msg.device_name, sizeof (hotplug_event->device_file));
+		g_strlcpy (hotplug_event->sysfs.device_file, msg.device_name, sizeof (hotplug_event->sysfs.device_file));
 		/* TODO: set wait_for_sysfs_path */
-		hotplug_event->net_ifindex = msg.net_ifindex;
+		hotplug_event->sysfs.net_ifindex = msg.net_ifindex;
 
 		/* queue up and process */
 		hotplug_event_enqueue (hotplug_event);
@@ -350,12 +351,13 @@
 
 		hotplug_event = g_new0 (HotplugEvent, 1);
 		hotplug_event->is_add = FALSE;
-		g_strlcpy (hotplug_event->subsystem, msg.subsystem, sizeof (hotplug_event->subsystem));
-		g_snprintf (hotplug_event->sysfs_path, sizeof (hotplug_event->sysfs_path), "%s%s", 
+		hotplug_event->type = HOTPLUG_EVENT_SYSFS;
+		g_strlcpy (hotplug_event->sysfs.subsystem, msg.subsystem, sizeof (hotplug_event->sysfs.subsystem));
+		g_snprintf (hotplug_event->sysfs.sysfs_path, sizeof (hotplug_event->sysfs.sysfs_path), "%s%s", 
 			    hal_sysfs_path, msg.sysfs_path);
-		g_strlcpy (hotplug_event->device_file, msg.device_name, sizeof (hotplug_event->device_file));
+		g_strlcpy (hotplug_event->sysfs.device_file, msg.device_name, sizeof (hotplug_event->sysfs.device_file));
 		/* TODO: set wait_for_sysfs_path */
-		hotplug_event->net_ifindex = msg.net_ifindex;
+		hotplug_event->sysfs.net_ifindex = msg.net_ifindex;
 
 		/* queue up and process */
 		hotplug_event_enqueue (hotplug_event);
@@ -466,16 +468,15 @@
 	hal_device_store_add (hald_get_gdl (), root);
 
 	/* will enqueue hotplug events for entire system */
-	HAL_INFO (("Synthesizing events..."));
+	HAL_INFO (("Synthesizing sysfs events..."));
 	coldplug_synthesize_events ();
+	HAL_INFO (("Synthesizing acpi events..."));
+	acpi_synthesize_hotplug_events ();
 	HAL_INFO (("Done synthesizing events"));
 
 	/* start processing events */
 	hotplug_event_process_queue ();
 
-	/* ACPI */
-	acpi_probe ();
-
 	/*osspec_probe_done ();*/
 }
 
@@ -484,3 +485,15 @@
 {
 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
+
+gboolean
+osspec_device_rescan (HalDevice *d)
+{
+	return hotplug_rescan_device (d);
+}
+
+gboolean
+osspec_device_reprobe (HalDevice *d)
+{
+	return hotplug_reprobe_tree (d);
+}

Index: physdev.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/physdev.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- physdev.c	1 Feb 2005 05:57:46 -0000	1.4
+++ physdev.c	2 Feb 2005 20:44:25 -0000	1.5
@@ -855,6 +855,9 @@
 				goto out;
 			}
 
+			hal_device_property_set_int (d, "linux.hotplug_type", HOTPLUG_EVENT_SYSFS_BUS);
+			hal_device_property_set_string (d, "linux.subsystem", subsystem);
+
 			/* Add to temporary device store */
 			hal_device_store_add (hald_get_tdl (), d);
 
@@ -919,3 +922,51 @@
 out2:
 	;
 }
+
+gboolean
+physdev_rescan_device (HalDevice *d)
+{
+	return FALSE;
+}
+
+HotplugEvent *
+physdev_generate_add_hotplug_event (HalDevice *d)
+{
+	const char *subsystem;
+	const char *sysfs_path;
+	HotplugEvent *hotplug_event;
+
+	subsystem = hal_device_property_get_string (d, "linux.subsystem");
+	sysfs_path = hal_device_property_get_string (d, "linux.sysfs_path");
+
+	hotplug_event = g_new0 (HotplugEvent, 1);
+	hotplug_event->is_add = TRUE;
+	hotplug_event->type = HOTPLUG_EVENT_SYSFS;
+	g_strlcpy (hotplug_event->sysfs.subsystem, subsystem, sizeof (hotplug_event->sysfs.subsystem));
+	g_strlcpy (hotplug_event->sysfs.sysfs_path, sysfs_path, sizeof (hotplug_event->sysfs.sysfs_path));
+	hotplug_event->sysfs.device_file[0] = '\0';
+	hotplug_event->sysfs.net_ifindex = -1;
+
+	return hotplug_event;
+}
+
+HotplugEvent *
+physdev_generate_remove_hotplug_event (HalDevice *d)
+{
+	const char *subsystem;
+	const char *sysfs_path;
+	HotplugEvent *hotplug_event;
+
+	subsystem = hal_device_property_get_string (d, "linux.subsystem");
+	sysfs_path = hal_device_property_get_string (d, "linux.sysfs_path");
+
+	hotplug_event = g_new0 (HotplugEvent, 1);
+	hotplug_event->is_add = FALSE;
+	hotplug_event->type = HOTPLUG_EVENT_SYSFS;
+	g_strlcpy (hotplug_event->sysfs.subsystem, subsystem, sizeof (hotplug_event->sysfs.subsystem));
+	g_strlcpy (hotplug_event->sysfs.sysfs_path, sysfs_path, sizeof (hotplug_event->sysfs.sysfs_path));
+	hotplug_event->sysfs.device_file[0] = '\0';
+	hotplug_event->sysfs.net_ifindex = -1;
+
+	return hotplug_event;
+}

Index: physdev.h
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/physdev.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- physdev.h	18 Jan 2005 19:48:13 -0000	1.1
+++ physdev.h	2 Feb 2005 20:44:25 -0000	1.2
@@ -27,9 +27,16 @@
 #define PHYSDEV_H
 
 #include <glib.h>
+#include "hotplug.h"
 
 void hotplug_event_begin_add_physdev (const gchar *subsystem, const gchar *sysfs_path, HalDevice *parent, void *end_token);
 
 void hotplug_event_begin_remove_physdev (const gchar *subsystem, const gchar *sysfs_path, void *end_token);
 
+gboolean physdev_rescan_device (HalDevice *d);
+
+HotplugEvent *physdev_generate_add_hotplug_event (HalDevice *d);
+
+HotplugEvent *physdev_generate_remove_hotplug_event (HalDevice *d);
+
 #endif /* PHYSDEV_H */




More information about the hal-commit mailing list