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 #pragma ident "%Z%%M% %I% %E% SMI" 134035Sphitran 144035Sphitran #ifdef HAVE_CONFIG_H 154035Sphitran #include <config.h> 164035Sphitran #endif 174035Sphitran 184035Sphitran #include <stdio.h> 194035Sphitran #include <string.h> 204035Sphitran #include <sys/utsname.h> 214035Sphitran #include <libdevinfo.h> 224035Sphitran #include <sys/mkdev.h> 234035Sphitran #include <sys/stat.h> 244035Sphitran #include <unistd.h> 256573Sphitran #include <sys/sysevent/dev.h> 266573Sphitran #include <sys/sysevent/pwrctl.h> 274035Sphitran 284035Sphitran #include "../osspec.h" 294035Sphitran #include "../logger.h" 304035Sphitran #include "../hald.h" 314035Sphitran #include "../hald_dbus.h" 324035Sphitran #include "../device_info.h" 334035Sphitran #include "../util.h" 344035Sphitran #include "../hald_runner.h" 354035Sphitran #include "devinfo_acpi.h" 364035Sphitran 374035Sphitran #define DEVINFO_PROBE_BATTERY_TIMEOUT 30000 384035Sphitran 394035Sphitran static HalDevice *devinfo_acpi_add(HalDevice *, di_node_t, char *, char *); 406573Sphitran static HalDevice *devinfo_power_button_add(HalDevice *parent, di_node_t node, 416573Sphitran char *devfs_path, char *device_type); 426573Sphitran static void devinfo_battery_rescan_probing_done(HalDevice *d, guint32 exit_type, 436573Sphitran gint return_code, char **error, gpointer userdata1, gpointer userdata2); 444035Sphitran 454035Sphitran DevinfoDevHandler devinfo_acpi_handler = { 464035Sphitran devinfo_acpi_add, 474035Sphitran NULL, 484035Sphitran NULL, 494035Sphitran NULL, 504035Sphitran NULL, 51*7137Sphitran devinfo_acpi_get_prober 524035Sphitran }; 534035Sphitran 546573Sphitran DevinfoDevHandler devinfo_power_button_handler = { 556573Sphitran devinfo_power_button_add, 566573Sphitran NULL, 576573Sphitran NULL, 586573Sphitran NULL, 596573Sphitran NULL, 606573Sphitran NULL 616573Sphitran }; 626573Sphitran 634035Sphitran static HalDevice * 644035Sphitran devinfo_acpi_add(HalDevice *parent, di_node_t node, char *devfs_path, 654035Sphitran char *device_type) 664035Sphitran { 674035Sphitran HalDevice *d, *computer; 684035Sphitran char *driver_name; 694035Sphitran di_devlink_handle_t devlink_hdl; 704035Sphitran int major; 714035Sphitran di_minor_t minor; 724035Sphitran dev_t dev; 734035Sphitran char *minor_path = NULL; 744035Sphitran char *devpath; 754035Sphitran 764035Sphitran driver_name = di_driver_name(node); 776573Sphitran if ((driver_name == NULL) || (strcmp(driver_name, "acpi_drv") != 0)) { 784035Sphitran return (NULL); 794035Sphitran } 804035Sphitran 814035Sphitran d = hal_device_new(); 824035Sphitran 834035Sphitran if ((computer = hal_device_store_find(hald_get_gdl(), 844035Sphitran "/org/freedesktop/Hal/devices/computer")) || 854035Sphitran (computer = hal_device_store_find(hald_get_tdl(), 864035Sphitran "/org/freedesktop/Hal/devices/computer"))) { 874035Sphitran hal_device_property_set_string(computer, 884035Sphitran "system.formfactor", "laptop"); 89*7137Sphitran hal_device_property_set_string(computer, 90*7137Sphitran "power_management.type", "acpi"); 914035Sphitran } 924035Sphitran devinfo_set_default_properties(d, parent, node, devfs_path); 93*7137Sphitran devinfo_add_enqueue(d, devfs_path, &devinfo_acpi_handler); 944035Sphitran 954035Sphitran major = di_driver_major(node); 964035Sphitran if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) { 974035Sphitran return (d); 984035Sphitran } 994035Sphitran minor = DI_MINOR_NIL; 1004035Sphitran while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) { 1014035Sphitran dev = di_minor_devt(minor); 1024035Sphitran if ((major != major(dev)) || 1034035Sphitran (di_minor_type(minor) != DDM_MINOR) || 1044035Sphitran (di_minor_spectype(minor) != S_IFCHR) || 1054035Sphitran ((minor_path = di_devfs_minor_path(minor)) == NULL)) { 1064035Sphitran continue; 1074035Sphitran } 1084035Sphitran 1094035Sphitran if (hal_device_store_match_key_value_string(hald_get_gdl(), 1104035Sphitran "solaris.devfs_path", minor_path) == NULL) { 111*7137Sphitran devinfo_acpi_add_minor(d, node, minor_path, dev); 1124035Sphitran } 1134035Sphitran 1144035Sphitran di_devfs_path_free(minor_path); 1154035Sphitran } 1164035Sphitran di_devlink_fini(&devlink_hdl); 1174035Sphitran 1184035Sphitran return (d); 1194035Sphitran } 1204035Sphitran 1214035Sphitran void 122*7137Sphitran devinfo_acpi_add_minor(HalDevice *parent, di_node_t node, char *minor_path, 1234035Sphitran dev_t dev) 1244035Sphitran { 1254035Sphitran HalDevice *d; 1264035Sphitran 1274035Sphitran d = hal_device_new(); 1284035Sphitran devinfo_set_default_properties(d, parent, node, minor_path); 129*7137Sphitran devinfo_add_enqueue(d, minor_path, &devinfo_acpi_handler); 1304035Sphitran } 1314035Sphitran 1326573Sphitran static HalDevice * 1336573Sphitran devinfo_power_button_add(HalDevice *parent, di_node_t node, char *devfs_path, 1346573Sphitran char *device_type) 1356573Sphitran { 1366573Sphitran HalDevice *d; 1376573Sphitran char *driver_name; 1386573Sphitran 1396573Sphitran driver_name = di_driver_name(node); 1406573Sphitran if ((driver_name == NULL) || (strcmp(driver_name, "power") != 0)) { 1416573Sphitran return (NULL); 1426573Sphitran } 1436573Sphitran 1446573Sphitran d = hal_device_new(); 1456573Sphitran 1466573Sphitran devinfo_set_default_properties(d, parent, node, devfs_path); 1476573Sphitran hal_device_add_capability(d, "button"); 1486573Sphitran hal_device_property_set_bool(d, "button.has_state", FALSE); 1496573Sphitran hal_device_property_set_string(d, "info.category", "input"); 1506573Sphitran hal_device_property_set_string(d, "button.type", "power"); 1516573Sphitran hal_device_property_set_string(d, "info.product", "Power Button"); 1526573Sphitran 1536573Sphitran devinfo_add_enqueue(d, devfs_path, &devinfo_power_button_handler); 1546573Sphitran 1556573Sphitran return (d); 1566573Sphitran } 1576573Sphitran 1586573Sphitran void 1596573Sphitran devinfo_power_button_rescan(void) 1606573Sphitran { 1616573Sphitran HalDevice *d = NULL; 1626573Sphitran HalDeviceStore *store = hald_get_gdl(); 1636573Sphitran 1646573Sphitran d = hal_device_store_match_key_value_string (store, "button.type", 1656573Sphitran "power"); 1666573Sphitran if (d != NULL) { 1676573Sphitran device_send_signal_condition(d, "ButtonPressed", "power"); 1686573Sphitran } 1696573Sphitran } 1706573Sphitran 1716573Sphitran void 1726573Sphitran devinfo_brightness_hotkeys_rescan(char *subclass) 1736573Sphitran { 1746573Sphitran HalDevice *d = NULL; 1756573Sphitran 1766573Sphitran if ((d = hal_device_store_find(hald_get_gdl(), 1776573Sphitran "/org/freedesktop/Hal/devices/computer")) || 1786573Sphitran (d = hal_device_store_find(hald_get_tdl(), 1796573Sphitran "/org/freedesktop/Hal/devices/computer"))) { 1806573Sphitran if (strcmp(subclass, ESC_PWRCTL_BRIGHTNESS_UP) == 0) { 1816573Sphitran device_send_signal_condition(d, "ButtonPressed", 1826573Sphitran "brightness-up"); 1836573Sphitran } else { 1846573Sphitran device_send_signal_condition(d, "ButtonPressed", 1856573Sphitran "brightness-down"); 1866573Sphitran } 1876573Sphitran } 1886573Sphitran } 1896573Sphitran 1904035Sphitran void 1914035Sphitran devinfo_battery_device_rescan(char *parent_devfs_path, gchar *udi) 1924035Sphitran { 1934035Sphitran HalDevice *d = NULL; 1944035Sphitran 1954035Sphitran d = hal_device_store_find(hald_get_gdl(), udi); 1964035Sphitran if (d == NULL) { 1974035Sphitran HAL_INFO(("device not found %s", udi)); 1984035Sphitran return; 1994035Sphitran } 2004035Sphitran 2016573Sphitran hald_runner_run(d, "hald-probe-acpi", NULL, 2024035Sphitran DEVINFO_PROBE_BATTERY_TIMEOUT, devinfo_battery_rescan_probing_done, 2034035Sphitran NULL, NULL); 2044035Sphitran } 2054035Sphitran 2066573Sphitran void 2076573Sphitran devinfo_lid_device_rescan(char *subclass, gchar *udi) 2086573Sphitran { 2096573Sphitran HalDevice *d = NULL; 2106573Sphitran 2116573Sphitran d = hal_device_store_find(hald_get_gdl(), udi); 2126573Sphitran if (d == NULL) { 2136573Sphitran HAL_INFO(("device not found %s", udi)); 2146573Sphitran return; 2156573Sphitran } 2166573Sphitran 2176573Sphitran hal_device_property_set_bool(d, "button.state.value", 2186573Sphitran (strcmp(subclass, ESC_PWRCTL_REMOVE) == 0)); 2196573Sphitran device_send_signal_condition(d, "ButtonPressed", "lid"); 2206573Sphitran } 2216573Sphitran 2224035Sphitran static void 2234035Sphitran devinfo_battery_rescan_probing_done(HalDevice *d, guint32 exit_type, 2244035Sphitran gint return_code, char **error, gpointer userdata1, gpointer userdata2) 2254035Sphitran { 2264035Sphitran /* hald_runner_run() requires this function since cannot pass NULL */ 2274035Sphitran } 2284035Sphitran 2294035Sphitran const gchar * 230*7137Sphitran devinfo_acpi_get_prober(HalDevice *d, int *timeout) 2314035Sphitran { 2324035Sphitran *timeout = DEVINFO_PROBE_BATTERY_TIMEOUT; /* 30 second timeout */ 2336573Sphitran return ("hald-probe-acpi"); 2344035Sphitran } 235