From 7f6bbd78729db96ae8368b9ab07ff62b08ea76f2 Mon Sep 17 00:00:00 2001 From: Jean Guyader Date: Thu, 18 Dec 2008 18:14:55 +0000 Subject: [PATCH] [xenpmd] Add sci for power management --- tools/xenpmd/Makefile | 4 +- tools/xenpmd/acpi-events.c | 154 +++++++++++++++++++++++++++++++++++++ tools/xenpmd/xenpmd.c | 33 +++++--- 3 files changed, 178 insertions(+), 13 deletions(-) create mode 100644 tools/xenpmd/acpi-events.c diff --git a/tools/xenpmd/Makefile b/tools/xenpmd/Makefile index 6fc31a4..c9fc637 100644 --- a/tools/xenpmd/Makefile +++ b/tools/xenpmd/Makefile @@ -10,6 +10,8 @@ BIN = xenpmd .PHONY: all all: $(BIN) +$(BIN): xenpmd.o acpi-events.o + .PHONY: install install: all $(INSTALL_DIR) $(DESTDIR)$(SBINDIR) @@ -17,4 +19,4 @@ install: all .PHONY: clean clean: - $(RM) -f $(BIN) + $(RM) -f $(BIN) *.o diff --git a/tools/xenpmd/acpi-events.c b/tools/xenpmd/acpi-events.c new file mode 100644 index 0000000..54b546b --- /dev/null +++ b/tools/xenpmd/acpi-events.c @@ -0,0 +1,154 @@ +/* + * acpi-events.c + * + * Register for and monitor acpi events and communicate relevant + * events to ioemu by triggering xenstore events. + * + * Copyright (c) 2008 Kamala Narasimhan + * Copyright (c) 2008 Citrix Systems, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#define AC_ADAPTER_STATE_FILE_PATH "/proc/acpi/ac_adapter/AC/state" +#define LID_STATE_FILE_PATH "/proc/acpi/button/lid/LID/state" +#define ACPID_SOCKET_PATH "/var/run/acpid.socket" + +#define XS_AC_ADAPTER_STATE_PATH "/pm/ac_adapter" +#define XS_LID_STATE_PATH "/pm/lid_state" + +#define XS_AC_ADAPTER_EVENT_PATH "/pm/events/acadapterstatechanged" +#define XS_LID_EVENT_PATH "/pm/events/lidstatechanged" +#define XS_PBTN_EVENT_PATH "/pm/events/powerbuttonpressed" + +static int socket_fd; +static pthread_t acpi_thread; +extern struct xs_handle *xs; + +void write_state_info_in_xenstore(char *file_path, char *xenstore_path, + char *search_str, char *default_value, char *alternate_value) +{ + FILE *file; + char file_data[1024]; + + xs_write(xs, XBT_NULL, xenstore_path, default_value, strlen(default_value)); + file = fopen(file_path, "r"); + if ( file == NULL ) + return; + + memset(file_data, 0, 1024); + fgets(file_data, 1024, file); + if ( strstr(file_data, search_str) ) + xs_write(xs, XBT_NULL, xenstore_path, alternate_value, + strlen(alternate_value)); + fclose(file); +} + +void initialize_system_state_info(void) +{ + write_state_info_in_xenstore(AC_ADAPTER_STATE_FILE_PATH, + XS_AC_ADAPTER_STATE_PATH, "off-line", "1", "0"); + write_state_info_in_xenstore(LID_STATE_FILE_PATH, XS_LID_STATE_PATH, + "closed", "1", "0"); +} + +void handle_ac_adapter_state_change(void) +{ + write_state_info_in_xenstore(AC_ADAPTER_STATE_FILE_PATH, + XS_AC_ADAPTER_STATE_PATH, "off-line", "1", "0"); + xs_write(xs, XBT_NULL, XS_AC_ADAPTER_EVENT_PATH, "1", 1); +} + +void handle_lid_state_change(void) +{ + write_state_info_in_xenstore(LID_STATE_FILE_PATH, XS_LID_STATE_PATH, + "closed", "1", "0"); + xs_write(xs, XBT_NULL, XS_LID_EVENT_PATH, "1", 1); +} + +void handle_pbtn_pressed_event(void) +{ + xs_write(xs, XBT_NULL, XS_PBTN_EVENT_PATH, "1", 1); +} + +void process_acpi_message(char *acpi_buffer) +{ + if ( strstr(acpi_buffer, "ac_adapter") ) + { + handle_ac_adapter_state_change(); + return; + } + + if ( strstr(acpi_buffer, "LID") ) + { + handle_lid_state_change(); + return; + } + + if ( strstr(acpi_buffer, "PBTN") ) + handle_pbtn_pressed_event(); +} + +static void *acpi_events_thread(void *arg) +{ + int ret; + struct sockaddr_un addr; + char acpi_buffer[1024]; + + socket_fd = socket(PF_UNIX, SOCK_STREAM, 0); + if ( socket_fd == -1) + return (void *)socket_fd; + + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, ACPID_SOCKET_PATH, strlen(ACPID_SOCKET_PATH)); + addr.sun_path[strlen(ACPID_SOCKET_PATH)] = '\0'; + ret = connect(socket_fd, (struct sockaddr *)&addr, sizeof(addr)); + if ( ret == -1 ) + return (void *)ret; + + while( 1 ) + { + memset(acpi_buffer, 0, sizeof(acpi_buffer)); + ret = recv(socket_fd, acpi_buffer, sizeof(acpi_buffer), 0); + if ( ret == 0 ) + continue; + + process_acpi_message(acpi_buffer); + } + + return (void *)1; +} + +void monitor_acpi_events(void) +{ + pthread_create(&acpi_thread, NULL, &acpi_events_thread, NULL); +} + +void acpi_events_cleanup(void) +{ + if ( socket_fd != -1 ) + close(socket_fd); + + pthread_cancel(acpi_thread); +} + diff --git a/tools/xenpmd/xenpmd.c b/tools/xenpmd/xenpmd.c index d6dd356..2d29c0c 100644 --- a/tools/xenpmd/xenpmd.c +++ b/tools/xenpmd/xenpmd.c @@ -84,7 +84,10 @@ struct battery_status { unsigned long present_voltage; }; -static struct xs_handle *xs; +struct xs_handle *xs; +extern void initialize_system_state_info(void); +extern void monitor_acpi_events(void); +extern void acpi_events_cleanup(void); #ifdef RUN_IN_SIMULATE_MODE #define BATTERY_DIR_PATH "/tmp/battery" @@ -321,14 +324,14 @@ int get_next_battery_info_or_status(DIR *battery_dir, void print_battery_info(struct battery_info *info) { printf("present: %d\n", info->present); - printf("design capacity: %d\n", info->design_capacity); - printf("last full capacity: %d\n", info->last_full_capacity); + printf("design capacity: %d\n", (int) info->design_capacity); + printf("last full capacity: %d\n", (int) info->last_full_capacity); printf("battery technology: %d\n", info->battery_technology); - printf("design voltage: %d\n", info->design_voltage); - printf("design capacity warning:%d\n", info->design_capacity_warning); - printf("design capacity low: %d\n", info->design_capacity_low); - printf("capacity granularity 1: %d\n", info->capacity_granularity_1); - printf("capacity granularity 2: %d\n", info->capacity_granularity_2); + printf("design voltage: %d\n", (int) info->design_voltage); + printf("design capacity warning:%d\n", (int) info->design_capacity_warning); + printf("design capacity low: %d\n", (int) info->design_capacity_low); + printf("capacity granularity 1: %d\n", (int) info->capacity_granularity_1); + printf("capacity granularity 2: %d\n", (int) info->capacity_granularity_2); printf("model number: %s\n", info->model_number); printf("serial number: %s\n", info->serial_number); printf("battery type: %s\n", info->battery_type); @@ -410,10 +413,11 @@ int write_one_time_battery_info(void) void print_battery_status(struct battery_status *status) { printf("present: %d\n", status->present); - printf("Battery state %d\n", status->state); - printf("Battery present rate %d\n", status->present_rate); - printf("Battery remining capacity %d\n", status->remaining_capacity); - printf("Battery present voltage %d\n", status->present_voltage); + printf("Battery state %d\n", (int) status->state); + printf("Battery present rate %d\n", (int) status->present_rate); + printf("Battery remining capacity %d\n", + (int) status->remaining_capacity); + printf("Battery present voltage %d\n", (int) status->present_voltage); } #endif /*RUN_STANDALONE*/ @@ -473,6 +477,7 @@ int wait_for_and_update_battery_status_request(void) return ret; } +#ifndef RUN_STANDALONE /* Borrowed daemonize from xenstored - Initially written by Stevens. */ static void daemonize(void) { @@ -497,6 +502,7 @@ static void daemonize(void) umask(0); } +#endif /* RUN_STANDALONE */ int main(int argc, char *argv[]) { @@ -507,6 +513,8 @@ int main(int argc, char *argv[]) if ( xs == NULL ) return -1; + initialize_system_state_info(); + monitor_acpi_events(); if ( write_one_time_battery_info() == 0 ) { xs_daemon_close(xs); @@ -514,6 +522,7 @@ int main(int argc, char *argv[]) } wait_for_and_update_battery_status_request(); + acpi_events_cleanup(); xs_daemon_close(xs); return 0; } -- 2.39.5