xref: /titanic_51/usr/src/cmd/hal/hald/solaris/devinfo_acpi.c (revision c5cd6260c3d6c06a9359df595ad9dddbfd00a80e)
1 /***************************************************************************
2  *
3  * devinfo_acpi : acpi 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/mkdev.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <sys/sysevent/dev.h>
26 #include <sys/sysevent/pwrctl.h>
27 
28 #include "../osspec.h"
29 #include "../logger.h"
30 #include "../hald.h"
31 #include "../hald_dbus.h"
32 #include "../device_info.h"
33 #include "../util.h"
34 #include "../hald_runner.h"
35 #include "devinfo_acpi.h"
36 
37 #define		DEVINFO_PROBE_BATTERY_TIMEOUT	30000
38 
39 static HalDevice *devinfo_acpi_add(HalDevice *, di_node_t, char *, char *);
40 static HalDevice *devinfo_power_button_add(HalDevice *parent, di_node_t node,
41     char *devfs_path, char *device_type);
42 static void devinfo_battery_rescan_probing_done(HalDevice *d, guint32 exit_type,
43     gint return_code, char **error, gpointer userdata1, gpointer userdata2);
44 
45 DevinfoDevHandler devinfo_acpi_handler = {
46 	devinfo_acpi_add,
47 	NULL,
48 	NULL,
49 	NULL,
50 	NULL,
51 	devinfo_acpi_get_prober
52 };
53 
54 DevinfoDevHandler devinfo_power_button_handler = {
55 	devinfo_power_button_add,
56 	NULL,
57 	NULL,
58 	NULL,
59 	NULL,
60 	NULL
61 };
62 
63 static HalDevice *
64 devinfo_acpi_add(HalDevice *parent, di_node_t node, char *devfs_path,
65     char *device_type)
66 {
67 	HalDevice *d, *computer;
68 	char	*driver_name;
69 	di_devlink_handle_t devlink_hdl;
70 	int	major;
71 	di_minor_t minor;
72 	dev_t   dev;
73 	char    *minor_path = NULL;
74 	char    *devpath;
75 
76 	driver_name = di_driver_name(node);
77 	if ((driver_name == NULL) || (strcmp(driver_name, "acpi_drv") != 0)) {
78 		return (NULL);
79 	}
80 
81 	d = hal_device_new();
82 
83 	if ((computer = hal_device_store_find(hald_get_gdl(),
84 	    "/org/freedesktop/Hal/devices/computer")) ||
85 	    (computer = hal_device_store_find(hald_get_tdl(),
86 	    "/org/freedesktop/Hal/devices/computer"))) {
87 		hal_device_property_set_string(computer,
88 		    "system.formfactor", "laptop");
89 		hal_device_property_set_string(computer,
90 		    "power_management.type", "acpi");
91 	}
92 	devinfo_set_default_properties(d, parent, node, devfs_path);
93 	devinfo_add_enqueue(d, devfs_path, &devinfo_acpi_handler);
94 
95 	major = di_driver_major(node);
96 	if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
97 		return (d);
98 	}
99 	minor = DI_MINOR_NIL;
100 	while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
101 		dev = di_minor_devt(minor);
102 		if ((major != major(dev)) ||
103 		    (di_minor_type(minor) != DDM_MINOR) ||
104 		    (di_minor_spectype(minor) != S_IFCHR) ||
105 		    ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
106 			continue;
107 		}
108 
109 		if (hal_device_store_match_key_value_string(hald_get_gdl(),
110 		    "solaris.devfs_path", minor_path) == NULL) {
111 			devinfo_acpi_add_minor(d, node, minor_path, dev);
112 		}
113 
114 		di_devfs_path_free(minor_path);
115 	}
116 	di_devlink_fini(&devlink_hdl);
117 
118 	return (d);
119 }
120 
121 void
122 devinfo_acpi_add_minor(HalDevice *parent, di_node_t node, char *minor_path,
123     dev_t dev)
124 {
125 	HalDevice *d;
126 
127 	d = hal_device_new();
128 	devinfo_set_default_properties(d, parent, node, minor_path);
129 	devinfo_add_enqueue(d, minor_path, &devinfo_acpi_handler);
130 }
131 
132 static HalDevice *
133 devinfo_power_button_add(HalDevice *parent, di_node_t node, char *devfs_path,
134     char *device_type)
135 {
136 	HalDevice *d;
137 	char *driver_name;
138 
139 	driver_name = di_driver_name(node);
140 	if ((driver_name == NULL) || (strcmp(driver_name, "power") != 0)) {
141 		return (NULL);
142 	}
143 
144 	d = hal_device_new();
145 
146 	devinfo_set_default_properties(d, parent, node, devfs_path);
147 	hal_device_add_capability(d, "button");
148 	hal_device_property_set_bool(d, "button.has_state", FALSE);
149 	hal_device_property_set_string(d, "info.category", "input");
150 	hal_device_property_set_string(d, "button.type", "power");
151 	hal_device_property_set_string(d, "info.product", "Power Button");
152 
153 	devinfo_add_enqueue(d, devfs_path, &devinfo_power_button_handler);
154 
155 	return (d);
156 }
157 
158 void
159 devinfo_power_button_rescan(void)
160 {
161 	HalDevice *d = NULL;
162 	HalDeviceStore *store = hald_get_gdl();
163 
164 	d = hal_device_store_match_key_value_string (store, "button.type",
165 	    "power");
166 	if (d != NULL) {
167 		device_send_signal_condition(d, "ButtonPressed", "power");
168 	}
169 }
170 
171 void
172 devinfo_brightness_hotkeys_rescan(char *subclass)
173 {
174 	HalDevice *d = NULL;
175 
176 	if ((d = hal_device_store_find(hald_get_gdl(),
177 	    "/org/freedesktop/Hal/devices/computer")) ||
178 	    (d = hal_device_store_find(hald_get_tdl(),
179 	    "/org/freedesktop/Hal/devices/computer"))) {
180 		if (strcmp(subclass, ESC_PWRCTL_BRIGHTNESS_UP) == 0) {
181 			device_send_signal_condition(d, "ButtonPressed",
182 			    "brightness-up");
183 		} else {
184 			device_send_signal_condition(d, "ButtonPressed",
185 			    "brightness-down");
186 		}
187         }
188 }
189 
190 void
191 devinfo_battery_device_rescan(char *parent_devfs_path, gchar *udi)
192 {
193 	HalDevice *d = NULL;
194 
195 	d = hal_device_store_find(hald_get_gdl(), udi);
196 	if (d == NULL) {
197 		HAL_INFO(("device not found %s", udi));
198 		return;
199 	}
200 
201 	hald_runner_run(d, "hald-probe-acpi", NULL,
202 	    DEVINFO_PROBE_BATTERY_TIMEOUT, devinfo_battery_rescan_probing_done,
203 	    NULL, NULL);
204 }
205 
206 void
207 devinfo_lid_device_rescan(char *subclass, gchar *udi)
208 {
209 	HalDevice *d = NULL;
210 
211 	d = hal_device_store_find(hald_get_gdl(), udi);
212 	if (d == NULL) {
213 		HAL_INFO(("device not found %s", udi));
214 		return;
215 	}
216 
217 	hal_device_property_set_bool(d, "button.state.value",
218 		(strcmp(subclass, ESC_PWRCTL_REMOVE) == 0));
219 	device_send_signal_condition(d, "ButtonPressed", "lid");
220 }
221 
222 static void
223 devinfo_battery_rescan_probing_done(HalDevice *d, guint32 exit_type,
224     gint return_code, char **error, gpointer userdata1, gpointer userdata2)
225 {
226 	/* hald_runner_run() requires this function since cannot pass NULL */
227 }
228 
229 const gchar *
230 devinfo_acpi_get_prober(HalDevice *d, int *timeout)
231 {
232 	*timeout = DEVINFO_PROBE_BATTERY_TIMEOUT;    /* 30 second timeout */
233 	return ("hald-probe-acpi");
234 }
235