:
#		(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.
# e3A0 e3A1 e3A2 e3A3		== 3Com501 boards 0 - 3
# e3B0 .....     e3B3		== 3Com503 boards 0 - 3
# e3C0 .....     e3C3		== 3Com523 boards 0 - 3
# wdn0 .....     wdn3		== Western Digital boards 0 - 3
# exos0 ....     exos3		== Excelan 205T boards 0 - 3
# tok0 tok1			== Token Ring Adapter 0, 1
# btok0 btok1 btok2 btok3	== Busmaster Token Ring Adapter 0 - 3
# ctr0 ctr1 ctr2 ctr3	== Compaq 32-Bit DualSpeed Token Ring Controllers 0 - 3
# hpi0 hpi1 hpi2 hpi3		== HP ThinLAN/EtherTwist ISA LAN Adapters 0 - 3
# hpe0 hpe1 hpe2 hpe3           == HP EtherTwist EISA Slave LAN Adapters 0 - 3
# i3B0 ....      i3B3		== Interlan ES3210 boards 0 - 3
# i6E0				== Interlan NI6510 board 0
# ne0 ne1 ne2 ne3	== Novell NE3200 Bus Master Ethernet Adapters 0 - 3
#
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 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;;
		2) cleanup $FAIL;;
		esac
	done
}

#
# Prompt the user for a hex value, it must be within one of two given ranges
# Usage:
# 	prompt_dual_range "Message" default min1 max1 step1 min2 max2 step2
#
prompt_dual_range() {
	mesg=$1
	default=$2
	range1_min=$3 range1_max=$4 step1=$5
	range2_min=$6 range2_max=$7 step2=$8

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

		dual_ret=0
		hc -q $result $range1_min $range1_max $step1 || {
			dual_ret=$?
			hc $result $range2_min $range2_max $step2
		}
		case $? in
		0) return $OK;;
		1) cleanup $FAIL;;
		2) [ "$dual_ret" = "2" ] && echo "$result is not in the range $range1_min to $range1_max"
		   cleanup $FAIL
		   ;;
		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
		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
#
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
}

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

	currdir=`pwd`

	while dointclash $driver $vector
	do
		clashdrv=`echo "$clash" | sed -e 's/[0-9]*$//`
			[ "$clashdrv" != "$drv" ] && {
			[ $NO_PROMPT ] && {
				echo "ERROR: eisavec irq conflict with $clash"
				cleanup $FAIL
	    		}
			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. Stop the installation and use EISA config to select a different interrupt\n\t   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
		} || {
			return $OK
		}
	done
	return $OK
}

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

	currdir=`pwd`

	while dointclash $driver $vector
	do
		[ $NO_PROMPT ] && {
			echo "ERROR: interrupt vector conflict with $clash"
			cleanup $FAIL
		}
		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
}

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
}

# Removes the $clash device.
rmaddr() {
	clash=$1

	cd $confdir
	echo "\nRemoving the $clash device ..."

	major=`./configure -j $clash` && { 
		# remove device but leave it required
		if [ "$major" != "0" ] 
		then
			./configure -d -c -m $major -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 -R -Y >> conflog 2>&1 || { 
				cd $currdir
				cleanup $FAIL
			}
		fi
    	}
	cd $currdir
	return $OK
}

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

	currdir=`pwd`

	while doaddrclash $driver $addr1 $addr2
	do
		[ $NO_PROMPT ] && {
			echo "ERROR: I/O address conflict with $clash"
			cleanup $FAIL
		}
		if [ "$clash" = "ad" ]
		then
			echo "\n\nWARNING: Do not remove the $clash device \c"
			echo "if you are using an Adaptec disk controller"
		fi
		prompt_select "Addresses $addr1-$addr2 are already in use by the $clash device.\n\n\
The alternatives available to you are:\n\n\
\t1. Continue the installation and remove the $clash device.\n\
\t2. Select a different address.\n\n\
Select an option" 1 "1 2" || { 
			cleanup $FAIL
		}
		case $result in
		1)	rmaddr $clash || { 
				echo "Failed to remove $clash device"
				cleanup $FAIL
			}
			makedevs
			return $OK
			;;
		2)	return $FAIL
			;;
		esac
	done
	return $OK
}

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

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

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

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

	currdir=`pwd`

	while doramclash $driver $addr1 $addr2
	do
		[ $NO_PROMPT ] && {
			echo "ERROR: ram address conflict with $clash"
			cleanup $FAIL
		}
		prompt_yn "
Ram addresses $addr1-$addr2 is already in use for 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
		if [ "$result" = "Y" ]
		then
			return $FAIL
		else	
			cleanup $FAIL
		fi
	done
	return $OK
}

# On unix, we must check the lines in mdevice file.
# Sets the variable $clash to the driver code name if there is a driver that
# has already been allocated the given channel. Uses awk.
dodmaclash() {
	driver=$1
	chan=$2
 	clash=

	# -1 is never a clash
	[ "$chan" = "-1" ] && return $FAIL

	cd $confdir
	clash=`awk '{ if ( $9 == dma ) print $1 }' dma=$chan mdevice`

	[ "$clash" = "" ] && {
		cd $currdir
		return $FAIL
	}

	cat ../sdevice.d/$clash | awk '{ if ( $2 == "Y" ) exit 1 }' || return $OK
	
	if [ "$rel" = "3.2.0" -o "$rel" = "3.2.1" -o "$rel" = "3.2.2" ]
	then
		[ $NO_PROMPT ] && {
			echo "ERROR: dma channel used by $clash not configured"
			cleanup $FAIL
		}
		prompt_yn "
DMA channel ${chan} is already in use by the $clash device.  However, the
$clash device is not currently configured into the kernel.  Do you wish to
remove DMA channel ${chan} from the $clash device?" y || cleanup $FAIL
		if [ "$result" = "Y" ]
		then
			sed -e "/^$clash	.*[0-9]$/{" \
				-e 's/[0-9]$/-1/p' \
				-e '}' mdevice > /tmp/bog$$
			mv /tmp/bog$$ mdevice 
			cd $currdir
			return $FAIL
		else	
			cd $currdir
			return $OK
		fi
	fi

	# Should be release >3.2.2, clash driver not installed if we get here.
	cd $currdir
	return $FAIL
}

#
# Check if there is a clash of DMA channels
#
checkdma() {
	driver=$1
	channel=$2
	clash=

	currdir=`pwd`

	while dodmaclash $driver $channel
	do
		[ $NO_PROMPT ] && {
			echo "ERROR: dma channel in use by $clash"
			cleanup $FAIL
		}
		prompt_yn "
DMA channel ${channel} is already in use by the $clash device.
You must choose a unique channel for this device to work. 
Do you wish to choose another channel now?" y || cleanup $FAIL
		if [ "$result" = "Y" ]
		then
			return $FAIL
		else	
			cleanup $FAIL
		fi
	done
	return $OK
}

