#!/bin/sh
# @(#)preremove	1.1 01/06/10 Sun Microsystems
# SUNWidecr.u preremove script
# Copyright (c) 1997-2001 by Sun Microsystems, Inc.
# All rights reserved.
#

# This version of the preremove script (v1.1) is intended to make
# both old and new IDE drivers coexist together. Both versions of the
# drivers get installed and coexist.  Depending on the OBP mode, only
# one will get loaded on the running system...!!
#
# if this script is invoked manually with the "switch-over" as its first
# argument, it will replace the old drivers to new drivers or vice-versa.
# The top half of this script should be the same as that of the 
# postinstallation script.
#


#
#	Defining convenient variables for later
#
iroot=${PKG_INSTALL_ROOT:-$BASEDIR}
ADD_DRV=add_drv
REM_DRV=rem_drv
DADA_ID="DADA"
CMDK_ID="CMDK"
ROOT_BASEDIR="/"
ROOT_ARCH="sparc.sun4u"
PHOTON_SYSNAMESTART="SUNW,Ultra"
PHOTON_SYSNAMEEND="Engine"

# DADA drivers 
#
DADA_DRV1=Neide
DADA_DRV2=atata
DADA_DRV3=disk_ata
DADA_DRV4=cdrom_atapi
DADA_DRV1_ALIAS='"pci100b,2"'
DADA_DRV2_ALIAS="softata"
DADA_DRV3_ALIAS='"ata-disk"'
DADA_DRV4_ALIAS='"atapi-cdrom"'
DADA_DRV2_CLASS="scsi"
DADA_DRV3_CLASS="dada"
DADA_DRV4_CLASS="atapi"
DADA_NODE_PERM="0640"
DADA_DRVPERM="* $DADA_NODE_PERM root sys"
DADA_DISK_DRV=${DADA_DRV3}

# The following will be used, if someone wants to switch over to new
# drivers wrt old OBP.

CMDK2DADA_DRV1_ALIAS="NSC,PC87415"
CMDK2DADA_DRV2_ALIAS="ata"
CMDK2DADA_DRV3_ALIAS="cmdk"
CMDK2DADA_DRV4_ALIAS=""

# CMDK driver definitions below. We do nothing with these for now.
#
CMDK_DRV1=eide
CMDK_DRV2=ata
CMDK_DRV3=cmdk
CMDK_DRV4=""
CMDK_DRV1_ALIAS="ide"
CMDK_DRV2_ALIAS=""
CMDK_DRV3_ALIAS=""
CMDK_DRV4_ALIAS=""
CMDK_DRVPERM="* 0640 root sys"
CMDK_DISK_DRV=${CMDK_DRV3}
 
# for 2.7 release and beyond, we shall use the following driver for atapi
# cdroms
CDROM_DRV_27="sd"
# since this is a 2.7 install script the following must be on.
CDROM_DRV_PRE_27=0

# 
# Number of Logical Unit Numbers supported by each Target.
# For SCSI and IDE, under SPARC it is 8.
#
LUNS_PER_TARG=8
DISK_DRV_MAJ_NUM=0
OLD_DISK_DRV_MAJ_NUM=0

PATH=$PATH:/usr/bin:/usr/sbin:/sbin:/etc

# Following parameters can be changed carefully.
#

# Load DADA always ?
# If this flag is set to 1, we always load DADA drivers irrespective of OBP mode#
FORCELOAD_DADA=0

# Load CMDK always ?
# If this flag is set to 1, we always load CMDK drivers irrespective of OBP mode
# This is true for now until we permanently switch from CMDK to DADA.
# 
FORCELOAD_CMDK=0

# Make a decision based on OBP mode switch ?
# If this flag is 0, then decision of loading drivers is based on the
# variable DEFAULT_DRV which is declared somewhere around here.
#
LOAD_BASED_ON_OBP=1
 
#
# If LOAD_BASED_ON_OBP is not true, then we load the following default
# driver
#
DEFAULT_DRV="$CMDK_ID"
# Disk driver whose nodes are to be checked for correctness.
DISK_DRV=${CMDK_DISK_DRV}
#DISK_DRV="dad"

# Are we a part of miniroot ? 
MINIROOT_DADA_INSTALLED=0

OBP_SUPPORT4DADA=0


# New OBP version beyond which our new drivers can be loaded.
# Hopefully the new version will be 3.1.6 or may be 3.2 or.. why bother
NEW_OBP_VER=3.1.5

# Is this script being executed for switching drivers ? a flag that determines.
SWITCH_DRV=0

# default log file for log information. 
DEF_LOGFILE=/tmp/SUNWidecr.log

# Update only our driver nodes OR everybody's ?? 
# IF this is set to 1, all major number inconsistencies under /dev/[r]dsk
# will be fixed. Ofcourse, lets not touch anyone's for now.
UPDATE_ALL_NODES=0

# debug flag = 1, for Detailed debug messages in log file.
DEBUG=0

# Interactive mode by default
INTERACTIVE_MODE=1

# Run drvconfing and disks to create /devices and /dev nodes/links.
REFRESH_NODES=0

# Always correct driver nodes by default.
CREATE_DRV_NODES=1

