• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

BSDFan, a simple fan control utility for ThinkPads

clod89

New Member

Thanks: 4
Messages: 13

#1
If you've ever used FreeBSD (or any other BSD for that matter) on a ThinkPad you might have noticed the loud and erratic behavior of the fan. I've written a small utility as per title to manage the fan and improve silence, coolness and battery life. If anyone finds it useful I'll make a port for it.

Be careful when playing with fan levels and temperatures.

Have fun.

https://github.com/darklightclod/bsdfan
 

f-andrey

Member

Thanks: 8
Messages: 42

#2
I'm test this for my Lenovo X220, unfortunately it does not work (set 0 speed).
Code:
# sysctl -a | grep thermal
hw.acpi.thermal.min_runtime: 0
hw.acpi.thermal.polling_rate: 10
hw.acpi.thermal.user_override: 0
hw.acpi.thermal.tz0.temperature: 62.0C
hw.acpi.thermal.tz0.active: -1
hw.acpi.thermal.tz0.passive_cooling: 0
hw.acpi.thermal.tz0.thermal_flags: 0
hw.acpi.thermal.tz0._PSV: -1
hw.acpi.thermal.tz0._HOT: -1
hw.acpi.thermal.tz0._CRT: 99.0C
hw.acpi.thermal.tz0._ACx: -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
hw.acpi.thermal.tz0._TC1: -1
hw.acpi.thermal.tz0._TC2: -1
hw.acpi.thermal.tz0._TSP: -1
# sysctl -a | grep fan
dev.acpi_ibm.0.fan_speed: 4481
dev.acpi_ibm.0.fan_level: 7
dev.acpi_ibm.0.fan: 0
Code:
# bsdfan -d -c /usr/local/etc/bsdfan.conf
# sysctl -a | grep fan
dev.acpi_ibm.0.fan_speed: 3931
dev.acpi_ibm.0.fan_level: 0
dev.acpi_ibm.0.fan: 0
# sysctl -a | grep thermal
hw.acpi.thermal.min_runtime: 0
hw.acpi.thermal.polling_rate: 10
hw.acpi.thermal.user_override: 0
hw.acpi.thermal.tz0.temperature: 62.0C
hw.acpi.thermal.tz0.active: -1
hw.acpi.thermal.tz0.passive_cooling: 0
hw.acpi.thermal.tz0.thermal_flags: 0
hw.acpi.thermal.tz0._PSV: -1
hw.acpi.thermal.tz0._HOT: -1
hw.acpi.thermal.tz0._CRT: 99.0C
hw.acpi.thermal.tz0._ACx: -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
hw.acpi.thermal.tz0._TC1: -1
hw.acpi.thermal.tz0._TC2: -1
hw.acpi.thermal.tz0._TSP: -1
 

clod89

New Member

Thanks: 4
Messages: 13

#3
I'm test this for my Lenovo X220, unfortunately does not work (set 0 speed)
Sorry for the late reply, could you try and start it not in daemon mode and see if there are any errors? Also post your configuration and sysctl dev.acpi_ibm before and while it's running. I can't seem to reproduce it here.
 

f-andrey

Member

Thanks: 8
Messages: 42

#4
Sorry for the late reply, could you try and start it not in daemon mode and see if there are any errors? also post your config and sysct dev.acpi_ibm before and while it's running. I can't seem to reproduce it here.
Code:
codedev.acpi_ibm.%parent:
dev.acpi_ibm.0.%desc: IBM ThinkPad ACPI Extras
dev.acpi_ibm.0.%driver: acpi_ibm
dev.acpi_ibm.0.%location: handle=\_SB_.PCI0.LPC_.EC__.HKEY
dev.acpi_ibm.0.%pnpinfo: _HID=LEN0068 _UID=0
dev.acpi_ibm.0.%parent: acpi0
dev.acpi_ibm.0.initialmask: 2060
dev.acpi_ibm.0.availmask: 134217727
dev.acpi_ibm.0.events: 0
dev.acpi_ibm.0.eventmask: 2060
dev.acpi_ibm.0.hotkey: 3353
dev.acpi_ibm.0.lcd_brightness: 0
dev.acpi_ibm.0.volume: 10
dev.acpi_ibm.0.mute: 0
dev.acpi_ibm.0.thinklight: 0
dev.acpi_ibm.0.bluetooth: 0
dev.acpi_ibm.0.wlan: 1
dev.acpi_ibm.0.fan_speed: 4464
dev.acpi_ibm.0.fan_level: 7
dev.acpi_ibm.0.fan: 0
dev.acpi_ibm.0.handlerevents: NONE
If I start bsdfan -c /usr/local/etc/bsdfan.conf it does not produce any error messages as the fan speed becomes set to zero, after start.
Code:
# sysctl dev.acpi_ibm
...
dev.acpi_ibm.0.fan_speed: 3424 <-- slowly decreases to 0
dev.acpi_ibm.0.fan_level: 0  <--- set 0 after start bsdfan
...
 

