#!/bin/sh
#
# Copyright (c) 2015-2016 by Cisco Systems, Inc.
# All rights reserved.
#
# This script runs on host and Calvados
# On Host it creates a ubifs type volume and device
# On Calvados it simply mounts this volume on /mnt/plog for obfl to use
#
# Check the onboard flashes.
# There are two MTD flashes
# 1. Bootflash 128MB on FC and SC 
# 2. OBFL 64MB on all the cards
# We use UBIFS on them. 
# Check if they have been formatted already. 
# If not, format them accordingly.
#
# mtdparts from /proc/cmdline
# FOR Fretta RP 
#mtdparts=physmap-flash.0:256k(SM_LOG),256k(RR_LOG),256k(KLOG),18m(PLOG),512k(mtdoops)
# FOR Pizza Box RPs and Fretta LC
#mtdparts=physmap-flash.0:256k(SM_LOG),256k(RR_LOG),256k(KLOG),18m(PLOG),512k(mtdoops),4m(shmoo)
# FOR SC AND FC
# mtdparts=physmap-flash.0:64m(bootflash);physmap-flash.1:256k(SM_LOG),256k(RR_LOG),18m(PLOG),256k(KLOG),1m(mtdoops),16m(KTRACES)
# /dev/mtd3 represents the OBFL PLOG
# /dev/mtd5 represents SHMOO 
#
# NOTE:!!!!
# Please check the cmdline param definition in the imaging file for the
# definition of mtdparts. This cmdline param will dictate the number of mtd
# devices we see and the sizes of it in kernel.
#
# After UBI formatting, 
# /dev/ubi3_0 will be /mnt/plog
# /dev/ubi5_0 will be /mnt/shmoo 

# import helpers
source /etc/init.d/spirit_pd.sh

PLOG_MTD_NUM=3
SHMOO_MTD_NUM=5
BOOTFLASH_MTD_NUM=0

check_mtd() {

    local mtdnum=$1
    local mtdname=$2
    local my_mtdname

    local mtddev="mtd${mtdnum}"

    if [ ! -e /sys/class/mtd/${mtddev} ]; then
        boot_debug "/dev/${mtddev} not found."
        exit -1
    fi

    my_mtdname=$(cat /sys/class/mtd/${mtddev}/name | tr '[:upper:]' '[:lower:]')

    if [ "$my_mtdname" != "$mtdname" ]; then
        boot_debug "/dev/${mtddev} $mtdname not found."
        exit -1
    fi
}


format_ubi_on_mtd() {

    local mtd_num=$1
    local vol_name=$2
    local dev_mtd="/dev/mtd${mtd_num}"
    local dev_ubi="/dev/ubi${mtd_num}"

    ubidetach -m ${mtd_num}

    # punch the watchdog
    pd_punch_watchdog

    # Send post code to indicate MTD device format has started
    pd_notify_host_mtd_format_started

    ubiformat ${dev_mtd} -y

    if [ $? -ne 0 ]; then
        boot_debug "UBI Formating of ${mtd_dev} failed with $?."
        # Send post code to indicate MTD device format has failed
        pd_notify_host_mtd_format_failed
        exit -1
    fi

    ubiattach -m ${mtd_num} -d ${mtd_num}

    # -m for use maximum size of the mtd for the volume
    ubimkvol ${dev_ubi} -N ${vol_name} -m

    if [ $? -ne 0 ]; then
        boot_debug "UBI Volume [${vol_name}] creation on ${dev_ubi} failed with $?."
        # Send post code to indicate MTD device volume creation has failed
        pd_notify_host_mtd_mkvol_failed
        exit -1
    fi

    # Send post code to indicate MTD device format and volume creation
    #  has ended
    pd_notify_host_mtd_format_ended
}

mount_ubifs() {

    local ret
    local UBI_PART=$1
    local MOUNT_DIR=$2

    # The mouting takes time if chk_fs is enabled
    # punch the watchdog
    pd_punch_watchdog

    mount /dev/${UBI_PART} ${MOUNT_DIR} -t ubifs

    ret=$?

    return $ret
}

check_flash() {

    local MTD_NUM=$1
    local MTD_NAME=$2
    local MOUNT_DIR=$3
    local UBI_PART="ubi${MTD_NUM}_0"
    local FORCE_FORMAT=$4

    check_mtd $MTD_NUM $MTD_NAME

    if [ -n "$FORCE_FORMAT" ]; then
        umount $MOUNT_DIR
        format_ubi_on_mtd ${MTD_NUM} ${MTD_NAME}
    fi

    ubiattach -m ${MTD_NUM} -d ${MTD_NUM}

    #ubi attach failed
    if [ ! -e /sys/class/ubi/${UBI_PART} ]; then
        format_ubi_on_mtd ${MTD_NUM} ${MTD_NAME}
    fi

    [ -e ${MOUNT_DIR} ] || mkdir ${MOUNT_DIR}
    mount_ubifs ${UBI_PART} ${MOUNT_DIR}

    # mount fails
    if [ $? -ne 0 ]; then
        # try format
        format_ubi_on_mtd ${MTD_NUM} ${MTD_NAME}

        #try mounting again
        mount_ubifs ${UBI_PART} ${MOUNT_DIR}
        if [ $? -ne 0 ]; then
            boot_debug "Mounting ${MOUNT_DIR} failed."
            exit -1
        fi
    fi
}

