summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2016-01-29 19:12:27 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2016-01-29 19:12:27 +0000
commitead7befaa50eb741fc37b35b4430859c93cd5c7d (patch)
tree9e30d71edf81e8ec989d104e79096dc663cd72c8 /sys/dev
parent9b71ebe0292ea9b021d59343d6b8d0dc14fc786f (diff)
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')
-rw-r--r--sys/dev/pv/xen.c56
-rw-r--r--sys/dev/pv/xenvar.h4
2 files changed, 57 insertions, 3 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
diff --git a/sys/dev/pv/xenvar.h b/sys/dev/pv/xenvar.h
index f381e9ed24d..29c013d2ad0 100644
--- a/sys/dev/pv/xenvar.h
+++ b/sys/dev/pv/xenvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: xenvar.h,v 1.27 2016/01/29 19:04:30 mikeb Exp $ */
+/* $OpenBSD: xenvar.h,v 1.28 2016/01/29 19:12:26 mikeb Exp $ */
/*
* Copyright (c) 2015 Mike Belopuhov
@@ -78,6 +78,8 @@ struct xen_softc {
* Xenstore
*/
struct xs_softc *sc_xs; /* xenstore softc */
+
+ struct task sc_ctltsk; /* control task */
};
extern struct xen_softc *xen_sc;