aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/acpi
diff options
context:
space:
mode:
authorNate Lawson <njl@FreeBSD.org>2007-06-21 22:50:37 +0000
committerNate Lawson <njl@FreeBSD.org>2007-06-21 22:50:37 +0000
commit00a304487f0d8b8f679ff8cb2007c26ec5c97b39 (patch)
tree6d3282ab53bb6c9d24fd93319d317dd8d32ef41e /usr.sbin/acpi
parentf99ccd643885eb9dc8b05ec0b664ea1725a0bd72 (diff)
downloadsrc-00a304487f0d8b8f679ff8cb2007c26ec5c97b39.tar.gz
src-00a304487f0d8b8f679ff8cb2007c26ec5c97b39.zip
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
Notes
Notes: svn path=/head/; revision=170976
Diffstat (limited to 'usr.sbin/acpi')
-rw-r--r--usr.sbin/acpi/acpiconf/acpiconf.c50
1 files changed, 22 insertions, 28 deletions
diff --git a/usr.sbin/acpi/acpiconf/acpiconf.c b/usr.sbin/acpi/acpiconf/acpiconf.c
index 3b0686e5ee05..0797892215b3 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);