# print debug messages
debug_print()
{
	if [ $DEBUG -eq 1 ]; then
		echo $1 >> ${PKGLOGFILE}
	fi
}

# print package install/remove log messages
log_print()
{
	echo $1 >> ${PKGLOGFILE}
}

verb_print()
{
	if [ $INTERACTIVE_MODE -eq 1 ]; then
		echo $1
	else
		echo $1 >> ${PKGLOGFILE}
	fi
}

print_usage()
{
	echo "\nThis script acts on certain keywords specified. The usage is\n"
	echo "$0 [switch-over|quiet|help|logfile=<logfile>|basedir=<dir>|force|examples]"
	echo "\nOption->"
	echo "switch-over   : Switch  drivers  from CMDK to DADA or vice versa "
	echo "                and update nodes."
	echo "                Must be specified for switching drivers."
	# echo "verbose       : verbose information"
	echo "CMDK          : Install CMDK drivers and nodes. This option"
	echo "                overtakes default action. (optional)"
	echo "DADA          : Install DADA drivers and nodes. This option"
	echo "                overtakes default action. (optional)"
	echo "quiet         : Non interactive  mode. No confirmation requested "
	echo "                about switch."
	echo "help          : print usage information of this script  and exit."
	echo "logfile=<file>: specify  <file> as  log  file  for  storing  log "
	echo "                information. (optional)"
	echo "                Default log file is $DEF_LOGFILE."
	echo "basedir=<dir> : specify <dir> as the new base directory(optional)"
	echo "                This option should be used on remote images only."
	echo "                Default base directory is /"
	echo "force         : force  switching of drivers irrespective  of OBP "
	echo "                support. "
	echo "                This option is mostly used for switching drivers "
	echo "                on  servers or other remote images where the OBP "
	echo "                version of the running system could be different "
	echo "                from that of the boot image on which this script "
	echo "                is run.  Commonly used with the 'basedir' option."
	echo "                User must not use  this option  unless sure that "
	echo "                PROM support exists."
	echo "examples      : Print some examples of usage and exit."
}
print_examples()
{
	echo
	echo "Examples->"
	echo "In its simplest form, it can be run as "
	echo "% sh preremove switch-over"
	echo "\nWithout any messages on screen, use the 'quiet' option"
	echo "% sh preremove switch-over quiet"
	echo "\nOn a remote boot image mounted on /mnt, we can force a switch by"
	echo "% sh preremove switch-over force basedir=/mnt"

}

# $1 = /etc/path_to_inst part of the /dev/dsk link name 
# For eg. $1 should be of the form pci@1f,4000/ide@3/ata@0,0/cmdk@0,0:a
#
get_instance_num()
{
	search_inst_dev=$1

	# get the final seach name for search in 
	# /etc/path_to_inst
	search_inst_name=`echo $search_inst_dev | cut -f1 -d:`
	debug_print "search_inst_name = $search_inst_name"

	# get the instance number for this node
	instance=`grep $search_inst_name ${PATH_TO_INST} | grep "\"${DISK_DRV}\"" | cut -f2 -d" "`
	debug_print "instance number got = $instance"

	if [ "$instance" = "" ]; then
		search_common_node=`echo $search_inst_name | nawk ' {
			split($0, a, "/ata")
			print a[1]
		}'`
		debug_print "search_common_node is $search_common_node"
		instance_num=`grep $search_common_node ${PATH_TO_INST} | grep "ata" | grep "${OLD_DISK_DRV}" | grep "\"${DISK_DRV}\"" | wc | awk ' { print $1 } '`
		debug_print "search_common_node instance is $instance_num"
		# grab the target id which is the instance no ?
		if [ "$instance_num" = "0" ]; then
			instance_num=`echo $node | cut -f2 -d"t" | cut -f1 -d"d"`
		fi
	else
		instance_num=$instance
	fi
	debug_print "instance number assigned = $instance_num"
	return $instance_num

}

make_all_nodes()
{
	for node in `ls`
	do
		make_one_node $node
	done
	echo >> ${PKGLOGFILE}

}

