Skip site navigation (1)Skip section navigation (2)
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>