#!/bin/sh

: '120916 Peter G. <pg_scr {at} scr.for.sabi.co.UK>'

ME="`basename "$0"`"

: '
  Inspired in part by:
  http://Mariner.CS.UCDavis.edu/slackware/doc/slackware/rc.local
'

vset()	{
  test -r "$1" && test "`cat "$1"`" != "$2" \
    && echo "$2" > "$1"
  # && test "`cat "$1"`" == "$2"
}
vsetgt(){
  test -r "$1" && test "`cat "$1"`" -gt "$2" \
    && echo "$2" > "$1"
  # && test "`cat "$1"`" == "$2"
}
vsetlt(){
  test -r "$1" && test "`cat "$1"`" -lt "$2" \
    && echo "$2" > "$1"
  # && test "`cat "$1"`" == "$2"
}

opt_v()	{ test "$OPT_VERBOSE" = 'y'; }

STATE="/var/tmp/laptop_"

VM='/proc/sys/vm'
ACPI='/proc/acpi'
SYSC='/sys/class'
SYSD='/sys/devices'

LAPTOP="$VM/laptop_mode"

DIRTYRATIO="$VM/dirty_ratio"
DIRTYBYTES="$VM/dirty_bytes"
DIRTYRATIOBG="$VM/dirty_background_ratio"
DIRTYBYTESBG="$VM/dirty_background_bytes"
DIRTYEXP="$VM/dirty_expire_centisecs"
DIRTYWBACK="$VM/dirty_writeback_centisecs"

OVERMEM="$VM/overcommit_memory"
OVERRATIO="$VM/overcommit_ratio"
SWAPPINESS="$VM/swappiness"
VFSPRESSURE="$VM/vfs_cache_pressure"

TOSHAPM="/proc/toshiba"
TOSHACPI="$ACPI/toshiba"

ACPIFAN="$ACPI/fan/FAN"
ACPILCD="$ACPI/video/VGA/LCD"
ACPICPU="$ACPI/processor/CPU0"

SCSIH="$SYSC/scsi_host"
SYSDCPU="$SYSD/system/cpu"

FSCOMMIT='ext[34]'
FSNOATIME='ext3\|xfs\|jfs\|ext2\|vfat\|fat'
FSWRITEBACK='ext[34]'

: 'Parameters'

CPUFREQl='ondemand'
CPUFREQm='ondemand'
CPUFREQh='performance'

doRemounts()	{ true; }

: '
  These were different values of the "data" option,
  but apparently can no longer "-o remount,data=OPT"
  if "OPT" is different from the existing value.
'
EXT3OPTSl=''
EXT3OPTSm=''
EXT3OPTSh=''

WRITEDELAYl='3'
WRITEDELAYm='1'
WRITEDELAYh='0'

HDAPMl='210'
HDAPMm='234'
HDAPMh='255'

HDSTANDBYl='4'
HDSTANDBYm='12'
HDSTANDBYh='240'

HDRAHEADl='1024'
HDRAHEADm='256'
HDRAHEADh='64'

LCDTOSHIl='3'
LCDTOSHIm='5'
LCDTOSHIh='6'

COMMITl='300'
COMMITm='60'
COMMITh='5'

# dirty_ratio
#   If more than this percentage of active memory is unflushed then

DIRTYRATIOl='40'
DIRTYRATIOm='40'
DIRTYRATIOh='40'

DIRTYBYTESl='1000000000'
DIRTYBYTESm='1000000000'
DIRTYBYTESh='1000000000'

DIRTYRATIOBGl='20'
DIRTYRATIOBGm='8'
DIRTYRATIOBGh='2'

DIRTYBYTESBGl='160000000'
DIRTYBYTESBGm='120000000'
DIRTYBYTESBGh='80000000'

DIRTYEXPl='30000'
DIRTYEXPm='8000'
DIRTYEXPh='400'

DIRTYWBACKl='10000'
DIRTYWBACKm='4000'
DIRTYWBACKh='200'

: 'Useful functions'

optionsAdd() \
{
  OPTS="$1"; shift

  case "$*" in '')	echo "$OPTS"; return;; esac

  for OPT
  do
    case "$OPTS" in
    *",$OPT,"*)	: ;;
    *",$OPT")	: ;;
    "$OPT,"*)	: ;;
    "$OPT")	: ;;

    ?*)		OPTS="$OPTS,$OPT";;
    '')		OPTS="$OPT";;
    esac
  done

  echo "$OPTS"
}