check_args() {

	case $drv in
	ctr) echo "Configuring COMPAQ 32-bit DualSpeed Token Ring Controller $bd";
		PREFIX="ctr";
		MAX_BD=3;
		;;
	e3A) echo "Configuring 3Com501 board $bd";
		PREFIX="e3c";
		MAX_BD=3;
		;;
	e3B) echo "Configuring 3Com503 board $bd";
		PREFIX="e503";
		MAX_BD=3;
		;;
	e3C) echo "Configuring 3Com523 board $bd";
		PREFIX="emc";
		MAX_BD=3;
		;;
	e3D) echo "Configuring 3Com507 board $bd";
		PREFIX="e3d";
		MAX_BD=3;
		;;
	e3m) echo "Configuring 3Com527 board $bd";
		PREFIX="e3m";
		MAX_BD=3;
		;;
	wdn) echo "Configuring Western Digital 8003/8013 board $bd";
		PREFIX="wdn";
		MAX_BD=3;
		;;
	btok) echo "Configuring IBM Busmaster Token Ring Adapter $bd";
		PREFIX="btok";
		MAX_BD=3;
		;;
	tok) echo "Configuring IBM Token Ring Adapter $bd";
		PREFIX="tok";
		MAX_BD=1;
		;;
	exos) echo "Configuring Excelan 205 Ethernet Adapter $bd";
		PREFIX="exos";
		MAX_BD=3;
		;;
	hpi) echo "Configuring HP ISA LAN adapter $bd";
		PREFIX="hpi";
		MAX_BD=3;
		;;
	hpe) echo "Configuring HP EISA Slave LAN adapter $bd";
		PREFIX="hpe";
		MAX_BD=3;
		;;
	i3B) echo "Configuring Racal InterLan ES 3210 board $bd";
		PREFIX="i3B";
		MAX_BD=3;
		;;
	i6E) echo "Configuring Racal InterLan NL 6510 board $bd";
		PREFIX="i6E";
		MAX_BD=0;
		;;
	nat) echo "Configuring Novell NE2000 board $bd";
		PREFIX="nat";
		MAX_BD=3;
		;;
	ne) echo "Configuring Novell NE3200 Bus Master Ethernet board $bd";
		PREFIX="ne";
		MAX_BD=3;
		;;
	*) echo "ERROR: Unknown LLI driver being configured ($drv$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
	if [ "$bd" -gt "0" -o "$drv" = "e3m" -o "$drv" = "ne" ]
	then
		PREFIX="$PREFIX$bd"
	fi
	echo
}

#
# The "eisa_nvm" process returns an abbreviated board configuration
#	string for each board found in EISA non-volatile memory.
# For a synopsis of the "eisa_nvm" function, type "eisa_nvm<Enter>".
#
eisa_cfg_get() {
	eisa_cfg=`eisa_nvm "$board_string" $board_id 0xfeffffff NET 2>/dev/null`
}

unit_cfg_get() {
	ucg_status=$FAIL	# Return code unless we succeed.

	[ "$eisa_cfg" ] && {
		# 1 or more units are configured in EISA non-volatile ram.
		set $eisa_cfg   # Assign board configuration data to $1 thru $n

		# This provides for configuring a single unit.
		[ `expr $# \/ $eisa_args` -gt $bd ] && {
			[ $bd -eq 0 ] || shift `expr $bd \* $eisa_args`
			unit_cfg="$1 $2 $3 $4 $5 $6 $7 $8"
			ucg_status=$OK
		} || :
	}
	return $ucg_status
}

#
# slot_irq_get - Sets the shell variables "eisa_cfg", "unit_cfg", "slot" and
#		 "irq" using "eisa_cfg_get" and "unit_cfg_get".
# inputs -	 The "bd" variable is assumed to have been set elsewhere.
# outputs -	 return code for success or failure.
 
slot_irq_get() {
	sig_status=$FAIL	# Return code unless we succeed.

	# Attempts to get the EISA configuration data for this unit.
	eisa_cfg_get && {
		unit_cfg_get && {
			# EISA configuration data is in $unit_cfg, as follows:
			# 1st = slot, 2nd - 3rd not used, 4th = irq,
			# 5th - 8th not used

			# Extracts only the slot number and irq.
			slot=`expr "$unit_cfg" : "\([0-$max_slot]\{1,\}\) .*"`
			[ "$slot" ] && {
				irq=`expr "$unit_cfg" : "[0-$max_slot]\{1,\} [^ ]\{7\}* -1 \([0-9]\{1,\}\) .*"`
				[ "$irq" ] && sig_status=$OK
			} || :
		} || :
	} || :
	return $sig_status
}

get_eisa_config() {

	slot_irq_get || {
		case ${bd} in
		0) IRQ=9;;
		1) IRQ=15;;
		2) IRQ=10;;
		3) IRQ=11;;
		esac

		while :
		do
		    if [ $NO_PROMPT ]
		    then
	    		[ $NO_PROMPT_IRQ ] || {
				echo "ERROR: irq not set"
				cleanup $FAIL
	    		}
			result=$NO_PROMPT_IRQ
		    else
			prompt_select "Enter IRQ" $IRQ "5 9 10 11 15" || cleanup $FAIL
		    fi
		    irq=$result
		    checkeisavec $drv$bd $irq && break
                    [ $NO_PROMPT ] && {
			echo "ERROR: bad irq"
                        cleanup $FAIL
		    }
		done

		while :
		do
		    if [ $NO_PROMPT ]
		    then
	    		[ $NO_PROMPT_SLOT ] || {
				echo "ERROR: slot not set"
				cleanup $FAIL
	    		}
			result=$NO_PROMPT_SLOT
		    else
			prompt_select "Enter slot number" "" "0 1 2 3 4 5 6 7 8 9" || cleanup $FAIL
		    fi
		    slot=$result
		    BIO=`expr $slot * 1000`
		    EIO=`ha $BIO fff`
		    checkaddr $drv$bd $BIO $EIO && break
                    [ $NO_PROMPT ] && {
			echo "ERROR: bad slot"
                        cleanup $FAIL
		    }
		done
	} && {
		checkeisavec $drv$bd $irq || {
			echo "\n\tPlease use EISA config to reconfigure $drv$bd"
			cleanup $FAIL
		}
	}
}

#
# function to produce the System and other file info for the NE3200 board
# slot_irq_get attempts to get the EISA configuration data for this unit
#
system_ne() {
	eisa_cfg=
	unit_cfg=
	slot=
	board_string="board_id"
	board_id="nvl0701"
	eisa_args=8
	max_slot=8

	get_eisa_config

	echo "Configuring $drv$bd in slot $slot, interrupt $irq"

	NMINORS=1
	IRQ=$irq
	TYPE=3
	MIN_UNITS=0
	MAX_UNITS=1
	BIO=`expr $slot * 1000`
	EIO=`ha $BIO c9f`
	BRAM=0
	ERAM=0

	cd /tmp/$base
	[ $bd -eq 0 ] && {
		cp $LIB/Driver.o .
		echo "${drv}_d	I	icS	${drv}_d	0	0	0	1	-1" >./Master
		echo "${drv}_d	Y	0	0	0	0	0	0	0	0" >./System
		echo "clone	${drv}_d	c	${drv}_d" >./Node
		idinstall -a -e -k ${drv}_d
		rm -f Master System Node
		copy -m /usr/lib/lli/$drv/Driver.o Driver.o
		copy -m /usr/lib/lli/$drv/Space.c Space.c
		SB=./S
	} || {
		SB=/etc/conf/pack.d/${drv}0/s
	}

	echo "clone	$drv$bd		c	$drv$bd" >./Node

	sed "s/NE3200_SLOT$bd .*$/NE3200_SLOT$bd ${slot}/" ${SB}pace.c > temp
	mv temp ${SB}pace.c
	sed "s/NE3200_IRQ$bd  .*$/NE3200_IRQ$bd  ${IRQ}/" ${SB}pace.c > temp
	mv temp ${SB}pace.c

	cp /usr/lib/lli/ne/S39neth_dl /etc/rc2.d/S39neth_dl 2>/dev/null
	chown root /etc/rc2.d/S39neth_dl
	chgrp root /etc/rc2.d/S39neth_dl
	chmod 744 /etc/rc2.d/S39neth_dl
}

