diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2012-03-26 20:18:15 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2012-03-26 20:18:15 +0000 |
commit | 8768245e39f55870ee40c5bfb14d78b3a260b746 (patch) | |
tree | d50ac4510495d4f3e1f30810725882a3a5e315c5 /sys/dev | |
parent | 7b7a83afe518f7a384a53392dd1a7ec2f4541d71 (diff) |
hook in the hibernate request code; half of this diff is from mlarkin
ok mlarkin
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/acpi/acpi.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c index 8dcfbc546f0..938e260fb26 100644 --- a/sys/dev/acpi/acpi.c +++ b/sys/dev/acpi/acpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi.c,v 1.228 2011/09/20 14:06:26 deraadt Exp $ */ +/* $OpenBSD: acpi.c,v 1.229 2012/03/26 20:18:14 deraadt Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> @@ -29,6 +29,7 @@ #include <sys/kthread.h> #include <sys/workq.h> #include <sys/sched.h> +#include <sys/reboot.h> #include <machine/conf.h> #include <machine/cpufunc.h> @@ -95,6 +96,7 @@ void acpi_pbtn_task(void *, int); int acpi_thinkpad_enabled; int acpi_toshiba_enabled; int acpi_saved_spl; +int acpi_saved_boothowto; int acpi_enabled; int acpi_matchhids(struct acpi_attach_args *aa, const char *hids[], @@ -1836,13 +1838,12 @@ acpi_sleep_state(struct acpi_softc *sc, int state) switch (state) { case ACPI_STATE_S0: return (0); - case ACPI_STATE_S4: - return (EOPNOTSUPP); case ACPI_STATE_S5: break; case ACPI_STATE_S1: case ACPI_STATE_S2: case ACPI_STATE_S3: + case ACPI_STATE_S4: if (sc->sc_sleeptype[state].slp_typa == -1 || sc->sc_sleeptype[state].slp_typb == -1) return (EOPNOTSUPP); @@ -1857,7 +1858,7 @@ acpi_sleep_state(struct acpi_softc *sc, int state) ret = acpi_enter_sleep_state(sc, state); #ifndef SMALL_KERNEL - if (state == ACPI_STATE_S3) + if (state == ACPI_STATE_S3 || state == ACPI_STATE_S4) acpi_resume(sc, state); #endif /* !SMALL_KERNEL */ return (ret); @@ -1952,6 +1953,9 @@ acpi_resume(struct acpi_softc *sc, int state) acpi_disable_allgpes(sc); acpi_enable_rungpes(sc); + if (state == ACPI_STATE_S4) + boothowto = acpi_saved_boothowto; + config_suspend(TAILQ_FIRST(&alldevs), DVACT_RESUME); cold = 0; @@ -2059,12 +2063,16 @@ acpi_prepare_sleep_state(struct acpi_softc *sc, int state) return (ENXIO); } + if (state == ACPI_STATE_S4) + printf("%s: hibernating to disk ...\n", DEVNAME(sc)); + #if NWSDISPLAY > 0 - if (state == ACPI_STATE_S3) + if (state == ACPI_STATE_S3 || state == ACPI_STATE_S4) wsdisplay_suspend(); #endif /* NWSDISPLAY > 0 */ - resettodr(); + if (state == ACPI_STATE_S3) + resettodr(); bufq_quiesce(); config_suspend(TAILQ_FIRST(&alldevs), DVACT_QUIESCE); @@ -2072,7 +2080,11 @@ acpi_prepare_sleep_state(struct acpi_softc *sc, int state) acpi_saved_spl = splhigh(); disable_intr(); cold = 1; - if (state == ACPI_STATE_S3) + if (state == ACPI_STATE_S4) { + acpi_saved_boothowto = boothowto; + boothowto = RB_RDONLY; + } + if (state == ACPI_STATE_S3 || state == ACPI_STATE_S4) if (config_suspend(TAILQ_FIRST(&alldevs), DVACT_SUSPEND) != 0) { acpi_handle_suspend_failure(sc); error = ENXIO; @@ -2507,6 +2519,16 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) acpi_wakeup(sc); } break; +#ifdef HIBERNATE + case APM_IOC_HIBERNATE: + if ((flag & FWRITE) == 0) { + error = EBADF; + } else { + acpi_addtask(sc, acpi_sleep_task, sc, ACPI_STATE_S4); + acpi_wakeup(sc); + } + break; +#endif case APM_IOC_GETPOWER: /* A/C */ pi->ac_state = APM_AC_UNKNOWN; |