Fedora Core N on a Dell Latitude D600

Last updated: May 11, 2006

The quick way for a working suspend: Install fedora Core 5.
It is not necessary to modify the standard setup in order to get a succes rate for suspend of about the same as with the method described below.
Furthermore, Core 5 automatically activates cpuspeed.
You still need to install the firmware for the 2200BG to get the wireless card working.

For Core 3:
updated: February 6, 2005

This is a very brief description of the very few modification I have had to make to the Fedora Core 3 installation on my Dell Latitue D600 inorder to get speedstep, hibernation (suspend to RAM), the Intel Centrino 2200BG wlan to work, and to increase the battery life time dramatically (using the laptop_mode of the kernel). History:
Feb 6: Added details on machine and xorg.conf, and information on one work-around (thanks to David Hole).
Jan 31: Remember to make suspend script executable.
Jan 30: Added information on how to get suspend working with DRI.
My Dell D600 is running rev. A14 of the BIOS (downloadable from the Dell website). Output from lspci:
[root@localhost ~]# lspci
00:00.0 Host bridge: Intel Corp. 82855PM Processor to I/O Controller (rev 03)
00:01.0 PCI bridge: Intel Corp. 82855PM Processor to AGP Controller (rev 03)
00:1d.0 USB Controller: Intel Corp. 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (rev 01)
00:1d.1 USB Controller: Intel Corp. 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (rev 01)
00:1d.2 USB Controller: Intel Corp. 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (rev 01)
00:1d.7 USB Controller: Intel Corp. 82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (rev 01)
00:1e.0 PCI bridge: Intel Corp. 82801 Mobile PCI Bridge (rev 81)
00:1f.0 ISA bridge: Intel Corp. 82801DBM (ICH4-M) LPC Interface Bridge (rev 01)
00:1f.1 IDE interface: Intel Corp. 82801DBM (ICH4-M) IDE Controller (rev 01)
00:1f.5 Multimedia audio controller: Intel Corp. 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (rev 01)
01:00.0 VGA compatible controller: ATI Technologies Inc Radeon R250 Lf [Radeon Mobility 9000 M9] (rev 02)
02:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5705M Gigabit Ethernet (rev 01)
02:01.0 CardBus bridge: O2 Micro, Inc. OZ711EC1 SmartCardBus Controller (rev 20)
02:01.1 CardBus bridge: O2 Micro, Inc. OZ711EC1 SmartCardBus Controller (rev 20)
02:03.0 Network controller: Intel Corp. PRO/Wireless 2200BG (rev 05)

1. cpuspeed

If you replace /etc/cpuspeed.conf by the following lines, then the cpuspeed deamon will be able to dynamically adjust the cpuspeed according to the present load. In practise this means that unless you are running at full load, the cpu fan will not need to run. It results in less noise and lower power consumption (the fan does not need to run to get rid of the excess heat... 2 birds with one stone...)
VMAJOR=1
VMINOR=1
DRIVER="speedstep-centrino"
OPTS="-i 2 -t /proc/acpi/thermal_zone/THM/temperature 65 -a /proc/acpi/ac_adapter/AC/state -p 10 25"

2. Intel 2200BG Wireless

