#!/bin/bash
################################################################
#说明：这个脚本用于LSI/Broadcom SAS HBA卡的固件升级.
#作者：Sky.Zhang
#脚本名：update.sh
#版本：1.0
#发布时间：2021/11/12
##############################################################
#更新时间：2021/11/19
#更新列表：
#1. 支持多张卡更新.
#2. 支持不同固件类型更新。
################################################################
#更新时间：2021/11/23
#更新列表：
#1. 支持标卡、OEM卡的型号识别和固件更新。
###############################################################
#版本：1.1
#发布时间：2021/12/02
#作者：sky.zhang
#变更列表：
#1.删除固件升级中resetnow参数（由于SAS HBA不支持在线固件升级固件）。
###################################################################
#版本：1.2
#发布时间：2021/12/08
#作者：sky.zhang
#变更列表：
#1. 增加日志删除功能。
#2. 修复因文件命名有特殊符号导致的异常报错。
#3. 调整过滤条件为关键字
################################################################### 

CURRENT_DIR="`cd $(dirname $0);pwd`"
cd ${CURRENT_DIR}
source "${CURRENT_DIR}/fw_update.conf"
TEMP_FILE=SAS3008.temp
PCI_ADDRESS_TEMP=pci_address.temp
FW_VESION=""
FW_FILE=""

function clear_logs() {
	rm -rf "${CURRENT_DIR}/${TEMP_FILE}" "${CURRENT_DIR}/${PCI_ADDRESS_TEMP}"

}


#DELL H330固件升级代码
function dell_h330_update() {
	cd ${CURRENT_DIR}
	#判断DELL存储控制器工具是否安装，没有安装，则yum安装
	if [ ! -f "${DELL_FW_FLASH_TOOL}" ]; then
		yum install perccli -y
		DELL_FW_FLASH_TOOL="/opt/MegaRAID/perccli/perccli64"
	fi
	#再次判断是否DELL存储控制器工具是否安装，没有代表上一步安装失败，退出固件升级进程
	if [ ! -f "${DELL_FW_FLASH_TOOL}" ]; then
		echo -e "缺少控制器固件升级工具，停止固件升级。"
		exit 0x01
	fi

	#查询DELL控制器数量	
	DELL_CONTROLLER_COUNT=`${DELL_FW_FLASH_TOOL} show ctrlcount | grep "Controller Count" | awk '{print $NF}'`
		
	for((DELL_CTRL_ID=0;DELL_CTRL_ID<${DELL_CONTROLLER_COUNT};DELL_CTRL_ID++))
	do
		#判断当前控制器的PCI 地址和要执行固件升级的设备的地址是否一致，一致执行固件升级，不一致，退出固件升级。
		DELL_PCI_ADDRESS="`echo ${1} | sed 's/\(.*\)\.\(.*\)/\1:\2/'`"
		if [ "`${DELL_FW_FLASH_TOOL} /c${DELL_CTRL_ID} show all | grep "${DELL_PCI_ADDRESS}"`" != "" ];then	
			DELL_CURRENT_FW_VERSION="`${DELL_FW_FLASH_TOOL} /c${DELL_CTRL_ID} show | grep -i "FW Version" | awk '{print $NF}'`"
			if [ "${DELL_CURRENT_FW_VERSION}" != "${DELL_SAS3008IMR_FW_VERSION}" ]; then
				${DELL_FW_FLASH_TOOL} /c${DELL_CTRL_ID} download file="${CURRENT_DIR}/${DELL_SAS3008IMR_FW_FILE}" noverchk
				sleep 5s
				echo -e "存储控制器固件版本已完成升级，重启后生效。"
			else
				echo -e "存储控制器${DELL_CTRL_ID}当前固件版本已为标准版本:${DELL_CURRENT_FW_VERSION}，不需要再更新。"
			fi
		else
			echo -e "固件和存储控制器${DELL_CTRL_ID}型号不匹配。"
			exit 0x02
		fi
	done
}


