svn commit: r191627 - head/sys/dev/acpica
Andriy Gapon
avg at FreeBSD.org
Tue Apr 28 11:56:56 UTC 2009
Author: avg
Date: Tue Apr 28 11:56:54 2009
New Revision: 191627
URL: http://svn.freebsd.org/changeset/base/191627
Log:
acpi: do not run resume/backout code when entering S0/S5 states
This change adds (possibly redundant) early check for invalid
state input parameter (including S0). Handling of S5 request
is reduced to simply calling shutdown_nice(). As a result
control flow of acpi_EnterSleepState is somewhat simplified
and resume/backout half of the function is not executed
for S5 (soft poweroff) request and invalid state requests.
Note: it seems that shutdown_nice may act as nop when initproc
is already initialized (to grab pid of 1), but init process is in
"pre-natal" state.
Tested by: Fabian Keil <fk at fabiankeil.de>
Reviewed by: njl, jkim
Approved by: rpaulo
Modified:
head/sys/dev/acpica/acpi.c
Modified: head/sys/dev/acpica/acpi.c
==============================================================================
--- head/sys/dev/acpica/acpi.c Tue Apr 28 11:45:36 2009 (r191626)
+++ head/sys/dev/acpica/acpi.c Tue Apr 28 11:56:54 2009 (r191627)
@@ -2482,6 +2482,18 @@ acpi_EnterSleepState(struct acpi_softc *
ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, state);
+ if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5)
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+
+ if (state == ACPI_STATE_S5) {
+ /*
+ * Shut down cleanly and power off. This will call us back through the
+ * shutdown handlers.
+ */
+ shutdown_nice(RB_POWEROFF);
+ return_ACPI_STATUS (AE_OK);
+ }
+
/* Re-entry once we're suspending is not allowed. */
status = acpi_sleep_disable(sc);
if (ACPI_FAILURE(status)) {
@@ -2502,92 +2514,74 @@ acpi_EnterSleepState(struct acpi_softc *
mtx_lock(&Giant);
slp_state = ACPI_SS_NONE;
- switch (state) {
- case ACPI_STATE_S1:
- case ACPI_STATE_S2:
- case ACPI_STATE_S3:
- case ACPI_STATE_S4:
- status = AcpiGetSleepTypeData(state, &TypeA, &TypeB);
- if (status == AE_NOT_FOUND) {
- device_printf(sc->acpi_dev,
- "Sleep state S%d not supported by BIOS\n", state);
- break;
- } else if (ACPI_FAILURE(status)) {
- device_printf(sc->acpi_dev, "AcpiGetSleepTypeData failed - %s\n",
- AcpiFormatException(status));
- break;
- }
+ status = AcpiGetSleepTypeData(state, &TypeA, &TypeB);
+ if (status == AE_NOT_FOUND) {
+ device_printf(sc->acpi_dev,
+ "Sleep state S%d not supported by BIOS\n", state);
+ goto backout;
+ } else if (ACPI_FAILURE(status)) {
+ device_printf(sc->acpi_dev, "AcpiGetSleepTypeData failed - %s\n",
+ AcpiFormatException(status));
+ goto backout;
+ }
+
+ sc->acpi_sstate = state;
+
+ /* Enable any GPEs as appropriate and requested by the user. */
+ acpi_wake_prep_walk(state);
+ slp_state = ACPI_SS_GPE_SET;
- sc->acpi_sstate = state;
+ /*
+ * Inform all devices that we are going to sleep. If at least one
+ * device fails, DEVICE_SUSPEND() automatically resumes the tree.
+ *
+ * XXX Note that a better two-pass approach with a 'veto' pass
+ * followed by a "real thing" pass would be better, but the current
+ * bus interface does not provide for this.
+ */
+ if (DEVICE_SUSPEND(root_bus) != 0) {
+ device_printf(sc->acpi_dev, "device_suspend failed\n");
+ goto backout;
+ }
+ slp_state = ACPI_SS_DEV_SUSPEND;
- /* Enable any GPEs as appropriate and requested by the user. */
- acpi_wake_prep_walk(state);
- slp_state = ACPI_SS_GPE_SET;
+ /* If testing device suspend only, back out of everything here. */
+ if (acpi_susp_bounce)
+ goto backout;
- /*
- * Inform all devices that we are going to sleep. If at least one
- * device fails, DEVICE_SUSPEND() automatically resumes the tree.
- *
- * XXX Note that a better two-pass approach with a 'veto' pass
- * followed by a "real thing" pass would be better, but the current
- * bus interface does not provide for this.
- */
- if (DEVICE_SUSPEND(root_bus) != 0) {
- device_printf(sc->acpi_dev, "device_suspend failed\n");
- break;
- }
- slp_state = ACPI_SS_DEV_SUSPEND;
+ status = AcpiEnterSleepStatePrep(state);
+ if (ACPI_FAILURE(status)) {
+ device_printf(sc->acpi_dev, "AcpiEnterSleepStatePrep failed - %s\n",
+ AcpiFormatException(status));
+ goto backout;
+ }
+ slp_state = ACPI_SS_SLP_PREP;
- /* If testing device suspend only, back out of everything here. */
- if (acpi_susp_bounce)
- break;
+ if (sc->acpi_sleep_delay > 0)
+ DELAY(sc->acpi_sleep_delay * 1000000);
+
+ if (state != ACPI_STATE_S1) {
+ acpi_sleep_machdep(sc, state);
- status = AcpiEnterSleepStatePrep(state);
+ /* Re-enable ACPI hardware on wakeup from sleep state 4. */
+ if (state == ACPI_STATE_S4)
+ AcpiEnable();
+ } else {
+ ACPI_DISABLE_IRQS();
+ status = AcpiEnterSleepState(state);
if (ACPI_FAILURE(status)) {
- device_printf(sc->acpi_dev, "AcpiEnterSleepStatePrep failed - %s\n",
+ device_printf(sc->acpi_dev, "AcpiEnterSleepState failed - %s\n",
AcpiFormatException(status));
- break;
+ goto backout;
}
- slp_state = ACPI_SS_SLP_PREP;
-
- if (sc->acpi_sleep_delay > 0)
- DELAY(sc->acpi_sleep_delay * 1000000);
-
- if (state != ACPI_STATE_S1) {
- acpi_sleep_machdep(sc, state);
-
- /* Re-enable ACPI hardware on wakeup from sleep state 4. */
- if (state == ACPI_STATE_S4)
- AcpiEnable();
- } else {
- ACPI_DISABLE_IRQS();
- status = AcpiEnterSleepState(state);
- if (ACPI_FAILURE(status)) {
- device_printf(sc->acpi_dev, "AcpiEnterSleepState failed - %s\n",
- AcpiFormatException(status));
- break;
- }
- }
- slp_state = ACPI_SS_SLEPT;
- break;
- case ACPI_STATE_S5:
- /*
- * Shut down cleanly and power off. This will call us back through the
- * shutdown handlers.
- */
- shutdown_nice(RB_POWEROFF);
- status = AE_OK;
- break;
- case ACPI_STATE_S0:
- default:
- status = AE_BAD_PARAMETER;
- break;
}
+ slp_state = ACPI_SS_SLEPT;
/*
* Back out state according to how far along we got in the suspend
* process. This handles both the error and success cases.
*/
+backout:
sc->acpi_next_sstate = 0;
if (slp_state >= ACPI_SS_GPE_SET) {
acpi_wake_prep_walk(state);
@@ -2609,8 +2603,7 @@ acpi_EnterSleepState(struct acpi_softc *
#endif
/* Allow another sleep request after a while. */
- if (state != ACPI_STATE_S5)
- timeout(acpi_sleep_enable, sc, hz * ACPI_MINIMUM_AWAKETIME);
+ timeout(acpi_sleep_enable, sc, hz * ACPI_MINIMUM_AWAKETIME);
/* Run /etc/rc.resume after we are back. */
if (devctl_process_running())
More information about the svn-src-all
mailing list