søndag den 6. marts 2011

Linux: Running a command/script after resuming from sleep

I've got myself a Asus Eee Top 1602, which I really want to run linux (gentoo) on.

I've got most of the stuff on it working, both the touchscreen, audio and wifi.

There are two issues left:
 * The volume keys on the front don't work, and
 * after I resume from suspend, the display is dimmed to something like 50%.

Previous issues have been:
 * Getting the wifi to work, and
 * Getting the wifi to work after resume.

Things I haven't looked at yet:
 * Memory card reader

Let me just give the some info to the eee top 1602:
 # lspci
00:00.0 Host bridge: Intel Corporation Mobile 945GME Express Memory Controller Hub (rev 03)
00:02.0 VGA compatible controller: Intel Corporation Mobile 945GME Express Integrated Graphics Controller (rev 03)
00:02.1 Display controller: Intel Corporation Mobile 945GM/GMS/GME, 943/940GML Express Integrated Graphics Controller (rev 03)
00:1b.0 Audio device: Intel Corporation 82801G (ICH7 Family) High Definition Audio Controller (rev 02)
00:1c.0 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 1 (rev 02)
00:1c.1 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 2 (rev 02)
00:1c.3 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 4 (rev 02)
00:1d.0 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI Controller #1 (rev 02)
00:1d.1 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI Controller #2 (rev 02)
00:1d.2 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI Controller #3 (rev 02)
00:1d.3 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI Controller #4 (rev 02)
00:1d.7 USB Controller: Intel Corporation 82801G (ICH7 Family) USB2 EHCI Controller (rev 02)
00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev e2)
00:1f.0 ISA bridge: Intel Corporation 82801GBM (ICH7-M) LPC Interface Bridge (rev 02)
00:1f.2 IDE interface: Intel Corporation 82801GBM/GHM (ICH7 Family) SATA IDE Controller (rev 02)
00:1f.3 SMBus: Intel Corporation 82801G (ICH7 Family) SMBus Controller (rev 02)
01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 02)
02:00.0 Network controller: RaLink RT2860
# lsusb
Bus 001 Device 005: ID 0bda:0158 Realtek Semiconductor Corp. Mass Storage Device
Bus 001 Device 006: ID 0458:7063 KYE Systems Corp. (Mouse Systems)
Bus 001 Device 003: ID 05e3:0608 Genesys Logic, Inc. USB-2.0 4-Port HUB
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 005 Device 002: ID 1bfd:1688 TouchPack Resistive Touch Screen
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 002: ID 04f2:0402 Chicony Electronics Co., Ltd
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub


Getting wifi to work
I'm using the staging driver in the kernel.
It's under: Device Drivers -> Staging drivers ->  Ralink 2860/3090 wireless support
You can compile it as a module or built it into the kernel, it dosen't matter.
What matters, is that you go go Ralink's website, and download the firmware file rt2860.bin, otherwise you'll just get something like this in dmesg when you "up" the wifi:
eeeTop kernel: [ 1321.424360] rt2860 0000:02:00.0: firmware file rt2860.bin request failed (-2)
eeeTop kernel: [ 1321.424378] ERROR! NICLoadFirmware failed, Status[=0x00000001]
eeeTop kernel: [ 1321.424397] rt28xx Initialized fail!

You'll find that here: http://www.ralinktech.com/support.php?s=2 and you'll need to get the PCI firmware of course.
Download that, extract, and place it under /lib/firmware (you might have to create the directory).

After this, I just emerged wpa_supplicant, and I'm able to connect to my wifi (WPA2 protected).

Getting wifi to work after resume
I found out that after the machine has been put in suspend, and reawaken, the wifi does work reconnect.
wpa_supplicant still reports the wifi as connected (with an IP adress and all that, but there's no connection).
I've read some people have some success by disabling some kernel options (specifically wireless extensions), but that  did not work for me.
Instead 'm just restarting the wifi after the machine resumes.
First I thought of using acpid, but I could not find see that that reports any suspend/resume events.
Anyway acpi is old, and maybe deprecated, now with hal (which is also deprecated) and policykit/consolekit, the last one being the future.
I've moved the system completely over to consolekit/policykit, and it work 100% now. (power management, shutdown, suspend, hibernate). But how to migrate was not that well documented, but thats a different story.

I found the solution to be pm-utils.
Even though it is written for HAL, it seems to work for consolekit as well.
Best of all, it is very easy to setup.
Under /etc/pm/ you'll find the configuration.

Under /etc/pm/sleep.d/ I just made a new file 50wifi, and put this in it:
#!/bin/bash
case $1 in
   hibernate)
       echo "Hibernating"
       ;;
   suspend)
       echo "Suspending"
       ;;
   thaw)
       echo "Returning from hibernation"
       /etc/init.d/net.wlan0 restart
       ;;
   resume)
       echo "Returning from suspend"
       /etc/init.d/net.wlan0 restart
       ;;
esac

Next, just make the file executable:
# chmod +x /etc/pm/sleep.d/50wifi

And thats it.
Now, every time the computer comes back from suspend or hibernation it restarts my wireless, and my connection is back within seconds.

I might update the blog, once I the re two remaining issues resolved.
I can live without the volume keys, but the dimmed display really needs to be fixed.