Deleted Added
full compact
acpi.c (170783) acpi.c (170976)
1/*-
2 * Copyright (c) 2000 Takanori Watanabe <takawata@jp.freebsd.org>
3 * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
4 * Copyright (c) 2000, 2001 Michael Smith
5 * Copyright (c) 2000 BSDi
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2000 Takanori Watanabe <takawata@jp.freebsd.org>
3 * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
4 * Copyright (c) 2000, 2001 Michael Smith
5 * Copyright (c) 2000 BSDi
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/acpica/acpi.c 170783 2007-06-15 18:02:34Z njl $");
31__FBSDID("$FreeBSD: head/sys/dev/acpica/acpi.c 170976 2007-06-21 22:50:37Z njl $");
32
33#include "opt_acpi.h"
34#include <sys/param.h>
35#include <sys/kernel.h>
36#include <sys/proc.h>
37#include <sys/fcntl.h>
38#include <sys/malloc.h>
39#include <sys/module.h>

--- 91 unchanged lines hidden (view full) ---

131 int state);
132static int acpi_isa_pnp_probe(device_t bus, device_t child,
133 struct isa_pnp_id *ids);
134static void acpi_probe_children(device_t bus);
135static int acpi_probe_order(ACPI_HANDLE handle, int *order);
136static ACPI_STATUS acpi_probe_child(ACPI_HANDLE handle, UINT32 level,
137 void *context, void **status);
138static BOOLEAN acpi_MatchHid(ACPI_HANDLE h, const char *hid);
32
33#include "opt_acpi.h"
34#include <sys/param.h>
35#include <sys/kernel.h>
36#include <sys/proc.h>
37#include <sys/fcntl.h>
38#include <sys/malloc.h>
39#include <sys/module.h>

--- 91 unchanged lines hidden (view full) ---

131 int state);
132static int acpi_isa_pnp_probe(device_t bus, device_t child,
133 struct isa_pnp_id *ids);
134static void acpi_probe_children(device_t bus);
135static int acpi_probe_order(ACPI_HANDLE handle, int *order);
136static ACPI_STATUS acpi_probe_child(ACPI_HANDLE handle, UINT32 level,
137 void *context, void **status);
138static BOOLEAN acpi_MatchHid(ACPI_HANDLE h, const char *hid);
139static ACPI_STATUS acpi_EnterSleepState(struct acpi_softc *sc, int state);
139static void acpi_shutdown_final(void *arg, int howto);
140static void acpi_enable_fixed_events(struct acpi_softc *sc);
141static int acpi_wake_sleep_prep(ACPI_HANDLE handle, int sstate);
142static int acpi_wake_run_prep(ACPI_HANDLE handle, int sstate);
143static int acpi_wake_prep_walk(int sstate);
144static int acpi_wake_sysctl_walk(device_t dev);
145static int acpi_wake_set_sysctl(SYSCTL_HANDLER_ARGS);
146static void acpi_system_eventhandler_sleep(void *arg, int state);

--- 258 unchanged lines hidden (view full) ---

405 UINT32 flags;
406 UINT8 TypeA, TypeB;
407 char *env;
408
409 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
410
411 sc = device_get_softc(dev);
412 sc->acpi_dev = dev;
140static void acpi_shutdown_final(void *arg, int howto);
141static void acpi_enable_fixed_events(struct acpi_softc *sc);
142static int acpi_wake_sleep_prep(ACPI_HANDLE handle, int sstate);
143static int acpi_wake_run_prep(ACPI_HANDLE handle, int sstate);
144static int acpi_wake_prep_walk(int sstate);
145static int acpi_wake_sysctl_walk(device_t dev);
146static int acpi_wake_set_sysctl(SYSCTL_HANDLER_ARGS);
147static void acpi_system_eventhandler_sleep(void *arg, int state);

--- 258 unchanged lines hidden (view full) ---

406 UINT32 flags;
407 UINT8 TypeA, TypeB;
408 char *env;
409
410 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
411
412 sc = device_get_softc(dev);
413 sc->acpi_dev = dev;
414 callout_init(&sc->susp_force_to, TRUE);
413
414 error = ENXIO;
415
416 /* Initialize resource manager. */
417 acpi_rman_io.rm_type = RMAN_ARRAY;
418 acpi_rman_io.rm_start = 0;
419 acpi_rman_io.rm_end = 0xffff;
420 acpi_rman_io.rm_descr = "ACPI I/O ports";

--- 166 unchanged lines hidden (view full) ---

