#!/bin/sh

########################################
# Authors:
# Originally by Ortwin Glueck.
# Modified by Nick Hoffman <litage7@gmail.com> on 2007-07-29 :
#   -Updated comments.
#   -Customised for use in Debian Etch.
#   -Customised for use with either ndiswrapper or madwifi.
#   -Only unloads and re-loads the 'uvcvideo' module if necessary.
########################################
# Description:
# This script suspends a MacBook Pro Core2 Duo to RAM.
########################################


###################################################
#    MODIFY THESE VARIABLES TO SUIT YOUR NEEDS    #

# Set these to 0 if using the proprietary ATI driver v35.5+ .
# Set these to 1 for older drivers.
LeaveX=0                # Set to 1 to log users out of X and unload the 'fglrx' module before suspending. Also re-load the module on resume.
VideoPost=0             # Set to 1 to run `vbetool post` after resuming.

wifiDevice="ath0"       # Set this to your wireless interface.
                        # If you're using madwifi, it's likely to be "ath0".
                        # If you're using ndiswrapper, it's likely to be "wlan0".

wifiModule='ath_pci'    # The wifi kernel module to load when resuming.
                        # If you're using madwifi, it's likely to be "ath_pci".
                        # If you're using ndiswrapper, it's "ndiswrapper".

unloadMadwifi='/usr/src/madwifi/scripts/madwifi-unload.bash'
                        # The path to the madwifi script "madwifi-unload.bash". This script is included with the madwifi source.
                        # If you don't use madwifi, you can ignore this variable.
###################################################


#######################################
#    DO NOT MODIFY THESE VARIABLES    #
PATH=/usr/kde/3.5/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
loadUvcvideo=0
logfile='/var/log/MBP_C2D_s2ram.log'
#######################################


# Log a message to stdout AND the log file.
logmsg() {
	echo "`date +'%F %T'` ${1}" | /usr/bin/tee -a "${logfile}" 
	}


getusers() {
	KDEUsers=$(w -hs | awk '$0~/startkde/ { print $1 }')
    }


# Ensure we're running as root.
if [ "`whoami`" != 'root' ]; then
    echo "This script must be run as root."
    exit 1
fi

logger -t acpi "${0}: Suspending to RAM"
logmsg 'Beginning the suspend-to-RAM sequence.'
echo

if [ "${LeaveX}" = "1" ]; then
    # To unload the 'flgrx' module, X must first be shutdown. Thus, log all users out of KDE.
	getusers
	for U in ${KDEUsers}; do
		logmsg "Logging user '${U}' out of KDE."
		dcop --all-sessions --user "${U}" ksmserver default logout 0 0 -1
	done

	# Wait until all users have been logged out of KDE.
	getusers
	while [ ! -z "${KDEUsers}" ]; do
		getusers
		sleep 0.5
	done

	logmsg 'Shutting down X.'
	/etc/init.d/kdm stop

    # If we got here, X is no longer running, so it's safe to unload the 'fglrx' module.
	logmsg 'Unloading the fglrx kernel module.'
	modprobe -r fglrx
else
    # Switch to the first virtual terminal.
	logmsg 'Switching to vt/1.'
	chvt 1
fi
echo

logmsg "Bringing down ${wifiDevice}."
ifdown "${wifiDevice}"
echo

# Unload the wifi kernel module.
logmsg "Unloading the wireless NIC's kernel module."
if [ "${wifiDevice}" = "ath0" ]; then
    ${unloadMadwifi}
elif [ "${wifiDevice}" = "wlan0" ]; then
    modprobe -r -v ndiswrapper
else
    echo "WARNING: No wifi module was unloaded."
fi
echo

# If the 'uvcvideo' module is loaded, unload it and make sure it gets re-loaded upon resume.
lsmod | grep -q uvcvideo
if [ "x$?" = 'x0' ]; then
	logmsg 'Unloading the uvcvideo kernel module.'
    loadUvcvideo=1
    modprobe -r -v uvcvideo
fi

# Use s3_bios when sleeping.
logmsg 'Setting up s3_bios use.'
echo 1 > /proc/sys/kernel/acpi_video_flags

# Store the video card's state.
logmsg "Storing the video card's state."
VGASTATE=$(vbetool vbemode get)
echo

# Ensure data is synced to the HDs before suspending.
logmsg 'Syncing data to the HDs.'
sync; sync
echo

# And finally, suspend to RAM.
logmsg 'Suspending to RAM.'
#echo mem > /sys/power/state
echo mem > /sys/power/state

sleep 2

# When we get to here, we're resuming.
logger -t acpi "${0}: Resuming from RAM"
echo
logmsg 'Resuming from RAM.'
echo

# Bring the video/LCD back to life.
if [ "${VideoPost}" = "1" ]; then
	logmsg 'POSTing the video card.'
	vbetool post
fi
logmsg "Setting the video card's state."
vbetool vbemode set ${VGASTATE}
echo

# Load the 'uvcvideo' module if it was unloaded.
if [ "x$loadUvcvideo" = 'x1' ]; then
	logmsg 'Loading the uvcvideo kernel module.'
    modprobe uvcvideo
	echo
fi

# If X was stopped before suspending, start it up again.
# Otherwise, X is already running, so switch to virtual terminal 7 (where X is).
if [ "${LeaveX}" = "1" ]; then
	logmsg 'Loading the fglrx kernel module.'
	modprobe fglrx

	logmsg 'Starting X.'
	/etc/init.d/kdm start

	echo
else
	logmsg 'Switching to vt/7.'
	chvt 7
fi

# Bring up the wireless interface.
logmsg "Loading the wireless NIC's kernel module."
modprobe -v "${wifiModule}"
logmsg "Bringing up ${wifiDevice}."
#ifup "${wifiDevice}"
echo

logmsg 'Finished resuming from RAM.'

# vi:ts=4