optionsDel() \
{
  OPTS="$1"; shift

  case "$*" in '')	echo "$OPTS"; return;; esac
  case "$OPTS" in '')	echo "$OPTS"; return;; esac

  for OPT
  do
    case "$OPTS" in
    "$OPT")	OPTS='';;
    "$OPT,"*)	OPTS="`echo "$OPTS" | sed 's/^'"$OPT"',//'`";;
    *",$OPT")	OPTS="`echo "$OPTS" | sed 's/,'"$OPT"'$//'`";;
    *",$OPT,"*)	OPTS="`echo "$OPTS" | sed 's/,'"$OPT"',/,/'`";;
    esac
  done

  echo "$OPTS"
}    

HELP="
    -v|--verbose	print messages about what is being done

    -h|--help		print this help

    (low|normal)"

OPTSO='hv'
OPTSL='help,verbose'

if ARGS="`getopt -n \"$0\" -o \"$OPTSO\" -l \"$OPTSL\" -- \"$@\"`"
then eval set -- "$ARGS"
else
  echo 1>&2 "  $0$HELP"
  exit 1
fi

while true
do
  case "$1" in
  '-v'|'--verbose')	OPT_VERBOSE='y'; shift;;

  '--')			shift; break;;

  *|'-h'|'--help')	echo 1>&2 "  $0$HELP"; exit 1;;
  esac
done