function comm_3008_update() {


	#$1:设备编号
	#$2:设备当前固版本
	#$3:固件版本标准
	#$4:固件更新源文件
	function fw_check_update() {
		if [ "${2}" != "${3}" ];then
			${CURRENT_DIR}/${COMM_FW_FLASH_TOOL} -o -c ${1} -f "${CURRENT_DIR}/${4}"
		
			sleep 5s
			echo -e "存储控制器$1固件版本已完成升级，重启后生效。"
		else
			echo -e "存储控制器$1当前固件版本已为标准版本:${CURRENT_FW_VERSION}，不需要再更新。"
		fi
	}

	function mptsas3_check_update() {

		if [ "${2}" != "${MPTSAS3_VERSION}" ]; then
			${CURRENT_DIR}/${COMM_FW_FLASH_TOOL} -c ${1} -b "${CURRENT_DIR}/${MPTSAS3_FILE}"
			sleep 5s
			echo -e "存储控制器${1}:BIOS已完成升级。"
		else
			echo -e "存储控制器${1}当前BIOS固件版本已为标准版本:${2}，不需要再更新。"
		fi

	}

	function mpt3x64_check_update() {

		if [ "${2}" != "${MPT3X64_VERSION}" ]; then
			${CURRENT_DIR}/${COMM_FW_FLASH_TOOL} -c ${1} -b "${CURRENT_DIR}/${MPT3X64_FILE}"
			sleep 5s
			echo -e "存储控制器${1}:UEFI BSD 已完成升级。"
		else
			echo -e "存储控制器${1}:UEFI BSD固件版本已为标准版本:${2}，不需要再更新。"
		fi
	}



	#获取控制器数量
	COMM_CONTROLLER_COUNT=`${CURRENT_DIR}/${COMM_FW_FLASH_TOOL} -list | grep "Controller Number" -c`

	for((COMM_CTRL_ID=0;COMM_CTRL_ID<${COMM_CONTROLLER_COUNT};COMM_CTRL_ID++))
	do
	
		${CURRENT_DIR}/${COMM_FW_FLASH_TOOL} -list -c ${COMM_CTRL_ID} > ${CURRENT_DIR}/${TEMP_FILE}
		COMM_PCI_ADDRESS="`echo ${1} | sed 's/\(.*\)\.\(.*\)/\1:\2/' `"

		CURRENT_FW_VERSION="`grep 'Firmware Version' ${CURRENT_DIR}/${TEMP_FILE} | awk '{print $NF}'`"
		CURRENT_MPTSAS3_VERSION="`grep 'BIOS Version' ${CURRENT_DIR}/${TEMP_FILE} | awk '{print $NF}'`"
		CURRENT_MPT3X64_VERSION="`grep 'UEFI BSD Version' ${CURRENT_DIR}/${TEMP_FILE}  | awk '{print $NF}'`"
		FW_TYPE="`grep 'Firmware Product ID' ${TEMP_FILE} | cut -d ':' -f 2 |sed 's/^ //g' `"		


		if [ "${FW_TYPE}" == "${IT_FW_LABEL}" ]; then
			FW_FILE="${COMM_IT_FW_FILE}"
		fi	
		
		#符合标准的厂商/设备的主/子ID的设备，方可以执行固件升级，否则反馈设备和固件类型不匹配。
		if [ "`grep -i "${2}" ${CURRENT_DIR}/${SSID_LIB_FILE} | grep -iE "9311-8i|inspur|Broadcom / LSI Device_SAS3008"`" != "" ];then
			FW_FILE="${COMM_IR_FW_FILE}"
			FW_VERSION="${STANDARD_FW_VERSION}"
		elif [ "`grep -i "${2}" ${CURRENT_DIR}/${SSID_LIB_FILE} | grep -i "SH08-L3008"`" != "" ];then
			FW_FILE="${SUGON_SAS3008IR_FW_FILE}"
			FW_VERSION="${SUGON_SAS3008_FW_VERSION}"
		elif [ "`grep -i "${2}" ${CURRENT_DIR}/${SSID_LIB_FILE} | grep -i "ASUSTek"`" != "" ];then
			FW_FILE="${ASUS_SAS3008IR_FW_FILE}"
			FW_VERSION="${ASUS_SAS3008_FW_VERSION}"
		elif [ "`grep -i "${2}" ${CURRENT_DIR}/${SSID_LIB_FILE} | grep -i "quanta"`" != "" ];then
			FW_FILE="${QUANTA_SAS3008IR_FW_FILE}"
			FW_VERSION="${QUANTA_SAS3008_FW_VERSION}"
		elif [ "`grep -i "${2}" ${CURRENT_DIR}/${SSID_LIB_FILE} | grep -i "gigabyte"`" != "" ];then
			FW_FILE="${GIGABYTE_SAS3008IR_FW_FILE}"
			FW_VERSION="${GIGABYTE_SAS3008_FW_VERSION}"
		elif [ "`grep -i "${2}" ${CURRENT_DIR}/${SSID_LIB_FILE} | grep -i "foxconn"`" != "" ];then
			FW_FILE="${FOXCONN_SAS3008IR_FW_FILE}"
			FW_VERSION="${FOXCONN_SAS3008_FW_VERSION}"
		elif [ "`grep -i "${2}" ${CURRENT_DIR}/${SSID_LIB_FILE} | grep -i "Super Micro"`" != "" ];then
                        FW_FILE="${SUPERMIRCO_SAS3008IR_FW_FILE}"
                        FW_VERSION="${SUPERMIRCO_SAS3008_FW_VERSION}"	
		else 
			echo -e "存储控制器${CTRL_ID}和固件类型不匹配,停止更新。"
			break
		fi
		
		fw_check_update ${COMM_CTRL_ID} ${CURRENT_FW_VERSION} ${FW_VERSION} "${FW_FILE}"
		
		mptsas3_check_update ${COMM_CTRL_ID} ${CURRENT_MPTSAS3_VERSION}
		mpt3x64_check_update ${COMM_CTRL_ID} ${CURRENT_MPT3X64_VERSION}
	done
}


function main() {
	clear_logs
	#获取控制器数量
	#CONTROLLER_COUNT=`${CURRENT_DIR}/${FW_FLASH_TOOL} -list | grep "Controller Number" -c`
	lspci | grep "${KEYWORD}" | awk '{print $1}' > ${PCI_ADDRESS_TEMP}	


	while read PCI_ADDRESS
	do
		SSID_PREFIX="`lspci -n -s ${PCI_ADDRESS} | awk '{print $(NF-2)}'`"
		SSID_STUFFIX="`lspci -vn -s ${PCI_ADDRESS} | grep 'Subsystem:' | awk '{print $NF}'`"
		if [ "`grep -i "${SSID_PREFIX}:${SSID_STUFFIX}" ${SSID_LIB_FILE} | grep -i dell`" != "" ]; then
			dell_h330_update "${PCI_ADDRESS}"
		else 
			comm_3008_update "${PCI_ADDRESS}" "${SSID_PREFIX}:${SSID_STUFFIX}"		
		fi
		
	done < ${PCI_ADDRESS_TEMP}
	clear_logs
}

main
