7b840e52d558c34b70cbcde044d8d79852d169d2phitran/***************************************************************************
7b840e52d558c34b70cbcde044d8d79852d169d2phitran *
7b840e52d558c34b70cbcde044d8d79852d169d2phitran * devinfo_acpi : acpi devices
7b840e52d558c34b70cbcde044d8d79852d169d2phitran *
d2ec54f7875f7e05edd56195adbeb593c947763fphitran * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
7b840e52d558c34b70cbcde044d8d79852d169d2phitran * Use is subject to license terms.
7b840e52d558c34b70cbcde044d8d79852d169d2phitran *
7b840e52d558c34b70cbcde044d8d79852d169d2phitran * Licensed under the Academic Free License version 2.1
7b840e52d558c34b70cbcde044d8d79852d169d2phitran *
7b840e52d558c34b70cbcde044d8d79852d169d2phitran **************************************************************************/
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#ifdef HAVE_CONFIG_H
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include <config.h>
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#endif
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include <stdio.h>
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include <string.h>
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include <sys/utsname.h>
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include <libdevinfo.h>
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include <sys/mkdev.h>
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include <sys/stat.h>
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include <unistd.h>
d2ec54f7875f7e05edd56195adbeb593c947763fphitran#include <sys/sysevent/dev.h>
d2ec54f7875f7e05edd56195adbeb593c947763fphitran#include <sys/sysevent/pwrctl.h>
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include "../osspec.h"
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include "../logger.h"
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include "../hald.h"
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include "../hald_dbus.h"
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include "../device_info.h"
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include "../util.h"
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include "../hald_runner.h"
7b840e52d558c34b70cbcde044d8d79852d169d2phitran#include "devinfo_acpi.h"
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran#define DEVINFO_PROBE_ACPI_TIMEOUT 30000
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitranstatic HalDevice *devinfo_acpi_add(HalDevice *, di_node_t, char *, char *);
d2ec54f7875f7e05edd56195adbeb593c947763fphitranstatic HalDevice *devinfo_power_button_add(HalDevice *parent, di_node_t node,
d2ec54f7875f7e05edd56195adbeb593c947763fphitran char *devfs_path, char *device_type);
d2ec54f7875f7e05edd56195adbeb593c947763fphitranstatic void devinfo_battery_rescan_probing_done(HalDevice *d, guint32 exit_type,
d2ec54f7875f7e05edd56195adbeb593c947763fphitran gint return_code, char **error, gpointer userdata1, gpointer userdata2);
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitranDevinfoDevHandler devinfo_acpi_handler = {
7b840e52d558c34b70cbcde044d8d79852d169d2phitran devinfo_acpi_add,
7b840e52d558c34b70cbcde044d8d79852d169d2phitran NULL,
7b840e52d558c34b70cbcde044d8d79852d169d2phitran NULL,
7b840e52d558c34b70cbcde044d8d79852d169d2phitran NULL,
7b840e52d558c34b70cbcde044d8d79852d169d2phitran NULL,
59066d3c46818a42896f327c78359187de55245bphitran devinfo_acpi_get_prober
7b840e52d558c34b70cbcde044d8d79852d169d2phitran};
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
d2ec54f7875f7e05edd56195adbeb593c947763fphitranDevinfoDevHandler devinfo_power_button_handler = {
d2ec54f7875f7e05edd56195adbeb593c947763fphitran devinfo_power_button_add,
d2ec54f7875f7e05edd56195adbeb593c947763fphitran NULL,
d2ec54f7875f7e05edd56195adbeb593c947763fphitran NULL,
d2ec54f7875f7e05edd56195adbeb593c947763fphitran NULL,
d2ec54f7875f7e05edd56195adbeb593c947763fphitran NULL,
d2ec54f7875f7e05edd56195adbeb593c947763fphitran NULL
d2ec54f7875f7e05edd56195adbeb593c947763fphitran};
d2ec54f7875f7e05edd56195adbeb593c947763fphitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitranstatic HalDevice *
7b840e52d558c34b70cbcde044d8d79852d169d2phitrandevinfo_acpi_add(HalDevice *parent, di_node_t node, char *devfs_path,
7b840e52d558c34b70cbcde044d8d79852d169d2phitran char *device_type)
7b840e52d558c34b70cbcde044d8d79852d169d2phitran{
7b840e52d558c34b70cbcde044d8d79852d169d2phitran HalDevice *d, *computer;
7b840e52d558c34b70cbcde044d8d79852d169d2phitran char *driver_name;
7b840e52d558c34b70cbcde044d8d79852d169d2phitran di_devlink_handle_t devlink_hdl;
7b840e52d558c34b70cbcde044d8d79852d169d2phitran int major;
7b840e52d558c34b70cbcde044d8d79852d169d2phitran di_minor_t minor;
7b840e52d558c34b70cbcde044d8d79852d169d2phitran dev_t dev;
7b840e52d558c34b70cbcde044d8d79852d169d2phitran char *minor_path = NULL;
7b840e52d558c34b70cbcde044d8d79852d169d2phitran char *devpath;
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitran driver_name = di_driver_name(node);
d2ec54f7875f7e05edd56195adbeb593c947763fphitran if ((driver_name == NULL) || (strcmp(driver_name, "acpi_drv") != 0)) {
7b840e52d558c34b70cbcde044d8d79852d169d2phitran return (NULL);
7b840e52d558c34b70cbcde044d8d79852d169d2phitran }
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitran d = hal_device_new();
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitran if ((computer = hal_device_store_find(hald_get_gdl(),
7b840e52d558c34b70cbcde044d8d79852d169d2phitran "/org/freedesktop/Hal/devices/computer")) ||
7b840e52d558c34b70cbcde044d8d79852d169d2phitran (computer = hal_device_store_find(hald_get_tdl(),
7b840e52d558c34b70cbcde044d8d79852d169d2phitran "/org/freedesktop/Hal/devices/computer"))) {
7b840e52d558c34b70cbcde044d8d79852d169d2phitran hal_device_property_set_string(computer,
7b840e52d558c34b70cbcde044d8d79852d169d2phitran "system.formfactor", "laptop");
59066d3c46818a42896f327c78359187de55245bphitran hal_device_property_set_string(computer,
59066d3c46818a42896f327c78359187de55245bphitran "power_management.type", "acpi");
7b840e52d558c34b70cbcde044d8d79852d169d2phitran }
7b840e52d558c34b70cbcde044d8d79852d169d2phitran devinfo_set_default_properties(d, parent, node, devfs_path);
59066d3c46818a42896f327c78359187de55245bphitran devinfo_add_enqueue(d, devfs_path, &devinfo_acpi_handler);
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitran major = di_driver_major(node);
7b840e52d558c34b70cbcde044d8d79852d169d2phitran if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
7b840e52d558c34b70cbcde044d8d79852d169d2phitran return (d);
7b840e52d558c34b70cbcde044d8d79852d169d2phitran }
7b840e52d558c34b70cbcde044d8d79852d169d2phitran minor = DI_MINOR_NIL;
7b840e52d558c34b70cbcde044d8d79852d169d2phitran while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
7b840e52d558c34b70cbcde044d8d79852d169d2phitran dev = di_minor_devt(minor);
7b840e52d558c34b70cbcde044d8d79852d169d2phitran if ((major != major(dev)) ||
7b840e52d558c34b70cbcde044d8d79852d169d2phitran (di_minor_type(minor) != DDM_MINOR) ||
7b840e52d558c34b70cbcde044d8d79852d169d2phitran (di_minor_spectype(minor) != S_IFCHR) ||
7b840e52d558c34b70cbcde044d8d79852d169d2phitran ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
7b840e52d558c34b70cbcde044d8d79852d169d2phitran continue;
7b840e52d558c34b70cbcde044d8d79852d169d2phitran }
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitran if (hal_device_store_match_key_value_string(hald_get_gdl(),
7b840e52d558c34b70cbcde044d8d79852d169d2phitran "solaris.devfs_path", minor_path) == NULL) {
59066d3c46818a42896f327c78359187de55245bphitran devinfo_acpi_add_minor(d, node, minor_path, dev);
7b840e52d558c34b70cbcde044d8d79852d169d2phitran }
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitran di_devfs_path_free(minor_path);
7b840e52d558c34b70cbcde044d8d79852d169d2phitran }
7b840e52d558c34b70cbcde044d8d79852d169d2phitran di_devlink_fini(&devlink_hdl);
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitran return (d);
7b840e52d558c34b70cbcde044d8d79852d169d2phitran}
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitranvoid
59066d3c46818a42896f327c78359187de55245bphitrandevinfo_acpi_add_minor(HalDevice *parent, di_node_t node, char *minor_path,
7b840e52d558c34b70cbcde044d8d79852d169d2phitran dev_t dev)
7b840e52d558c34b70cbcde044d8d79852d169d2phitran{
7b840e52d558c34b70cbcde044d8d79852d169d2phitran HalDevice *d;
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitran d = hal_device_new();
7b840e52d558c34b70cbcde044d8d79852d169d2phitran devinfo_set_default_properties(d, parent, node, minor_path);
59066d3c46818a42896f327c78359187de55245bphitran devinfo_add_enqueue(d, minor_path, &devinfo_acpi_handler);
7b840e52d558c34b70cbcde044d8d79852d169d2phitran}
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
d2ec54f7875f7e05edd56195adbeb593c947763fphitranstatic HalDevice *
d2ec54f7875f7e05edd56195adbeb593c947763fphitrandevinfo_power_button_add(HalDevice *parent, di_node_t node, char *devfs_path,
d2ec54f7875f7e05edd56195adbeb593c947763fphitran char *device_type)
d2ec54f7875f7e05edd56195adbeb593c947763fphitran{
d2ec54f7875f7e05edd56195adbeb593c947763fphitran HalDevice *d;
d2ec54f7875f7e05edd56195adbeb593c947763fphitran char *driver_name;
d2ec54f7875f7e05edd56195adbeb593c947763fphitran
d2ec54f7875f7e05edd56195adbeb593c947763fphitran driver_name = di_driver_name(node);
d2ec54f7875f7e05edd56195adbeb593c947763fphitran if ((driver_name == NULL) || (strcmp(driver_name, "power") != 0)) {
d2ec54f7875f7e05edd56195adbeb593c947763fphitran return (NULL);
d2ec54f7875f7e05edd56195adbeb593c947763fphitran }
d2ec54f7875f7e05edd56195adbeb593c947763fphitran
d2ec54f7875f7e05edd56195adbeb593c947763fphitran d = hal_device_new();
d2ec54f7875f7e05edd56195adbeb593c947763fphitran
d2ec54f7875f7e05edd56195adbeb593c947763fphitran devinfo_set_default_properties(d, parent, node, devfs_path);
d2ec54f7875f7e05edd56195adbeb593c947763fphitran hal_device_add_capability(d, "button");
d2ec54f7875f7e05edd56195adbeb593c947763fphitran hal_device_property_set_bool(d, "button.has_state", FALSE);
d2ec54f7875f7e05edd56195adbeb593c947763fphitran hal_device_property_set_string(d, "info.category", "input");
d2ec54f7875f7e05edd56195adbeb593c947763fphitran hal_device_property_set_string(d, "button.type", "power");
d2ec54f7875f7e05edd56195adbeb593c947763fphitran hal_device_property_set_string(d, "info.product", "Power Button");
d2ec54f7875f7e05edd56195adbeb593c947763fphitran
d2ec54f7875f7e05edd56195adbeb593c947763fphitran devinfo_add_enqueue(d, devfs_path, &devinfo_power_button_handler);
d2ec54f7875f7e05edd56195adbeb593c947763fphitran
d2ec54f7875f7e05edd56195adbeb593c947763fphitran return (d);
d2ec54f7875f7e05edd56195adbeb593c947763fphitran}
d2ec54f7875f7e05edd56195adbeb593c947763fphitran
d2ec54f7875f7e05edd56195adbeb593c947763fphitranvoid
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Trandevinfo_power_button_event(void)
d2ec54f7875f7e05edd56195adbeb593c947763fphitran{
d2ec54f7875f7e05edd56195adbeb593c947763fphitran HalDevice *d = NULL;
d2ec54f7875f7e05edd56195adbeb593c947763fphitran HalDeviceStore *store = hald_get_gdl();
d2ec54f7875f7e05edd56195adbeb593c947763fphitran
d2ec54f7875f7e05edd56195adbeb593c947763fphitran d = hal_device_store_match_key_value_string (store, "button.type",
d2ec54f7875f7e05edd56195adbeb593c947763fphitran "power");
d2ec54f7875f7e05edd56195adbeb593c947763fphitran if (d != NULL) {
d2ec54f7875f7e05edd56195adbeb593c947763fphitran device_send_signal_condition(d, "ButtonPressed", "power");
d2ec54f7875f7e05edd56195adbeb593c947763fphitran }
d2ec54f7875f7e05edd56195adbeb593c947763fphitran}
d2ec54f7875f7e05edd56195adbeb593c947763fphitran
d2ec54f7875f7e05edd56195adbeb593c947763fphitranvoid
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Trandevinfo_brightness_hotkeys_event(char *subclass)
d2ec54f7875f7e05edd56195adbeb593c947763fphitran{
d2ec54f7875f7e05edd56195adbeb593c947763fphitran HalDevice *d = NULL;
d2ec54f7875f7e05edd56195adbeb593c947763fphitran
d2ec54f7875f7e05edd56195adbeb593c947763fphitran if ((d = hal_device_store_find(hald_get_gdl(),
d2ec54f7875f7e05edd56195adbeb593c947763fphitran "/org/freedesktop/Hal/devices/computer")) ||
d2ec54f7875f7e05edd56195adbeb593c947763fphitran (d = hal_device_store_find(hald_get_tdl(),
d2ec54f7875f7e05edd56195adbeb593c947763fphitran "/org/freedesktop/Hal/devices/computer"))) {
d2ec54f7875f7e05edd56195adbeb593c947763fphitran if (strcmp(subclass, ESC_PWRCTL_BRIGHTNESS_UP) == 0) {
d2ec54f7875f7e05edd56195adbeb593c947763fphitran device_send_signal_condition(d, "ButtonPressed",
d2ec54f7875f7e05edd56195adbeb593c947763fphitran "brightness-up");
d2ec54f7875f7e05edd56195adbeb593c947763fphitran } else {
d2ec54f7875f7e05edd56195adbeb593c947763fphitran device_send_signal_condition(d, "ButtonPressed",
d2ec54f7875f7e05edd56195adbeb593c947763fphitran "brightness-down");
d2ec54f7875f7e05edd56195adbeb593c947763fphitran }
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran }
d2ec54f7875f7e05edd56195adbeb593c947763fphitran}
d2ec54f7875f7e05edd56195adbeb593c947763fphitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitranvoid
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Trandevinfo_battery_rescan(char *parent_devfs_path, gchar *udi)
7b840e52d558c34b70cbcde044d8d79852d169d2phitran{
7b840e52d558c34b70cbcde044d8d79852d169d2phitran HalDevice *d = NULL;
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitran d = hal_device_store_find(hald_get_gdl(), udi);
7b840e52d558c34b70cbcde044d8d79852d169d2phitran if (d == NULL) {
7b840e52d558c34b70cbcde044d8d79852d169d2phitran HAL_INFO(("device not found %s", udi));
7b840e52d558c34b70cbcde044d8d79852d169d2phitran return;
7b840e52d558c34b70cbcde044d8d79852d169d2phitran }
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
d2ec54f7875f7e05edd56195adbeb593c947763fphitran hald_runner_run(d, "hald-probe-acpi", NULL,
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran DEVINFO_PROBE_ACPI_TIMEOUT, devinfo_battery_rescan_probing_done,
7b840e52d558c34b70cbcde044d8d79852d169d2phitran NULL, NULL);
7b840e52d558c34b70cbcde044d8d79852d169d2phitran}
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
d2ec54f7875f7e05edd56195adbeb593c947763fphitranvoid
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Trandevinfo_lid_event(char *subclass, gchar *udi)
d2ec54f7875f7e05edd56195adbeb593c947763fphitran{
d2ec54f7875f7e05edd56195adbeb593c947763fphitran HalDevice *d = NULL;
d2ec54f7875f7e05edd56195adbeb593c947763fphitran
d2ec54f7875f7e05edd56195adbeb593c947763fphitran d = hal_device_store_find(hald_get_gdl(), udi);
d2ec54f7875f7e05edd56195adbeb593c947763fphitran if (d == NULL) {
d2ec54f7875f7e05edd56195adbeb593c947763fphitran HAL_INFO(("device not found %s", udi));
d2ec54f7875f7e05edd56195adbeb593c947763fphitran return;
d2ec54f7875f7e05edd56195adbeb593c947763fphitran }
d2ec54f7875f7e05edd56195adbeb593c947763fphitran
d2ec54f7875f7e05edd56195adbeb593c947763fphitran hal_device_property_set_bool(d, "button.state.value",
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran (strcmp(subclass, ESC_PWRCTL_REMOVE) == 0));
d2ec54f7875f7e05edd56195adbeb593c947763fphitran device_send_signal_condition(d, "ButtonPressed", "lid");
d2ec54f7875f7e05edd56195adbeb593c947763fphitran}
d2ec54f7875f7e05edd56195adbeb593c947763fphitran
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Trangboolean
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Trandevinfo_lid_rescan(HalDevice *d)
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran{
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran if (hal_device_property_get_bool(d, "button.workaround")) {
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran /* Set lid state to open for workaround */
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran hal_device_property_set_bool(d, "button.state.value", FALSE);
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran } else {
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran hald_runner_run(d, "hald-probe-acpi", NULL,
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran DEVINFO_PROBE_ACPI_TIMEOUT,
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran devinfo_battery_rescan_probing_done, NULL, NULL);
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran }
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran return (TRUE);
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran}
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran
7b840e52d558c34b70cbcde044d8d79852d169d2phitranstatic void
7b840e52d558c34b70cbcde044d8d79852d169d2phitrandevinfo_battery_rescan_probing_done(HalDevice *d, guint32 exit_type,
7b840e52d558c34b70cbcde044d8d79852d169d2phitran gint return_code, char **error, gpointer userdata1, gpointer userdata2)
7b840e52d558c34b70cbcde044d8d79852d169d2phitran{
7b840e52d558c34b70cbcde044d8d79852d169d2phitran /* hald_runner_run() requires this function since cannot pass NULL */
7b840e52d558c34b70cbcde044d8d79852d169d2phitran}
7b840e52d558c34b70cbcde044d8d79852d169d2phitran
7b840e52d558c34b70cbcde044d8d79852d169d2phitranconst gchar *
59066d3c46818a42896f327c78359187de55245bphitrandevinfo_acpi_get_prober(HalDevice *d, int *timeout)
7b840e52d558c34b70cbcde044d8d79852d169d2phitran{
076d97abc78bcba2f2216859fe2c6913cc7aff32Phi Tran *timeout = DEVINFO_PROBE_ACPI_TIMEOUT; /* 30 second timeout */
d2ec54f7875f7e05edd56195adbeb593c947763fphitran return ("hald-probe-acpi");
7b840e52d558c34b70cbcde044d8d79852d169d2phitran}