# make one node. $1 is name of the /dev/dsk node.
#
make_one_node()
{
	node=$1
	old_link_name=`ls -l $node | cut -f2 -d ">"`
	echo $old_link_name > /tmp/link.$$
	debug_print "current link name is $old_link_name"
	link_name=$old_link_name

	OLD_DRV=`basename $link_name | cut -f1 -d"@"`
	if [ "$OLD_DRV" != "$OLD_DISK_DRV" -a "$OLD_DRV" != "$DISK_DRV" ]; then
		debug_print "Not our driver..Returning without touching this node"
		return
	fi
	new_link_name=`echo $link_name | nawk -v DOLD=$OLD_DRV -v DNEW=$DISK_DRV ' { sub(DOLD,DNEW,$0) } END { print $0 }'`
	debug_print "new link name to be created is: $new_link_name"
	# see if link_name itself was our node.
	if [ "$new_link_name" != "" ]; then
		link_name=$new_link_name
	fi

	check_if_node_link_wrong $node $link_name
	rc=$?

# return code 	0 = node exists and linked correctly, do nothing
#		1 = node does not exists but link exists. Need to create node.
#	 	2 = Link does not exist. Need to create links or probably node.
#		3 = link and node wrong. Needs to create/correct node and relink
#		4 = invalid operation for this case. Eg. driver not present.
	case $rc in
		# if not correct(rc=1), we need to create links.
		1|3)	rm -f $node > /dev/null 2>&1
			rm -f $old_link_name > /dev/null 2>&1
			debug_print "correct link being created now for $node "
			ln -s $link_name $node

			# cut off upto /devices part from the name
			search_inst_dev=`echo $link_name | nawk ' {
				split($0, a, "/devices/")
				print a[2]
			}' `
			debug_print "search_inst_dev = $search_inst_dev"

			rm -f /tmp/link.$$ > /dev/null 2>&1

			get_instance_num $search_inst_dev
			instance_num=$?

			# get major number now
			get_drv_major_num $link_name
			major_num=$?

			if [ $major_num -eq 0 ]; then
				debug_print "Invalid Major number retrieved no major number for driver" >> ${PKGLOGFILE}
				# exit 1
				continue
			fi

			# get minor number now.
			# The following will result in a wrong
			# minor number, IFF path_to_inst does not really
			# have the instance numbers for this instance of the
			# driver. This is probably true only during fresh
			# installation. This mess is becuase there are 
			# more than one drivers
			# driving the set of these linked nodes. 
			# for eg. c0t0d0s0 can be driven by dad disk driver
			# and c1t2d0s0 can be driven by 'atapicd' CDROM driver.
			# Both can start with a minor number Zero during
			# their first load instance.
			#
			# But luckily for us, since this is a IDE driver,
			# the primary boot disk device will usually appear
			# as Target 0 on the primray channel, as unlike in
			# SCSI land, Target ID is not set on the device.
			# The driver itself will asign target numbers 
			# dynamically and checks for the "type" property
			# validity of the corresponding "target" device
			# as defined in the .conf file.
			#
			start_minor_num=`expr $instance_num \* ${LUNS_PER_TARG}`
			lun_num=`echo $node | cut -f2 -d"s"`
			minor_num=`expr $start_minor_num + $lun_num`
	
			# create LUNS_PER_TARG number of nodes, 
			# each time pointing to the right links
			debug_print "$node>mknod $link_name ${NODE_TYPE} $major_num $minor_num"
			mknod $link_name ${NODE_TYPE} $major_num $minor_num > /dev/null 2>&1
			chmod $DADA_NODE_PERM $link_name
			chgrp sys $link_name
			rm -f $node
			ln -s $link_name $node

			if [ ! $? -eq 0 ]; then
				log_print "ERROR creating device node $node" 
				log_print "*\c"
			else
				log_print "#\c"
			fi
			;;
		0)
			debug_print "$node exists and correct."
			log_print ".\c"
			;;
		*)
			debug_print "invalid case for link check."
			;;
	esac
}

# get the driver major number given the driver name 
# NOTE: Although Zero is a valid major number, it is considered a FAILURE
# case, because we know that we can never get assigned a major number of Zero
# The console device has it always, if not there are better contenders than us.
#
# $1 = [ <driver_name> | <driver-node-link-name-as-in-/devices> ]
# eg. $1 can be just "cmdk" OR worse "../../devices/.<>./.<>./cmdk@0,0:a
#

get_drv_major_num()
{
	cur_link_name=$1

	# get major number now
	drv_name=`basename $cur_link_name | cut -f1 -d"@"`
	debug_print "node driver name is $drv_name"

	# Check if this is aliased driver, if yes
	# lets get the real name before we check for its
	# major number
	#
	grep "$drv_name" ${DRIVER_ALIASES} | cut -f2 -d " " | grep "^$drv_name" > /dev/null 2>&1
	rc=$?
	grep "$drv_name" ${DRIVER_ALIASES} > /tmp/getdrv.$$

	if [ ! $? -eq 0 ]; then
		debug_print "This is not an aliased driver"
		driver_aliased=0
		TARG_DRV=$drv_name
	else
		debug_print "This driver is aliased"
		driver_aliased=1
		TARG_DRV=`nawk -v drvname=$drv_name '
		{
			#print "Checking on ",  $2, drvname
			if ( $2 == drvname )
			{
				#print $1
				drvname=$1
			}
		} END { print drvname }' /tmp/getdrv.$$`
	fi

	rm -f /tmp/getdrv.$$
	debug_print "target driver is $TARG_DRV"
	# get major number of our device 
	target_driver=`grep "^$TARG_DRV" ${NAME_TO_MAJOR} | cut -f1 -d" "` 
	if [ ! "$target_driver" = "$TARG_DRV" ]; then
		debug_print "different target driver "
		debug_print "ERROR No Major number for Target Disk driver ${TARG_DRV}"
		# echo "Check for ERRORs in installation "
		return 0	# return invalid major number
	fi
	major_num=`grep "^$TARG_DRV" ${NAME_TO_MAJOR} | cut -f2 -d" "` 

	# The following statement will not work if driver major number
	# exceeds a value of 255, as the shell only returns a 8bit value.
	return $major_num
}


