#!/bin/bash

#get work path
path=$(dirname "$0")
path="${path/\./$(pwd)}"
pwd="${path}"
mlnx_log_error_list=("failed to allocate command entry" "mlx5e_netdev_init failed, err" "Waiting for FW initialization, timeout abort in" "firmware CRC error")
smartsp_dmesg_path="/mnt/usb/spforbmc/spinfo/dmesg.log"

cd "${pwd}"
#init 
rm "${pwd}/result.xml" 2>/dev/null
rm "${pwd}/work.log" 2>/dev/null
tool_type=""
dev_num=0
flag_fail=0

#column for result.xml
result=""
errorCode=""
description=""

#create result.xml for esight
create_resultXml(){	
	echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>" >"${pwd}/result.xml"
	echo "<ConfigureResult>" >>"${pwd}/result.xml"
	echo "    <FwUpgrade>" >>"${pwd}/result.xml"
	echo "        <Result>${result}</Result>" >>"${pwd}/result.xml"
	echo "        <ErrorCode>${errorCode}</ErrorCode>" >>"${pwd}/result.xml"
	echo "        <Description>${description}</Description>" >>"${pwd}/result.xml"
	echo "    </FwUpgrade>" >>"${pwd}/result.xml"
	echo "</ConfigureResult>" >>"${pwd}/result.xml"
}

#read version xml
read_version_xml(){
	if [ ! -f "${pwd}/version.xml" ]
	then
		#version xml not found
		result="Fail"
		errorCode="5"
		description="Version xml not found"
		create_resultXml
		exit 5
	fi

	#get device info
	fw_file=$(cat "${pwd}/version.xml" |grep -i "<FileName>"|awk 'BEGIN{FS=">"}{print $2}'|awk 'BEGIN{FS="<"}{print $1}')
	cfg_fw_Version=$(cat "${pwd}/version.xml" |grep -i "<Version>"|awk 'BEGIN{FS=">"}{print $2}'|awk 'BEGIN{FS="<"}{print $1}')
	cfg_devices=$(cat "${pwd}/version.xml" |grep -i "<SupportModel>"|awk 'BEGIN{FS=">"}{print $2}'|awk 'BEGIN{FS="<"}{print $1}' |sed 's/;/ /g')
	upgrade_devices=$(cat "${pwd}/version.xml" |grep -i "<SupportModelUID>"|awk 'BEGIN{FS=">"}{print $2}'|awk 'BEGIN{FS="<"}{print $1}' |sed 's/;/ /g')
    
	for device in ${cfg_devices}
	do
		case ${device} in
			LSI2208|LSI3108|LSI3408|LSI3508)
				tool_type="mega"
			;;
			LSI2308)
				tool_type="LSI2308"
			;;
			LSI3008)
				tool_type="LSI3008"
			;;
			SM233|SM231|MU230|SM211|SM212|MU212|MU210|SP230|SP330|SP331|SP332|MZ310|MZ312|SP212|SP210|SP310|XL710|X722|X550)
				tool_type="Intel"
			;;
			MZ311|MZ610|MZ611|MZ612|MZ613|MZ710)
				tool_type="MellanoxCX3"
			;;
			HP380|SP333|SP380|MCX416A-BCAT|MCX4121A-ACUT|MZ620)
				tool_type="MellanoxCX4"
			;;
			HP382|SP350|SC382|SP351|SP382|MCX512A-ACAT|MCX512A-ACUT|MCX515A-CCAT|MCX515A-CCUT|MCX516A-CCAT)
				tool_type="MellanoxCX5"
			;;
			MCX653105A-EFAT)
				tool_type="MellanoxCX6"
			;;
			MX510)
				tool_type="Qlogic"
			;;
            MZ520|MZ522)
                tool_type="Qlogic_Huawei"
            ;;
			MZ910|MZ912|MZ220)
				tool_type="EmulexLancer"
			;;
			MZ510|MZ512)
				tool_type="EmulexBE3"
			;;
			SM210|MZ110)
				tool_type="BroadCom5719"
			;;
			MZ111)
				tool_type="BroadCom5720"
			;;						
			*)
				echo ${device} |grep -i "ES3" >/dev/null
				if [ $? == 0 ]
				then
					tool_type="ES3000"
				fi
				
				echo ${device} |grep -i "QLE" >/dev/null
				if [ $? == 0 ]
				then
					tool_type="Qlogic"
				fi
				
				echo ${device} |grep -i "LPe" >/dev/null
				if [ $? == 0 ]
				then
					tool_type="EmulexLancer"
				fi
				
				echo ${device} |grep -i "OCE" >/dev/null
				if [ $? == 0 ]
				then
					tool_type="EmulexBE3"
				fi
				
				echo ${device} |grep -i "MCX3" >/dev/null
				if [ $? == 0 ]
				then
					tool_type="MellanoxCX3"
				fi
				
				echo ${device} |grep -i "MCX4" >/dev/null
				if [ $? == 0 ]
				then
					tool_type="MellanoxCX4"
				fi
				
				echo ${device} |grep -i "MCX6" >/dev/null
				if [ $? == 0 ]
				then
					tool_type="MellanoxCX6"
				fi
				
				echo ${device} |egrep -i "WD|ST|MG|HUS|HUC|AL|SSD|Toshiba|Seagate|Hitachi|intel|HW" >/dev/null
				if [ $? == 0 ]
				then
					tool_type="HardDisk"
				fi
			;;
		esac
	done
	
	if [ "${tool_type}" == "" ]
	then
		#unsupport device type
		result="Fail"
		errorCode="7"
		description="Unsupport device type"
		create_resultXml
		exit 7;
	fi
}

