added a forcing sleep option in ACPI module, and implements
(experimental) sleep.
the code used to put the machine to sleep is the same as in uswsusp
package (s2ram program)
Paul
diff -urN pbbuttonsd_original/pbbuttonsd.cnf.5 pbbuttonsd_ptt3_forcesleep/pbbuttonsd.cnf.5
--- pbbuttonsd_original/pbbuttonsd.cnf.5 2007-02-11 10:40:46.000000000 +0100
+++ pbbuttonsd_ptt3_forcesleep/pbbuttonsd.cnf.5 2008-04-16 21:22:29.000000000 +0200
@@ -915,6 +915,12 @@
allow investigation of a battery ageing. This option includes the \fBcycle\fR
option.
+.SH MODULE ACPI
+This module contains all Acpi related configuration.
+.TP
+\fBAcpi_ForceSleep\fR = \fI[yes | no]\fR (default: no)
+Force sleep mode as supported (EXPERIMENTAL).
+
.SH "SEE ALSO"
pbbuttonsd (1)
diff -urN pbbuttonsd_original/src/module_acpi.c pbbuttonsd_ptt3_forcesleep/src/module_acpi.c
--- pbbuttonsd_original/src/module_acpi.c 2007-11-23 12:47:19.000000000 +0100
+++ pbbuttonsd_ptt3_forcesleep/src/module_acpi.c 2008-04-16 21:15:52.000000000 +0200
@@ -33,6 +33,14 @@
#include <glib.h>
#include <pbb.h>
+#include <sys/ioctl.h>
+#include <sys/kd.h>
+#include <linux/vt.h>
+#include "class_config.h"
+/* private prototypes */
+void acpi_secure (struct tagitem *taglist);
+void activate_sleepmode ();
+
#include "gettext_macros.h"
#include "input_manager.h"
#include "module_acpi.h"
@@ -95,8 +103,14 @@
return rc;
}
- /* check if sleep is supported on this system */
+ /* check if sleep is supported on this system... */
base->flags.sleepsupported = 0;
+ /* ...or if Acpi_ForceSleep is set to true */
+ if (config_get_boolean (SECTION, "Acpi_ForceSleep", FALSE)){
+ base->flags.sleepsupported = 1;
+ print_msg (PBB_INFO, _("ACPI sleep support forced\n"));
+ }
+ base->flags.goto_sleep = 0;
base->ac = NULL;
base->lid = NULL;
@@ -128,6 +142,7 @@
register_function (T1000QUEUE, acpi_timer1000);
register_function (QUERYQUEUE, acpi_query);
register_function (CONFIGQUEUE, acpi_configure);
+ register_function (SECUREQUEUE, acpi_secure);
return 0;
}
@@ -205,6 +220,9 @@
while (taglist->tag != TAG_END) {
switch (taglist->tag) {
+ case TAG_REQUESTSLEEP: /* private tag */
+ if (cfgure) base->flags.goto_sleep = 1; /* trigger delayed sleep */
+ break;
case TAG_SLEEPSUPPORTED:
if (cfgure) tagerror (taglist, E_NOWRITE);
else taglist->data = base->flags.sleepsupported;
@@ -372,6 +390,146 @@
}
/**
+ * @brief Activate sleep
+ */
+void
+acpi_secure (struct tagitem *taglist)
+{
+ struct moddata_acpi *base = &modbase_acpi;
+
+ if (base->flags.goto_sleep == 1) {
+ base->flags.goto_sleep = 0;
+ if (base->flags.sleepsupported) {
+ process_queue_single (CONFIGQUEUE, TAG_PREPAREFORSLEEP, 0);
+ activate_sleepmode ();
+ process_queue_single (CONFIGQUEUE, TAG_WAKEUPFROMSLEEP, 0);
+ }
+ }
+}
+
+int
+is_a_console(int fd)
+{
+ char arg;
+
+ arg = 0;
+ return (ioctl(fd, KDGKBTYPE, &arg) == 0
+ && ((arg == KB_101) || (arg == KB_84)));
+}
+
+int
+open_a_console(const char *fnam)
+{
+ int fd;
+
+ fd = open(fnam, O_RDWR);
+ if (fd < 0)
+ return -1;
+ if (!is_a_console(fd)) {
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+int
+getconsolefd(void)
+{
+ int fd;
+
+ fd = open_a_console("/dev/tty");
+ if (fd >= 0)
+ return fd;
+
+ fd = open_a_console("/dev/tty0");
+ if (fd >= 0)
+ return fd;
+
+ fd = open_a_console("/dev/vc/0");
+ if (fd >= 0)
+ return fd;
+
+ fd = open_a_console("/dev/console");
+ if (fd >= 0)
+ return fd;
+
+ for (fd = 0; fd < 3; fd++)
+ if (is_a_console(fd))
+ return fd;
+
+ return -1;
+}
+
+int
+fgconsole(void)
+{
+ int fd;
+ struct vt_stat vtstat;
+
+ fd = getconsolefd();
+ if (fd < 0) {
+ perror("fgconsole: getconsolefd");
+ return -1;
+ }
+
+ if (ioctl(fd, VT_GETSTATE, &vtstat)) {
+ perror("fgconsole: VT_GETSTATE");
+ return -1;
+ }
+ return vtstat.v_active;
+}
+
+void
+chvt(int num)
+{
+ int fd = getconsolefd();
+ if (ioctl(fd, VT_ACTIVATE, num)) {
+ perror("chvt: VT_ACTIVATE");
+ }
+ if (ioctl(fd, VT_WAITACTIVE, num)) {
+ perror("VT_WAITACTIVE");
+ }
+}
+
+void
+activate_sleepmode (int mode)
+{
+ int active_console = -1, ret = 0;
+ //struct moddata_acpi *base = &modbase_acpi;
+ FILE *f = NULL;
+
+ sync();
+
+ /* switch to console 1 first, since we might be in X */
+ active_console = fgconsole();
+ printf("Switching from vt%d to vt1\n", active_console);
+ chvt(1);
+
+ /* TODO : it should be nicer to send an ioctl here!!!! */
+ f = fopen("/sys/power/state", "w");
+ if (!f) {
+ printf("/sys/power/state does not exist; what kind of ninja mutant machine is this?\n");
+ }
+ if (fprintf(f, "mem") < 0) {
+ ret = errno;
+ //perror("pbbuttonsd suspend error\n");
+ }
+ /* usually only fclose fails, not fprintf, so it does not matter
+ * that we might overwrite the previous error.
+ */
+ if (fclose(f) < 0) {
+ ret = errno;
+ //perror("pbbuttonsd suspend error\n");
+ }
+
+ /* if we switched consoles before suspend, switch back */
+ if (active_console > 0) {
+ printf("switching back to vt%d\n", active_console);
+ chvt(active_console);
+ }
+}
+
+/**
* @brief Calculate the time left on battery
*
* The battery list contains data about current and voltage
diff -urN pbbuttonsd_original/src/module_acpi.h pbbuttonsd_ptt3_forcesleep/src/module_acpi.h
--- pbbuttonsd_original/src/module_acpi.h 2007-01-03 19:30:37.000000000 +0100
+++ pbbuttonsd_ptt3_forcesleep/src/module_acpi.h 2008-04-16 21:14:51.000000000 +0200
@@ -117,6 +117,7 @@
unsigned int coveropen :1;
unsigned int ac_power:1;
unsigned int sleepsupported:1;
+ unsigned int goto_sleep:1; /* delayed function triggered */
unsigned int :0;
};
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
pbbuttons-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/pbbuttons-users