#!/bin/sh

source ${CONF_DIR}/config;
source ${CONF_DIR}/devices;
source ${CONF_DIR}/helpers/functions;
source ${CONF_DIR}/dsx_version;

echo -ne "Invoking autoupdate script...........\n"

UPGRADE_DIRNAME=boot

UPGRADE_FILENAME_BOOTLOADER=nand-bootloader.bin
UPGRADE_FILENAME_KERNEL=nand-kernel.img
UPGRADE_FILENAME_INITRD=nand-initrd.img
UPGRADE_FILENAME_ROOTFS=nand-rootfs.tgz

UPGRADE_FLAG=upgrade.force

UPGRADE_BOOTLOADER="y";
UPGRADE_KERNEL="y";
UPGRADE_INITRD="y";
UPGRADE_ROOTFS="y";

UPGRADE_ROOTFS_TYPE="$(echo ${UPGRADE_FILENAME_ROOTFS} | sed -e 's/.*\.//')";

NEWPARTITIONS="768k(mboot1),3200k(kernel1),3200k(kernel2),2176k(initrd1),2176k(initrd2),72192k(rootfs),-(data)"


get_partitions()
{
	ALLOW_REPARTITION=$1

	local boot_mtddev=
	local root_mtddev=

	if [ "X${CFGDEVICES_BOOTDEV}" == "Xnand" ] || [ "X${CFGDEVICES_BOOTDEV}" == "Xnor" ]
	then
		boot_mtddev="true"
	fi
	if [ "X${CFGDEVICES_ROOTDEV}" == "Xnand" ] || [ "X${CFGDEVICES_ROOTDEV}" == "Xnor" ]
	then
		root_mtddev="true"
	fi

	REPARTITION=
	if [ -n "${boot_mtddev}" ] || [ -n "${root_mtddev}" ] 
	then
	    if [ $ALLOW_REPARTITION -eq 1 ]
	    then
		REPARTITION="y"
	    else
		REPARTITION="n"
	    fi

	    if [ "X${REPARTITION}" == "Xy" ] || [ "X${REPARTITION}" == "XY" ]
	    then
		REPARTITION="y"
		echo "New Partition: ${NEWPARTITIONS}"
		echo $NEWPARTITIONS |grep -sq '"'
		if [ $? -eq 0 ]
		then
		    echo $NEWPARTITIONS |grep -sq '^"'
		    if [ $? -eq 0 ]
		    then
			NEWPARTITIONS=`echo $NEWPARTITIONS | busybox cut -d'"' -f2`
		    else
			NEWPARTITIONS=`echo $NEWPARTITIONS | busybox cut -d'"' -f1`
		    fi
		fi
		if [ -n "${boot_mtddev}" ]
		then
		    BOOTDEV_MTDPARTS="${NEWPARTITIONS}"
		fi
		if [ -n "${root_mtddev}" ]
		then
		    ROOTDEV_MTDPARTS="${NEWPARTITIONS}"
		fi
	    else
		REPARTITION="n"
		if [ -n "${boot_mtddev}" ]
		then
		    BOOTDEV_MTDPARTS="${CFGDEVICES_BOOTDEV_MTDPARTS}"
		fi
		if [ -n "${root_mtddev}" ]
		then
		    ROOTDEV_MTDPARTS="${CFGDEVICES_ROOTDEV_MTDPARTS}"
		fi
	    fi
	fi
}

