#!/bin/bash 
#
# Bring up/down sxdkernel
#
# chkconfig: 2345 05 95
# description: Activates/Deactivates SwitchX Driver to \
#              start at boot time.
#
### BEGIN INIT INFO
# Provides:       sxdkernel
# Required-Start: 
# Required-Stop:  
# Default-Start:  3 5
# Default-Stop:   0 1 2 6
# Short-Description: SwitchX driver service
# Description:    Activates/Deactivates SwitchX Driver
### END INIT INFO

# Therefore determine the base, follow a runlevel link name ...
base=${0##*/}
link=${base#*[SK][0-9][0-9]}
# ... and compare them
if [ $link == $base ] ; then
	RUNMODE=manual
else
	RUNMODE=auto    
fi
            
ACTION=$1
CHIP_TYPE=$2
shift
RESTART=0

UNLOAD_MODULES=""
STATUS_MODULES="sx_core sx_netdev 8021q"

#########################################################################
# Get a sane screen width
[ -z "${COLUMNS:-}" ] && COLUMNS=80

[ -z "${CONSOLETYPE:-}" ] && [ -x /sbin/consoletype ] && CONSOLETYPE="`/sbin/consoletype`"

if [ -f /etc/sysconfig/i18n -a -z "${NOLOCALE:-}" ] ; then
	. /etc/sysconfig/i18n
	if [ "$CONSOLETYPE" != "pty" ]; then
		case "${LANG:-}" in
			ja_JP*|ko_KR*|zh_CN*|zh_TW*)
				export LC_MESSAGES=en_US
				;;
			*)
				export LANG
				;;
		esac
	else
		export LANG
	fi
fi