587 */
588 sc->acpi_power_button_sx = ACPI_STATE_S5;
589 sc->acpi_lid_switch_sx = ACPI_S_STATES_MAX + 1;
590 sc->acpi_standby_sx = ACPI_STATE_S1;
591 sc->acpi_suspend_sx = ACPI_STATE_S3;
592
593 /* Pick the first valid sleep state for the sleep button default. */
594 sc->acpi_sleep_button_sx = ACPI_S_STATES_MAX + 1;
415
416 error = ENXIO;
417
418 /* Initialize resource manager. */
419 acpi_rman_io.rm_type = RMAN_ARRAY;
420 acpi_rman_io.rm_start = 0;
421 acpi_rman_io.rm_end = 0xffff;
422 acpi_rman_io.rm_descr = "ACPI I/O ports";

--- 166 unchanged lines hidden (view full) ---

589 */
590 sc->acpi_power_button_sx = ACPI_STATE_S5;
591 sc->acpi_lid_switch_sx = ACPI_S_STATES_MAX + 1;
592 sc->acpi_standby_sx = ACPI_STATE_S1;
593 sc->acpi_suspend_sx = ACPI_STATE_S3;
594
595 /* Pick the first valid sleep state for the sleep button default. */
596 sc->acpi_sleep_button_sx = ACPI_S_STATES_MAX + 1;
595 for (state = ACPI_STATE_S1; state < ACPI_STATE_S5; state++)
597 for (state = ACPI_STATE_S1; state <= ACPI_STATE_S4; state++)
596 if (ACPI_SUCCESS(AcpiGetSleepTypeData(state, &TypeA, &TypeB))) {
597 sc->acpi_sleep_button_sx = state;
598 break;
599 }
600
601 acpi_enable_fixed_events(sc);
602
603 /*

--- 1509 unchanged lines hidden (view full) ---

2113 */
2114ACPI_STATUS
2115acpi_SetIntrModel(int model)
2116{
2117
2118 return (acpi_SetInteger(ACPI_ROOT_OBJECT, "_PIC", model));
2119}
2120
598 if (ACPI_SUCCESS(AcpiGetSleepTypeData(state, &TypeA, &TypeB))) {
599 sc->acpi_sleep_button_sx = state;
600 break;
601 }
602
603 acpi_enable_fixed_events(sc);
604
605 /*

--- 1509 unchanged lines hidden (view full) ---

2115 */
2116ACPI_STATUS
2117acpi_SetIntrModel(int model)
2118{
2119
2120 return (acpi_SetInteger(ACPI_ROOT_OBJECT, "_PIC", model));
2121}
2122
2123/*
2124 * DEPRECATED. This interface has serious deficiencies and will be
2125 * removed.
2126 *
2127 * Immediately enter the sleep state. In the old model, acpiconf(8) ran
2128 * rc.suspend and rc.resume so we don't have to notify devd(8) to do this.
2129 */
2130ACPI_STATUS
2131acpi_SetSleepState(struct acpi_softc *sc, int state)
2132{
2133 static int once;
2134
2135 if (!once) {
2136 printf(
2137"warning: acpi_SetSleepState() deprecated, need to update your software\n");
2138 once = 1;
2139 }
2140 return (acpi_EnterSleepState(sc, state));
2141}
2142
2121static void
2143static void
2144acpi_sleep_force(void *arg)
2145{
2146 struct acpi_softc *sc;
2147
2148 printf("acpi: suspend request timed out, forcing sleep now\n");
2149 sc = arg;
2150 if (ACPI_FAILURE(acpi_EnterSleepState(sc, sc->acpi_next_sstate)))
2151 printf("acpi: force sleep state S%d failed\n", sc->acpi_next_sstate);
2152}
2153
2154/*
2155 * Request that the system enter the given suspend state. All /dev/apm
2156 * devices and devd(8) will be notified. Userland then has a chance to
2157 * save state and acknowledge the request. The system sleeps once all
2158 * acks are in.
2159 */
2160int
2161acpi_ReqSleepState(struct acpi_softc *sc, int state)
2162{
2163 struct apm_clone_data *clone;
2164
2165 if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5)
2166 return (EINVAL);
2167
2168 /* S5 (soft-off) should be entered directly with no waiting. */
2169 if (state == ACPI_STATE_S5) {
2170 if (ACPI_SUCCESS(acpi_EnterSleepState(sc, state)))
2171 return (0);
2172 else
2173 return (ENXIO);
2174 }
2175
2176 /* If a suspend request is already in progress, just return. */
2177 ACPI_LOCK(acpi);
2178 if (sc->acpi_next_sstate != 0) {
2179 ACPI_UNLOCK(acpi);
2180 return (0);
2181 }
2182
2183 /* Record the pending state and notify all apm devices. */
2184 sc->acpi_next_sstate = state;
2185 STAILQ_FOREACH(clone, &sc->apm_cdevs, entries) {
2186 clone->notify_status = APM_EV_NONE;
2187 if ((clone->flags & ACPI_EVF_DEVD) == 0) {
2188 selwakeuppri(&clone->sel_read, PZERO);
2189 KNOTE_UNLOCKED(&clone->sel_read.si_note, 0);
2190 }
2191 }
2192
2193 /* Now notify devd(8) also. */
2194 acpi_UserNotify("Suspend", ACPI_ROOT_OBJECT, state);
2195
2196 /*
2197 * Set a timeout to fire if userland doesn't ack the suspend request
2198 * in time. This way we still eventually go to sleep if we were
2199 * overheating or running low on battery, even if userland is hung.
2200 * We cancel this timeout once all userland acks are in or the
2201 * suspend request is aborted.
2202 */
2203 callout_reset(&sc->susp_force_to, 10 * hz, acpi_sleep_force, sc);
2204 ACPI_UNLOCK(acpi);
2205 return (0);
2206}
2207
2208/*
2209 * Acknowledge (or reject) a pending sleep state. The caller has
2210 * prepared for suspend and is now ready for it to proceed. If the
2211 * error argument is non-zero, it indicates suspend should be cancelled
2212 * and gives an errno value describing why. Once all votes are in,
2213 * we suspend the system.
2214 */
2215int
2216acpi_AckSleepState(struct apm_clone_data *clone, int error)
2217{
2218 struct acpi_softc *sc;
2219 int ret, sleeping;
2220
2221 /* If no pending sleep state, return an error. */
2222 ACPI_LOCK(acpi);
2223 sc = clone->acpi_sc;
2224 if (sc->acpi_next_sstate == 0) {
2225 ACPI_UNLOCK(acpi);
2226 return (ENXIO);
2227 }
2228
2229 /* Caller wants to abort suspend process. */
2230 if (error) {
2231 sc->acpi_next_sstate = 0;
2232 callout_stop(&sc->susp_force_to);
2233 printf("acpi: listener on %s cancelled the pending suspend\n",
2234 devtoname(clone->cdev));
2235 ACPI_UNLOCK(acpi);
2236 return (0);
2237 }
2238
2239 /*
2240 * Mark this device as acking the suspend request. Then, walk through
2241 * all devices, seeing if they agree yet. We only count devices that
2242 * are writable since read-only devices couldn't ack the request.
2243 */
2244 clone->notify_status = APM_EV_ACKED;
2245 sleeping = TRUE;
2246 STAILQ_FOREACH(clone, &sc->apm_cdevs, entries) {
2247 if ((clone->flags & ACPI_EVF_WRITE) != 0 &&
2248 clone->notify_status != APM_EV_ACKED) {
2249 sleeping = FALSE;
2250 break;
2251 }
2252 }
2253
2254 /* If all devices have voted "yes", we will suspend now. */
2255 if (sleeping)
2256 callout_stop(&sc->susp_force_to);
2257 ACPI_UNLOCK(acpi);
2258 ret = 0;
2259 if (sleeping) {
2260 if (ACPI_FAILURE(acpi_EnterSleepState(sc, sc->acpi_next_sstate)))
2261 ret = ENODEV;
2262 }
2263
2264 return (ret);
2265}
2266
2267static void
2122acpi_sleep_enable(void *arg)
2123{
2124
2125 ((struct acpi_softc *)arg)->acpi_sleep_disabled = 0;
2126}
2127
2128enum acpi_sleep_state {
2129 ACPI_SS_NONE,
2130 ACPI_SS_GPE_SET,
2131 ACPI_SS_DEV_SUSPEND,
2132 ACPI_SS_SLP_PREP,
2133 ACPI_SS_SLEPT,
2134};
2135
2136/*
2268acpi_sleep_enable(void *arg)
2269{
2270
2271 ((struct acpi_softc *)arg)->acpi_sleep_disabled = 0;
2272}
2273
2274enum acpi_sleep_state {
2275 ACPI_SS_NONE,
2276 ACPI_SS_GPE_SET,
2277 ACPI_SS_DEV_SUSPEND,
2278 ACPI_SS_SLP_PREP,
2279 ACPI_SS_SLEPT,
2280};
2281
2282/*
2137 * Set the system sleep state
2283 * Enter the desired system sleep state.
2138 *
2139 * Currently we support S1-S5 but S4 is only S4BIOS
2140 */
2284 *
2285 * Currently we support S1-S5 but S4 is only S4BIOS
2286 */
2141ACPI_STATUS
2142acpi_SetSleepState(struct acpi_softc *sc, int state)
2287static ACPI_STATUS
2288acpi_EnterSleepState(struct acpi_softc *sc, int state)
2143{
2144 ACPI_STATUS status;
2145 UINT8 TypeA;
2146 UINT8 TypeB;
2147 enum acpi_sleep_state slp_state;
2148
2149 ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, state);
2150
2289{
2290 ACPI_STATUS status;
2291 UINT8 TypeA;
2292 UINT8 TypeB;
2293 enum acpi_sleep_state slp_state;
2294
2295 ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, state);
2296
2297 /* Re-entry once we're suspending is not allowed. */
2151 status = AE_OK;
2152 ACPI_LOCK(acpi);
2153 if (sc->acpi_sleep_disabled) {
2298 status = AE_OK;
2299 ACPI_LOCK(acpi);
2300 if (sc->acpi_sleep_disabled) {
2154 if (sc->acpi_sstate != ACPI_STATE_S0)
2155 status = AE_ERROR;
2156 ACPI_UNLOCK(acpi);
2157 printf("acpi: suspend request ignored (not ready yet)\n");
2301 ACPI_UNLOCK(acpi);
2302 printf("acpi: suspend request ignored (not ready yet)\n");
2158 return (status);
2303 return (AE_ERROR);
2159 }
2160 sc->acpi_sleep_disabled = 1;
2161 ACPI_UNLOCK(acpi);
2162
2163 /*
2164 * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE
2165 * drivers need this.
2166 */

--- 79 unchanged lines hidden (view full) ---

2246 status = AE_BAD_PARAMETER;
2247 break;
2248 }
2249
2250 /*
2251 * Back out state according to how far along we got in the suspend
2252 * process. This handles both the error and success cases.
2253 */
2304 }
2305 sc->acpi_sleep_disabled = 1;
2306 ACPI_UNLOCK(acpi);
2307
2308 /*
2309 * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE
2310 * drivers need this.
2311 */

