Date: Fri, 18 Sep 2015 13:51:15 -0400 From: Jung-uk Kim <jkim@FreeBSD.org> To: Colin Percival <cperciva@freebsd.org>, "freebsd-acpi@freebsd.org" <freebsd-acpi@freebsd.org> Subject: Re: disabling sleep when shutting down Message-ID: <55FC4F13.3090603@FreeBSD.org> In-Reply-To: <55FB48E3.20401@freebsd.org> References: <55FA3848.7090802@freebsd.org> <55FB233D.2080000@FreeBSD.org> <55FB48E3.20401@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------080505010706070807030101
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: 7bit
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
On 09/17/2015 19:12, Colin Percival wrote:
> On 09/17/15 13:31, Jung-uk Kim wrote:
>> On 09/16/2015 23:49, Colin Percival wrote:
>>> I ran into an interesting glitch recently: I told my laptop to
>>> shut down, then closed the lid... and it promptly went into S3.
>>> When I opened the lid a couple days later, it resumed... and
>>> then finished the shutdown which it had started 2 days
>>> earlier.
>>
>> Please try the attached patch.
>
> No, this doesn't do what I wanted. It might be a good idea anyway,
> but your patch only disables suspend once the kernel is trying to
> reboot; what I want is to disable suspend a bit earlier -- once
> rc.shutdown is running and the userland is trying to shut down,
> because at that point unless something breaks horribly we're *about
> to* tell the kernel to shut down even though we haven't gotten
> there quite yet.
Okay. The attached patch is a quick-and-dirty & untested hack for you.
Jung-uk Kim
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
iQEcBAEBCAAGBQJV/E8NAAoJEHyflib82/FGKB4IAJud2fy+GKB8XLnbKYDv7ftx
WGB3RWXLCRkkSC41YtnVUJUeCWUmXdRpy6DWRQtQQIFvAgV1ZjjZiHQRJzRtKhKW
spPXCUXU9LL7wnYpBWejH9EuH3+xtLLSPxM32eKVRmSgMGUcIse3Q/b2Ztf5yZC5
K0p60jmLvGaXrKgf99tyyX90UUhoJ1bABCVheNuMbf/UuWOJD0AytGDGrKGZckmS
fLm8nPQIYVJIC1Xsu3Av/EfmKgQpNoFGk7pDhQqf5glmC+jgzp4KElo7KA9ekq43
ybBusp8tfjY0LVRCoMB+K35KWku9puYLeBDm/2PygzOXOIzfkBC2F4dpfmDI3vY=
=unIE
-----END PGP SIGNATURE-----
--------------080505010706070807030101
Content-Type: text/x-patch;
name="acpi.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="acpi.diff"
Index: etc/rc.shutdown
===================================================================
--- etc/rc.shutdown (revision 287937)
+++ etc/rc.shutdown (working copy)
@@ -43,6 +43,9 @@ HOME=/
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin
export HOME PATH
+# Temporarily block any suspend requests.
+acpiconf -b 1 >/dev/null 2>&1
+
. /etc/rc.subr
load_rc_config 'XXX'
@@ -109,5 +112,8 @@ fi
# Insert other shutdown procedures here
+# Unblock suspend requests.
+acpiconf -b 0 >/dev/null 2>&1
+
echo '.'
exit 0
Index: sys/dev/acpica/acpi.c
===================================================================
--- sys/dev/acpica/acpi.c (revision 287937)
+++ sys/dev/acpica/acpi.c (working copy)
@@ -98,6 +98,9 @@ struct callout acpi_sleep_timer;
/* Bitmap of device quirks. */
int acpi_quirks;
+/* Block suspend requests. */
+static int acpi_sleep_blocked;
+
/* Supported sleep states. */
static BOOLEAN acpi_sleep_states[ACPI_S_STATE_COUNT];
@@ -2574,10 +2577,12 @@ acpi_ReqSleepState(struct acpi_softc *sc, int stat
if (!acpi_sleep_states[state])
return (EOPNOTSUPP);
- /* If a suspend request is already in progress, just return. */
- if (sc->acpi_next_sstate != 0) {
+ /*
+ * If a reboot/shutdown/suspend request is already in progress
+ * or suspend is explicitly disabled, just return.
+ */
+ if (rebooting || sc->acpi_next_sstate != 0 || acpi_sleep_blocked)
return (0);
- }
/* Wait until sleep is enabled. */
while (sc->acpi_sleep_disabled) {
@@ -3568,6 +3573,9 @@ acpiioctl(struct cdev *dev, u_long cmd, caddr_t ad
error = *(int *)addr;
error = acpi_AckSleepState(sc->acpi_clone, error);
break;
+ case ACPIIO_BLKSLPSTATE:
+ acpi_sleep_blocked = *(int *)addr;
+ break;
case ACPIIO_SETSLPSTATE: /* DEPRECATED */
state = *(int *)addr;
if (state < ACPI_STATE_S0 || state > ACPI_S_STATES_MAX)
Index: sys/dev/acpica/acpiio.h
===================================================================
--- sys/dev/acpica/acpiio.h (revision 287937)
+++ sys/dev/acpica/acpiio.h (working copy)
@@ -41,6 +41,9 @@
/* Allow suspend to continue (0) or abort it (errno). */
#define ACPIIO_ACKSLPSTATE _IOW('P', 5, int)
+/* Allow suspend request (0) or block it. */
+#define ACPIIO_BLKSLPSTATE _IOW('P', 6, int)
+
struct acpi_battinfo {
int cap; /* percent */
int min; /* remaining time (in minutes) */
Index: usr.sbin/acpi/acpiconf/acpiconf.8
===================================================================
--- usr.sbin/acpi/acpiconf/acpiconf.8 (revision 287937)
+++ usr.sbin/acpi/acpiconf/acpiconf.8 (working copy)
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 10, 2014
+.Dd September 18, 2015
.Dt ACPICONF 8
.Os
.Sh NAME
@@ -35,6 +35,7 @@
.Nd control ACPI power management
.Sh SYNOPSIS
.Nm
+.Op Fl b Ar block
.Op Fl h
.Op Fl i Ar batt
.Op Fl k Ar ack
@@ -45,7 +46,10 @@ The
utility allows the user control of the ACPI power management
functions.
The following command-line options are recognized:
-.Bl -tag -width ".Fl s Ar type"
+.Bl -tag -width ".Fl b Ar block"
+.It Fl b Ar block
+Block or unblock suspend requests using the argument provided.
+.Sy Most users should not use this option directly.
.It Fl h
Displays a summary of available options.
.It Fl i Ar batt
Index: usr.sbin/acpi/acpiconf/acpiconf.c
===================================================================
--- usr.sbin/acpi/acpiconf/acpiconf.c (revision 287937)
+++ usr.sbin/acpi/acpiconf/acpiconf.c (working copy)
@@ -77,6 +77,17 @@ acpi_sleep_ack(int err_val)
err(EX_IOERR, "ack sleep type failed");
}
+/* Block or unblock suspend requests. */
+static void
+acpi_sleep_block(int block)
+{
+ int ret;
+
+ ret = ioctl(acpifd, ACPIIO_BLKSLPSTATE, &block);
+ if (ret != 0)
+ err(EX_IOERR, "%sblock sleep failed", block ? "" : "un");
+}
+
/* should be a acpi define, but doesn't appear to be */
#define UNKNOWN_CAP 0xffffffff
#define UNKNOWN_VOLTAGE 0xffffffff
@@ -213,8 +224,11 @@ main(int argc, char *argv[])
sleep_type = -1;
acpi_init();
- while ((c = getopt(argc, argv, "hi:k:s:")) != -1) {
+ while ((c = getopt(argc, argv, "b:hi:k:s:")) != -1) {
switch (c) {
+ case 'b':
+ acpi_sleep_block(atoi(optarg));
+ break;
case 'i':
acpi_battinfo(atoi(optarg));
break;
--------------080505010706070807030101--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?55FC4F13.3090603>