#
# function to produce the System and other file info for the Compaq token ring
# board.
# slot_irq_get attempts to get the EISA configuration data for this unit
#
system_ctr() {
	eisa_cfg=
	unit_cfg=
	slot=
	board_string="board_id type"
	board_id="cpq6000"
	eisa_args=8
	max_slot=8

	get_eisa_config

	NMINORS=$slot
	IRQ=$irq
	TYPE=1
	MIN_UNITS=0
	MAX_UNITS=`expr $max_slot + 1`		# max number of slots (0..8)
	BIO=`expr $slot * 1000`
	EIO=`ha $BIO fff`
	BRAM=0
	ERAM=0

	currdir=`pwd`
	cd /tmp/$base

	[ $bd -eq 0 ] && {
		copy -m /usr/lib/lli/$drv/Driver.o Driver.o
		echo "$base	Ih	iScH	$PREFIX	0	0	$MIN_UNITS	$MAX_UNITS	$DMACHAN" >./Master
	}

	echo "clone	$drv$bd		c	$drv$bd" >./Node

	echo "#include	<sys/types.h>\n#include	<sys/stream.h>\n" >./Space.c
	echo "extern struct qinit ${drv}nrinit, ${drv}winit;\n" >>./Space.c
	echo "struct streamtab ${drv}0info =\n   {\n   &${drv}nrinit, &${drv}winit, (struct qinit *)0, (struct qinit *)0\n   };\n" >>./Space.c
	echo "extern void ${drv}intr();\n" >>./Space.c

	#
	# Gets the slots, irqs and groups actually configured. The driver "init"
	# routine will use these to recognize configuration differences with
	# respect to EISA non-volatile memory.
	#
	slot_units=		# List of slot numbers actually configured.
	intrs=			# List of irq group dummy interrupt handlers.
	ext_units=		# List of external unit numbers for start_stop.
	ivecs=			# interrupt vectors used

	cd /etc/conf/pack.d
	for unit_device in ${drv}[0-$MAX_BD]
	do
		unit_inst=`cat ../sdevice.d/${unit_device} | awk '{ print $2 }'`
		[ "$unit_inst" = "Y" -o "$unit_device" = ${drv}${bd} ] && { 

			echo "void ${unit_device}intr() {}" >>/tmp/${base}/Space.c
			echo "void (*${unit_device}_intr)() = ${unit_device}intr;\n" >>/tmp/${base}/Space.c
			[ "$unit_device" = "$drv$bd" ] && {
				unit_slot=$slot
			} || {
				unit_slot=`sed -n "s/$unit_device	Y	\([1-$max_slot]\)	.*/\1/p" ../sdevice.d/$unit_device`
			}
			ext_unit=`expr "$unit_device" : "$drv\([0-$MAX_BD]\{1\}\)"`
				[ "$slot_units" ] && slot_units="${slot_units}, {$unit_slot, $ext_unit}" || slot_units="{$unit_slot, $ext_unit}"
			echo "Configuring $drv$ext_unit in slot $unit_slot"
			ext_units="$ext_units $ext_unit"
			[ "$intrs" ] && intrs="$intrs, &${unit_device}_intr" || intrs="&${unit_device}_intr"

		}
		[ "$unit_inst" = "Y" ] && { 
			i=`echo ${unit_device} | sed -e "s/$drv//"`
			[ "$i" -lt $bd ] && ivecs="$ivecs "`cat ../sdevice.d/${unit_device} | awk '{ print $6 }'`
		}
	done
	[ -x ${drv}${bd} ] || {
		unit_device=${drv}${bd}
		echo "void ${unit_device}intr() {}" >>/tmp/${base}/Space.c
		echo "void (*${unit_device}_intr)() = ${unit_device}intr;\n" >>/tmp/${base}/Space.c
		unit_slot=$slot
		ext_unit=`expr "$unit_device" : "$drv\([0-$MAX_BD]\{1\}\)"`
			[ "$slot_units" ] && slot_units="${slot_units}, {$unit_slot, $ext_unit}" || slot_units="{$unit_slot, $ext_unit}"
		echo "Configuring $drv$ext_unit in slot $unit_slot"
		ext_units="$ext_units $ext_unit"
		[ "$intrs" ] && intrs="$intrs, &${unit_device}_intr" || intrs="&${unit_device}_intr"

	}


	cd /tmp/${base}
	echo "void (**${drv}_ints[])() = {$intrs};\n" >>./Space.c
	echo "struct {
	unsigned short slot;
	unsigned short unit;
} ${drv}_slots[] = { $slot_units };

unsigned short ${drv}_units = sizeof(${drv}_slots) / sizeof(${drv}_slots[0]);
	" >>./Space.c

	[ $bd -gt 0 ] && {
		cp $LIB/Driver.o .
		cp Space.c /etc/conf/pack.d/${drv}0/space.c
		echo "#include	<sys/types.h>\n#include	<sys/stream.h>\n" >./Space.c
		echo "extern struct qinit ${drv}nrinit, ${drv}winit;\n" >>./Space.c
		echo "struct streamtab $drv${bd}info =\n   {\n   &${drv}nrinit, &${drv}winit, (struct qinit *)0, (struct qinit *)0\n   };\n" >>./Space.c

		for i in $ivecs
		do
			[ $i = $IRQ ] && TYPE=0
		done

		# fixup any left over devices configured as type 1
		cd /etc/conf/sdevice.d
		for i in ${drv}[$bd-$MAX_BD]
		do
			[ -f $i ] && {
				clash=`cat $i | awk '{ if ( $6 == intr && $5 == "1" && $2 == "Y" ) exit } \
						END { print $1 }' intr=$IRQ`
				[ $clash ] && {
					cat $i | awk '{ printf "%s\t%s\t%s\t%s\t0\t%s\t%s\t%s\t%s\t%s\n", $1, $2, $3, $4, $6, $7, $8, $9, $10 }' > /tmp/bog$$
					mv /tmp/bog$$ $i
					break
				}
			}
		done
		cd /tmp/${base}
	}

	cp /usr/lib/lli/ctr/S39ctr /tmp/bog 2>/dev/null
	sed -e "s/mac380.bin 0.*/mac380.bin ${ext_units}/" < /tmp/bog > /tmp/bog$$
	sed -e "s/stop 0.*/stop ${ext_units}/" < /tmp/bog$$ > /etc/ctr
	chown root /etc/ctr
	chgrp root /etc/ctr
	chmod 744 /etc/ctr
	rm -f /tmp/bog /tmp/bog$$
	cp /etc/ctr /etc/rc2.d/S39ctr 2>/dev/null
	chown root /etc/rc2.d/S39ctr
	chgrp root /etc/rc2.d/S39ctr
	chmod 744 /etc/rc2.d/S39ctr

	cd $currdir
}

