diff options
author | 2016-01-29 19:12:26 +0000 | |
---|---|---|
committer | 2016-01-29 19:12:26 +0000 | |
commit | 49e584c00d65154139aa371bd81bc92a3155a4e1 (patch) | |
tree | 789218abd3b9f47aac18ae8538c2d1c4242594c5 /sys/dev/pv/xen.c | |
parent | Add support for XS_WATCH: XenStore notification facility (diff) | |
download | wireguard-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.c | 56 |
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 |