# check to see if we need to remove wrong links so that new links can
# be created using make_one_node function above.
#
# needs to be called with 2 arguments
# Currently, you need to be in /dev/[r]dsk directory.
#
# return code 	0 = node exists and linked correctly, do nothing
#		1 = node does not exists but link exists. Need to create node.
#	 	2 = Link does not exist. Need to create links or probably node.
#		3 = link and node wrong. Needs to create/correct node and relink
#		4 = invalid operation for this case. Eg. driver not present.
#		    or some other driver. should not touch this case at all
#		    unless UPDATE_ALL_NODES flag is set. We are not going
#		    worry about its implementation yet.
#		
# 
check_if_node_link_wrong()
{
	cur_node=$1
	new_link_name=$2
	# dont worry. if the following is not true, it will be set accordingly.
	node_link_wrong=0
	node_major_num=0

	if [ $cur_node ]; then
		if [ ! -${NODE_TYPE} $cur_node ]; then
			node_link_wrong=1
		else
			node_major_num=`ls -lL $cur_node | awk ' { print $5 } ' | cut -f1 -d ","`
			debug_print "node major num = $node_major_num"
		fi
	else
		node_link_wrong=2
	fi
	if [ ! $node_major_num -eq 0 ]; then

		if [ ! $node_major_num -eq $DISK_DRV_MAJ_NUM ]; then

			if [ ! $node_major_num -eq $OLD_DISK_DRV_MAJ_NUM ]; then
				debug_print "$cur_node exists: Linked CORRECTly...But does not belong to our driver"
				node_link_wrong=4
			else
				debug_print "$cur_node wrongly linked. Need to remove node. Correct link."
				node_link_wrong=3
			fi
		fi
	fi

	# if [ -${NODE_TYPE} $new_link_node ]; then
		# sleep 0
	# fi

	return $node_link_wrong
}

# check for driver installation

# Given a driver name as an argument, this function checks to see  if the
# driver has been installed or not. If yes,
# 
# If installed, returns a value of 0 so that caller may not try to load
# drivers again. If returned 1, the caller may proceed with loading the
# driver module.

safe_to_install()
{
	drv_name=$1

	# log_print "Check for previous installation of $drv_name"
	egrep -s "^${drv_name}" ${NAME_TO_MAJOR} > /dev/null 2>&1
	rc=$?
	if [ $rc -eq 0 ]; then
		log_print "${drv_name} already configured, returning"

	fi
	return $rc
}

# returns 0 if ok to switch drivers, 1 otherwise.
get_really_switch_ans()
{
	echo "This script will switch drivers to \"$DEFAULT_DRV\" interface"
	return 0
}