Please note that tke kernel 2.6.9-1.724_FC3 available through the Fedora Core 3 updates includes the modules for ipw2200 version 0.13. Therefore, in order to use the wireless network card one needs only to install the correct version of the firmware (please refer to http://ipw2200.sf.net). The instructions applies if you would like to install the latest version of the driver. Start by deleting the ipw2200, ipw2100 and ieee80211 directories as described on this page. After using both ndiswrapper and linuxant as wrappers for the windows driver with varying success, I was very happy when Intel released the promised native linux driver for the 2200BG card. It is still in early development, but the necessary basic features (WEP etc) are implemented. Follow these steps to get it working:
  • Download the driver at http://ipw2200.sf.net
  • Follow the instructions in the distributed package:-
  • tar xzvf ipw2200-0.19.tgz
  • ln -sf ipw2200-0.19 current
  • cd ipw2200-0.19
  • read INSTALL
  • make install
  • Download and install the firmware ver 2.2 (follow this link and instructions)
    Please see this page for more information.

    3. Increase Battery Lifetime (using laptop_mode)

    The laptop mode of the kernels since 2.6.6 is describe here. Recentlym the activation of the laptop_mode has become significantly easier, with the introduction of the laptop mode tools. Download and install the laptop mode tools (I currently use version 1.04) as described on the web page. I routinely get 4.5 hours out of my batteries (with the screen backlighting turned down to the minimum). Remember to activate the different syslogd setups for power/battery as described in the /etc/laptop-mode/laptop-mode.conf.

    4. Suspend (hibernation, sleep, S3)

    February 6, 2005
    The method described here works for me - however, you may get completely different results - use this information at your own risk. This setup has been tested with kernel 2.6.9-2.6.10-1.760_FC3 and Xorg 6.8.1. The Fedora kernels released by RedHat have messed up the time during suspend since kernel-2.6.10-1.737_FC3. So if you do not want to rely on ntp to keep the clock accurate after a suspend (and the annoyance of a skewed clock when you do not have net access), you need to use kernels that are either not patched by Redhat or kernel patches earlier than 2.6.10-1.737_FC3 (it is the number '737' that is the culprit). If you followed my previous instructions, you can now re-activate DRI for the Xserver. If you never modified your xorg.conf-file, there is nothing to do (apart from activating modifying the sleep scripts as described below). My new version of sleep.sh treats the clock better, and change to text-terminals is necessary to make DRI work. Activate hybernation process with acpi by creating (as root) a file /etc/acpi/events/sleep.conf with the following content:
    event=button/sleep *
    action=/etc/acpi/actions/sleep.sh
    

    Finally, create the file /etc/acpi/actions/sleep.sh (and make it executable: chmod u+x /etc/acpi/actions/sleep.sh) containing these lines:
    #!/bin/tcsh
    # Script to drive the system to S3
    # suspend-to-ram
    #
    # JRA Jan 2005
    
    # Step 1: preparing sleep
    
    if (-e /suspending) then
     echo "already in the process of suspending. Please be patient."
    else
    /bin/touch /suspending
    /usr/bin/killall -s SIGUSR1 cpuspeed
    /usr/bin/chvt 1 # necessary to make DRI work
    /sbin/service anacron stop
    # USB doesn't suspend without unloading first
    /sbin/rmmod ehci_hcd
    /sbin/rmmod uhci_hcd
    #save the system time
    /sbin/hwclock --adjust
    /sbin/rmmod wacom # only necessary of you have wacom stylus
    /sbin/rmmod -as
    /bin/sync
    # Step 2: send sleep command via ACPI
    echo mem > /sys/power/state
    
    # Step 3: wake-up and reload
    /sbin/hwclock --hctosys
    /sbin/modprobe ehci_hcd
    /sbin/modprobe uhci_hcd
    # initialise X
    xinit /bin/false -- :1
    /usr/bin/chvt 7
    /sbin/service anacron start
    /sbin/service cpuspeed restart
    rm /suspending
    endif
    

    Next, restart the acpi system: service acpid restart (as root). Now, pressing Fn+Esc should put your laptop asleep. If you close and open the lid, it should spring to life again. Same result is obtained by pressing the power button shortly (when the laptop is asleep). Enjoy! Here is my xorg.conf file:
    # XFree86 4 configuration created by pyxf86config
    
    Section "ServerLayout"
    	Identifier     "Default Layout"
    	Screen      0  "Screen0" 0 0
    	InputDevice    "Mouse0" "CorePointer"
    	InputDevice    "Keyboard0" "CoreKeyboard"
    	InputDevice    "cursor" "SendCoreEvents"
    	InputDevice    "stylus" "SendCoreEvents"
    	InputDevice    "eraser" "SendCoreEvents"
    EndSection
    
    Section "Files"
    
    # RgbPath is the location of the RGB database.  Note, this is the name of the 
    # file minus the extension (like ".txt" or ".db").  There is normally
    # no need to change the default.
    # Multiple FontPath entries are allowed (they are concatenated together)
    # By default, Red Hat 6.0 and later now use a font server independent of
    # the X server to render fonts.
    	RgbPath      "/usr/X11R6/lib/X11/rgb"
    	FontPath     "unix/:7100"
    EndSection
    
    Section "Module"
    	Load  "dbe"
    	Load  "extmod"
    	Load  "fbdevhw"
    	Load  "glx"
    	Load  "record"
    	Load  "freetype"
    	Load  "type1"
    	Load  "dri"
    EndSection
    
    Section "InputDevice"
    
    # Specify which keyboard LEDs can be user-controlled (eg, with xset(1))
    #	Option	"Xleds"		"1 2 3"
    # To disable the XKEYBOARD extension, uncomment XkbDisable.
    #	Option	"XkbDisable"
    # To customise the XKB settings to suit your keyboard, modify the
    # lines below (which are the defaults).  For example, for a non-U.S.
    # keyboard, you will probably want to use:
    #	Option	"XkbModel"	"pc102"
    # If you have a US Microsoft Natural keyboard, you can use:
    #	Option	"XkbModel"	"microsoft"
    #
    # Then to change the language, change the Layout setting.
    # For example, a german layout can be obtained with:
    #	Option	"XkbLayout"	"de"
    # or:
    #	Option	"XkbLayout"	"de"
    #	Option	"XkbVariant"	"nodeadkeys"
    #
    # If you'd like to switch the positions of your capslock and
    # control keys, use:
    #	Option	"XkbOptions"	"ctrl:swapcaps"
    # Or if you just want both to be control, use:
    #	Option	"XkbOptions"	"ctrl:nocaps"
    #
    	Identifier  "Keyboard0"
    	Driver      "kbd"
    	Option	    "XkbModel" "pc105"
    	Option	    "XkbLayout" "gb"
    EndSection
    
    Section "InputDevice"
    	Identifier  "Mouse0"
    	Driver      "mouse"
    	Option	    "Protocol" "IMPS/2"
    	Option	    "Device" "/dev/input/mice"
    	Option	    "ZAxisMapping" "4 5"
    	Option	    "Emulate3Buttons" "yes"
    EndSection
    
    Section "InputDevice"
    	Identifier  "cursor"
    	Driver      "wacom"
    	Option	    "Device" "/dev/input/wacom"
    	Option	    "Type" "cursor"
    	Option	    "USB" "on"
    EndSection
    
    Section "InputDevice"
    	Identifier  "stylus"
    	Driver      "wacom"
    	Option	    "Device" "/dev/input/wacom"
    	Option	    "Type" "stylus"
    	Option	    "USB" "on"
    EndSection
    
    Section "InputDevice"
    	Identifier  "eraser"
    	Driver      "wacom"
    	Option	    "Device" "/dev/input/wacom"
    	Option	    "Type" "eraser"
    	Option	    "USB" "on"
    EndSection
    
    Section "InputDevice"
    	Identifier  "pad"
    	Driver      "wacom"
    	Option	    "Device" "/dev/input/wacom"
    	Option	    "Type" "pad"
    	Option	    "USB" "on"
    EndSection
    
    Section "Monitor"
    	Identifier   "Monitor0"
    	VendorName   "Monitor Vendor"
    	ModelName    "LCD Panel 1400x1050"
    	HorizSync    31.5 - 90.0
    	VertRefresh  59.0 - 75.0
    	Option	    "dpms"
    EndSection
    
    Section "Device"
    
    #       Option      "CloneHSync" "30.0-86.0"
    #       Option      "CloneHSync" "30.0-86.0"
    #       Option      "CloneMode" "1024x768"
    #	Option      "CloneHSync" "30.0-86.0"
    #	Option	    "CloneMode" "1280x1024"
    #        Option      "CloneMode" "1024x768"
    #	Option	    "CloneHSync" "55.0-65.0"
    #        Option      "CloneVRefresh" "50.0-120.0"
    #	Option	    "CloneVRefresh" "55.0-65.0"
    	Identifier  "Videocard0"
    	Driver      "radeon"
    	VendorName  "Videocard vendor"
    	BoardName   "ATI Radeon Mobility M9"
    	Option	    "AGPMode" "4"
    #	Option	    "AGPFastWrite" "on"
    #	Option	    "MonitorLayout" "LVDS, CRT"
    	Option	    "MonitorLayout" "LVDS, LVDS"
    	Option	    "CRT2HSync" "30.0-86.0"
    #	Option	    "CRT2VRefresh" "50.0-65.0"
    	Option	    "CRT2VRefresh" "50.0-120.0"
    #	Option	    "CloneMode" "1400x1050"
    	Option	    "EnablePageFlip" "on"
    	Option	    "DynamicClocks" "on"
    EndSection
    
    Section "Screen"
    	Identifier "Screen0"
    	Device     "Videocard0"
    	Monitor    "Monitor0"
    	DefaultDepth     24
    	SubSection "Display"
    		Viewport   0 0
    		Depth     16
    		Modes    "800x600" "640x480"
    	EndSubSection
    	SubSection "Display"
    		Viewport   0 0
    		Depth     24
    		Modes    "1400x1050" "1280x1024" "1280x960" "1152x864" "1024x768" "800x600" "640x480"
    	EndSubSection
    EndSection
    
    Section "DRI"
    	Group        0
    	Mode         0666
    EndSection
    

    Work-around if this does not work for you

    Davod Hole reported that the method descriped above did not work on his D600:
    But, there was just one thing needed changing (I don't quite understand
    what the difference was that made it necessary on mine, but not on yours,
    but anyway... maybe it's the later kernel...).  Anyway, I needed to
    download the video_post tool, which is an attachment to this bug:
    
    http://bugzilla.kernel.org/show_bug.cgi?id=3670
    
    Download the attachment.cgi file, unzip it (tar xzvf attachment.cgi),
    cd emu; make;
    then add
    
    /path_to_video_post/video_post
    
    as the first thing that happens in your script in Step 3.
    
    Otherwise, the screen just goes totally blank (I mean, there is *nothing*,
    not even a blank screen) on resume; the disk spins up, etc., but nothing
    else.
    
    I'm running 2.6.10-1.760_FC3.
    
    Maybe you could add this to your web page?  It might help others.
    

    Previous version: 4. Suspend (hibernation, sleep, S3) (outdated Jan 30 2005)

    The method described here works for me - however, you may get completely different results - use this information at your own risk. With that said - my laptop has survived more than 20 concecutive suspend/wake up cycles without any hitch. I consider this method working, although you do have to live without accelerated graphics (i.e. without using DRI). In the first attempt, the Xserver became extremely slow after the first suspend, but it is possible to circumvent this problem by starting a dummy Xserver after resuming. This is done automatically by the script lilsted below. In conclusion though, it would be extremely nice with a patched Xorg radeon driver! Enough talk - here is what I did.
    1)Uncomment the
    Load "dri"
    
    line in /etc/X11/xorg.conf (line 31 in my /etc/X11/xorg.conf file):
    #       Load  "dri"
    
    This is what slows down the graphics. To repeat: it would be really nice with a patched Xorg radeon driver...
    Next, activate the hybernation process with acpi by creating (as root) a file /etc/acpi/events/sleep.sh with the following content:
    event=button/sleep *
    action=/etc/acpi/actions/sleep.sh
    

    Finally, create the file /etc/acpi/actions/sleep.sh containing these lines:
    #!/bin/tcsh
    # Script to drive the system to S3
    # suspend-to-ram
    #
    
    # Step 1: preparing sleep
    # need to unload some modules for successful suspend
    
    if (-e /suspending) then
     echo "already in the process of suspending. Please be patient."
    else
    /bin/touch /suspending
    /bin/sync
    
    # USB doesn't suspend without unloading first
    /sbin/rmmod ehci_hcd
    /sbin/rmmod uhci_hcd
    
    #save the system time
    /sbin/hwclock --adjust
    /sbin/service ntpd stop
    
    # Step 2: send sleep command via ACPI
    echo mem > /sys/power/state
    
    # Step 3: wake-up and reload
    
    # restore USB
    
    /sbin/modprobe ehci_hcd
    /sbin/modprobe uhci_hcd
    
    /sbin/service ntpd restart
    rm /suspending
    xinit /bin/false -- :1
    endif
    

    Next, restart the acpi system: service acpid restart (as root). Now, pressing Fn+Esc should put your laptop asleep. If you close and open the lid, it should spring to life again. Same result is obtained by pressing the power button shortly (when the laptop is asleep). Enjoy!


    Fedora Core 2 on a Dell Latitude D600

    Last updated: Sep 7, 2004

    This is a very brief description of the few modification I have made to my Fedora Core 2 linux installation on my Dell Latitude D600. Most of the hardware works out of the box. In fact, this document will deal with the only two problems I have encountered:
  • the WLAN card (Intel Centrino 2200BG)
  • the ability to resume after a suspend
    Furthermore, I will describe how to use the laptop mode of the kernel to get up to 4 hours battery life time. There is very little original work reported here; I have merely compiled what I have found useful from mostly two sources (1, 2)

    Setup

    My description applies to the following setup
  • Dell Latitude D600 (BIOS Rev. A13)
  • Intel Pentium-M 1600MHz CPU
  • 14" 1400X1050 TFT / ATI Radeon 9000 32Mb AGP graphics
  • Intel Centrino 2200BG WLAN 802.11b/g
  • Broadcom Gigabit Ethernet
  • kernel 2.6.8-1.521 (the following description applies to all the kernels released by the Fedora project, but since we are dealing with issues under constant development we might as well use the latest kernel).

    Modifications of the vanilla Fedora setup

    The modifications fall into four independent categories, described in the following separate sections.

    1. cpuspeed

    If you replace /etc/cpuspeed.conf by the following lines, then the cpuspeed deamon will be able to dynamically adjust the cpuspeed according to the present load. In practise this means that unless you are running at full load, the cpu fan will not need to run. It results in less noise and lower power consumption (the fan does not need to run to get rid of the excess heat... 2 birds with one stone...)
    VMAJOR=1
    VMINOR=1
    DRIVER="speedstep-centrino"
    OPTS="-i 5 -t /proc/acpi/thermal_zone/THM/temperature 65 -a /proc/acpi/ac_adapter/AC/state -p 10 25"
    

    2. Intel 2200BG Wireless

    After using both ndiswrapper and linuxant as wrappers for the windows driver with varying success, I was very happy when Intel released the promised native linux driver for the 2200BG card. It is still in early development, but the necessary basic features (WEP etc) are implemented. Follow these steps to get it working:
  • Download the driver at http://ipw2200.sf.net
  • Follow the instructions in the distributed package:-
  • tar xzvf ipw2200-0.7.tgz
  • ln -sf ipw2200-0.7 current
  • cd ipw2200-0.7
  • read INSTALL
  • make
  • Download and install the firmware ver 2 (follow this link and instructions)
  • after compiling the code, the drivers can be loaded as described in the README.ipw2200. Simply run "./load debug=0" to load the drivers into the kernel. Make sure that the wireless card is switched on before loading the driver - failing to do so can crash the maschine. You should now be able to check the available AP's by "iwlist eth1 scan". Use the gnome network configuration tool to setup the wireless card (System Settings->Network).
    With the method described above, the wireless card works also after a suspend. I am currently investigating a method that should automate some of the steps. Please see this page for more information.

    3. Suspend (S3)

    ...or rather, surviving a suspend. There exists a few different approaches to solving the problem of the radeon driver not waking up, resulting in a locked computer. I am using the old method by described by Emmanuel Thomé. Apparently, better results can be achieved by a new method. However, I am enjoying relatively good results using the "old" method, so until there is another method giving 100% reliability I am sticking with it. This is an extract (with minor modifications) from the description of the procedure by Emmanuel Thomé. Only the Xserver needs patching, and the patch can be downloaded here.

    Patching the XFree86 driver

    You will need to recompile new drivers that includes the patches supplied. For this, you need the XFree86-sdk package, which puts source stuff below /usr/X11R6/lib/Server/. As root, do:

    	cd /usr/X11R6/lib/Server
    	gzip -dc ~/Local/kernel/radeon.patch.gz | patch -p0
    	./mkmf
    	make -C drivers/ati radeon_drv.o
    

    Now you can install the drivers:

    	cd /usr/X11R6/lib/modules/drivers
    	mv -f radeon_drv.o radeon_drv.o.orig
    	cp -f /usr/X11R6/lib/Server/drivers/ati/radeon_drv.o .
    

    It is now necessary for your X server to fully restart in order for changes to take effect. You can either log out (if in graphical mode) and do telinit 3 ; telinit 5 from the console, or reboot the machine.


    ACPI now needs to be configured to perform the necessary shutdown and waking up routines. Copy the following (modified from a script found somewhere on the web...) to /etc/acpi/actions/sleep.sh:
     
    # Script to drive the system to S3 
    # suspend-to-ram # # DS@CFA June04
    
    # Step 1: preparing sleep 
    # need to unload some modules for successful suspend
    
    /bin/touch /suspending
    /bin/sync
    # not sure we need this at all
    # USB doesn't suspend without unloading first <-- Still true with new kernel???
    /sbin/rmmod ehci_hcd
    /sbin/rmmod uhci_hcd
    # ethernet
    #/sbin/rmmod tg3
    /sbin/service netplugd stop
    #/etc/rc.d/init.d/network stop
    #save the system time
    /sbin/hwclock --adjust
    /sbin/service ntpd stop
    /sbin/ifdown eth0 
    /sbin/ifdown eth1
    /sbin/rmmod tg3
    /root/ipw2200/current/unload
    
    # Step 2: send sleep command via ACPI
    echo mem > /sys/power/state
    
    # Step 3: wake-up and reload 
    
    # restore USB
    /sbin/modprobe ehci_hcd
    /sbin/modprobe uhci_hcd
    
    # ethernet
    #/etc/rc.d/init.d/network start
    #/sbin/ifup eth0
    /root/ipw2200/current/load debug=0
    /sbin/service ntpd start
    rm /suspending
    # The following line only if the battery section is implemented:
    /etc/acpi/actions/ac.sh
    # DONE
    

    The script assumes that the wireless driver is installed in /root/ipw2200/current/. If this is not the case, the corresponding lines of the script should be modified.
    Next, the following two lines should be copied to /etc/acpi/events/sleep.conf
    event=button/sleep *
    action=/etc/acpi/actions/sleep.sh
    

    Lastly, the following procedure should increase the likelihood of recovering from a suspend. Download the wrapper for updfstab and save it in a local dir as updfstab. Then do the following:
    mv /usr/sbin/updfstab /usr/sbin/updfstab.orig
    cp updfstab /usr/sbin/updfstab
    chmod u+x /usr/sbin/updfstab
    

    After a "service acpid restart" as root (or a reboot), your Dell D600 should now be able to suspend when you press Fn+Esc, and wake up when you press the power button. Good luck!

    4. Increasing Battery Time

    This section is basically an extract from /usr/src/linux-2.6.8-1.521/Documentation/laptop-mode.txt describing how to make use of the laptop mode of the kernel. Remember the caveats of running your computer in laptop-mode. They are mentioned in the file laptop-mode.txt (find this file by running 'locate laptop-mode.txt'). I have included the added modification of the syslogd deamon setup such that it does not sync the harddisk at each entry. Copy /etc/syslog.conf to /etc/syslog.conf.power. The copy the following to /etc/syslog.conf.battery
    # Log all kernel messages to the console.
    # Logging much else clutters up the screen.
    #kern.*							/dev/console
    
    # Log anything (except mail) of level info or higher.
    # Don't log private authentication messages!
    *.info;mail.none;news.none;authpriv.none;cron.none		-/var/log/messages
    
    # The authpriv file has restricted access.
    authpriv.*						-/var/log/secure
    
    # Log all the mail messages in one place.
    mail.*							-/var/log/maillog
    
    
    # Log cron stuff
    cron.*							-/var/log/cron
    
    # Everybody gets emergency messages
    *.emerg							*
    
    # Save news errors of level crit and higher in a special file.
    uucp,news.crit						-/var/log/spooler
    
    # Save boot messages also to boot.log
    local7.*						-/var/log/boot.log
    
    #
    # INN
    #
    news.=crit                                        -/var/log/news/news.crit
    news.=err                                         -/var/log/news/news.err
    news.notice                                       -/var/log/news/news.notice
    

    Copy the following to /etc/sysconfig/laptop-mode
    # Maximum time, in seconds, of hard drive spindown time that you are
    # confortable with. Worst case, it's possible that you could lose this
    # amount of work if your battery fails you while in laptop mode.
    #MAX_AGE=600
    
    # Automatically disable laptop mode when the number of minutes of battery
    # that you have left goes below this threshold.
    MINIMUM_BATTERY_MINUTES=10
    
    # Read-ahead, in 512-byte sectors. You can spin down the disk while playing MP3/OGG
    # by setting the disk readahead to 8MB (READAHEAD=16384). Effectively, the disk
    # will read a complete MP3 at once, and will then spin down while the MP3/OGG is
    # playing.
    #READAHEAD=4096
    
    # Shall we remount journaled fs. with appropiate commit interval? (1=yes)
    #DO_REMOUNTS=1
    
    # And shall we add the "noatime" option to that as well? (1=yes)
    #DO_REMOUNT_NOATIME=1
    
    # Dirty synchronous ratio.  At this percentage of dirty pages the process
    # which
    # calls write() does its own writeback
    #DIRTY_RATIO=40
    
    #
    # Allowed dirty background ratio, in percent.  Once DIRTY_RATIO has been
    # exceeded, the kernel will wake pdflush which will then reduce the amount
    # of dirty memory to dirty_background_ratio.  Set this nice and low, so once
    # some writeout has commenced, we do a lot of it.
    #
    #DIRTY_BACKGROUND_RATIO=5
    
    # kernel default dirty buffer age
    #DEF_AGE=30
    #DEF_UPDATE=5
    #DEF_DIRTY_BACKGROUND_RATIO=10
    #DEF_DIRTY_RATIO=40
    #DEF_XFS_AGE_BUFFER=15
    #DEF_XFS_SYNC_INTERVAL=30
    #DEF_XFS_BUFD_INTERVAL=1
    
    # This must be adjusted manually to the value of HZ in the running kernel
    # on 2.4, until the XFS people change their 2.4 external interfaces to work in
    # centisecs. This can be automated, but it's a work in progress that still
    # needs# some fixes. On 2.6 kernels, XFS uses USER_HZ instead of HZ for
    # external interfaces, and that is currently always set to 100. So you don't
    # need to change this on 2.6.
    #XFS_HZ=100
    
    # Should the maximum CPU frequency be adjusted down while on battery?
    # Requires CPUFreq to be setup.
    # See Documentation/cpu-freq/user-guide.txt for more info
    #DO_CPU=0
    
    # When on battery what is the maximum CPU speed that the system should
    # use? Legal values are "slowest" for the slowest speed that your
    # CPU is able to operate at, or a value listed in:
    # /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
    # Only applicable if DO_CPU=1.
    #CPU_MAXFREQ=slowest
    
    # Idle timeout for your hard drive (man hdparm for valid values, -S option)
    # Default is 2 hours on AC (AC_HD=244) and 20 seconds for battery (BATT_HD=4).
    #AC_HD=244
    #BATT_HD=4
    
    # The drives for which to adjust the idle timeout. Separate them by a space,
    # e.g. HD="/dev/hda /dev/hdb".
    #HD="/dev/hda"
    
    # Set the spindown timeout on a hard drive?
    #DO_HD=1
    

    Copy the following to /sbin/laptop_mode and make it executable: 'chmod u+x /sbin/laptop_mode' (as root).
    #!/bin/bash
    
    # start or stop laptop_mode, best run by a power management daemon when
    # ac gets connected/disconnected from a laptop
    #
    # install as /sbin/laptop_mode
    #
    # Contributors to this script:   Kiko Piris
    #				 Bart Samwel
    #				 Micha Feigin
    #				 Andrew Morton
    #				 Herve Eychenne
    #				 Dax Kelson
    #
    # Original Linux 2.4 version by: Jens Axboe
    
    #############################################################################
    
    # Source config
    if [ -f /etc/default/laptop-mode ] ; then
    	# Debian
    	. /etc/default/laptop-mode
    elif [ -f /etc/sysconfig/laptop-mode ] ; then
    	# Others
            . /etc/sysconfig/laptop-mode
    fi
    
    # Don't raise an error if the config file is incomplete
    # set defaults instead:
    
    # Maximum time, in seconds, of hard drive spindown time that you are
    # confortable with. Worst case, it's possible that you could lose this
    # amount of work if your battery fails you while in laptop mode.
    MAX_AGE=${MAX_AGE:-'600'}
    
    # Read-ahead, in kilobytes
    READAHEAD=${READAHEAD:-'4096'}
    
    # Shall we remount journaled fs. with appropiate commit interval? (1=yes)
    DO_REMOUNTS=${DO_REMOUNTS:-'1'}
    
    # And shall we add the "noatime" option to that as well? (1=yes)
    DO_REMOUNT_NOATIME=${DO_REMOUNT_NOATIME:-'1'}
    
    # Shall we adjust the idle timeout on a hard drive?
    DO_HD=${DO_HD:-'1'}
    
    # Adjust idle timeout on which hard drive?
    HD="${HD:-'/dev/hda'}"
    
    # spindown time for HD (hdparm -S values)
    AC_HD=${AC_HD:-'244'}
    BATT_HD=${BATT_HD:-'4'}
    
    # Dirty synchronous ratio.  At this percentage of dirty pages the process which
    # calls write() does its own writeback
    DIRTY_RATIO=${DIRTY_RATIO:-'40'}
    
    # cpu frequency scaling
    # See Documentation/cpu-freq/user-guide.txt for more info
    DO_CPU=${CPU_MANAGE:-'0'}
    CPU_MAXFREQ=${CPU_MAXFREQ:-'slowest'}
    
    #
    # Allowed dirty background ratio, in percent.  Once DIRTY_RATIO has been
    # exceeded, the kernel will wake pdflush which will then reduce the amount
    # of dirty memory to dirty_background_ratio.  Set this nice and low, so once
    # some writeout has commenced, we do a lot of it.
    #
    DIRTY_BACKGROUND_RATIO=${DIRTY_BACKGROUND_RATIO:-'5'}
    
    # kernel default dirty buffer age
    DEF_AGE=${DEF_AGE:-'30'}
    DEF_UPDATE=${DEF_UPDATE:-'5'}
    DEF_DIRTY_BACKGROUND_RATIO=${DEF_DIRTY_BACKGROUND_RATIO:-'10'}
    DEF_DIRTY_RATIO=${DEF_DIRTY_RATIO:-'40'}
    DEF_XFS_AGE_BUFFER=${DEF_XFS_AGE_BUFFER:-'15'}
    DEF_XFS_SYNC_INTERVAL=${DEF_XFS_SYNC_INTERVAL:-'30'}
    DEF_XFS_BUFD_INTERVAL=${DEF_XFS_BUFD_INTERVAL:-'1'}
    
    # This must be adjusted manually to the value of HZ in the running kernel
    # on 2.4, until the XFS people change their 2.4 external interfaces to work in
    # centisecs. This can be automated, but it's a work in progress that still needs
    # some fixes. On 2.6 kernels, XFS uses USER_HZ instead of HZ for external
    # interfaces, and that is currently always set to 100. So you don't need to
    # change this on 2.6.
    XFS_HZ=${XFS_HZ:-'100'}
    
    #############################################################################
    
    KLEVEL="$(uname -r |
                 {
    	       IFS='.' read a b c
    	       echo $a.$b
    	     }
    )"
    case "$KLEVEL" in
    	"2.4"|"2.6")
    		;;
    	*)
    		echo "Unhandled kernel version: $KLEVEL ('uname -r' = '$(uname -r)')" >&2
    		exit 1
    		;;
    esac
    
    if [ ! -e /proc/sys/vm/laptop_mode ] ; then
    	echo "Kernel is not patched with laptop_mode patch." >&2
    	exit 1
    fi
    
    if [ ! -w /proc/sys/vm/laptop_mode ] ; then
    	echo "You do not have enough privileges to enable laptop_mode." >&2
    	exit 1
    fi
    
    # Remove an option (the first parameter) of the form option= from
    # a mount options string (the rest of the parameters).
    parse_mount_opts () {
    	OPT="$1"
    	shift
    	echo ",$*," | sed		\
    	 -e 's/,'"$OPT"'=[0-9]*,/,/g'	\
    	 -e 's/,,*/,/g'			\
    	 -e 's/^,//'			\
    	 -e 's/,$//'
    }
    
    # Remove an option (the first parameter) without any arguments from
    # a mount option string (the rest of the parameters).
    parse_nonumber_mount_opts () {
    	OPT="$1"
    	shift
    	echo ",$*," | sed		\
    	 -e 's/,'"$OPT"',/,/g'		\
    	 -e 's/,,*/,/g'			\
    	 -e 's/^,//'			\
    	 -e 's/,$//'
    }
    
    # Find out the state of a yes/no option (e.g. "atime"/"noatime") in
    # fstab for a given filesystem, and use this state to replace the
    # value of the option in another mount options string. The device
    # is the first argument, the option name the second, and the default
    # value the third. The remainder is the mount options string.
    #
    # Example:
    # parse_yesno_opts_wfstab /dev/hda1 atime atime defaults,noatime
    #
    # If fstab contains, say, "rw" for this filesystem, then the result
    # will be "defaults,atime".
    parse_yesno_opts_wfstab () {
    	L_DEV="$1"
    	OPT="$2"
    	DEF_OPT="$3"
    	shift 3
    	L_OPTS="$*"
    	PARSEDOPTS1="$(parse_nonumber_mount_opts $OPT $L_OPTS)"
    	PARSEDOPTS1="$(parse_nonumber_mount_opts no$OPT $PARSEDOPTS1)"
    	# Watch for a default atime in fstab
    	FSTAB_OPTS="$(awk '$1 == "'$L_DEV'" { print $4 }' /etc/fstab)"
    	if echo "$FSTAB_OPTS" | grep "$OPT" > /dev/null ; then
    		# option specified in fstab: extract the value and use it
    		if echo "$FSTAB_OPTS" | grep "no$OPT" > /dev/null ; then
    			echo "$PARSEDOPTS1,no$OPT"
    		else
    			# no$OPT not found -- so we must have $OPT.
    			echo "$PARSEDOPTS1,$OPT"
    		fi
    	else
    		# option not specified in fstab -- choose the default.
    		echo "$PARSEDOPTS1,$DEF_OPT"
    	fi
    }
    
    # Find out the state of a numbered option (e.g. "commit=NNN") in
    # fstab for a given filesystem, and use this state to replace the
    # value of the option in another mount options string. The device
    # is the first argument, and the option name the second. The
    # remainder is the mount options string in which the replacement
    # must be done.
    #
    # Example:
    # parse_mount_opts_wfstab /dev/hda1 commit defaults,commit=7
    #
    # If fstab contains, say, "commit=3,rw" for this filesystem, then the
    # result will be "rw,commit=3".
    parse_mount_opts_wfstab () {
    	L_DEV="$1"
    	OPT="$2"
    	shift 2
    	L_OPTS="$*"
    	PARSEDOPTS1="$(parse_mount_opts $OPT $L_OPTS)"
    	# Watch for a default commit in fstab
    	FSTAB_OPTS="$(awk '$1 == "'$L_DEV'" { print $4 }' /etc/fstab)"
    	if echo "$FSTAB_OPTS" | grep "$OPT=" > /dev/null ; then
    		# option specified in fstab: extract the value, and use it
    		echo -n "$PARSEDOPTS1,$OPT="
    		echo ",$FSTAB_OPTS," | sed \
    		 -e 's/.*,'"$OPT"'=//'	\
    		 -e 's/,.*//'
    	else
    		# option not specified in fstab: set it to 0
    		echo "$PARSEDOPTS1,$OPT=0"
    	fi
    }
    
    deduce_fstype () {
    	MP="$1"
    	# My root filesystem unfortunately has
    	# type "unknown" in /etc/mtab. If we encounter
    	# "unknown", we try to get the type from fstab.
    	cat /etc/fstab |
    	grep -v '^#' |
    	while read FSTAB_DEV FSTAB_MP FSTAB_FST FSTAB_OPTS FSTAB_DUMP FSTAB_DUMP ; do
    		if [ "$FSTAB_MP" = "$MP" ]; then
    			echo $FSTAB_FST
    			exit 0
    		fi
    	done
    }
    
    if [ $DO_REMOUNT_NOATIME -eq 1 ] ; then
    	NOATIME_OPT=",noatime"
    fi
    
    case "$1" in
    	start)
    		AGE=$((100*$MAX_AGE))
    		XFS_AGE=$(($XFS_HZ*$MAX_AGE))
    		echo -n "Starting laptop_mode"
    
    		if [ -d /proc/sys/vm/pagebuf ] ; then
    			# (For 2.4 and early 2.6.)
    			# This only needs to be set, not reset -- it is only used when
    			# laptop mode is enabled.
    			echo $XFS_AGE > /proc/sys/vm/pagebuf/lm_flush_age
    			echo $XFS_AGE > /proc/sys/fs/xfs/lm_sync_interval
    		elif [ -f /proc/sys/fs/xfs/lm_age_buffer ] ; then
    			# (A couple of early 2.6 laptop mode patches had these.)
    			# The same goes for these.
    			echo $XFS_AGE > /proc/sys/fs/xfs/lm_age_buffer
    			echo $XFS_AGE > /proc/sys/fs/xfs/lm_sync_interval
    		elif [ -f /proc/sys/fs/xfs/age_buffer ] ; then
    			# (2.6.6)
    			# But not for these -- they are also used in normal
    			# operation.
    			echo $XFS_AGE > /proc/sys/fs/xfs/age_buffer
    			echo $XFS_AGE > /proc/sys/fs/xfs/sync_interval
    		elif [ -f /proc/sys/fs/xfs/age_buffer_centisecs ] ; then
    			# (2.6.7 upwards)
    			# And not for these either. These are in centisecs,
    			# not USER_HZ, so we have to use $AGE, not $XFS_AGE.
    			echo $AGE > /proc/sys/fs/xfs/age_buffer_centisecs
    			echo $AGE > /proc/sys/fs/xfs/xfssyncd_centisecs
    			echo 3000 > /proc/sys/fs/xfs/xfsbufd_centisecs
    		fi
    
    		case "$KLEVEL" in
    			"2.4")
    				echo 1					> /proc/sys/vm/laptop_mode
    				echo "30 500 0 0 $AGE $AGE 60 20 0"	> /proc/sys/vm/bdflush
    				;;
    			"2.6")
    				echo 5					> /proc/sys/vm/laptop_mode
    				echo "$AGE"				> /proc/sys/vm/dirty_writeback_centisecs
    				echo "$AGE"				> /proc/sys/vm/dirty_expire_centisecs
    				echo "$DIRTY_RATIO"			> /proc/sys/vm/dirty_ratio
    				echo "$DIRTY_BACKGROUND_RATIO"		> /proc/sys/vm/dirty_background_ratio
    				;;
    		esac
    		if [ $DO_REMOUNTS -eq 1 ]; then
    			cat /etc/mtab | while read DEV MP FST OPTS DUMP PASS ; do
    				PARSEDOPTS="$(parse_mount_opts "$OPTS")"
    				if [ "$FST" = 'unknown' ]; then
    					FST=$(deduce_fstype $MP)
    				fi
    				case "$FST" in
    					"ext3"|"reiserfs")
    						PARSEDOPTS="$(parse_mount_opts commit "$OPTS")"
    						mount $DEV -t $FST $MP -o remount,$PARSEDOPTS,commit=$MAX_AGE$NOATIME_OPT
    						;;
    					"xfs")
    						mount $DEV -t $FST $MP -o remount,$OPTS$NOATIME_OPT
    						;;
    				esac
    				if [ -b $DEV ] ; then
    					blockdev --setra $(($READAHEAD * 2)) $DEV
    				fi
    			done
    		fi
    		if [ $DO_HD -eq 1 ] ; then
    			for THISHD in $HD ; do
    				/sbin/hdparm -S $BATT_HD $THISHD > /dev/null 2>&1
    				/sbin/hdparm -B 1 $THISHD > /dev/null 2>&1
    			done
    		fi
    		if [ $DO_CPU -eq 1 -a -e /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq ]; then
    			if [ $CPU_MAXFREQ = 'slowest' ]; then
    				CPU_MAXFREQ=`cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq`
    			fi
    			echo $CPU_MAXFREQ > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
    		fi
    		echo "."
    		;;
    	stop)
    		U_AGE=$((100*$DEF_UPDATE))
    		B_AGE=$((100*$DEF_AGE))
    		echo -n "Stopping laptop_mode"
    		echo 0 > /proc/sys/vm/laptop_mode
    		if [ -f /proc/sys/fs/xfs/age_buffer -a ! -f /proc/sys/fs/xfs/lm_age_buffer ] ; then
    			# These need to be restored, if there are no lm_*.
    			echo $(($XFS_HZ*$DEF_XFS_AGE_BUFFER))	 	> /proc/sys/fs/xfs/age_buffer
    			echo $(($XFS_HZ*$DEF_XFS_SYNC_INTERVAL)) 	> /proc/sys/fs/xfs/sync_interval
    		elif [ -f /proc/sys/fs/xfs/age_buffer_centisecs ] ; then
    			# These need to be restored as well.
    			echo $((100*$DEF_XFS_AGE_BUFFER))	> /proc/sys/fs/xfs/age_buffer_centisecs
    			echo $((100*$DEF_XFS_SYNC_INTERVAL))	> /proc/sys/fs/xfs/xfssyncd_centisecs
    			echo $((100*$DEF_XFS_BUFD_INTERVAL))	> /proc/sys/fs/xfs/xfsbufd_centisecs
    		fi
    		case "$KLEVEL" in
    			"2.4")
    				echo "30 500 0 0 $U_AGE $B_AGE 60 20 0"	> /proc/sys/vm/bdflush
    				;;
    			"2.6")
    				echo "$U_AGE"				> /proc/sys/vm/dirty_writeback_centisecs
    				echo "$B_AGE"				> /proc/sys/vm/dirty_expire_centisecs
    				echo "$DEF_DIRTY_RATIO"			> /proc/sys/vm/dirty_ratio
    				echo "$DEF_DIRTY_BACKGROUND_RATIO"	> /proc/sys/vm/dirty_background_ratio
    				;;
    		esac
    		if [ $DO_REMOUNTS -eq 1 ] ; then
    			cat /etc/mtab | while read DEV MP FST OPTS DUMP PASS ; do
    				# Reset commit and atime options to defaults.
    				if [ "$FST" = 'unknown' ]; then
    					FST=$(deduce_fstype $MP)
    				fi
    				case "$FST" in
    					"ext3"|"reiserfs")
    						PARSEDOPTS="$(parse_mount_opts_wfstab $DEV commit $OPTS)"
    						PARSEDOPTS="$(parse_yesno_opts_wfstab $DEV atime atime $PARSEDOPTS)"
    						mount $DEV -t $FST $MP -o remount,$PARSEDOPTS
    						;;
    					"xfs")
    						PARSEDOPTS="$(parse_yesno_opts_wfstab $DEV atime atime $OPTS)"
    						mount $DEV -t $FST $MP -o remount,$PARSEDOPTS
    						;;
    				esac
    				if [ -b $DEV ] ; then
    					blockdev --setra 256 $DEV
    				fi
    			done
    		fi
    		if [ $DO_HD -eq 1 ] ; then
    			for THISHD in $HD ; do
    				/sbin/hdparm -S $AC_HD $THISHD > /dev/null 2>&1
    				/sbin/hdparm -B 255 $THISHD > /dev/null 2>&1
    			done
    		fi
    		if [ $DO_CPU -eq 1 -a -e /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq ]; then
    			echo `cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq` > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
    		fi
    		echo "."
    		;;
    	*)
    		echo "Usage: $0 {start|stop}" 2>&1
    		exit 1
    		;;
    
    esac
    
    exit 0
    

    Finally, the following few files have to be created with the following content:
    -----------------/etc/acpi/events/ac_adapter BEGIN------------------------------
    event=ac_adapter
    action=/etc/acpi/actions/ac.sh %e
    ----------------/etc/acpi/events/ac_adapter END---------------------------------
    
    
    -----------------/etc/acpi/events/battery BEGIN---------------------------------
    event=battery.*
    action=/etc/acpi/actions/battery.sh %e
    ----------------/etc/acpi/events/battery END------------------------------------
    
    
    ----------------/etc/acpi/actions/ac.sh BEGIN-----------------------------------
    #!/bin/bash
    
    # ac on/offline event handler
    
    status=`awk '/^state: / { print $2 }' /proc/acpi/ac_adapter/$2/state`
    
    case $status in
            "on-line")
                     cp /etc/syslog.conf.power /etc/syslog.conf
                     /sbin/service syslog restart
                     /sbin/laptop_mode stop
                    exit 0
            ;;
            "off-line")
                     cp /etc/syslog.conf.battery /etc/syslog.conf
                     /sbin/service syslog restart
                     /sbin/laptop_mode start
                    exit 0
            ;;
    esac
    ---------------------------/etc/acpi/actions/ac.sh END--------------------------
    
    
    ---------------------------/etc/acpi/actions/battery.sh BEGIN-------------------
    #! /bin/bash
    
    # Automatically disable laptop mode when the battery almost runs out.
    
    BATT_INFO=/proc/acpi/battery/$2/state
    
    if [[ -f /proc/sys/vm/laptop_mode ]]
    then
       LM=`cat /proc/sys/vm/laptop_mode`
       if [[ $LM -gt 0 ]]
       then
         if [[ -f $BATT_INFO ]]
         then
            # Source the config file only now that we know we need
            if [ -f /etc/default/laptop-mode ] ; then
                    # Debian
                    . /etc/default/laptop-mode
            elif [ -f /etc/sysconfig/laptop-mode ] ; then
                    # Others
                    . /etc/sysconfig/laptop-mode
            fi
            MINIMUM_BATTERY_MINUTES=${MINIMUM_BATTERY_MINUTES:-'10'}
    
            ACTION="`cat $BATT_INFO | grep charging | cut -c 26-`"
            if [[ ACTION -eq "discharging" ]]
            then
               PRESENT_RATE=`cat $BATT_INFO | grep "present rate:" | sed  "s/.* \([0-9][0-9]* \).*/\1/" `
               REMAINING=`cat $BATT_INFO | grep "remaining capacity:" | sed  "s/.* \([0-9][0-9]* \).*/\1/" `
            fi
            if (($REMAINING * 60 / $PRESENT_RATE < $MINIMUM_BATTERY_MINUTES))
            then
               /sbin/laptop_mode stop
            fi
         else
           logger -p daemon.warning "You are using laptop mode and your battery interface $BATT_INFO is missing. This may lead to loss of data when the battery runs out. Check kernel ACPI support and /proc/acpi/battery folder, and edit /etc/acpi/battery.sh to set BATT_INFO to the correct path."
         fi
       fi
    fi
    

    After a restart of the acpid daemon (service acpid restart), the laptop mode should become activated if the AC power is disconnected.
    If you have got some nice setup for the D600 please do not hesitate to contact me on jeppe.andersen_REMOVE_@_THIS_cern.ch with the details.