#!/bin/bash

#get work path
path=$(dirname "$0")
path="${path/\./$(pwd)}"
pwd="${path}"

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|LSI3004|3416IMR|LSI3516)
				tool_type="mega"
			;;
			LSI2308)
				tool_type="LSI2308"
			;;
			LSI3008)
				tool_type="LSI3008"
			;;
			LSI3416-IT)
				tool_type="LSI3416-IT"
			;;
			LSI3408IT)
				tool_type="LSI3408IT"
			;;			
			SmartRAID3152-8i|SmartHBA2100-8i|PM8060)
				tool_type="pmcluxor"
			;;			
			SM233|SM231|MU230|SM211|SM212|MU212|MU210|SP230|SP330|SP331|SP332|MZ310|MZ312|SP212|SP210|SP310|XL710)
				tool_type="Intel"
			;;
			MZ311|MZ610|MZ611|MZ612|MZ613|MZ620|MZ710)
				tool_type="MellanoxCX3"
			;;
			SP333)
				tool_type="MellanoxCX4"
			;;
			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} |egrep -i "WD|ST|MG|HUS|HUC|AL|SSD|Toshiba|Seagate|Hitachi|intel" >/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/"
		cat /etc/*-release | grep -i "SUSE" >/dev/null 2>&1
        if [ $? -eq 0 ]
		then
			if [ -d "${pwd}/drivers/suse11-3_3.0.76-0.11-default" ]
			then
				rpm -ivh --ignoresize ./suse11-3_3.0.76-0.11-default/*.rpm  >>"${pwd}/work.log" 2>/dev/null
			fi
        fi
		
		cat /etc/*-release | grep -i "EulerOS 2.0 (SP3)" >/dev/null 2>&1
        if [ $? -eq 0 ]
		then
			if [ -d "${pwd}/drivers/centos7-3_3.10.0-514.41.4.28.h70.x86_64" ]
			then
				rpm -ivh --ignoresize ./centos7-3_3.10.0-514.41.4.28.h70.x86_64/*.rpm  >>"${pwd}/work.log" 2>/dev/null
				modprobe mpt3sas
			fi
        fi
		
		cat /etc/*-release | grep -i "EulerOS 2.0 (SP5)" >/dev/null 2>&1
        if [ $? -eq 0 ]
		then
			if [ -d "${pwd}/drivers/centos7-5_3.10.0-862.el7.x86_64" ]
			then
				cp -fr  "${pwd}/drivers/centos7-5_3.10.0-862.el7.x86_64/iqvlinux_forbootutil_centos.ko" /lib/modules/`uname -r`/kernel/drivers/net/iqvlinux.ko >>"${pwd}/work.log" 2>/dev/null
				depmod
				modprobe iqvlinux >/dev/null 2>&1
			fi
        fi
		
	fi
	
	# load i40e 
	echo ${cfg_devices} | grep -i "XL710" >/dev/null 2>&1
	if [ $? -eq 0 ]
	then	
		rmmod -f i40e >/dev/null 2>&1
		depmod
		modprobe i40e
	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 ${tool_type} | grep -i -E "mega" >/dev/null 2>&1
	if [ $? -eq 0 ]
	then
		cat /sys/module/megaraid_sas/version
		if [ $? -ne 0 ]
		then
		rmmod -f megaraid_sas >/dev/null 2>&1
		depmod
		modprobe megaraid_sas
		fi
	fi
	
	# load iqvlinux
	echo ${cfg_devices} | grep -i -E "XL710|X722|SP332|SP331" >/dev/null 2>&1
	if [ $? -eq 0 ]
	then
        cat /etc/*-release | grep -i "SUSE" >/dev/null 2>&1
        if [ $? -eq 0 ]
        then
            cp -fr ./suse11-3_3.0.76-0.11-default/iqvlinux_foreeupdate_suse.ko /lib/modules/`uname -r`/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  ./centos7-3_3.10.0-514.41.4.28.h70.x86_64/iqvlinux_foreeupdate_euler.ko /lib/modules/`uname -r`/kernel/drivers/net/iqvlinux.ko
			depmod
			modprobe iqvlinux
		fi
    fi	
	
	cd "${pwd}/tools/"
	case ${tool_type} in
		mega)
			if [ -f "./storcli64" ]
			then
				chmod +x "./storcli64" 
			else 
				tool_flag=1
			fi
		;;
		LSI2308)
			if [ -f "./sas2flash" ]
			then
				chmod +x "./sas2flash" 
				chmod +x "./sas2ircu"
			else 
				tool_flag=1
			fi
		;;
		LSI3008)
			if [ -f "./sas3flash" ]
			then
				chmod +x "./sas3flash" 
				chmod +x "./sas3ircu"
			else 
				tool_flag=1
			fi
		;;
		pmcluxor)
			if [ -f "./arcconf" ]
			then
				chmod +x "./arcconf" 
			else 
				tool_flag=1
			fi
		;;
		LSI3416-IT)
			if [ -f "./storcli64" ]
			then
				chmod +x "./storcli64" 
			else 
				tool_flag=1
			fi
		;;	
		LSI3408IT)
			if [ -f "./storcli64" ]
			then
				chmod +x "./storcli64" 
			else 
				tool_flag=1
			fi
		;;		
		Intel)
			if [ -f "./eeupdate64e" ]
			then
				chmod +x "./eeupdate64e" 
			else 
				tool_flag=1
			fi
			
		;;
		EmulexLancer|EmulexBE3)
			if [ -f ./elxocmcore*.rpm ]
			then
				hbacmd >>"${pwd}/work.log" 2>/dev/null
				if [ $? == 127 ]
				then
					rpm -ivh --ignoresize ./elxocmlibhbaapi*.rpm >>"${pwd}/work.log" 2>/dev/null
					rpm -ivh --ignoresize ./elxocmcore*.rpm >>"${pwd}/work.log" 2>/dev/null
				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
			else
				tool_flag=1
			fi						
		;;
		Qlogic)
			if [ -f ./QC*.rpm ]
			then
				/opt/QLogic_Corporation/QConvergeConsoleCLI/qaucli -h >>"${pwd}/work.log" 2>/dev/null
				if [ $? == 127 ]
				then
					rpm -ivh --ignoresize ./QC*.rpm >>"${pwd}/work.log" 2>/dev/null
				fi
			else
				tool_flag=1
			fi
		;;
        Qlogic_Huawei)
			if [ -f ./load.sh ]
			then
				chmod +x *
                cp -fr * ../
			else
				tool_flag=1
			fi
		;;
		ES3000)
			if [ -f ./hioadm*.rpm ]
			then
				hioadm >>"${pwd}/work.log" 2>/dev/null
				if [ $? == 127 ]
				then
					rpm -ivh --ignoresize ./irqbalance*.rpm >>"${pwd}/work.log" 2>/dev/null
					rpm -ivh --ignoresize ./hioadm*.rpm >>"${pwd}/work.log" 2>/dev/null
				fi
			else
				tool_flag=1
			fi
		;;
		MellanoxCX3|MellanoxCX4)
			if [ -f ./mft*.rpm ]
			then
				insmod "${pwd}/drivers/mst_pci.ko"  >>"${pwd}/work.log" 2>/dev/null
				insmod "${pwd}/drivers/mst_pciconf.ko"  >>"${pwd}/work.log" 2>/dev/null
				
				mst help >>"${pwd}/work.log" 2>/dev/null
				if [ $? == 127 ]
				then
					rpm -ivh --ignoresize ./mft*.rpm >>"${pwd}/work.log" 2>/dev/null					
				fi
				mst start >>"${pwd}/work.log" 2>/dev/null
			else
				tool_flag=1
			fi
		;;
		HardDisk)
			if [ -f ./disktool ]
			then
				chmod +x "${pwd}/tools/disktool"
			else 
				tool_flag=1
			fi
			
			if [ -f ./storcli64 ]
			then
				chmod +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 777 -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 +x "${pwd}/tools/runDiag" 
				chmod +x "${pwd}/tools/b57ldiagi64"
			else 
				tool_flag=1
			fi
		;;
		*)
		;;
	esac
	
	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}
}

#get device info by tools
get_device_info(){
	case ${tool_type} in
		mega)
			get_device_mega
		;;
		LSI2308)
			get_device_2308
		;;
		LSI3008)
			get_device_3008
		;;
		LSI3416-IT)
			get_device_34xxIT
		;;
		LSI3408IT)
			get_device_34xxIT
		;;		
		pmcluxor)
			get_device_pmcluxor
		;;			
		Intel)
			get_device_intel
		;;
		ES3000)
			get_device_ES3000
		;;
		MellanoxCX3|MellanoxCX4)
			get_device_Mellanox
		;;
		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/3004 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)
	local fw_dev=0
	local num_index=$("${pwd}/tools/sas3ircu" list |grep -i "3008" |grep -v "IT"|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}')
		fw_version=$(cat "${pwd}/version.xml" |grep -i "<Version>"|awk 'BEGIN{FS=">"}{print $2}'|awk 'BEGIN{FS="<"}{print $1}')
		device_index[$dev_num]=$i
		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 3416IT device
get_device_34xxIT(){
	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_device_pmcluxor(){
	"${pwd}/tools/arcconf" >tmp_pmcluxor.txt 2>/dev/null
	local num_pmcluxor=$(cat tmp_pmcluxor.txt |grep -i "Controllers found" |awk 'BEGIN{FS=" "}{print $3}') 
	echo 
	for ((i=1; i<=num_pmcluxor; i++))
	do
		"${pwd}/tools/arcconf" getconfig $i ad >tmp_luxor_bdf.txt 2>/dev/null
		bus_num[$dev_num]=$(cat tmp_luxor_bdf.txt |grep -i "PCI Address" |awk 'BEGIN{FS=": "}{print $2}' |awk 'BEGIN{FS=":"}{print $2}')
		device_num[$dev_num]=$(cat tmp_luxor_bdf.txt |grep -i "PCI Address" |awk 'BEGIN{FS=": "}{print $2}' |awk 'BEGIN{FS=":"}{print $3}')
		function_num[$dev_num]=$(cat tmp_luxor_bdf.txt |grep -i "PCI Address" |awk 'BEGIN{FS=": "}{print $2}' |awk 'BEGIN{FS=":"}{print $4}')
		
		#get base info
		lspci -s "${bus_num[$dev_num]}:${device_num[$dev_num]}.${function_num[$dev_num]}" -xx >base_info_luxor.txt
		vendor_id=$(sed -n '2p' base_info_luxor.txt |awk 'BEGIN{FS=" "}{print $3}')$(sed -n '2p' base_info_luxor.txt |awk 'BEGIN{FS=" "}{print $2}')
		device_id=$(sed -n '2p' base_info_luxor.txt |awk 'BEGIN{FS=" "}{print $5}')$(sed -n '2p' base_info_luxor.txt |awk 'BEGIN{FS=" "}{print $4}')
		sub_vid=$(sed -n '4p' base_info_luxor.txt |awk 'BEGIN{FS=" "}{print $15}')$(sed -n '4p' base_info_luxor.txt |awk 'BEGIN{FS=" "}{print $14}')
		sub_did=$(sed -n '4p' base_info_luxor.txt |awk 'BEGIN{FS=" "}{print $17}')$(sed -n '4p' base_info_luxor.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_luxor.txt 2>/dev/null
			continue
		fi		
		device_index[$dev_num]=$i
		rm base_info_luxor.txt 2>/dev/null
		
		#init BDF flag
		BDF_select[$dev_num]=0		
		let dev_num=$dev_num+1		
		
	done
}





#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=""
	local x64sas2_file=""
	
	#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
		
		echo "${file_name}" | grep -i "x64sas2" >/dev/null
		if [ $? == 0 ]
		then
			x64sas2_file="${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
	
	./sas2flash -c ${device_index[$index]} -list | grep -i "SAS Address" | awk '{print $4}' > "${pwd}/tmp_SASADD.log"
	SAS1=`cat tmp_SASADD.log | awk -F- '{print $1}'`
	SAS2=`cat tmp_SASADD.log | awk -F- '{print $2}'`
	SAS3=`cat tmp_SASADD.log | awk -F- '{print $3}'`
	SAS4=`cat tmp_SASADD.log | awk -F- '{print $4}'`	
	rm -rf "./tmp_SASADD.log" 2>/dev/null
	
	./sas2flash -o -c ${device_index[$index]} -e 3
	#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 x64sas2 if file exists
	if [ -f "${pwd}/${fw_path}/${x64sas2_file}" ]
	then
		"${pwd}/tools/sas2flash" -c ${device_index[$index]} -b "${pwd}/${fw_path}/${x64sas2_file}" >>"${pwd}/work.log"	
		if [ $? != 0 ]
		then
			flag_fail=1
		fi	
	fi	
	
	./sas2flash -o -c ${device_index[$index]} -sasadd $SASADD >>"${pwd}/work.log"
}

#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=""
	local efidriver=""
	
	#get FW files by type
	for file_name in $(ls "${pwd}/${fw_path}")
	do 		
		echo "${file_name}" |egrep -i "P12|3008IR.bin" >/dev/null
		if [ $? == 0 ]
		then
			ir_fw="${file_name}"
		fi  

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

		echo "${file_name}" |grep -i "9300" >/dev/null
		if [ $? == 0 ]
		then
			it_stdfw="${file_name}"
		fi 
		
		echo "${file_name}" |grep -i "mptsas3" >/dev/null
		if [ $? == 0 ]
		then
			rom="${file_name}"
		fi 
		
		echo "${file_name}" |grep -i "mpt3x64" >/dev/null
		if [ $? == 0 ]
		then
			efidriver="${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
	#text
	chmod +x "${pwd}/flashoem"
	"${pwd}/tools/sas3flash" -c ${device_index[$index]} -list | grep -i "SAS Address" | awk '{print $4}' > "tmp_SASADD.log"
		SAS1=`cat tmp_SASADD.log | awk -F- '{print $1}'`
		SAS2=`cat tmp_SASADD.log | awk -F- '{print $2}'`
		SAS3=`cat tmp_SASADD.log | awk -F- '{print $3}'`
		SAS4=`cat tmp_SASADD.log | awk -F- '{print $4}'`
		SASADD="${SAS1}${SAS2}${SAS3}${SAS4}"
		
		TRACE=`${pwd}/tools/sas3flash -c ${device_index[$index]} -list | grep -i "Tracer Number" | awk '{print $5}'`
	#clear
	"${pwd}/tools/sas3flash" -o -c ${device_index[$index]} -e 3  >>"${pwd}/work.log"
	#upgrade
	if [ -f "${pwd}/${fw_path}/${fw}" ]
	then	
		"${pwd}/tools/sas3flash" -o -c ${device_index[$index]} -f "${pwd}/${fw_path}/${fw}" >>"${pwd}/work.log"	
		if [ $? != 0 ]
		then
			"${pwd}/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	
	else
		flag_fail=1
	fi

	#upgrade rom if file exists
	if [ -f "${pwd}/${fw_path}/${rom}" ]
	then
		"${pwd}/tools/sas3flash" -o -c ${device_index[$index]} -b "${pwd}/${fw_path}/${rom}" >>"${pwd}/work.log"
		if [ $? != 0 ]
		then
			flag_fail=1
		fi
	else
		flag_fail=1
	fi
	
	#upgrade efidriver if file exists
	if [ -f "${pwd}/${fw_path}/${efidriver}" ]
	then
		"${pwd}/tools/sas3flash" -o -c ${device_index[$index]} -b "${pwd}/${fw_path}/${efidriver}" >>"${pwd}/work.log"
		if [ $? != 0 ]
		then
			flag_fail=1
		fi	
	else
		flag_fail=1
	fi	
	#write
	"${pwd}/tools/sas3flash" -o -c ${device_index[$index]} -sasadd $SASADD > "fwtmp.log"
	if [ $? != 0 ]
	then
		flag_fail=1
	fi
	"${pwd}/tools/sas3flash" -o -c ${device_index[$index]} -tracer $TRACE > "fwtmp.log"
	if [ $? != 0 ]
	then
		flag_fail=1
	else
		rm -f "tmp_SASADD.log" 2>/dev/null
		rm -f "fwtmp.log" 2>/dev/null
	fi
}

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

	local bios_fw=""
	local it_fw=""
	local efibios_fw=""
	
	#get FW files by type
	for file_name in $(ls "${pwd}/${fw_path}")
	do 		
		echo "${file_name}" |grep -i "mpt35sas_legacy" >/dev/null
		if [ $? == 0 ]
		then
			bios_fw="${file_name}"
		fi  

		echo "${file_name}" |grep -i "3416IT.rom" >/dev/null
		if [ $? == 0 ]
		then
			it_fw="${file_name}"
		fi 
	   
		echo "${file_name}" | grep -i "mpt35sas_x64" >/dev/null
		if [ $? == 0 ]
		then
			efibios_fw="${file_name}"
		fi  
	
	done
	
	
	##upgrade bios file if file exists
	if [ -f "${pwd}/${fw_path}/${bios_fw}" ]
	then
		"${pwd}/tools/storcli64" /c${device_index[$index]} download bios file="./${bios_fw}" >>"${pwd}/work.log"	
		if [ $? != 0 ]
		then
			flag_fail=1
		fi	
	else
		flag_fail=1
	fi

	#upgrade it file if file exists
	if [ -f "${pwd}/${fw_path}/${it_fw}" ]
	then
		"${pwd}/tools/storcli64" /c${device_index[$index]} download file="./${it_fw}" noverchk >>"${pwd}/work.log"
		if [ $? != 0 ]
		then
			flag_fail=1
		fi	
	else
		flag_fail=1
	fi
	
	#upgrade efibios file if file exists
	if [ -f "${pwd}/${fw_path}/${efibios_fw}" ]
	then
		"${pwd}/tools/storcli64" /c${device_index[$index]} download efibios file="./${efibios_fw}" >>"${pwd}/work.log"
		if [ $? != 0 ]
		then
			flag_fail=1
		fi	
	else
		flag_fail=1
	fi	
}

lsi_3408it_upgrade(){	
	local fw_path=""
	if [ -d "${pwd}/${fw_file}" ]
	then
		fw_path="${fw_file}"
	fi

	local bios_fw=""
	local it_fw=""
	local efibios_fw=""
	
	#get FW files by type
	for file_name in $(ls "${pwd}/${fw_path}")
	do 		
		echo "${file_name}" |grep -i "mpt35sas_legacy.rom" >/dev/null
		if [ $? == 0 ]
		then
			bios_fw="${file_name}"
		fi  

		echo "${file_name}" |grep -i "3408IT.rom" >/dev/null
		if [ $? == 0 ]
		then
			it_fw="${file_name}"
		fi 
	   
		echo "${file_name}" | grep -i "mpt35sas_x64.rom" >/dev/null
		if [ $? == 0 ]
		then
			efibios_fw="${file_name}"
		fi  
	
	done
	
	
	##upgrade bios file if file exists
	if [ -f "${pwd}/${fw_path}/${bios_fw}" ]
	then
		"${pwd}/tools/storcli64" /c${device_index[$index]} download bios file="./${bios_fw}" >>"${pwd}/work.log"	
		if [ $? != 0 ]
		then
			flag_fail=1
		fi	
	else
		flag_fail=1
	fi

	#upgrade it file if file exists
	if [ -f "${pwd}/${fw_path}/${it_fw}" ]
	then
		"${pwd}/tools/storcli64" /c${device_index[$index]} download file="./${it_fw}" noverchk >>"${pwd}/work.log"
		if [ $? != 0 ]
		then
			flag_fail=1
		fi	
	else
		flag_fail=1
	fi
	
	#upgrade efibios file if file exists
	if [ -f "${pwd}/${fw_path}/${efibios_fw}" ]
	then
		"${pwd}/tools/storcli64" /c${device_index[$index]} download efibios file="./${efibios_fw}" >>"${pwd}/work.log"
		if [ $? != 0 ]
		then
			flag_fail=1
		fi	
	else
		flag_fail=1
	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
		
		"${pwd}/tools/storcli64" -pdfwdownload -physdrv[${device_index[$index]}] -f "./${fw_file}" -a${raid_index[$index]}  >>"${pwd}/work.log" 2>/dev/null
		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	
}

#upgrade FW 
upgrade_By_tools(){
	case ${tool_type} in
		MellanoxCX3|MellanoxCX4)	
			flint -y -d ${device_index[$index]} -i "${pwd}/${fw_file}" -allow_psid_change b >>"${pwd}/work.log"			
			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		
		;;
		LSI3416-IT)
			lsi3416it_upgrade
		;;
		LSI3408IT)
			lsi_3408it_upgrade
		;;		
		pmcluxor)
			"${pwd}/tools/arcconf" romupdate ${device_index[$index]} "./${fw_file}" noprompt >>"${pwd}/work.log"
			if [ $? != 0 ]
			then
				flag_fail=1
			fi	
		;;		
		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 777 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)
			"${pwd}/tools/eeupdate64e" /NIC=${device_index[$index]} /d "${pwd}/${fw_file}"  >>"${pwd}/work.log"
			if [ $? != 0 ]
			then
				flag_fail=1
			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
	
}



#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
	;;
	*)
	;;
esac

exit 0
