Deleted Added
full compact
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 ---