#!/bin/sh
# $Id: loadem_linux.sh,v 1.10 2004/01/12 11:58:16 lreiter Exp $ 
# SCCSID(@(#)loadem_linux.sh	1.30) Modified 21:41:43 11/1/01
# Load the Win4Lin drivers.

# Get the VARMERGE and STATICMERGE setting.
. /etc/mrgssv.sh

LOGFILE="$VARMERGE"/log/insmod.log
rm -f "$LOGFILE"
exec >$LOGFILE 2>&1

if [ -f "$VARMERGE/MERGE_CHROOT" ]
then
	echo "Loadem found MERGE_CHROOT, doing nothing"
	exit 0
fi

get_serial_tunable()
{
  OUTLIST=""
  # If there is a serial_tune override file, use it.
  SERIAL_TUNE_FILE="$VARMERGE"/serial_tune
  if [ -f "$SERIAL_TUNE_FILE" ]
  then
	echo "Using serial tune file: $SERIAL_TUNE_FILE" 1>&2
  	OUTLIST="`grep -v '^#' "$SERIAL_TUNE_FILE" 2>/dev/null`"
  else
	cat /proc/tty/driver/serial | tr '[A-Z]' '[a-z]' | \
	    sed -e '{
		/uart:unknown/d
		/uart/!d
		s/^[0-9]*: //
		s/irq /irq=/g 
		s/:/=/g 
		s/baud=.*//g
		s/tx=.*//g
		s/rx=.*//g
		s/brk=.*//g
		s/fe=.*//g
		s/|.*//g
	    }' >"$VARMERGE"/tmp/$$ser
	for PORT in 3f8 2f8 3e8 2e8
	do
	    uart=unknown
	    port=0
	    SSOUT=`grep "port=[0]*${PORT}" "$VARMERGE"/tmp/$$ser`
	    eval $SSOUT
	    case "$port" in
	      *3f8)
		 OUTLIST="$OUTLIST mcom1_irq=${irq}"
		 ;;
	      *2f8)
		 OUTLIST="$OUTLIST mcom2_irq=${irq}"
		 ;;
	      *3e8)
		 OUTLIST="$OUTLIST mcom3_irq=${irq}"
		 ;;
	      *2e8)
		 OUTLIST="$OUTLIST mcom4_irq=${irq}"
		 ;;
	    esac
	done
	rm -f "$VARMERGE"/tmp/$$ser
  fi

  # This will strip newlines and spaces
  echo `echo "$OUTLIST"`
}

# Get the maximum Windows sessions count from the license info,
# and set the tuneable _M_max_num_sessions accordingly.
# This sets the size of some internal data structures in the modules.

SESSIONS=`"$STATICMERGE"/bin/max_sessions`
echo "SESSIONS=$SESSIONS"
if [ "x$SESSIONS" = "x" ]
then
	echo "max_sessions failed.  Here is the output:"
	"$STATICMERGE"/bin/max_sessions
	VAL=$?
	echo "exit code $VAL"
	SESSIONS=1
fi

# Adjust the SESSIONS value for the _M_max_num_sessions to be larger
# than the allowed number of Windows sessions because there can also
# be DOS sessions.  So at least triple the value, and set the minumum
# to 10 and the maximum to 128.  (128 because that is the current max
# table size in the drivers.
SESSIONS=`expr $SESSIONS + $SESSIONS + $SESSIONS`
if [ $SESSIONS -lt 10 ]
then
	SESSIONS=10
elif [ $SESSIONS -gt 128 ]
then
	SESSIONS=128
fi

MERGE_TUNE="_M_max_num_sessions=$SESSIONS"
echo "MERGE_TUNE: $MERGE_TUNE"

SERIAL_TUNE=`get_serial_tunable`
echo "SERIAL_TUNE: $SERIAL_TUNE"

cd $STATICMERGE/drivers

tools/unloadem > /dev/null 2> /dev/null


