:
#		(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
}


#
# prompt the user to answer a yes no question or 'q' to quit
# Usage:
#	prompt_yn "Message" default

prompt_yn() {
	mesg=$1
	default=$2

	while :
	do
		echo "${mesg} (y/n) [${default}] or 'q' to quit: \c"
		read result

		case $result in
		q|Q) return $FAIL;;
		y|Y) result="Y"; return $OK;;
		n|N) result="N"; return $OK;;
		"") result=`echo $default | tr "yn" "YN"`; return $OK;;
		esac

		echo "Illegal value, please type 'y' 'n' or 'q'"
	done
}


#
# Fake up an mdevice and an sdevice for idcheck
# Do not remove $base if called with an argument...
#

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
    [ $1 ] && {
	# remove driver being reconfigured from sdevice & mdevice files.
	sed -e "/^$base/d" < /tmp/dev$$/sdevice > /tmp/bog$$
	mv /tmp/bog$$ /tmp/dev$$/sdevice 
	sed -e "/^$base/d" < /tmp/dev$$/mdevice > /tmp/bog$$
	mv /tmp/bog$$ /tmp/dev$$/mdevice 
    }
    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
	./configure -d -c -m $major -v $vec -Y >> conflog 2>&1 || { 
	    cd $currdir
	    cleanup $FAIL
	}
	# remove required setting if no more left
	if grep "Y" ../sdevice.d/$clash > /dev/null 2>&1
	then
	    true
	else
	    ./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`
    confdir=/etc/conf/cf.d

    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 restore and remove address conflicts in the sio driver
#

sio_conflict() {
    if [ "$BIO" = "$OBIO" ]
    then
	return $OK
    fi

    currdir=`pwd`
    cd /etc/conf/pack.d/sio
    grep "/* LLI {.*$OBIO" space.c > /dev/null && {
	echo "Restoring serial cards using base address 0x$OBIO into link kit..."
	sed -e /"LLI.*$OBIO,/s/^\/\* LLI //" space.c >/tmp/bog$$
	mv /tmp/bog$$ space.c 
    }
    grep "(sd)0x$BIO" space.c > /dev/null && {
	echo "Removing serial cards using base address 0x$BIO from link kit..."
	[ ! -f space.c.rls ] && cp space.c space.c.rls
	sed -e /"(sd)0x$BIO,/s/^{/\/* LLI {/p" space.c >/tmp/bog$$
	mv /tmp/bog$$ space.c
    }
    cd $currdir
}


# restorevector check for sio (vecs 3-4) and pa drivers (vec 7)
# if these are being released by lli then let us restore them to sio or pa

restorevector() {
    currdir=`pwd`
    cd /etc/conf/cf.d

    intvector=$1
    test="0"
    [ "$intvector" = "3" -o "$intvector" = "4" ] && {
	prompt_yn "Restore vector $intvector to sio driver" y
	[ "$result" = "Y" ] && {
	    echo "Restoring vector $intvector to sio driver"
	    siomajor=`./configure -j sio`
	    ./configure -m $siomajor -c -v $intvector -a -Y
	    return $OK
	}
    }
    [ "$intvector" = "7" ] && {
	prompt_yn "Restore vector $intvector to pa driver" y
	[ "$result" = "Y" ] && {
	    echo "Restoring vector $intvector to pa driver"
	    pamajor=`./configure -j pa`
	    ./configure -m $pamajor -c -v $intvector -a -Y
	    return $OK
	}
    }
    return $OK
}


#
# 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
}


# 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 : '.*\(.\)'`

makedevs $OK
check_args $drv $bd

#
# verify the driver is in the kernel link-kit
#

idcheck -p $base -i /tmp/dev$$
if [ $? -le 16 ]
then
    echo "Error: $base driver is not installed"
    cleanup $FAIL
fi

echo "Reconfiguring the $drv driver"
cd /usr/lib/lli/$drv
makedevs

#
# 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

# get the interrupt vector & Base I/O address for the board that we are removing

currdir=`pwd`
cd /etc/conf/sdevice.d
ivec=`awk '{ if ( $1 != "*" ) print $6 }' < $base`
OBIO=`awk '{ if ( $1 != "*" ) print $7 }' < $base`
cd $currdir

#
# 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

    idinstall -u -m -s -n -e -k $base
else
    echo "$base	I	iScH	$PREFIX	0	0	1	256	$DMACHAN" >./Master
    idinstall -u -m -s -e -k $base
fi

# 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

if [ "$ivec" = "3" -o "$ivec" = "4" -o "$ivec" = "7" ]
then
    [ ${ivec} != ${IRQ} ] && restorevector $ivec
fi

cleanup $RELINK
