acpi.c (185059) | acpi.c (189903) |
---|---|
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 185059 2008-11-18 21:01:54Z jhb $"); | 31__FBSDID("$FreeBSD: head/sys/dev/acpica/acpi.c 189903 2009-03-17 00:48:11Z jkim $"); |
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> 40#include <sys/bus.h> 41#include <sys/conf.h> 42#include <sys/ioccom.h> 43#include <sys/reboot.h> 44#include <sys/sysctl.h> 45#include <sys/ctype.h> 46#include <sys/linker.h> 47#include <sys/power.h> 48#include <sys/sbuf.h> | 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> 40#include <sys/bus.h> 41#include <sys/conf.h> 42#include <sys/ioccom.h> 43#include <sys/reboot.h> 44#include <sys/sysctl.h> 45#include <sys/ctype.h> 46#include <sys/linker.h> 47#include <sys/power.h> 48#include <sys/sbuf.h> |
49#ifdef SMP 50#include <sys/sched.h> 51#endif |
|
49#include <sys/smp.h> | 52#include <sys/smp.h> |
53#include <sys/timetc.h> |
|
50 51#if defined(__i386__) || defined(__amd64__) 52#include <machine/pci_cfgreg.h> 53#endif 54#include <machine/resource.h> 55#include <machine/bus.h> 56#include <sys/rman.h> 57#include <isa/isavar.h> --- 2211 unchanged lines hidden (view full) --- 2269 if (!once) { 2270 printf( 2271"warning: acpi_SetSleepState() deprecated, need to update your software\n"); 2272 once = 1; 2273 } 2274 return (acpi_EnterSleepState(sc, state)); 2275} 2276 | 54 55#if defined(__i386__) || defined(__amd64__) 56#include <machine/pci_cfgreg.h> 57#endif 58#include <machine/resource.h> 59#include <machine/bus.h> 60#include <sys/rman.h> 61#include <isa/isavar.h> --- 2211 unchanged lines hidden (view full) --- 2273 if (!once) { 2274 printf( 2275"warning: acpi_SetSleepState() deprecated, need to update your software\n"); 2276 once = 1; 2277 } 2278 return (acpi_EnterSleepState(sc, state)); 2279} 2280 |
2281#if defined(__amd64__) || defined(__i386__) |
|
2277static void 2278acpi_sleep_force(void *arg) 2279{ 2280 struct acpi_softc *sc; 2281 2282 printf("acpi: suspend request timed out, forcing sleep now\n"); 2283 sc = arg; 2284 if (ACPI_FAILURE(acpi_EnterSleepState(sc, sc->acpi_next_sstate))) 2285 printf("acpi: force sleep state S%d failed\n", sc->acpi_next_sstate); 2286} | 2282static void 2283acpi_sleep_force(void *arg) 2284{ 2285 struct acpi_softc *sc; 2286 2287 printf("acpi: suspend request timed out, forcing sleep now\n"); 2288 sc = arg; 2289 if (ACPI_FAILURE(acpi_EnterSleepState(sc, sc->acpi_next_sstate))) 2290 printf("acpi: force sleep state S%d failed\n", sc->acpi_next_sstate); 2291} |
2292#endif |
|
2287 2288/* 2289 * Request that the system enter the given suspend state. All /dev/apm 2290 * devices and devd(8) will be notified. Userland then has a chance to 2291 * save state and acknowledge the request. The system sleeps once all 2292 * acks are in. 2293 */ 2294int 2295acpi_ReqSleepState(struct acpi_softc *sc, int state) 2296{ | 2293 2294/* 2295 * Request that the system enter the given suspend state. All /dev/apm 2296 * devices and devd(8) will be notified. Userland then has a chance to 2297 * save state and acknowledge the request. The system sleeps once all 2298 * acks are in. 2299 */ 2300int 2301acpi_ReqSleepState(struct acpi_softc *sc, int state) 2302{ |
2303#if defined(__i386__) |
|
2297 struct apm_clone_data *clone; | 2304 struct apm_clone_data *clone; |
2305#endif |
|
2298 2299 if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5) 2300 return (EINVAL); 2301 2302 /* S5 (soft-off) should be entered directly with no waiting. */ 2303 if (state == ACPI_STATE_S5) { 2304 if (ACPI_SUCCESS(acpi_EnterSleepState(sc, state))) 2305 return (0); 2306 else 2307 return (ENXIO); 2308 } 2309 | 2306 2307 if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5) 2308 return (EINVAL); 2309 2310 /* S5 (soft-off) should be entered directly with no waiting. */ 2311 if (state == ACPI_STATE_S5) { 2312 if (ACPI_SUCCESS(acpi_EnterSleepState(sc, state))) 2313 return (0); 2314 else 2315 return (ENXIO); 2316 } 2317 |
2310#if !defined(__i386__) 2311 /* This platform does not support acpi suspend/resume. */ 2312 return (EOPNOTSUPP); 2313#endif 2314 | 2318#if defined(__amd64__) || defined(__i386__) |
2315 /* If a suspend request is already in progress, just return. */ 2316 ACPI_LOCK(acpi); 2317 if (sc->acpi_next_sstate != 0) { 2318 ACPI_UNLOCK(acpi); 2319 return (0); 2320 } 2321 2322 /* Record the pending state and notify all apm devices. */ 2323 sc->acpi_next_sstate = state; | 2319 /* If a suspend request is already in progress, just return. */ 2320 ACPI_LOCK(acpi); 2321 if (sc->acpi_next_sstate != 0) { 2322 ACPI_UNLOCK(acpi); 2323 return (0); 2324 } 2325 2326 /* Record the pending state and notify all apm devices. */ 2327 sc->acpi_next_sstate = state; |
2328#if defined(__i386__) |
|
2324 STAILQ_FOREACH(clone, &sc->apm_cdevs, entries) { 2325 clone->notify_status = APM_EV_NONE; 2326 if ((clone->flags & ACPI_EVF_DEVD) == 0) { 2327 selwakeuppri(&clone->sel_read, PZERO); 2328 KNOTE_UNLOCKED(&clone->sel_read.si_note, 0); 2329 } 2330 } | 2329 STAILQ_FOREACH(clone, &sc->apm_cdevs, entries) { 2330 clone->notify_status = APM_EV_NONE; 2331 if ((clone->flags & ACPI_EVF_DEVD) == 0) { 2332 selwakeuppri(&clone->sel_read, PZERO); 2333 KNOTE_UNLOCKED(&clone->sel_read.si_note, 0); 2334 } 2335 } |
2336#endif |
|
2331 2332 /* If devd(8) is not running, immediately enter the sleep state. */ 2333 if (devctl_process_running() == FALSE) { 2334 ACPI_UNLOCK(acpi); 2335 if (ACPI_SUCCESS(acpi_EnterSleepState(sc, sc->acpi_next_sstate))) { 2336 return (0); 2337 } else { 2338 return (ENXIO); --- 8 unchanged lines hidden (view full) --- 2347 * in time. This way we still eventually go to sleep if we were 2348 * overheating or running low on battery, even if userland is hung. 2349 * We cancel this timeout once all userland acks are in or the 2350 * suspend request is aborted. 2351 */ 2352 callout_reset(&sc->susp_force_to, 10 * hz, acpi_sleep_force, sc); 2353 ACPI_UNLOCK(acpi); 2354 return (0); | 2337 2338 /* If devd(8) is not running, immediately enter the sleep state. */ 2339 if (devctl_process_running() == FALSE) { 2340 ACPI_UNLOCK(acpi); 2341 if (ACPI_SUCCESS(acpi_EnterSleepState(sc, sc->acpi_next_sstate))) { 2342 return (0); 2343 } else { 2344 return (ENXIO); --- 8 unchanged lines hidden (view full) --- 2353 * in time. This way we still eventually go to sleep if we were 2354 * overheating or running low on battery, even if userland is hung. 2355 * We cancel this timeout once all userland acks are in or the 2356 * suspend request is aborted. 2357 */ 2358 callout_reset(&sc->susp_force_to, 10 * hz, acpi_sleep_force, sc); 2359 ACPI_UNLOCK(acpi); 2360 return (0); |
2361#else 2362 /* This platform does not support acpi suspend/resume. */ 2363 return (EOPNOTSUPP); 2364#endif |
|
2355} 2356 2357/* 2358 * Acknowledge (or reject) a pending sleep state. The caller has 2359 * prepared for suspend and is now ready for it to proceed. If the 2360 * error argument is non-zero, it indicates suspend should be cancelled 2361 * and gives an errno value describing why. Once all votes are in, 2362 * we suspend the system. 2363 */ 2364int 2365acpi_AckSleepState(struct apm_clone_data *clone, int error) 2366{ | 2365} 2366 2367/* 2368 * Acknowledge (or reject) a pending sleep state. The caller has 2369 * prepared for suspend and is now ready for it to proceed. If the 2370 * error argument is non-zero, it indicates suspend should be cancelled 2371 * and gives an errno value describing why. Once all votes are in, 2372 * we suspend the system. 2373 */ 2374int 2375acpi_AckSleepState(struct apm_clone_data *clone, int error) 2376{ |
2377#if defined(__amd64__) || defined(__i386__) |
|
2367 struct acpi_softc *sc; 2368 int ret, sleeping; 2369 | 2378 struct acpi_softc *sc; 2379 int ret, sleeping; 2380 |
2370#if !defined(__i386__) 2371 /* This platform does not support acpi suspend/resume. */ 2372 return (EOPNOTSUPP); 2373#endif 2374 | |
2375 /* If no pending sleep state, return an error. */ 2376 ACPI_LOCK(acpi); 2377 sc = clone->acpi_sc; 2378 if (sc->acpi_next_sstate == 0) { 2379 ACPI_UNLOCK(acpi); 2380 return (ENXIO); 2381 } 2382 --- 7 unchanged lines hidden (view full) --- 2390 return (0); 2391 } 2392 2393 /* 2394 * Mark this device as acking the suspend request. Then, walk through 2395 * all devices, seeing if they agree yet. We only count devices that 2396 * are writable since read-only devices couldn't ack the request. 2397 */ | 2381 /* If no pending sleep state, return an error. */ 2382 ACPI_LOCK(acpi); 2383 sc = clone->acpi_sc; 2384 if (sc->acpi_next_sstate == 0) { 2385 ACPI_UNLOCK(acpi); 2386 return (ENXIO); 2387 } 2388 --- 7 unchanged lines hidden (view full) --- 2396 return (0); 2397 } 2398 2399 /* 2400 * Mark this device as acking the suspend request. Then, walk through 2401 * all devices, seeing if they agree yet. We only count devices that 2402 * are writable since read-only devices couldn't ack the request. 2403 */ |
2398 clone->notify_status = APM_EV_ACKED; | |
2399 sleeping = TRUE; | 2404 sleeping = TRUE; |
2405#if defined(__i386__) 2406 clone->notify_status = APM_EV_ACKED; |
|
2400 STAILQ_FOREACH(clone, &sc->apm_cdevs, entries) { 2401 if ((clone->flags & ACPI_EVF_WRITE) != 0 && 2402 clone->notify_status != APM_EV_ACKED) { 2403 sleeping = FALSE; 2404 break; 2405 } 2406 } | 2407 STAILQ_FOREACH(clone, &sc->apm_cdevs, entries) { 2408 if ((clone->flags & ACPI_EVF_WRITE) != 0 && 2409 clone->notify_status != APM_EV_ACKED) { 2410 sleeping = FALSE; 2411 break; 2412 } 2413 } |
2414#endif |
|
2407 2408 /* If all devices have voted "yes", we will suspend now. */ 2409 if (sleeping) 2410 callout_stop(&sc->susp_force_to); 2411 ACPI_UNLOCK(acpi); 2412 ret = 0; 2413 if (sleeping) { 2414 if (ACPI_FAILURE(acpi_EnterSleepState(sc, sc->acpi_next_sstate))) 2415 ret = ENODEV; 2416 } | 2415 2416 /* If all devices have voted "yes", we will suspend now. */ 2417 if (sleeping) 2418 callout_stop(&sc->susp_force_to); 2419 ACPI_UNLOCK(acpi); 2420 ret = 0; 2421 if (sleeping) { 2422 if (ACPI_FAILURE(acpi_EnterSleepState(sc, sc->acpi_next_sstate))) 2423 ret = ENODEV; 2424 } |
2417 | |
2418 return (ret); | 2425 return (ret); |
2426#else 2427 /* This platform does not support acpi suspend/resume. */ 2428 return (EOPNOTSUPP); 2429#endif |
|
2419} 2420 2421static void 2422acpi_sleep_enable(void *arg) 2423{ 2424 2425 ((struct acpi_softc *)arg)->acpi_sleep_disabled = 0; 2426} --- 27 unchanged lines hidden (view full) --- 2454 if (sc->acpi_sleep_disabled) { 2455 ACPI_UNLOCK(acpi); 2456 printf("acpi: suspend request ignored (not ready yet)\n"); 2457 return (AE_ERROR); 2458 } 2459 sc->acpi_sleep_disabled = 1; 2460 ACPI_UNLOCK(acpi); 2461 | 2430} 2431 2432static void 2433acpi_sleep_enable(void *arg) 2434{ 2435 2436 ((struct acpi_softc *)arg)->acpi_sleep_disabled = 0; 2437} --- 27 unchanged lines hidden (view full) --- 2465 if (sc->acpi_sleep_disabled) { 2466 ACPI_UNLOCK(acpi); 2467 printf("acpi: suspend request ignored (not ready yet)\n"); 2468 return (AE_ERROR); 2469 } 2470 sc->acpi_sleep_disabled = 1; 2471 ACPI_UNLOCK(acpi); 2472 |
2473#ifdef SMP 2474 thread_lock(curthread); 2475 sched_bind(curthread, 0); 2476 thread_unlock(curthread); 2477#endif 2478 |
|
2462 /* 2463 * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE 2464 * drivers need this. 2465 */ 2466 mtx_lock(&Giant); | 2479 /* 2480 * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE 2481 * drivers need this. 2482 */ 2483 mtx_lock(&Giant); |
2484 |
|
2467 slp_state = ACPI_SS_NONE; 2468 switch (state) { 2469 case ACPI_STATE_S1: 2470 case ACPI_STATE_S2: 2471 case ACPI_STATE_S3: 2472 case ACPI_STATE_S4: 2473 status = AcpiGetSleepTypeData(state, &TypeA, &TypeB); 2474 if (status == AE_NOT_FOUND) { --- 90 unchanged lines hidden (view full) --- 2565 /* Allow another sleep request after a while. */ 2566 if (state != ACPI_STATE_S5) 2567 timeout(acpi_sleep_enable, sc, hz * ACPI_MINIMUM_AWAKETIME); 2568 2569 /* Run /etc/rc.resume after we are back. */ 2570 acpi_UserNotify("Resume", ACPI_ROOT_OBJECT, state); 2571 2572 mtx_unlock(&Giant); | 2485 slp_state = ACPI_SS_NONE; 2486 switch (state) { 2487 case ACPI_STATE_S1: 2488 case ACPI_STATE_S2: 2489 case ACPI_STATE_S3: 2490 case ACPI_STATE_S4: 2491 status = AcpiGetSleepTypeData(state, &TypeA, &TypeB); 2492 if (status == AE_NOT_FOUND) { --- 90 unchanged lines hidden (view full) --- 2583 /* Allow another sleep request after a while. */ 2584 if (state != ACPI_STATE_S5) 2585 timeout(acpi_sleep_enable, sc, hz * ACPI_MINIMUM_AWAKETIME); 2586 2587 /* Run /etc/rc.resume after we are back. */ 2588 acpi_UserNotify("Resume", ACPI_ROOT_OBJECT, state); 2589 2590 mtx_unlock(&Giant); |
2591 2592 /* Warm up timecounter again */ 2593 (void)timecounter->tc_get_timecount(timecounter); 2594 (void)timecounter->tc_get_timecount(timecounter); 2595 2596#ifdef SMP 2597 thread_lock(curthread); 2598 sched_unbind(curthread); 2599 thread_unlock(curthread); 2600#endif 2601 |
|
2573 return_ACPI_STATUS (status); 2574} 2575 2576/* Initialize a device's wake GPE. */ 2577int 2578acpi_wake_init(device_t dev, int type) 2579{ 2580 struct acpi_prw_data prw; --- 939 unchanged lines hidden --- | 2602 return_ACPI_STATUS (status); 2603} 2604 2605/* Initialize a device's wake GPE. */ 2606int 2607acpi_wake_init(device_t dev, int type) 2608{ 2609 struct acpi_prw_data prw; --- 939 unchanged lines hidden --- |