From root@wan2.wanlink.com  Sun Aug  9 20:25:12 1998
Received: from wan2.wanlink.com (l1.doitnow.com [207.98.156.215])
          by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id UAA02907
          for <FreeBSD-gnats-submit@freebsd.org>; Sun, 9 Aug 1998 20:25:07 -0700 (PDT)
          (envelope-from root@wan2.wanlink.com)
Received: (from root@localhost) by wan2.wanlink.com (8.8.8/8.8.3) id UAA23503; Sun, 9 Aug 1998 20:30:53 -0700 (MST)
Message-Id: <199808100330.UAA23503@wan2.wanlink.com>
Date: Sun, 9 Aug 1998 20:30:53 -0700 (MST)
From: neal@wanlink.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: shutdown -p - system power off implementation
X-Send-Pr-Version: 3.2

>Number:         7546
>Category:       kern
>Synopsis:       [PATCH] [STABLE ?]shutdown -p - system power off implementation
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Aug  9 20:30:01 PDT 1998
>Closed-Date:    Thu Aug 10 05:56:40 PDT 2000
>Last-Modified:  Thu Aug 10 05:59:16 PDT 2000
>Originator:     neal@wanlink.com
>Release:        FreeBSD 2.2.6-RELEASE i386
>Organization:
WANLink
>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

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->suspended 
State-Changed-By: phk 
State-Changed-When: Mon Aug 10 00:24:43 PDT 1998 
State-Changed-Why:  
It is my impression that this functionality is already present in 
-current. 
Awaiting cimmitter 

From: Neal Horman <neal@wanlink.com>
To: freebsd-gnats-submit@freebsd.org, neal@wanlink.com
Cc:  Subject: Re: kern/7546: [PATCH] [STABLE ?]shutdown -p - system power off implementation
Date: Mon, 10 Aug 1998 22:14:43 -0700

 Upon examination of kern_shutdown.c and apm.c presently in CVS, I do
 indeed find that code that apparently deals with system power down does
 exist.
 
 However, please consider the following points carefully before
 discounting the submitted patches.
 
 What doesn't exist is the code that will allow the user to select a
 "halt" vs. a "power down" condition. ie. kern_shutdown.c ignores the
 "howto & RB_POWEROFF" flag in this respect.
 
 At first, this may seem trivial, but consider that in server
 environments, when a UPS driven system is shutdown with "shutdown -h",
 or "halt" because of impending power outage conditions, and the kernel
 tells APM to turn the power off (using the code presently in CVS), upon
 power restoral, the system may not (this I think should be read as
 "probably won't") re-power without human intervention, which may not be
 acceptable.
 
 Using the patches that I've put together, the problem of the system not
 re-powering after line voltage restoral can be avoided by issuing a
 "shutdown -h", or "halt", to bring the system down, but not power off,
 vs. issuing a "shutdown -p", or "halt -p" to bring the system down, and
 then power off.
 
 Also, in some circumstances, it may be totaly inappropriate for a system
 to be able to power it's self off, and as such, the patches I've
 submitted will allow for the APM based power-down code to be a
 configurable kernel option.
State-Changed-From-To: suspended->closed 
State-Changed-By: johan 
State-Changed-When: Thu Aug 10 05:56:40 PDT 2000 
State-Changed-Why:  
superseded by PR 7990 

http://www.freebsd.org/cgi/query-pr.cgi?pr=7546 
>Unformatted:
