svn commit: r194352 - projects/mesh11s/sys/dev/acpica
Rui Paulo
rpaulo at FreeBSD.org
Wed Jun 17 11:43:34 UTC 2009
Author: rpaulo
Date: Wed Jun 17 11:43:33 2009
New Revision: 194352
URL: http://svn.freebsd.org/changeset/base/194352
Log:
fix mismerge
Modified:
projects/mesh11s/sys/dev/acpica/acpi.c
Modified: projects/mesh11s/sys/dev/acpica/acpi.c
==============================================================================
--- projects/mesh11s/sys/dev/acpica/acpi.c Wed Jun 17 11:42:51 2009 (r194351)
+++ projects/mesh11s/sys/dev/acpica/acpi.c Wed Jun 17 11:43:33 2009 (r194352)
@@ -61,11 +61,12 @@ __FBSDID("$FreeBSD$");
#include <isa/isavar.h>
#include <isa/pnpvar.h>
-#include <contrib/dev/acpica/acpi.h>
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
#include <dev/acpica/acpivar.h>
#include <dev/acpica/acpiio.h>
-#include <contrib/dev/acpica/achware.h>
-#include <contrib/dev/acpica/acnamesp.h>
#include "pci_if.h"
#include <dev/pci/pcivar.h>
@@ -97,6 +98,9 @@ struct mtx acpi_mutex;
/* Bitmap of device quirks. */
int acpi_quirks;
+/* Supported sleep states. */
+static BOOLEAN acpi_sleep_states[ACPI_S_STATE_COUNT];
+
static int acpi_modevent(struct module *mod, int event, void *junk);
static int acpi_probe(device_t dev);
static int acpi_attach(device_t dev);
@@ -142,6 +146,8 @@ static void acpi_probe_order(ACPI_HANDLE
static ACPI_STATUS acpi_probe_child(ACPI_HANDLE handle, UINT32 level,
void *context, void **status);
static BOOLEAN acpi_MatchHid(ACPI_HANDLE h, const char *hid);
+static void acpi_sleep_enable(void *arg);
+static ACPI_STATUS acpi_sleep_disable(struct acpi_softc *sc);
static ACPI_STATUS acpi_EnterSleepState(struct acpi_softc *sc, int state);
static void acpi_shutdown_final(void *arg, int howto);
static void acpi_enable_fixed_events(struct acpi_softc *sc);
@@ -152,6 +158,8 @@ static int acpi_wake_sysctl_walk(device_
static int acpi_wake_set_sysctl(SYSCTL_HANDLER_ARGS);
static void acpi_system_eventhandler_sleep(void *arg, int state);
static void acpi_system_eventhandler_wakeup(void *arg, int state);
+static int acpi_sname2sstate(const char *sname);
+static const char *acpi_sstate2sname(int sstate);
static int acpi_supported_sleep_state_sysctl(SYSCTL_HANDLER_ARGS);
static int acpi_sleep_state_sysctl(SYSCTL_HANDLER_ARGS);
static int acpi_pm_func(u_long cmd, void *arg, ...);
@@ -227,9 +235,6 @@ static struct rman acpi_rman_io, acpi_rm
#define ACPI_MINIMUM_AWAKETIME 5
-static const char* sleep_state_names[] = {
- "S0", "S1", "S2", "S3", "S4", "S5", "NONE"};
-
/* Holds the description of the acpi0 device. */
static char acpi_desc[ACPI_OEM_ID_SIZE + ACPI_OEM_TABLE_ID_SIZE + 2];
@@ -254,6 +259,12 @@ TUNABLE_INT("debug.acpi.do_powerstate",
SYSCTL_INT(_debug_acpi, OID_AUTO, do_powerstate, CTLFLAG_RW,
&acpi_do_powerstate, 1, "Turn off devices when suspending.");
+/* Reset system clock while resuming. XXX Remove once tested. */
+static int acpi_reset_clock = 1;
+TUNABLE_INT("debug.acpi.reset_clock", &acpi_reset_clock);
+SYSCTL_INT(_debug_acpi, OID_AUTO, reset_clock, CTLFLAG_RW,
+ &acpi_reset_clock, 1, "Reset system clock while resuming.");
+
/* Allow users to override quirks. */
TUNABLE_INT("debug.acpi.quirks", &acpi_quirks);
@@ -406,7 +417,6 @@ static int
acpi_attach(device_t dev)
{
struct acpi_softc *sc;
- ACPI_TABLE_FACS *facs;
ACPI_STATUS status;
int error, state;
UINT32 flags;
@@ -583,29 +593,31 @@ acpi_attach(device_t dev)
}
/* Only enable S4BIOS by default if the FACS says it is available. */
- status = AcpiGetTable(ACPI_SIG_FACS, 0, (ACPI_TABLE_HEADER **)&facs);
- if (ACPI_FAILURE(status)) {
- device_printf(dev, "couldn't get FACS: %s\n",
- AcpiFormatException(status));
- error = ENXIO;
- goto out;
- }
- if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT)
+ if (AcpiGbl_FACS->Flags & ACPI_FACS_S4_BIOS_PRESENT)
sc->acpi_s4bios = 1;
+ /* Probe all supported sleep states. */
+ acpi_sleep_states[ACPI_STATE_S0] = TRUE;
+ for (state = ACPI_STATE_S1; state < ACPI_S_STATE_COUNT; state++)
+ if (ACPI_SUCCESS(AcpiGetSleepTypeData(state, &TypeA, &TypeB)))
+ acpi_sleep_states[state] = TRUE;
+
/*
* Dispatch the default sleep state to devices. The lid switch is set
- * to NONE by default to avoid surprising users.
+ * to UNKNOWN by default to avoid surprising users.
*/
- sc->acpi_power_button_sx = ACPI_STATE_S5;
- sc->acpi_lid_switch_sx = ACPI_S_STATES_MAX + 1;
- sc->acpi_standby_sx = ACPI_STATE_S1;
- sc->acpi_suspend_sx = ACPI_STATE_S3;
+ sc->acpi_power_button_sx = acpi_sleep_states[ACPI_STATE_S5] ?
+ ACPI_STATE_S5 : ACPI_STATE_UNKNOWN;
+ sc->acpi_lid_switch_sx = ACPI_STATE_UNKNOWN;
+ sc->acpi_standby_sx = acpi_sleep_states[ACPI_STATE_S1] ?
+ ACPI_STATE_S1 : ACPI_STATE_UNKNOWN;
+ sc->acpi_suspend_sx = acpi_sleep_states[ACPI_STATE_S3] ?
+ ACPI_STATE_S3 : ACPI_STATE_UNKNOWN;
/* Pick the first valid sleep state for the sleep button default. */
- sc->acpi_sleep_button_sx = ACPI_S_STATES_MAX + 1;
+ sc->acpi_sleep_button_sx = ACPI_STATE_UNKNOWN;
for (state = ACPI_STATE_S1; state <= ACPI_STATE_S4; state++)
- if (ACPI_SUCCESS(AcpiGetSleepTypeData(state, &TypeA, &TypeB))) {
+ if (acpi_sleep_states[state]) {
sc->acpi_sleep_button_sx = state;
break;
}
@@ -630,9 +642,9 @@ acpi_attach(device_t dev)
sc, ACPI_EVENT_PRI_LAST);
/* Flag our initial states. */
- sc->acpi_enabled = 1;
+ sc->acpi_enabled = TRUE;
sc->acpi_sstate = ACPI_STATE_S0;
- sc->acpi_sleep_disabled = 0;
+ sc->acpi_sleep_disabled = TRUE;
/* Create the control device */
sc->acpi_dev_t = make_dev(&acpi_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644,
@@ -648,6 +660,9 @@ acpi_attach(device_t dev)
if (!acpi_disabled("bus"))
acpi_probe_children(dev);
+ /* Allow sleep request after a while. */
+ timeout(acpi_sleep_enable, sc, hz * ACPI_MINIMUM_AWAKETIME);
+
error = 0;
out:
@@ -880,7 +895,7 @@ acpi_read_ivar(device_t dev, device_t ch
struct acpi_device *ad;
if ((ad = device_get_ivars(child)) == NULL) {
- printf("device has no ivars\n");
+ device_printf(child, "device has no ivars\n");
return (ENOENT);
}
@@ -919,7 +934,7 @@ acpi_write_ivar(device_t dev, device_t c
struct acpi_device *ad;
if ((ad = device_get_ivars(child)) == NULL) {
- printf("device has no ivars\n");
+ device_printf(child, "device has no ivars\n");
return (ENOENT);
}
@@ -1523,7 +1538,7 @@ acpi_set_powerstate_method(device_t bus,
error = 0;
h = acpi_get_handle(child);
- if (state < ACPI_STATE_D0 || state > ACPI_STATE_D3)
+ if (state < ACPI_STATE_D0 || state > ACPI_D_STATES_MAX)
return (EINVAL);
if (h == NULL)
return (0);
@@ -1797,7 +1812,7 @@ acpi_fake_objhandler(ACPI_HANDLE h, UINT
static void
acpi_shutdown_final(void *arg, int howto)
{
- struct acpi_softc *sc;
+ struct acpi_softc *sc = (struct acpi_softc *)arg;
ACPI_STATUS status;
/*
@@ -1805,42 +1820,42 @@ acpi_shutdown_final(void *arg, int howto
* Some chipsets do not power off the system correctly if called from
* an AP.
*/
- sc = arg;
if ((howto & RB_POWEROFF) != 0) {
status = AcpiEnterSleepStatePrep(ACPI_STATE_S5);
if (ACPI_FAILURE(status)) {
- printf("AcpiEnterSleepStatePrep failed - %s\n",
- AcpiFormatException(status));
+ device_printf(sc->acpi_dev, "AcpiEnterSleepStatePrep failed - %s\n",
+ AcpiFormatException(status));
return;
}
- printf("Powering system off using ACPI\n");
+ device_printf(sc->acpi_dev, "Powering system off\n");
ACPI_DISABLE_IRQS();
status = AcpiEnterSleepState(ACPI_STATE_S5);
- if (ACPI_FAILURE(status)) {
- printf("ACPI power-off failed - %s\n", AcpiFormatException(status));
- } else {
+ if (ACPI_FAILURE(status))
+ device_printf(sc->acpi_dev, "power-off failed - %s\n",
+ AcpiFormatException(status));
+ else {
DELAY(1000000);
- printf("ACPI power-off failed - timeout\n");
+ device_printf(sc->acpi_dev, "power-off failed - timeout\n");
}
} else if ((howto & RB_HALT) == 0 &&
(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER) &&
sc->acpi_handle_reboot) {
/* Reboot using the reset register. */
- status = AcpiHwLowLevelWrite(
- AcpiGbl_FADT.ResetRegister.BitWidth,
+ status = AcpiWrite(
AcpiGbl_FADT.ResetValue, &AcpiGbl_FADT.ResetRegister);
- if (ACPI_FAILURE(status)) {
- printf("ACPI reset failed - %s\n", AcpiFormatException(status));
- } else {
+ if (ACPI_FAILURE(status))
+ device_printf(sc->acpi_dev, "reset failed - %s\n",
+ AcpiFormatException(status));
+ else {
DELAY(1000000);
- printf("ACPI reset failed - timeout\n");
+ device_printf(sc->acpi_dev, "reset failed - timeout\n");
}
} else if (sc->acpi_do_disable && panicstr == NULL) {
/*
* Only disable ACPI if the user requested. On some systems, writing
* the disable value to SMI_CMD hangs the system.
*/
- printf("Shutting down ACPI\n");
+ device_printf(sc->acpi_dev, "Shutting down\n");
AcpiTerminate();
}
}
@@ -2271,7 +2286,7 @@ acpi_SetSleepState(struct acpi_softc *sc
static int once;
if (!once) {
- printf(
+ device_printf(sc->acpi_dev,
"warning: acpi_SetSleepState() deprecated, need to update your software\n");
once = 1;
}
@@ -2282,12 +2297,13 @@ acpi_SetSleepState(struct acpi_softc *sc
static void
acpi_sleep_force(void *arg)
{
- struct acpi_softc *sc;
+ struct acpi_softc *sc = (struct acpi_softc *)arg;
- printf("acpi: suspend request timed out, forcing sleep now\n");
- sc = arg;
+ device_printf(sc->acpi_dev,
+ "suspend request timed out, forcing sleep now\n");
if (ACPI_FAILURE(acpi_EnterSleepState(sc, sc->acpi_next_sstate)))
- printf("acpi: force sleep state S%d failed\n", sc->acpi_next_sstate);
+ device_printf(sc->acpi_dev, "force sleep state S%d failed\n",
+ sc->acpi_next_sstate);
}
#endif
@@ -2304,8 +2320,10 @@ acpi_ReqSleepState(struct acpi_softc *sc
struct apm_clone_data *clone;
#endif
- if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5)
+ if (state < ACPI_STATE_S1 || state > ACPI_S_STATES_MAX)
return (EINVAL);
+ if (!acpi_sleep_states[state])
+ return (EOPNOTSUPP);
/* S5 (soft-off) should be entered directly with no waiting. */
if (state == ACPI_STATE_S5) {
@@ -2336,7 +2354,7 @@ acpi_ReqSleepState(struct acpi_softc *sc
#endif
/* If devd(8) is not running, immediately enter the sleep state. */
- if (devctl_process_running() == FALSE) {
+ if (!devctl_process_running()) {
ACPI_UNLOCK(acpi);
if (ACPI_SUCCESS(acpi_EnterSleepState(sc, sc->acpi_next_sstate))) {
return (0);
@@ -2345,9 +2363,6 @@ acpi_ReqSleepState(struct acpi_softc *sc
}
}
- /* Now notify devd(8) also. */
- acpi_UserNotify("Suspend", ACPI_ROOT_OBJECT, state);
-
/*
* Set a timeout to fire if userland doesn't ack the suspend request
* in time. This way we still eventually go to sleep if we were
@@ -2357,6 +2372,10 @@ acpi_ReqSleepState(struct acpi_softc *sc
*/
callout_reset(&sc->susp_force_to, 10 * hz, acpi_sleep_force, sc);
ACPI_UNLOCK(acpi);
+
+ /* Now notify devd(8) also. */
+ acpi_UserNotify("Suspend", ACPI_ROOT_OBJECT, state);
+
return (0);
#else
/* This platform does not support acpi suspend/resume. */
@@ -2390,7 +2409,8 @@ acpi_AckSleepState(struct apm_clone_data
if (error) {
sc->acpi_next_sstate = 0;
callout_stop(&sc->susp_force_to);
- printf("acpi: listener on %s cancelled the pending suspend\n",
+ device_printf(sc->acpi_dev,
+ "listener on %s cancelled the pending suspend\n",
devtoname(clone->cdev));
ACPI_UNLOCK(acpi);
return (0);
@@ -2432,8 +2452,34 @@ acpi_AckSleepState(struct apm_clone_data
static void
acpi_sleep_enable(void *arg)
{
+ struct acpi_softc *sc = (struct acpi_softc *)arg;
- ((struct acpi_softc *)arg)->acpi_sleep_disabled = 0;
+ /* Reschedule if the system is not fully up and running. */
+ if (!AcpiGbl_SystemAwakeAndRunning) {
+ timeout(acpi_sleep_enable, sc, hz * ACPI_MINIMUM_AWAKETIME);
+ return;
+ }
+
+ ACPI_LOCK(acpi);
+ sc->acpi_sleep_disabled = FALSE;
+ ACPI_UNLOCK(acpi);
+}
+
+static ACPI_STATUS
+acpi_sleep_disable(struct acpi_softc *sc)
+{
+ ACPI_STATUS status;
+
+ /* Fail if the system is not fully up and running. */
+ if (!AcpiGbl_SystemAwakeAndRunning)
+ return (AE_ERROR);
+
+ ACPI_LOCK(acpi);
+ status = sc->acpi_sleep_disabled ? AE_ERROR : AE_OK;
+ sc->acpi_sleep_disabled = TRUE;
+ ACPI_UNLOCK(acpi);
+
+ return (status);
}
enum acpi_sleep_state {
@@ -2453,22 +2499,34 @@ static ACPI_STATUS
acpi_EnterSleepState(struct acpi_softc *sc, int state)
{
ACPI_STATUS status;
- UINT8 TypeA;
- UINT8 TypeB;
enum acpi_sleep_state slp_state;
ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, state);
+ if (state < ACPI_STATE_S1 || state > ACPI_S_STATES_MAX)
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if (!acpi_sleep_states[state]) {
+ device_printf(sc->acpi_dev, "Sleep state S%d not supported by BIOS\n",
+ state);
+ return (AE_SUPPORT);
+ }
+
/* Re-entry once we're suspending is not allowed. */
- status = AE_OK;
- ACPI_LOCK(acpi);
- if (sc->acpi_sleep_disabled) {
- ACPI_UNLOCK(acpi);
- printf("acpi: suspend request ignored (not ready yet)\n");
- return (AE_ERROR);
+ status = acpi_sleep_disable(sc);
+ if (ACPI_FAILURE(status)) {
+ device_printf(sc->acpi_dev,
+ "suspend request ignored (not ready yet)\n");
+ return (status);
+ }
+
+ 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);
}
- sc->acpi_sleep_disabled = 1;
- ACPI_UNLOCK(acpi);
#ifdef SMP
thread_lock(curthread);
@@ -2483,91 +2541,64 @@ 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;
- }
- sc->acpi_sstate = state;
+ 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;
+ /* Enable any GPEs as appropriate and requested by the user. */
+ acpi_wake_prep_walk(state);
+ slp_state = ACPI_SS_GPE_SET;
- /*
- * 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;
+ /*
+ * 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;
- /* If testing device suspend only, back out of everything here. */
- if (acpi_susp_bounce)
- break;
+ /* If testing device suspend only, back out of everything here. */
+ if (acpi_susp_bounce)
+ goto backout;
- status = AcpiEnterSleepStatePrep(state);
- if (ACPI_FAILURE(status)) {
- device_printf(sc->acpi_dev, "AcpiEnterSleepStatePrep failed - %s\n",
- AcpiFormatException(status));
- break;
- }
- slp_state = ACPI_SS_SLP_PREP;
+ 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 (sc->acpi_sleep_delay > 0)
- DELAY(sc->acpi_sleep_delay * 1000000);
+ if (sc->acpi_sleep_delay > 0)
+ DELAY(sc->acpi_sleep_delay * 1000000);
- if (state != ACPI_STATE_S1) {
- acpi_sleep_machdep(sc, state);
+ 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;
- }
+ /* 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));
+ goto backout;
}
- 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);
- 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);
@@ -2580,28 +2611,39 @@ acpi_EnterSleepState(struct acpi_softc *
if (slp_state >= ACPI_SS_SLEPT)
acpi_enable_fixed_events(sc);
- /* Allow another sleep request after a while. */
- if (state != ACPI_STATE_S5)
- timeout(acpi_sleep_enable, sc, hz * ACPI_MINIMUM_AWAKETIME);
-
- /* Run /etc/rc.resume after we are back. */
- acpi_UserNotify("Resume", ACPI_ROOT_OBJECT, state);
-
mtx_unlock(&Giant);
- /* Warm up timecounter again */
- (void)timecounter->tc_get_timecount(timecounter);
- (void)timecounter->tc_get_timecount(timecounter);
-
#ifdef SMP
thread_lock(curthread);
sched_unbind(curthread);
thread_unlock(curthread);
#endif
+ /* Allow another sleep request after a while. */
+ timeout(acpi_sleep_enable, sc, hz * ACPI_MINIMUM_AWAKETIME);
+
+ /* Run /etc/rc.resume after we are back. */
+ if (devctl_process_running())
+ acpi_UserNotify("Resume", ACPI_ROOT_OBJECT, state);
+
return_ACPI_STATUS (status);
}
+void
+acpi_resync_clock(struct acpi_softc *sc)
+{
+
+ if (!acpi_reset_clock)
+ return;
+
+ /*
+ * Warm up timecounter again and reset system clock.
+ */
+ (void)timecounter->tc_get_timecount(timecounter);
+ (void)timecounter->tc_get_timecount(timecounter);
+ inittodr(time_second + sc->acpi_sleep_delay);
+}
+
/* Initialize a device's wake GPE. */
int
acpi_wake_init(device_t dev, int type)
@@ -2906,19 +2948,20 @@ out:
static void
acpi_system_eventhandler_sleep(void *arg, int state)
{
+ struct acpi_softc *sc = (struct acpi_softc *)arg;
int ret;
ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, state);
- /* Check if button action is disabled. */
- if (state == ACPI_S_STATES_MAX + 1)
+ /* Check if button action is disabled or unknown. */
+ if (state == ACPI_STATE_UNKNOWN)
return;
/* Request that the system prepare to enter the given suspend state. */
- ret = acpi_ReqSleepState((struct acpi_softc *)arg, state);
+ ret = acpi_ReqSleepState(sc, state);
if (ret != 0)
- printf("acpi: request to enter state S%d failed (err %d)\n",
- state, ret);
+ device_printf(sc->acpi_dev,
+ "request to enter state S%d failed (err %d)\n", state, ret);
return_VOID;
}
@@ -3135,19 +3178,19 @@ acpi_deregister_ioctl(u_long cmd, acpi_i
}
static int
-acpiopen(struct cdev *dev, int flag, int fmt, d_thread_t *td)
+acpiopen(struct cdev *dev, int flag, int fmt, struct thread *td)
{
return (0);
}
static int
-acpiclose(struct cdev *dev, int flag, int fmt, d_thread_t *td)
+acpiclose(struct cdev *dev, int flag, int fmt, struct thread *td)
{
return (0);
}
static int
-acpiioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, d_thread_t *td)
+acpiioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
{
struct acpi_softc *sc;
struct acpi_ioctl_hook *hp;
@@ -3183,22 +3226,22 @@ acpiioctl(struct cdev *dev, u_long cmd,
case ACPIIO_REQSLPSTATE:
state = *(int *)addr;
if (state != ACPI_STATE_S5)
- error = acpi_ReqSleepState(sc, state);
- else {
- printf("power off via acpi ioctl not supported\n");
- error = ENXIO;
- }
+ return (acpi_ReqSleepState(sc, state));
+ device_printf(sc->acpi_dev, "power off via acpi ioctl not supported\n");
+ error = EOPNOTSUPP;
break;
case ACPIIO_ACKSLPSTATE:
error = *(int *)addr;
error = acpi_AckSleepState(sc->acpi_clone, error);
break;
case ACPIIO_SETSLPSTATE: /* DEPRECATED */
- error = EINVAL;
state = *(int *)addr;
- if (state >= ACPI_STATE_S0 && state <= ACPI_S_STATES_MAX)
- if (ACPI_SUCCESS(acpi_SetSleepState(sc, state)))
- error = 0;
+ if (state < ACPI_STATE_S0 || state > ACPI_S_STATES_MAX)
+ return (EINVAL);
+ if (!acpi_sleep_states[state])
+ return (EOPNOTSUPP);
+ if (ACPI_FAILURE(acpi_SetSleepState(sc, state)))
+ error = ENXIO;
break;
default:
error = ENXIO;
@@ -3209,16 +3252,43 @@ acpiioctl(struct cdev *dev, u_long cmd,
}
static int
+acpi_sname2sstate(const char *sname)
+{
+ int sstate;
+
+ if (toupper(sname[0]) == 'S') {
+ sstate = sname[1] - '0';
+ if (sstate >= ACPI_STATE_S0 && sstate <= ACPI_STATE_S5 &&
+ sname[2] == '\0')
+ return (sstate);
+ } else if (strcasecmp(sname, "NONE") == 0)
+ return (ACPI_STATE_UNKNOWN);
+ return (-1);
+}
+
+static const char *
+acpi_sstate2sname(int sstate)
+{
+ static const char *snames[] = { "S0", "S1", "S2", "S3", "S4", "S5" };
+
+ if (sstate >= ACPI_STATE_S0 && sstate <= ACPI_STATE_S5)
+ return (snames[sstate]);
+ else if (sstate == ACPI_STATE_UNKNOWN)
+ return ("NONE");
+ return (NULL);
+}
+
+static int
acpi_supported_sleep_state_sysctl(SYSCTL_HANDLER_ARGS)
{
int error;
struct sbuf sb;
- UINT8 state, TypeA, TypeB;
+ UINT8 state;
sbuf_new(&sb, NULL, 32, SBUF_AUTOEXTEND);
- for (state = ACPI_STATE_S1; state < ACPI_S_STATES_MAX + 1; state++)
- if (ACPI_SUCCESS(AcpiGetSleepTypeData(state, &TypeA, &TypeB)))
- sbuf_printf(&sb, "S%d ", state);
+ for (state = ACPI_STATE_S1; state < ACPI_S_STATE_COUNT; state++)
+ if (acpi_sleep_states[state])
+ sbuf_printf(&sb, "%s ", acpi_sstate2sname(state));
sbuf_trim(&sb);
sbuf_finish(&sb);
error = sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req);
@@ -3230,27 +3300,20 @@ static int
acpi_sleep_state_sysctl(SYSCTL_HANDLER_ARGS)
{
char sleep_state[10];
- int error;
- u_int new_state, old_state;
+ int error, new_state, old_state;
- old_state = *(u_int *)oidp->oid_arg1;
- if (old_state > ACPI_S_STATES_MAX + 1)
- strlcpy(sleep_state, "unknown", sizeof(sleep_state));
- else
- strlcpy(sleep_state, sleep_state_names[old_state], sizeof(sleep_state));
+ old_state = *(int *)oidp->oid_arg1;
+ strlcpy(sleep_state, acpi_sstate2sname(old_state), sizeof(sleep_state));
error = sysctl_handle_string(oidp, sleep_state, sizeof(sleep_state), req);
if (error == 0 && req->newptr != NULL) {
- new_state = ACPI_STATE_S0;
- for (; new_state <= ACPI_S_STATES_MAX + 1; new_state++)
- if (strcmp(sleep_state, sleep_state_names[new_state]) == 0)
- break;
- if (new_state <= ACPI_S_STATES_MAX + 1) {
- if (new_state != old_state)
- *(u_int *)oidp->oid_arg1 = new_state;
- } else
- error = EINVAL;
+ new_state = acpi_sname2sstate(sleep_state);
+ if (new_state < ACPI_STATE_S1)
+ return (EINVAL);
+ if (new_state < ACPI_S_STATE_COUNT && !acpi_sleep_states[new_state])
+ return (EOPNOTSUPP);
+ if (new_state != old_state)
+ *(int *)oidp->oid_arg1 = new_state;
}
-
return (error);
}
@@ -3320,8 +3383,6 @@ static struct debugtag dbg_layer[] = {
};
static struct debugtag dbg_level[] = {
- {"ACPI_LV_ERROR", ACPI_LV_ERROR},
- {"ACPI_LV_WARN", ACPI_LV_WARN},
{"ACPI_LV_INIT", ACPI_LV_INIT},
{"ACPI_LV_DEBUG_OBJECT", ACPI_LV_DEBUG_OBJECT},
{"ACPI_LV_INFO", ACPI_LV_INFO},
More information about the svn-src-projects
mailing list