#!/bin/bash # ----------------------------------------------------------------------------- # $Id: pwrctl,v 1.1 2004/03/16 04:50:41 warpzero Exp $ # # This script is invoked by pmud to configure the system for a # given power level. The desired level is indicated by the first # argument and can take the following values: # # minimum = minimum power # medium = medium power # maximum = full power # sleep = prepare for sleep # wakeup = system woke up after a sleep # warning = low battery condition detected, issue a warning to users # # the second argument gives the current power source, and can take the # following values: # # ac # battery # # This script is invoked when the AC power is connected or disconnected, # and also immediately after sleep. If the script /etc/power/pwrctl-local # is present and executable, it will be called by this script before the # main body of this script is executed. If pwrctl-local returns 1, then # the main body of this script is NOT executed, in all other cases the # main body of this script will be executed. # # Note that if you leave pwrctl-local writable by others than root (which # should be the owner) you have created a serious security hole! # # You can edit this file, but it's better to edit /etc/power/pwrctl-local # as that file will not be overwritten on upgrades. # ----------------------------------------------------------------------------- # Debian add-on: support (sort of) for Core99 machines (Pismo,...). The # Pismo can't sleep right now so it will wake again immediately. We spin # down the disk on sleep, turn off backlight power and ignore the wakeup. # # While things are stabilizing, these commands could be used to put the system # into absolute minimum power mode. You can use commands of this sort in # /etc/init.d/powerfail if needs be (sample powerfail script is in # /usr/share/doc/sysvinit/examples/). # fblevel 0 # [ "`cat /proc/ide/hde/model`" != "(none)" ] && hdparm -f -S 1 -Y /dev/hde # hdparm -f -S 1 -Y /dev/hda # Use this to switch the display back on if the powerfail status is called # off: # fblevel 12 # # 01/09/13: Recent 2.4 kernel versions support sleep properly, by all # accounts. So shut down only if kernel version is insufficient. # Sample code to deal with broken airport drivers moved to pwrctl-local # (courtesy Tom Rini). # # $Log: pwrctl,v $ # Revision 1.1 2004/03/16 04:50:41 warpzero # app-laptop moves for ppc # # Revision 1.1 2002/04/27 10:34:28 pvdabeel # PPC sys-apps merge # # Revision 1.1 2002/04/14 03:41:30 kain # Initial import of PMUD for gentoo-ppc # # Revision 1.1.1.1 2001/12/07 11:31:53 sleemburg # Initial CVS import of the unreleased pmud-0.8 to apmud (new project name # because of a name clash at sourceforge.net). # # Revision 1.6 2000/12/12 08:56:57 stephan # support for iBook and Pismo (same as other G3's) # # Revision 1.5 2000/10/09 14:33:40 stephan # wakebay added # # Revision 1.4 2000/05/11 14:54:45 stephan # pmud 0.6 changes # # Revision 1.3 2000/03/25 21:26:32 stephan # pmud-0.5 changes # # Revision 1.2 2000/03/09 13:01:50 stephan # formatting and call to pwrctl-local # # Revision 1.1 2000/01/06 13:48:19 stephan # Initial revision # ----------------------------------------------------------------------------- logger=/usr/bin/logger localfun=/etc/power/pwrctl-local function do_warn() { local msg="Low battery, system will go down..." ( /usr/X11R6/bin/xmessage -center -timeout 15 "$msg" || \ echo "$msg" | /usr/bin/wall ) & } function pwrctl_G3() { case "$1" in minimum) # min power, set disk to spin down after 1 minute [ -f /sbin/hdparm ] && hdparm -p -S 12 /dev/hda ;; medium) # medium power, set disk to spin down after 2.5 minutes [ -f /sbin/hdparm ] && hdparm -p -S 30 /dev/hda ;; maximum) case "$2" in ac) # on mains, do not spin down [ -f /sbin/hdparm ] && hdparm -p -S 0 /dev/hda ;; *) # on battery, set disk to spin down after 5 minutes [ -f /sbin/hdparm ] && hdparm -p -S 60 /dev/hda ;; esac ;; warning) do_warn ;; lid-closed) ;; lid-opened) ;; sleep) ;; wakeup) [ -f /proc/sys/dev/cdrom/info ] && { device=$(cat /proc/sys/dev/cdrom/info | ( IFS=":" while read var val do [ "$var" = "drive name" ] && { echo $val break } done )) [ ! -z "$device" ] && { /sbin/wakebay /dev/${device} } } ;; *) $logger -p daemon.error -t pwrctl "$0: invalid arg $1" ;; esac } #------------------------------------------------------------------------------ # This is largely a no-op on iBook or Pismo, as we don't know how to handle # the sleep functions yet. Instead, we shut down on the spot. #------------------------------------------------------------------------------ function pwrctl_Core99() { case "$1" in minimum) # min power, set disk to spin down after 1 minute [ -f /sbin/hdparm ] && hdparm -p -S 12 /dev/hda ;; medium) # medium power, set disk to spin down after 2.5 minutes [ -f /sbin/hdparm ] && hdparm -p -S 30 /dev/hda ;; maximum) case "$2" in ac) # on mains, do not spin down [ -f /sbin/hdparm ] && hdparm -p -S 0 /dev/hda ;; *) # on battery, set disk to spin down after 5 minutes [ -f /sbin/hdparm ] && hdparm -p -S 60 /dev/hda ;; esac ;; warning) do_warn ;; lid-closed) ;; lid-opened) ;; sleep) # We may end up here if someone closed the lid ... # SIGPWR can be sent to init anyway with -s option, do the only # safe thing for now: shut the hell down on 2.2 kernels, or anything # below a known safe 2.4 version. KVER=`uname -r` case "$KVER" in 2.2.*|2.3.*|2.4.[1-7]|2.4.[1-7]-*) $logger -p daemon.error -t pwrctl "$0: insufficient kernel verison - sleep function not implemented, shutting down!" echo "Kernel does not support sleep, shutting down!" | /usr/bin/wall /sbin/shutdown -h now ;; *) ;; esac ;; wakeup) # maybe force wakeup of media bay devices? ;; *) $logger -p daemon.error -t pwrctl "$0: invalid arg $1" ;; esac } # ----------------------------------------------------------------------------- # On the 3400, for minimum power, we put the CPU into nap mode # (rather than doze mode) when it is idle. This reduces power # consumption but means that DMA is no longer cache coherent. # Therefore we have to disable DMA, including the ethernet. # We also turn the ethernet off during sleep. # ----------------------------------------------------------------------------- function pwrctl_3400() { case "$1" in minimum) ifconfig eth0 down [ -f /sbin/hdparm ] && hdparm -d0 -S 12 /dev/hda [ "`cat /proc/ide/hdc/model`" != "(none)" ] && [ -f /sbin/hdparm ] && hdparm -d0 /dev/hdc echo 1 >/proc/sys/kernel/powersave-nap ;; medium) echo 0 >/proc/sys/kernel/powersave-nap [ -f /sbin/hdparm ] && hdparm -d1 -p -S 30 /dev/hda [ "`cat /proc/ide/hdc/model`" != "(none)" ] && [ -f /sbin/hdparm ] && hdparm -d1 /dev/hdc ifconfig eth0 up ;; maximum) echo 0 >/proc/sys/kernel/powersave-nap case "$2" in ac) # on mains, do not spin down [ -f /sbin/hdparm ] && hdparm -d1 -p -S 0 /dev/hda ;; *) # on battery, set disk to spin down after 5 minutes [ -f /sbin/hdparm ] && hdparm -d1 -p -S 60 /dev/hda ;; esac [ "`cat /proc/ide/hdc/model`" != "(none)" ] && [ -f /sbin/hdparm ] && hdparm -d1 /dev/hdc ifconfig eth0 up ;; warning) do_warn ;; sleep) ifconfig eth0 down ;; wakeup) ifconfig eth0 up ;; *) $logger -p daemon.error -t pwrctl "$0: invalid arg $1" ;; esac } # ----------------------------------------------------------------------------- # main # ----------------------------------------------------------------------------- [ -x $localfun ] && { $logger -p daemon.info -t pwrctl "calling $localfun $*" $localfun $* case $? in 0) $logger -p daemon.debug -t pwrctl "continuing with main" ;; 1) $logger -p daemon.debug -t pwrctl "skipping main" exit 0 ;; *) $logger -p daemon.error -t pwrctl "error in $localfun" ;; esac } case "$PMUVERSION" in 9) pwrctl_3400 $1 $2 ;; 10|11) pwrctl_G3 $1 $2 ;; 12) pwrctl_Core99 $1 $2 ;; *) $logger -p daemon.error -t pwrctl "no function for PMU $PMUVERSION" ;; esac >>/var/log/pwrctls 2>&1 exit 0