:
#		(C) 1989-1990 The Santa Cruz Operation, Inc.  All Rights
#		Reserved.  The user has unlimited right to use, modify
#		and incorporate this code into other products provided
#		it is used with SCO products and the user includes
#		this notice and the associated copyright notices with
#		any such application.
#
# This script is for installing an LLI driver using netconfig
# 
# lan0	== Intel L-Series (Panther) Ethernet Network Adapter Driver
#

LIB=/usr/lib/lli
CONF=/etc/conf
PATH=/bin:/usr/bin:/etc/:$CONF/bin:$LIB

#
# Set possible return codes for this script
#

OK=0;	FAIL=1;	RELINK=2;

BRAM="0"
ERAM="0"


#
# Prompt the user to make a selection a list of values
# Usage:
#	prompt_select "Message" default "value_list"
#

prompt_select() {
    mesg=$1
    default=$2
    values=$3

    while :
    do
	if [ "$default" = "" ]
	then
	    echo "${mesg} (${values}) or 'q' to quit: \c"
	else
	    echo "${mesg} (${values}) [${default}] or 'q' to quit: \c"
	fi
	read result
	case $result in
	Q|q)
	    return $FAIL
	    ;;
	"")
	    result=$default
	    ;;
	esac

	for i in $values
	do
	    if [ "$i" = "$result" ]
	    then
		return $OK
	    fi
	done
	echo "Illegal value, must be one of (${values})"
    done
}


#
# Fake up an mdevice and an sdevice for idcheck
#

makedevs() {
    dir=`pwd`
    rm -fr /tmp/dev$$
    mkdir /tmp/dev$$
    cd /etc/conf/cf.d
    cp mdevice /tmp/dev$$
    cd ../sdevice.d
    cat * > /tmp/dev$$/sdevice
    cd $dir
}


cleanup() {
    cd /
    rm -fr /tmp/dev$$
    rm -fr /tmp/$base
    exit $1
}


#
# Removes the given interrupt vector for the $clash device.
#

rmvector() {
    clash=$1
    vec=$2

    cd $confdir
    echo "\nRemoving interrupt vector $vec for the $clash device ..."

    [ "$vec" = "2" ] && vec=9
    major=`./configure -j $clash` && { 
	# remove device but leave it required
	if [ "$major" != "0" ] 
	then
	    ./configure -d -c -m $major -v $vec -Y >> conflog 2>&1 || { 
		cd $currdir
		cleanup $FAIL
	    }
	else
	    sed -e "s/Y/N/" ../sdevice.d/$clash > /tmp/bog$$
	    mv /tmp/bog$$ ../sdevice.d/$clash 
	fi
	# remove required setting if no more left
	if grep "Y" ../sdevice.d/$clash > /dev/null 2>&1
	then
	    true
	elif [ "$major" != "0" ]
	then
	    ./configure -d -c -m $major -v $vec -R -Y >> conflog 2>&1 || { 
		cd $currdir
		cleanup $FAIL
	    }
	fi
    }
    cd $currdir
    return $OK
}


#
# On unix, we must check the files in sdevice.d.
# Sets the variable $clash to the driver code name if there is a driver that
# has already been allocated the given vector. Uses awk.
#

dointclash() {
    driver=$1
    vec=$2

    [ "$vec" = "2" ] && vec=9
    cd $confdir/../sdevice.d
    clash=`cat * | awk '{ if ( $6 == intr && $2 == "Y" ) exit } \
	    END { print $1 }' intr=$vec`

    cd $currdir

    [ "$clash" = "" -o "$clash" = "$driver" ] && return $FAIL
    # found a clash
    return $OK
}


checkvec() {
    driver=$1
    vector=$2
    clash=

    currdir=`pwd`

    while dointclash $driver $vector
    do
	prompt_select "Interrupt vector $vector is already in use for the $clash device.\n\n\
The alternatives available to you are:\n\n\
\t1. Continue the installation and remove vector $vector for the $clash device.\n\
\t2. Select a different interrupt vector.\n\n\
Select an option" 1 "1 2" || { 
	    cleanup $FAIL
	}
	case $result in
	1)	rmvector $clash $vector || { 
		    echo "Failed to remove vector $vector"
		    cleanup $FAIL
		}
		makedevs
		return $OK
		;;
	2)	return $FAIL
		;;
	esac
    done
    return $OK
}


