#!/bin/sh
retval=1
flash=/dev/flash0
flashmod=flash
chgnand=n
upg=y
force=n
doenv=n
if [ $# -gt 0 ]; then
	if [ $1 = "force" ]; then
		force=y
	fi
fi
host=`platform`
case $host in
	PCS100 )
		filen=pcs100.ldr
		flash=/dev/flash_raw
		chkbut=n
		;;
	PCS200 )
		filen=pcs200.ldr
		chkbut=n
		;;
	PCS400 )
		filen=pcs400.ldr
		chkbut=n
		flashmod=flashenv
		;;
	VCM )
		filen=vcm.ldr
		chkbut=y
		;;
	PHONE )
		filen=phone.ldr
		;;
	TRUNK )
		filen=trunk.ldr
		chkbut=y
		;;
	CALLSERVER )
		filen=callserver.ldr
		nfile=callserver-16M.nimg
		chgnand=y
		chkbut=y
		;;
	REMOTECS )
		filen=rcallserver.ldr
		nfile=rcallserver-16M.nimg
		chgnand=y
		chkbut=y
		;;
	* )
		echo Unknown Host $host
		exit $retval
		;;
esac

case `uname -r` in
	2.4.* ) modext=o;;
	2.6.* ) modext=ko;;
esac

echo Running upgrade for $host
echo '#####################################################################################'
echo Upgrade process will take some time, please be patient and do not power down the unit
echo '#####################################################################################'

rmmod $flashmod
if [ $host = "PCS100" ]; then
	insmod /lib/modules/`uname -r`/$flashmod.ko
	if [ $? -ne 0 ]; then
	    echo failed to load flash driver
		exit $retval
	fi
else
	lsmod | grep -q "^flash"
	if [ $? -ne 0 ]; then
		insmod ./${flashmod}.${modext} rwe=1
		if [ $? -ne 0 ]; then
			insmod ./${flashmod}.${modext}
			if [ $? -ne 0 ]; then
				echo failed to load flash driver
				exit $retval
			fi
		fi
	fi
fi
if [ ! -r $filen ]; then
	echo can\'t open $filen
	exit $retval
fi
if [ ! -w $flash ]; then
	echo can\'t open $flash
	exit $retval
fi
if [ chkbut = "y" ]; then
	if [ `cat /dev/button` -eq 1 ]; then
		echo Loader upgrade aborted due to button push
		exit $retval
	fi
fi

badfiletype=n
if [ $host = "PCS100" ]; then
	magic=`od -An -j32768 -N4 -td4 $filen`
	ftype=`od -An -j32772 -N4 -td4 $filen`
	frevn=`od -An -j32776 -N4 -td4 $filen`
	fbldn=`od -An -j32780 -N4 -td4 $filen`
	if [ $ftype != 1297370946 ]; then
		badfiletype=y
	fi
else
	magic=`od -An      -N4 -td4 $filen`
	ftype=`od -An -j4  -N4 -td4 $filen`
	frevn=`od -An -j8  -N4 -td4 $filen`
	fbldn=`od -An -j12 -N4 -td4 $filen`
	if [ $ftype != 1414483778 ]; then
		badfiletype=y
	fi
fi

if [ $magic != 1414807885 ]; then
	echo -e bad file magic for new loader \"$magic\"