LOAD_LINUX24_MODULES()
{
    # install the mki-adapter module
    ( set -x ; /sbin/modprobe mki-adapter )
    if [ $? -ne 0 ]
    then
	echo "Trying insmod on generic /lib/modules/mki-adapter.o"
	(set -x ; /sbin/insmod -f /lib/modules/mki-adapter.o )
    else
	echo "modprobe successful"
    fi

    modadpvers=`grep mkia_ver /proc/ksyms|sed -e's/.*mkia_ver_//g '|\
		sed -e's/\[mki-adapter\]//g'`
    echo "module adapter version: $modadpvers" >>$LOGFILE
    if [ "x$modadpvers" = "x" ]
    then
	echo 'Failed to insert the mki-adapter module. Please install the '
	echo 'mki-adapter kernel module that matches this kernel:'
	uname -r
	echo See $LOGFILE for additional messages.
	exit 1
    fi

    # check mki
    mkivers=`grep mki_version /proc/ksyms`
    echo "mki_version : $mkivers" >>$LOGFILE
    if [ "x$mkivers" = "x" ]
    then
	# The required kernel support is missing, so don't load the
	# drivers.
	echo "Win4Lin kernel support is missing, cannot load Win4Lin modules." \
		| tee -a $LOGFILE
	exit 1
    fi

    # Load the Mmerge driver first
    LIST=`ls M*.o | sed -e 's/Mmerge.o//' -e 's/Mvnet.*//'`
    if [ -e Mvnetd.o ]
    then
	VNET="Mvnetint.o Mvnet.o Mvnetd.o"
    fi
    for i in Mmerge.o $LIST $VNET
    do
	case "$i" in
	    Mmerge.o)
		TUNE_PARAMS="$MERGE_TUNE"
		;;
	    Mserial.o)
		TUNE_PARAMS="$SERIAL_TUNE"
		;;
	    *)
		TUNE_PARAMS=""
		;;
	esac
	if [ -x /sbin/insmod_ver ]
	then
	    (set -x ; /sbin/insmod_ver -f $i $TUNE_PARAMS )
	    STATUS="$?"
	else
	    (set -x ; insmod -f $i $TUNE_PARAMS )
	    STATUS="$?"
	fi

	if [ "$STATUS" -ne 0 ]
	then
	    # These messages need to be NLSized.  TBD_NLS
	    echo Failed to load $i
	    if [ ! -x /sbin/insmod_ver ]
	    then
		echo "NOTE: This failure happened because Win4Lin was NOT"
		    echo "installed according to the instructions, and thus"
		    echo "'/sbin/insmod_ver' did not get installed from the"
		    echo "installation CD."
		    echo "This is needed because the standard 'insmod' command"
		    echo "is insufficient to load the Win4Lin modules on this"
		    echo "system type."
		fi
		echo "See $LOGFILE for load failure messages."
		# Unload any previously loaded drivers so
		# we don't leave things half loaded.
		tools/unloadem > /dev/null 2> /dev/null
		exit 2
	fi
    done
}

LOAD_LINUX26_MODULES()
{
    # install the mki-adapter module
    ( set -x ; /sbin/modprobe mki-adapter )
    if [ $? -ne 0 ]
    then
	echo "Warning: Modprobe on mki-adapter FAILED"
    else
	echo "Modprobe on mki-adapter successful"
    fi

    MODPREP=tools/mkiamodprep
    if [ ! -f Win4Lin.pko ]
    then
	echo "No Win4Lin.pko in current directory"
	exit 2
    fi
    if [ ! -f $MODPREP ]
    then
	echo "No $MODPREP utility"
	exit 2
    fi

    VAR_DRIVER_DIR="$VARMERGE"/drivers
    mkdir -p "$VAR_DRIVER_DIR"
    chmod 755 "$VAR_DRIVER_DIR"
    KO_FILE="$VAR_DRIVER_DIR"/Win4Lin.ko

    (set -x ; $MODPREP Win4Lin.pko "$KO_FILE" )
    if [ "$?" -ne 0 ]
    then
	echo "$MODPREP Win4Lin.pko $KO_FILE failed"
	exit 2
    fi

    (set -x ; insmod $KO_FILE $MERGE_TUNE $SERIAL_TUNE )
    if [ "$?" -ne 0 ]
    then
	echo "insmod $KO_FILE $MERGE_TUNE $SERIAL_TUNE failed"
	exit 2
    fi
}

LINUX_VER="`uname -r`"
case "$LINUX_VER" in
  2.4*)
    LOAD_LINUX24_MODULES
    ;;

  2.6*)
    LOAD_LINUX26_MODULES
    ;;
  *)
    echo "Unknown Linux version $LINUX_VER"
    exit 3
    ;;
esac

"$STATICMERGE"/drivers/tools/mknode_linux $SESSIONS >/dev/null 2>&1

# Now load the VNET deamons.
START_LINUX_VNET_DAEMON()
{
	if [ !  -x "$STATICMERGE"/bin/vnetd ]
	then
		echo ""
		echo "Missing $STATICMERGE/bin/vnetd"
		return
	fi
	if [ ! -d /proc/sys/net/ipv4 ]
	then
		echo ""
		echo "Not starting Merge virtual network"
		echo "(Networking not installed)"
		return
	fi
	grep "^MERGE_VNETWORK=off" /etc/default/merge > /dev/null
	if [ $? -eq 0 ]
	then
		echo ""
		echo "Not starting Merge virtual network"
		echo "(MERGE_VNETWORK=off in /etc/default/merge)"
		return
	fi
	"$STATICMERGE"/bin/vnetd &
}
START_LINUX_VNET_DAEMON

# Now load the mergevncd daemon, if needed
START_LINUX_MERGEVNCD_DAEMON()
{
	. "$VERFILE"
	if [ "$PRODUCT_STYLE" = "server" ]
	then
		if [ ! -x "$STATICMERGE"/mergevncd ]
		then
			echo ""
			echo "Missing $STATICMERGE/mergevncd"
			return
		fi
		PATH="$PATH:/usr/bin/X11:/usr/X11R6/bin" \
			"$STATICMERGE"/mergevncd
	fi
}
START_LINUX_MERGEVNCD_DAEMON

# Now load the cdahubd daemon, if needed
START_LINUX_CDAHUBD_DAEMON()
{
	. "$VERFILE"
	if [ "$PRODUCT_STYLE" = "server" ]
	then
		if [ ! -x "$STATICMERGE"/cdahubd ]
		then
			echo ""
			echo "Missing $STATICMERGE/cdahubd"
			return
		fi
		"$STATICMERGE"/cdahubd
	fi
}
START_LINUX_CDAHUBD_DAEMON