check_args() {
    name=$1
    bd=$2

    case $name in
    lan) echo "Configuring Intel L-Series Ethernet board $bd";
	PREFIX="lan";
	MAX_BD=0;
	;;
    *) echo "ERROR: Unknown LLI driver being configured ($name$bd)";
	cleanup $FAIL;
	;;
    esac

    if [ $bd -gt $MAX_BD ]
    then
	echo "ERROR: Only boards 0..$MAX_BD are supported by this driver";
	cleanup $FAIL
    fi
    echo
}


#
# Function to produce the info for the System file for the
#  Intel L-Series (Panther) Ethernet Network Adapter Driver
#

system_lan() {
    bd=$1

    case $bd in
    0) IRQ=10;;
    esac

    while :
    do
	prompt_select "Enter IRQ" $IRQ "10 11" || cleanup $FAIL
	irq=$result
	checkvec $name$bd $irq && break
    done
    IRQ=$irq

    cd $LIB/lan
    sed -e "s/=.*;/= $IRQ;/" Space.c > /tmp/bog$$
    mv /tmp/bog$$ Space.c

    BIO=0

    EIO=0

    NMINORS="1"

    # up the 2k block buffers, this driver uses more than most drivers.
    awk '/^NBLK2048/ {
	NEW=$2+8
	printf "%s\t%s\n",$1,NEW
	next
    }
    { print } ' < /etc/conf/cf.d/stune > /tmp/bog$$
    mv /tmp/bog$$ /etc/conf/cf.d/stune
}


#
# function to remove address conflicts in the sio driver
#

sio_conflict() {
    currdir=`pwd`
    cd /etc/conf/pack.d/sio
    if [ "$type" = "386GT" -a "$base" = "tok0" ]
    then
	# get rid of sio access to 0x2f0 (Global Interrupt enable) on AT
	grep "ibm COM3" space.c > /dev/null && {
	    echo "Removing ibm COM3 from link kit..."
	    [ ! -f space.c.rls ] && cp space.c space.c.rls
	    sed -e /"ibm COM3/s/^{/\/* LLI {/p" space.c > /tmp/bog$$
	    mv /tmp/bog$$ space.c > /dev/null 2>&1
	}
    fi
    grep "(sd)0x$BIO" space.c > /dev/null && {
	sed -e /"(sd)0x$BIO,/s/^{/\/* LLI {/p" space.c > /tmp/bog$$
	mv /tmp/bog$$ space.c > /dev/null 2>&1
    }
    cd $currdir
}


#
# determine release, and AT or MCA bus - set rel and type variables accordingly.
#

os_type() {
    rel=`sed -n 's/^#rel=\(.*\).$/\1/p' /etc/perms/rts`
    if [ "$rel" = "3.2.0" -o "$rel" = "3.2.1" -o "$rel" = "3.2.2" ]
    then
	type=`sed -n 's/^#typ=\(.*\)$/\1/p' /etc/perms/inst`
    else
	# 3.2.4 - one release supports AT, MCA, and EISA.
	uname -X | grep "BusType = MCA" >/dev/null 2>&1
	if [ $? -eq 0 ]
	then
	    type=386MC
	else
	    type=386GT
	fi
    fi
}


create_scripts()
{
    if [ $bd -ne $MAX_BD ]
    then
	currdir=`pwd`
	netconfigdir=/usr/lib/netconfig
	cd $netconfigdir/info
	newboard=`expr $bd + 1`
	newfile=${drv}${newboard}
	cp ${drv}0 $newfile
	sed -e '/^NAME=.*'"[^0]"'/s/0\"/'$newboard'\"/p' $newfile > /tmp/bog$$
	sed -e '/^DESCRIPTION=.*'"[^0]"'/s/0\"/'$newboard'\"/p' /tmp/bog$$ > $newfile
	rm -r /tmp/bog$$
	chown bin $newfile
	chgrp bin $newfile
	chmod 750 $newfile

	cd $netconfigdir/init
	ln $base ${drv}`expr $bd + 1` > /dev/null 2>&1

	cd $netconfigdir/remove
	ln $base ${drv}`expr $bd + 1` > /dev/null 2>&1
	cd $currdir
    fi
}



