summaryrefslogtreecommitdiff
path: root/hald
diff options
context:
space:
mode:
authorDavid Zeuthen <david@fubar.dk>2003-12-21 17:26:12 +0000
committerDavid Zeuthen <david@fubar.dk>2003-12-21 17:26:12 +0000
commit4b4279286f8fd6eb3466a2d05cc07c16b2e2be2a (patch)
treeb77c064fb3ebf74c04e2759351b1a80a261cfe91 /hald
parent396cbc34da2b4e92b6a765c2afa1eff99e635134 (diff)
add tools directory
fixup doxygen grouping fixup doxygen grouping Don't print out trace priority logging statements Add mount point detection by monitoring /etc and looking at /etc/mtab. Several new functions. new function Add _detection_done() method that is called when device detection (on startup of the HAL daemon) is done Call _detection_done (ospec_hotplug): Handle input being hotplugged added doxygen comments added doxygen comments added doxygen comments
Diffstat (limited to 'hald')
-rw-r--r--hald/device_store.c13
-rw-r--r--hald/device_store.h13
-rw-r--r--hald/linux/linux_class_block.c297
-rw-r--r--hald/linux/linux_class_block.h7
-rw-r--r--hald/linux/linux_class_input.c40
-rw-r--r--hald/linux/linux_class_input.h9
-rw-r--r--hald/linux/linux_class_net.c8
-rw-r--r--hald/linux/linux_class_net.h7
-rw-r--r--hald/linux/linux_class_scsi.c8
-rw-r--r--hald/linux/linux_class_scsi.h7
-rw-r--r--hald/linux/linux_ide.c8
-rw-r--r--hald/linux/linux_ide.h7
-rw-r--r--hald/linux/linux_osspec.c111
-rw-r--r--hald/linux/linux_pci.c13
-rw-r--r--hald/linux/linux_pci.h7
-rw-r--r--hald/linux/linux_usb.c36
-rw-r--r--hald/linux/linux_usb.h7
-rw-r--r--hald/logger.c5
18 files changed, 519 insertions, 84 deletions
diff --git a/hald/device_store.c b/hald/device_store.c
index 3e40e9c5..4497d4dc 100644
--- a/hald/device_store.c
+++ b/hald/device_store.c
@@ -39,10 +39,15 @@
#include "device_store.h"
/**
- * @defgroup DeviceStore HAL device store
- * @ingroup HalDaemon
- * @brief The device store is where the HAL daemon device objects are stored
- * @{
+ * @defgroup DeviceStore HAL device store
+ * @ingroup HalDaemon
+ *
+ * @todo FIXME: Right now this implementation is quite naive - should
+ * be replaced with something like hashtables etc.
+ *
+ *
+ * @brief The device store is where the device objects are stored
+ * @{
*/
/** Maximum number of callbacks inside the HAL daemon */
diff --git a/hald/device_store.h b/hald/device_store.h
index d11ef516..b3f95dd6 100644
--- a/hald/device_store.h
+++ b/hald/device_store.h
@@ -31,11 +31,11 @@
#include <dbus/dbus.h>
-
-/**************************************************************************/
-
-/* NOTE: Right now this implementation is quite naive - should be replaced
- with something like hashtables etc. */
+/**
+ * @addtogroup DeviceStore
+ *
+ * @{
+ */
/** HalProperty internals; private
*/
@@ -227,5 +227,8 @@ void ds_add_capability(HalDevice* device, const char* capability);
dbus_bool_t ds_query_capability(HalDevice* device, const char* capability);
+/**
+ * @}
+ */
#endif /* DEVICE_STORE_H */
diff --git a/hald/linux/linux_class_block.c b/hald/linux/linux_class_block.c
index b5395540..0f2624f9 100644
--- a/hald/linux/linux_class_block.c
+++ b/hald/linux/linux_class_block.c
@@ -35,6 +35,15 @@
#include <assert.h>
#include <unistd.h>
#include <stdarg.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#define _GNU_SOURCE 1
+#include <linux/fcntl.h>
+#include <linux/kdev_t.h>
+
#include "../logger.h"
#include "../device_store.h"
@@ -321,6 +330,285 @@ static void visit_class_device_block_got_parent(HalDevice* parent,
rename_and_maybe_add(d, block_compute_udi, "block");
}
+
+
+
+
+#define MOUNT_POINT_MAX 256
+#define MOUNT_POINT_STRING_SIZE 128
+
+/** Structure for holding mount point information */
+struct mount_point_s
+{
+ int major; /**< Major device number */
+ int minor; /**< Minor device number */
+ char device[MOUNT_POINT_STRING_SIZE]; /**< Device filename */
+ char mount_point[MOUNT_POINT_STRING_SIZE]; /**< Mount point */
+ char fs_type[MOUNT_POINT_STRING_SIZE]; /**< Filesystem type */
+};
+
+/** Array holding (valid) mount points from /etc/mtab. */
+static struct mount_point_s mount_points[MOUNT_POINT_MAX];
+
+/** Number of elements in #mount_points array */
+static int num_mount_points;
+
+static int etc_fd = -1;
+
+
+/** Process a line in /etc/mtab. The given string will be modifed by
+ * this function.
+ *
+ * @param s Line of /etc/mtab
+ */
+static void etc_mtab_process_line(char* s)
+{
+ int i;
+ char* p;
+ char* delim = " \t\n";
+ char buf[256];
+ char* bufp = buf;
+ struct stat stat_buf;
+ int major = 0;
+ int minor = 0;
+ char* device = NULL;
+ char* mount_point = NULL;
+ char* fs_type = NULL;
+
+ i=0;
+ p = strtok_r(s, delim, &bufp);
+ while( p!=NULL )
+ {
+ /*printf("token: '%s'\n", p);*/
+ switch(i)
+ {
+ case 0:
+ if( strcmp(p, "none")==0 )
+ return;
+ if( p[0]!='/' )
+ return;
+ device = p;
+ /* Find major/minor for this device */
+
+ if( stat(p, &stat_buf)!=0 )
+ {
+ return;
+ }
+ major = MAJOR(stat_buf.st_rdev);
+ minor = MINOR(stat_buf.st_rdev);
+ break;
+
+ case 1:
+ mount_point = p;
+ break;
+
+ case 2:
+ fs_type = p;
+ break;
+
+ case 3:
+ break;
+
+ case 4:
+ break;
+
+ case 5:
+ break;
+ }
+
+ p = strtok_r(NULL, delim, &bufp);
+ i++;
+ }
+
+ /** @todo FIXME: Use a linked list or something that doesn't restrict
+ * us like this
+ */
+ if( num_mount_points==MOUNT_POINT_MAX )
+ return;
+
+ mount_points[num_mount_points].major = major;
+ mount_points[num_mount_points].minor = minor;
+ strncpy(mount_points[num_mount_points].device, device,
+ MOUNT_POINT_STRING_SIZE);
+ strncpy(mount_points[num_mount_points].mount_point, mount_point,
+ MOUNT_POINT_STRING_SIZE);
+ strncpy(mount_points[num_mount_points].fs_type, fs_type,
+ MOUNT_POINT_STRING_SIZE);
+
+ num_mount_points++;
+}
+
+/** Last mtime when /etc/mtab was processed */
+static time_t etc_mtab_mtime = 0;
+
+
+/** Reads /etc/mtab and fill out #mount_points and #num_mount_points
+ * variables accordingly
+ *
+ * This function holds the file open for further access
+ *
+ * @return FALSE if there was no changes to /etc/mtab
+ * since last invocation or an error occured
+ */
+static dbus_bool_t read_etc_mtab()
+{
+ int fd;
+ char buf[256];
+ FILE* f;
+ struct stat stat_buf;
+
+ num_mount_points=0;
+
+ fd = open("/etc/mtab", O_RDONLY);
+
+ if( fd==-1 )
+ {
+ HAL_ERROR(("Cannot open /etc/mtab"));
+ return FALSE;
+ }
+
+ if( fstat(fd, &stat_buf)!=0 )
+ {
+ HAL_ERROR(("Cannot fstat /etc/mtab fd, errno=%d", errno));
+ return FALSE;
+ }
+
+ if( etc_mtab_mtime==stat_buf.st_mtime )
+ {
+ /*printf("No modification, etc_mtab_mtime=%d\n", etc_mtab_mtime);*/
+ return FALSE;
+ }
+
+ etc_mtab_mtime = stat_buf.st_mtime;
+
+ /*printf("Modification, etc_mtab_mtime=%d\n", etc_mtab_mtime);*/
+
+ f = fdopen(fd, "r");
+
+ if( f==NULL )
+ {
+ HAL_ERROR(("Cannot fdopen /etc/mtab fd"));
+ return FALSE;
+ }
+
+ while( !feof(f) )
+ {
+ if( fgets(buf, 256, f)==NULL )
+ break;
+ /*printf("got line: '%s'\n", buf);*/
+ etc_mtab_process_line(buf);
+ }
+
+ fclose(f);
+
+ close(fd);
+
+ return TRUE;
+}
+
+static void sigio_handler(int sig);
+
+/** Global to see if we have setup the watcher on /etc */
+static dbus_bool_t have_setup_watcher = FALSE;
+
+/** Load /etc/mtab and process all HAL block devices and set properties
+ * according to mount status. Also, optionally, sets up a watcher to do
+ * this whenever /etc/mtab changes
+ *
+ * @param setup_watcher Monitor /etc/mtab
+ */
+static void etc_mtab_process_all_block_devices()
+{
+ int i;
+ const char* bus;
+ HalDevice* d;
+ int major, minor;
+ dbus_bool_t found_mount_point;
+ struct mount_point_s* mp;
+ HalDeviceIterator diter;
+
+ /* Start or continue watching /etc */
+ if( !have_setup_watcher )
+ {
+ have_setup_watcher = TRUE;
+
+ signal(SIGIO, sigio_handler);
+ etc_fd = open("/etc", O_RDONLY);
+ fcntl(etc_fd, F_NOTIFY, DN_MODIFY|DN_MULTISHOT);
+ }
+
+ /* Just return if /etc/mtab wasn't modified */
+ if( !read_etc_mtab() )
+ return;
+
+ HAL_INFO(("/etc/mtab changed, processing all block devices"));
+
+ /* Iterate over all HAL devices */
+ for(ds_device_iter_begin(&diter);
+ ds_device_iter_has_more(&diter);
+ ds_device_iter_next(&diter))
+ {
+
+ d = ds_device_iter_get(&diter);
+
+ bus = ds_property_get_string(d, "Bus");
+ if( bus==NULL || strcmp(bus, "block")!=0 )
+ continue;
+
+ major = ds_property_get_int(d, "block.major");
+ minor = ds_property_get_int(d, "block.minor");
+
+ /* Search all mount points */
+ found_mount_point = FALSE;
+ for(i=0; i<num_mount_points; i++)
+ {
+ mp = &mount_points[i];
+
+ if( mp->major==major && mp->minor==minor )
+ {
+ HAL_INFO((
+ "%s mounted at %s, major:minor=%d:%d, fstype=%s, udi=%s",
+ mp->device, mp->mount_point, mp->major, mp->minor,
+ mp->fs_type, d->udi));
+
+ /* Yay! Found a mount point; set properties accordingly */
+ ds_property_set_string(d, "block.device", mp->device);
+ ds_property_set_string(d, "block.mountPoint", mp->mount_point);
+ ds_property_set_string(d, "block.fileSystem", mp->fs_type);
+ ds_property_set_bool(d, "block.isMounted", TRUE);
+
+ found_mount_point = TRUE;
+ break;
+ }
+ }
+
+ /* No mount point found; (possibly) remove all information */
+ if( !found_mount_point )
+ {
+ ds_property_set_bool(d, "block.isMounted", FALSE);
+ ds_property_remove(d, "block.mountPoint");
+ ds_property_remove(d, "block.fileSystem");
+ }
+ }
+}
+
+
+/** Signal handler for watching /etc
+ *
+ * @param sig Signal number
+ */
+static void sigio_handler(int sig)
+{
+ HAL_INFO(("Directory /etc changed"));
+
+ /** @todo FIXME: It's evil to sleep in a signal handler, yes? */
+ usleep(250*1000);
+
+ etc_mtab_process_all_block_devices(TRUE);
+}
+
+
+
/** Init function for block device handling
*
*/
@@ -328,6 +616,15 @@ void linux_class_block_init()
{
}
+/** This function is called when all device detection on startup is done
+ * in order to perform optional batch processing on devices
+ *
+ */
+void linux_class_block_detection_done()
+{
+ etc_mtab_process_all_block_devices();
+}
+
/** Shutdown function for block device handling
*
*/
diff --git a/hald/linux/linux_class_block.h b/hald/linux/linux_class_block.h
index 0f81690a..57e3db5e 100644
--- a/hald/linux/linux_class_block.h
+++ b/hald/linux/linux_class_block.h
@@ -28,16 +28,11 @@
#include "linux_common.h"
-/* @ingroup HalAgentsLinux
- * @{
- */
-
void visit_class_device_block(const char* path,
struct sysfs_class_device *class_device);
void linux_class_block_init();
+void linux_class_block_detection_done();
void linux_class_block_shutdown();
-/* @} */
-
#endif /* LINUX_CLASS_BLOCK_H */
diff --git a/hald/linux/linux_class_input.c b/hald/linux/linux_class_input.c
index 363a15ed..38923d04 100644
--- a/hald/linux/linux_class_input.c
+++ b/hald/linux/linux_class_input.c
@@ -626,6 +626,38 @@ void linux_class_input_probe()
process_input_proc_info(i);
}
+
+/** Handle input hotplug event add
+ *
+ * @param name $NAME from hotplug event
+ * @param phys $PHYS from hotplug event
+ * @param key $KEY from hotplug event
+ * @param ev $EV from hotplug event (or 0 if not found)
+ * @param rel $REL from hotplug event (or 0 if not found)
+ * @param abs $ABS from hotplug event (or 0 if not found)
+ * @param led $LED from hotplug event (or 0 if not found)
+ */
+void linux_class_input_handle_hotplug_add(char* name, char* phys, char* key,
+ int ev, int rel, int abs, int led)
+{
+ char* s;
+ input_proc_info* i;
+
+ i = get_input_proc_cur_info_obj();
+
+ /** @todo FIXME; parse product (we don't use it yet) */
+
+ strncpy(i->name, name, 128);
+ strncpy(i->phys_name, phys, 128);
+ strncpy(i->keybit, key, 128);
+ i->evbit = ev;
+ i->relbit = rel;
+ i->absbit = abs;
+ i->ledbit = led;
+
+ process_input_proc_info(i);
+}
+
/** Init function for block device handling
*
*/
@@ -633,6 +665,14 @@ void linux_class_input_init()
{
}
+/** This function is called when all device detection on startup is done
+ * in order to perform optional batch processing on devices
+ *
+ */
+void linux_class_input_detection_done()
+{
+}
+
/** Shutdown function for block device handling
*
*/
diff --git a/hald/linux/linux_class_input.h b/hald/linux/linux_class_input.h
index 027a83cc..4f9291d7 100644
--- a/hald/linux/linux_class_input.h
+++ b/hald/linux/linux_class_input.h
@@ -28,15 +28,14 @@
#include "linux_common.h"
-/* @ingroup HalAgentsLinux
- * @{
- */
-
void linux_class_input_probe();
void linux_class_input_init();
+void linux_class_input_detection_done();
void linux_class_input_shutdown();
-/* @} */
+void linux_class_input_handle_hotplug_add(char* name, char* phys, char* key,
+ int ev, int rel, int abs, int led);
+
#endif /* LINUX_CLASS_INPUT_H */
diff --git a/hald/linux/linux_class_net.c b/hald/linux/linux_class_net.c
index a84985fa..8242631b 100644
--- a/hald/linux/linux_class_net.c
+++ b/hald/linux/linux_class_net.c
@@ -530,6 +530,14 @@ void linux_class_net_init()
ds_add_cb_gdl_changed(gdl_changed);
}
+/** This function is called when all device detection on startup is done
+ * in order to perform optional batch processing on devices
+ *
+ */
+void linux_class_net_detection_done()
+{
+}
+
/** Shutdown function for block device handling
*
*/
diff --git a/hald/linux/linux_class_net.h b/hald/linux/linux_class_net.h
index 0cee4c14..51bc4994 100644
--- a/hald/linux/linux_class_net.h
+++ b/hald/linux/linux_class_net.h
@@ -28,16 +28,11 @@
#include "linux_common.h"
-/* @ingroup HalAgentsLinux
- * @{
- */
-
void visit_class_device_net(const char* path,
struct sysfs_class_device *class_device);
void linux_class_net_init();
+void linux_class_net_detection_done();
void linux_class_net_shutdown();
-/* @} */
-
#endif /* LINUX_CLASS_NET_H */
diff --git a/hald/linux/linux_class_scsi.c b/hald/linux/linux_class_scsi.c
index ba9bd1d2..5254c9d2 100644
--- a/hald/linux/linux_class_scsi.c
+++ b/hald/linux/linux_class_scsi.c
@@ -301,6 +301,14 @@ void linux_class_scsi_init()
{
}
+/** This function is called when all device detection on startup is done
+ * in order to perform optional batch processing on devices
+ *
+ */
+void linux_class_scsi_detection_done()
+{
+}
+
/** Shutdown function for SCSI handling
*
*/
diff --git a/hald/linux/linux_class_scsi.h b/hald/linux/linux_class_scsi.h
index c3397a60..54b8d0fb 100644
--- a/hald/linux/linux_class_scsi.h
+++ b/hald/linux/linux_class_scsi.h
@@ -28,10 +28,6 @@
#include "linux_common.h"
-/* @ingroup HalAgentsLinux
- * @{
- */
-
void visit_class_device_scsi_host(const char* path,
struct sysfs_class_device *class_device);
@@ -39,8 +35,7 @@ void visit_class_device_scsi_device(const char* path,
struct sysfs_class_device *class_device);
void linux_class_scsi_init();
+void linux_class_scsi_detection_done();
void linux_class_scsi_shutdown();
-/* @} */
-
#endif /* LINUX_CLASS_SCSI_H */
diff --git a/hald/linux/linux_ide.c b/hald/linux/linux_ide.c
index a27a4605..6eda1fa0 100644
--- a/hald/linux/linux_ide.c
+++ b/hald/linux/linux_ide.c
@@ -276,6 +276,14 @@ void linux_ide_init()
{
}
+/** This function is called when all device detection on startup is done
+ * in order to perform optional batch processing on devices
+ *
+ */
+void linux_ide_detection_done()
+{
+}
+
/** Shutdown function for IDE handling
*
*/
diff --git a/hald/linux/linux_ide.h b/hald/linux/linux_ide.h
index a2f1d6da..0d15ce12 100644
--- a/hald/linux/linux_ide.h
+++ b/hald/linux/linux_ide.h
@@ -28,17 +28,12 @@
#include "linux_common.h"
-/* @ingroup HalAgentsLinux
- * @{
- */
-
void visit_device_ide_host(const char* path, struct sysfs_device *device);
void visit_device_ide(const char* path, struct sysfs_device *device);
void linux_ide_init();
+void linux_ide_detection_done();
void linux_ide_shutdown();
-/* @} */
-
#endif /* LINUX_IDE_H */
diff --git a/hald/linux/linux_osspec.c b/hald/linux/linux_osspec.c
index ca8ec5c0..fea372b6 100644
--- a/hald/linux/linux_osspec.c
+++ b/hald/linux/linux_osspec.c
@@ -233,10 +233,6 @@ void osspec_init(DBusConnection* dbus_connection)
linux_class_scsi_init();
linux_class_block_init();
linux_class_net_init();
-
- /* input devices are not yet in sysfs */
- linux_class_input_probe();
-
}
/** This is set to #TRUE if we are probing and #FALSE otherwise */
@@ -285,25 +281,52 @@ void osspec_probe()
/* visit all net devices */
visit_class("net", TRUE);
- /* Find the input devices (no yet in sysfs) */
- //hal_input_probe();
-
- /* Process /etc/mtab and modify block devices we indeed have mounted
- * (dont set up the watcher)
- */
- //etc_mtab_process_all_block_devices(FALSE);
+ /* input devices are not yet in sysfs */
+ linux_class_input_probe();
is_probing = FALSE;
+
+ /* Notify various device and class types that detection is done, so
+ * they can do some (optional) batch processing
+ */
+ linux_pci_detection_done();
+ linux_usb_detection_done();
+ linux_ide_detection_done();
+ linux_class_block_detection_done();
+ linux_class_input_detection_done();
+ linux_class_net_detection_done();
+ linux_class_scsi_detection_done();
}
+/** Maximum length of string parameter in hotplug input events */
+#define HOTPLUG_INPUT_MAX 128
+
+/** Handle a org.freedesktop.Hal.HotplugEvent message. This message
+ * origins from the hal.hotplug program, tools/linux/hal_hotplug.c,
+ * and is basically just a D-BUS-ification of the hotplug event.
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
static DBusHandlerResult osspec_hotplug(DBusConnection* connection,
DBusMessage* message)
{
DBusMessageIter iter;
DBusMessageIter dict_iter;
+ dbus_bool_t is_add;
char* subsystem;
+ char input_name[HOTPLUG_INPUT_MAX];
+ char input_phys[HOTPLUG_INPUT_MAX];
+ char input_key[HOTPLUG_INPUT_MAX];
+ int input_ev=0;
+ int input_rel=0;
+ int input_abs=0;
+ int input_led=0;
char sysfs_devpath[SYSFS_PATH_MAX];
- dbus_bool_t is_add;
+
+ sysfs_devpath[0] = '\0';
+ input_name[0] = input_phys[0] = input_key[0] = '\0';
dbus_message_iter_init(message, &iter);
@@ -318,8 +341,6 @@ static DBusHandlerResult osspec_hotplug(DBusConnection* connection,
dbus_message_iter_next(&iter);
dbus_message_iter_init_dict_iterator(&iter, &dict_iter);
- /*printf("subsystem = %s\n", subsystem);*/
-
is_add = FALSE;
for( ;dbus_message_iter_has_next(&dict_iter);
@@ -340,21 +361,38 @@ static DBusHandlerResult osspec_hotplug(DBusConnection* connection,
is_add = TRUE;
}
}
-
- if( strcmp(key, "DEVPATH")==0 )
+ else if( strcmp(key, "DEVPATH")==0 )
{
strncpy(sysfs_devpath, sysfs_mount_path, SYSFS_PATH_MAX);
strncat(sysfs_devpath, value, SYSFS_PATH_MAX);
}
+ else if( strcmp(key, "NAME")==0 )
+ strncpy(input_name, value, HOTPLUG_INPUT_MAX);
+ else if( strcmp(key, "PHYS")==0 )
+ strncpy(input_phys, value, HOTPLUG_INPUT_MAX);
+ else if( strcmp(key, "KEY")==0 )
+ strncpy(input_key, value, HOTPLUG_INPUT_MAX);
+ else if( strcmp(key, "EV")==0 )
+ input_ev = parse_dec(value);
+ else if( strcmp(key, "REL")==0 )
+ input_rel = parse_hex(value);
+ else if( strcmp(key, "ABS")==0 )
+ input_abs = parse_hex(value);
+ else if( strcmp(key, "LED")==0 )
+ input_led = parse_hex(value);
}
- if( sysfs_devpath!=NULL &&
+ HAL_INFO(("HotplugEvent %s, subsystem=%s",
+ (is_add ? "add" : "remove"), subsystem));
+
+ if( sysfs_devpath[0]!='\0' &&
(strcmp(subsystem, "usb")==0 ||
strcmp(subsystem, "pci")==0) )
{
+
if( is_add )
{
- HAL_INFO(("Adding device @ sysfspath %s\n", sysfs_devpath));
+ HAL_INFO(("Adding device @ sysfspath %s", sysfs_devpath));
visit_device(sysfs_devpath, FALSE);
}
else
@@ -370,20 +408,21 @@ static DBusHandlerResult osspec_hotplug(DBusConnection* connection,
}
else
{
+ HAL_INFO(("Removing device @ sysfspath %s, udi %s",
+ sysfs_devpath, d->udi));
ds_device_destroy(d);
}
}
}
-
- if( sysfs_devpath!=NULL &&
- (strcmp(subsystem, "net")==0 ||
- strcmp(subsystem, "block")==0 ||
- strcmp(subsystem, "scsi_host")==0 ||
- strcmp(subsystem, "scsi_device")==0) )
+ else if( sysfs_devpath[0]!='\0' &&
+ (strcmp(subsystem, "net")==0 ||
+ strcmp(subsystem, "block")==0 ||
+ strcmp(subsystem, "scsi_host")==0 ||
+ strcmp(subsystem, "scsi_device")==0) )
{
if( is_add )
{
- HAL_INFO(("Adding device @ sysfspath %s\n", sysfs_devpath));
+ HAL_INFO(("Adding classdevice @ sysfspath %s", sysfs_devpath));
visit_class_device(sysfs_devpath, FALSE);
}
else
@@ -398,10 +437,32 @@ static DBusHandlerResult osspec_hotplug(DBusConnection* connection,
}
else
{
+ HAL_INFO(("Removing classdevice @ sysfspath %s, udi %s",
+ sysfs_devpath, d->udi));
ds_device_destroy(d);
}
}
}
+ else if( strcmp(subsystem, "input")==0 )
+ {
+ if( is_add )
+ {
+ /** @todo FIXME when kernel 2.6 got input devices in sysfs
+ * this terrible hack can be removed
+ */
+ linux_class_input_handle_hotplug_add(input_name, input_phys,
+ input_key,
+ input_ev, input_rel,
+ input_abs, input_led);
+ }
+ else
+ {
+ /* This block is left intentionally blank, since input class
+ * devices simply attach to other (physical) devices and when
+ * they disappear, the input part also goes away
+ */
+ }
+ }
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
diff --git a/hald/linux/linux_pci.c b/hald/linux/linux_pci.c
index b780abd7..fdcc0c36 100644
--- a/hald/linux/linux_pci.c
+++ b/hald/linux/linux_pci.c
@@ -378,7 +378,7 @@ static void pci_add_caps_from_class(HalDevice* d,
int dev_sub_class,
int dev_proto)
{
- char* cat = "unknown";
+ char* cat = NULL;
switch( dev_class )
{
@@ -642,7 +642,8 @@ static void pci_add_caps_from_class(HalDevice* d,
break;
}
- ds_property_set_string(d, "Category", cat);
+ if( cat!=NULL )
+ ds_property_set_string(d, "Category", cat);
}
@@ -828,6 +829,14 @@ void linux_pci_init()
pci_ids_load(HWDATA_DIR "/pci.ids");
}
+/** This function is called when all device detection on startup is done
+ * in order to perform optional batch processing on devices
+ *
+ */
+void linux_pci_detection_done()
+{
+}
+
/** Shutdown function for PCI handling
*
*/
diff --git a/hald/linux/linux_pci.h b/hald/linux/linux_pci.h
index 6e088af1..4bd4bcc0 100644
--- a/hald/linux/linux_pci.h
+++ b/hald/linux/linux_pci.h
@@ -28,15 +28,10 @@
#include "linux_common.h"
-/* @ingroup HalAgentsLinux
- * @{
- */
-
void visit_device_pci(const char* path, struct sysfs_device *device);
void linux_pci_init();
+void linux_pci_detection_done();
void linux_pci_shutdown();
-/* @} */
-
#endif /* LINUX_PCI_H */
diff --git a/hald/linux/linux_usb.c b/hald/linux/linux_usb.c
index 82be8d3a..175f8484 100644
--- a/hald/linux/linux_usb.c
+++ b/hald/linux/linux_usb.c
@@ -578,20 +578,20 @@ static char* usb_compute_udi(HalDevice* d, int append_num)
}
-/** Set capabilities from interface class. This is a function from hell,
- * maybe some searchable data-structure would be better...
+/** Set capabilities from interface and/or device class. This is a
+ * function from hell, maybe some searchable data-structure would be
+ * better...
*
* @param d The HalDevice to set the caps
* @param if_class Interface class
* @param if_sub_class Interface sub class
- * @param if_proto Interface protocol
- */
+ * @param if_proto Interface protocol */
static void usb_add_caps_from_class(HalDevice* d,
int if_class,
int if_sub_class,
int if_proto)
{
- char* cat = "unknown";
+ char* cat = NULL;
switch( if_class )
{
@@ -649,9 +649,17 @@ static void usb_add_caps_from_class(HalDevice* d,
break;
case 0x0a:
break;
+ case 0xe0:
+ if( if_sub_class==0x01 && if_proto==0x01 )
+ {
+ cat = "bluetooth_adaptor";
+ ds_add_capability(d, "bluetooth_adaptor");
+ }
+ break;
}
- ds_property_set_string(d, "Category", cat);
+ if( cat!=NULL )
+ ds_property_set_string(d, "Category", cat);
}
@@ -980,6 +988,13 @@ void visit_device_usb(const char* path, struct sysfs_device *device)
ds_property_set_string(d, "Product", numeric_name);
}
+
+ /* Check device class */
+ usb_add_caps_from_class(d,
+ ds_property_get_int(d, "usb.bDeviceClass"),
+ ds_property_get_int(d, "usb.bDeviceSubClass"),
+ ds_property_get_int(d, "usb.bDeviceProtocol"));
+
parent_sysfs_path = get_parent_sysfs_path(path);
/* Find parent; this happens asynchronously as our parent might
@@ -1208,6 +1223,15 @@ void linux_usb_init()
usb_proc_parse();
}
+/** This function is called when all device detection on startup is done
+ * in order to perform optional batch processing on devices
+ *
+ */
+void linux_usb_detection_done()
+{
+}
+
+
/** Shutdown function for USB handling
*
*/
diff --git a/hald/linux/linux_usb.h b/hald/linux/linux_usb.h
index f4d085cf..02ddc7d5 100644
--- a/hald/linux/linux_usb.h
+++ b/hald/linux/linux_usb.h
@@ -28,15 +28,10 @@
#include "linux_common.h"
-/* @ingroup HalAgentsLinux
- * @{
- */
-
void visit_device_usb(const char* path, struct sysfs_device *device);
void linux_usb_init();
+void linux_usb_detection_done();
void linux_usb_shutdown();
-/* @} */
-
#endif /* LINUX_USB_H */
diff --git a/hald/logger.c b/hald/logger.c
index 59d335bc..21f28642 100644
--- a/hald/logger.c
+++ b/hald/logger.c
@@ -94,7 +94,10 @@ void logger_emit(const char* format,...)
case HAL_LOGPRI_ERROR: pri="[E]"; break;
}
- fprintf(stderr, "%s %s:%d %s() : %s\n", pri, file, line, function, buf);
+ /** @todo Make programmatic interface to logging */
+ if( priority!=HAL_LOGPRI_TRACE )
+ fprintf(stderr, "%s %s:%d %s() : %s\n",
+ pri, file, line, function, buf);
va_end(args);
}