refresh_nodes()
{
	if [ ! "${iroot}" = "/" ]; then
		verb_print "This option currently supported only when base directory is /"
		verb_print "Please do not use this option otherwise. Sorry."
		exit 1
	fi

	rm -f ${iroot}/dev/dsk/*  > /dev/null  2>&1
	rm -f ${iroot}/dev/rdsk/* > /dev/null  2>&1
	drvconfig -r ${iroot} > /dev/null 2>&1
	disks -r ${iroot} > /dev/null 2>&1
	tapes -r ${iroot} > /dev/null 2>&1
	ports -r ${iroot} > /dev/null 2>&1
}

# main()
# 

LOGFILE_OPT=0
NULL_ARGS=0
BASEDIR_OPT=0
PKGLOGFILE=${DEF_LOGFILE}
USR_SELECT_DRV_OPT=0
USR_SELECT_DRV=""

SCRIPT_NAME=`basename $0`
LOAD_UNLOAD_DRVS=1

# if called with null args, we do assume that this script is not being
# manually invoked but by pkgadd/pkgrm.
# Even if invoked manually without args, we do no damage. So not to worry.
if [ $# -eq 0 ]; then
	NULL_ARGS=1
fi

while [ "$1" ]; 
do
	case "$1" in
		switch-over)	SWITCH_DRV=1
				iroot="${ROOT_BASEDIR}"
				ARCH="$ROOT_ARCH"
				;;

		CMDK)		USR_SELECT_DRV_OPT=1
				USR_SELECT_DRV="$CMDK_ID"
				;;

		DADA)		USR_SELECT_DRV_OPT=1
				USR_SELECT_DRV="$DADA_ID"
				;;

		force)		FORCELOAD=1
				# The following will work only if the 
				# OBP patches are installed for correct 
				# drivers to load. If not, old drivers 
				# will be loaded provided node configuration 
				# has been set up correctly. Anyway, this 
				# is only for the design test purposes 
				# and noone else should use this flag. 
				# This flag is non-documented anyway.
				LOAD_BASED_ON_OBP=0
				;;

		verbose)	VERBOSE=1;;

		quiet)		INTERACTIVE_MODE=0;;

		help)		print_usage
				exit 0
				;;

		logfile=*)	LOGFILE_OPT=1
				LOGFILEARG=$1
				PKGLOGFILE=`echo $LOGFILEARG | cut -f2 -d"="`
				if [ "${PKGLOGFILE}" = "" ] ; then
					PKGLOGFILE=$DEF_LOGFILE
					log_print "No logfile specified. Default logfile is $PKGLOGFILE."
				fi
				;;
		basedir=*)	BASEDIR_OPT=1
				BASEDIRARG=$1
				NEW_BASEDIR=`echo $BASEDIRARG | cut -f2 -d"="`
				if [ "$NEW_BASEDIR" = "" ]; then
					verb_print "Must specify new base directory with 'basedir=' option"
					exit 1
				fi
				;;

		noload)		LOAD_UNLOAD_DRVS=0
				;;

		nonodes)	CREATE_DRV_NODES=0
				;;

		refresh)	
				REFRESH_NODES=1
				;;

		debug)		DEBUG=1
				;;
		examples)	print_examples
				exit 0
				;;

		*)		;;
	esac
	shift
done

# override other print related args, if DEBUG is specified.
if [ $DEBUG -eq 1 ]; then
	INTERACTIVE_MODE=1
fi

# package log file should be somewhere else ? No.
# PKGLOGFILE=${iroot}/${PKGLOGFILE}

# Lets not do the following but instead, just empty it. What if user has
# specified a /dev file. So.
# rm -f ${PKGLOGFILE} > /dev/null 2>&1

touch ${PKGLOGFILE} > /dev/null 2>&1
echo > ${PKGLOGFILE} > /dev/null 2>&1
if [ ! $? -eq 0 ]; then
	verb_print "Cannot create/erase/overwrite log file. "
	verb_print "Check permissions or specify new filename."
fi

# only way to know if we are being invoked manually or not.
if [ -z "$iroot" ] ;then
	verb_print "Must be called with correct arguments. Use \"$0 help\""
	debug_print "switch-over option must be used at any time for switching drivers."
	exit 1
fi

# basedir= option takes precedence.
if [ $BASEDIR_OPT -eq 1 ]; then
	iroot=$NEW_BASEDIR
fi

if [ $REFRESH_NODES -eq 1 ]; then
	if [ ! $SWITCH_DRV -eq 1 ]; then
		verb_print "Must specify switch-over option"
		exit 1
	fi
	refresh_nodes
	verb_print "Node creation complete. Exitting."
	exit 0
fi
# Files we touch or see.
DISK_BNODE_DIR=${iroot}/dev/dsk
DISK_RNODE_DIR=${iroot}/dev/rdsk
PATH_TO_INST=${iroot}/etc/path_to_inst
NAME_TO_MAJOR=${iroot}/etc/name_to_major
DRIVER_ALIASES=${iroot}/etc/driver_aliases

log_print "Executing script $SCRIPT_NAME ( $0 )"

log_print "\nInstalling drivers at Base Directory ${iroot} on `date`"
log_print "System Name  : \"`uname -n`\""
log_print "Logfile Name : ${PKGLOGFILE}\n"

# Select the correct add_drv options to execute.
# Only attempt to attach the driver
# on a running system with the hardware present.
#
if [ "${iroot}" = "/" ]; then
	#
	# No need to add_drv if the running system is of a different arch
	# than the package
	#
	karch=`uname -p`.`uname -m`
	if [ "${karch}" != "${ARCH}" ]; then
		verb_print "Invalid Architecture type ${karch} for package ${PKG}"
		exit 1
	fi
	ADD_DRV="add_drv -n"

else
	#
	# On a client,
	# modify the system files and touch /reconfigure ??
	# for reconfigure reboot ??
	#
	ADD_DRV="${ADD_DRV} -n -b ${iroot}"
	REM_DRV="${REM_DRV} -b ${iroot}"
fi

#   check for OBP version
#   if new version and higher,
#	add_drv all new drivers.
#	if iroot="/"
#		change node configuration to point to new major numbers.

# Get release,rev and subrev fields of our new OBP for comparison with current
NEWREL=`echo $NEW_OBP_VER | cut -f1 -d"."`
NEWREV=`echo $NEW_OBP_VER | cut -f2 -d"."`
NEWSUBREV=`echo $NEW_OBP_VER | cut -f3 -d"."`
if [ "$NEWSUBREV" = "" ]; then
	NEWSUBREV=0
fi
CUR_OBP_VER=`prtconf -V | cut -f2 -d" "`
log_print "Current OBP version is ${CUR_OBP_VER}"

CurRel=`echo $CUR_OBP_VER | cut -f1 -d"."`
if [ $CurRel -gt  $NEWREL ]; then
	DEFAULT_DRV="$DADA_ID"
else
if [ ! $CurRel -lt  $NEWREL ]; then
	CurRev=`echo $CUR_OBP_VER | cut -f2 -d"."`
	if [ $CurRev -gt $NEWREV ]; then
		DEFAULT_DRV="$DADA_ID"
	else
	if [ ! $CurRev -lt $NEWREV ]; then
		CurSubRev=`echo $CUR_OBP_VER | cut -f3 -d"."`
		if [ "$CurSubRev" = "" ]; then
			CurSubRev=0
		fi
		if [ $CurSubRev -gt $NEWSUBREV ]; then
			DEFAULT_DRV="$DADA_ID"
		fi
	fi
	fi
fi
fi

# A final check to see if we are installing on a Photon. If not, 
# we set default to CMDK drivers. This is helpful when building
# a net install image for 1197 where we should default to CMDK
# as we will not know the right OBP yet. We cannot simply just go
# on the above check of checking the version no. Everyone here may
# have similar version numbers. So the following check is also a must.
prtconf -p | grep Node | grep "$PHOTON_SYSNAMESTART" | grep "$PHOTON_SYSNAMEEND" > /dev/null  2>&1
if [ $? -eq 1 ]; then
	debug_print "WARNING system node name is invalid"
	# we do not know, what OBP version we are going to install on.
	# so we default to CMDK by default. As of now.
	OBP_SUPPORT4DADA=0
	DEFAULT_DRV="$CMDK_ID"
fi

# be clear about obp support finally.
if [ "$DEFAULT_DRV" = "$DADA_ID" ]; then
	OBP_SUPPORT4DADA=1
else
	OBP_SUPPORT4DADA=0
fi
# Now we know what OBP version is; and if we can really go ahead and install
# drivers.
# Check what version driver is installed, old or new.
#

debug_print "Using $DEFAULT_DRV drivers as default"

egrep -s "^(${DADA_DRV1}|${DADA_DRV2}|${DADA_DRV3})" ${NAME_TO_MAJOR} 2> /dev/null
if [ $? -eq 0 ]; then
	DADA_INSTALLED=1
	debug_print "DADA drivers are already installed."
else
	DADA_INSTALLED=0
fi
egrep -s "^(${CMDK_DRV1}|${CMDK_DRV2}|${CMDK_DRV3})" ${NAME_TO_MAJOR} 2> /dev/null
if [ $? -eq 0 ]; then
	CMDK_INSTALLED=1
	debug_print "CMDK drivers are already installed."
else
	CMDK_INSTALLED=0
fi
# Find out if drivers are installed at mini-root.
egrep -s "^(${DADA_DRV1}|${DADA_DRV2}|${DADA_DRV3})" /etc/name_to_major 2> /dev/null
if [ $? -eq 0 ]; then
	MINIROOT_DADA_INSTALLED=1
	debug_print "DADA drivers are already installed in miniroot."
else
	debug_print "DADA drivers are NOT installed in miniroot."
	MINIROOT_DADA_INSTALLED=0
fi

if [ $SWITCH_DRV -eq 1 ]; then
	if [ $USR_SELECT_DRV_OPT -eq 1 ]; then
		DEFAULT_DRV=$USR_SELECT_DRV
	else
		if [ $DADA_INSTALLED -eq 1 ]; then
			DEFAULT_DRV="$CMDK_ID"
		else
			DEFAULT_DRV="$DADA_ID"
		fi
	fi
	if [ $LOAD_BASED_ON_OBP -eq 1 ]; then
		if [ $OBP_SUPPORT4DADA -eq 0 ]; then
			verb_print "Current version OBP does not support switching. Sorry"
			exit 1
		fi
	fi
	if [ $INTERACTIVE_MODE -eq 1 ]; then
		get_really_switch_ans
		if [ $? -eq 0 ]; then
			debug_print "Switching over to $DEFAULT_DRV drivers on request"
		else
			debug_print "Switch terminated upon request."
			exit 1
		fi
	else
		verb_print "Switching over to $DEFAULT_DRV drivers on request"
	fi
	ADD_DRV="add_drv -n -b ${iroot}"
	REM_DRV="rem_drv -b ${iroot}"
fi
# At this point, we are set to load or unload.
# The only special case we handle is when this script is called from
# pkgadd and pkgrm, in which case we should not worry about any switch
# as we always load during pkgadd and unload during pkgrm based on OBP support.
#
if [ $SWITCH_DRV -eq 0 ]; then
	# add driver if we are pkgadd'ing
	if [ "$SCRIPT_NAME" = "postinstall" ]; then
		# Now we always load DADA during pkgadd installation
		DEFAULT_DRV="$DADA_ID"
	fi
	# remove drivers if we are pkgrm'ing
	if [ "$SCRIPT_NAME" = "preremove" ]; then
		DEFAULT_DRV="$CMDK_ID"
	fi
	# Do not add drivers if FORCELOAD_CMDK is 1, in which case we
	# always let cmdk load. Only a manual switch over will switch
	# drivers from cmdk to dada and vice versa.
	if [ $FORCELOAD_CMDK -eq 1 ]; then
		# if during upgrade operation, DADA drivers are installed
		# we keep DADA drivers.
		# Does Solaris wipe out /dev tree at the end of the
		# installation and copy from the boot media to target disk ?
		# in whic case the following will not work and we will
		# need to avoid this check and always default to 'CMDK'.

		# if [ $DADA_INSTALLED -eq 0 ]; then
		#	DEFAULT_DRV="$CMDK_ID"
		# fi

		DEFAULT_DRV="$CMDK_ID"
	fi
fi

# variable initialization.
DISK_DRV_MAJ_NUM=0
OLD_DISK_DRV_MAJ_NUM=0
# we load unload DADA always.
DRV1=$DADA_DRV1
DRV2=$DADA_DRV2
DRV3=$DADA_DRV3
DRV4=$DADA_DRV4
DRV1_ALIAS=$DADA_DRV1_ALIAS
DRV2_ALIAS=$DADA_DRV2_ALIAS
DRV3_ALIAS=$DADA_DRV3_ALIAS
DRV4_ALIAS=$DADA_DRV4_ALIAS
DRV2_CLASS=$DADA_DRV2_CLASS
DRVPERM=$DADA_DRVPERM
DISK_DRV=${DADA_DISK_DRV}

debug_print "default driver upon reboot is ${DEFAULT_DRV}"

if [ "$DEFAULT_DRV" = "$DADA_ID" ]; then
LUNS_PER_TARG=8
if [ $LOAD_UNLOAD_DRVS -eq 1 ]; then
log_print "Loading drivers now"
#
#	When using -i flag to specify an alias for a driver, should bracket
#	the alias with single then double-quote.  The alias (is usually a
#	PROM nodename) might start with a non-numeric character which would
#	cause add_drv to bark; so need to single-then-double-quote the aliases.
#	The shell removes the outer single quotes leaving the double-quotes

#	Add the ide nexus driver
safe_to_install ${DRV1}
if [ $? -eq 1 ]; then
${ADD_DRV} -i ${DRV1_ALIAS} ${DRV1} >> ${PKGLOGFILE} 2>&1 && log_print "Successfully added \"${DRV1}\" driver" || {
	#echo "\n${PKGINST}: Failed ${ADD_DRV} -m '${DRVPERM}' -i ${DRV1_ALIAS} ${DRV1}\n" >&2
	log_print "*\c"
	log_print "Failed adding driver module ${DRV1}"
#	exit 1
	}
# log_print "Successfully added \"${DRV1}\" driver"
# log_print "#\c"
else
#log_print ".\c"
log_print " \c"
fi
#	Add ata driver
safe_to_install ${DRV2}
if [ $? -eq 1 ]; then
${ADD_DRV} -i ${DRV2_ALIAS} -c ${DRV2_CLASS} ${DRV2} >> ${PKGLOGFILE} 2>&1 && log_print "Successfully added \"${DRV2}\" driver" || {
	#echo "\n${PKGINST}: Failed ${ADD_DRV} -m '${DRVPERM}' -i ${DRV2_ALIAS} ${DRV2}\n" >&2
	log_print "Failed adding driver module ${DRV2}"
	log_print "*\c"
#		exit 1
	}
# log_print "Successfully added \"${DRV2}\" driver"
# log_print "#\c"
else
#log_print ".\c"
log_print " \c"
fi

#	Add cmdk/dad driver
safe_to_install ${DRV3}
if [ $? -eq 1 ]; then
${ADD_DRV} -m "${DRVPERM}" -i ${DRV3_ALIAS}  ${DRV3} >> ${PKGLOGFILE} 2>&1 && log_print "Successfully added \"${DRV3}\" driver" || {
	#echo "\n${PKGINST}: Failed ${ADD_DRV} -m '${DRVPERM}' -i ${DRV3_ALIAS} ${DRV3}\n" >&2
	log_print "Failed adding driver module ${DRV3}"
	log_print "*\c"
#		exit 1
	}
# log_print "Successfully added \"${DRV3}\" driver"
# log_print "#\c"
else
# log_print ".\c"
log_print " \c"
fi

#	Add atapicd CDROM driver

if [ ${CDROM_DRV_PRE_27} -eq 1 ]; then
safe_to_install ${DRV4}
if [ $? -eq 1 ]; then
${ADD_DRV} -m "${DRVPERM}" -i ${DRV4_ALIAS} ${DRV4} >> ${PKGLOGFILE} 2>&1 && log_print "Successfully added \"${DRV4}\" driver" || {
	#echo "\n${PKGINST}: Failed ${ADD_DRV} -m '${DRVPERM}' ${DRV4}\n" >&2
	log_print "Failed adding driver module ${DRV4}"
	log_print "*\c"
#		exit 1
	}
# 
# log_print "Successfully added \"${DRV4}\" driver"
# log_print "#\c"
else
# log_print ".\c"
log_print " \c"
fi
else    # CDROM_DRV_PRE_27

# Before configuring the new driver, remove the old driver entry. This 
# will not effect the working of new driver but done just for the sake
# of having a clean system.
# This is getting messier yet hopefully is the last one..
${REM_DRV} ${DRV4} >> ${PKGLOGFILE} 2>&1
if [ $? -eq 0 ]; then
	log_print "Successfully removed ${DRV4} driver."
else
	log_print "Error removing${DRV4}."
fi

#if 2.7 sd driver is already configured as an alias. if not do it now.
grep ${CDROM_DRV_27} ${DRIVER_ALIASES} | grep ${DRV4_ALIAS} > /dev/null 2>&1
if [ ! $? -eq 0 ]; then
	log_print "Successfully added \"${CDROM_DRV_27}\" driver"
	echo "${CDROM_DRV_27} ${DRV4_ALIAS}" >> ${DRIVER_ALIASES}
else
	log_print "${CDROM_DRV_27} already configured for ${DRV4_ALIAS}."
fi

fi      # CDROM_DRV_PRE_27

fi      # LOAD_UNLOAD_DRVS

# get and store driver major numbers, we will need to know this
# to switch driver major numbers.
debug_print "drivers are added. Lets get major numbers now."
DISK_DRV=${DADA_DISK_DRV}
OLD_DISK_DRV=${CMDK_DISK_DRV}
get_drv_major_num $DISK_DRV
DISK_DRV_MAJ_NUM=$?
get_drv_major_num $OLD_DISK_DRV
OLD_DISK_DRV_MAJ_NUM=$?

else 	# if DEFAULT_DRV == DADA

if [ $SWITCH_DRV -eq 1 ]; then
	if [ $CMDK_INSTALLED -eq 0 ]; then
		echo "ERROR: CMDK drivers not installed. Cannot switch."
		exit 1
	fi
fi
LUNS_PER_TARG=64

# If switching over, please take care of the following cases.
# 1. Give the option to the user to upgrade even in case of a old OBP.
#    In this case, we will actually end up using different aliases
# 2. Give the option of rebooting automatically.

if [ $DADA_INSTALLED -eq 1 ]; then

	debug_print "drivers are to be removed. Lets get major numbers now."
	DISK_DRV=${CMDK_DISK_DRV}
	OLD_DISK_DRV=${DADA_DISK_DRV}
	get_drv_major_num $DISK_DRV
	DISK_DRV_MAJ_NUM=$?
	get_drv_major_num $OLD_DISK_DRV
	OLD_DISK_DRV_MAJ_NUM=$?

	if [ $LOAD_UNLOAD_DRVS -eq 1 ]; then
	log_print "removing drivers now \c"

#	Remove atapicd CDROM driver
	${REM_DRV} ${DRV4} >> ${PKGLOGFILE} 2>&1 && log_print "#\c" || {
		log_print "\n${PKGINST}: Failed ${REM_DRV} ${DRV4}\n" 
		log_print "*\c"
#		exit 1
	}

#	Remove cmdk driver
	${REM_DRV} ${DRV3} >> ${PKGLOGFILE} 2>&1 && log_print "#\c" || {
		log_print "\n${PKGINST}: Failed ${REM_DRV} ${DRV3}\n"
		log_print "*\c"
#		exit 1
	}

#	Remove ata driver
	${REM_DRV} ${DRV2} >> ${PKGLOGFILE} 2>&1 && log_print "#\c" || {
		log_print "\n${PKGINST}: Failed ${REM_DRV} ${DRV2}\n" 
		log_print "*\c"
#		exit 1
	}

#	Remove ide nexus (?) driver
	${REM_DRV} ${DRV1} >> ${PKGLOGFILE} 2>&1 && log_print "#\c" || {
		log_print "\n${PKGINST}: Failed ${REM_DRV} ${DRV1}\n"
		log_print "*\c"
#		exit 1
	}
	fi	# LOAD_UNLOAD_DRVS

fi	# DADA_INSTALLED
fi	# if DEFAULT_DRV == DADA

log_print ""

# SUNWide2 postinstall test script node creation logic.
#
# 1. For each entry in the /dev/[r]dsk
#   i. See what does this entry points to in /devices.
#  ii. Get the instance number of this device from /etc/path_to_inst.
# iii. Knowing the instance number and how many LUNs your driver supports 
#      per target, you can get
#      the minor number for your device node entry. You already have the major
#      number from /etc/name_to_major.
#			 

if [ $SWITCH_DRV -eq 1 -a $CREATE_DRV_NODES -eq 1 ]; then
	if [ "$DEFAULT_DRV" = "$DADA_ID" ]; then
		sleep 0
		# This will create /devices nodes as per the 
		# current configuration. Please note that the 
		# major numbers still could be different. 
		# make_all_nodes script will correct all that.
		# echo "Configuring Device nodes.." >> ${PKGLOGFILE} 2>&1
        	# drvconfig -r ${iroot} -i  ${DRV1} >> ${PKGLOGFILE} 2>&1
        	# drvconfig -r ${iroot} -i  ${DRV2} >> ${PKGLOGFILE} 2>&1
        	# drvconfig -r ${iroot} -i  ${DRV3} >> ${PKGLOGFILE} 2>&1
        	# drvconfig -r ${iroot} -i  ${DRV4} >> ${PKGLOGFILE} 2>&1
		# sleep 1
		# this creates the actual /dev/[r]dsk links.
		# echo "Configuring Device Links.." >> ${PKGLOGFILE} 2>&1
		# disks -r ${iroot} >> ${PKGLOGFILE} 2>&1

	fi


	if [ $SWITCH_DRV -eq 1 ]; then
	log_print "Checking node configuration.."

	debug_print "main(): Checking nodes for \"${DISK_DRV}\""
	if [ $DISK_DRV_MAJ_NUM -eq 0 -o $OLD_DISK_DRV_MAJ_NUM -eq 0 ]; then
		echo "main: Invalid Major number OR No major number for Disk driver disk_ata or cmdk."
		echo "Exitting."
		exit 1
	fi
	debug_print "main(): major number is ${DISK_DRV_MAJ_NUM}\n"

	egrep -s "^(${CMDK_DRV1}|${CMDK_DRV2}|${CMDK_DRV3})" ${NAME_TO_MAJOR} 2> /dev/null
	if [ $? -eq 0 ]; then
		debug_print "CMDK drivers installed. check node configuration"
	fi
	# Check and create any device nodes whose links already exist.
	cd ${DISK_BNODE_DIR} && NODE_TYPE="b" && make_all_nodes
	cd ${DISK_RNODE_DIR} && NODE_TYPE="c" && make_all_nodes

	verb_print "switch done. Please reboot(1M) your system at once."

	fi # SWITCH_DRV

fi	# if iroot = "/"

log_print "\nScript executed successfully."
exit 0