echo_success() {
	echo -n $@

	[ "$BOOTUP" = "color" ] && $MOVE_TO_COL
	echo -n "[  "
	[ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS
	echo -n $"OK"
	[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
	echo -n "  ]"
	echo -e "\r"
	return 0
}

echo_done() {
	echo -n $@
	[ "$BOOTUP" = "color" ] && $MOVE_TO_COL
	echo -n "[  "
	[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
	echo -n $"done"
	[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
	echo -n "  ]"
	echo -e "\r"
	return 0
}

echo_failure() {
	echo -n $@
	[ "$BOOTUP" = "color" ] && $MOVE_TO_COL
	echo -n "["
	[ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
	echo -n $"FAILED" 
	[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
	echo -n "]"
	echo -e "\r"
	return 1
}

echo_warning() {
	echo -n $@
	[ "$BOOTUP" = "color" ] && $MOVE_TO_COL
	echo -n "["
	[ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
	echo -n $"WARNING"
	[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
	echo -n "]"
	echo -e "\r"
	return 1
}

# If module $1 is loaded return - 0 else - 1
is_module()
{
	local RC

	/sbin/lsmod | grep -w "$1" > /dev/null
	RC=$?
    
	return $RC        
}

# Return module's refcnt
is_ref()
{
	local refcnt
	refcnt=`cat /sys/module/"$1"/refcnt 2> /dev/nill`
	return $refcnt
}

start()
{
        if ! is_module 8021q ; then
	    /sbin/modprobe 8021q
	    RC=$?
	    if [ $RC -ne 0 ]; then
		echo_failure $"Loading 8021q: "
		return $RC
	    fi
        fi

	if [ -z $CHIP_TYPE ]; then
		/sbin/modprobe sx_core cq_thread_sched_priority=98 g_chip_type=1
	else
		/sbin/modprobe sx_core cq_thread_sched_priority=98 g_chip_type=$CHIP_TYPE
	fi

	RC=$?
	if [ $RC -ne 0 ]; then
		echo_failure $"Loading SX core: "
		return $RC
	fi

	if [ "x$udevd_restart" != "xno" ]; then
		if [ -x /sbin/udevtrigger ]; then
			echo "Reloading udev:"
			/sbin/udevtrigger
			RC=$?
			if [ $RC = 1 ]; then
				echo "Failed to run udevtrigger."
				return $RC
			fi
		fi
		if [ -x /sbin/udevadm ]; then
			echo "Reloading udev:"
			/sbin/udevadm trigger
			RC=$?
			if [ $RC = 1 ]; then
				echo "Failed to run udevadm."
				return $RC
			fi
		fi
	fi

       /sbin/modprobe sx_netdev
        RC=$?
        if [ $RC -ne 0 ]; then
                echo_failure $"Loading sx_netdev: "
                return $RC
        fi

	rm -rf /dev/sxdevs
	mkdir /dev/sxdevs
	RC=$?
	if [ $RC -ne 0 ]; then
		echo_failure $"Preparing /dev/sxdevs folder, has service been already started?"
		return $RC
	fi

	major=$(awk -F ' ' '$2 == "sxcdev" { print $1}' /proc/devices)
	mknod -m 666 /dev/sxdevs/sxcdev c $major 193

	RC=$?
	if [ $RC -ne 0 ]; then
		echo_failure $"Preparing /dev/sxdevs/sxcdev device"
		return $RC
	fi

       /sbin/modprobe mlnx_asic_drv
        RC=$?
        if [ $RC -ne 0 ]; then
                echo_failure $"Loading mlnx_asic_drv: "
                return $RC
        fi

	echo_success $"Loading SX driver: "

	return $RC
}

rm_mod()
{
	local mod=$1
	shift

	unload_log=`/sbin/rmmod $mod 2>&1`
	if [ $? -ne 0 ]; then
		echo_failure $"Unloading $mod"
		if [ ! -z "${unload_log}" ]; then
			echo $unload_log
		fi
		[ ! -z $2 ] && echo $2
		return 1
	fi
}

unload()
{
	# Unload module $1
	local mod=$1
	local unload_log

	if is_module $mod; then
		case $mod in
			*)
			/sbin/modprobe -r $mod
			if [ $? -ne 0 ] || is_module $mod; then
				# Try rmmod if modprobe failed.
				rm_mod $mod || return 1
			fi
			;;
		esac
	fi
}

stop()
{
    local NEED_UNLOAD=0
    
    if ! is_module mlnx_asic_drv ; then
        if [ $RESTART -eq 0 ]; then
            echo
            echo_warning $"mlnx_asic_drv driver is not loaded or loaded with errors"
            echo
        fi
    else
        NEED_UNLOAD=1
    fi

    if ! is_module sx_netdev ; then
        if [ $RESTART -eq 0 ]; then
            echo
            echo_warning $"SX NETDEV driver is not loaded or loaded with errors"
            echo
        fi
    else
        NEED_UNLOAD=1
    fi

    if ! is_module sx_core ; then
        if [ $RESTART -eq 0 ]; then
            echo
            echo_warning $"SX driver is not loaded or loaded with errors"
            echo
        fi                        
    else
        NEED_UNLOAD=1
    fi

    if [ $NEED_UNLOAD -eq 0 ]; then
        return 0
    fi

	# Unload modules
	if [ "$UNLOAD_MODULES" != "" ]; then
		for mod in  $UNLOAD_MODULES
		do
			unload $mod
		done
	fi

	local done=0

        # Unload mlnx_asic_drv
	if is_module mlnx_asic_drv; then
		is_ref mlnx_asic_drv
		unload mlnx_asic_drv
	fi

        # Unload mlx_sx_netdev
	if is_module sx_netdev; then
		is_ref sx_netdev
		unload sx_netdev
	fi

	# Unload mlx_sx_core
	if is_module sx_core; then
		is_ref sx_core
		unload sx_core
		if [ $? -eq 0 ]; then
			rm -rf /dev/sxdevs
		fi
		done=1
	fi


	if [ $done -eq 1 ]; then
		echo_success $"Unloading SX driver: "
	fi
	sleep 1
}

status()
{
	local RC=0
 
	if is_module sx_core; then
		echo
		echo "  SX driver loaded"
		echo
	else
		echo
		echo $"SX driver is not loaded"
		echo
	fi

	local cnt=0
    
	for mod in  $STATUS_MODULES
	do
		if is_module $mod; then
			[ $cnt -eq 0 ] && echo "The following SX modules are loaded:" && echo
			let cnt++
			echo "  $mod"
		fi
	done
     
	echo
    
	return $RC
}


RC=0
start_time=$(date +%s | tr -d '[:space:]')

trap_handler()
{
	let run_time=$(date +%s | tr -d '[:space:]')-${start_time}

	# Ask to wait for 5 seconds if trying to stop sx
	if [ $run_time -gt 5 ] && [ "$ACTION" == "stop" ]; then
		printf "\nProbably some application are still using SX modules...\n"
	else
		printf "\nPlease wait ...\n"
	fi
	return 0
}

trap 'trap_handler' 2 9 15

case $ACTION in
	start)
		start
	;;
	stop)
		stop    
	;;
	restart)
		RESTART=1
		stop
		start
	;;
	status)
		status
	;;
	*)
		echo 
		echo "Usage: `basename $0` {start|stop|restart|status}"
		echo
		exit 1
	;;
esac

RC=$?
exit $RC
