#! /bin/ksh
# fix_prom - fix the prom in a specified location.
#
# SYNOPSIS
# --------
# 	'fix_prom' '-l' /location/ 
#
# DESCRIPTION
# -----------
# 'fix_prom' is the top level of a package which allows field support
# to upgrade the flash proms of cpusets in the field.
#
# The user must specify:
#
# 	the location - using the '-l' flag.
#
# The target cpuset must be either:
#	- powered off (but screwed in)
#	- online (ie part of the in sync set).
# The system must not be split.
#

# /* HIDE */
# ident @(#)xs_solaris/xs_solaris/FTutils/program_flash/fix_prom.sh	1.9 Last delta 98/01/29 (IMP Consett)
# Author: R.A.Littlewood.

DEFAULT_Y_NUMBER=7723.G

#
# error [-w] [-c] message ...
#
# print an error message.
# -w indicates that this is a warning message.
# -c indicates that this is a continuation message.
# 


error()
{
	if [ "$1" = "-c" ]
	then
		shift
		echo "	$*"
	elif [ "$1" = "-w" ]
	then
		shift
		echo "WARNING:	$*"
	else
		echo "ERROR:	$*"
	fi
}

#
# fatal_error return_val message ...
# 
# Print an error message and exit with the supplied return value.
#
fatal_error()
{
	RESULT=$1
	shift 
	error $*
	exit ${RESULT}
}

usage()
{
	echo "usage: fix_prom -l <location>"
}

#
# debug message ...
#
# Print a message (or not) depending on the value of the environment variable
# DEBUG
#

debug()
{
	if [ "${DEBUG}" ]
	then
		if [ "$1" = "-c" ]
		then
		    shift
		    echo "	$*"
		else
		    echo "DEBUG:	$*"
		fi
	fi
}



#
# Get the module number of a location, using moduleinfo.
# Return (via stdout) "0" if the module is not accessible.
#
get_mod_num()
{
	if moduleinfo -l ${1} >/dev/null 2>&1
	then
		moduleinfo -l ${1}|grep '^module number:'|sed 's/^module number:[ 	]*//'
	else	
		echo 0
	fi
}


#
# Check that the revision of module is appropriate to upgrade
#

no_can_upgrade()
{
	REVISION=`echo $1| sed 's/[0-9]*//g'`
	case ${REVISION} in
	[ABCDWXYZ])	return 1
			;;
	*)		return 0
			;;
	esac
}


#
# fix_variance - change variance to 98.
#

fix_variance()
{
	echo ${1}|sed 's/\([0-9]*[A-Z]*\)[0-9]*/\198/'
}

# 
# A cpuset is ok to flash if it is either powered off (if we get this far
# we have read the module info, so we know it is screwed in.
#

ok_to_flash()
{
	STATUS=`ftctl -d /dev/FTcpuset:ctl status $1`
	set -- ${STATUS}
	if [ "$3" = "powered_down" ]
	then
		echo "powered_down"
	elif [ "$1" = "online" ]
	then
		echo "online"
	else
		echo "not_ok"
	fi
}

LOCATION=
FORCE=no

#
# Deal with parameters.
#
opterr=0
while getopts o:n:fl:y:F: opt
do
	case  $opt in 
	f)	FORCE=yes
		;;
	l)	LOCATION=$OPTARG
		;;
	o)	OLD_MOD=$OPTARG
		;;
	y)	Y=${OPTARG}
		;;
	F)	FILE=$OPTARG
		;;
	esac
done


if [ ! "${LOCATION}" ] 
then
	fatal_error 1 "must specify location."
fi

if [ ! "${Y}" ]
then
	Y=${DEFAULT_Y_NUMBER}
fi

if [ ! "${FILE}" ]
then
    FILE=./y${Y}.prom
fi

# 
# Get the module number of the cpuset.
#

if [ ! "${OLD_MOD}" ]
then
	OLD_MOD=`get_mod_num ${LOCATION}`
fi
if [ ${OLD_MOD} = "0" ]
then
	fatal_error 1 "cant find the module number of the  cpuset in ${LOCATION}"
fi

if no_can_upgrade ${OLD_MOD}
then 
	fatal_error 1 "Your cpuset does not need upgrading."
fi

NEW_MOD=`fix_variance ${OLD_MOD}`

STATE=`ok_to_flash ${LOCATION}`

if [ ${STATE} = "not_ok" ]
then
	fatal_error 1 "the cpuset in ${LOCATION} must be either powered off or in sync before\nyou can program its flash."
fi


if [ ! -f "${FILE}" ]
then
	fatal_error 1 "the Y number y${Y} is not supported by this upgrade package."
fi

echo "This upgrade will change the module number from ${OLD_MOD} to ${NEW_MOD}."
./update_mod_num -c -p  ${LOCATION} ${OLD_MOD} ${NEW_MOD}
if [ $? -ne 0 -a "${FORCE}" != "yes" ]
then
	fatal_error 1 "module number check failed."
fi

if [ ${STATE} == "powered_down" ]
then
	./program_flash -c -p ${LOCATION} ${FILE}
else
	./program_flash -c -n -p ${LOCATION} ${FILE}
fi

RES=$?
if [ ${RES} -ne 0 ]
then
	if [ ${RES} -ne 2 ]
	then
	    fatal_error 1 "parameter check failed - ${LOCATION} might be an invalid cpuset location."
	fi
	exit 1
fi

#
# About to start work - so lock out keyboard interrupts
# 
trap ""	1 2 3 15 24
echo "Updating module number in ${LOCATION} from ${OLD_MOD} to ${NEW_MOD}"
./update_mod_num -p ${LOCATION} ${OLD_MOD} ${NEW_MOD}

echo "Programming flash on ${LOCATION}."
if [ ${STATE} = "powered_down" ]
then
	./program_flash -f -s /var/tmp/${OLD_MOD}.${LOCATION}.save -p ${LOCATION} ${FILE}
else 
	./program_flash -f -n -s /var/tmp/${OLD_MOD}.${LOCATION}.save -p ${LOCATION} ${FILE}
fi
if [ $? -ne 0 ]
then
	echo "failed to program flash in ${LOCATION}" 
	error -w "the cpuset is might be unusable."
	echo "Restoring module number to ${OLD_MOD} in ${LOCATION}."
	./update_mod_num -u ${LOCATION} ${NEW_MOD} ${OLD_MOD}
	if [ $? -ne 0 ]
	then
		error -w "failed to restore module number in ${LOCATION} after failure to program flash"
	fi
	exit 1
fi
trap 1 2 3 15 24
exit 0
