summaryrefslogtreecommitdiffstats
path: root/sys/dev/pv/xen.c
diff options
context:
space:
mode:
authormikeb <mikeb@openbsd.org>2016-01-29 19:12:26 +0000
committermikeb <mikeb@openbsd.org>2016-01-29 19:12:26 +0000
commit49e584c00d65154139aa371bd81bc92a3155a4e1 (patch)
tree789218abd3b9f47aac18ae8538c2d1c4242594c5 /sys/dev/pv/xen.c
parentAdd support for XS_WATCH: XenStore notification facility (diff)
downloadwireguard-openbsd-49e584c00d65154139aa371bd81bc92a3155a4e1.tar.xz
wireguard-openbsd-49e584c00d65154139aa371bd81bc92a3155a4e1.zip
Add support for "control/shutdown" power management facility
At the moment only "poweroff" and "reboot" actions are supported. Suspend/resume requires additional changes.
Diffstat (limited to 'sys/dev/pv/xen.c')
-rw-r--r--sys/dev/pv/xen.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/sys/dev/pv/xen.c b/sys/dev/pv/xen.c
index 3cc0d964910..8aa7565cba8 100644
--- a/sys/dev/pv/xen.c
+++ b/sys/dev/pv/xen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xen.c,v 1.47 2016/01/29 19:04:30 mikeb Exp $ */
+/* $OpenBSD: xen.c,v 1.48 2016/01/29 19:12:26 mikeb Exp $ */
/*
* Copyright (c) 2015 Mike Belopuhov
@@ -18,6 +18,9 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/signal.h>
+#include <sys/signalvar.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/device.h>
@@ -66,6 +69,7 @@ void xen_disable_emulated_devices(struct xen_softc *);
int xen_match(struct device *, void *, void *);
void xen_attach(struct device *, struct device *, void *);
void xen_deferred(struct device *);
+void xen_control(void *);
void xen_resume(struct device *);
int xen_activate(struct device *, int);
int xen_probe_devices(struct xen_softc *);
@@ -153,7 +157,6 @@ xen_attach(struct device *parent, struct device *self, void *aux)
if (xs_attach(sc))
return;
-
xen_probe_devices(sc);
/* pvbus(4) key/value interface */
@@ -177,6 +180,55 @@ xen_deferred(struct device *self)
}
xen_intr_enable();
+
+ if (xs_watch(sc, "control", "shutdown", &sc->sc_ctltsk,
+ xen_control, sc))
+ printf("%s: failed to setup shutdown control watch\n",
+ sc->sc_dev.dv_xname);
+}
+
+void
+xen_control(void *arg)
+{
+ struct xen_softc *sc = arg;
+ struct xs_transaction xst;
+ char action[128];
+
+ memset(&xst, 0, sizeof(xst));
+ xst.xst_id = 0;
+ xst.xst_sc = sc->sc_xs;
+
+ if (xs_getprop(sc, "control", "shutdown", action, sizeof(action))) {
+ printf("%s: failed to process control event\n",
+ sc->sc_dev.dv_xname);
+ return;
+ }
+
+ if (strlen(action) == 0)
+ return;
+
+ if (strcmp(action, "halt") == 0 || strcmp(action, "poweroff") == 0) {
+ extern int allowpowerdown;
+
+ if (allowpowerdown == 1) {
+ allowpowerdown = 0;
+ prsignal(initprocess, SIGUSR2);
+ }
+ } else if (strcmp(action, "reboot") == 0) {
+ extern int allowpowerdown;
+
+ if (allowpowerdown == 1) {
+ allowpowerdown = 0;
+ prsignal(initprocess, SIGINT);
+ }
+ } else if (strcmp(action, "crash") == 0) {
+ panic("xen told us to do this");
+ } else if (strcmp(action, "suspend") == 0) {
+ /* Not implemented yet */
+ } else {
+ printf("%s: unknown shutdown event \"%s\"\n",
+ sc->sc_dev.dv_xname, action);
+ }
}
void