#
# function to produce the info for the System file for the 3C501 board
#
system_e3A() {

	case $bd in
	0) IRQ=3; BIO=300;;
	1) IRQ=2; BIO=310;;
	2) IRQ=5; BIO=330;;
	3) IRQ=7; BIO=350;;
	esac

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_IRQ ] || {
			echo "ERROR: irq not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_IRQ
	    else
		prompt_select "Enter IRQ" $IRQ "2 3 4 5 6 7" || cleanup $FAIL
	    fi
	    irq=$result
	    checkvec $drv$bd $irq && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad irq"
                cleanup $FAIL
	    }
	done
	IRQ=$irq

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BIO ] || {
			echo "ERROR: bio not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BIO
	    else
		prompt_range "Enter I/O base address" $BIO "100" "3f0" "10" || cleanup $FAIL
	    fi
	    bio=$result
	    EIO=`ha $bio 0f`
	    checkaddr $drv$bd $bio $EIO && break
            [ $NO_PROMPT ] && {
	        echo "ERROR: bad bio"
                cleanup $FAIL
	    }
	done
	BIO=$bio

	NMINORS="1"
}

#
# function to produce the info for the System file for the 3C503 board
#
system_e3B() {

	case $bd in
	0) IRQ=3; BIO=300;;
	1) IRQ=2; BIO=310;;
	2) IRQ=5; BIO=330;;
	3) IRQ=4; BIO=350;;
	esac

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_IRQ ] || {
			echo "ERROR: irq not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_IRQ
	    else
		prompt_select "Enter IRQ" $IRQ "2 3 4 5" || cleanup $FAIL
	    fi
	    irq=$result
	    checkvec $drv$bd $irq && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad irq"
                cleanup $FAIL
	    }
	done
	IRQ=$irq

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BIO ] || {
			echo "ERROR: BIO not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BIO
	    else
		prompt_select "Enter I/O base address" $BIO "250 280 2A0 2E0 300 310 330 350" || cleanup $FAIL
	    fi
	    bio=$result
	    EIO=`ha $bio 0f`
	    checkaddr $drv$bd $bio $EIO && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad bio"
                cleanup $FAIL
	    }
	done
	BIO=$bio

	NMINORS="1"

	# set the thick/thin thing
	if [ $NO_PROMPT ]
	then
	    [ $NO_PROMPT_AUI ] || {
		echo "ERROR: aui not set"
		cleanup $FAIL
	    }
	    result=$NO_PROMPT_AUI
	else
	    prompt_yn "Does this 503 board use thick (AUI) ethernet?" "n" || cleanup $FAIL
	fi
	thick=0
	[ "$result" = "Y" ] && thick=1

	currdir=`pwd`
	cd /etc/conf/pack.d/e3B0
	sed -e "s/fine XCVR$bd.*/fine XCVR$bd	$thick/" < space.c > /tmp/bog$$
	mv /tmp/bog$$ space.c
	cd $currdir
}

#
# function to produce the information for the System file for the 3C523
#
system_e3C() {

	case $bd in
	0) IRQ=3; BIO=300; BRAM=c0000;;
	1) IRQ=7; BIO=1300; BRAM=c8000;;
	2) IRQ=9; BIO=2300; BRAM=d0000;;
	3) IRQ=12; BIO=3300; BRAM=d8000;;
	esac

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_IRQ ] || {
			echo "ERROR: irq not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_IRQ
	    else
		prompt_select "Enter IRQ" $IRQ "3 7 9 12" || cleanup $FAIL
	    fi
	    irq=$result
	    checkvec $drv$bd $irq && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad irq"
                cleanup $FAIL
	    }
	done
	IRQ=$irq

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BIO ] || {
			echo "ERROR: bio not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BIO
	    else
		prompt_range "Enter I/O base address" $BIO "300" "3300" "1000" || cleanup $FAIL
	    fi
	    bio=$result
	    EIO=`ha $bio 7`
	    checkaddr $drv$bd $bio $EIO && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad bio"
                cleanup $FAIL
	    }
	done
	BIO=$bio

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BRAM ] || {
			echo "ERROR: bram not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BRAM
	    else
		prompt_range "Enter RAM base address" $BRAM "c0000" "d8000" "8000" || cleanup $FAIL
	    fi
	    bram=$result
	    ERAM=`ha $bram 5fff`
	    checkram $drv$bd $bram $ERAM && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad bram"
		cleanup $FAIL
	    }
	done
	BRAM=$bram

	NMINORS="1"
}

system_e3m()
{

	case $bd in
	0) IRQ=9; BIO=7280; BRAM=d0000;;
	1) IRQ=10; BIO=7680; BRAM=d8000;;
	2) IRQ=11; BIO=7a80; BRAM=c0000;;
	3) IRQ=12; BIO=7e80; BRAM=c8000;;
	esac

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_IRQ ] || {
			echo "ERROR: irq not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_IRQ
	    else
		prompt_select "Enter IRQ" $IRQ "9 10 11 12" || cleanup $FAIL
	    fi
	    irq=$result
	    checkvec $drv$bd $irq && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad irq"
                cleanup $FAIL
	    }
	done
	IRQ=$irq

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BIO ] || {
			echo "ERROR: bio not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BIO
	    else
		prompt_select "Enter I/O base address" $BIO "7280 7290 7680 7690 7a80 7a90 7e80 7e90" || cleanup $FAIL
	    fi
	    bio=$result
	    EIO=`ha $bio f`
	    checkaddr $drv$bd $bio $EIO && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad bio"
                cleanup $FAIL
	    }
	done
	BIO=$bio

	if [ $NO_PROMPT ]
	then
	    [ $NO_PROMPT_RAMS ] || {
		echo "ERROR: rams not set"
		cleanup $FAIL
	    }
	    result=$NO_PROMPT_RAMS
	else
	    prompt_select "Enter RAM Size in k" 16 "16 32 64" || cleanup $FAIL
        fi
	case $result in
		16) size=3fff ;;
		32) size=7fff ;;
		64) size=ffff ;;
		*)  [ $NO_PROMPT ] && {
		        echo "ERROR: bad ram size"
			cleanup $FAIL
		    }
	esac

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BRAM ] || {
			echo "ERROR: bram not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BRAM
	    else
		prompt_range "Enter RAM base address" $BRAM "c0000" "dc000" "4000" || cleanup $FAIL
	    fi
	    bram=$result
	    ERAM=`ha $bram $size`
	    checkram $drv$bd $bram $ERAM && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad bram"
                cleanup $FAIL
	    }
	done
	BRAM=$bram

	NMINORS="1"
}

#
# function to produce the information for the System file for the 3C507
# board
#
system_e3D() {

	case $bd in
	0) IRQ=3; BIO=300; BRAM=d0000;;
	1) IRQ=9; BIO=310; BRAM=c0000;;
	2) IRQ=5; BIO=320; BRAM=c8000;;
	3) IRQ=7; BIO=330; BRAM=d8000;;
	esac

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_IRQ ] || {
			echo "ERROR: irq not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_IRQ
	    else
		prompt_select "Enter IRQ" $IRQ "3 5 7 9 10 11 12 15" || cleanup $FAIL
	    fi
	    irq=$result
	    checkvec $drv$bd $irq && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad irq"
                cleanup $FAIL
	    }
	done
	IRQ=$irq

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BIO ] || {
			echo "ERROR: bio not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BIO
	    else
		prompt_select "Enter I/O base address" $BIO "200 210 220 230 240 250 260 280 290 2a0 2b0 2c0 2d0 2e0 300 310 320 330 340 350 360 380 390 3a0 3e0" || cleanup $FAIL
	    fi
	    bio=$result
	    EIO=`ha $bio f`
	    checkaddr $drv$bd $bio $EIO && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad bio"
                cleanup $FAIL
	    }
	done
	BIO=$bio

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BRAM ] || {
			echo "ERROR: bram not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BRAM
	    else
		prompt_select "Enter RAM base address" $BRAM "c0000 c8000 d0000 d8000 f00000 f20000 f40000 f60000 f80000" || cleanup $FAIL
	    fi
	    bram=$result

	    case $bram in
	    c[08]000|d0000)	sizelist="16 32 48 64"
				defsize=64;;
	    d8000)		sizelist="16 32"
				defsize=32;;
	    *)			sizelist="64"
				defsize=64;;
	    esac
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BRAM ] || {
			echo "ERROR: bram not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_RAMS
	    else
		prompt_select "Enter RAM Size in k" $defsize "$sizelist" || cleanup $FAIL
	    fi
	    case $result in
	    16) size=3fff ;;
	    32) size=7fff ;;
	    48) size=bfff ;;
	    64) size=ffff ;;
	    esac
	    ERAM=`ha $bram $size`
	    checkram $drv$bd $bram $ERAM && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad bram or ram size"
                cleanup $FAIL
	    }
	done
	BRAM=$bram

	NMINORS="16"
}

