diff options
author | njl <njl@FreeBSD.org> | 2007-06-21 22:50:37 +0000 |
---|---|---|
committer | njl <njl@FreeBSD.org> | 2007-06-21 22:50:37 +0000 |
commit | 79d6390885127f514c12c1f7aeb8e0272fa73621 (patch) | |
tree | 6d3282ab53bb6c9d24fd93319d317dd8d32ef41e /usr.sbin/acpi | |
parent | 4db323384d511bec08394e226ffbc340bcadbbf0 (diff) | |
download | FreeBSD-src-79d6390885127f514c12c1f7aeb8e0272fa73621.zip FreeBSD-src-79d6390885127f514c12c1f7aeb8e0272fa73621.tar.gz |
Update the suspend/resume user API while maintaining backwards compat.
Improvements:
* /etc/rc.suspend,rc.resume are always run, no matter the source of the
suspend request (user or kernel, apm or acpi)
* suspend now requires positive user acknowledgement. If a user program
wants to cancel the suspend, they can. If one of the user programs
hangs or doesn't respond within 10 seconds, the system suspends anyway.
* /dev/apm is clonable, allowing multiple listeners for suspend events.
In the future, xorg-server can use this to be informed about suspend
even if there are other listeners (i.e. apmd).
Changes:
* Two new ACPI ioctls: REQSLPSTATE and ACKSLPSTATE. Request begins the
process of suspending by notifying all listeners. acpi is monitored by
devd(8) and /dev/apm listener(s) are also counted. Users register their
approval or disapproval via Ack. If anyone disapproves, suspend is vetoed.
* Old user programs or kernel modules that used SETSLPSTATE continue to
work. A message is printed once that this interface is deprecated.
* acpiconf gains the -k flag to ack the suspend request. This flag is
undocumented on purpose since it's only used by /etc/rc.suspend. It is
not intended to be a permanent change and will be removed once a better
power API is implemented.
* S5 (power off) is no longer supported via acpiconf -s 5 or apm -z/-Z.
This restores previous behavior of halt/shutdown -p being the interface.
* Miscellaneous improvements to error reporting
Approved by: re
Diffstat (limited to 'usr.sbin/acpi')
-rw-r--r-- | usr.sbin/acpi/acpiconf/acpiconf.c | 50 |
1 files changed, 22 insertions, 28 deletions
diff --git a/usr.sbin/acpi/acpiconf/acpiconf.c b/usr.sbin/acpi/acpiconf/acpiconf.c index 3b0686e..0797892 100644 --- a/usr.sbin/acpi/acpiconf/acpiconf.c +++ b/usr.sbin/acpi/acpiconf/acpiconf.c @@ -40,8 +40,6 @@ #include <contrib/dev/acpica/acpi.h> #define ACPIDEV "/dev/acpi" -#define RC_SUSPEND_PATH "/etc/rc.suspend" -#define RC_RESUME_PATH "/etc/rc.resume" static int acpifd; @@ -55,32 +53,27 @@ acpi_init(void) err(EX_OSFILE, ACPIDEV); } -static int +/* Prepare to sleep and then wait for the signal that sleeping can occur. */ +static void acpi_sleep(int sleep_type) { - char cmd[64]; int ret; + + /* Notify OS that we want to sleep. devd(8) gets this notify. */ + ret = ioctl(acpifd, ACPIIO_REQSLPSTATE, &sleep_type); + if (ret != 0) + err(EX_IOERR, "request sleep type (%d) failed", sleep_type); +} - /* Run the suspend rc script, if available. */ - if (access(RC_SUSPEND_PATH, X_OK) == 0) { - snprintf(cmd, sizeof(cmd), "%s acpi %d", RC_SUSPEND_PATH, - sleep_type); - system(cmd); - } - - ret = ioctl(acpifd, ACPIIO_SETSLPSTATE, &sleep_type); - - /* Run the resume rc script, if available. */ - if (access(RC_RESUME_PATH, X_OK) == 0) { - snprintf(cmd, sizeof(cmd), "%s acpi %d", RC_RESUME_PATH, - sleep_type); - system(cmd); - } +/* Ack or abort a pending suspend request. */ +static void +acpi_sleep_ack(int err_val) +{ + int ret; + ret = ioctl(acpifd, ACPIIO_ACKSLPSTATE, &err_val); if (ret != 0) - err(EX_IOERR, "sleep type (%d) failed", sleep_type); - - return (0); + err(EX_IOERR, "ack sleep type failed"); } /* should be a acpi define, but doesn't appear to be */ @@ -183,7 +176,7 @@ acpi_battinfo(int num) static void usage(const char* prog) { - printf("usage: %s [-h] [-i batt] [-s 1-5]\n", prog); + printf("usage: %s [-h] [-i batt] [-k ack] [-s 1-4]\n", prog); exit(0); } @@ -200,17 +193,20 @@ main(int argc, char *argv[]) sleep_type = -1; acpi_init(); - while ((c = getopt(argc, argv, "hi:s:")) != -1) { + while ((c = getopt(argc, argv, "hi:k:s:")) != -1) { switch (c) { case 'i': acpi_battinfo(atoi(optarg)); break; + case 'k': + acpi_sleep_ack(atoi(optarg)); + break; case 's': if (optarg[0] == 'S') sleep_type = optarg[1] - '0'; else sleep_type = optarg[0] - '0'; - if (sleep_type < 0 || sleep_type > 5) + if (sleep_type < 1 || sleep_type > 4) errx(EX_USAGE, "invalid sleep type (%d)", sleep_type); break; @@ -223,10 +219,8 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - if (sleep_type != -1) { - sleep(1); /* wait 1 sec. for key-release event */ + if (sleep_type != -1) acpi_sleep(sleep_type); - } close(acpifd); exit (0); |