check_bad_files() {
    local mount_dir=$1

    # Check you can list the files.
    ls -R $mount_dir/ >/dev/null
    if [ $? -ne 0 ]; then
        # The filesystem looks bad
        echo "1"
        return

    fi

    # Check you can read all files.
    if [ -n "$(ls $mount_dir/)" ]; then
        for file in `ls $mount_dir`
        do
            if [ ! -f $mount_dir/$file ]; then
                continue
            fi
            cksum $mount_dir/$file > /dev/null
            if [ $? -ne 0 ]; then
                # The filesystem looks bad
                echo "1"
                return
            fi
        done
    fi

    # Check you can write a file
    touch $mount_dir/test_sanity
    echo "BADBEEF" > $mount_dir/test_sanity
    if [ $? -ne 0 ]; then
        # The filesystem looks bad
        echo "1"
    fi
    rm -rf $mount_dir/test_sanity
}

check_partition() {

    local name=$1
    
    local mtd_num=$2

    local force_format=$3

    check_flash $mtd_num $name /mnt/${name} $force_format
        
    if [ -n "$(check_bad_files /mnt/${name})" ]; then
        check_flash ${mtd_num} $name /mnt/${name} "force_format" 
        dmesg > /mnt/${name}/force_formatted
    else
        boot_debug "Partition /mnt/${name} looks good."
    fi
}

unmount_partition() {

    local name=$1

    mountpoint -q /mnt/${name}

    if [ $? == 0 ]; then
        umount /mnt/${name}
    fi
}

check_bootflash() {

    local force_format=$1

    check_flash ${BOOTFLASH_MTD_NUM} "bootflash" /mnt/bootflash $force_format
}


unprotect_flash() {
    local reg=0xe8000300
    local reg_val

    reg_val=$(/bin/iorw r $reg w|cut -d':' -f2|tr -d ' ')
    reg_val="0x$reg_val"
    reg_val=$((reg_val&0xffffffe7))
    reg_val=$(printf "0x%x" $reg_val)
    boot_debug "Unprotecting flash value $reg_val"
    /bin/iorw w $reg $reg_val w
}

enable_ubifs_fs_check() {
    echo 1 > /sys/kernel/debug/ubifs/chk_fs
}

main() {

    # mtd formatting takes sometime.
    # inform to SUP via SC One-Wire about our status,
    # to extend any normal boot timeouts.
    #send_ow_err_code ${CHECK_FLASH_BEGIN}

    boot_debug "Unprotecting flashes .."
    unprotect_flash

    # Enable ubifs fs check
    enable_ubifs_fs_check

    boot_debug "Checking plog partition"
    check_partition plog $PLOG_MTD_NUM
    unmount_partition plog


    pd_is_shmoo_partition_needed
    shmoo_needed=$? 

    if [ $shmoo_needed -eq 1 ];then
        boot_debug "Checking shmoo partition"
        check_partition shmoo $SHMOO_MTD_NUM
        unmount_partition shmoo
    fi

     #Enable bootflash when needed on FC and SC
     #boot_debug "Checking bootflash ..."
     #check_bootflash
    
     #Unmount /mnt/bootflash on host os    
     #mountpoint -q /mnt/bootflash
     #if [ $? == 0 ]; then
     #   umount /mnt/bootflash
     #fi

     #send_ow_err_code ${CHECK_FLASH_OK}

}

case "$1" in
    start)
        # Populate BOARDTYPE variable
        get_board_type

        VMTYPE=`cat /proc/cmdline | grep vmtype=`

        if [ -n "$VMTYPE" ]; then
            VMTYPE=`cat /proc/cmdline | sed 's/^.*vmtype=//' | cut -d" " -f1`
        fi

        if [ "$VMTYPE" == "hostos" ]; then
            if [ ! -e /sys/kernel/debug/ubifs ]; then
                modprobe ubifs
            fi
            main
        elif [ "$VMTYPE" == "sysadmin-vm" ];then
            mkdir -p /mnt/plog
            mount_ubifs "ubi${PLOG_MTD_NUM}_0" /mnt/plog
        elif [ "$VMTYPE" == "xr-vm" ] && [ "$BOARDTYPE" == "LC" ];then
            mkdir -p /mnt/shmoo
            mount_ubifs "ubi${SHMOO_MTD_NUM}_0" /mnt/shmoo
        fi
        ;;

    stop)
        ;;

    restart | reload | force-reload | status | condrestart | try-restart)
        ;;

    *)
        NAME=/etc/init.d/check-flash
        echo "Usage: $NAME {start}" >&2
        exit 1
        ;;
esac

exit 0
