1 /***************************************************************************
3 * hotplug.c : HAL-internal hotplug events
5 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
6 * Use is subject to license terms.
8 * Licensed under the Academic Free License version 2.1
10 **************************************************************************/
20 #include <sys/types.h>
23 #include <sys/utsname.h>
27 #include <dbus/dbus.h>
28 #include <dbus/dbus-glib.h>
30 #include "../osspec.h"
31 #include "../logger.h"
33 #include "../device_info.h"
35 #include "osspec_solaris.h"
39 /** Queue of ordered hotplug events */
40 GQueue
*hotplug_event_queue
;
42 /** List of HotplugEvent objects we are currently processing */
43 GSList
*hotplug_events_in_progress
= NULL
;
45 static void hotplug_event_begin (HotplugEvent
*hotplug_event
);
48 hotplug_event_end (void *end_token
)
50 HotplugEvent
*hotplug_event
= (HotplugEvent
*) end_token
;
52 hotplug_events_in_progress
= g_slist_remove (hotplug_events_in_progress
, hotplug_event
);
53 g_free (hotplug_event
);
54 hotplug_event_process_queue ();
58 hotplug_event_begin_devfs_add (HotplugEvent
*hotplug_event
, HalDevice
*d
)
61 const gchar
*parent_udi
;
62 void (*begin_add_func
) (HalDevice
*, HalDevice
*, DevinfoDevHandler
*, void *);
66 HAL_ERROR (("devpath %s already present in store, ignore event", hotplug_event
->un
.devfs
.devfs_path
));
72 parent_udi
= hal_device_property_get_string (hotplug_event
->d
, "info.parent");
73 if (parent_udi
== NULL
|| strlen(parent_udi
) == 0) {
76 parent
= hal_device_store_match_key_value_string (hald_get_gdl (), "info.udi", parent_udi
);
78 /* only root node is allowed to be orphan */
80 if (strcmp(hotplug_event
->un
.devfs
.devfs_path
, "/") != 0) {
81 HAL_ERROR (("Parent is NULL devfs_path=%s parent_udi=%s", hotplug_event
->un
.devfs
.devfs_path
, parent_udi
? parent_udi
: "<null>"));
87 /* children of ignored parent should be ignored */
88 if (parent
!= NULL
&& hal_device_property_get_bool (parent
, "info.ignore")) {
89 HAL_INFO (("parent ignored %s", parent_udi
));
94 /* custom or generic add function */
95 begin_add_func
= hotplug_event
->un
.devfs
.handler
->hotplug_begin_add
;
96 if (begin_add_func
== NULL
) {
97 begin_add_func
= hotplug_event_begin_add_devinfo
;
99 begin_add_func (hotplug_event
->d
,
101 hotplug_event
->un
.devfs
.handler
,
102 (void *) hotplug_event
);
106 g_object_unref (hotplug_event
->d
);
107 hotplug_event_end ((void *) hotplug_event
);
113 hotplug_event_begin_devfs_remove (HotplugEvent
*hotplug_event
, HalDevice
*d
)
116 HAL_ERROR (("devpath %s not present in store, ignore event", hotplug_event
->un
.devfs
.devfs_path
));
117 hotplug_event_end ((void *) hotplug_event
);
120 HAL_INFO (("hotplug_event_begin_devfs_remove %s", hal_device_get_udi (d
)));
122 hotplug_event_begin_remove_devinfo(d
,
123 hotplug_event
->un
.devfs
.devfs_path
,
124 (void *) hotplug_event
);
128 hotplug_event_begin_devfs (HotplugEvent
*hotplug_event
)
132 HAL_INFO (("hotplug_event_begin_devfs: %s", hotplug_event
->un
.devfs
.devfs_path
));
133 d
= hal_device_store_match_key_value_string (hald_get_gdl (),
134 "solaris.devfs_path",
135 hotplug_event
->un
.devfs
.devfs_path
);
137 if (hotplug_event
->action
== HOTPLUG_ACTION_ADD
) {
138 hotplug_event_begin_devfs_add (hotplug_event
, d
);
139 } else if (hotplug_event
->action
== HOTPLUG_ACTION_REMOVE
) {
140 hotplug_event_begin_devfs_remove (hotplug_event
, d
);
142 HAL_ERROR (("unsupported action %d", hotplug_event
->action
));
143 g_object_unref (hotplug_event
->d
);
144 hotplug_event_end ((void *) hotplug_event
);
149 hotplug_event_begin (HotplugEvent
*hotplug_event
)
151 switch (hotplug_event
->type
) {
153 case HOTPLUG_EVENT_DEVFS
:
154 hotplug_event_begin_devfs (hotplug_event
);
158 HAL_ERROR (("Unknown hotplug event type %d", hotplug_event
->type
));
159 g_object_unref (hotplug_event
->d
);
160 hotplug_event_end ((void *) hotplug_event
);
166 hotplug_event_enqueue (HotplugEvent
*hotplug_event
, int front
)
168 if (hotplug_event_queue
== NULL
)
169 hotplug_event_queue
= g_queue_new ();
172 g_queue_push_head (hotplug_event_queue
, hotplug_event
);
174 g_queue_push_tail (hotplug_event_queue
, hotplug_event
);
179 hotplug_event_process_queue (void)
181 HotplugEvent
*hotplug_event
;
183 if (hotplug_events_in_progress
== NULL
&&
184 (hotplug_event_queue
== NULL
|| g_queue_is_empty (hotplug_event_queue
))) {
185 hotplug_queue_now_empty ();
189 /* do not process events if some other event is in progress */
190 if (hotplug_events_in_progress
!= NULL
&& g_slist_length (hotplug_events_in_progress
) > 0)
193 hotplug_event
= g_queue_pop_head (hotplug_event_queue
);
194 if (hotplug_event
== NULL
)
197 hotplug_events_in_progress
= g_slist_append (hotplug_events_in_progress
, hotplug_event
);
198 hotplug_event_begin (hotplug_event
);