mount_nand_extra_partitions()
{

	i=0;
	OLD_IFS=${IFS};
	IFS=",";
	for part in ${CFGDEVICES_BOOTDEV_MTDPARTS}
	do
		name=$(echo ${part} | sed -e 's/[^\(]*[\(]\([^\)]*\)[\)].*/\1/')
		case ${name} in
			mboot*) 
				i=$((i+1))
				;;
			initrd*) 
				i=$((i+1))
				;;
			kernel*) 
				i=$((i+1))
				;;
			rootfs*) 
				i=$((i+1))
				;;
			*) break
				;;
		esac
	done

	# now mount any extra partitions
	if [ "X${CFGDEVICES_ROOTDEV_EXTRA_MTDPARTS}" != "X" ]
	then
		load_module mtdblock
	fi

	for part in ${CFGDEVICES_ROOTDEV_EXTRA_MTDPARTS}
	do
		MOUNTPOINT=`echo ${part}|busybox cut -d':' -f1`
		FSTYPE=`echo ${part}|busybox cut -d':' -f2`

		# skip raw partitions
		if [ "X${FSTYPE}" == "Xraw" ]
		then
			i=$((i+1));
			continue
		fi

		mount |grep -sq /dev/mtdblock${i}
		if [ $? -ne 0 ] 
		then
			if [ ! -d /${MOUNTPOINT} ]
			then
				mkdir -p /${MOUNTPOINT};
			fi
			busybox chmod 777 /${MOUNTPOINT}

			if [ ! -e /dev/mtdblock${i} ]
			then
				mknod /dev/mtdblock${i} b 31 ${i}
			fi
			mount -t ${FSTYPE} /dev/mtdblock${i} /${MOUNTPOINT}
			if [ $? -ne 0 ]
			then
				echo -ne "ERROR:  Failed to mount NAND partition /dev/mtdblock${i}\n"
				exit 41
			fi
		fi
		i=$((i+1));
	done
	IFS=${OLD_IFS};
}

nand_get_images()
{
	mount_nand_extra_partitions

	if [ "X${UPGRADE_BOOTLOADER}" == "Xy" ]; then
		echo -ne "Downloading new bootloader ... ";
		cp "/data/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_BOOTLOADER}" ${LOCAL_BOOTLOADER_FILENAME};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to copy /data/${UPGRADE_FILENAME_INITRD}.\n"
			exit 41;
		fi
		echo -ne "done.\n";
	fi
	if [ "X${UPGRADE_KERNEL}" == "Xy" ]; then
		echo -ne "Downloading new kernel ... ";
		cp "/data/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_KERNEL}" ${LOCAL_KERNEL_FILENAME};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to copy /data/${UPGRADE_FILENAME_KERNEL}.\n"
			exit 41;
		fi
		echo -ne "done.\n";
	fi
	if [ "X${UPGRADE_INITRD}" == "Xy" ]; then
		echo -ne "Downloading new initrd ... ";
		cp "/data/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_INITRD}" ${LOCAL_INITRD_FILENAME};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to copy /data/${UPGRADE_FILENAME_INITRD}.\n"
			exit 41;
		fi
		echo -ne "done.\n";
	fi
}

mount_usb_device()
{
	mount | grep -sq '/mnt type'
	if [ $? -ne 0 ]
	then
		mkdir /mnt
		load_module sd_mod
		load_module usb-storage
		load_module dwc_otg

		count=0
		while [ $count -le 30 ]
		do
			if [ -e /sys/block/sda ]
			then
				break
			else
				sleep 1
			fi
			count=$((count+1))
		done

		if [ ! -e /sys/block/sda ]
		then
			echo "ERROR:  USB device not found!\n"
			exit 40
		fi

		DEV=/dev/sda
		mknod ${DEV} b 8 0
		# just in case there are no partitions
		ID_FS_TYPE=$(/lib/udev/vol_id ${DEV} | grep ID_FS_TYPE | sed -e 's/ID_FS_TYPE=//')
		if [ "X$ID_FS_TYPE" == "X" ]
		then
			DEV=/dev/sda1
			mknod ${DEV} b 8 1
			ID_FS_TYPE=$(/lib/udev/vol_id ${DEV} | grep ID_FS_TYPE | sed -e 's/ID_FS_TYPE=//')
		fi
		if [ "X$ID_FS_TYPE" == "X" ]
		then
			echo -ne "ERROR:\nUnrecognized filesystem: $ID_FS_TYPE\n"
			exit 40;
		fi
		if [ "X$ID_FS_TYPE" != "Xjfs" ] && \
			[ "X$ID_FS_TYPE" != "Xxfs" ] && \
			[ "X$ID_FS_TYPE" != "Xvfat" ] && \
			[ "X$ID_FS_TYPE" != "Xext2" ] && \
			[ "X$ID_FS_TYPE" != "Xext3" ] 
		then
			echo -ne "ERROR:\nUnrecognized filesystem: $ID_FS_TYPE\n"
			exit 40;
		fi
		mount -t $ID_FS_TYPE ${DEV} /mnt
		if [ $? -ne 0 ]
		then
			echo -ne "ERROR:  Failed to mount NAND data partition\n"
			exit 41
		fi
	fi
}