f-andrey

Member

Thanks: 8
Messages: 42

#6
Could you show me your bsdfan.conf ?
I haven't changed this.
Code:
# diff --report-identical-files /usr/local/etc/bsdfan.conf /home/andrey/bsdfan/bsdfan.conf 
Files /usr/local/etc/bsdfan.conf and /home/andrey/bsdfan/bsdfan.conf are identical
 

clod89

New Member

Thanks: 4
Messages: 13

#7
Ah! I don't know how I missed it in the other post, it seems like you lack dev.acpi_ibm.0.thermal, which is where it gets the temperatures from, I'm not sure why (hardware not fully supported by the driver perhaps?), I could look at hw.acpi.thermal.tz0.temperature instead but I suggest you first try to find out why the driver does not have the sysctl. What version of FreeBSD are you using?
 

f-andrey

Member

Thanks: 8
Messages: 42

#8
Code:
FreeBSD 11.0-CURRENT #0 r273477: Tue Oct 28
It looks like it is a feature of new models of Lenovo, they do not fully realize the old acpi_ibm.
 

f-andrey

Member

Thanks: 8
Messages: 42

#10
The new code does not compile, the first error I fixed:
Code:
% git diff
diff --git a/system.c b/system.c
index 310539d..27e6cf0 100644
--- a/system.c
+++ b/system.c
@@ -31,7 +31,7 @@ void setFan(int mode,struct Level *levels)
 
  /*get mib for dev.acpi_ibm.0.thermal*/
  len = 4;
-  if (sysctlnametomib("dev.acpi_ibm.0.thermal",mib_get_temp_level,&len) == -1);
+  if (sysctlnametomib("dev.acpi_ibm.0.thermal",mib_get_temp_level,&len) == -1)
  {
  len = 5;
  /*get mib for hw.acpi.thermal.tz0.temperature*/
How to correct the mistake I do not know.
Code:
% make
clang -c -Wall -O3 system.c -o system.o
system.c:92:9: error: use of undeclared identifier 'temp'
  return temp[0];
  ^
1 error generated.
*** Error code 1

Stop.
make: stopped in /usr/home/andrey/bsdfan
 

f-andrey

Member

Thanks: 8
Messages: 42

#12
Okay, now it builds and runs correctly. But the speed increases only; immediately after the start it's small and growing about a minute to a
Code:
maximum dev.acpi_ibm.0.fan_level: 7
I made this configuration:
Code:
level (0,0,25)
level (1,23,35)
level (2,32,45)
level (3,42,55)
level (4,52,65)
level (5,62,75)
level (6,72,85)
level (7,82,32767)
Current temperature
Code:
hw.acpi.thermal.tz0.temperature: 63.0C
 

clod89

New Member

Thanks: 4
Messages: 13

#13
Ok, I can't even build it from here, you could try to get the latest version, add a
Code:
printf("Temp: %d",cur_temp);
at the end of bsdfan.c right before
Code:
oldtemp = cur_temp;
in the while loop. Build, launch without -d and let's see what's the output.
 

clod89

New Member

Thanks: 4
Messages: 13

#15
Sorry it took a while, life got in the way, apparently hw.acpi.thermal.tz0.temperature returns Celsius using /usr/sbin/sysctl but when doing a sysctl in C it returns Kelvin. I have no idea if it's intentional or wrong but anyways I made some changes and it should work now. I tested it here and it worked fine :)
 

Zirias

Well-Known Member

Thanks: 127
Messages: 367

#17
Hi clod89, looking through your code, I feel compelled giving some unsolicited advice :D

Now that you have it working properly, you should take the time for some cleanup:
  • Eliminate typos in strings.
  • Format the code according to a single scheme you like.
It helps a lot when it grows (and projects tend to do so).

On a side node, the daemon(3) function looks like a nice time/SLOC-saver for code that doesn't need to be portable -- this one was new to me.
 

dscrdia

New Member

Thanks: 2
Messages: 15

#18
I'd just like to report that this works wonderfully on my T61. Great work.

If you were working on a second version, a RC script would be wonderful!
 
Top