Talk:Patch for controlling fan speed
Contents
Windows XP port
How would I port this patch to Windows XP?
--Jason
You can't. But you can write a Windows device driver based on the specs and ibm-acpi.
--Thinker 18:54, 7 Nov 2005 (CET)
gkrellm support
I can confirm that it works on Thinkpad T43 here. However after applying the patch, the fan speed monitor of gkrellm 2.2.7 cannot read value correctly. Maybe we gkrellm is reading the second line for speed but instead find the line for level, so it got confused? Would it be possible to interchange the lines so that speed still appears in the second line and level appears in the third instead? I'm no coder, just a suggestion to improve the patch.
--Jiang
I'd say it's a bug in gkrellm. It should parse the line header rather than relying on line numbers. But feel free to change (and test) the patch if you wish.
--Thinker 05:14, 26 Oct 2005 (CEST)
patch to keep gkrell working against 2.6.14
As in "works for me on a T43p", use with caution at your own risk. And thanks to thinker for the original patch, very nice work.
(See article for the actual patch)
--Spiney
Looks excellent, why not add it to the article page? Also, care to provide a license (preferably public domain like my patch) so the kernel guys can handle it? Speaking of which, the kernel people seem to like their patches generated via "diff -up vanilla-kernel-2.6.14 patched-kernel-2.6.14".
--Thinker 22:04, 1 Nov 2005 (CET)
Done, using the -p option for diff and "borrowing" your sentence for licensing purposes.
--Spiney
Updated script for unpatched kernels
A couple of command line options added, plus this version is able to daemonize and writes a pid file (to a custom location if needed). It's for an unpatched version of the kernel, since I think that's the way to go, but it should be easy to merge into the other version as well since it doesn't change any internals.
Any feedback appreciated.
Here we go:
#!/bin/bash # This script dynamically controls fan speed on some ThinkPad models # according to user-defined temperature thresholds. It implements its # own decision algorithm, overriding the ThinkPad embedded # controller. It also implements a workaround for the fan noise pulse # experienced every few seconds on some ThinkPads. # # WARNING: This script relies on undocumented hardware features and # overrides nominal hardware behavior. It may thus cause arbitrary # damage to your laptop or data. Watch your temperatures! # # This file is placed in the public domain and may be freely distributed. LEVELS=( 0 2 4 7) # Fan speed levels UP_TEMPS=( 52 60 68 ) # Speed increase trip points DOWN_TEMPS=( 48 56 64 ) # Speed decrease trip points ANTIPULSE=( 0 1 0 0) # Prevent fan pulsing noise at this level # (this also prevents fan speed updates) IBM_ACPI=/proc/acpi/ibm PID_FILE=/var/run/tp-fancontrol.pid INTERVAL=3 VERBOSE=true DRY_RUN=false DAEMONIZE=false usage() { echo "Usage: $0 [OPTION]..." echo echo "Available options:" echo " -t test mode" echo " -q quiet mode" echo " -d daemon mode, go into background, implies -q" echo " -p pid file location for daemon mode, default: $PID_FILE" exit 1 } while getopts 'qtdp:h' OPT; do case "$OPT" in t) DRY_RUN=true ;; q) # quiet mode VERBOSE=false ;; d) # go into background and daemonize DAEMONIZE=true ;; p) # different pidfile PID_FILE="$OPTARG" ;; h) # short help usage ;; \?) # error usage ;; esac done [[ $OPTIND -gt $# ]] || usage # no non-option args if $DRY_RUN; then echo "$0: Dry run, will not change fan state." VERBOSE=true DAEMONIZE=false fi if $DAEMONIZE ; then if [[ -e "$PID_FILE" ]]; then echo "$0: File $PID_FILE already exists, refusing to run." exit 1 else exec $0 -q -p "$PID_FILE" 0<&- 1>&- 2>&- & echo $! > "$PID_FILE" exit 0 fi fi # Enable the fan in default mode if anything goes wrong: set -e -E -u $DRY_RUN || trap "rm -f $PID_FILE 2> /dev/null; echo enable > $IBM_ACPI/fan; exit 0" EXIT HUP INT ABRT QUIT SEGV TERM thermometer() { # output list of temperatures read X Y < $IBM_ACPI/thermal if ! [[ "$X" == "temperatures:" ]]; then echo "$0: Bad temperatures: $X $Y" >&2 exit 1 fi echo "$Y"; } speedometer() { # output fan speed RPM sed -n 's/^speed:[ \t]*//p' $IBM_ACPI/fan } setlevel() { # set fan speed level $DRY_RUN || echo 0x2F $1 > $IBM_ACPI/ecdump } IDX=0 MAX_IDX=$(( ${#LEVELS[@]} - 1 )) SETTLE=0 while true; do TEMPS=`thermometer` $VERBOSE && SPEED=`speedometer` # Calculate new level NEWIDX=$IDX DOWN=$(( IDX > 0 )) for TEMP in $TEMPS; do # Increase speed as much as needed while [[ $NEWIDX -lt $MAX_IDX ]] && [[ $TEMP -ge ${UP_TEMPS[$NEWIDX]} ]]; do (( NEWIDX ++ )) DOWN=0 done # Allow decrease (by one index)? if [[ $DOWN == 1 ]] && [[ $TEMP -gt ${DOWN_TEMPS[$(( IDX - 1 ))]} ]]; then DOWN=0 fi done if [[ $DOWN == 1 ]]; then NEWIDX=$(( IDX - 1 )) fi # Transition OLDLEVEL=${LEVELS[$IDX]} NEWLEVEL=${LEVELS[$NEWIDX]} $VERBOSE && echo "tpfan: Temps: $TEMPS Fan: $SPEED Level: $OLDLEVEL->$NEWLEVEL" setlevel $NEWLEVEL sleep $INTERVAL # If needed, apply anti-pulsing hack after a settle-down period: if [[ ${ANTIPULSE[${NEWIDX}]} == 1 ]]; then if [[ $NEWLEVEL == $OLDLEVEL ]]; then if [[ $SETTLE -ge 0 ]]; then (( SETTLE -= INTERVAL )) else setlevel 0x40 # disengaged sleep 0.5 fi else SETTLE=6 fi fi IDX=$NEWIDX done
As usual, I disclaim all warranty for this script, and release it to the public domain (meaning you may use and further distribute it under any terms you wish, including incorporating it into other software).
--Spiney, Nov 7 2005, 19:46 (CET)
Hi,
I made a few changses (in your code above, for easy diff) to make the opt parsing safer and improve daemon mode. The indentation needs to be made consistently 4, but I didn't fix that to avoid trashing the diff.
--Thinker 13:37, 8 Nov 2005 (CET)
Thanks for the cleanup, I just cut'n'paste parts from ancient scripts of mine into it. ;) About the indentation, I usually prefer tabs and had tw=8 in vim at the moment I pasted into the Wiki. Unfortunately it's not possible to use tabs here...
BTW, I tried to add some sort of logging of level changes to syslog, using logger and a line like
[ -f $PID_FILE ] && [ $OLDLEVEL != $NEWLEVEL ] && /usr/bin/logger -i -t `basename $0` "Level: $OLDLEVEL->$NEWLEVEL"
(using the existance of the pidfile as crude check whether we run in daemon mode) just below the normal verbose output ("tpfan: ....") and the interesting thing is that the PID is changing in the logged lines, any idea why?
--spiney, still wondering how to get this signature added automatically, being not all that adept in Wikis
Using the $PID_FILE existence as a check isn't a good idea, even non-daemonized instances will use the syslog. Maybe that explains the PID change?
Speaking of which, a more elegant way to daemonize is to put the main loop in a function, and then use
main 0<&- ... &
instead of
exec $0 0<&- ... &"
BTW, [ -f $PIDFILE ] unnecessarily invokes the [ binary. Better to use bash's built-in version ([[ ... ]]).
For the signature, just type --~~~~ or click the 2nd-from-right button above the Wiki edit box.
--Thinker 17:16, 8 Nov 2005 (CET)
Of course $PID_FILE is not a good idea as check, hence the word 'crude'. ;) Probably adding an option -l for logging would do.
The backgrounding of the function is a very good idea, I'll incorporate that.
Regarding the usage of [, it's a builtin as well, isn't it? And strace-ing a testscript doesn't show a call of /usr/bin/[ which is probably just shipped nowadays in case someone uses an ancient shell. In any case, never mind me talking about a change of PID, logger uses it's own PID when using -i, so of course it's different every time it's called. Easily amended by using $$ in the text supplied to the -t option of logger.
And thanks for the tip about the signature, I should pay more attention to the GUI parts of websites. :)
--spiney 17:42, 8 Nov 2005 (CET)
Yeah, the logger PID explains it... And you're right about [ - strange, the only difference between [ expr ] and [[ expr ]] seems to be a slightly difference syntax, and that the former is a "builtin" whereas the latter is a "compound command" (whatever that means). BTW, I guess this discussion should have been in the Talk page of the script, not the patch.
--Thinker 17:55, 8 Nov 2005 (CET)
Of course, silly me, no idea why I chose this page. I'll just put an updated version of the script there, and these comments can be deleted afterwards I guess.
--spiney 18:11, 8 Nov 2005 (CET)
whats the problem kernel 2.6.14
hi all,
i patched the kernel with the patch for 2.6.14 with the option: /usr/src/linux # patch -p0 -l -i ../ibm_acpi.patch (which i copy&pasted)
they dont show me errors or so. but after i reboot and load the modul ibm_acpi i cant see any /proc/acpi/ibm/fan
whats the problem? copy&past ( tab -> space?) or is it a problem in my kernel config?
greetings and big thx from .ch,
system: ibm thinkpad t43p
kernel: 2.6.14
--62.203.29.204 19:22, 9 Nov 2005 (CET)kru
You need to pass the "experimental=1" module parameter to ibm-acpi:
# modprobe ibm_acpi experimental=1
--Thinker 21:01, 9 Nov 2005 (CET)