From 22fa4662688463847a118e1d2038f1e6e1e281ba Mon Sep 17 00:00:00 2001 From: Erik van der Kouwe Date: Wed, 21 Nov 2012 20:28:37 +0100 Subject: [PATCH] Restore poweroff to some of it's former glory (on QEMU, at least) --- commands/poweroff/poweroff.sh | 2 +- commands/reboot/halt.c | 3 ++- commands/reboot/shutdown.c | 4 +++- include/sys/reboot.h | 3 ++- kernel/arch/i386/arch_reset.c | 18 ++++++++++++++++++ servers/pm/main.c | 2 +- 6 files changed, 27 insertions(+), 5 deletions(-) diff --git a/commands/poweroff/poweroff.sh b/commands/poweroff/poweroff.sh index 92c563fba..366baac4e 100644 --- a/commands/poweroff/poweroff.sh +++ b/commands/poweroff/poweroff.sh @@ -10,4 +10,4 @@ fi PATH=/usr/bin:$PATH -exec shutdown -x off +exec shutdown -p diff --git a/commands/reboot/halt.c b/commands/reboot/halt.c index 361d6835e..60d1ad9c2 100644 --- a/commands/reboot/halt.c +++ b/commands/reboot/halt.c @@ -34,7 +34,7 @@ char *reboot_code = "delay; boot"; void usage() { - fprintf(stderr, "Usage: %s [-hrRfd] [-x reboot-code]\n", prog); + fprintf(stderr, "Usage: %s [-hrRfpd] [-x reboot-code]\n", prog); exit(1); } @@ -66,6 +66,7 @@ char **argv; case 'r': flag = RBT_REBOOT; break; case 'R': flag = RBT_RESET; break; case 'd': flag = RBT_DEFAULT; break; + case 'p': flag = RBT_POWEROFF; break; case 'f': fast = 1; break; case 'x': flag = RBT_MONITOR; diff --git a/commands/reboot/shutdown.c b/commands/reboot/shutdown.c index 418aab8c2..57e00f132 100644 --- a/commands/reboot/shutdown.c +++ b/commands/reboot/shutdown.c @@ -148,6 +148,7 @@ char *argv[]; break; case 'h': case 'r': + case 'p': case 'x': case 'd': reboot_flag = *opt; @@ -273,10 +274,11 @@ char *argv[]; void usage() { - fputs("Usage: shutdown [-hrRmkd] [-x code] [time [message]]\n", stderr); + fputs("Usage: shutdown [-hrRpmkd] [-x code] [time [message]]\n", stderr); fputs(" -h -> halt system after shutdown\n", stderr); fputs(" -r -> reboot system after shutdown\n", stderr); fputs(" -R -> reset system after shutdown\n", stderr); + fputs(" -p -> power system off after shutdown\n", stderr); fputs(" -x -> return to the monitor doing...\n", stderr); fputs(" -d -> default CTRL-ALT-DEL shutdown for current bootloader\n", stderr); fputs(" -m -> read a shutdown message from standard input\n", stderr); diff --git a/include/sys/reboot.h b/include/sys/reboot.h index 6a4edd825..3e8f6d44e 100644 --- a/include/sys/reboot.h +++ b/include/sys/reboot.h @@ -8,6 +8,7 @@ #define RBT_MONITOR 3 /* let the monitor do this */ #define RBT_RESET 4 /* hard reset the system */ #define RBT_DEFAULT 5 /* return to monitor, reset if not possible */ -#define RBT_INVALID 6 /* first invalid reboot flag */ +#define RBT_POWEROFF 6 /* power off, reset if not possible */ +#define RBT_INVALID 7 /* first invalid reboot flag */ #endif diff --git a/kernel/arch/i386/arch_reset.c b/kernel/arch/i386/arch_reset.c index 26e579a60..565a542f7 100644 --- a/kernel/arch/i386/arch_reset.c +++ b/kernel/arch/i386/arch_reset.c @@ -80,6 +80,19 @@ reset(void) } } +void +poweroff(void) +{ + const char *shutdown_str; + + /* Bochs/QEMU poweroff */ + shutdown_str = "Shutdown"; + while (*shutdown_str) outb(0x8900, *(shutdown_str++)); + + /* fallback option: reset */ + reset(); +} + __dead void arch_shutdown(int how) { unsigned char unused_ch; @@ -114,6 +127,11 @@ __dead void arch_shutdown(int how) /* Stop */ for (; ; ) halt_cpu(); NOT_REACHABLE; + + case RBT_POWEROFF: + /* Power off if possible, reset otherwise */ + poweroff(); + NOT_REACHABLE; default: case RBT_REBOOT: diff --git a/servers/pm/main.c b/servers/pm/main.c index e870d7703..d3c50f2d5 100644 --- a/servers/pm/main.c +++ b/servers/pm/main.c @@ -398,7 +398,7 @@ static void handle_vfs_reply() * the PM, will get a HARD_STOP notification. Await the * notification in the main loop. */ - sys_abort(RBT_DEFAULT); + sys_abort(abort_flag); return; }