18c2aff776a775d34a4c9893a4c72e0434d68e36artem/***************************************************************************
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * devinfo.c : main file for libdevinfo-based device enumeration
506aa7c68b127eefb0197e329af7e9abcc3ebc98Garrett D'Amore * Copyright 2013 Garrett D'Amore <garrett@damore.org>
3f7d54a6b84904c8f4d8daa4c7b577bede7df8b9Garrett D'Amore * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Licensed under the Academic Free License version 2.1
18c2aff776a775d34a4c9893a4c72e0434d68e36artem **************************************************************************/
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../osspec.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../logger.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../hald.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../hald_dbus.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../util.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artemvoid devinfo_add_subtree(HalDevice *parent, di_node_t node, gboolean is_root);
18c2aff776a775d34a4c9893a4c72e0434d68e36artemHalDevice *devinfo_add_node(HalDevice *parent, di_node_t node);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((root = di_init(path, DINFOCACHE)) == DI_NODE_NIL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((root = di_init(path, DINFOCPYALL)) == DI_NODE_NIL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdevinfo_add_subtree(HalDevice *parent, di_node_t node, gboolean is_root)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((d != NULL) &&
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdevinfo_set_default_properties (HalDevice *d, HalDevice *parent, di_node_t node, char *devfs_path)
00687e57f8c568d4f8fb446b6530a2942842292fartem hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/local");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (di_prop_lookup_strings (DDI_DEV_T_ANY, node, "model", &s) > 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hal_device_property_set_string (d, "info.product", s);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hal_device_property_set_string (d, "info.product", di_node_name (node));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hal_device_property_set_string (d, "solaris.devfs_path", devfs_path);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hal_device_property_set_string (d, "info.solaris.driver",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* inherit parent's claim attributes */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hal_device_property_get_bool (parent, "info.claimed")) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem s1 = hal_device_property_get_string (parent, "info.claimed.service");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hal_device_property_set_bool (d, "info.claimed", TRUE);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hal_device_property_set_string (d, "info.claimed.service", s1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/* device handlers, ordered specific to generic */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) di_prop_lookup_strings (DDI_DEV_T_ANY, node, "device_type",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem for (i = 0; (d == NULL) && (devinfo_handlers[i] != NULL); i++) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem d = handler->add (parent, node, devfs_path, device_type);
00687e57f8c568d4f8fb446b6530a2942842292fartem HAL_INFO (("add_node: %s", d ? hal_device_get_udi (d) : "none"));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (d);
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdevinfo_hotplug_enqueue(HalDevice *d, gchar *devfs_path, DevinfoDevHandler *handler, int action, int front)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem strlcpy (hotplug_event->un.devfs.devfs_path, devfs_path,
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdevinfo_add_enqueue(HalDevice *d, gchar *devfs_path, DevinfoDevHandler *handler)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem devinfo_hotplug_enqueue (d, devfs_path, handler, HOTPLUG_ACTION_ADD, 0);
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdevinfo_add_enqueue_at_front(HalDevice *d, gchar *devfs_path, DevinfoDevHandler *handler)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem devinfo_hotplug_enqueue (d, devfs_path, handler, HOTPLUG_ACTION_ADD, 1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdevinfo_remove_enqueue(gchar *devfs_path, DevinfoDevHandler *handler)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem devinfo_hotplug_enqueue (NULL, devfs_path, handler, HOTPLUG_ACTION_REMOVE, 0);
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdevinfo_callouts_add_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Move from temporary to global device store */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdevinfo_callouts_probing_done (HalDevice *d, guint32 exit_type, gint return_code, char **error, gpointer userdata1, gpointer userdata2)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Discard device if probing reports failure */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (exit_type != HALD_RUN_SUCCESS || (return_code != 0)) {
00687e57f8c568d4f8fb446b6530a2942842292fartem HAL_INFO (("Probing for %s failed %d", hal_device_get_udi (d), return_code));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Merge properties from .fdi files */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem di_search_and_merge (d, DEVICE_INFO_TYPE_INFORMATION);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hal_util_callout_device_add (d, devinfo_callouts_add_done, end_token, NULL);
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdevinfo_callouts_preprobing_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem DevinfoDevHandler *handler = (DevinfoDevHandler *) userdata2;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem void (*probing_done) (HalDevice *, guint32, gint, char **, gpointer, gpointer);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hal_device_property_get_bool (d, "info.ignore")) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Leave device with info.ignore==TRUE so we won't pick up children */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* probe the device */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/* This is the beginning of hotplug even handling */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhotplug_event_begin_add_devinfo (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token)
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems HotplugEvent *hotplug_event = (HotplugEvent *)end_token;
00687e57f8c568d4f8fb446b6530a2942842292fartem HAL_INFO(("Preprobing udi=%s", hal_device_get_udi (d)));
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems if (parent == NULL && (strcmp(hotplug_event->un.devfs.devfs_path, "/") != 0)) {
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems HAL_ERROR (("Parent is NULL, devfs_path=%s", hotplug_event->un.devfs.devfs_path));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (parent != NULL && hal_device_property_get_bool (parent, "info.ignore")) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_INFO (("Ignoring device since parent has info.ignore==TRUE"));
112cd14a18db3bd3fac4ff92c4117b51ddd339abqz if (hal_device_store_find (hald_get_tdl (), hal_device_get_udi (d)) == NULL) {
112cd14a18db3bd3fac4ff92c4117b51ddd339abqz /* add to TDL so preprobing callouts and prober can access it */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Process preprobe fdi files */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Run preprobe callouts */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hal_util_callout_device_preprobe (d, devinfo_callouts_preprobing_done, end_token, handler);
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems if (hal_device_store_find (hald_get_tdl (), hal_device_get_udi (d)))
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems hal_device_store_remove (hald_get_tdl (), d);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/* generate hotplug event for each device in this branch */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdevinfo_remove_branch (gchar *devfs_path, HalDevice *d)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (d == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem d = hal_device_store_match_key_value_string (hald_get_gdl (),
00687e57f8c568d4f8fb446b6530a2942842292fartem HAL_INFO (("remove_branch: %s %s\n", devfs_path, hal_device_get_udi (d)));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* first remove children */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem children = hal_device_store_match_multiple_key_value_string (hald_get_gdl(),
00687e57f8c568d4f8fb446b6530a2942842292fartem HAL_INFO (("remove_branch: child %s\n", hal_device_get_udi (child)));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem devinfo_remove_branch ((gchar *)hal_device_property_get_string (child, "solaris.devfs_path"), child);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* then remove self */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_INFO (("remove_branch: queueing %s", devfs_path));
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdevinfo_callouts_remove_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
00687e57f8c568d4f8fb446b6530a2942842292fartem HAL_INFO (("Remove callouts completed udi=%s", hal_device_get_udi (d)));
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhotplug_event_begin_remove_devinfo (HalDevice *d, gchar *devfs_path, void *end_token)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem devinfo_volume_hotplug_begin_remove (d, devfs_path, end_token);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hal_util_callout_device_remove (d, devinfo_callouts_remove_done, end_token, NULL);
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran } else if (hal_device_has_capability (d, "button")) {