#-------------------------------  Main Code --------------------------------

UPGRADE_MODE="usb"

VERSION_CURRENT=${DSX_VERSION_STR}

# allow re-partition (argument == 1)
get_partitions 1


# Now we create a tmpfs drive to download the boot images on it
mkdir /upgrade
mount none /upgrade -t tmpfs
if [ $? -ne 0 ]; then
	echo "ERROR: failed to allocate RAM drive to store the images."
	exit 20;
fi

# Now we download all the boot images
LOCAL_BOOTLOADER_FILENAME="/upgrade/bootloader.bin";
LOCAL_KERNEL_FILENAME="/upgrade/kernel.img";
LOCAL_INITRD_FILENAME="/upgrade/initrd.img";

# usb_get_images
mount_usb_device

source /mnt/${UPGRADE_DIRNAME}/dsx_version;
VERSION_UPGRADE=${DSX_VERSION_STR}

if [ -e /mnt/${UPGRADE_DIRNAME}/${UPGRADE_FLAG} ]; then
    echo -ne "firmware Force upgrade flag exist, ... removing the upgrade flag...\n"
    /bin/rm -fr /mnt/${UPGRADE_DIRNAME}/${UPGRADE_FLAG}
else
    echo -ne "${UPGRADE_FLAG} not found, continue to auto firmware update ...\n"
    echo -ne "\ncurrent version is: ${VERSION_CURRENT}\n"
    echo -ne "Upgrade version is: ${VERSION_UPGRADE}\n"
    if [ ${VERSION_CURRENT} = ${VERSION_UPGRADE} ]; then
	echo -ne "Upgrade aborted - current and upgrade version are the same\n"
	exit 0;
    fi
fi

echo -ne "Upgrading to version: ${VERSION_UPGRADE}\n"

echo -ne "Downloading new bootloader ... ";
cp "/mnt/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_BOOTLOADER}" ${LOCAL_BOOTLOADER_FILENAME};
if [ $? -ne 0 ]; then
    echo -ne "ERROR:\nFailed to copy /mnt/${UPGRADE_FILENAME_INITRD}.\n"
    exit 41;
fi
echo -ne "done.\n";

echo -ne "Downloading new kernel ... ";
cp "/mnt/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_KERNEL}" ${LOCAL_KERNEL_FILENAME};
if [ $? -ne 0 ]; then
    echo -ne "ERROR:\nFailed to copy /mnt/${UPGRADE_FILENAME_KERNEL}.\n"
    exit 41;
fi
echo -ne "done.\n";

if [ "X${UPGRADE_INITRD}" == "Xy" ]; then
    echo -ne "Downloading new initrd ... ";
    cp "/mnt/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_INITRD}" ${LOCAL_INITRD_FILENAME};
    if [ $? -ne 0 ]; then
	echo -ne "ERROR:\nFailed to copy /mnt/${UPGRADE_FILENAME_INITRD}.\n"
	exit 41;
    fi
    echo -ne "done.\n";
fi

# Load any required and missing module
echo -ne "Initializing access to the boot device ... ";
LOAD_MODULES="${LOAD_MODULES} nand aumb3000_nand";
BOOT_MTDDEV="aumb3000-nand";
WRBLOCKSIZE=$((CONFIG_NAND_PAGESIZE));

if [ -n "${BOOT_MTDDEV}" ]; then
    LOAD_MODULES="${LOAD_MODULES} mtdchar";
    if [ "X${BOOTDEV_MTDPARTS}" != "X" ]
    then
	load_module cmdlinepart "mtdparts=${BOOT_MTDDEV}:${BOOTDEV_MTDPARTS}"
    else
	load_module cmdlinepart
    fi
    if [ $? -ne 0 ]; then
	echo -ne "ERROR:\nFailed to load module cmdlinepart.\n";
	exit 61;
    fi
fi

for module in ${LOAD_MODULES}; do
    load_module ${module}
    if [ $? -ne 0 ]; then
	echo -ne "ERROR:\nFailed to load module ${module}.\n";
	exit 62;
    fi