case "$1" in
low)
  for CPU in "$SYSDCPU"/cpu*
  do GOVERNOR="$CPU/cpufreq/scaling_governor"
    C="`expr "$GOVERNOR" : "$SYSDCPU/\([^/]*\)"`"
    vset "$GOVERNOR"			"$CPUFREQl" \
       && opt_v && echo "$ME: '$C' governor '$CPUFREQl'"
  done

  vset "$LAPTOP"			"$WRITEDELAYl" \
    && opt_v && echo "$ME: laptop_mode '$WRITEDELAYl'"
  vsetlt "$DIRTYEXP"			"$DIRTYEXPl" \
    && opt_v && echo "$ME: dirty expire '$DIRTYEXPl'"
  vsetlt "$DIRTYWBACK"			"$DIRTYWBACKl" \
    && opt_v && echo "$ME: dirty writeback '$DIRTYWBACKl'"
  if test -w "$DIRTYBYTES"
  then
    vsetlt "$DIRTYBYTES"		"$DIRTYBYTESl" \
      && opt_v && echo "$ME: dirty bytes '$DIRTYBYTESl'"
    vsetlt "$DIRTYBYTESBG"		"$DIRTYBYTESBGl" \
      && opt_v && echo "$ME: dirty bytes bg '$DIRTYBYTESBGl'"
  else
    vsetlt "$DIRTYRATIO"		"$DIRTYRATIOl" \
      && opt_v && echo "$ME: dirty ratio '$DIRTYRATIOl'"
    vsetlt "$DIRTYRATIOBG"		"$DIRTYRATIOBGl" \
      && opt_v && echo "$ME: dirty ratio bg '$DIRTYRATIOBGl'"
  fi

  for D in /proc/ide/hd?
  do
    if test -r "$D"/driver
    then
      < "$D"/driver read IDEDRIVER REST
      F="`expr "$D" : '/proc/ide/\(hd.*\)'`"
      case "$IDEDRIVER" in 'ide-disk')
	hdparm -q -B "$HDAPMl" "/dev/$F" \
	  && opt_v && echo "$ME: '$D' APM '$HDAPMl'"
	hdparm -q -S "$HDSTANDBYl" "/dev/$F" \
	  && opt_v && echo "$ME: '$D' standby '$HDSTANDBYl'"
	hdparm-q -a "$HDRAHEADl" "/dev/$F" \
	  && opt_v && echo "$ME: '$D' readahead '$HDRAHEADl'";;
      esac
    fi
  done

  for D in /dev/sd?
  do
    if hdparm -v "$D" > /dev/null 2>&1
    then
      hdparm -q -B "$HDAPMl" "$D" \
        && opt_v && echo "$ME: '$D' APM '$HDAPMl'"
      hdparm -q -S "$HDSTANDBYl" "$D" \
        && opt_v && echo "$ME: '$D' standby '$HDSTANDBYl'"
      hdparm -q -a "$HDRAHEADl" "$D" \
        && opt_v && echo "$ME: '$D' readahead '$HDRAHEADl'"
    fi
  done

  if false
  then
    for H in "$SCSIH"/host*
    do LPMP="$H/link_power_management_policy"
      H="`expr "$LPMP" : "$SCSIH/\([^/]*\)"`"
      vset "$LPMP" "min_power" \
	&& opt_v && echo "$ME: SCSI '$H' power low"
    done
  fi

  if false
  then
    case "$DISPLAY" in *':'*)
      xrandr | while read OUTPUT STATUS REST
	do
	  case "$STATUS" in 'disconnected')
	    xrandr --output "$OUTPUT" --off;;
	  esac
	done
    esac
  fi

  vset "$ACPIFAN/state"			"off" \
    && opt_v && echo "$ME: fan off"
  vsetgt "$ACPILCD/brightness"		"30" \
    && opt_v && echo "$ME: brightness low"

  if test -d "$TOSHACPI" -o -r "$TOSHAPM"
  then
    opt_v && echo "$ME: fan off and brightness low"
    toshset -cpu slow; toshset -fan low
    vset "$TOSHACPI/lcd"		"brightness:$LCDTOSHIl"
  fi

  cp -p /proc/mounts "${STATE}mtab"

  if doRemounts
  then
    while read DEV FS TYPE OPTS REST
    do
      OPTSO="$OPTS"

      if expr >/dev/null "$TYPE" : "$FSCOMMIT"
      then
	OPTS="`optionsDel "$OPTS" 'commit='"$COMMITh"`"
	OPTS="`optionsAdd "$OPTS" 'commit='"$COMMITl"`"
      fi
      if expr >/dev/null "$TYPE" : "$FSWRITEBACK" && ! test "$FS" = '/'
      then
	OPTS="`optionsDel "$OPTS" "$EXT3OPTSh"`"
	OPTS="`optionsAdd "$OPTS" "$EXT3OPTSl"`"
      fi
      if false
      then
	if expr >/dev/null "$TYPE" : "$FSNOATIME"
	then OPTS="`optionsAdd "$OPTS" 'noatime'`"
	fi
      fi

      if test "$OPTS" != "$OPTSO"
      then
        case "$TYPE" in 'ext'[34])
	  OPTS="`optionsDel "$OPTS" 'relatime'`";;
        esac
	opt_v && echo "$ME: remounting '$FS' with '$OPTS'"
	if mount -o remount,"$OPTS" "$FS"
	then :
	else
	  umount "$FS"
	  mount -t "$TYPE" -o "$OPTS" "$DEV" "$FS" \
	    || mount -t "$TYPE" -o "$OPTSO" "$DEV" "$FS"
	fi
      fi
    done < /proc/mounts
  fi;;

