1 /***************************************************************************
2  *
3  * devinfo_misc : misc devices
4  *
5  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
6  * Use is subject to license terms.
7  *
8  * Licensed under the Academic Free License version 2.1
9  *
10  **************************************************************************/
11 
12 #pragma ident	"%Z%%M%	%I%	%E% SMI"
13 
14 #ifdef HAVE_CONFIG_H
15 #  include <config.h>
16 #endif
17 
18 #include <stdio.h>
19 #include <string.h>
20 #include <sys/utsname.h>
21 #include <libdevinfo.h>
22 #include <sys/uadmin.h>
23 
24 #include "../osspec.h"
25 #include "../logger.h"
26 #include "../hald.h"
27 #include "../hald_dbus.h"
28 #include "../device_info.h"
29 #include "../util.h"
30 #include "devinfo_misc.h"
31 
32 static HalDevice *devinfo_computer_add(HalDevice *, di_node_t, char *, char *);
33 static HalDevice *devinfo_cpu_add(HalDevice *, di_node_t, char *, char *);
34 static HalDevice *devinfo_keyboard_add(HalDevice *, di_node_t, char *, char *);
35 static HalDevice *devinfo_default_add(HalDevice *, di_node_t, char *, char *);
36 
37 DevinfoDevHandler devinfo_computer_handler = {
38 	devinfo_computer_add,
39 	NULL,
40 	NULL,
41 	NULL,
42 	NULL,
43 	NULL
44 };
45 DevinfoDevHandler devinfo_cpu_handler = {
46 	devinfo_cpu_add,
47 	NULL,
48 	NULL,
49 	NULL,
50 	NULL,
51 	NULL
52 };
53 DevinfoDevHandler devinfo_keyboard_handler = {
54 	devinfo_keyboard_add,
55 	NULL,
56 	NULL,
57 	NULL,
58 	NULL,
59 	NULL
60 };
61 DevinfoDevHandler devinfo_default_handler = {
62 	devinfo_default_add,
63 	NULL,
64 	NULL,
65 	NULL,
66 	NULL,
67 	NULL
68 };
69 
70 static HalDevice *
71 devinfo_computer_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
72 {
73 	HalDevice *d, *local_d;
74 	struct utsname un;
75 
76 	if (strcmp (devfs_path, "/") != 0) {
77 		return (NULL);
78 	}
79 
80 	d = hal_device_new ();
81 
82 	hal_device_property_set_string (d, "info.subsystem", "unknown");
83 	hal_device_property_set_string (d, "info.product", "Computer");
84 	hal_device_property_set_string (d, "info.udi", "/org/freedesktop/Hal/devices/computer");
85 	hal_device_set_udi (d, "/org/freedesktop/Hal/devices/computer");
86 	hal_device_property_set_string (d, "solaris.devfs_path", devfs_path);
87 
88 	if (uname (&un) >= 0) {
89 		hal_device_property_set_string (d, "system.kernel.name", un.sysname);
90 		hal_device_property_set_string (d, "system.kernel.version", un.release);
91 		hal_device_property_set_string (d, "system.kernel.machine", un.machine);
92 	}
93 
94 	hal_device_property_set_bool(d, "power_management.can_hibernate",
95 	    (uadmin(A_FREEZE, AD_CHECK_SUSPEND_TO_DISK, 0) == 0));
96 	hal_device_property_set_bool(d, "power_management.can_suspend",
97 	    (uadmin(A_FREEZE, AD_CHECK_SUSPEND_TO_RAM, 0) == 0));
98 
99 	hal_device_add_capability(d, "button");
100 
101 	/*
102 	 * Let computer be in TDL while synthesizing all other events
103 	 * because some may write to the object
104 	 */
105 	hal_device_store_add (hald_get_tdl (), d);
106 
107 	devinfo_add_enqueue (d, devfs_path, &devinfo_computer_handler);
108 
109 	/* all devinfo devices belong to the 'local' branch */
110 	local_d = hal_device_new ();
111 
112 	hal_device_property_set_string (local_d, "info.parent", hal_device_get_udi (d));
113 	hal_device_property_set_string (local_d, "info.subsystem", "unknown");
114 	hal_device_property_set_string (local_d, "info.product", "Local devices");
115 	hal_device_property_set_string (local_d, "info.udi", "/org/freedesktop/Hal/devices/local");
116 	hal_device_set_udi (local_d, "/org/freedesktop/Hal/devices/local");
117 	hal_device_property_set_string (local_d, "solaris.devfs_path", "/local");
118 
119 	devinfo_add_enqueue (local_d, "/local", &devinfo_default_handler);
120 
121 	return (local_d);
122 }
123 
124 static HalDevice *
125 devinfo_cpu_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
126 {
127 	HalDevice *d;
128 
129 	if ((device_type == NULL) || (strcmp(device_type, "cpu") != 0)) {
130 		return (NULL);
131 	}
132 
133 	d = hal_device_new ();
134 
135 	devinfo_set_default_properties (d, parent, node, devfs_path);
136 	hal_device_add_capability (d, "processor");
137 
138 	devinfo_add_enqueue (d, devfs_path, &devinfo_cpu_handler);
139 
140 	return (d);
141 }
142 
143 static HalDevice *
144 devinfo_keyboard_add(HalDevice *parent, di_node_t node, char *devfs_path,
145     char *device_type)
146 {
147 	HalDevice *d;
148 
149 	if (strcmp(di_node_name(node), "keyboard") != 0) {
150 		return (NULL);
151 	}
152 
153 	d = hal_device_new ();
154 
155 	devinfo_set_default_properties (d, parent, node, devfs_path);
156 	hal_device_add_capability (d, "input.keyboard");
157 	hal_device_add_capability(d, "button");
158 
159 	devinfo_add_enqueue (d, devfs_path, &devinfo_keyboard_handler);
160 
161 	return (d);
162 }
163 
164 static HalDevice *
165 devinfo_default_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
166 {
167 	char *driver_name;
168 	const char *parent_path;
169 	HalDevice *d;
170 
171 	/* ignore all children of the 'pseudo' node except lofi */
172 	if (parent != NULL) {
173 		parent_path = hal_device_property_get_string(parent, "solaris.devfs_path");
174 		if ((parent_path != NULL) &&
175 		    (strcmp (parent_path, "/pseudo") == 0)) {
176 			driver_name = di_driver_name (node);
177 			if ((driver_name != NULL) &&
178 			    (strcmp (driver_name, "lofi") != 0)) {
179 				return (NULL);
180 			}
181 		}
182 	}
183 
184 	d = hal_device_new ();
185 
186 	devinfo_set_default_properties (d, parent, node, devfs_path);
187 
188 	devinfo_add_enqueue (d, devfs_path, &devinfo_default_handler);
189 
190 	return (d);
191 }
192