Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 17 Jun 2009 11:43:33 +0000 (UTC)
From:      Rui Paulo <rpaulo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r194352 - projects/mesh11s/sys/dev/acpica
Message-ID:  <200906171143.n5HBhX1G074380@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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},



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906171143.n5HBhX1G074380>