#
# function to produce the information for the space.c file for the token ring
#
space_token() {

	# Set whether Netbeui is above us or not
	nbe=0
	[ "$name_above" = "nbe" ] && nbe=1

	currdir=`pwd`
	cd /etc/conf/pack.d/tok0

	sed -e "s/fine TOK${bd}_ISO.*/fine TOK${bd}_ISO	$nbe/" < space.c > /tmp/bog$$
	cp /tmp/bog$$ space.c
	rm -r /tmp/bog$$

	# hrf (10/94), Set BSHRAM to validate shared ram address on tok driver
	sed -e "s/fine TOK_${bd}_BSHRAM.*/fine TOK_${bd}_BSHRAM	0x0$BSHRAM/" < space.c > /tmp/bog$$
	cp /tmp/bog$$ space.c
	rm -r /tmp/bog$$

	# hrf (10/94), Set SSHRAM to validate shared ram size on tok driver
	sed -e "s/fine TOK_${bd}_SSHRAM.*/fine TOK_${bd}_SSHRAM	0x0$SSHRAM/" < space.c > /tmp/bog$$
	cp /tmp/bog$$ space.c
	rm -r /tmp/bog$$

	cd $currdir
}

#
# 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 && {
		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 > /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
}

#
# function to produce the information for the System file for the token ring
#
# BRAM/ERAM indicate ROM address switch settings; BSHRAM/ESHRAM indicate
# shared memory settings.  We no more (hrf 10/94) assume they're using 16K of
# SHRAM on the adapter.
#
system_tok() {

	case $bd in
	0) IRQ=2; BIO=a20; BRAM=cc000; BSHRAM=d8000;;
	1) IRQ=3; BIO=a24; BRAM=dc000; BSHRAM=d4000;;
	esac

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_IRQ ] || {
			echo "ERROR: irq not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_IRQ
	    else
		if [ "$type" = "386GT" ]
		then
			# hrf (10/94), PnP accept irq's 10 and 11
			prompt_select "Enter IRQ" $IRQ "2 3 6 7 10 11" || cleanup $FAIL
		else
			prompt_select "Enter IRQ" $IRQ "2 3 10 11" || cleanup $FAIL
		fi
	    fi
	    irq=$result
	    checkvec $drv$bd $irq && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad irq"
                cleanup $FAIL
	    }
	done
	IRQ=$irq

	EIO=`ha $BIO 3`

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BROM ] || {
			echo "ERROR: brom not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BROM
	    else
		prompt_range "Enter ROM base address" $BRAM "c0000" "de000" "2000" || cleanup $FAIL
	    fi
	    brom=$result
	    ERAM=`ha $brom 1fff`
	    checkram $drv$bd $brom $ERAM && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad brom"
                cleanup $FAIL
	    }
	done
	BRAM=$brom

	# hrf (10/94), all tok adapters have a configurable shared RAM address
        #              and shared ram size.
	## Microchannel tok adapters have a configurable shared RAM address.
	#if [ "$type" = "386GT" ]
	#then
	#	ESHRAM=`ha $BSHRAM 3fff`
	#	doramclash $drv$bd $BSHRAM $ESHRAM && {
	#		echo "The RAM addresses required for $drv$bd are in use by the $clash device"
	#		echo "You must remove $clash before installing $drv$bd"
	#		cleanup $FAIL
	#	}
	#else
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BSHRAM ] || {
			echo "ERROR: bshram not set"
			cleanup $FAIL
	    	}
		BSHRAM=$NO_PROMPT_BSHRAM
                sshram=16
	    else
		prompt_range "Enter RAM base address" $BSHRAM "c0000" "dc000" "4000" || cleanup $FAIL
	        BSHRAM=$result
		prompt_select "Enter RAM size (KBytes)" 16 "8 16 32 64" || cleanup $FAIL
	        sshram=$result
	    fi
	    case $sshram in
	         8) SSHRAM=1fff;;
	        16) SSHRAM=3fff;;
	        32) SSHRAM=7fff;;
	        64) SSHRAM=ffff;;
	    esac
	    ESHRAM=`ha $BSHRAM ${SSHRAM}`
	    SSHRAM=`ha ${SSHRAM} 1`
	    doramclash $drv$bd $BSHRAM $ESHRAM && {
		echo "The RAM addresses required for $drv$bd are in use by the $clash device"
		echo "You must remove $clash before installing $drv$bd"
		cleanup $FAIL
	    }
	#fi

        if [ $NO_PROMPT ]
        then
	    [ $NO_PROMPT_LRBR ] || {
		echo "ERROR: lrbr not set"
		cleanup $FAIL
	    }
	    result=$NO_PROMPT_LRBR
	else
	    prompt_yn "Restrict broadcasts to the local ring" "y" || cleanup $FAIL
	fi
	if [ "$result" = "Y" ]
	then
		touch /usr/lib/lli/tok/noroute$bd
	else
		rm -f /usr/lib/lli/tok/noroute$bd
	fi

	NMINORS="16"

	space_token
}

#
# function to produce the information for the System file for the busmaster
# token ring board.
#
system_btok() {

	case $bd in
	0) IRQ=2; BIO=86a0;;
	1) IRQ=3; BIO=96a0;;
	2) IRQ=4; BIO=a6a0;;
	3) IRQ=5; BIO=b6a0;;
	esac

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_IRQ ] || {
			echo "ERROR: irq not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_IRQ
	    else
		prompt_select "Enter IRQ" $IRQ "2 3 4 5 7 10 11 12" || cleanup $FAIL
	    fi
	    irq=$result
	    checkvec $drv$bd $irq && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad irq"
                cleanup $FAIL
	    }
	done
	IRQ=$irq

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BIO ] || {
			echo "ERROR: bio not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BIO
	    else
		prompt_range "Enter I/O base address" $BIO "86a0" "f6a0" "1000" || cleanup $FAIL
	    fi
	    bio=$result
	    EIO=`ha $bio f`
	    checkaddr $drv$bd $bio $EIO && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad bio"
                cleanup $FAIL
	    }
	done
	BIO=$bio

	BRAM=0		# No shared memory on this device.
	ERAM=0

	NMINORS="16"

        if [ $NO_PROMPT ]
        then
	    [ $NO_PROMPT_LRBR ] || {
		echo "ERROR: lrbr not set"
		cleanup $FAIL
	    }
            result=$NO_PROMPT_LRBR
        else
	    prompt_yn "Restrict broadcasts to the local ring" "y" || cleanup $FAIL
	fi
	if [ "$result" = "Y" ]
	then
		touch /usr/lib/lli/btok/noroute$bd
	else
		/bin/rm -f /usr/lib/lli/btok/noroute$bd
	fi

	# increase the number of boards recognized in the boot-time microcode
	# file.
	awk 'BEGIN { FS = "=" } /^NBOARDS/ {
		NEW=$2+1
		if (NEW > 4) NEW=4
		printf "%s=%s\n",$1,NEW
		next
	}
	{ print } ' < /usr/lib/lli/btok/S25btok > /tmp/Sbt$$
	mv /tmp/Sbt$$ /usr/lib/lli/btok/S25btok
	cp /usr/lib/lli/btok/S25btok /etc/rc2.d

	[ "$name_above" = "lt610" ] && {
		btok_warning
	}

	echo "clone	$drv$bd		c	$drv$bd" >./Node
	echo "$drv$bd	bdld$bd	c	0" >>./Node
}

