-/* $OpenBSD: acpi_machdep.c,v 1.94 2021/03/15 22:44:57 patrick Exp $ */
+/* $OpenBSD: acpi_machdep.c,v 1.95 2022/02/08 17:25:10 deraadt Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
#include <dev/isa/isareg.h>
#include <dev/pci/pcivar.h>
+#include <machine/apmvar.h>
+
#include "isa.h"
+#include "wsdisplay.h"
#include "ioapic.h"
#include "lapic.h"
#include <machine/i82489var.h>
#endif
+#include <dev/wscons/wsdisplayvar.h>
+
extern u_char acpi_real_mode_resume[], acpi_resume_end[];
extern u_char acpi_tramp_data_start[], acpi_tramp_data_end[];
extern u_int32_t acpi_pdirpa;
#ifndef SMALL_KERNEL
void
-acpi_sleep_clocks(struct acpi_softc *sc, int state)
+sleep_clocks(void *v)
{
rtcstop();
#ifdef MULTIPROCESSOR
void
-acpi_sleep_mp(void)
+sleep_mp(void)
{
int i;
}
void
-acpi_resume_mp(void)
+resume_mp(void)
{
void cpu_start_secondary(struct cpu_info *ci);
struct cpu_info *ci;
}
#endif /* MULTIPROCESSOR */
+void
+display_suspend(void *v)
+{
+#if NWSDISPLAY > 0
+ struct acpi_softc *sc = v;
+
+ /*
+ * Temporarily release the lock to prevent the X server from
+ * blocking on setting the display brightness.
+ */
+ rw_exit_write(&sc->sc_lck);
+ wsdisplay_suspend();
+ rw_enter_write(&sc->sc_lck);
+#endif /* NWSDISPLAY > 0 */
+}
+
+void
+display_resume(void *v)
+{
+#if NWSDISPLAY > 0
+ struct acpi_softc *sc = v;
+
+ rw_exit_write(&sc->sc_lck);
+ wsdisplay_resume();
+ rw_enter_write(&sc->sc_lck);
+#endif /* NWSDISPLAY > 0 */
+}
+
+void
+suspend_finish(void *v)
+{
+ struct acpi_softc *sc = v;
+ extern int lid_action;
+
+ acpi_record_event(sc, APM_NORMAL_RESUME);
+ acpi_indicator(sc, ACPI_SST_WORKING);
+
+ /* If we woke up but all the lids are closed, go back to sleep */
+ if (acpibtn_numopenlids() == 0 && lid_action != 0)
+ acpi_addtask(sc, acpi_sleep_task, sc, sc->sc_state);
+}
+
+void
+disable_lid_wakeups(void *v)
+{
+ acpibtn_disable_psw(); /* disable _LID for wakeup */
+}
+
#endif /* ! SMALL_KERNEL */
bus_dma_tag_t
-# $OpenBSD: GENERIC,v 1.510 2022/01/04 05:50:43 gnezdo Exp $
+# $OpenBSD: GENERIC,v 1.511 2022/02/08 17:25:11 deraadt Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
option MTRR # CPU memory range attributes control
option NTFS # NTFS support
-option HIBERNATE # Hibernate support
+option SUSPEND
+option HIBERNATE
config bsd swap generic
-/* $OpenBSD: acpi_machdep.c,v 1.16 2021/10/24 17:52:28 mpi Exp $ */
+/* $OpenBSD: acpi_machdep.c,v 1.17 2022/02/08 17:25:11 deraadt Exp $ */
/*
* Copyright (c) 2018 Mark Kettenis
*
}
void
-acpi_sleep_clocks(struct acpi_softc *sc, int state)
+sleep_clocks(void *)
{
}
-# $OpenBSD: GENERIC,v 1.860 2022/01/02 23:14:27 jsg Exp $
+# $OpenBSD: GENERIC,v 1.861 2022/02/08 17:25:11 deraadt Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
option MTRR # CPU memory range attributes control
option NTFS # NTFS support
-option HIBERNATE # Hibernate support
+option SUSPEND
+option HIBERNATE
config bsd swap generic
-/* $OpenBSD: acpi_machdep.c,v 1.76 2021/03/15 22:44:57 patrick Exp $ */
+/* $OpenBSD: acpi_machdep.c,v 1.77 2022/02/08 17:25:11 deraadt Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
#include <dev/acpi/acpireg.h>
#include <dev/acpi/acpivar.h>
#include <dev/acpi/acpidev.h>
+#include <dev/acpi/dsdt.h>
#include <dev/isa/isareg.h>
#include <dev/pci/pcivar.h>
+#include <machine/apmvar.h>
+
#include "apm.h"
+#include "wsdisplay.h"
#include "isa.h"
#include "ioapic.h"
#include "lapic.h"
#include <machine/i82489var.h>
#endif
+#include <dev/wscons/wsdisplayvar.h>
+
#if NAPM > 0
int haveacpibutusingapm;
#endif
#endif
void
-acpi_sleep_clocks(struct acpi_softc *sc, int state)
+sleep_clocks(void *v)
{
rtcstop();
#ifdef MULTIPROCESSOR
void
-acpi_sleep_mp(void)
+sleep_mp(void)
{
int i;
}
void
-acpi_resume_mp(void)
+resume_mp(void)
{
struct cpu_info *ci;
struct proc *p;
}
#endif /* MULTIPROCESSOR */
+void
+display_suspend(void *v)
+{
+#if NWSDISPLAY > 0
+ struct acpi_softc *sc = v;
+
+ /*
+ * Temporarily release the lock to prevent the X server from
+ * blocking on setting the display brightness.
+ */
+ rw_exit_write(&sc->sc_lck);
+ wsdisplay_suspend();
+ rw_enter_write(&sc->sc_lck);
+#endif /* NWSDISPLAY > 0 */
+}
+
+void
+display_resume(void *v)
+{
+#if NWSDISPLAY > 0
+ struct acpi_softc *sc = v;
+
+ rw_exit_write(&sc->sc_lck);
+ wsdisplay_resume();
+ rw_enter_write(&sc->sc_lck);
+#endif /* NWSDISPLAY > 0 */
+}
+
+void
+suspend_finish(void *v)
+{
+ struct acpi_softc *sc = v;
+ extern int lid_action;
+
+ acpi_record_event(sc, APM_NORMAL_RESUME);
+ acpi_indicator(sc, ACPI_SST_WORKING);
+
+ /* If we woke up but all the lids are closed, go back to sleep */
+ if (acpibtn_numopenlids() == 0 && lid_action != 0)
+ acpi_addtask(sc, acpi_sleep_task, sc, sc->sc_state);
+}
+
+void
+disable_lid_wakeups(void *v)
+{
+ acpibtn_disable_psw(); /* disable _LID for wakeup */
+}
+
#endif /* ! SMALL_KERNEL */
bus_dma_tag_t
-# $OpenBSD: files,v 1.708 2022/01/09 13:26:08 visa Exp $
+# $OpenBSD: files,v 1.709 2022/02/08 17:25:11 deraadt Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
file kern/subr_disk.c
file kern/subr_evcount.c
file kern/subr_extent.c
+file kern/subr_suspend.c suspend
file kern/subr_hibernate.c hibernate
file kern/subr_kubsan.c kubsan
file kern/subr_log.c
-/* $OpenBSD: acpi.c,v 1.409 2022/02/04 08:06:48 robert Exp $ */
+/* $OpenBSD: acpi.c,v 1.410 2022/02/08 17:25:12 deraadt Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
int acpi_gpe(struct acpi_softc *, int, void *);
void acpi_enable_rungpes(struct acpi_softc *);
-void acpi_enable_wakegpes(struct acpi_softc *, int);
-
int acpi_foundec(struct aml_node *, void *);
int acpi_foundsony(struct aml_node *node, void *arg);
#ifndef SMALL_KERNEL
-void acpi_indicator(struct acpi_softc *, int);
-
void acpi_init_pm(struct acpi_softc *);
int acpi_founddock(struct aml_node *, void *);
{
struct acpi_softc *sc = arg0;
- /* System goes to sleep here.. */
- acpi_sleep_state(sc, sleepmode);
+#ifdef SUSPEND
+ sleep_state(sc, sleepmode);
+#endif
/* Tell userland to recheck A/C and battery status */
acpi_record_event(sc, APM_POWER_CHANGE);
}
break;
#ifndef SMALL_KERNEL
case 2:
- acpi_addtask(sc, acpi_sleep_task, sc, ACPI_SLEEP_SUSPEND);
+ acpi_addtask(sc, acpi_sleep_task, sc, SLEEP_SUSPEND);
break;
#endif
}
}
}
-
-int
-acpi_sleep_state(struct acpi_softc *sc, int sleepmode)
-{
- extern int perflevel;
- extern int lid_action;
- int error = ENXIO;
- size_t rndbuflen = 0;
- char *rndbuf = NULL;
- int state, s;
-#if NSOFTRAID > 0
- extern void sr_quiesce(void);
-#endif
-
- switch (sleepmode) {
- case ACPI_SLEEP_SUSPEND:
- state = ACPI_STATE_S3;
- break;
- case ACPI_SLEEP_HIBERNATE:
- state = ACPI_STATE_S4;
- break;
- default:
- return (EOPNOTSUPP);
- }
-
- if (sc->sc_sleeptype[state].slp_typa == -1 ||
- sc->sc_sleeptype[state].slp_typb == -1) {
- printf("%s: state S%d unavailable\n",
- sc->sc_dev.dv_xname, state);
- return (EOPNOTSUPP);
- }
-
- /* 1st suspend AML step: _TTS(tostate) */
- if (aml_node_setval(sc, sc->sc_tts, state) != 0)
- goto fail_tts;
- acpi_indicator(sc, ACPI_SST_WAKING); /* blink */
-
-#if NWSDISPLAY > 0
- /*
- * Temporarily release the lock to prevent the X server from
- * blocking on setting the display brightness.
- */
- rw_exit_write(&sc->sc_lck);
- wsdisplay_suspend();
- rw_enter_write(&sc->sc_lck);
-#endif /* NWSDISPLAY > 0 */
-
- stop_periodic_resettodr();
-
-#ifdef HIBERNATE
- if (sleepmode == ACPI_SLEEP_HIBERNATE) {
- /*
- * Discard useless memory to reduce fragmentation,
- * and attempt to create a hibernate work area
- */
- hibernate_suspend_bufcache();
- uvmpd_hibernate();
- if (hibernate_alloc()) {
- printf("%s: failed to allocate hibernate memory\n",
- sc->sc_dev.dv_xname);
- goto fail_alloc;
- }
- }
-#endif /* HIBERNATE */
-
- sensor_quiesce();
- if (config_suspend_all(DVACT_QUIESCE))
- goto fail_quiesce;
-
- vfs_stall(curproc, 1);
-#if NSOFTRAID > 0
- sr_quiesce();
-#endif
- bufq_quiesce();
-
-#ifdef MULTIPROCESSOR
- acpi_sleep_mp();
-#endif
-
-#ifdef HIBERNATE
- if (sleepmode == ACPI_SLEEP_HIBERNATE) {
- /*
- * We've just done various forms of syncing to disk
- * churned lots of memory dirty. We don't need to
- * save that dirty memory to hibernate, so release it.
- */
- hibernate_suspend_bufcache();
- uvmpd_hibernate();
- }
-#endif /* HIBERNATE */
-
- resettodr();
-
- s = splhigh();
- intr_disable(); /* PSL_I for resume; PIC/APIC broken until repair */
- cold = 2; /* Force other code to delay() instead of tsleep() */
-
- if (config_suspend_all(DVACT_SUSPEND) != 0)
- goto fail_suspend;
- acpi_sleep_clocks(sc, state);
-
- suspend_randomness();
-
- /* 2nd suspend AML step: _PTS(tostate) */
- if (aml_node_setval(sc, sc->sc_pts, state) != 0)
- goto fail_pts;
-
- acpibtn_enable_psw(); /* enable _LID for wakeup */
- acpi_indicator(sc, ACPI_SST_SLEEPING);
-
- /* 3rd suspend AML step: _GTS(tostate) */
- aml_node_setval(sc, sc->sc_gts, state);
-
- /* Clear fixed event status */
- acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_ALL_STS);
-
- /* Enable wake GPEs */
- acpi_disable_allgpes(sc);
- acpi_enable_wakegpes(sc, state);
-
- /* Sleep */
- sc->sc_state = state;
- error = acpi_sleep_cpu(sc, state);
- sc->sc_state = ACPI_STATE_S0;
- /* Resume */
-
-#ifdef HIBERNATE
- if (sleepmode == ACPI_SLEEP_HIBERNATE) {
- uvm_pmr_dirty_everything();
- hib_getentropy(&rndbuf, &rndbuflen);
- }
-#endif /* HIBERNATE */
-
- acpi_resume_cpu(sc, state);
-
-fail_pts:
- config_suspend_all(DVACT_RESUME);
-
-fail_suspend:
- cold = 0;
- intr_enable();
- splx(s);
-
- acpibtn_disable_psw(); /* disable _LID for wakeup */
-
- inittodr(gettime());
-
- /* 3rd resume AML step: _TTS(runstate) */
- aml_node_setval(sc, sc->sc_tts, sc->sc_state);
-
- /* force RNG upper level reseed */
- resume_randomness(rndbuf, rndbuflen);
-
-#ifdef MULTIPROCESSOR
- acpi_resume_mp();
-#endif
-
- vfs_stall(curproc, 0);
- bufq_restart();
-
-fail_quiesce:
- config_suspend_all(DVACT_WAKEUP);
- sensor_restart();
-
-#ifdef HIBERNATE
- if (sleepmode == ACPI_SLEEP_HIBERNATE) {
- hibernate_free();
-fail_alloc:
- hibernate_resume_bufcache();
- }
-#endif /* HIBERNATE */
-
- start_periodic_resettodr();
-
-#if NWSDISPLAY > 0
- rw_exit_write(&sc->sc_lck);
- wsdisplay_resume();
- rw_enter_write(&sc->sc_lck);
-#endif /* NWSDISPLAY > 0 */
-
- sys_sync(curproc, NULL, NULL);
-
- /* Restore hw.setperf */
- if (cpu_setperf != NULL)
- cpu_setperf(perflevel);
-
- acpi_record_event(sc, APM_NORMAL_RESUME);
- acpi_indicator(sc, ACPI_SST_WORKING);
-
- /* If we woke up but all the lids are closed, go back to sleep */
- if (acpibtn_numopenlids() == 0 && lid_action != 0)
- acpi_addtask(sc, acpi_sleep_task, sc, sleepmode);
-
-fail_tts:
- return (error);
-}
-
/* XXX
* We are going to do AML execution but are not in the acpi thread.
* We do not know if the acpi thread is sleeping on acpiec in some
error = EBADF;
break;
}
- acpi_addtask(sc, acpi_sleep_task, sc, ACPI_SLEEP_SUSPEND);
+ acpi_addtask(sc, acpi_sleep_task, sc, SLEEP_SUSPEND);
acpi_wakeup(sc);
break;
#ifdef HIBERNATE
error = EOPNOTSUPP;
break;
}
- acpi_addtask(sc, acpi_sleep_task, sc, ACPI_SLEEP_HIBERNATE);
+ acpi_addtask(sc, acpi_sleep_task, sc, SLEEP_HIBERNATE);
acpi_wakeup(sc);
break;
#endif
return (0);
}
+int
+sleep_showstate(void *v, int sleepmode)
+{
+ struct acpi_softc *sc = v;
+
+ switch (sleepmode) {
+ case SLEEP_SUSPEND:
+ sc->sc_state = ACPI_STATE_S3;
+ break;
+ case SLEEP_HIBERNATE:
+ sc->sc_state = ACPI_STATE_S4;
+ break;
+ default:
+ return (EOPNOTSUPP);
+ }
+
+ if (sc->sc_sleeptype[sc->sc_state].slp_typa == -1 ||
+ sc->sc_sleeptype[sc->sc_state].slp_typb == -1) {
+ printf("%s: state S%d unavailable\n",
+ sc->sc_dev.dv_xname, sc->sc_state);
+ return (EOPNOTSUPP);
+ }
+
+ /* 1st suspend AML step: _TTS(tostate) */
+ if (aml_node_setval(sc, sc->sc_tts, sc->sc_state) != 0)
+ return (EINVAL);
+ acpi_indicator(sc, ACPI_SST_WAKING); /* blink */
+ return 0;
+}
+
+int
+sleep_setstate(void *v)
+{
+ struct acpi_softc *sc = v;
+
+ /* 2nd suspend AML step: _PTS(tostate) */
+ if (aml_node_setval(sc, sc->sc_pts, sc->sc_state) != 0)
+ return (EINVAL);
+ acpi_indicator(sc, ACPI_SST_WAKING); /* blink */
+ return 0;
+}
+
+void
+gosleep(void *v)
+{
+ struct acpi_softc *sc = v;
+
+ acpibtn_enable_psw(); /* enable _LID for wakeup */
+ acpi_indicator(v, ACPI_SST_SLEEPING);
+
+ /* 3rd suspend AML step: _GTS(tostate) */
+ aml_node_setval(sc, sc->sc_gts, sc->sc_state);
+
+ /* Clear fixed event status */
+ acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_ALL_STS);
+
+ /* Enable wake GPEs */
+ acpi_disable_allgpes(sc);
+ acpi_enable_wakegpes(sc, sc->sc_state);
+
+ /* Sleep */
+ acpi_sleep_cpu(sc, sc->sc_state);
+ sc->sc_state = ACPI_STATE_S0;
+ /* Resume */
+
+ acpi_resume_cpu(sc, sc->sc_state);
+}
+
+int
+sleep_resume(void *v)
+{
+ struct acpi_softc *sc = v;
+
+ /* 3rd resume AML step: _TTS(runstate) */
+ if (aml_node_setval(sc, sc->sc_tts, sc->sc_state) != 0)
+ return (EINVAL);
+ acpi_indicator(sc, ACPI_SST_WAKING); /* blink */
+ return 0;
+}
+
#else /* SMALL_KERNEL */
int
-/* $OpenBSD: acpibtn.c,v 1.47 2019/01/20 02:45:44 tedu Exp $ */
+/* $OpenBSD: acpibtn.c,v 1.48 2022/02/08 17:25:12 deraadt Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
*
/* Request to go to sleep */
if (acpi_record_event(sc->sc_acpi, APM_USER_HIBERNATE_REQ))
acpi_addtask(sc->sc_acpi, acpi_sleep_task,
- sc->sc_acpi, ACPI_SLEEP_HIBERNATE);
+ sc->sc_acpi, SLEEP_HIBERNATE);
break;
#endif
default:
/* Request to go to sleep */
if (acpi_record_event(sc->sc_acpi, APM_USER_SUSPEND_REQ))
acpi_addtask(sc->sc_acpi, acpi_sleep_task,
- sc->sc_acpi, ACPI_SLEEP_SUSPEND);
+ sc->sc_acpi, SLEEP_SUSPEND);
break;
}
#endif /* SMALL_KERNEL */
-/* $OpenBSD: acpisony.c,v 1.8 2020/04/06 00:01:08 pirofti Exp $ */
+/* $OpenBSD: acpisony.c,v 1.9 2022/02/08 17:25:12 deraadt Exp $ */
/*
* Copyright (c) 2010 Paul Irofti <paul@irofti.net>
*
#ifndef SMALL_KERNEL
if (acpi_record_event(sc->sc_acpi, APM_USER_SUSPEND_REQ))
acpi_addtask(sc->sc_acpi, acpi_sleep_task,
- sc->sc_acpi, ACPI_SLEEP_SUSPEND);
+ sc->sc_acpi, SLEEP_SUSPEND);
#endif
break;
case SONY_NOTIFY_SUSPEND_RELEASED:
-/* $OpenBSD: acpithinkpad.c,v 1.68 2019/12/31 01:38:33 jsg Exp $ */
+/* $OpenBSD: acpithinkpad.c,v 1.69 2022/02/08 17:25:12 deraadt Exp $ */
/*
* Copyright (c) 2008 joshua stein <jcs@openbsd.org>
*
#ifndef SMALL_KERNEL
if (acpi_record_event(sc->sc_acpi, APM_USER_SUSPEND_REQ))
acpi_addtask(sc->sc_acpi, acpi_sleep_task,
- sc->sc_acpi, ACPI_SLEEP_SUSPEND);
+ sc->sc_acpi, SLEEP_SUSPEND);
#endif
break;
case THINKPAD_BUTTON_VOLUME_MUTE:
#if defined(HIBERNATE) && !defined(SMALL_KERNEL)
if (acpi_record_event(sc->sc_acpi, APM_USER_HIBERNATE_REQ))
acpi_addtask(sc->sc_acpi, acpi_sleep_task,
- sc->sc_acpi, ACPI_SLEEP_HIBERNATE);
+ sc->sc_acpi, SLEEP_HIBERNATE);
#endif
break;
case THINKPAD_BUTTON_THINKLIGHT:
-/* $OpenBSD: acpitoshiba.c,v 1.13 2020/03/16 08:51:48 jasper Exp $ */
+/* $OpenBSD: acpitoshiba.c,v 1.14 2022/02/08 17:25:12 deraadt Exp $ */
/*-
* Copyright (c) 2003 Hiroyuki Aizu <aizu@navi.org>
* All rights reserved.
#ifndef SMALL_KERNEL
if (acpi_record_event(sc->sc_acpi, APM_USER_SUSPEND_REQ)) {
acpi_addtask(sc->sc_acpi, acpi_sleep_task,
- sc->sc_acpi, ACPI_SLEEP_SUSPEND);
+ sc->sc_acpi, SLEEP_SUSPEND);
ret = HCI_SUCCESS;
}
#endif
#if defined(HIBERNATE) && !defined(SMALL_KERNEL)
if (acpi_record_event(sc->sc_acpi, APM_USER_HIBERNATE_REQ)) {
acpi_addtask(sc->sc_acpi, acpi_sleep_task,
- sc->sc_acpi, ACPI_SLEEP_HIBERNATE);
+ sc->sc_acpi, SLEEP_HIBERNATE);
ret = HCI_SUCCESS;
}
#endif
-/* $OpenBSD: acpivar.h,v 1.117 2022/02/01 18:09:00 deraadt Exp $ */
+/* $OpenBSD: acpivar.h,v 1.118 2022/02/08 17:25:12 deraadt Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
void acpi_powerdown(void);
void acpi_reset(void);
-
-#define ACPI_SLEEP_SUSPEND 0x01
-#define ACPI_SLEEP_HIBERNATE 0x02
-
-int acpi_sleep_state(struct acpi_softc *, int);
-void acpi_sleep_clocks(struct acpi_softc *, int);
int acpi_sleep_cpu(struct acpi_softc *, int);
-void acpi_sleep_mp(void);
void acpi_sleep_pm(struct acpi_softc *, int);
void acpi_resume_pm(struct acpi_softc *, int);
void acpi_resume_cpu(struct acpi_softc *, int);
-void acpi_resume_mp(void);
void acpi_sleep_walk(struct acpi_softc *, int);
-
#define ACPI_IOREAD 0
#define ACPI_IOWRITE 1
int acpi_getprop(struct aml_node *, const char *, void *, int);
uint64_t acpi_getpropint(struct aml_node *, const char *, uint64_t);
+void acpi_indicator(struct acpi_softc *, int);
+void acpi_disable_allgpes(struct acpi_softc *);
+void acpi_enable_wakegpes(struct acpi_softc *, int);
+
int acpi_record_event(struct acpi_softc *, u_int);
void acpi_addtask(struct acpi_softc *, void (*)(void *, int), void *, int);
--- /dev/null
+/* $OpenBSD: subr_suspend.c,v 1.1 2022/02/08 17:25:12 deraadt Exp $ */
+/*
+ * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
+ * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/malloc.h>
+#include <sys/pool.h>
+#include <sys/proc.h>
+#include <sys/sensors.h>
+#include <sys/sysctl.h>
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+#include <dev/wscons/wsdisplayvar.h>
+#ifdef HIBERNATE
+#include <sys/hibernate.h>
+#endif
+
+#include "softraid.h"
+
+int
+sleep_state(void *v, int sleepmode)
+{
+ int error = ENXIO;
+ extern int perflevel;
+ size_t rndbuflen = 0;
+ char *rndbuf = NULL;
+ int s;
+#if NSOFTRAID > 0
+ extern void sr_quiesce(void);
+#endif
+
+ if (sleep_showstate(v, sleepmode))
+ return EOPNOTSUPP;
+
+ display_suspend(v);
+
+ stop_periodic_resettodr();
+
+#ifdef HIBERNATE
+ if (sleepmode == SLEEP_HIBERNATE) {
+ /*
+ * Discard useless memory to reduce fragmentation,
+ * and attempt to create a hibernate work area
+ */
+ hibernate_suspend_bufcache();
+ uvmpd_hibernate();
+ if (hibernate_alloc()) {
+ printf("failed to allocate hibernate memory\n");
+ goto fail_alloc;
+ }
+ }
+#endif /* HIBERNATE */
+
+ sensor_quiesce();
+ if (config_suspend_all(DVACT_QUIESCE))
+ goto fail_quiesce;
+
+ vfs_stall(curproc, 1);
+#if NSOFTRAID > 0
+ sr_quiesce();
+#endif
+ bufq_quiesce();
+
+
+#ifdef MULTIPROCESSOR
+ sleep_mp();
+#endif
+
+#ifdef HIBERNATE
+ if (sleepmode == SLEEP_HIBERNATE) {
+ /*
+ * We've just done various forms of syncing to disk
+ * churned lots of memory dirty. We don't need to
+ * save that dirty memory to hibernate, so release it.
+ */
+ hibernate_suspend_bufcache();
+ uvmpd_hibernate();
+ }
+#endif /* HIBERNATE */
+
+ resettodr();
+
+ s = splhigh();
+ intr_disable(); /* PSL_I for resume; PIC/APIC broken until repair */
+ cold = 2; /* Force other code to delay() instead of tsleep() */
+
+ if (config_suspend_all(DVACT_SUSPEND) != 0)
+ goto fail_suspend;
+ sleep_clocks(v);
+
+ suspend_randomness();
+
+ if (sleep_setstate(v))
+ goto fail_pts;
+
+ gosleep(v);
+
+#ifdef HIBERNATE
+ if (sleepmode == SLEEP_HIBERNATE) {
+ uvm_pmr_dirty_everything();
+ hib_getentropy(&rndbuf, &rndbuflen);
+ }
+#endif /* HIBERNATE */
+
+fail_pts:
+ config_suspend_all(DVACT_RESUME);
+
+fail_suspend:
+ cold = 0;
+ intr_enable();
+ splx(s);
+
+ disable_lid_wakeups(v);
+
+ inittodr(gettime());
+
+ sleep_resume(v);
+
+ /* force RNG upper level reseed */
+ resume_randomness(rndbuf, rndbuflen);
+
+#ifdef MULTIPROCESSOR
+ resume_mp();
+#endif
+
+ vfs_stall(curproc, 0);
+ bufq_restart();
+
+fail_quiesce:
+ config_suspend_all(DVACT_WAKEUP);
+ sensor_restart();
+
+#ifdef HIBERNATE
+ if (sleepmode == SLEEP_HIBERNATE) {
+ hibernate_free();
+fail_alloc:
+ hibernate_resume_bufcache();
+ }
+#endif /* HIBERNATE */
+
+ start_periodic_resettodr();
+
+ display_resume(v);
+
+ sys_sync(curproc, NULL, NULL);
+
+ /* Restore hw.setperf */
+ if (cpu_setperf != NULL)
+ cpu_setperf(perflevel);
+
+ suspend_finish(v);
+
+ return (error);
+}
-/* $OpenBSD: device.h,v 1.56 2021/10/26 16:29:49 deraadt Exp $ */
+/* $OpenBSD: device.h,v 1.57 2022/02/08 17:25:12 deraadt Exp $ */
/* $NetBSD: device.h,v 1.15 1996/04/09 20:55:24 cgd Exp $ */
/*
void config_mountroot(struct device *, void (*)(struct device *));
void config_process_deferred_mountroot(void);
+int sleep_state(void *, int);
+#define SLEEP_SUSPEND 0x01
+#define SLEEP_HIBERNATE 0x02
+void sleep_clocks(void *);
+void sleep_mp(void);
+void resume_mp(void);
+int sleep_showstate(void *v, int sleepmode);
+int sleep_setstate(void *v);
+int sleep_resume(void *v);
+void gosleep(void *v);
+void display_suspend(void *v);
+void display_resume(void *v);
+void suspend_finish(void *v);
+void disable_lid_wakeups(void *v);
+
struct device *device_mainbus(void);
struct device *device_mpath(void);
struct device *device_lookup(struct cfdriver *, int unit);