done
echo -ne "done.\n"

# WARNING: we only support MTD devices for now
if [ -n "${BOOT_MTDDEV}" ]
then
    i=0;
    OLD_IFS=${IFS};
    IFS=",";
    
    # if repartitioning, lets erase all the non-core partitions here, this 
    # should allow any filesystem partitions to be mounted properly during 
    # bootup
    if [ "X${REPARTITION}" == "Xy" ] 
    then
	for part in ${BOOTDEV_MTDPARTS}
	do
	  name=$(echo ${part} | sed -e 's/[^\(]*[\(]\([^\)]*\)[\)].*/\1/')
	  case ${name} in
	      mboot*) 
		  i=$((i+1))
		  ;;
	      initrd*) 
		  i=$((i+1))
		  ;;
	      kernel*) 
		  i=$((i+1))
		  ;;
	      rootfs*) 
		  i=$((i+1))
		  ;;
	      *)  
		  mknod /dev/mtd$((i)) c 90 $((i*2));
		  if [ $? -ne 0 ]; then
		      echo -ne "ERROR: Failed to create access node to /dev/mtd$((i)).\n"
		      exit 70;
		  fi
		  echo  -ne "Erasing partition /dev/mtd$((i)) ... ";echo
		  flash_eraseall /dev/mtd$((i))
		  if [ $? -ne 0 ]; then
		      echo -ne "ERROR:\nFailed to erase /dev/mtd$((i)).\n"
		      exit 71;
		  fi
		  echo -ne "done.\n"
		  i=$((i+1))
		  ;;
	  esac
	done
    fi
    
    i=0;
    for part in ${BOOTDEV_MTDPARTS}; do
	name=$(echo ${part} | sed -e 's/[^\(]*[\(]\([^\)]*\)[\)].*/\1/');
	if [ -z "$(echo ${name} | sed -e 's/mboot[0-9]*//')" ] && [ "X${UPGRADE_BOOTLOADER}" == "Xy" ]
	then
	    type=bootloader;
	    file=${LOCAL_BOOTLOADER_FILENAME};
	elif [ -z "$(echo ${name} | sed -e 's/kernel[0-9]*//')" ] && [ "X${UPGRADE_KERNEL}" == "Xy" ]
	then
	    type=kernel;
	    file=${LOCAL_KERNEL_FILENAME};
	elif [ -z "$(echo ${name} | sed -e 's/initrd[0-9]*//')" ] && [ "X${UPGRADE_INITRD}" == "Xy" ]
	then
	    type=initrd;
	    file=${LOCAL_INITRD_FILENAME};
	else
	    i=$((i+1));
	    continue;
	fi
	
	mknod /dev/mtd$((i)) c 90 $((i*2));
	if [ $? -ne 0 ]; then
	    echo -ne "ERROR: Failed to create access node to /dev/mtd$((i)).\n"
	    exit 70;
	fi
	echo -ne "Erasing ${type} partition /dev/mtd$((i)) ... ";echo
	flash_eraseall /dev/mtd$((i))
	if [ $? -ne 0 ]; then
	    echo -ne "ERROR:\nFailed to erase /dev/mtd$((i)).\n"
	    exit 71;
	fi
	echo -ne "done.\n"
	echo -ne "Writing new ${type} into /dev/mtd$((i)) ... "
	if [ "X${CFGDEVICES_BOOTDEV}" == "Xnand" ]; then
	    nandwrite -p /dev/mtd$((i)) ${file}
	    if [ $? -ne 0 ]; then
		echo -ne "ERROR:\nFailed to copy ${file} on NAND device ${RAW_DEVICE}.\n"
		exit 150;
	    fi
	else
	    dd if=${file} of=/dev/mtd$((i)) bs=$((WRBLOCKSIZE)) conv=sync
	    if [ $? -ne 0 ]; then
		echo -ne "ERROR:\nFailed to copy ${file} to /dev/mtd$((i)).\n"
		exit 72;
	    fi
	fi
	echo -ne "done.\n"
	i=$((i+1));
    done
    IFS=${OLD_IFS};
