diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-01-29 19:12:27 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-01-29 19:12:27 +0000 |
commit | ead7befaa50eb741fc37b35b4430859c93cd5c7d (patch) | |
tree | 9e30d71edf81e8ec989d104e79096dc663cd72c8 /sys/dev | |
parent | 9b71ebe0292ea9b021d59343d6b8d0dc14fc786f (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.c | 56 | ||||
-rw-r--r-- | sys/dev/pv/xenvar.h | 4 |
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; |