#
# This is a workaround for a bug in the OSI configuration scripts.  Warn the
# user that they should run a script to fixup the osid.cfg file which is
# corrupted when configuring over the btok driver.
#
btok_warning() {
	echo "\nWARNING: There is a known problem in the lt610 package, where the"
	echo "file /etc/osid.cfg is corrupted when configuring over the btok driver."
	echo "\nBefore rebooting your system, be sure to run /etc/fixosid.cfg"

	echo -n "\nPress ENTER to continue"
	read x

}

#
# function to produce the information for the System file for the Excelan
#
system_exos() {

	case $bd in
	0) IRQ=2; BIO=310; BRAM=d0000;;
	1) IRQ=3; BIO=300; BRAM=d4000;;
	2) IRQ=5; BIO=320; BRAM=d8000;;
	3) IRQ=7; BIO=330; BRAM=dc000;;
	esac

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_IRQ ] || {
			echo "ERROR: irq not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_IRQ
	    else
		prompt_select "Enter IRQ" $IRQ "2 3 4 5 6 7" || cleanup $FAIL
	    fi
	    irq=$result
	    checkvec $drv$bd $irq && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad irq"
                cleanup $FAIL
	    }
	done
	IRQ=$irq

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BIO ] || {
			echo "ERROR: bio not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BIO
	    else
		prompt_range "Enter I/O base address" $BIO "300" "330" "10" || cleanup $FAIL
	    fi
	    bio=$result
	    EIO=`ha $bio 7`
	    checkaddr $drv$bd $bio $EIO && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad bio"
                cleanup $FAIL
	    }
	done
	BIO=$bio

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BRAM ] || {
			echo "ERROR: bram not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BRAM
	    else
		prompt_range "Enter RAM base address" $BRAM "a0000" "f0000" "4000" || cleanup $FAIL
	    fi
	    bram=$result
	    ERAM=`ha $bram 3fff`
	    checkram $drv$bd $bram $ERAM && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad bram"
                cleanup $FAIL
	    }
	done
	BRAM=$bram

	NMINORS="16"
}

#
# function to produce the information for the System file for the western
# digital board
#
system_wdn() {

	case $bd in
	0) IRQ=3; BIO=240; BRAM=d0000;;
	1) IRQ=2; BIO=380; BRAM=d2000;;
	2) IRQ=5; BIO=260; BRAM=d4000;;
	3) IRQ=7; BIO=340; BRAM=d6000;;
	esac

    if [ $NO_PROMPT ]
    then
	:
    else
	if [ "$type" = "386MC" ]
	then
		echo
		echo "To configure the system to use your SMC or Western"
		echo "Digital card, you will need to answer some questions"
		echo "about what configuration you want to use.  Depending"
		echo "upon which particular model of card you have, there"
		echo "are different possible correct answers to the questions"
		echo "you are asked.  In particular, default options which"
		echo "are valid for the \"Elite \" series of cards for"
		echo "Microchannel systems DO NOT WORK with NON-Elite cards."
		echo "If you answer the following question incorrectly, you"
		echo "will end up with a configuration which WILL NOT WORK"
		echo "with your card.  Please check to make sure which type"
		echo "of card you have.  The Elite series cards have packaging"
		echo "and documentation with names like \"EtherCard Plus Elite\","
		echo "while the other cards just say something like"
		echo "\"EtherCard Plus\".  In any case, you should make sure"
		echo "to check your hardware documentation to find out which"
		echo "configuration parameters are valid, and make sure to"
		echo "specify the same parameters here and in the Microchannel"
		echo "Setup program."
		prompt_yn "\nAre you installing an Elite series (WD8013EP/A, WD8013WP/A, or\nWD8013EW/A) SMC or Western Digital card?" "n" || cleanup $FAIL
		if [ "$result" = "Y" ]
		then
			elite="Y"
			case $bd in
			0) IRQ=3; BIO=800; BRAM=d0000;;
			1) IRQ=4; BIO=1800; BRAM=d2000;;
			2) IRQ=10; BIO=2800; BRAM=d4000;;
			3) IRQ=15; BIO=3800; BRAM=d6000;;
			esac
		fi
	fi
    fi

	while :
	do
	    if [ $NO_PROMPT ]
	    then
		[ $NO_PROMPT_IRQ ] || {
		    echo "ERROR: irq not set"
		    cleanup $FAIL
		}
		result=$NO_PROMPT_IRQ
	    else
		prompt_select "Enter IRQ" $IRQ "2 3 4 5 7 10 11 14 15" || cleanup $FAIL
	    fi
	    irq=$result
	    checkvec $drv$bd $irq && break
	    [ $NO_PROMPT ] && {
		echo "ERROR: bad irq"
		cleanup $FAIL
	    }
	done
	IRQ=$irq

	while :
	do
	    if [ $NO_PROMPT ]
	    then
		[ $NO_PROMPT_BIO ] || {
		    echo "ERROR: bio not set"
		    cleanup $FAIL
		}
		result=$NO_PROMPT_BIO
	    else
		if [ "$type" = "386MC" ]
		then
			prompt_dual_range "Enter I/O base address" $BIO "200" "3e0" "20" "800" "f800" "1000" || cleanup $FAIL
		else
			prompt_range "Enter I/O base address" $BIO "200" "3e0" "20" || cleanup $FAIL
		fi
	    fi
	    bio=$result
	    EIO=`ha $bio 1f`
	    checkaddr $drv$bd $bio $EIO && break
	    [ $NO_PROMPT ] && {
		echo "ERROR: bad bio"
		cleanup $FAIL
	    }
	done
	BIO=$bio

	while :
	do
	    if [ $NO_PROMPT ]
	    then
		[ $NO_PROMPT_BRAM ] || {
		    echo "ERROR: bram not set"
		    cleanup $FAIL
		}
		result=$NO_PROMPT_BRAM
	    else
		prompt_range "Enter RAM base address" $BRAM "80000" "fde000" "2000" || cleanup $FAIL
	    fi
	    bram=$result

	    if [ "$type" = "386GT" -o "$elite" = "Y" -o -n "$NO_PROMPT" ]
	    then
	    	if [ $NO_PROMPT ]
	        then
		    [ $NO_PROMPT_RAMS ] || {
		    	echo "ERROR: rams not set"
		        cleanup $FAIL
		    }
		    result=$NO_PROMPT_RAMS
		else
		    prompt_select "Enter RAM Size in k" 16 "8 16" || cleanup $FAIL
		fi
		case $result in
		8)  size=1fff ;;
		16) size=3fff ;;
		esac
	    else
		size=3fff
	    fi
	    ERAM=`ha $bram $size`
	    checkram $drv$bd $bram $ERAM || {
	        [ $NO_PROMPT ] && {
		    echo "ERROR: bad bram or rams"
		    cleanup $FAIL
	        }
		continue
	    }
	    hc $bram 100000 f0c000 2000 > /dev/null 2>& 1 && {
	 	echo "Warning: this address may not be valid if your network adapter"
		echo "is not a 16-Bit Elite adapter"
		echo "Shared memory addresses above 1 Meg are supported by 16-bit Elite adapters only."
	    }
	    break
	done
	BRAM=$bram

	NMINORS="16"

	[ "$rel" = "3.2.1" -o "$rel" = "3.2.0" ] && {
		if [ "$type" = "386GT" ]
		then
			grep "int arch =" /etc/conf/pack.d/wdn0/space.c >/dev/null 2>&1 || {
			echo "int arch = 1;" >> /etc/conf/pack.d/wdn0/space.c
			}
		elif [ "$type" = "386MC" ]
		then
			grep "int arch =" /etc/conf/pack.d/wdn0/space.c >/dev/null 2>&1 || {
			echo "int arch = 2;" >> /etc/conf/pack.d/wdn0/space.c
			}
		fi
	}
}