fi
#	echo -ne "Cleanup all modules loaded ... "
#	for module in ${LOAD_MODULES}; do
#		/sbin/modprobe -r ${module};
#	done
rm /upgrade/*
echo -ne "done.\n"

# Last we update the root filesystem. We try to do that without
# storing anything on the device because the root filesystem
# may be too big
if [ "X${UPGRADE_ROOTFS}" == "Xy" ]
then

	if [ "X${UPGRADE_ROOTFS_TYPE}" == "Xtar" ]  ||  \
		[ "X${UPGRADE_ROOTFS_TYPE}" == "Xtgz" ] || \
		[ "X${UPGRADE_ROOTFS_TYPE}" == "Xgz" ]	|| \
		[ "X${UPGRADE_ROOTFS_TYPE}" == "Xbz2" ]
	then
		UPGRADE_ROOTFS_TYPE_TAR=1;
	# Otherwise we write directly to the device
	elif [ "X${UPGRADE_ROOTFS_TYPE}" == "Xbin" ] || [ "X${UPGRADE_ROOTFS_TYPE}" == "Ximg" ]; then
		UPGRADE_ROOTFS_TYPE_TAR=0;	
	else
		echo "ERROR: Unknown rootfs image type ${UPGRADE_ROOTFS_TYPE}.";
		exit 80
	fi
	# We initialize the root filesystem 
	# Load any required and missing module
	echo -ne "Initializing access to the root device ... ";
	LOAD_MODULES=
	if [ "X${CFGDEVICES_ROOTDEV}" == "Xnand" ]; then
		LOAD_MODULES="${LOAD_MODULES} nand aumb3000_nand";
		ROOT_MTDDEV="aumb3000-nand";
		WRBLOCKSIZE=$((CONFIG_NAND_PAGESIZE));
	elif [ "X${CFGDEVICES_ROOTDEV}" == "Xnor" ]; then
		LOAD_MODULES="${LOAD_MODULES} mhif mg3500_flash cfi_probe cfi_util cfi_cmdset_0001 cfi_cmdset_0002";
		ROOT_MTDDEV="physmap-flash";
		WRBLOCKSIZE=1;
	elif [ "X${CFGDEVICES_ROOTDEV}" == "Xnfs" ]; then
		ROOT_MTDDEV=;
		WRBLOCKSIZE=1;
		if [ $((UPGRADE_ROOTFS_TYPE_TAR)) -ne 0 ]; then
			echo "ERROR:\nYou cannot use an image when upgrading an NFS rootfs.\n";
			exit 81;
		fi
	else
		echo -ne "ERROR:\nUnsupported Root device.\n";
		exit 82;
	fi
	if [ -n "${ROOT_MTDDEV}" ]; then
		LOAD_MODULES="${LOAD_MODULES} mtdchar mtdblock";
		if [ "X${ROOTDEV_MTDPARTS}" != "X" ]
		then
			load_module cmdlinepart "mtdparts=${ROOT_MTDDEV}:${ROOTDEV_MTDPARTS}"
		else
			load_module cmdlinepart
		fi
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to load module cmdlinepart.\n";
			exit 83;
		fi
	fi
	if [ "X${CFGDEVICES_ROOTDEV_FS}" != "Xtmpfs" ]; then
		# tmpfs is compiled in the kernel
		LOAD_MODULES="${LOAD_MODULES} ${CFGDEVICES_ROOTDEV_FS}";	
	fi
	for module in ${LOAD_MODULES}; do
		load_module ${module};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to load module ${module}.\n";
			exit 84;
		fi
	done
	echo -ne "done.\n"
	# If we use a TAR file for the upgrade we 
	# format the root filesystem, then we mount it
	i=0;
	OLD_IFS=${IFS};
	IFS=",";
	for part in ${ROOTDEV_MTDPARTS}; do
		name=$(echo ${part} | sed -e 's/[^\(]*[\(]\([^\)]*\)[\)].*/\1/');
		if [ -z "$(echo ${name} | sed -e 's/rootfs//')" ]; then
			break;
		fi
		i=$((i+1));
	done
	IFS=${OLD_IFS};
	# Prepare the root filesystem to be mounted
	# For MTD devices that means erasing them, for most others
	# it means formatting the device
	MOUNT_DEVICE=;
	MOUNT_OPTIONS="-o defaults";
	if [ "X${CFGDEVICES_ROOTDEV}" == "Xnand" ] || [ "X${CFGDEVICES_ROOTDEV}" == "Xnor" ]; then
		RAW_DEVICE="/dev/mtd$((i))";
		mknod ${RAW_DEVICE} c 90 $((i*2));
		if [ $? -ne 0 ]; then
			echo -ne "ERROR: failed to create access node to /dev/mtd$((i)).\n"
			exit 90;
		fi
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to erase /dev/mtd$((i)).\n"
			exit 91;
		fi
		echo -ne "done.\n";
		if [ $((UPGRADE_ROOTFS_TYPE_TAR)) -ne 0 ]; then
			MOUNT_DEVICE="/dev/mtdblock$((i))";
			mknod ${MOUNT_DEVICE} b 31 $((i));
			if [ $? -ne 0 ]; then
				echo -ne "ERROR: failed to create access node to /dev/mtdblock$((i)).\n"
				exit 92;
			fi
		fi
	elif [ "X${CFGDEVICES_ROOTDEV}" == "Xnfs" ]; then
		MOUNT_DEVICE="${CONFIG_ROOTFS_NFS_PATH}";
		MOUNT_OPTIONS="${MOUNT_OPTIONS},nolock";
		if [ $((UPGRADE_ROOTFS_TYPE_TAR)) -eq 0 ]; then
			echo -ne "ERROR: You cannot upgrade an NFS root filesystem using a binary image.\n"
			exit 95;
		fi
	fi

