#! /bin/sh
#
### BEGIN INIT INFO
# Provides:          pcmcia
# Default-Start:     1 2 3 4 5
# Default-Stop:      0 6
# Short-Description: PCMCIA support
# Description:       This service provides PCMCIA hardware support for
#                    systems running Linux >= 2.6.13-rc1.
### END INIT INFO

set -e

# If /lib/lsb/init-functions doesn't exist
# define them here, otherwise installer breaks
if [ -f /lib/lsb/init-functions ]; then
    . /lib/lsb/init-functions
else
    log_action_begin_msg ()
    {
	printf '%s...' "$*"
    }
    log_action_end_msg ()
    {
	CODE="$1"
	shift
	if [ "$CODE" = 0 ]; then
	    printf done
	else
	    printf failed
	fi
	if [ "$2" ]; then
	    printf ' (%s)' "$2"
	fi
	echo .
    }
fi

KERNEL_VERSION="$(uname -r | sed 's/-.*//')"

supported_kernel()
{
    case $KERNEL_VERSION in
	2.[012345].*|2.6.[0-9]|2.6.[0-9][!0-9]*) return 1 ;;
	2.6.1[012]|2.6.1[012][!0-9]*) return 1 ;;
    esac
    return 0
}

module_is_loaded()
{
    grep -q "^$1 " /proc/modules
}

bridge_module_loaded()
{
    module_is_loaded yenta_socket || module_is_loaded i82365 \
	|| module_is_loaded tcic || module_is_loaded i82092
}

# Only works on 2.6 kernels
cardbus_bridge_present()
{
    [ -d /sys/bus/pci/devices ] || return 1
    # yenta_socket
    if grep -q 0x060700 /sys/bus/pci/devices/*/class; then
	return 0
    fi
    for x in /sys/bus/pci/devices/*; do
	# i82092
	if [ -e "$x/vendor" ] && [ -e "$x/device" ]; then
	    if [ "$(cat "$x/vendor")" = 0x8086 ] && \
	       [ "$(cat "$x/device")" = 0x1221 ]; then
		return 0
	    fi
	fi
    done
    return 1
}

failed_to_load()
{
    log_action_end_msg 1 "Failed to load $1"
    exit 1
}

# Source PCMCIA configuration, if available
if [ -f /etc/default/pcmciautils ]; then
    # Save option values passed in through the environment
    for N in PCIC PCIC_OPTS CORE_OPTS; do
	V=`eval echo '$'$N`; if [ "$V" ]; then eval ENV_$N=\"$V\"; fi
    done

    . /etc/default/pcmciautils
    
    for N in PCIC PCIC_OPTS CORE_OPTS; do
	V=`eval echo '$'ENV_$N`; if [ "$V" ]; then eval $N=\"$V\"; fi
    done
fi

[ -f /etc/default/rcS ] && . /etc/default/rcS

if [ "x$VERBOSE" = "xno" ]; then
    MODPROBE_OPTIONS="$MODPROBE_OPTIONS -Q"
    export MODPROBE_OPTIONS
fi

case "$1" in
    start)
	log_action_begin_msg "Starting PCMCIA services"

	if ! supported_kernel; then
	    log_action_end_msg 1 "pcmciautils requires Linux >= 2.6.13-rc1"
	    exit 1
	fi

	if [ -z "$PCIC" ] && \
	   ! ls /sys/class/pcmcia_socket/* >/dev/null 2>&1; then
	    log_success_msg "PCMCIA not present"
	    exit 1
	fi

	if [ "$CORE_OPTS" ]; then
	    modprobe -Qb pcmcia_core $CORE_OPTS
	fi

	if [ "$PCIC" ] && ! ls /sys/class/pcmcia_socket/* >/dev/null 2>&1; then
	    # Treat i82365 specially, as many people with yenta_socket
	    # incorrectly have PCIC set to i82365 for historical reasons.
	    if [ "$PCIC" = i82365 ]; then
		if ! bridge_module_loaded; then
		    # We must not load any other bridge modules than the
		    # right one.
		    if ! cardbus_bridge_present; then
			modprobe -Qb $PCIC $PCIC_OPTS || failed_to_load $PCIC
		    fi
		fi
	    else
		modprobe -Qb $PCIC $PCIC_OPTS || failed_to_load $PCIC
	    fi
	fi

	log_action_end_msg 0
	;;

    stop)
	;;
    
    restart)
	$0 stop
	$0 start
	exit $?
	;;

    reload|force-reload)
	;;

    *)
	log_success_msg "Usage: $0 {start|stop|restart|reload|force-reload}"
	exit 2
	;;
esac
