xref: /onnv-gate/usr/src/cmd/hal/hald/solaris/devinfo_acpi.c (revision 7651:0cebc536e909)
14035Sphitran /***************************************************************************
24035Sphitran  *
34035Sphitran  * devinfo_acpi : acpi devices
44035Sphitran  *
56573Sphitran  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
64035Sphitran  * Use is subject to license terms.
74035Sphitran  *
84035Sphitran  * Licensed under the Academic Free License version 2.1
94035Sphitran  *
104035Sphitran  **************************************************************************/
114035Sphitran 
124035Sphitran #ifdef HAVE_CONFIG_H
134035Sphitran #include <config.h>
144035Sphitran #endif
154035Sphitran 
164035Sphitran #include <stdio.h>
174035Sphitran #include <string.h>
184035Sphitran #include <sys/utsname.h>
194035Sphitran #include <libdevinfo.h>
204035Sphitran #include <sys/mkdev.h>
214035Sphitran #include <sys/stat.h>
224035Sphitran #include <unistd.h>
236573Sphitran #include <sys/sysevent/dev.h>
246573Sphitran #include <sys/sysevent/pwrctl.h>
254035Sphitran 
264035Sphitran #include "../osspec.h"
274035Sphitran #include "../logger.h"
284035Sphitran #include "../hald.h"
294035Sphitran #include "../hald_dbus.h"
304035Sphitran #include "../device_info.h"
314035Sphitran #include "../util.h"
324035Sphitran #include "../hald_runner.h"
334035Sphitran #include "devinfo_acpi.h"
344035Sphitran 
35*7651SPhi.Tran@Sun.COM #define		DEVINFO_PROBE_ACPI_TIMEOUT	30000
364035Sphitran 
374035Sphitran static HalDevice *devinfo_acpi_add(HalDevice *, di_node_t, char *, char *);
386573Sphitran static HalDevice *devinfo_power_button_add(HalDevice *parent, di_node_t node,
396573Sphitran     char *devfs_path, char *device_type);
406573Sphitran static void devinfo_battery_rescan_probing_done(HalDevice *d, guint32 exit_type,
416573Sphitran     gint return_code, char **error, gpointer userdata1, gpointer userdata2);
424035Sphitran 
434035Sphitran DevinfoDevHandler devinfo_acpi_handler = {
444035Sphitran 	devinfo_acpi_add,
454035Sphitran 	NULL,
464035Sphitran 	NULL,
474035Sphitran 	NULL,
484035Sphitran 	NULL,
497137Sphitran 	devinfo_acpi_get_prober
504035Sphitran };
514035Sphitran 
526573Sphitran DevinfoDevHandler devinfo_power_button_handler = {
536573Sphitran 	devinfo_power_button_add,
546573Sphitran 	NULL,
556573Sphitran 	NULL,
566573Sphitran 	NULL,
576573Sphitran 	NULL,
586573Sphitran 	NULL
596573Sphitran };
606573Sphitran 
614035Sphitran static HalDevice *
devinfo_acpi_add(HalDevice * parent,di_node_t node,char * devfs_path,char * device_type)624035Sphitran devinfo_acpi_add(HalDevice *parent, di_node_t node, char *devfs_path,
634035Sphitran     char *device_type)
644035Sphitran {
654035Sphitran 	HalDevice *d, *computer;
664035Sphitran 	char	*driver_name;
674035Sphitran 	di_devlink_handle_t devlink_hdl;
684035Sphitran 	int	major;
694035Sphitran 	di_minor_t minor;
704035Sphitran 	dev_t   dev;
714035Sphitran 	char    *minor_path = NULL;
724035Sphitran 	char    *devpath;
734035Sphitran 
744035Sphitran 	driver_name = di_driver_name(node);
756573Sphitran 	if ((driver_name == NULL) || (strcmp(driver_name, "acpi_drv") != 0)) {
764035Sphitran 		return (NULL);
774035Sphitran 	}
784035Sphitran 
794035Sphitran 	d = hal_device_new();
804035Sphitran 
814035Sphitran 	if ((computer = hal_device_store_find(hald_get_gdl(),
824035Sphitran 	    "/org/freedesktop/Hal/devices/computer")) ||
834035Sphitran 	    (computer = hal_device_store_find(hald_get_tdl(),
844035Sphitran 	    "/org/freedesktop/Hal/devices/computer"))) {
854035Sphitran 		hal_device_property_set_string(computer,
864035Sphitran 		    "system.formfactor", "laptop");
877137Sphitran 		hal_device_property_set_string(computer,
887137Sphitran 		    "power_management.type", "acpi");
894035Sphitran 	}
904035Sphitran 	devinfo_set_default_properties(d, parent, node, devfs_path);
917137Sphitran 	devinfo_add_enqueue(d, devfs_path, &devinfo_acpi_handler);
924035Sphitran 
934035Sphitran 	major = di_driver_major(node);
944035Sphitran 	if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
954035Sphitran 		return (d);
964035Sphitran 	}
974035Sphitran 	minor = DI_MINOR_NIL;
984035Sphitran 	while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
994035Sphitran 		dev = di_minor_devt(minor);
1004035Sphitran 		if ((major != major(dev)) ||
1014035Sphitran 		    (di_minor_type(minor) != DDM_MINOR) ||
1024035Sphitran 		    (di_minor_spectype(minor) != S_IFCHR) ||
1034035Sphitran 		    ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
1044035Sphitran 			continue;
1054035Sphitran 		}
1064035Sphitran 
1074035Sphitran 		if (hal_device_store_match_key_value_string(hald_get_gdl(),
1084035Sphitran 		    "solaris.devfs_path", minor_path) == NULL) {
1097137Sphitran 			devinfo_acpi_add_minor(d, node, minor_path, dev);
1104035Sphitran 		}
1114035Sphitran 
1124035Sphitran 		di_devfs_path_free(minor_path);
1134035Sphitran 	}
1144035Sphitran 	di_devlink_fini(&devlink_hdl);
1154035Sphitran 
1164035Sphitran 	return (d);
1174035Sphitran }
1184035Sphitran 
1194035Sphitran void
devinfo_acpi_add_minor(HalDevice * parent,di_node_t node,char * minor_path,dev_t dev)1207137Sphitran devinfo_acpi_add_minor(HalDevice *parent, di_node_t node, char *minor_path,
1214035Sphitran     dev_t dev)
1224035Sphitran {
1234035Sphitran 	HalDevice *d;
1244035Sphitran 
1254035Sphitran 	d = hal_device_new();
1264035Sphitran 	devinfo_set_default_properties(d, parent, node, minor_path);
1277137Sphitran 	devinfo_add_enqueue(d, minor_path, &devinfo_acpi_handler);
1284035Sphitran }
1294035Sphitran 
1306573Sphitran static HalDevice *
devinfo_power_button_add(HalDevice * parent,di_node_t node,char * devfs_path,char * device_type)1316573Sphitran devinfo_power_button_add(HalDevice *parent, di_node_t node, char *devfs_path,
1326573Sphitran     char *device_type)
1336573Sphitran {
1346573Sphitran 	HalDevice *d;
1356573Sphitran 	char *driver_name;
1366573Sphitran 
1376573Sphitran 	driver_name = di_driver_name(node);
1386573Sphitran 	if ((driver_name == NULL) || (strcmp(driver_name, "power") != 0)) {
1396573Sphitran 		return (NULL);
1406573Sphitran 	}
1416573Sphitran 
1426573Sphitran 	d = hal_device_new();
1436573Sphitran 
1446573Sphitran 	devinfo_set_default_properties(d, parent, node, devfs_path);
1456573Sphitran 	hal_device_add_capability(d, "button");
1466573Sphitran 	hal_device_property_set_bool(d, "button.has_state", FALSE);
1476573Sphitran 	hal_device_property_set_string(d, "info.category", "input");
1486573Sphitran 	hal_device_property_set_string(d, "button.type", "power");
1496573Sphitran 	hal_device_property_set_string(d, "info.product", "Power Button");
1506573Sphitran 
1516573Sphitran 	devinfo_add_enqueue(d, devfs_path, &devinfo_power_button_handler);
1526573Sphitran 
1536573Sphitran 	return (d);
1546573Sphitran }
1556573Sphitran 
1566573Sphitran void
devinfo_power_button_event(void)157*7651SPhi.Tran@Sun.COM devinfo_power_button_event(void)
1586573Sphitran {
1596573Sphitran 	HalDevice *d = NULL;
1606573Sphitran 	HalDeviceStore *store = hald_get_gdl();
1616573Sphitran 
1626573Sphitran 	d = hal_device_store_match_key_value_string (store, "button.type",
1636573Sphitran 	    "power");
1646573Sphitran 	if (d != NULL) {
1656573Sphitran 		device_send_signal_condition(d, "ButtonPressed", "power");
1666573Sphitran 	}
1676573Sphitran }
1686573Sphitran 
1696573Sphitran void
devinfo_brightness_hotkeys_event(char * subclass)170*7651SPhi.Tran@Sun.COM devinfo_brightness_hotkeys_event(char *subclass)
1716573Sphitran {
1726573Sphitran 	HalDevice *d = NULL;
1736573Sphitran 
1746573Sphitran 	if ((d = hal_device_store_find(hald_get_gdl(),
1756573Sphitran 	    "/org/freedesktop/Hal/devices/computer")) ||
1766573Sphitran 	    (d = hal_device_store_find(hald_get_tdl(),
1776573Sphitran 	    "/org/freedesktop/Hal/devices/computer"))) {
1786573Sphitran 		if (strcmp(subclass, ESC_PWRCTL_BRIGHTNESS_UP) == 0) {
1796573Sphitran 			device_send_signal_condition(d, "ButtonPressed",
1806573Sphitran 			    "brightness-up");
1816573Sphitran 		} else {
1826573Sphitran 			device_send_signal_condition(d, "ButtonPressed",
1836573Sphitran 			    "brightness-down");
1846573Sphitran 		}
185*7651SPhi.Tran@Sun.COM 	}
1866573Sphitran }
1876573Sphitran 
1884035Sphitran void
devinfo_battery_rescan(char * parent_devfs_path,gchar * udi)189*7651SPhi.Tran@Sun.COM devinfo_battery_rescan(char *parent_devfs_path, gchar *udi)
1904035Sphitran {
1914035Sphitran 	HalDevice *d = NULL;
1924035Sphitran 
1934035Sphitran 	d = hal_device_store_find(hald_get_gdl(), udi);
1944035Sphitran 	if (d == NULL) {
1954035Sphitran 		HAL_INFO(("device not found %s", udi));
1964035Sphitran 		return;
1974035Sphitran 	}
1984035Sphitran 
1996573Sphitran 	hald_runner_run(d, "hald-probe-acpi", NULL,
200*7651SPhi.Tran@Sun.COM 	    DEVINFO_PROBE_ACPI_TIMEOUT, devinfo_battery_rescan_probing_done,
2014035Sphitran 	    NULL, NULL);
2024035Sphitran }
2034035Sphitran 
2046573Sphitran void
devinfo_lid_event(char * subclass,gchar * udi)205*7651SPhi.Tran@Sun.COM devinfo_lid_event(char *subclass, gchar *udi)
2066573Sphitran {
2076573Sphitran 	HalDevice *d = NULL;
2086573Sphitran 
2096573Sphitran 	d = hal_device_store_find(hald_get_gdl(), udi);
2106573Sphitran 	if (d == NULL) {
2116573Sphitran 		HAL_INFO(("device not found %s", udi));
2126573Sphitran 		return;
2136573Sphitran 	}
2146573Sphitran 
2156573Sphitran 	hal_device_property_set_bool(d, "button.state.value",
216*7651SPhi.Tran@Sun.COM 	    (strcmp(subclass, ESC_PWRCTL_REMOVE) == 0));
2176573Sphitran 	device_send_signal_condition(d, "ButtonPressed", "lid");
2186573Sphitran }
2196573Sphitran 
220*7651SPhi.Tran@Sun.COM gboolean
devinfo_lid_rescan(HalDevice * d)221*7651SPhi.Tran@Sun.COM devinfo_lid_rescan(HalDevice *d)
222*7651SPhi.Tran@Sun.COM {
223*7651SPhi.Tran@Sun.COM 	if (hal_device_property_get_bool(d, "button.workaround")) {
224*7651SPhi.Tran@Sun.COM 		/* Set lid state to open for workaround */
225*7651SPhi.Tran@Sun.COM 		hal_device_property_set_bool(d, "button.state.value", FALSE);
226*7651SPhi.Tran@Sun.COM 	} else {
227*7651SPhi.Tran@Sun.COM 		hald_runner_run(d, "hald-probe-acpi", NULL,
228*7651SPhi.Tran@Sun.COM 		    DEVINFO_PROBE_ACPI_TIMEOUT,
229*7651SPhi.Tran@Sun.COM 		    devinfo_battery_rescan_probing_done, NULL, NULL);
230*7651SPhi.Tran@Sun.COM 	}
231*7651SPhi.Tran@Sun.COM 
232*7651SPhi.Tran@Sun.COM 	return (TRUE);
233*7651SPhi.Tran@Sun.COM }
234*7651SPhi.Tran@Sun.COM 
2354035Sphitran static void
devinfo_battery_rescan_probing_done(HalDevice * d,guint32 exit_type,gint return_code,char ** error,gpointer userdata1,gpointer userdata2)2364035Sphitran devinfo_battery_rescan_probing_done(HalDevice *d, guint32 exit_type,
2374035Sphitran     gint return_code, char **error, gpointer userdata1, gpointer userdata2)
2384035Sphitran {
2394035Sphitran 	/* hald_runner_run() requires this function since cannot pass NULL */
2404035Sphitran }
2414035Sphitran 
2424035Sphitran const gchar *
devinfo_acpi_get_prober(HalDevice * d,int * timeout)2437137Sphitran devinfo_acpi_get_prober(HalDevice *d, int *timeout)
2444035Sphitran {
245*7651SPhi.Tran@Sun.COM 	*timeout = DEVINFO_PROBE_ACPI_TIMEOUT;    /* 30 second timeout */
2466573Sphitran 	return ("hald-probe-acpi");
2474035Sphitran }
248