Date: Sun, 9 Aug 1998 20:30:53 -0700 (MST) From: neal@wanlink.com To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: kern/7546: shutdown -p - system power off implementation Message-ID: <199808100330.UAA23503@wan2.wanlink.com>
next in thread | raw e-mail | index | archive | help
>Number: 7546 >Category: kern >Synopsis: shutdown -p - system power off implementation >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sun Aug 9 20:30:01 PDT 1998 >Last-Modified: >Originator: neal@wanlink.com >Organization: WANLink >Release: FreeBSD 2.2.6-RELEASE i386 >Environment: FreeBSD wan2.wanlink.com 2.2.6-RELEASE FreeBSD 2.2.6-RELEASE #0: Fri Jun 26 08:15:49 MST 1998 root@wan2.wanlink.com:/usr/src/sys/compile/TAZZ i386 >Description: Patch - will use APM API to turn system power off, after the normal halt proccess. This works with my clone motherboard, which has both the AT & ATX style power connectors, an ATX power supply, and Intel's 82371AB Power management controller. This has not been tried on any other system that I'm aware of. YMMV. Files patched; /sys/kern/kern_shutdown.c /sys/i386/apm/apm.c /sys/i386/include/apm_bios.h /sys/i386/conf/options.i386 /sys/i386/conf/LINT /usr/src/sbin/shutdown/shutdown.c /usr/src/sbin/shutdown/shutdown.8 >How-To-Repeat: Installation Instructions; 1. copy the text from the "Fix:" section into a file called "apmdiff.seta". 2. execute the script with "sh apmdiff.seta -p", which will extract the patches into seperate "diff" files, and then call patch for you. 3. cd /usr/src/sbin/shutdown 4. make clean all install clean 5. cd /sys/i386/conf 6. edit your kernel config file and add; if not already present; "device apm0 at isa?" "options APM_SHUTDOWN" 7. config YOUR_KERNEL_NAME_HERE 8. cd ../../compile/YOUR_KERNEL_NAME_HERE 9. make depend all install && shutdown -r now Test Instructions; 1. make sure that you see something like... "apm0 on xxx" "apm: found APM BIOS version x.x" durring your boot sequence... use dmesg if neccessary, otherwise all of this is for not... 2. pick either option a, or b, depending on your preference a. shutdown -p now b. halt -p 3. you shoold see; The operating system has halted. Trying to turn the system off... and nothing else..., if you see Failed to turn the system off.. Please press any key to reboot. well... you get the idea... :( >Fix: #!/bin/sh # # apmdiff.seta - This file # # This is a SETA (self extracting text archive), and can be # executed by "sh apmdiffs.seta" at the command line. # Any text above the "#!/bin/sh" line should be removed! # PATCHIT="NO"; MAKEIT="NO" if [ "$1" = "-p" ]; then PATCHIT="YES"; shift; fi if [ "$1" = "-m" ]; then MAKEIT="YES"; shift; fi # ----- start of LINT.diff ----- cat <<SETAEOF |sed -e's/^S //g'>LINT.diff S *** /sys/i386/conf/LINT Mon Mar 23 19:57:24 1998 S --- LINT Fri Aug 7 21:55:56 1998 S *************** S *** 984,989 **** S --- 984,990 ---- S # S S options APM_IDLE_CPU # Tell APM to idle rather than halt'ing the cpu S + options APM_SHUTDOWN # Tell APM to shutdown the system power S S # S # Notes on the spigot: SETAEOF if [ "$PATCHIT" = "YES" ]; then patch -l /sys/i386/conf/LINT < LINT.diff; fi # ----- end of LINT.diff ----- # ----- start of apm.c.diff ----- cat <<SETAEOF |sed -e's/^S //g'>apm.c.diff S *** /sys/i386/apm/apm.c Sun Aug 9 18:13:29 1998 S --- apm.c Fri Aug 7 23:46:53 1998 S *************** S *** 17,22 **** S --- 17,23 ---- S * $Id: apm.c,v 1.49.2.2 1997/11/10 14:40:40 nate Exp $ S */ S S + #include "opt_apm.h" S #include <sys/param.h> S #include <sys/conf.h> S #include <sys/kernel.h> S *************** S *** 207,212 **** S --- 208,231 ---- S return 0; S } S S + #ifdef APM_SHUTDOWN S + static int apm_shutdown_system(void) S + { S + u_long eax, ebx, ecx; S + S + eax = (APM_BIOS << 8) | APM_SETPWSTATE; S + ebx = PMDV_ALLDEV; S + ecx = PMST_OFF; S + S + if (apm_int(&eax, &ebx, &ecx)) { S + printf("Entire system shutdown failure: errcode = %ld\n", S + 0xff & (eax >> 8)); S + return 1; S + } S + return 0; S + } S + #endif S + S /* Display control */ S /* S * Experimental implementation: My laptop machine can't handle this function S *************** S *** 377,382 **** S --- 396,416 ---- S * Execute suspend and resume hook before and after sleep, respectively. S * S */ S + S + #ifdef APM_SHUTDOWN S + void S + apm_shutdown(void) S + { S + struct apm_softc *sc = &apm_softc; S + S + if (!sc) S + return; S + S + if (sc->initialized) { S + if (apm_shutdown_system() == 0) apm_processevent(); S + } S + } S + #endif S S void S apm_suspend(void) SETAEOF if [ "$PATCHIT" = "YES" ]; then patch -l /sys/i386/apm/apm.c < apm.c.diff; fi # ----- end of apm.c.diff ----- # ----- start of apm_bios.h.diff ----- cat <<SETAEOF |sed -e's/^S //g'>apm_bios.h.diff S *** /sys/i386/include/apm_bios.h Thu Jul 30 19:25:54 1998 S --- apm_bios.h Sat Aug 1 13:23:12 1998 S *************** S *** 152,157 **** S --- 152,158 ---- S #define NAPM_HOOK 2 S S void apm_suspend(void); S + void apm_shutdown(void); S struct apmhook *apm_hook_establish (int apmh, struct apmhook *); S void apm_hook_disestablish (int apmh, struct apmhook *); S void apm_cpu_idle(void); SETAEOF if [ "$PATCHIT" = "YES" ]; then patch -l /sys/i386/include/apm_bios.h < apm_bios.h.diff; fi # ----- end of apm_bios.h.diff ----- # ----- start of kern_shutdown.c.diff ----- cat <<SETAEOF |sed -e's/^S //g'>kern_shutdown.c.diff S *** /sys/kern/kern_shutdown.c Sun Aug 10 19:04:14 1997 S --- kern_shutdown.c Fri Aug 7 23:44:51 1998 S *************** S *** 40,45 **** S --- 40,46 ---- S */ S S #include "opt_ddb.h" S + #include "opt_apm.h" S S #include <sys/param.h> S #include <sys/systm.h> S *************** S *** 251,256 **** S --- 252,266 ---- S if (howto & RB_HALT) { S printf("\n"); S printf("The operating system has halted.\n"); S + #ifdef APM_SHUTDOWN S + if(howto & RB_POWEROFF) { S + printf("Trying to turn the system off...\n"); S + DELAY(5000000); S + apm_shutdown(); S + DELAY(500000); S + printf("Failed to turn the system off..\n"); S + } S + #endif S printf("Please press any key to reboot.\n\n"); S switch (cngetc()) { S case -1: /* No console, just die */ SETAEOF if [ "$PATCHIT" = "YES" ]; then patch -l /sys/kern/kern_shutdown.c < kern_shutdown.c.diff; fi # ----- end of kern_shutdown.c.diff ----- # ----- start of options.i386.diff ----- cat <<SETAEOF |sed -e's/^S //g'>options.i386.diff S *** /sys/i386/conf/options.i386 Fri Feb 27 22:17:25 1998 S --- options.i386 Fri Aug 7 23:41:17 1998 S *************** S *** 64,69 **** S --- 64,71 ---- S PSM_RESETAFTERSUSPEND opt_psm.h S PSM_DEBUG opt_psm.h S S + APM_SHUTDOWN opt_apm.h S + S KBD_RESETDELAY opt_kbdio.h S KBD_MAXRETRY opt_kbdio.h S KBD_MAXWAIT opt_kbdio.h SETAEOF if [ "$PATCHIT" = "YES" ]; then patch -l /sys/i386/conf/options.i386 < options.i386.diff; fi # ----- end of options.i386.diff ----- # ----- start of shutdown.8.diff ----- cat <<SETAEOF |sed -e's/^S //g'>shutdown.8.diff S *** /usr/src/sbin/shutdown/shutdown.8 Thu Jul 3 23:35:19 1997 S --- shutdown.8 Fri Aug 7 21:46:39 1998 S *************** S *** 40,46 **** S .Sh SYNOPSIS S .Nm shutdown S .Op Fl S ! .Op Fl hkrn S .Ar time S .Op Ar warning-message ... S .Sh DESCRIPTION S --- 40,46 ---- S .Sh SYNOPSIS S .Nm shutdown S .Op Fl S ! .Op Fl hkrnp S .Ar time S .Op Ar warning-message ... S .Sh DESCRIPTION S *************** S *** 59,64 **** S --- 59,72 ---- S .Nm shutdown S execs S .Xr halt 8 . S + .It Fl p S + The system is halted at the specified S + .Ar time S + when S + .Nm shutdown S + execs S + .Xr halt 8 S + with a -p option to try and power down the system. S .It Fl k S Kick every body off. S The SETAEOF if [ "$PATCHIT" = "YES" ]; then patch -l /usr/src/sbin/shutdown/shutdown.8 < shutdown.8.diff; fi # ----- end of shutdown.8.diff ----- # ----- start of shutdown.c.diff ----- cat <<SETAEOF |sed -e's/^S //g'>shutdown.c.diff S *** /usr/src/sbin/shutdown/shutdown.c Sun Jan 25 18:01:39 1998 S --- shutdown.c Sat Aug 1 14:03:11 1998 S *************** S *** 83,89 **** S #undef S S S static time_t offset, shuttime; S ! static int dohalt, doreboot, killflg, mbuflen; S static char *nosync, *whom, mbuf[BUFSIZ]; S S void badtime __P((void)); S --- 83,89 ---- S #undef S S S static time_t offset, shuttime; S ! static int dohalt, doreboot, killflg, mbuflen, dopowerdown; S static char *nosync, *whom, mbuf[BUFSIZ]; S S void badtime __P((void)); S *************** S *** 112,118 **** S #endif S nosync = NULL; S readstdin = 0; S ! while ((ch = getopt(argc, argv, "-hknr")) != -1) S switch (ch) { S case '-': S readstdin = 1; S --- 112,118 ---- S #endif S nosync = NULL; S readstdin = 0; S ! while ((ch = getopt(argc, argv, "-hknrp")) != -1) S switch (ch) { S case '-': S readstdin = 1; S *************** S *** 129,134 **** S --- 129,138 ---- S case 'r': S doreboot = 1; S break; S + case 'p': S + dopowerdown = 1; S + dohalt = 1; S + break; S case '?': S default: S usage(); S *************** S *** 143,148 **** S --- 147,157 ---- S warnx("incompatible switches -h and -r."); S usage(); S } S + S + if (dopowerdown && doreboot) { S + warnx("incompatible switches -p and -r."); S + usage(); S + } S getoffset(*argv++); S S if (*argv) { S *************** S *** 332,338 **** S perror("shutdown"); S } S else if (dohalt) { S ! execle(_PATH_HALT, "halt", "-l", nosync, 0); S syslog(LOG_ERR, "shutdown: can't exec %s: %m.", _PATH_HALT); S perror("shutdown"); S } S --- 341,348 ---- S perror("shutdown"); S } S else if (dohalt) { S ! if(dopowerdown) execle(_PATH_HALT, "halt", "-lp", nosync, 0); S ! else execle(_PATH_HALT, "halt", "-l", nosync, 0); S syslog(LOG_ERR, "shutdown: can't exec %s: %m.", _PATH_HALT); S perror("shutdown"); S } SETAEOF if [ "$PATCHIT" = "YES" ]; then patch -l /usr/src/sbin/shutdown/shutdown.c < shutdown.c.diff; fi # ----- end of shutdown.c.diff ----- if [ "$MAKEIT" = "YES" ]; then make; fi # MAKEIT >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199808100330.UAA23503>