Metropoli BBS
VIEWER: init MODE: TEXT (ASCII)
#
#               (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
#
# The name it is called with will cause different operation.
# w9400 w9401 w9402 w9403           == Winbond W89C940 boards 0 - 3
#
LIB=/usr/lib/lli
CONF=/etc/conf
PATH=/bin:/usr/bin:/etc/:$CONF/bin:$LIB:/usr/lib/lli
#
# Set possible return codes for this script
#
OK=0;   FAIL=1; RELINK=2;

#
# Prompt the user for a hex value, it must be within a given range
# Usage:
#       prompt_range "Message" default min max [step]
#
prompt_range() {
        mesg=$1
        default=$2
        range_min=$3 range_max=$4
        step="1"
        if [ $# -eq 5 ]
        then
                step=$5
        fi

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

                hc $result $range_min $range_max $step
                case $? in
                0) return $OK;;
                1) cleanup $FAIL 1;;
                esac
        done
}

#
# 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
                echo "${mesg} (${values}) [${default}] or 'q' to quit: \c"
                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
#
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
    if [ $2 -eq 1 ]
    then

        currdir=`pwd`

            cd /etc/conf/cf.d

            sparam=0
            sparam=`./configure -y NBLK2048`
            echo -n Value of NBLK2048 changed from $sparam t
            sparam=`expr $sparam + 10`
            echo o $sparam
        idtune -f NBLK2048 $sparam

            cd $currdir
    fi

        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 1
                }
                # 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 1
                        }
                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 1
                }
                case $result in
                1)      rmvector $clash $vector || {
                                echo "Failed to remove vector $vector"
                                cleanup $FAIL 1
                        }
                        makedevs
                        return $OK
                        ;;
                2)      return $FAIL
                        ;;
                esac
        done
        return $OK
}

doaddrclash() {
        driver=$1
        addr1=$2
        addr2=$3

        cd $confdir
        clash=`../bin/idcheck -ar -l $addr1 -u $addr2 -i /tmp/dev$$`
        cd $currdir

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

checkaddr() {
        driver=$1
        addr1=$2
        addr2=$3
        clash=

        currdir=`pwd`
        confdir=/etc/conf/cf.d

        while doaddrclash $driver $addr1 $addr2
        do
                prompt_yn "
Addresses $addr1-$addr2 are already in use by the $clash device.
You must choose a unique address for this device to work.
Do you wish to choose another address now?" y || cleanup $FAIL 1
                if [ "$result" = "Y" ]
                then
                        return $FAIL
                else
                        cleanup $FAIL 1
                fi
        done
        return $OK
}


#
# check_args ()
#
# Check the name and board number.
# The name have to be dce and the board number between 0..3
#
# This function defines the variables :
#  bd
#  name
#  PREFIX
#  MAX_BD
#
# which are used as global variables in main()

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

        case $name in
        w940s3) echo "Configuring Winbond W89C940 board $bd";
                PREFIX="w940";
                MAX_BD=3;
                ;;
        *) echo "ERROR: Unknown LLI driver being configured ($name$bd)";
                cleanup $FAIL 1;
                ;;
        esac

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

#
# system_w940s3()
#
system_w940s3() {
        bd=$1

        BIO=0
        EIO=0

        IRQ=0

        currdir=`pwd`

        cd /etc/conf/cf.d

        sparam=0
        sparam=`./configure -y NBLK2048`
        echo -n Value of NBLK2048 changed from $sparam t
        sparam=`expr $sparam + 10`
        echo o $sparam
        idtune -f NBLK2048 $sparam

        cd $currdir

        NMINORS="1"
}

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 $netconfigdir/reconf
                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

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 && {
        cleanup $OK 0
}
# this board already installed
grep $base: $chains > /dev/null 2>& 1 && {
        echo $base already configured.
        echo $chain >> $chains
        cleanup $OK 0
}
#
# 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 1
        }
}

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

#
# create the temporary directory for installing the driver
#
cd /tmp; rm -rf $base
mkdir $base; cd $base

DMACHAN="-1"
MIN_UNITS=1
MAX_UNITS=256
# IPL=5
# TYPE=1

#
# set rel, type variables.
#
# os_type

#
# Do special board dependent processing
#
case $drv in
        w940s3)    system_w940s3 $bd;;
esac
echo
if [ "$IRQ" = "2" ]
then
        IRQ=9
fi

# echo "$base\tY\t$NMINORS\t$IPL\t$TYPE\t$IRQ\t$BIO\t$EIO\t0\t0" >./System
echo "$base\tY\t$NMINORS\t0\t0\t$IRQ\t$BIO\t$EIO\t0\t0" >./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  -1" >./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
        idinstall -u -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

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

cleanup $RELINK 0


[ RETURN TO DIRECTORY ]