devinfo_acpi.c revision 4035:4874e0752050
1/***************************************************************************
2 *
3 * devinfo_acpi : acpi devices
4 *
5 * Copyright 2007 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
26#include "../osspec.h"
27#include "../logger.h"
28#include "../hald.h"
29#include "../hald_dbus.h"
30#include "../device_info.h"
31#include "../util.h"
32#include "../hald_runner.h"
33#include "devinfo_acpi.h"
34
35#define		DEVINFO_PROBE_BATTERY_TIMEOUT	30000
36
37static HalDevice *devinfo_acpi_add(HalDevice *, di_node_t, char *, char *);
38static HalDevice *devinfo_battery_add(HalDevice *, di_node_t, char *, char *);
39
40DevinfoDevHandler devinfo_acpi_handler = {
41	devinfo_acpi_add,
42	NULL,
43	NULL,
44	NULL,
45	NULL,
46	NULL
47};
48
49DevinfoDevHandler devinfo_battery_handler = {
50	devinfo_battery_add,
51	NULL,
52	NULL,
53	NULL,
54	NULL,
55	devinfo_battery_get_prober
56};
57
58static HalDevice *
59devinfo_acpi_add(HalDevice *parent, di_node_t node, char *devfs_path,
60    char *device_type)
61{
62	HalDevice *d, *computer;
63
64	if (strcmp(devfs_path, "/acpi") != 0) {
65		return (NULL);
66	}
67
68	d = hal_device_new();
69
70	if ((computer = hal_device_store_find(hald_get_gdl(),
71	    "/org/freedesktop/Hal/devices/computer")) ||
72	    (computer = hal_device_store_find(hald_get_tdl(),
73	    "/org/freedesktop/Hal/devices/computer"))) {
74		hal_device_property_set_string(computer,
75		    "power_management.type", "acpi");
76	}
77	devinfo_set_default_properties(d, parent, node, devfs_path);
78	devinfo_add_enqueue(d, devfs_path, &devinfo_acpi_handler);
79
80	return (d);
81}
82
83static HalDevice *
84devinfo_battery_add(HalDevice *parent, di_node_t node, char *devfs_path,
85    char *device_type)
86{
87	HalDevice *d, *computer;
88	char	*driver_name;
89	di_devlink_handle_t devlink_hdl;
90	int	major;
91	di_minor_t minor;
92	dev_t   dev;
93	char    *minor_path = NULL;
94	char    *devpath;
95
96	driver_name = di_driver_name(node);
97	if ((driver_name == NULL) || (strcmp(driver_name, "battery") != 0)) {
98		return (NULL);
99	}
100
101	d = hal_device_new();
102
103	if ((computer = hal_device_store_find(hald_get_gdl(),
104	    "/org/freedesktop/Hal/devices/computer")) ||
105	    (computer = hal_device_store_find(hald_get_tdl(),
106	    "/org/freedesktop/Hal/devices/computer"))) {
107		hal_device_property_set_string(computer,
108		    "system.formfactor", "laptop");
109	}
110	devinfo_set_default_properties(d, parent, node, devfs_path);
111	devinfo_add_enqueue(d, devfs_path, &devinfo_battery_handler);
112
113	major = di_driver_major(node);
114	if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
115		return (d);
116	}
117	minor = DI_MINOR_NIL;
118	while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
119		dev = di_minor_devt(minor);
120		if ((major != major(dev)) ||
121		    (di_minor_type(minor) != DDM_MINOR) ||
122		    (di_minor_spectype(minor) != S_IFCHR) ||
123		    ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
124			continue;
125		}
126
127		if (hal_device_store_match_key_value_string(hald_get_gdl(),
128		    "solaris.devfs_path", minor_path) == NULL) {
129			devinfo_battery_add_minor(d, node, minor_path, dev);
130		}
131
132		di_devfs_path_free(minor_path);
133	}
134	di_devlink_fini(&devlink_hdl);
135
136	return (d);
137}
138
139void
140devinfo_battery_add_minor(HalDevice *parent, di_node_t node, char *minor_path,
141    dev_t dev)
142{
143	HalDevice *d;
144
145	d = hal_device_new();
146	devinfo_set_default_properties(d, parent, node, minor_path);
147	devinfo_add_enqueue(d, minor_path, &devinfo_battery_handler);
148}
149
150void
151devinfo_battery_device_rescan(char *parent_devfs_path, gchar *udi)
152{
153	HalDevice *d = NULL;
154
155	d = hal_device_store_find(hald_get_gdl(), udi);
156	if (d == NULL) {
157		HAL_INFO(("device not found %s", udi));
158		return;
159	}
160
161	hald_runner_run(d, "hald-probe-battery", NULL,
162	    DEVINFO_PROBE_BATTERY_TIMEOUT, devinfo_battery_rescan_probing_done,
163	    NULL, NULL);
164}
165
166static void
167devinfo_battery_rescan_probing_done(HalDevice *d, guint32 exit_type,
168    gint return_code, char **error, gpointer userdata1, gpointer userdata2)
169{
170	/* hald_runner_run() requires this function since cannot pass NULL */
171}
172
173const gchar *
174devinfo_battery_get_prober(HalDevice *d, int *timeout)
175{
176	*timeout = DEVINFO_PROBE_BATTERY_TIMEOUT;    /* 30 second timeout */
177	return ("hald-probe-battery");
178}
179