echo -ne "\nupgrade_mode is: ${UPGRADE_MODE}\n"

	# Now comes the hard stuff, we must install the rootfs
	# image but avoid downloading it first. If we have
	# to download it we create a tmpfs and copy the 
	# file there.
	rm -f /upgrade/*
	if [ $((UPGRADE_ROOTFS_TYPE_TAR)) -ne 0 ]; then
		LOCAL_ROOTFS_IMAGE_FILENAME="/upgrade/rootfs.tgz";
	else
		LOCAL_ROOTFS_IMAGE_FILENAME="/upgrade/rootfs.bin";
	fi
	if [ "X${UPGRADE_MODE}" == "Xftp" ]; then
		OPTIONS="";
		if [ -n "${UPGRADE_USER_NAME}" ]; then
			OPTIONS="${OPTIONS} -u ${UPGRADE_USER_NAME}";
		fi
		if [ -n "${UPGRADE_USER_PASSWORD}" ]; then
			OPTIONS="${OPTIONS} -p ${UPGRADE_USER_PASSWORD}";
		fi
		echo -ne "Downloading new root filesystem ... ";
		ftpget ${OPTIONS} ${UPGRADE_SERVER} ${LOCAL_ROOTFS_IMAGE_FILENAME} ${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_ROOTFS};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to retrieve ${UPGRADE_FILENAME_ROOTFS} on ${UPGRADE_SERVER} using FTP.\n"
			exit 100;
		fi
		# Now the image is accessible
		echo -ne "done.\n";

	elif [ "X${UPGRADE_MODE}" == "Xhttp" ]; then
		echo -ne "Downloading new root filesystem ... ";
		wget http://${UPGRADE_SERVER}/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_ROOTFS} -O ${LOCAL_ROOTFS_IMAGE_FILENAME}
		if [ $? -ne 0 ]
		then
			echo -ne "ERROR:\nFailed to retrieve ${UPGRADE_FILENAME_ROOTFS} on ${UPGRADE_SERVER} using HTTP.\n"
			exit 100;
		fi
		# Now the image is accessible
		echo -ne "done.\n";

	elif [ "X${UPGRADE_MODE}" == "Xnfs" ]; then
		OPTIONS="-o defaults,ro,nolock";
		if [ ! -d /mnt ]; then
			mkdir /mnt
		fi
		mount "${UPGRADE_SERVER}:${UPGRADE_DIRNAME}" /mnt -t nfs ${OPTIONS};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to mount ${UPGRADE_SERVER}:${UPGRADE_DIRNAME} using NFS.\n"
			exit 110;
		fi
		LOCAL_ROOTFS_IMAGE_FILENAME=/mnt/${UPGRADE_FILENAME_ROOTFS};
	elif [ "X${UPGRADE_MODE}" == "Xcifs" ]; then
		OPTIONS="-o defaults,ro";
		if [ -n "${UPGRADE_USER_NAME}" ]; then
			OPTIONS="${OPTIONS},user=${UPGRADE_USER_NAME}";
		fi
		if [ -n "${UPGRADE_USER_PASSWORD}" ]; then
			OPTIONS="${OPTIONS},password=${UPGRADE_USER_PASSWORD}";
		else
			OPTIONS="${OPTIONS},guest";
		fi
		if [ ! -d /mnt ]; then
			mkdir /mnt
		fi
		mount "${UPGRADE_SERVER}:${UPGRADE_DIRNAME}" /mnt -t nfs ${OPTIONS};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to mount ${UPGRADE_SERVER}:${UPGRADE_DIRNAME} using NFS.\n"
			exit 120;
		fi
		LOCAL_ROOTFS_IMAGE_FILENAME=/mnt/${UPGRADE_FILENAME_ROOTFS};
	elif [ "X${UPGRADE_MODE}" == "Xuart" ]; then
		cd $(dirname ${LOCAL_ROOTFS_IMAGE_FILENAME});
		DONE=0;
		while [ $((DONE)) -eq 0 ]; do
			echo 
			echo "Device ready to receive data."
			echo "On the host side initiate the ZMODEM transaction"
			echo "for the following file:"
			echo $(basename ${LOCAL_ROOTFS_IMAGE_FILENAME});
			lrz --binary
			DONE=1;

			if [ ! -f ${LOCAL_ROOTFS_IMAGE_FILENAME} ] && [ -f *rootfs* ] 
			then
				mv *rootfs* $(basename ${LOCAL_ROOTFS_IMAGE_FILENAME})
			fi
			# Check the file are there
			if [ ! -f ${LOCAL_ROOTFS_IMAGE_FILENAME} ]; then
				echo "Missing $(basename ${LOCAL_ROOTFS_IMAGE_FILENAME})";
				DONE=0;
			fi
		done
		cd
	elif [ "X${UPGRADE_MODE}" == "Xnand" ]; then
echo -ne "\nupgrade_mode is nand\n"
		mount_nand_extra_partitions
		LOCAL_ROOTFS_IMAGE_FILENAME=/data/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_ROOTFS};
	elif [ "X${UPGRADE_MODE}" == "Xusb" ]; then
echo -ne "\nupgrade_mode is usb\n"
		mount_usb_device
		LOCAL_ROOTFS_IMAGE_FILENAME=/mnt/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_ROOTFS};
	fi

	if [ "X${CFGDEVICES_ROOTDEV}" == "Xnand" ] || [ "X${CFGDEVICES_ROOTDEV}" == "Xnor" ]
	then
		if [ -e ${LOCAL_ROOTFS_IMAGE_FILENAME} ]
		then
			echo -ne "Erasing root filesystem partition ... ";
			flash_eraseall ${RAW_DEVICE}
		else
			echo "rootFS file not found: ${LOCAL_ROOTFS_IMAGE_FILENAME}"
			exit 110
		fi
	fi

	if [ $((UPGRADE_ROOTFS_TYPE_TAR)) -ne 0 ]; then
		echo -ne "Mounting root filesystem ... ";
		if [ ! -d /rootfs ]; then
			mkdir /rootfs;
			if [ $? -ne 0 ]; then
				echo -ne "ERROR:\nFailed to create /rootfs directory.\n"
				exit 100;
			fi
		fi
		mount ${MOUNT_DEVICE} /rootfs -t ${CFGDEVICES_ROOTDEV_FS} ${MOUNT_OPTIONS};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to mount root filesystem.\n"
			exit 130;
		fi
		echo -ne "done.\n";
		# In NFS we now clean the root filesystem
		if [ "X${CFGDEVICES_ROOTDEV}" == "Xnfs" ]; then
			echo -ne "Cleaning root filesystem ... ";
			rm -rf /rootfs/*
			if [ $? -ne 0 ]; then
				echo -ne "ERROR:\nFailed to erase data on NFS rootfs.\n"
				exit 102;
			fi
			echo -ne "done.\n";
		fi
		# Extract the archive
		echo -ne "Installing new root filesystem ... ";
		if [ "X${UPGRADE_ROOTFS_TYPE}" == "Xgz" ] || [ "X${UPGRADE_ROOTFS_TYPE}" == "Xtgz" ]; then
			TAR='tar z';
		elif [ "X${UPGRADE_ROOTFS_TYPE}" == "Xbz2" ]; then
			TAR='tar j';
		else
			TAR='tar ';
		fi
		${TAR}xpf ${LOCAL_ROOTFS_IMAGE_FILENAME} -C /rootfs;
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to untar ${LOCAL_ROOTFS_IMAGE_FILENAME}.\n"
			exit 140;
		fi
		echo -ne "done.\n";
	else
		# Flash the image directly on the device
		# Use nandwrite for a NAND or dd otherwise
		if [ "X${CFGDEVICES_ROOTDEV}" == "Xnand" ]; then
			nandwrite -p ${RAW_DEVICE} ${LOCAL_ROOTFS_IMAGE_FILENAME};
			if [ $? -ne 0 ]; then
				echo -ne "ERROR:\nFailed to copy ${LOCAL_ROOTFS_IMAGE_FILENAME} on NAND device ${RAW_DEVICE}.\n"
				exit 150;
			fi
		else
			dd if=${LOCAL_ROOTFS_IMAGE_FILENAME} of=${RAW_DEVICE} bs=${CFGDEVICES_ROOTDEV_BLOCKSIZE};
			if [ $? -ne 0 ]; then
				echo -ne "ERROR:\nFailed to copy ${LOCAL_ROOTFS_IMAGE_FILENAME} on device ${RAW_DEVICE}.\n"
				exit 155;
			fi
		fi
	fi
	if [ $(mount | grep -c /rootfs) -ne 0 ]; then
		umount /rootfs;
		if [ $? -ne 0 ]; then
			echo -ne "WARNING:\nFailed to unmount /rootfs.\n"
		fi
	fi
	if [ $(mount | grep -c /mnt) -ne 0 ]; then
		umount /mnt;
		if [ $? -ne 0 ]; then
			echo -ne "WARNING:\nFailed to unmount /mnt.\n"
		fi
	fi
	if [ $(mount | grep -c /data) -ne 0 ]; then
		umount /data
		if [ $? -ne 0 ]; then
			echo -ne "WARNING:\nFailed to unmount /data.\n"
		fi
	fi
	rm -f /upgrade/*
# not all dependancies are being resolved by this unload
# however, is is really necessary to unload??
#echo -ne "Cleanup all modules loaded ... "
#	for module in ${LOAD_MODULES}; do
#		/sbin/modprobe -r ${module};
#	done
	echo -ne "done.\n"
fi

cd
umount /upgrade

if [ "X${UPGRADE_MODE}" == "Xftp" ] || \
	[ "X${UPGRADE_MODE}" == "Xcifs" ] || \
	[ "X${UPGRADE_MODE}" == "Xhttp" ] || \
	[ "X${UPGRADE_MODE}" == "Xnfs" ]
then
	echo -ne "Stopping network ... ";
	${HELPERS_DIR}/network stop;
	echo -ne "done.\n";
fi

if [ "X${UPGRADE_BOOTLOADER}" == "Xy" ] || [ "X${UPGRADE_KERNEL}" == "Xy" ] || [ "X${UPGRADE_INITRD}" == "Xy" ]; then
	echo "Rebooting the board to apply changes ... "
	# /sbin/reboot doesn't work here so we will just do what it eventually does  
	# also, want to play nice and make sure any mtdblock devices mounted are unmounted
	# can't do umount -a since we need /proc to do the reset
	mount |grep -sq mtdblock | \
	while read dev 
	do
		umount `echo $dev |cut -d" " -f1`
	done
	mount |grep -sq /mnt
	if [ $? -eq 0 ]
	then
		umount /mnt
	fi
	echo "0x8 0xC4 0x4 0x1" > /proc/driver/qcc/writebid
fi

exit 0;