#
# function to produce info for the System file for HP EISA Slave LAN adapters
#
system_hpe() {

	case ${bd} in
	0) IRQ=5 ; DMA=3;;
	1) IRQ=7 ; DMA=2;;
	2) IRQ=10; DMA=6;;
	3) IRQ=11; DMA=5;;
	esac

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_DMA ] || {
			echo "ERROR: dma not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_DMA
	    else
		prompt_select "Enter DMA channel" $DMA "1 2 3 5 6" || cleanup $FAIL
	    fi
	    dma=$result
	    checkdma $drv$bd $dma && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad dma"
                cleanup $FAIL
	    }
	done
	DMACHAN=$dma

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_IRQ ] || {
			echo "ERROR: irq not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_IRQ
	    else
		prompt_select "Enter IRQ" $IRQ "3 4 5 7 10 11 12" || cleanup $FAIL
	    fi
	    irq=$result
	    checkvec $drv$bd $irq && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad irq"
                cleanup $FAIL
	    }
	done
	IRQ=$irq

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_SLOT ] || {
			echo "ERROR: slot not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_SLOT
	    else
		prompt_select "Enter slot number" "" "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" || cleanup $FAIL
	    fi
	    SLOT=$result
	    case $result in
	    0) bio=0C00; EIO=0CFF;;
	    1) bio=1C00; EIO=1CFF;;
	    2) bio=2C00; EIO=2CFF;;
	    3) bio=3C00; EIO=3CFF;;
	    4) bio=4C00; EIO=4CFF;;
	    5) bio=5C00; EIO=5CFF;;
	    6) bio=6C00; EIO=6CFF;;
	    7) bio=7C00; EIO=7CFF;;
	    8) bio=8C00; EIO=8CFF;;
	    9) bio=9C00; EIO=9CFF;;
	    10) bio=AC00; EIO=ACFF;;
	    11) bio=BC00; EIO=BCFF;;
	    12) bio=CC00; EIO=CCFF;;
	    13) bio=DC00; EIO=DCFF;;
	    14) bio=EC00; EIO=ECFF;;
	    15) bio=FC00; EIO=DCFF;;
   	     *) cleanup $FAIL
	    esac
	    checkaddr $drv$bd $bio $EIO && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad slot"
                cleanup $FAIL
	    }
	done
	BIO=$bio
	BRAM="0"
	ERAM="0"
	NMINORS="1"
}

#
# function to produce the info for the System file for the HP ISA LAN adapters
#
system_hpi() {

	case ${bd} in
	0) IRQ=2  ; BIO=300;;
	1) IRQ=3  ; BIO=240;;
	2) IRQ=5  ; BIO=280;;
	3) IRQ=7  ; BIO=2C0;;
	esac

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_IRQ ] || {
			echo "ERROR: irq not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_IRQ
	    else
		echo "IRQs 10 and 11 are only valid for 16-bit adapters."
		prompt_select "Enter IRQ" $IRQ "2 3 4 5 7 10 11" || cleanup $FAIL
	    fi
	    irq=$result
	    checkvec $drv$bd $irq && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad irq"
                cleanup $FAIL
	    }
	done
	IRQ=$irq
	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BIO ] || {
			echo "ERROR: bio not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BIO
	    else
		prompt_select "Enter I/O base address" $BIO "200 240 280 2C0 300 320 340" || cleanup $FAIL
	    fi
	    bio=$result
	    case $result in
	    200) EIO=21F ;;
	    240) EIO=25F ;;
	    280) EIO=29F ;;
	    2C0) EIO=2DF ;;
	    300) EIO=31F ;;
	    320) EIO=33F ;;
	    340) EIO=35F ;;
   	    *) cleanup $FAIL
	    esac
	    checkaddr $drv$bd $bio $EIO && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad bio"
                cleanup $FAIL
	    }
	done
	BIO=$bio
	BRAM="0"
	ERAM="0"
	NMINORS="1"
}

#
# function to produce the information for the System file for the Racal InterLan
# ES-3210 board.
#
system_i3B() {

	ucbase="I3B"
	spacef=${CONF:-/etc/conf}/pack.d/${drv}0/space.c

	# BIO represents EISA slot number here
	case $bd in
	0) IRQ=9; BIO=1; BRAM=d0000; DMA=NONE;;
	1) IRQ=10; BIO=2; BRAM=d4000; DMA=NONE;;
	2) IRQ=11; BIO=4; BRAM=d8000; DMA=NONE;;
	3) IRQ=12; BIO=5; BRAM=dc000; DMA=NONE;;
	esac

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_IRQ ] || {
			echo "ERROR: irq not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_IRQ
	    else
		prompt_select "Enter IRQ" $IRQ "3 4 5 6 7 9 10 11 12 14 15" || cleanup $FAIL
	    fi
	    irq=$result
	    checkvec $drv$bd $irq && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad irq"
                cleanup $FAIL
	    }
	done
	IRQ=$irq

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_SLOT ] || {
			echo "ERROR: slot not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_SLOT
	    else
		prompt_range "Enter slot number" $BIO "1" "9" "1" || cleanup $FAIL
	    fi
	    bio=`expr $result * 1000`
	    EIO=`ha $bio fff`
	    checkaddr $drv$bd $bio $EIO && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad bio"
                cleanup $FAIL
	    }
	done
	BIO=$bio

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BRAM ] || {
			echo "ERROR: bram not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BRAM
	    else
		prompt_range "Enter RAM base address" $BRAM "c0000" "3fffc000" "4000" || cleanup $FAIL
	    fi
	    bram=$result
	    ERAM=`ha $bram 3fff`
	    checkram $drv$bd $bram $ERAM && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad bram"
                cleanup $FAIL
	    }
	done
	BRAM=$bram

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_DMA ] || {
			echo "ERROR: dma not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_DMA
	    else
		prompt_select "Enter DMA" $DMA "NONE 0 1 2 3 5 6 7" || cleanup $FAIL
	    fi
	    if [ "$result" = "NONE" ]
	    then
	        dma=-1
	    else
	 	dma=$result
	    fi
	    checkdma $drv$bd $dma && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad dma"
                cleanup $FAIL
	    }
	done
	DMACHAN=$dma

	# Setup space.c.  
	# Get the media type (thick or thin and edit it into space.c
        if [ $NO_PROMPT ]
        then
	    [ $NO_PROMPT_AUI ] || {
		echo "ERROR: aui not set"
		cleanup $FAIL
	    }
	    result=$NO_PROMPT_AUI
	else
	    prompt_yn "Does this ES-3210 board use thick (AUI) ethernet?" "n" || cleanup $FAIL
	fi
	if [ "$result" = "Y" ] 
	then
		netyp="THIK"
	else
		netyp="THIN"
	fi
	if [ $bd -eq 0 ]
	then
		str="THIKTHIN"
	else
		str="THIKTHIN${bd}"
	fi
	a=`grep -n "^#define[ 	]${str}[ 	]" $spacef`
	b=`expr "$a" : '.*G1_\(....\)'`
	if [ "$b" != "$netyp" ]
	then
		c=`expr "$a" : '\(.*:\)' | sed 's/://'`
		sed "${c}s/G1_$b/G1_$netyp/" $spacef >/tmp/bog$$
		cp /tmp/bog$$ $spacef
		rm /tmp/bog$$
	fi
	NMINORS="1"
}