else
	if [ badfiletype = "y" ]; then
		echo file type is not a loader
	else
		echo file: contains loader rev $frevn build $fbldn

		if [ $host = "PCS100" ]; then
			magic=`od -An -j32768 -N4 -td4 $flash`
			prevn=`od -An -j32776 -N4 -td4 $flash`
			pbldn=`od -An -j32780 -N4 -td4 $flash`
		else
			magic=`od -An      -N4 -td4 $flash`
			prevn=`od -An -j8  -N4 -td4 $flash`
			pbldn=`od -An -j12 -N4 -td4 $flash`
		fi

		if [ $magic != 1414807885 ]; then
			echo FLASH contains old style loader

			echo Upgrading loader
			if [ $host = "PCS100" ]; then
				# Do it in 2 bits to preserve the config sectors
				dd if=$filen of=$flash bs=1k count=16
				dd if=$filen of=$flash bs=1k count=224 \
					seek=32 skip=32 conv=notrunc
			else
				# Do it in 2 bits to preserve the MAC address sector
				dd if=$filen of=$flash bs=1k count=128
				dd if=$filen of=$flash bs=1k count=64 \
					seek=192 skip=192 conv=notrunc
			fi

			echo Done
			retval=0
		else
			echo FLASH contains loader rev $prevn build $pbldn
			doenv=y
			if [ $frevn -lt $prevn ]; then
				echo FLASH contents are newer than file \(use force to overwrite\)
				upg=n
			else
				if [ $frevn -eq $prevn ]; then
					if [ $fbldn -lt $pbldn ]; then
						echo FLASH contents are newer than file \(use force to overwrite\)
						upg=n
					else
						if [ $fbldn -eq $pbldn ]; then
							echo FLASH contents are the same as the file \(use force to overwrite\)
							upg=n
						fi
					fi
				fi
			fi

			if [ \( $upg = "y" \) -o \( $force = "y" \) ]; then
				echo Changing loader
				if [ $host = "PCS100" ]; then
					# Do it in 2 bits to preserve the config sectors
					dd if=$filen of=$flash bs=1k count=16
					dd if=$filen of=$flash bs=1k count=224 \
						seek=32 skip=32 conv=notrunc
				else
					# Do it in 3 bits to preserve the MAC address sector and config sectors
					# Someday we may no longer need to keep the MAC sector
					dd if=$filen of=$flash bs=1k count=16
					dd if=$filen of=$flash bs=1k count=96 \
						seek=32 skip=32 conv=notrunc
					dd if=$filen of=$flash bs=1k count=64 \
						seek=192 skip=192 conv=notrunc
				fi
				echo Done
				retval=0
			fi
		fi
	fi
fi

if [ $chgnand = "y" ]; then
	nflash=/dev/nflash0
	blksz=16896
	maxbad=400
	nandblks=1024
	lsmod | grep -q "^nflash"
	if [ $? -ne 0 ]; then
		insmod /lib/modules/`uname -r`/nflash.${modext}
		if [ $? -ne 0 ]; then
			echo failed to load NAND flash driver
			exit $retval
		fi
	fi
	if [ ! -r $nfile ]; then
		echo can\'t open $nfile
		exit $retval
	fi
	if [ ! -w $nflash ]; then
		echo can\'t open $nflash
		exit $retval
	fi
	len=`ls -l $nfile | cut -b33-43`
	blks=`expr $len / $blksz`

	tmp=`read_nf -d $nfile | cksum`
	nfilechk=`echo $tmp | cut -f 1 -d " "`
	nfilelen=`echo $tmp | cut -f 2 -d " "`
	nandchk=`read_nf -l $nfilelen | cksum | cut -f 1 -d " "`
	
	if [ $nfilechk != $nandchk ]; then
		echo Upgrading NAND Flash \($blks blocks\)
		inblks=0
		outblks=0
		badblks=0
		c1=`dd if=$nfile bs=$blksz count=1 skip=$inblks 2>/dev/null | cksum | cut -f 1 -d " "`
		while [ $inblks -lt $blks ]; do
			echo -n .
			dd if=$nfile of=$nflash bs=$blksz count=1 skip=$inblks seek=$outblks conv=notrunc 2>/dev/null
			c2=`dd if=$nflash bs=$blksz count=1 skip=$outblks 2>/dev/null | cksum | cut -f 1 -d " "`
			if [ $c1 = $c2 ]; then
				inblks=`expr $inblks + 1`
				c1=`dd if=$nfile bs=$blksz count=1 skip=$inblks 2>/dev/null | cksum | cut -f 1 -d " "`
			else
				badblks=`expr $badblks + 1`
				echo bad block encountered - mark bad and skip
				dd if=/dev/zero of=$nflash bs=$blksz count=1 seek=$outblks conv=notrunc 2>/dev/null
				if [ $badblks -gt $maxbad ]; then
					echo Very bad NAND - aborting
					exit $retval
				fi
			fi
			outblks=`expr $outblks + 1`
		done
		echo

		remblks=`expr $nandblks - $outblks`
		if [ $remblks -gt 0 ]; then
			echo clearing out the rest of NAND \($remblks blocks\)
			echo -n -e '\377' | dd of=$nflash bs=$blksz count=$remblks seek=$outblks conv=notrunc 2>/dev/null
			echo
		fi

		if [ $doenv = "y" ]; then
			# Need to set the u-boot environment variable for the kernel length or
			# u-boot will get a file CRC error.
			envdev=/dev/flash_env_single
			rmmod $flashmod
			rm -f $envdev
			mknod $envdev c 67 2
			insmod ./flashenv.${modext} rwe=1
			hexlen=`bash -c "printf %x $len;echo"`
			echo fsz0=$hexlen > $envdev
			echo fsz1=0 > $envdev
			rmmod flashenv
		fi

		retval=0
	else
		echo NAND Flash is up to date
	fi
fi

exit $retval