--- 79 unchanged lines hidden (view full) ---

2391 status = AE_BAD_PARAMETER;
2392 break;
2393 }
2394
2395 /*
2396 * Back out state according to how far along we got in the suspend
2397 * process. This handles both the error and success cases.
2398 */
2399 sc->acpi_next_sstate = 0;
2254 if (slp_state >= ACPI_SS_GPE_SET) {
2255 acpi_wake_prep_walk(state);
2256 sc->acpi_sstate = ACPI_STATE_S0;
2257 }
2258 if (slp_state >= ACPI_SS_SLP_PREP)
2259 AcpiLeaveSleepState(state);
2260 if (slp_state >= ACPI_SS_DEV_SUSPEND)
2261 DEVICE_RESUME(root_bus);
2262 if (slp_state >= ACPI_SS_SLEPT)
2263 acpi_enable_fixed_events(sc);
2264
2265 /* Allow another sleep request after a while. */
2266 if (state != ACPI_STATE_S5)
2400 if (slp_state >= ACPI_SS_GPE_SET) {
2401 acpi_wake_prep_walk(state);
2402 sc->acpi_sstate = ACPI_STATE_S0;
2403 }
2404 if (slp_state >= ACPI_SS_SLP_PREP)
2405 AcpiLeaveSleepState(state);
2406 if (slp_state >= ACPI_SS_DEV_SUSPEND)
2407 DEVICE_RESUME(root_bus);
2408 if (slp_state >= ACPI_SS_SLEPT)
2409 acpi_enable_fixed_events(sc);
2410
2411 /* Allow another sleep request after a while. */
2412 if (state != ACPI_STATE_S5)
2267 timeout(acpi_sleep_enable, (caddr_t)sc, hz * ACPI_MINIMUM_AWAKETIME);
2413 timeout(acpi_sleep_enable, sc, hz * ACPI_MINIMUM_AWAKETIME);
2268
2414
2415 /* Run /etc/rc.resume after we are back. */
2416 acpi_UserNotify("Resume", ACPI_ROOT_OBJECT, state);
2417
2269 mtx_unlock(&Giant);
2270 return_ACPI_STATUS (status);
2271}
2272
2273/* Initialize a device's wake GPE. */
2274int
2275acpi_wake_init(device_t dev, int type)
2276{

--- 292 unchanged lines hidden (view full) ---

2569 * ACPI Event Handlers
2570 */
2571
2572/* System Event Handlers (registered by EVENTHANDLER_REGISTER) */
2573
2574static void
2575acpi_system_eventhandler_sleep(void *arg, int state)
2576{
2418 mtx_unlock(&Giant);
2419 return_ACPI_STATUS (status);
2420}
2421
2422/* Initialize a device's wake GPE. */
2423int
2424acpi_wake_init(device_t dev, int type)
2425{

--- 292 unchanged lines hidden (view full) ---

2718 * ACPI Event Handlers
2719 */
2720
2721/* System Event Handlers (registered by EVENTHANDLER_REGISTER) */
2722
2723static void
2724acpi_system_eventhandler_sleep(void *arg, int state)
2725{
2726 int ret;
2577
2578 ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, state);
2579
2727
2728 ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, state);
2729
2580 if (state >= ACPI_STATE_S0 && state <= ACPI_S_STATES_MAX)
2581 acpi_SetSleepState((struct acpi_softc *)arg, state);
2730 /* Request that the system prepare to enter the given suspend state. */
2731 ret = acpi_ReqSleepState((struct acpi_softc *)arg, state);
2732 if (ret != 0)
2733 printf("acpi: request to enter state S%d failed (err %d)\n",
2734 state, ret);
2582
2583 return_VOID;
2584}
2585
2586static void
2587acpi_system_eventhandler_wakeup(void *arg, int state)
2588{
2589

--- 245 unchanged lines hidden (view full) ---

2835 * Currently, other ioctls just fetch information.
2836 * Not changing system behavior.
2837 */
2838 if ((flag & FWRITE) == 0)
2839 return (EPERM);
2840
2841 /* Core system ioctls. */
2842 switch (cmd) {
2735
2736 return_VOID;
2737}
2738
2739static void
2740acpi_system_eventhandler_wakeup(void *arg, int state)
2741{
2742

--- 245 unchanged lines hidden (view full) ---

2988 * Currently, other ioctls just fetch information.
2989 * Not changing system behavior.
2990 */
2991 if ((flag & FWRITE) == 0)
2992 return (EPERM);
2993
2994 /* Core system ioctls. */
2995 switch (cmd) {
2843 case ACPIIO_SETSLPSTATE:
2996 case ACPIIO_REQSLPSTATE:
2997 state = *(int *)addr;
2998 if (state != ACPI_STATE_S5)
2999 error = acpi_ReqSleepState(sc, state);
3000 else {
3001 printf("power off via acpi ioctl not supported\n");
3002 error = ENXIO;
3003 }
3004 break;
3005 case ACPIIO_ACKSLPSTATE:
3006 error = *(int *)addr;
3007 error = acpi_AckSleepState(sc->acpi_clone, error);
3008 break;
3009 case ACPIIO_SETSLPSTATE: /* DEPRECATED */
2844 error = EINVAL;
2845 state = *(int *)addr;
2846 if (state >= ACPI_STATE_S0 && state <= ACPI_S_STATES_MAX)
2847 if (ACPI_SUCCESS(acpi_SetSleepState(sc, state)))
2848 error = 0;
2849 break;
2850 default:
2851 error = ENXIO;

--- 314 unchanged lines hidden (view full) ---

3166 case POWER_SLEEP_STATE_HIBERNATE:
3167 acpi_state = ACPI_STATE_S4;
3168 break;
3169 default:
3170 error = EINVAL;
3171 goto out;
3172 }
3173
3010 error = EINVAL;
3011 state = *(int *)addr;
3012 if (state >= ACPI_STATE_S0 && state <= ACPI_S_STATES_MAX)
3013 if (ACPI_SUCCESS(acpi_SetSleepState(sc, state)))
3014 error = 0;
3015 break;
3016 default:
3017 error = ENXIO;

--- 314 unchanged lines hidden (view full) ---

3332 case POWER_SLEEP_STATE_HIBERNATE:
3333 acpi_state = ACPI_STATE_S4;
3334 break;
3335 default:
3336 error = EINVAL;
3337 goto out;
3338 }
3339
3174 acpi_SetSleepState(sc, acpi_state);
3340 if (ACPI_FAILURE(acpi_EnterSleepState(sc, acpi_state)))
3341 error = ENXIO;
3175 break;
3176 default:
3177 error = EINVAL;
3178 goto out;
3179 }
3180
3181out:
3182 return (error);

--- 12 unchanged lines hidden ---
3342 break;
3343 default:
3344 error = EINVAL;
3345 goto out;
3346 }
3347
3348out:
3349 return (error);

--- 12 unchanged lines hidden ---