# main()


# get the name of the init script being run, since one script
# is used for multiple drivers; get the number at the end of the
# script's name

if [ $# -gt 1 ]
then
    name_below=$1; if_below=$2
    name_above=$3; if_above=$4
    configure=$5
fi

base=`basename $0`
drv=`echo $base | sed -e 's/[0-9]*$//`
bd=`expr $base : '.*\(.\)'`
chains=/usr/lib/lli/chains
chain=$base:$name_above
confdir=/etc/conf/cf.d

makedevs
check_args $drv $bd

#
# Check and manage our internal chains file.
# This file allows coexistent mkdev and netconfig calls.
#
# chain already installed
#

grep $chain $chains > /dev/null 2>& 1 && {
    echo $chain >> $chains
    cleanup $OK
}

#
# this board already installed
#

grep $base: $chains > /dev/null 2>& 1 && {
    echo $base already configured.
    echo $chain >> $chains
    echo "NODE=/etc/conf/node.d/$base" >/tmp/$base.src
    chmod 777 /tmp/$base.src
    cleanup $OK
}

#
# Now check that if we are not board zero that board zero is installed
#

[ "$bd" -ne "0" ] && {
    grep ${drv}0 $chains > /dev/null 2>& 1 || {
	echo "${drv}0 not configured, you must configure it first"
	cleanup $FAIL
    }
}

#
# check to see if the driver is already in the kernel link-kit so we can
# either add it or update it later on
#

idcheck -p $base -i /tmp/dev$$
if [ $? -gt 16 ]
then
    installed="TRUE"
else
    installed="FALSE"
fi

if [ "$bd" = "0" ]
then
    echo "Installing the $drv driver into the link kit"
    cd /usr/lib/lli/$drv
    if [ "$installed" = "TRUE" ]
    then
	idinstall -u -e -k $base
    else
	idinstall -a -e -k $base
    fi
    makedevs
else
    idcheck -p ${drv}0 -i /tmp/dev$$
    if [ $? -le 16 ]
    then
	echo "${drv}0 must be configured before attempting to configure $drv"
	cleanup 1
    fi
fi

#
# create the temporary directory for installing the driver
#

cd /tmp; rm -rf $base
mkdir $base; cd $base

DMACHAN="-1"

#
# set rel, type variables.
#

os_type

#
# Do special board dependent processing
#

system_$drv $bd

echo
if [ "$IRQ" = "2" ]
then
    IRQ=9
fi

echo "$base\tY\t$NMINORS\t5\t1\t$IRQ\t$BIO\t$EIO\t$BRAM\t$ERAM" >./System

#
# All the drivers support more than one board.  In fact all the code to
# support all the boards is in the Driver.o for the board for the 1st board
# (eg the e3A0 driver acually contains enough code for the e3A1, e3A2 & e3A3
# boards).  As we need a Driver.o to be associated with 2nd, 3rd or 4th board
# we install a dummy Driver.o, and a Master and Node which will actually cause
# calls into the base driver.
#

if [ $bd -gt 0 ]
then
    echo "$base	-	iScH	$PREFIX$bd	0	0	1	256	$DMACHAN" >./Master
    echo "clone	$base	c	$base" >./Node

    if [ "$installed" = "TRUE" ]
    then
	idinstall -u -m -s -n -e -k $base
    else
	cp $LIB/Driver.o .
	idinstall -a -e -k $base
    fi
else
    echo "$base	I	iScH	$PREFIX	0	0	1	256	$DMACHAN" >./Master
    idinstall -u -m -s -e -k $base
fi

#
# we successfully installed this driver, add it to the chains file
#

echo $chain >> $chains

#
# create next set of info, init, and remove files
#

create_scripts

#
# delete any potential BASE I/O address conflicts with the sio driver
#

[ "$rel" = "3.2.0" -o "$rel" = "3.2.1" -o "$rel" = "3.2.2" ] && sio_conflict

echo "NODE=/etc/conf/node.d/$base" >/tmp/$base.src
chmod 777 /tmp/$base.src

cleanup $RELINK