#install tools
prepare_tools(){
	local tool_flag=0
	if [ -d "${pwd}/drivers/" ]
	then
		cd "${pwd}/drivers/"
		local rpms_list=ls |grep rpm
		for rpm_name in ${rpms_list}
		do
			rpm --test ./rpm_name 2>/dev/null
			if [ $? -eq 0]
			then
			#install drivers
			rpm -ivh --ignoresize ./rpm_name  >>"${pwd}/work.log" 2>/dev/null
			sleep 3
			fi
        done
	fi	
	
	# load i40e
	echo ${cfg_devices} | grep -i -E "XL710|X722|SP332" >/dev/null 2>&1
	if [ $? -eq 0 ]
	then	
        rmmod -f i40e >/dev/null 2>&1
        depmod
        modprobe i40e
        cat /etc/*-release | grep -i "SUSE" >/dev/null 2>&1
        if [ $? -eq 0 ]
        then
            cp -fr iqvlinux_suse.ko /lib/modules/3.0.76-0.11-default/kernel/drivers/net/iqvlinux.ko
            depmod
            modprobe iqvlinux --allow-unsupported
        fi
	cat /etc/*-release | grep -i "Euler" >/dev/null 2>&1
	if [ $? -eq 0 ]
	then
		cp -fr  iqvlinux_euler.ko /lib/modules/`uname -r`/kernel/drivers/net/iqvlinux.ko
		depmod
		modprobe iqvlinux
	fi
	
        fi
    
    # load qla2xxx
    echo ${cfg_devices} | grep -i -E "QLE2692|QLE2690" >/dev/null 2>&1
    if [ $? -eq 0 ]
    then    
        rmmod -f qla2xxx >/dev/null 2>&1
        depmod
        modprobe qla2xxx
    fi
    
    # load megaraid_sas
	echo ${cfg_devices} | grep -i -E "LSI3408|lSI3508" >/dev/null 2>&1
	if [ $? -eq 0 ]
	then	
		cat /sys/module/megaraid_sas/version >/dev/null
		if [ $? -ne 0 ]
		then
		rmmod -f megaraid_sas >/dev/null 2>&1
		depmod
		modprobe megaraid_sas
		fi
	fi
    
    #load nvme.ko
    echo ${cfg_devices} | grep -i "ES3">/dev/null 2>&1
    if [ $? -eq 0 ]
    then
        cd /lib/modules/`uname -r`/updates/hiodriver/ && insmod nvme.ko >/dev/null 2>&1
    fi
	
    if [ -d "${pwd}/tools/" ]
    then 
        cd "${pwd}/tools/"
        case ${tool_type} in
            mega)
                if [ -f "./storcli64" ]
                then
                    chmod u+x "./storcli64" 
                else 
                    tool_flag=1
                fi
            ;;
            LSI2308)
                if [ -f "./sas2flash" ] && [ -f "./sas2ircu" ]
                then
                    chmod u+x "./sas2flash" 
                    chmod u+x "./sas2ircu"
                else 
                    tool_flag=1
                fi
            ;;
            LSI3008)
                if [ -f "./sas3flash" ] && [ -f "./sas3ircu" ]
                then
                    chmod u+x "./sas3flash" 
                    chmod u+x "./sas3ircu"
                else 
                    tool_flag=1
                fi
            ;;
            Intel)
                if [ -f "./eeupdate64e" ]
                then
                    chmod u+x "./eeupdate64e" 
                else 
                    tool_flag=1
                fi
                
            ;;
            EmulexLancer|EmulexBE3)
                hbacmd >>"${pwd}/work.log" 2>/dev/null
                if [ $? == 127 ]
                then
                    if [ -f ./elxocmcore*.rpm ] && [ -f ./elxocmlibhbaapi*.rpm ]
                    then                     
                        rpm -ivh --ignoresize ./elxocmlibhbaapi*.rpm >>"${pwd}/work.log" 2>/dev/null
                        rpm -ivh --ignoresize ./elxocmcore*.rpm >>"${pwd}/work.log" 2>/dev/null
                    else
                        tool_flag=1
                    fi	
                    /etc/init.d/elxhbamgrd start >>"${pwd}/work.log" 2>/dev/null
                    /etc/init.d/elxmilid start >>"${pwd}/work.log" 2>/dev/null
                    /etc/init.d/elxsnmpd start >>"${pwd}/work.log" 2>/dev/null
                    sleep 1
                fi
            ;;
            Qlogic)
                /opt/QLogic_Corporation/QConvergeConsoleCLI/qaucli -h >>"${pwd}/work.log" 2>/dev/null
                if [ $? == 127 ]
                then
                    if [ -f ./QConvergeConsoleCLI*.rpm ]
                    then
                        rpm -ivh --ignoresize ./QConvergeConsoleCLI*.rpm >>"${pwd}/work.log" 2>/dev/null
                    else
                        tool_flag=1
                    fi
                fi
            ;;
            Qlogic_Huawei)
                if [ -f ./load.sh ]
                then
                    chmod u+x *
                    cp -fr * ../
                else
                    tool_flag=1
                fi
            ;;
            ES3000)
                hioadm >>"${pwd}/work.log" 2>/dev/null
                if [ $? == 127 ]
                then
                    if [ -f ./hioadm*.rpm ] && [ -f ./irqbalance*.rpm ]
                    then                       
                        rpm -ivh --ignoresize ./irqbalance*.rpm >>"${pwd}/work.log" 2>/dev/null
                        rpm -ivh --ignoresize ./hioadm*.rpm >>"${pwd}/work.log" 2>/dev/null
                    else
                        tool_flag=1
                    fi
                fi
            ;;
            MellanoxCX3|MellanoxCX4|MellanoxCX5|MellanoxCX6)
                #insmod drivers
				cat /etc/*-release | grep -i "SUSE" >/dev/null 2>&1
				if [ $? -eq 0 ]
				then
					insmod "${pwd}/drivers/suse11-3_3.0.76-0.11-default/mst_pci_suse.ko"  >>"${pwd}/work.log" 2>/dev/null
					insmod "${pwd}/drivers/suse11-3_3.0.76-0.11-default/mst_pciconf_suse.ko"  >>"${pwd}/work.log" 2>/dev/null
					sleep 3
				fi
				
                cat /etc/*-release | grep -i "EulerOS 2.0 (SP3)" >/dev/null 2>&1
				if [ $? -eq 0 ]
				then
					insmod "${pwd}/drivers/centos7-3_3.10.0-514.41.4.28.h70.x86_64/mst_pci_euler.ko"  >>"${pwd}/work.log" 2>/dev/null
					insmod "${pwd}/drivers/centos7-3_3.10.0-514.41.4.28.h70.x86_64/mst_pciconf_euler.ko"  >>"${pwd}/work.log" 2>/dev/null
					sleep 3
				fi
				 cat /etc/*-release | grep -i "EulerOS 2.0 (SP8)" >/dev/null 2>&1
				if [ $? -eq 0 ]
				then
					insmod "${pwd}/drivers/centos7-8_4.19.36_1906.1.0.h288/mst_pci.ko"  >>"${pwd}/work.log" 2>/dev/null
					insmod "${pwd}/drivers/centos7-8_4.19.36_1906.1.0.h288/mst_pciconf.ko"  >>"${pwd}/work.log" 2>/dev/null
					sleep 3
				fi
				
                if [ $? == 127 ]
                then                   
                    if [ -d "${pwd}/tools/" ]
                    then                                   
                        cp "${pwd}/tools/flint* /usr/bin" >>"${pwd}/work.log" 2>/dev/null					                      
                    else
                        tool_flag=1
                    fi
                fi
                flint -version >>"${pwd}/work.log" 2>/dev/null
            ;;
            HardDisk)
                if [ -f ./disktool ]
                then
                    chmod u+x "${pwd}/tools/disktool"
                else 
                    tool_flag=1
                fi
                
                if [ -f ./storcli64 ]
                then
                    chmod u+x "${pwd}/tools/storcli64"
                else 
                    tool_flag=1
                fi
                
                if [  -f ./huawei-ISM-server-management*.tar.gz ]
                then
                    tar -xvf ./huawei-ISM-server-management-5.2.3.tar.gz -C "${pwd}/tools/"  >/dev/null
                    cd "${pwd}/tools/huawei-ISM-server-management-5.2.3/"
                    ln -s /usr/lib64/libssl.so.0.9.8 /usr/lib64/libssl.so.1.0.0 >/dev/null 2>/dev/null
                    chmod u+x -R *
                    sed -i "s/rpm -ivh/rpm -ivh --ignoresize/g" "${pwd}/tools/huawei-ISM-server-management-5.2.3/SLES11/install.sh" 2>/dev/null
                    "${pwd}/tools/huawei-ISM-server-management-5.2.3/setup.sh" install monitor=no snmp=no >/dev/null 2>/dev/null
                    cd "${pwd}/"
                else 
                    tool_flag=1
                fi
            ;;
            BroadCom5719|BroadCom5720)
                if [ -f "${pwd}/tools/runDiag" ] && [ -f "${pwd}/tools/tg3d.ko" ] && [ -f "${pwd}/tools/b57ldiagi64" ]
                then
                    chmod u+x "${pwd}/tools/runDiag" 
                    chmod u+x "${pwd}/tools/b57ldiagi64"
                else 
                    tool_flag=1
                fi
            ;;
            *)
            ;;
        esac
    else
        tool_flag=1
    fi
	
	cd "${pwd}/"
	if [ ${tool_flag} == 1 ]
	then
		#prepare tools failed
		result="Fail"
		errorCode="6"
		description="Prepare tools failed"
		create_resultXml
		exit 6;
	fi
}

#check card with no SVID:SDID
function check_card_pcie(){
	result=`ls -l /sys/bus/pci/devices/$1`
	result_list=($(tr "/" " " <<< $result))
    local len=${#result_list[*]}
	root_bdf=${result_list[${len}-2]}
	echo ${root_bdf}
}

function checkislom() 
{
    local check_root_port=$1
    local check_device_port=$2     
    local tmpfile=$((mktemp))
    
    dmidecode  -u  -t 9 | grep -A 1  '^[[:blank:]]*09' > ${tmpfile}
    sed -i '/^--/d' ${tmpfile}
    sed -i 'N;s/\n//' ${tmpfile}
    
    eval $(awk -F " "  'BEGIN{ domain1[0]=0;domain2[0]=0;bus[0]=0;devfun[0]=0 } {if(NR>=1) {printf "domain1[%d]=%s; domain2[%d]=%s; bus[%d]=%s; devfun[%d]=%s;\n",NR-1,$14,NR-1,$15,NR-1,$16,NR-1,$17}}' ${tmpfile})
    rm -rf ${tmpfile} &2> /dev/null
    
    local root_port_num=${#domain1[*]}
    local rootport=(0)
    local devicebdf=(0)
    local count=0
    
    while ((${count} < ${root_port_num}))
    do
        devnum=$((16#${devfun[$count]}))
        funnum=${devnum}
        devnum=$(((${devnum}&0xF8)>>3))
        funnum=$((${funnum}&0x3))
        rootport[${count}]=$(printf "%s%s:%s:%02x.%x" ${domain1[${count}]}  ${domain2[${count}]} ${bus[${count}]} ${devnum} ${funnum})        
        devicebdf[${count}]=$(printf "%s%s:%s:%02x" ${domain1[${count}]}  ${domain2[${count}]} ${bus[${count}]} ${devnum})    
            
        count=$((${count}+1))   
    done
    
    count=0
    root_port_num=${#rootport[*]}
    while  ((${count} < ${root_port_num}))
    do
        if [ ${check_root_port} = ${rootport[${count}]} ]
        then 
        {
           return  0
        }
        fi
        
        if [ ${check_device_port} = ${devicebdf[${count}]} ]
        then
        {           
            return  0
        }
        fi
        count=$((${count}+1))  
    done
    
    return 1

}

function get_i350_portnum()
{
    local device_bd=$1    
    local fun_num=0 
    
    if [ "${device_bd}" = "" ]
    then 
    {
        return 0
    }
    fi    
    fun_num=$( lspci -s ${device_bd}|wc -l )
    return ${fun_num}

}

function get_i350_type()
{
    local  device_root_port=$1
    local  device_bd=$2
    local  islom_card=0
    local  portnum=0
    local  card_type="error"
    local  return_value=1
    if [ "${device_bd}" = "" ] || [ "${device_root_port}" = "" ]
    then 
        echo ${card_type}
        return ${return_value}
    fi
  
    checkislom ${device_root_port}  ${device_bd} > /dev/null
    islom_card=$?    
    
    get_i350_portnum ${device_bd} > /dev/null
    portnum=$?    
   
    if  [ ${islom_card} = 0 ]
    then 
        case   ${portnum}  in
        2):
        #pcieCard 2 port
            card_type="SP210"
            return_value=0
        ;;
        4):
        #pcieCard 4 port
            card_type="SP212"   
            return_value=0
        ;;        
        esac       
    else
        case  ${portnum}  in
        2):
         #LOM 2 port
            card_type="SM211"
            return_value=0
        ;;
        4):
        #LOM 4 port
            card_type="SM212"  
            return_value=0
        ;;
        esac        
    fi
    echo ${card_type}
    return ${return_value}

}

#get device info by tools
get_device_info(){
	case ${tool_type} in
		mega)
			get_device_mega
		;;
		LSI2308)
			get_device_2308
		;;
		LSI3008)
			get_device_3008
		;;
		Intel)
			get_device_intel
		;;
		ES3000)
			get_device_ES3000
		;;
		MellanoxCX3|MellanoxCX4|MellanoxCX5|MellanoxCX6)
			get_device_Mellanox
			#check mellanox card in dmesg status is abnormal
			check_dmesg_mellanox_card_status ${select_BDFs}
		;;
		EmulexLancer|EmulexBE3)
			get_device_Emulex
		;;
		Qlogic)
			get_device_Qlogic
		;;
        Qlogic_Huawei)
			get_device_Qlogic_Hw
		;;
		HardDisk)
			get_device_HardDisk
		;;
		BroadCom5719|BroadCom5720)
			get_device_BroadCom
		;;
		*)
		;;
	esac
	
	#no device found in version.xml
	if [ ${dev_num} == 0 ]
	then
		result="Fail"
		errorCode="4"
		description="No available device found"
		create_resultXml
		exit 4;
	fi
}

#get 2208/3108/3408/3508 device
get_device_mega(){
	local num_mega=$("${pwd}/tools/storcli64" show ctrlcount |grep -i "Controller Count" |awk 'BEGIN{FS=" "}{print $4}')
		
	for ((i=0; i<num_mega; i++))
	do
		"${pwd}/tools/storcli64" /c$i show all >tmp_raid.txt 2>/dev/null
		#get base info
		vendor_id=$(cat tmp_raid.txt |grep -i "^Vendor Id" |awk '{print $4}')
		device_id=$(cat tmp_raid.txt |grep -i "^Device Id" |awk '{print $4}')
		sub_vid=$(cat tmp_raid.txt |grep -i "SubVendor Id" |awk '{print $4}')
		sub_did=$(cat tmp_raid.txt |grep -i "SubDevice Id" |awk '{print $4}')		
		
		device_id_front=$(echo ${device_id} |cut -c 1-2 )
		device_id_end=$(echo ${device_id} |cut -c 3-4 )
		#check device
		cat version.xml |grep -i "${vendor_id}" |grep -i "${device_id_front}00${device_id_end}" |grep -i "${sub_vid}" |grep -i "${sub_did}" >/dev/null
		if [ $? != 0 ]
		then	
			rm tmp_raid.txt 2>/dev/null
			continue
		fi
		
		bus_num[$dev_num]=$(cat tmp_raid.txt |grep -i "Bus Number" |awk 'BEGIN{FS=" "}{print $4}')
		device_num[$dev_num]=$(cat tmp_raid.txt |grep -i "Device Number" |awk 'BEGIN{FS=" "}{print $4}')
		function_num[$dev_num]=$(cat tmp_raid.txt |grep -i "Function Number" |awk 'BEGIN{FS=" "}{print $4}')
		cur_fw[$dev_num]=$(cat tmp_raid.txt |grep -i "Firmware Version" |awk 'BEGIN{FS=" "}{print $4}')
		device_index[$dev_num]=$i
		rm tmp_raid.txt 2>/dev/null
		
		#init BDF flag
		BDF_select[$dev_num]=0		
		let dev_num=$dev_num+1
	done
}

#get 2308 device
get_device_2308(){
	local num_2308=$("${pwd}/tools/sas2ircu" list |grep -i "2308" |wc -l)

	for ((i=0; i<num_2308; i++))
	do		
		bus_num[$dev_num]=$("${pwd}/tools/sas2ircu" $i display |grep -i "Bus" |awk 'BEGIN{FS=" "}{print $3}')
		device_num[$dev_num]=$("${pwd}/tools/sas2ircu" $i display |grep -i "Device  " |awk 'BEGIN{FS=" "}{print $3}')
		function_num[$dev_num]=$("${pwd}/tools/sas2ircu" $i display |grep -i "Function" |awk 'BEGIN{FS=" "}{print $3}')
		cur_fw[$dev_num]=$("${pwd}/tools/sas2flash" -c $i -list |grep -i "Firmware Version" |awk 'BEGIN{FS=" "}{print $4}')
		device_index[$dev_num]=$i
		
		#init BDF flag
		BDF_select[$dev_num]=0
		
		let dev_num=$dev_num+1
	done
}

#get 3008 device
get_device_3008(){
	local num_3008=$("${pwd}/tools/sas3ircu" list |grep -i "3008" |wc -l)

	for ((i=0; i<num_3008; i++))
	do
		bus_num[$dev_num]=$("${pwd}/tools/sas3ircu" $i display |grep -i "Bus" |awk 'BEGIN{FS=" "}{print $3}')
		device_num[$dev_num]=$("${pwd}/tools/sas3ircu" $i display |grep -i "Device  " |awk 'BEGIN{FS=" "}{print $3}')
		function_num[$dev_num]=$("${pwd}/tools/sas3ircu" $i display |grep -i "Function" |awk 'BEGIN{FS=" "}{print $3}')
		cur_fw[$dev_num]=$("${pwd}/tools/sas3flash" -c $i -list |grep -i "Firmware Version" |awk 'BEGIN{FS=" "}{print $4}')
		device_index[$dev_num]=$i
		
		#init BDF flag
		BDF_select[$dev_num]=0
		
		let dev_num=$dev_num+1
	done
}

#get device of intel 
get_device_intel(){
	"${pwd}/tools/eeupdate64e" >tmp_intel.txt
	local num_intel=$(cat tmp_intel.txt |grep "^ " |wc -l)

	for ((i=1; i<=num_intel; i++))
	do
		device_index[$dev_num]=$(cat tmp_intel.txt |grep "^ " |sed -n ''$i'p' |awk 'BEGIN{FS=" "}{print $1}')
		"${pwd}/tools/eeupdate64e" /NIC=${device_index[$dev_num]} /PCIINFO >tmp_device.txt 2>/dev/null
		
		#get base info
		vendor_id=$(cat tmp_device.txt |tail -n 2 |head -n 1 |awk '{print $5}'|awk 'BEGIN{FS="-"}{print $1}')
		device_id=$(cat tmp_device.txt |tail -n 2 |head -n 1 |awk '{print $5}'|awk 'BEGIN{FS="-"}{print $2}')
		sub_vid=$(cat tmp_device.txt |tail -n 2 |head -n 1 |awk '{print $6}'|awk 'BEGIN{FS="-"}{print $1}')
		sub_did=$(cat tmp_device.txt |tail -n 2 |head -n 1 |awk '{print $6}'|awk 'BEGIN{FS="-"}{print $2}')
		
		rm tmp_device.txt 2>/dev/null
		#check device
		cat version.xml |grep -i "${vendor_id}" |grep -i "${device_id}" |grep -i "${sub_vid}" |grep -i "${sub_did}" >/dev/null
		if [ $? != 0 ]
		then	
			continue
		fi		
		
		bus_num[$dev_num]=$(cat tmp_intel.txt |grep "^ " |sed -n ''$i'p' |awk 'BEGIN{FS=" "}{print $2}')
		device_num[$dev_num]=$(cat tmp_intel.txt |grep "^ " |sed -n ''$i'p' |awk 'BEGIN{FS=" "}{print $3}')
		function_num[$dev_num]=$(cat tmp_intel.txt |grep "^ " |sed -n ''$i'p'  |awk 'BEGIN{FS=" "}{print $4}')
		
		#check card with SDID:SVID=FFFF:0000
		local vendor="8086"
		local device="1521"
		local sub_vender="FFFF"
		local sub_device="0000"
		
		#get PCIe
		if [ ${function_num[$dev_num]:0:1} = "0" ]
		then 
			function_data=${function_num[$dev_num]:1:2}
		else
			function_data=${function_num[$dev_num]}
		fi
		
		local pcie=$(printf "%s:%02x:%s.%s" "0000" ${bus_num[$dev_num]} "${device_num[$dev_num]}" "${function_data}")		
		#get PCIe with no function_num
		local pcie_noFun=$(printf "%s:%02x:%s" "0000" ${bus_num[$dev_num]} "${device_num[$dev_num]}")				
			
		if [ "${vendor_id}" = "$vendor" ] && [ "${device_id}" = "$device" ] && [ "${sub_vid}" = "$sub_vender" ] && [ "${sub_did}" = "$sub_device" ]
		then			
            result=$(check_card_pcie ${pcie})			
			card_type=$(get_i350_type ${result} ${pcie_noFun})
			card_num=$(echo ${cfg_devices} | grep "${card_type}" | wc -l)
			if [ ${card_num} = 0 ]
			then
				continue
			fi
		fi
		
		"${pwd}/tools/eeupdate64e" /NIC=${device_index[$dev_num]} /ADAPTERINFO >tmp_intel_FW.txt
		cur_fw[$dev_num]="$(cat tmp_intel_FW.txt |grep -i 'NVM Version' |awk 'BEGIN{FS=" "}{print $3}'),$(cat tmp_intel_FW.txt |grep -i 'EtrackID' |awk 'BEGIN{FS=" "}{print $2}')"
		rm tmp_intel_FW.txt 2>/dev/null
		
		#init BDF flag
		BDF_select[$dev_num]=0		
		let dev_num=$dev_num+1
	done
	
	rm tmp_intel.txt
}

#get device of intel 
get_device_ES3000(){
	hioadm info >>work.log 2>/dev/null
	if [ $? != 0 ]
	then
		return
	fi	

	num_ES3000=$(hioadm info |grep -i " nvme" |grep -v "^ " |wc -l)
	
	#set base info for ES3000
	for ((i=1;i<=num_ES3000;i++))
	do
		device_index[$dev_num]=$(hioadm info |grep -i " nvme" |grep -v "^ " |sed -n ''$i'p' |awk 'BEGIN{FS=" "}{print $2}')
		cur_fw[$dev_num]=$(hioadm info -d ${device_index[$index]} |grep -i "firmware version" |awk 'BEGIN{FS=" "}{print $3}')
		
		#init BDF flag
		BDF_select[$dev_num]=0		
		let dev_num=$dev_num+1
	done
}

#get device of Mellanox 
get_device_Mellanox(){
	lspci |grep Mellanox >>work.log 2>/dev/null
	if [ $? != 0 ]
	then
		return
	fi	
	
	local num_Mellanox=$(lspci | grep Mellanox | grep "\.0" |wc -l)
	cp tools/flint* /usr/bin
	chmod u+x /usr/bin/flint*
	lspci | grep Mellanox | grep "\.0" >total_info_Mellanox.txt
	local fw_dev=0
	local num_index=0	
	for ((i=1;i<=num_Mellanox;i++))
	do
	    
		device_index[$dev_num]=$(awk 'NR==1' total_info_Mellanox.txt |awk 'BEGIN{FS=" "}{print $1}')
		#delete first line of total_info_Mellanox.txt
		sed -i '1d' total_info_Mellanox.txt
		
		local temp_bdf="${device_index[$dev_num]}"
		bus_num[$dev_num]=${temp_bdf:0:2}
		device_num[$dev_num]=${temp_bdf:3:2}
		function_num[$dev_num]=${temp_bdf:6:1}
		
		#get base info
		lspci -s "${device_index[$dev_num]}" -xx >base_info_Mellanox.txt
		vendor_id=$(sed -n '2p' base_info_Mellanox.txt |awk 'BEGIN{FS=" "}{print $3}')$(sed -n '2p' base_info_Mellanox.txt |awk 'BEGIN{FS=" "}{print $2}')
		device_id=$(sed -n '2p' base_info_Mellanox.txt |awk 'BEGIN{FS=" "}{print $5}')$(sed -n '2p' base_info_Mellanox.txt |awk 'BEGIN{FS=" "}{print $4}')
		sub_vid=$(sed -n '4p' base_info_Mellanox.txt |awk 'BEGIN{FS=" "}{print $15}')$(sed -n '4p' base_info_Mellanox.txt |awk 'BEGIN{FS=" "}{print $14}')
		sub_did=$(sed -n '4p' base_info_Mellanox.txt |awk 'BEGIN{FS=" "}{print $17}')$(sed -n '4p' base_info_Mellanox.txt |awk 'BEGIN{FS=" "}{print $16}')
		
		#check device
		cat version.xml |grep -i "${vendor_id}" |grep -i "${device_id}" |grep -i "${sub_vid}" |grep -i "${sub_did}" >/dev/null
		if [ $? != 0 ]
		then	
			rm base_info_Mellanox.txt
			continue
		else
			let num_index=$num_index+1
		fi			
		flint -d "${device_index[$dev_num]}" q >dev_info.txt
		cur_fw="$(cat dev_info.txt |grep -i 'Fw Version:'|awk 'BEGIN{FS=" "}{print $3}')"
		fw_version=$(cat "${pwd}/version.xml" |grep -i "<Version>"|awk 'BEGIN{FS=">"}{print $2}'|awk 'BEGIN{FS="<"}{print $1}')
		if [ "${cur_fw}" == "${fw_version}" ]
		then
			let fw_dev=$fw_dev+1
			continue
		fi
		#init BDF flag
		BDF_select[$dev_num]=0		
		let dev_num=$dev_num+1			
	done
	if [ ${fw_dev} -eq ${num_index} ] && [ ${num_index} != 0 ]
	then
		#already upgrade
		result="OK"
		errorCode="0"
		description="already upgrade"
		create_resultXml
		exit 0;
	fi
}

#get device of Emulex
get_device_Emulex(){
	hbacmd listhbas > tmp_Emulex.txt 2>/dev/null		
	num_hbas=$(cat tmp_Emulex.txt | egrep -i "Port WWN|Current MAC" |wc -l)	
	
	#set base info
	for ((i=1;i<=num_hbas;i++))
	do
		device_index[$dev_num]=$(cat tmp_Emulex.txt | egrep -i "Port WWN|Current MAC" |sed -n ''$i'p' | awk '{print $4}')		
		hbacmd hbaAttributes "${device_index[$dev_num]}" >tmp_attributes.txt
	
		#get base info
		vendor_id=$(cat tmp_attributes.txt |grep -i "Vendor Spec ID" |awk '{print $5}')
		device_id=$(cat tmp_attributes.txt |grep -i "Device ID" |awk '{print $4}')
		sub_vid=$(cat tmp_attributes.txt |grep -i "Sub Vendor ID" |awk '{print $5}')
		sub_did=$(cat tmp_attributes.txt |grep -i "Sub Device ID" |awk '{print $5}')
		
		#check device
		cat version.xml |grep -i "${vendor_id}" |grep -i "${device_id}" |grep -i "${sub_vid}" |grep -i "${sub_did}" >/dev/null
		if [ $? != 0 ]
		then	
			rm tmp_attributes.txt 2>/dev/null
			continue
		fi	
		
		#get BDF info
		bus_num[$dev_num]=$(cat tmp_attributes.txt |grep -i "PCI Bus Number" |awk 'BEGIN{FS=" "}{print $5}')		
		function_num[$dev_num]=$(cat tmp_attributes.txt |grep -i "PCI Func Number"  |awk 'BEGIN{FS=" "}{print $5}')
		cat tmp_Emulex.txt | egrep -i "Port WWN|Current MAC" |sed -n ''$i'p' |grep -i "Port WWN" >/dev/null
		if [ $? == 0 ]
		then
			device_num[$dev_num]=$(cat tmp_attributes.txt |grep -i "Number of Ports" |awk 'BEGIN{FS=" "}{print $5}')
		else
			device_num[$dev_num]=$(cat tmp_attributes.txt |grep -i "Port Number" |awk 'BEGIN{FS=" "}{print $4}')
		fi
		rm tmp_attributes.txt 2>/dev/null	
		
		#init BDF flag
		BDF_select[$dev_num]=0		
		let dev_num=$dev_num+1
	done	
	
	rm tmp_Emulex.txt 2>/dev/null
}

#get device of Qlogic
get_device_Qlogic(){
	/opt/QLogic_Corporation/QConvergeConsoleCLI/qaucli -i | grep -i "Port Name" >>tmp_Qlogic.txt 2>/dev/null
	num_Qlogic=$(cat tmp_Qlogic.txt |wc -l)
			
	#set base
	for ((i=1;i<=num_Qlogic;i++))
	do
		device_index[$dev_num]=$(cat tmp_Qlogic.txt |sed -n ''$i'p' | awk '{print $4}')		
		/opt/QLogic_Corporation/QConvergeConsoleCLI/qaucli -i ${device_index[$dev_num]} >tmp_info.txt 2>/dev/null
		
		#get base info
		device_id=$(cat tmp_info.txt |grep -i "PCI Device ID" |awk '{print $5}')
		sub_vid=$(cat tmp_info.txt |grep -i "Subsystem Vendor ID" |awk '{print $5}')
		sub_did=$(cat tmp_info.txt |grep -i "Subsystem Device ID" |awk '{print $5}')		
		
		#check device
		cat version.xml |grep -i "${device_id}" |grep -i "${sub_vid}" |grep -i "${sub_did}" >/dev/null
		if [ $? != 0 ]
		then	
			rm tmp_info.txt 2>/dev/null
			continue
		fi
		
		bus_num[$dev_num]=$(cat tmp_info.txt |grep -i "PCI Bus Number" |awk 'BEGIN{FS=" "}{print $5}')
		device_num[$dev_num]=$(cat tmp_info.txt |grep -i "PCI Device Number" |awk 'BEGIN{FS=" "}{print $5}')
		function_num[$dev_num]=$(cat tmp_info.txt |grep -i "PCI Function Number"  |awk 'BEGIN{FS=" "}{print $5}')
		cur_fw[$dev_num]=$(cat tmp_info.txt |grep -i "Flash Firmware version" |awk 'BEGIN{FS=" "}{print $5}')
		rm tmp_info.txt 2>/dev/null
		
		#init BDF flag
		BDF_select[$dev_num]=0		
		let dev_num=$dev_num+1		
	done	
	
	rm tmp_Qlogic.txt 2>/dev/null
}

#get device of Huawei-developed Qlogic 
get_device_Qlogic_Hw(){
    cd "${pwd}"
    num_qlo_hw=$(lspci|grep -i 57810|wc -l)
    for ((i=1;i<=num_qlo_hw;i++))
	do
        if [ -f tmp_qlo_hw.txt ]
        then
            rm -fr tmp_qlo_hw.txt
        fi
        ##Create display script  
        echo "./load.sh -b10eng << EOF" > fw_display.sh
        echo "device $i" >> fw_display.sh;
        echo "nvm cfg -dump tmp_qlo_hw.txt" >> fw_display.sh
        echo "exit" >> fw_display.sh
        
        ##display info
        chmod u+x fw_display.sh
        sh fw_display.sh > /dev/null 2>&1
        
        device_index[$dev_num]="${i}"
        
        #get base info
		device_id=$(cat tmp_qlo_hw.txt |grep -i "Vendor Device ID"|grep -v -i "MF" |awk '{print $NF}')
        dendor_id=$(cat tmp_qlo_hw.txt |grep -i "Vendor ID"|grep -v -i "sub" |awk '{print $NF}')
		sub_vid=$(cat tmp_qlo_hw.txt |grep -i "Subsystem Vendor ID" |awk '{print $NF}')
		sub_did=$(cat tmp_qlo_hw.txt |grep -i "Subsystem Device ID" |awk '{print $NF}')		
		
		#check device
		cat version.xml |grep -i "${device_id}" |grep -i "${dendor_id}" |grep -i "${sub_vid}" |grep -i "${sub_did}" >/dev/null
		if [ $? != 0 ]
		then
			continue
		fi
        
        #init BDF flag
		BDF_select[$dev_num]=0		
		let dev_num=$dev_num+1
	done	
    
    
}

#get device of HardDisk
get_device_HardDisk(){
	#get diskinfo by hwdiag
	/opt/huawei/bma/bin/hwdiag -t disk -i 2>/dev/null|awk 'NR>2'>tmp_hwdiag.txt 2>/dev/null
	cat tmp_hwdiag.txt |awk '{print $1}' >tmp_SN.txt 2>/dev/null
	
	#get base info by disktool
	local disk_num=$("${pwd}/tools/disktool" -s |grep -i "/dev"|wc -l)
	for ((i=1;i<=disk_num;i++))
	do
		device_index[$dev_num]=$("${pwd}/tools/disktool" -s |grep -i "/dev" |sed -n ''$i'p' |awk 'BEGIN{FS=" "}{print $1}')
		device_type[$dev_num]=$("${pwd}/tools/disktool" -f i ${device_index[$dev_num]} |grep -i "Device Model")
		
		#skip disks which under raid card
		echo "${device_type[$dev_num]}" |egrep -i "LSI|Logical|USB|AVAGO" >/dev/null
		if [ $? == 0 ]
		then
			continue
		fi
		
		#check disk type by product
		check_disk_type
		if [ $? != 0 ]
		then
			continue
		fi
		disk_sn[$dev_num]=$("${pwd}/tools/disktool" -f i ${device_index[$dev_num]} |grep -i "Serial Number" |awk '{print $3}')
		cur_fw[$dev_num]=$("${pwd}/tools/disktool" -f i ${device_index[$dev_num]} |grep -i "Firmware Version" |awk 'BEGIN{FS=" "}{print $3}')		
		disk_tool[$dev_num]="disktool"
		#init BDF flag
		BDF_select[$dev_num]=0		
		let dev_num=$dev_num+1
	done
	
	#get base info by storcli64(2208/3108/3408/3508)
	local num_mega=$("${pwd}/tools/storcli64" show ctrlcount |grep -i "Controller Count" |awk 'BEGIN{FS=" "}{print $4}')		
	for ((i=0; i<num_mega; i++))
	do
		"${pwd}/tools/storcli64" -pdlist -a$i  >tmp_disk.txt 2>/dev/null
		local mega_type=$("${pwd}/tools/storcli64" /c$i show | grep -i "Product Name" |awk 'BEGIN{FS=" "}{print $4}')
		disk_num=$(cat tmp_disk.txt|wc -l)
		for ((j=1;j<=disk_num;j++))
		do
			device_index[$dev_num]="$(cat tmp_disk.txt |grep -i "Enclosure Device Id" |sed -n ''$j'p' \
				|awk '{print $4}'):$(cat tmp_disk.txt |grep -i "Slot Number" |sed -n ''$j'p' |awk '{print $3}')"
			device_type[$dev_num]=$(cat tmp_disk.txt |grep -i "Inquiry Data" |sed -n ''$j'p')

			#check disk type by product
			check_disk_type
			if [ $? != 0 ]
			then
				continue
			fi
			
			slot_num=$(cat tmp_disk.txt |grep -i "Slot Number" |sed -n ''$j'p'|awk '{print $NF}')
			local line=$(cat tmp_SN.txt |grep -n '\<${slot_num}\>')
			disk_sn[$dev_num]=$(cat tmp_hwdiag.txt |sed -n ''${line}'p' |awk '{print $5}')
			disk_tool[$dev_num]="storcli64"
			raid_index[$dev_num]=$i
			raid_type[$dev_num]=$mega_type
			#init BDF flag
			BDF_select[$dev_num]=0
			let dev_num=$dev_num+1
		done
	done
	
	rm tmp_SN.txt 2>/dev/null
	rm tmp_hwdiag.txt 2>/dev/null
	rm tmp_disk.txt 2>/dev/null
}

#check disk type
check_disk_type(){
	local check_disk_flag=1
	for device in ${upgrade_devices}
	do
		echo "${device_type[$dev_num]}" |grep -i "${device}" >/dev/null
		if [ $? == 0 ]
		then
			check_disk_flag=0
		else
			continue
		fi
	done
	
	if [ "${check_disk_flag}" == "0" ]
	then
		return 0
	else
		return 1
	fi
}

#get device of BroadCom
get_device_BroadCom(){
	cd "${pwd}/tools"
	echo -e "c\nc\nc\nq" |"${pwd}/tools/runDiag" >tmp_log.txt 2>/dev/null
	cat tmp_log.txt |egrep -i "5719|5720" >tmp_bcm.txt
	rm tmp_log.txt 2>/dev/null
	
	num_bcm=$(cat tmp_bcm.txt |wc -l)
	#set base
	for ((i=1;i<=num_bcm;i++))
	do
		device_index[$dev_num]=$(cat tmp_bcm.txt |sed -n ''$i'p' | awk '{print $1}')		
		
		local check_str=""
		if [ "${tool_type}" == "BroadCom5719" ]
		then
			check_str="5719"
		else
			check_str="5720"
		fi
		cat tmp_bcm.txt |sed -n ''$i'p' |grep -i "${check_str}" >/dev/null
		if [ $? != 0 ]
		then
			continue
		fi
		
		bus_num[$dev_num]=$(cat tmp_bcm.txt |sed -n ''$i'p' | awk '{print $3}'|awk 'BEGIN{FS=":"}{print $1}')
		device_num[$dev_num]=$(cat tmp_bcm.txt |sed -n ''$i'p' | awk '{print $3}'|awk 'BEGIN{FS=":"}{print $2}')
		function_num[$dev_num]=$(cat tmp_bcm.txt |sed -n ''$i'p' | awk '{print $3}'|awk 'BEGIN{FS=":"}{print $3}')
		cur_fw[$dev_num]=$(cat tmp_bcm.txt |sed -n ''$i'p' | awk '{print $10}')
		
		#init BDF flag
		BDF_select[$dev_num]=0		
		let dev_num=$dev_num+1		
	done	
	
	rm tmp_bcm.txt 2>/dev/null	
	cd "${pwd}"
}

#upgrade firmware
upgrade_firmware(){
	
	#upgrade in loop
	for ((i=0;i<${dev_num};i++))
	do
		index=$i
		
		#this device is not in select BDFs
		if [ ${BDF_select[$index]} != 0 ]
		then
			continue
		fi

		upgrade_By_tools	
	done
	
	if [ ${flag_fail} == 1 ]
	then
		#upgrade Failed
		result="Fail"
		errorCode="1"
		description="Upgrade failed"
		create_resultXml
		exit 1;
	else
		#upgrade Success
		result="OK"
		errorCode="NA"
		description="NA"
		create_resultXml
		exit 0;
	fi
}

#filter devices by BDF
filter_ByBDF(){	
	flag_filter=0
	
	case ${tool_type} in
		HardDisk)
			#check Serial Number
			for ((i=0;i<${dev_num};i++))
			do 
				if [ -z "${disk_sn[$i]}" ]
				then
					continue
				fi
				
				echo "${select_BDFs}" |grep "\<${disk_sn[$i]}" >/dev/null
				if [ $? != 0 ]
				then 
					BDF_select[$i]=1
				else 
					flag_filter=1
				fi
			done
		;;
		*)
			#check BDF
			for ((i=0;i<${dev_num};i++))
			do 
				if [ -z "${bus_num[$i]}" ] && [ -z "${device_num[$i]}" ] && [ -z "${function_num[$i]}" ]
				then
					continue
				fi
				
				echo "${select_BDFs}" |grep "\<${bus_num[$i]}:${device_num[$i]}.${function_num[$i]}" >/dev/null
				if [ $? != 0 ]
				then 
					BDF_select[$i]=1
				else 
					flag_filter=1
				fi
			done
		;;
	esac
	
	#no device found  by filter
	if [ ${flag_filter} == 0 ]
	then 
		result="Fail"
		errorCode="2"
		description="Error input"
		create_resultXml
		exit 2;
	fi
}

#upgrade FW of 2308
sas2_upgrade(){	
	local fw_path=""
	if [ -d "${pwd}/${fw_file}" ]
	then
		fw_path="${fw_file}"
	fi

	local bfw=""
	local dfw=""
	local stdfw=""
	local fw=""
	local rom=""
	
	#get FW files by type
	for file_name in $(ls "${pwd}/${fw_path}")
	do 		
		echo "${file_name}" | grep -i "B0" >/dev/null
		if [ $? == 0 ]
		then
			bfw="${file_name}"
		fi  

		echo "${file_name}" | grep -i "D1" >/dev/null
		if [ $? == 0 ]
		then
			dfw="${file_name}"
		fi 
	   
		echo "${file_name}" | grep -i "9217" >/dev/null
		if [ $? == 0 ]
		then
			stdfw="${file_name}"
		fi 
		
		echo "${file_name}" | grep -i "mpt" >/dev/null
		if [ $? == 0 ]
		then
			rom="${file_name}"
		fi
	done

	#choose FW file
	"${pwd}/tools/sas2flash" -c ${device_index[$index]} -list | grep -i "NVDATA Product ID" | grep -i "SAS9217-8i" >/dev/null
	if [ $? == 0 ]
	then
		fw="${stdfw}"
	fi
	
	"${pwd}/tools/sas2flash" -c ${device_index[$index]} -list | grep -i "Controller" | grep -i "(B" >/dev/null
	if [ $? == 0 ]
	then
		fw="${bfw}"
	fi
	
	"${pwd}/tools/sas2flash" -c ${device_index[$index]} -list | grep -i "Controller" | grep -i "(D" >/dev/null
	if [ $? == 0 ]
	then
		fw="${dfw}"
	fi

	if [ "${fw}" == "" ]
	then
		return
	fi
	
	#upgrade
	"${pwd}/tools/sas2flash" -c ${device_index[$index]} -f "${pwd}/${fw_path}/${fw}" >>"${pwd}/work.log"	
	if [ $? != 0 ]
	then
		flag_fail=1
	fi

	#upgrade rom if file exists
	if [ -f "${pwd}/${fw_path}/${rom}" ]
	then
		"${pwd}/tools/sas2flash" -c ${device_index[$index]} -b "${pwd}/${fw_path}/${rom}" >>"${pwd}/work.log"	
		if [ $? != 0 ]
		then
			flag_fail=1
		fi	
	fi
}

#upgrade FW of 3008
sas3_upgrade(){	
	local fw_path=""
	if [ -d "${pwd}/${fw_file}" ]
	then
		fw_path="${fw_file}"
	fi

	local ir_fw=""
	local it_fw=""
	local ir_stdfw=""
	local it_stdfw=""
	local fw=""
	local rom=""
	
	#get FW files by type
	for file_name in $(ls "${pwd}/${fw_path}")
	do 		
		#add processing for P08 
		echo "${file_name}" |grep -E "P12|P08" >/dev/null
		if [ $? == 0 ]
		then
			ir_fw="${file_name}"
		fi  

		echo "${file_name}" |grep "9311" >/dev/null
		if [ $? == 0 ]
		then
			ir_stdfw="${file_name}"
		fi 
	   
		echo "${file_name}" | grep "T12" >/dev/null
		if [ $? == 0 ]
		then
			it_fw="${file_name}"
		fi  

		echo "${file_name}" |grep "9300" >/dev/null
		if [ $? == 0 ]
		then
			it_stdfw="${file_name}"
		fi 
		
		echo "${file_name}" |grep "mptsas3" >/dev/null
		if [ $? == 0 ]
		then
			rom="${file_name}"
		fi 
	done

	#choose FW file
	"${pwd}/tools/sas3flash" -c ${device_index[$index]} -list | grep -i "Firmware Product ID" | grep -i "IR" >/dev/null
	if [ $? == 0 ]
	then
		"${pwd}/tools/sas3flash" -c ${device_index[$index]} -list | grep -i "NVDATA Product ID" | grep -i "SAS3008" >/dev/null
		if [ $? == 0 ]
		then
			fw="${ir_fw}"
		else
			fw="${ir_stdfw}"
		fi
	fi
	
	"${pwd}/tools/sas3flash" -c ${device_index[$index]} -list | grep -i "Firmware Product ID" | grep -i "IT" >/dev/null
	if [ $? == 0 ]
	then
		"${pwd}/tools/sas3flash" -c ${device_index[$index]} -list | grep -i "NVDATA Product ID" | grep -i "SAS3008" >/dev/null
		if [ $? == 0 ]
		then
			fw="${it_fw}"
		else
			fw="${it_stdfw}"
		fi
	fi
	
	if [ "${fw}" == "" ]
	then
		return
	fi
	
	#upgrade,first upgrade operation if unsuccessful and then downgrade operation
	"${pwd}/tools/sas3flash" -c ${device_index[$index]} -f "${pwd}/${fw_path}/${fw}" >>"${pwd}/work.log"	
	if [ $? != 0 ]
	then
		"${pwd}/tools/flashoem" -c ${device_index[$index]} -ctype sas3 -ftype ir2ir -f "${pwd}/${fw_path}/${fw}" >>"${pwd}/work.log"
		if [ $? != 0 ]
		then
			flag_fail=1
		fi
	fi	
	
	#upgrade rom if file exists
	if [ -f "${pwd}/${fw_path}/${rom}" ]
	then
		"${pwd}/tools/sas3flash" -c ${device_index[$index]} -b "${pwd}/${fw_path}/${rom}" >>"${pwd}/work.log"
		if [ $? != 0 ]
		then
			flag_fail=1
		fi	
	fi
}

#upgrade FW of hardDisk by tools
hardDisk_upgrade(){
	case ${disk_tool[$index]} in
	disktool)
		"${pwd}/tools/disktool" -f u -w  "${pwd}/${fw_file}"  ${device_index[$index]}  >"${pwd}/HardDisk.log" 
		cat "${pwd}/HardDisk.log" >>"${pwd}/work.log"
		cat "${pwd}/HardDisk.log" |grep -i "upgrade failed" >/dev/null
		if [ $? == 0 ]
		then
			rm "${pwd}/HardDisk.log" 2>/dev/null
			return 1
		else
			rm "${pwd}/HardDisk.log" 2>/dev/null
			return 0
		fi				
	;;	
	storcli64)
		cd "${pwd}"
		tmp_fw_file=""
		echo "${fw_file}" | grep " " >/dev/null
		if [ $? == 0 ]
		then
			tmp_fw_file="${fw_file}"
			fw_file=$(echo "${fw_file}" | sed 's/ /_/g')
			cp "./${tmp_fw_file}"  "./${fw_file}"
		fi
		
		local eid_num=`echo ${device_index[$index]} | awk 'BEGIN{FS=":"}{print $1}'`
		local sid_num=`echo ${device_index[$index]} | awk 'BEGIN{FS=":"}{print $2}'`
		local disk_type=`"${pwd}/tools/storcli64" /c${raid_index[$index]}/e${eid_num}/s${sid_num} show J |grep "State" |awk 'BEGIN{FS=":"}{print $2}' |awk 'BEGIN{FS="\""}{print $2}'`
		if [ $disk_type != "JBOD" ]
		then
			echo "${raid_type[$index]}" | egrep -i "3408|3508|3416|3516" >/dev/null
			if [ $? == 0 ]
			then
				"${pwd}/tools/storcli64" /c${raid_index[$index]}/e${eid_num}/s${sid_num} download src="./${fw_file}" satabridge mode=5 >>"${pwd}/work.log"
			else
				"${pwd}/tools/storcli64" -pdfwdownload -physdrv[${device_index[$index]}] -f "./${fw_file}" -a${raid_index[$index]}  >>"${pwd}/work.log"
			fi
		fi
		
		if [ $? != 0 ]
		then
			if [ "${tmp_fw_file}" != "" ] && [ -f "${fw_file}" ]
			then
				rm -rf "./${fw_file}" 2>/dev/null
			fi
			return 1
		else
			if [ "${tmp_fw_file}" != "" ] && [ -f "${fw_file}" ]
			then
				rm -rf "./${fw_file}" 2>/dev/null
			fi
			return 0
		fi
	;;
	*)
	;;
	esac	
}

check_flint_status() {
    flint_flag=0
    flint -d ${device_index[$index]} q >> "${pwd}/work.log" 2>/dev/null
    if [ $? != 0 ];then
        mst restart
        flint -d ${device_index[$index]} q >> "${pwd}/work.log" 2>/dev/null
        if [ $? != 0 ];then
            flint_flag=1
        fi
    fi
    if [ ${flint_flag} == 1 ]; then
            # delete tmp file
            result="Fail"
            errorCode="9"
            description="flint tool is abnormal"
            create_resultXml
            exit 9;
    fi
}

check_mellanox_target_version() {
    check_flint_status
    if [ $? != 0 ];then
        return 1
    fi
    flint -d ${device_index[$index]} q > "${pwd}/tmp_flint_out.log" | tee -a "${pwd}/work.log"
    if [ $? != 0 ];then
        return 1
    fi
    cat ${pwd}/tmp_flint_out.log >> "${pwd}/work.log" 2>/dev/null
    cur_fw="$(cat ${pwd}/tmp_flint_out.log |grep -i 'Fw Version:'|awk 'BEGIN{FS=" "}{print $3}')"
    if [ -f ${pwd}/tmp_flint_out.log ];then
        rm -f ${pwd}/tmp_flint_out.log
    fi
    if [ "$cur_fw" != "$cfg_fw_Version" ];then
        return 1
    fi
    
    return 0
}

#upgrade FW 
upgrade_By_tools(){
	case ${tool_type} in
		MellanoxCX3|MellanoxCX4|MellanoxCX5|MellanoxCX6)	
			
			flint -y -d ${device_index[$index]} -i "${pwd}/${fw_file}" b >>"${pwd}/work.log"			
			check_mellanox_target_version			
			if [ $? != 0 ];then
				flag_fail=1
			fi
		;;
		mega)
			"${pwd}/tools/storcli64" /c${device_index[$index]} download file="./${fw_file}" \
				nosigchk noverchk >>"${pwd}/work.log"	
			if [ $? != 0 ]
			then
				flag_fail=1
			fi	
		;;
		LSI2308)
			sas2_upgrade 
		;;
		LSI3008)
			sas3_upgrade		
		;;
		Qlogic)
			echo "${upgradeBus}" |egrep ",${bus_num[$index]}" >/dev/null
			if [ $? != 0 ]
			then
				local error_code=0
				/opt/QLogic_Corporation/QConvergeConsoleCLI/qaucli -b ${device_index[$index]} "${pwd}/${fw_file}" >>"${pwd}/work.log"	
				error_code=$?
				if [ ${error_code} -ne 0 ] && [ ${error_code} -ne 201 ]
				then
					flag_fail=1
				fi
				upgradeBus="${upgradeBus},${bus_num[$index]}"
			fi
		;;
        Qlogic_Huawei)
			echo "./load.sh -b10eng << EOF" > fw_update.sh  
            echo "device ${device_index[$index]}" >> fw_update.sh
            echo "nvm upgrade -F -mbi ${pwd}/${fw_file} " >> fw_update.sh
            echo "exit 0" >> fw_update.sh
            ##Create Fw_update script Dynamiclly end

            ##update Fw
            chmod u+x fw_update.sh
            sh fw_update.sh > /dev/null 2>&1
            if [ $? != 0 ]
            then
                flag_fail=1
            fi
		;;
		EmulexLancer|EmulexBE3)
			echo "${upgradeBus}" |egrep ",${bus_num[$index]}" >/dev/null
			if [ $? != 0 ]
			then
				local err_code=0
				hbacmd download  ${device_index[$index]} "${pwd}/${fw_file}" >>"${pwd}/work.log"	
				err_code=$?			
				if [ ${err_code} -ne 0 ] && [ ${err_code} -ne 247 ]
				then
					flag_fail=1
				fi
				upgradeBus="${upgradeBus},${bus_num[$index]}"
			fi			
		;;
		Intel)
            echo "${upgradeBus}" |egrep ",${bus_num[$index]}" >/dev/null
			if [ $? != 0 ]
			then
                "${pwd}/tools/eeupdate64e" /NIC=${device_index[$index]} /d "${pwd}/${fw_file}"  >>"${pwd}/work.log"
                if [ $? != 0 ]
                then
                    flag_fail=1
                fi	
                upgradeBus="${upgradeBus},${bus_num[$index]}"
			fi
		;;
		ES3000)
			echo -e "y" |hioadm updatefw -d ${device_index[$index]} -f "${pwd}/${fw_file}"  >>"${pwd}/work.log"
			if [ $? != 0 ]
			then
				flag_fail=1
			fi	
		;;
		HardDisk)
			hardDisk_upgrade			
			if [ $? != 0 ]
			then
				flag_fail=1
			fi
		;;
		BroadCom5719|BroadCom5720)
			cd "${pwd}/tools"
			
			echo -e "c\nc\nc\ndevice ${device_index[$index]} \nseprg ../${fw_file} \nnq" |"${pwd}/tools/runDiag" >"${pwd}/work_bcm.log" 2>/dev/null
			cat "${pwd}/work_bcm.log" >>"${pwd}/work.log"
			cat "${pwd}/work_bcm.log" |egrep -i "Mismatched|Invalid file" >/dev/null
			if [ $? == 0 ]
			then	
				flag_fail=1
			fi	
			
			rm "${pwd}/work_bcm.log" 2>/dev/null
			cd "${pwd}"
		;;
		*)
		;;
	esac
	
}


check_dmesg_mellanox_card_status() {
    check_mlnx_result=0
    check_bdf_list=()
    error_bdf=""
    
    if [ -n "$1" ];then
        check_bdf_list+=("$1")
    else
        local jx=0;
        for ((jx=0;jx<${dev_num};jx++))
        do
            check_bdf_list+=("${device_index[$jx]}")
        done
    fi
    
    #add "echo $(cmd) 2>/dev/null" to avoid exiting this script when dmesg no mlx5_core 
    echo $(dmesg -T | grep -i mlx5_core  > ${pwd}/mlnx_dmesg_check.log)  2>/dev/null
    if [ -f ${smartsp_dmesg_path} ]; then
        echo $(cat ${smartsp_dmesg_path} | grep -i mlx5_core >> ${pwd}/mlnx_dmesg_check.log)  2>/dev/null
    fi
    
    for check_bdf in "${check_bdf_list[@]}"
    do
        #delete last num of bdf, example: 81:00.0 -> 81:00
        check_bdf=${check_bdf%.*}
        for mlnx_error in "${mlnx_log_error_list[@]}"
        do
            if [ "`cat ${pwd}/mlnx_dmesg_check.log 2>/dev/null |grep ${check_bdf} |grep "${mlnx_error}" | wc -l`" != "0" ];then
                cat ${pwd}/mlnx_dmesg_check.log 2>/dev/null |grep ${check_bdf} |grep "${mlnx_error}" >> "${pwd}/work.log" 2>/dev/null
                error_bdf=$(cat ${pwd}/mlnx_dmesg_check.log |grep ${check_bdf} |grep "${mlnx_error}"|awk 'BEGIN{FS="]"}{print $2}'|awk 'BEGIN{FS=" "}{print $2}')
                check_mlnx_result=1
            fi
        done
    done
    
    if [ -f ${pwd}/mlnx_dmesg_check.log ];then
        rm -f ${pwd}/mlnx_dmesg_check.log
    fi
    
    cd "${pwd}/"
    if [ ${check_mlnx_result} != 0 ]
    then
        #prepare tools failed
        result="Fail"
        errorCode="8"
        description="Mellanox card bdf:${error_bdf} check firmware staus failed!"
        create_resultXml
        exit 8;
    fi
    
}

#set select BDF
select_BDFs=""
if [ -n "$2" ] && [ "$2" == "BDF" ]  
then
	select_BDFs=$(echo $3 |sed 's/;/ /g')
fi

case $1 in
	upgrade)
		#read version xml
		read_version_xml
		
		#install tools
		prepare_tools
		
		#get device info by tools
		get_device_info

		#filter BDFs by input
		if [ -n "${select_BDFs}" ]
		then
			filter_ByBDF
		fi
		
		#filter emulex by bus number
		upgradeBus=""
		
		#upgrade firmware
		upgrade_firmware
	;;
	help|H|h)
		echo "Usage: ./install.sh upgrade BDF <bdf>"
		echo "Examples:"
		echo "    ./install.sh upgrade"
		echo "    ./install.sh upgrade BDF 01:00.0"
	;;
	*)
	;;
esac

exit 0