#
# function to produce the information for the System file for the Racal InterLan
# NI-6510 board.
#
system_i6E() {
	ucbase="I6E"
	BRAM=0

	case $bd in
	0) IRQ=9; BIO=360; DMA=3;;
	1) IRQ=12; BIO=340; DMA=5;;
	esac

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_IRQ ] || {
			echo "ERROR: irq not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_IRQ
	    else
		prompt_select "Enter IRQ" $IRQ "5 9 12 15" || cleanup $FAIL
	    fi
	    irq=$result
	    checkvec $drv$bd $irq && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad irq"
                cleanup $FAIL
	    }
	done
	IRQ=$irq

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BIO ] || {
			echo "ERROR: bio not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BIO
	    else
		prompt_range "Enter I/O base address" $BIO "300" "360" "20" || cleanup $FAIL
	    fi
	    bio=$result
	    EIO=`ha $bio f`
	    checkaddr $drv$bd $bio $EIO && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad bio"
                cleanup $FAIL
	    }
	done
	BIO=$bio

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_DMA ] || {
			echo "ERROR: dma not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_DMA
	    else
		prompt_select "Enter DMA" $DMA "0 3 5 6" || cleanup $FAIL
	    fi
	    dma=$result
	    checkdma $drv$bd $dma && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad dma"
                cleanup $FAIL
	    }
	done
	DMACHAN=$dma
	NMINORS="1"
}

#
# function to produce the info for the System file for the NE2000
# boards
#
system_nat() {

	case $bd in
	0) IRQ=2; BIO=300;;
	1) IRQ=3; BIO=320;;
	2) IRQ=4; BIO=340;;
	3) IRQ=5; BIO=360;;
	esac

	while :
	do
            if [ $NO_PROMPT ]
            then
	    	[ $NO_PROMPT_IRQ ] || {
			echo "ERROR: irq not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_IRQ
	    else
		prompt_select "Enter IRQ" $IRQ "2 3 4 5 6 7" || cleanup $FAIL
	    fi
	    irq=$result
	    checkvec $drv$bd $irq && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad irq"
                cleanup $FAIL
	    }
	done
	IRQ=$irq

	while :
	do
	    if [ $NO_PROMPT ]
	    then
	    	[ $NO_PROMPT_BIO ] || {
			echo "ERROR: bio not set"
			cleanup $FAIL
	    	}
		result=$NO_PROMPT_BIO
	    else
		prompt_range "Enter I/O base address" $BIO "300" "360" "10" || cleanup $FAIL
	    fi
	    bio=$result
	    EIO=`ha $bio 0f`
	    checkaddr $drv$bd $bio $EIO && break
            [ $NO_PROMPT ] && {
		echo "ERROR: bad bio"
                cleanup $FAIL
	    }
	done
	BIO=$bio

	BRAM="0"
	ERAM="0"

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

NO_PROMPT=

[ -n "$IQM_FILE" -a -f "$IQM_FILE" -a ! -f /tmp/system_upgrade ] && {
        NO_PROMPT=IQM
        . $IQM_FILE
        # There is an assumption that this will never be called when
        # $IQM_LLI_DRVBD = none but it never hurts to check.
        [ "$IQM_LLI_DRVBD" = "none" ] && exit 0
        [ $IQM_LLI_DRVBD ] && NO_PROMPT_DRVBD=$IQM_LLI_DRVBD
        [ $IQM_LLI_INTR ] && NO_PROMPT_IRQ=$IQM_LLI_INTR
        [ $IQM_LLI_BIO ] && NO_PROMPT_BIO=$IQM_LLI_BIO
        [ $IQM_LLI_DMA ] && NO_PROMPT_DMA=$IQM_LLI_DMA
        [ $IQM_LLI_BRAM ] && NO_PROMPT_BRAM=$IQM_LLI_BRAM
        [ $IQM_LLI_BROM ] && NO_PROMPT_BROM=$IQM_LLI_BROM
        [ $IQM_LLI_RAMS ] && NO_PROMPT_RAMS=$IQM_LLI_RAMS
        [ $IQM_LLI_BSHRAM ] && NO_PROMPT_BSHRAM=$IQM_LLI_BSHRAM
        [ $IQM_LLI_SLOT ] && NO_PROMPT_SLOT=$IQM_LLI_SLOT
        [ $IQM_LLI_AUI ] && {
	    case "$IQM_LLI_AUI" in
	 	"AUI")NO_PROMPT_AUI=Y ;;
		    *)NO_PROMPT_AUI=N ;;
	    esac
	}
        [ $IQM_LLI_LRBR ] && NO_PROMPT_LRBR=$IQM_LLI_LRBR
}

makedevs
check_args

#
# Check and manage our internal chains file.
# This file allows coexistent mkdev and netconfig calls.
#
# check if board/chain already installed
grep "^$base:" $chains > /dev/null 2>& 1 && {
	echo $base already configured.
	grep "^$chain" $chains > /dev/null 2>&1 && {
		cleanup $OK
	} || {
		echo $chain >> $chains
		[ "$drv" = "tok" -a "$name_above" = "nbe" ] && space_token
	}
	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"
MIN_UNITS=1
MAX_UNITS=256
TYPE=1

#
# set rel, type variables.
#
os_type

#
# Do special board dependent processing
#
system_$drv

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

echo "$base\tY\t$NMINORS\t5\t$TYPE\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
	[ -f Master ] || echo "$base	-	iScH	$PREFIX	0	0	$MIN_UNITS	$MAX_UNITS	$DMACHAN" >./Master
	[ -f Node ] || echo "clone	$base	c	$base" >./Node

	if [ "$installed" = "TRUE" ]
	then
		idinstall -u -m -s -p -n -o -e -k $base
	else
		cp $LIB/Driver.o .
		idinstall -a -e -k $base
	fi
else
	[ -f Master ] || echo "$base	I	icSH	$PREFIX	0	0	$MIN_UNITS	$MAX_UNITS	$DMACHAN" >./Master
	idinstall -u -m -s -p -n -o -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
