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 --- |