normal)
  for CPU in "$SYSDCPU"/cpu*
  do GOVERNOR="$CPU/cpufreq/scaling_governor"
    C="`expr "$GOVERNOR" : "$SYSDCPU/\([^/]*\)"`"
    vset "$GOVERNOR"			"$CPUFREQh" \
      && opt_v && echo "$ME: '$C' governor '$CPUFREQh'"
  done

  vset "$LAPTOP"			"$WRITEDELAYh" \
    && opt_v && echo "$ME: laptop_mode '$WRITEDELAYh'"
  vsetgt "$DIRTYEXP"			"$DIRTYEXPh" \
    && opt_v && echo "$ME: dirty expire '$DIRTYEXPh'"
  vsetgt "$DIRTYWBACK"			"$DIRTYWBACKh" \
    && opt_v && echo "$ME: dirty writeback '$DIRTYWBACKh'"
  if test -w "$DIRTYBYTES"
  then
    vsetgt "$DIRTYBYTES"		"$DIRTYBYTESh" \
      && opt_v && echo "$ME: dirty bytes '$DIRTYBYTESh'"
    vsetgt "$DIRTYBYTESBG"		"$DIRTYBYTESBGh" \
      && opt_v && echo "$ME: dirty bytes bg '$DIRTYBYTESBGh'"
  else
    vsetgt "$DIRTYRATIO"		"$DIRTYRATIOh" \
      && opt_v && echo "$ME: dirty ratio '$DIRTYRATIOh'"
    vsetgt "$DIRTYRATIOBG"		"$DIRTYRATIOBGh" \
      && opt_v && echo "$ME: dirty ratio bg '$DIRTYRATIOBGh'"
  fi

  for D in /proc/ide/hd?
  do
    if  test -r "$D"/driver
    then
      < "$D"/driver read IDEDRIVER REST
      F="`expr "$D" : '/proc/ide/\(hd.*\)'`"
      case "$IDEDRIVER" in 'ide-disk')
	hdparm -q -B "$HDAPMh" "/dev/$F" \
	  && opt_v && echo "$ME: '$D' APM '$HDAPMh'"
	hdparm -q -S "$HDSTANDBYh" "/dev/$F" \
	  && opt_v && echo "$ME: '$D' standby '$HDSTANDBYh'"
	hdparm-q -a "$HDRAHEADh" "/dev/$F" \
	  && opt_v && echo "$ME: '$D' readahead '$HDRAHEADh'";;
      esac
    fi
  done

  for D in /dev/sd?
  do
    if hdparm -v "$D" > /dev/null 2>&1
    then
      hdparm -q -B "$HDAPMh" "$D" \
        && opt_v && echo "$ME: '$D' APM '$HDAPMh'"
      hdparm -q -S "$HDSTANDBYh" "$D" \
        && opt_v && echo "$ME: '$D' standby '$HDSTANDBYh'"
      hdparm -q -a "$HDRAHEADh" "$D" \
        && opt_v && echo "$ME: '$D' readahead '$HDRAHEADh'"
    fi
  done

  if false
  then
    for H in "$SCSIH"/host*
    do LPMP="$H/link_power_management_policy"
      H="`expr "$LPMP" : "$SCSIH/\([^/]*\)"`"
      vset "$LPMP"			"max_performance" \
	&& opt_v && echo "$ME: SCSI '$H' power normal"
    done
  fi

  vset "$ACPIFAN/state"			"on" \
    && opt_v && echo "$ME: fan on"
  vset "$ACPILCD/brightness"		"50" \
    && opt_v && echo "$ME: brightness normal"

  if test -d "$TOSHACPI" -o -r "$TOSHAPM"
  then
    opt_v && echo "$ME: fan on and brightness normal"
    toshset -cpu fast; toshset -fan low
    vset "$TOSHACPI/lcd"	"brightness:$LCDTOSHIh"
  fi

  if false
  then
    case "$DISPLAY" in *':'*)
      xrandr | while read OUTPUT STATUS REST
	do
	  case "$STATUS" in 'connected')
	    xrandr --output "$OUTPUT" --auto;;
	  esac
	done
    esac
  fi

  : cp -p /proc/mounts "${STATE}mounts"

  if doRemounts
  then
    while read DEV FS TYPE OPTS REST
    do
      OPTSO="$OPTS"

      if expr >/dev/null "$TYPE" : "$FSCOMMIT"
      then
	OPTS="`optionsDel "$OPTS" 'commit='"$COMMITl"`"
	OPTS="`optionsAdd "$OPTS" 'commit='"$COMMITh"`"
      fi
      if expr >/dev/null "$TYPE" : "$FSWRITEBACK" && ! test "$FS" = '/'
      then
	OPTS="`optionsDel "$OPTS" "$EXT3OPTSl"`"
	OPTS="`optionsAdd "$OPTS" "$EXT3OPTSh"`"
      fi
      if false
      then
	if expr >/dev/null "$TYPE" : "$FSNOATIME"
	then OPTS="`optionsDel "$OPTS" 'noatime'`"
	fi
      fi

      if test "$OPTS" != "$OPTSO"
      then
        case "$TYPE" in 'ext'[34])
	  OPTS="`optionsDel "$OPTS" 'relatime'`";;
        esac
	opt_v && echo "$ME: remount '$FS' with '$OPTS'"
	if mount -o remount,"$OPTS" "$FS"
	then :
	else
	  umount "$FS"
	  mount -t "$TYPE" -o "$OPTS" "$DEV" "$FS" \
	    || mount -t "$TYPE" -o "$OPTSO" "$DEV" "$FS"
	fi
      fi
    done < /proc/mounts
  fi;;

*)
  echo 1>&2 "$0: the argument must be 'low' or 'normal'"
  exit 1;;
esac
