#!/bin/sh

# When a v3p1 root patch is applied to a system the drivers will not load
# until the kernel has been downgraded and the system rebooted. Note that
# /SpliceCom/kernel/upgrade_kernel gets overwritten in the root patch
# extraction, so the kernel downgrade functionality is provided here.

# Remove flash drivers on exit
trap "busybox.old rmmod flash >/dev/null 2>&1; busybox.old rmmod flashenv >/dev/null 2>&1" 0

flash=/dev/flash0

host=`platform`
case $host in
	CALLSERVER )
		nfile=/SpliceCom/loader/callserver-16M.nimg
		;;
	REMOTECS )
		nfile=/SpliceCom/loader/rcallserver-16M.nimg
		;;
	* )
		echo Unknown Host $host
		exit
		;;
esac

[ ! -r $nfile ] && exit

mv ${nfile} ${nfile}.done
nfile=${nfile}.done

nflash=/dev/nflash0
blksz=16896
maxbad=400
nandblks=1024
busybox.old lsmod | grep -q "^nflash"
if [ $? -ne 0 ]; then
	busybox.old insmod nflash
	if [ $? -ne 0 ]; then
		echo failed to load NAND flash driver
		exit
	fi
fi

if [ ! -w $nflash ]; then
	echo can\'t open $nflash
	exit
fi

len=`ls -l $nfile | cut -b33-43`
blks=`expr $len / $blksz`

# Check whether kernel change is needed ...
inblks=0
outblks=0
upg="n"

while [ $outblks -lt $blks ]; do
	ooboff=`expr $inblks '*' $blksz + 517`
	oob1=`dd if=$nfile bs=1 count=1 skip=$ooboff 2>/dev/null | od -tx1 | head -n 1 | cut -f 2 -d " "`
	ooboff=`expr $ooboff + 528`
	oob2=`dd if=$nfile bs=1 count=1 skip=$ooboff 2>/dev/null | od -tx1 | head -n 1 | cut -f 2 -d " "`
	if [ $oob1 = "ff" -a $oob2 = "ff" ]; then
		c1=`dd if=$nflash bs=$blksz count=1 skip=$inblks 2>/dev/null | cksum | cut -f 1 -d " "`
		c2=`dd if=$nfile bs=$blksz count=1 skip=$outblks 2>/dev/null | cksum | cut -f 1 -d " "`
		if [ $c1 != $c2 ]; then
			echo Mismatch at nand blk $inblks file blk $outblks
			dd if=$nflash bs=$blksz count=1 skip=$inblks of=/tmp/nblk 2>/dev/null
			dd if=$nfile bs=$blksz count=1 skip=$outblks of=/tmp/fblk 2>/dev/null
			cmp /tmp/nblk /tmp/fblk
			upg="y"
			break
		fi
		outblks=`expr $outblks + 1`
	else
		echo bad block $inblks
	fi
	inblks=`expr $inblks + 1`
done

if [ $upg = "y" ]; 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 $badblks encountered at $outblks - mark bad and skip
			echo Checksums: c1=$c1 c2=$c2
			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
			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
	fi

	# 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
	busybox.old rmmod flashenv
	rm -f $envdev
	mknod $envdev c 67 2
	busybox.old insmod /SpliceCom/loader/flashenv.ko rwe=1
	hexlen=`bash -c "printf %x $len;echo"`
	echo fsz0=$hexlen > $envdev
	echo fsz1=0 > $envdev
	busybox.old rmmod flashenv

	poweroff
	sleep 60
else
	echo Kernel in NAND flash is up to date.
fi

































