#!/bin/bash

#***********************************************************************#
#                                                                       #
#                               NOTICE                                  #
#                                                                       #
#                  COPYRIGHT 2005 QLOGIC CORPORATION               	#
#                        ALL RIGHTS RESERVED                            #
#                                                                       #
#  This computer program is CONFIDENTIAL  and contains TRADE SECRETS of #
#  QLOGIC CORPORATION.  The  receipt or possession of this program does #
#  not convey any rights to reproduce or disclose  its contents,  or to #
#  manufacture, use, or sell anything that it may describe, in whole or #
#  in part, without the specific written consent of QLOGIC CORPORATION. #
#  Any reproduction of this program without the express written consent #
#  of QLOGIC CORPORATION  is a violation of the copyright laws and  may #
#  subject you to civil liability and criminal prosecution.             #
#                                                                       #
#***********************************************************************#

#***********************************************************************#
#                   		qlinstall				#
#		                ----------		   		#		
#							    		#
#   QLogic FC/ISCSI HBA Driver Ease of Installation Script  		#
#							    		#
#							    		#
# Support:						    		#
#	 Kernel version: 2.4.x, 2.6.x			    		#
#	 FC Driver version: 7.x, 8.x			    		# 
#	 ISCSI Driver version: 3.x			    		#
#							    		#
#	 Distribution  :				    		#
#		RedHat Enterprise Linux (RHEL) : 3.0/4.0    		#
#		SuSE Enterprise Linux (SLES): 8.0/9.0	    		#
#	        Asianux : 1.0				    		#
#							    		#	
#***********************************************************************#

QL_INSTALLER_VERSION=1.00.01
# This script can be used for installation of both
# FC and iSCSI HBA. Following two flags govern the
# installation. 
QL_FC_INSTALLATION=0
QL_iSCSI_INSTALLATION=0

QL_INSTALLER=$0
QL_INSTALL_LOG="qlinstall_log"
QL_UPGRADE=0

# Installation script names
QL_FC_INSTALLER="./ql-fc-install"
QL_iSCSI_INSTALLER="./ql-iscsi-install"
QL_ALL_INSTALLER="./qlinstall"

DEBUG_ON=0 #Make it 0 on release
# Remember the same DRIVE name is used to detect previous installations 
QL_FC_DRIVER_NAME="" # See get_driver_details()
QL_FC_DRIVER_VERSION="" # See get_driver_details()
QL_iSCSI_DRIVER_NAME="" # See get_driver_details()
QL_iSCSI_DRIVER_VERSION="" # See get_driver_details()
QL_LD_DRIVER_VERSION="" # Global, see get_ld_driver_version
QL_FC_BACKUP_DIR=""
QL_iSCSI_BACKUP_DIR=""


KERNEL_VERSION=`uname -r`
KERNEL_MAJ_MIN=`echo $KERNEL_VERSION | cut -d . -f -2`
#SUPPORTED_KERNLE_VER is appended by create_dist script
SUPPORTED_KERNEL_VER=""


# Get the distribution
QL_DISTRIBUTION=""
DISTRO_SUSE="suse"
DISTRO_REDHAT="redhat"
DISTRO_ASIANUX="asianux"
DISTRO=""
if [ -f "/etc/SuSE-release" ]; then
	read DISTRO < "/etc/SuSE-release"
	QL_DISTRIBUTION=$DISTRO_SUSE
elif [ -f "/etc/asianux-release" ]; then
	read DISTRO < "/etc/asianux-release"
	QL_DISTRIBUTION=$DISTRO_ASIANUX
elif [ -f "/etc/redhat-release" ]; then 
	read DISTRO < "/etc/redhat-release"
	QL_DISTRIBUTION=$DISTRO_REDHAT
fi

QL_INITRD_MOD="" #Var containing the INITRD_MODULES line from /etc/sysconfig/kernel

QL_FC_ISP_LIST=( 2100 2200 2200A 2300 2312 2322 6312 6322 2400 2422 2432 )
QL_iSCSI_ISP_LIST=( 4000 4010 4022 4040 ) 
#QL_iSCSI_ISP_LIST=( 4000 4010 )
QL_FC_MOD_LIST=( 2100 2200_conf 2300_conf 2200 2300 2322 2400 6312 23xx_conf 2xxx_conf 2xxx  )
QL_iSCSI_MOD_LIST=( 4000 4010 4022)
QL_FC_HBA="FC"
QL_iSCSI_HBA="iSCSI"
QL_INSTALLED_HBA=( ) # Array with element [0]: FC, element [1]: iSCSI
QL_HBA_LIST=( ) # Array of all the HBAs installed in the system
	        # use to load and unload the driver
QL_FC_HBA_LIST=( ) # Persistent list of FC HBAs
QL_HBA_MODULES=( ) # ISP to modules converted array
QL_iSCSI_HBA_LIST=( )
QL_USR_SRC="/usr/src/qlogic"
QL_DRIVER_SRC=""
QL_BUILD_SCRIPT=""
QL_BUILD_FC="build_fc_qla2x00.sh"
QL_BUILD_iSCSI="build_iscsi_qla4x00.sh"
QL_BUILD_FC26="extras/build.sh"
QL_BUILD_iSCSI26="UNKNOWN"
QL_PROC=/proc/scsi/
QL_SYSCONF_K="/etc/sysconfig/kernel"	
QL_MOD_REMOVED="" #list of modules removed from 
						      #modules conf file
QL_DEVICE_INFO="ql_device_info"

QL_DO_BIND=1 # On by default
QL_MOD_CONF=""
QL_MOD_FILE="" 
QL_TMP_MOD_FILE=/etc/ql_tmp_mod

# Function return status
QL_SUCCESS=0
QL_FAIL=1
QL_FORCE_INSTALLATION=2
QL_BEGIN=3
QL_DONE=4
# Old package installation state
QL_INSTALLED=5 # Same one installed
QL_LATEST_INSTALLED=6 # Newer one installed
QL_OLD_INSTALLED=7 # Older one installed
QL_NOT_INSTALLED=8 # Not installed


SPC="    " # 4 space
RETURN_VAL=""
BACKUP=0
NO_BACKUP=1
QL_CLEAR_MOD=0; #Global off by default, used to clear any modules
		#already there in modprobe.conf or /etc/sysconfig/kernel

RM_MOD="modprobe -r"

# --------------------------------------------------------- #
# debug_print ()	                                    #
# Prints debug messages if verbose is on		    #
# Parameter: 						    #
#	$1	Message to be printed			    #
# Returns: None.		 			    #
# --------------------------------------------------------- #
function debug_print() {
	if [ $DEBUG_ON = 1 ]; then
		echo $1
	fi
	return $QL_SUCCESS
}

# --------------------------------------------------------- #
# echo_b()		                                    #
# Prints messages in bold				    #
# Parameter: 						    #
#	$1	Message to be printed			    #
# Returns: None.		 			    #
# --------------------------------------------------------- #

function echo_b() {
	echo -en "\033[1m${1}\033[0m"
	tput sgr0
}

# --------------------------------------------------------- #
# check_path()		                                    #
# Checks if /sbin and /usr/sbin are in path		    #
# if not then add them in the path variable		    #
# Parameter: None					    #
# Returns: None.		 			    #
# --------------------------------------------------------- #
function check_path() {
	#check for /usr/sbin
	ADD_PATH="\/usr\/sbin"
	echo $PATH | grep ":$ADD_PATH:" >& /dev/null ||
	echo $PATH | grep "^$ADD_PATH:" >& /dev/null ||
	echo $PATH | grep ":$ADD_PATH$"  >& /dev/null
	ret=$?
	if [ "$ret" != "0" ]; then
		export PATH=/usr/sbin:$PATH
	fi
	ADD_PATH="\/sbin"
	echo $PATH | grep ":$ADD_PATH:" >& /dev/null ||
	echo $PATH | grep "^$ADD_PATH:" >& /dev/null ||
	echo $PATH | grep ":$ADD_PATH$"  >& /dev/null
	ret=$?
	if [ "$ret" != "0" ]; then
		export PATH=/sbin:$PATH
	fi
}

# --------------------------------------------------------- #
# reset_return_val ()                                       #
# Resets the RETURN_VAL, used to return non-numeric returns #
# from functions					    #
# Parameter: None                                           #
# Returns: None.                                            #
# --------------------------------------------------------- #
function reset_return_val() {
	RETURN_VAL=""
}

# --------------------------------------------------------- #
# get_latest_rpm ()                                         #
# In case multiple rpm files are present in the current	    #
# directory, then this function bubble sorts the latest     #
# one							    #
# Parameter: 						    #
#	$1	RPM  name				    #
# Returns: RETURN_VALUE: Latest rpm file name		    #
# --------------------------------------------------------- #
function get_latest_rpm()  {
	LATEST_RPM_FILE=""
	LATEST_RPM_VERSION=""
	RPM_FILES=`ls $1-*.rpm`
	
	for RPM_FILE in $RPM_FILES
	do
		RPM_VERSION=`rpm -qp --qf %{VERSION} $RPM_FILE | sed "s/^v//"`
		if [ "$LATEST_RPM_VERSION" != "" ]; then
			compare_version $RPM_VERSION $LATEST_RPM_VERSION
			if [ $? = $QL_SUCCESS ]; then
				LATEST_RPM_FILE=$RPM_FILE
				LATEST_RPM_VERSION=$RPM_VERSION
			fi	
		else	
			LATEST_RPM_FILE=$RPM_FILE
			LATEST_RPM_VERSION=$RPM_VERSION
		fi
	done
	RETURN_VAL=$LATEST_RPM_FILE
}

# --------------------------------------------------------- #
# get_drv_rpm_version ()                                    #
# Get the driver version and rpm release version	    # 
# Parameter: 						    #
#	$1	RPM  name				    #
# Returns: QL_SUCCESS on success, QL_FAIL on failure to     #
#	   get the driver version			    #
# --------------------------------------------------------- #
function get_drv_rpm_version() {
	local ret_status=$QL_FAIL;
	get_latest_rpm $1
	RPM_FILE=$RETURN_VAL
        if [ -f "$RPM_FILE" ]; then
                debug_print "$1 exist"
                #RPM exist
                RETURN_VAL=$(rpm -qp --qf %{VERSION}-%{RELEASE} "$RPM_FILE")
		ret_status=$QL_SUCCESS
        else
                # check if RPM is already installed
                # get the version from the installed
                # RPM
                rpm -q $1 >& /dev/null
                if [ $? = $QL_SUCCESS ]; then
                        RETURN_VAL=$(rpm -q --qf %{VERSION}-%{RELEASE} "$1")
			ret_status=$QL_SUCCESS
                fi
        fi
	return $ret_status
}

# --------------------------------------------------------- #
# get_driver_version ()                                     #
# Get the driver version from the rpm file or from	    #
# the installed rpm					    #
# Parameter: 						    #
#	$1	RPM  name				    #
# Returns: QL_SUCCESS on success, QL_FAIL on failure to     #
#	   get the driver version			    #
# --------------------------------------------------------- #
function get_driver_version() {
	local ret_status=$QL_FAIL;
	# Need to take care of presence of multiple rpms
	# If multiple rpm with same name are present then pickup
	# the latest one
	get_latest_rpm $1
	LATEST_RPM_FILE=$RETURN_VAL
        if [ -f "$LATEST_RPM_FILE" ]; then
                debug_print "$1 exist"
                #RPM exist
                RETURN_VAL=$(rpm -qp --qf %{VERSION} "$LATEST_RPM_FILE")
		ret_status=$QL_SUCCESS
        else
                # check if RPM is already installed
                # get the version from the installed
                # RPM
                rpm -q $1 >& /dev/null
                if [ $? = $QL_SUCCESS ]; then
                        RETURN_VAL=$(rpm -q --qf %{VERSION} "$1")
			ret_status=$QL_SUCCESS
                fi
        fi
	return $ret_status
}

# --------------------------------------------------------- #
# get_installer_type					    #
# Based on the QL_INSTALLER set the installation type	    #
# flags							    #
# Parameter: None 		                            #
# Returns: None		 				    #
# --------------------------------------------------------- #
function get_installer_type() {
	case  $QL_INSTALLER in
		$QL_FC_INSTALLER )
			QL_FC_INSTALLATION=1
			QL_iSCSI_INSTALLATION=0
			QL_INSTALL_LOG="install-${QL_FC_DRIVER_VERSION}.log"	
		;;
		$QL_iSCSI_INSTALLER )
			QL_FC_INSTALLATION=0
			QL_iSCSI_INSTALLATION=1
			QL_INSTALL_LOG="install-${QL_iSCSI_DRIVER_VERSION}.log"	
		;;
		$QL_ALL_INSTALLER )
			QL_FC_INSTALLATION=1
			QL_iSCSI_INSTALLATION=0
			QL_INSTALL_LOG="install-${QL_FC_DRIVER_VERSION}.log"	
			#QL_INSTALL_LOG="install-${QL_FC_DRIVER_VERSION-$QL_iSCSI_DRIVER_VERSION}.log"	
		;;
		* )
			echo "Unknown installer, please check."
			echo "The installer script should be one of these"
			echo "1. $QL_FC_INSTALLER"
			echo "2. $QL_iSCSI_INSTALLER"
			echo "3. $QL_ALL_INSTALLER"
		;;
	esac
}

# --------------------------------------------------------- #
# set_install_log					    #
# Based on the QL_INSTALLER set the name of the log file    #
# Parameter: None 		                            #
# Returns: None		 				    #
# --------------------------------------------------------- #
function set_install_log() {
	case  $QL_INSTALLER in
		$QL_FC_INSTALLER )
			QL_INSTALL_LOG="ql-fc-install-${QL_FC_DRIVER_VERSION}.log"	
		;;
		$QL_iSCSI_INSTALLER )
			QL_INSTALL_LOG="ql-iscsi-install-${QL_iSCSI_DRIVER_VERSION}.log"	
		;;
		$QL_ALL_INSTALLER )
			QL_INSTALL_LOG="qlinstall-${QL_FC_DRIVER_VERSION}.log"	
		;;
	esac
}
# --------------------------------------------------------- #
# get_driver_details ()                                     #
# Get the driver name based on the kernel version	    #
# Get the driver version from the RPM			    #
# Sets the QL_BACKUP dir
# Sets the QL_MOD_CONF				            #
# Parameter: None 		                            #
# Returns: None		 				    #
# --------------------------------------------------------- #
function get_driver_details() {
	case $KERNEL_MAJ_MIN in
		2.4 )
			QL_FC_DRIVER_NAME="qla2x00" 
			QL_iSCSI_DRIVER_NAME="qla4xxx" 
			QL_MOD_CONF="/etc/modules.conf"
			QL_MOD_FILE="modules.conf"
		;;
		2.6 )
			QL_FC_DRIVER_NAME="qla2xxx" 
			QL_iSCSI_DRIVER_NAME="qla4xxx"
			if [ "$QL_DISTRIBUTION" = "$DISTRO_SUSE" ]; then
				QL_MOD_CONF="/etc/modprobe.conf.local"
				QL_MOD_FILE="modprobe.conf.local"
			else #redhat/asianux
				QL_MOD_CONF="/etc/modprobe.conf"
				QL_MOD_FILE="modprobe.conf"
			fi
		;;
		* )
			echo "Kernel version $KERNEL_VERSION not supported"
			exit 1
		;;
	esac
	# FC
	if [ $QL_FC_INSTALLATION = 1 ]; then
		get_driver_version $QL_FC_DRIVER_NAME
		if [ $? = $QL_SUCCESS ]; then
			QL_FC_DRIVER_VERSION=$RETURN_VAL
			reset_return_val
		else
			echo "ERROR: Failed to get the driver version for $QL_FC_DRIVER_NAME"
		fi		
		get_drv_rpm_version $QL_FC_DRIVER_NAME
		if [ $? = $QL_SUCCESS ]; then
			QL_DRIVER_SRC=/usr/src/qlogic/$RETURN_VAL
			QL_FC_BACKUP_DIR="$QL_DRIVER_SRC/backup"
			QL_MOD_REMOVED="$QL_DRIVER_SRC/backup/ql_mod_removed"
			reset_return_val
			if [ "$KERNEL_MAJ_MIN" = "2.4" ]; then
				QL_BUILD_SCRIPT=$QL_DRIVER_SRC/$QL_BUILD_FC
			else # 2.6
				DRIVER_VERSION=(`echo $QL_FC_DRIVER_VERSION |
							              sed "s/^.//"`)
				QL_BUILD_SCRIPT=$QL_DRIVER_SRC/qla2xxx-$DRIVER_VERSION/$QL_BUILD_FC26
			fi
		else
			echo "ERROR: Failed to get the driver/rpm version for $QL_FC_DRIVER_NAME"
		fi	
	fi

	#iSCSI
        if [ $QL_iSCSI_INSTALLATION = 1 ]; then
                get_driver_version $QL_iSCSI_DRIVER_NAME
                if [ $? = $QL_SUCCESS ]; then
                        QL_iSCSI_DRIVER_VERSION=$RETURN_VAL
                        reset_return_val
                else
                        echo "ERROR: Failed to get the driver version for $QL_iSCSI_DRIVER_NAME"
                fi
		get_drv_rpm_version $QL_iSCSI_DRIVER_NAME
		if [ $? = $QL_SUCCESS ]; then
			QL_DRIVER_SRC=/usr/src/qlogic/$RETURN_VAL
			QL_iSCSI_BACKUP_DIR="$QL_DRIVER_SRC/backup"
			reset_return_val
			if [ "$KERNEL_MAJ_MIN" = "2.4" ]; then
				QL_BUILD_SCRIPT=$QL_DRIVER_SRC/$QL_BUILD_iSCSI
			else # 2.6
				DRIVER_VERSION=(`echo $QL_FC_DRIVER_VERSION |
							              sed "s/^.//"`)
				QL_BUILD_SCRIPT=$QL_DRIVER_SRC/qla2xxx-$DRIVER_VERSION/$QL_BUILD_iSCSI26
			fi

		else
			echo "ERROR: Failed to get the driver/rpm version for $QL_iSCSI_DRIVER_NAME"
		fi	
        fi
}

# --------------------------------------------------------- #
# display_install_msg ()                                    #
# Displays the very first installation message		    #
# Parameter: 	                                            #
#	$1	BEGIN or END of installation		    #
#	$2	Name of the driver			    #
# Returns: None						    #
# --------------------------------------------------------- #
display_install_msg() {
	if [ $1 = $QL_BEGIN ]; then 
		echo ""
		echo "#*********************************************************#"
#		echo "#            QLogic HBA Linux Driver Installation         #"
		echo "#           SANsurfer Driver Installer for Linux          #"
		echo "#               Installer Version:  $QL_INSTALLER_VERSION               #"
		echo "#*********************************************************#"
	elif [ $1 = $QL_DONE ]; then

		echo -e  "" 
		echo -e "#*********************************************************#"
		echo -e "#               INSTALLATION SUCCESSFUL!!                 #"
		echo -e "#    SANsurfer Driver installation for Linux completed    #"
#		echo -e "#      QLogic HBA Linux driver installation completed.    #" 
		echo -e "#*********************************************************#"

	fi
}

# --------------------------------------------------------- #
# display_uninstall_msg ()                                  #
# Displays the very first un-installation message           #
# Parameter: None                                           #
# Returns: None                                             #
# --------------------------------------------------------- #
display_uninstall_msg() {
	if [ $1 = $QL_BEGIN ]; then
        echo ""
        echo "#*********************************************************#"
        echo "#        SANsurfer Driver for Linux Un-installation       #"
#        echo "#            QLogic HBA Linux Driver Un-installation      #"
        echo "#*********************************************************#"
	elif [ $1 = $QL_DONE ]; then
	echo ""
	echo "#*********************************************************#"
	echo "#           UN-INSTALLATION SUCCESSFUL!!                  #"
	echo "#*********************************************************#"
	fi
}

# --------------------------------------------------------- #
# compare_version ()	                                    #
# Compares the QL driver versions			    #
#Version can be 7.00.00, 8.00.04b9-fo, 8.05.00b20, 3.0	    #
# 8.00.03a, 8.00.03b					    #
# Assumption, the version number format will		    #
# always be like this,					    #
# xx.xx.xxbxx (or maj.min.patch<b: beta>xx)		    #
#							    #
# Parameter:						    # 
#	$1	Driver Version 1			    #
#	$2	Driver Version 2			    #
# Returns: 						    #
# 	QL_SUCCESS if $1 > $2				    #
# 	QL_FAIL if $1 = $2				    #
# 	QL_FAIL if $1 < $2				    #
# --------------------------------------------------------- #
function compare_version() {
	VERSION1=$(echo $1 | sed "s/^v//")
	VERSION2=$(echo $2 | sed "s/^v//")

	LEN1=`echo $VERSION1 | awk -F . "{print NF}"` 
	LEN2=`echo $VERSION2 | awk -F . "{print NF}"` 
	if [ ${LEN1} -gt  ${LEN2} ]; then
		return $QL_SUCCESS 
	elif [ ${LEN1} -lt  ${LEN2} ]; then
		return $QL_FAIL
	fi	

	for ((FIELD=1; FIELD <= LEN1 ; FIELD++))  
	do
		VER1=`echo $VERSION1 | cut -d . -f $FIELD`
		VER2=`echo $VERSION2 | cut -d . -f $FIELD`

		#check for b or beta release
		IS_BETA=`echo $VER1 | sed "s/^.*b//"`
		if [ "$IS_BETA" != "" ]; then
			#its beta remove b.*	
			VER1=`echo $VER1 | sed "s/b.*//"`
		fi

		IS_BETA=`echo $VER2 | sed "s/^.*b//"`
		if [ "$IS_BETA" != "" ]; then
			#its beta remove b.*	
			VER2=`echo $VER2 | sed "s/b.*//"`
		fi

		echo "$VER1" | grep "^[0-9]\+$" >& /dev/null
		if [ $? != 0 ]; then 
			#compare strings	
			if [[ "$VER1" > "$VER2" ]]; then
				return $QL_SUCCESS
			fi
			return $QL_FAIL
		else
			echo "$VER2" | grep "^[0-9]\+$" >& /dev/null
			if [ $? != 0 ]; then 
				#compare strings	
				if [[ "$VER1" > "$VER2" ]]; then
					return $QL_SUCCESS
				fi
				return $QL_FAIL
			fi
		fi	
		[ $VER1 -gt $VER2 ] && return $QL_SUCCESS
		[ $VER1 -lt $VER2 ] && return $QL_FAIL	
	done   

	# if we are here means so far version is same
	# now we should compare the beta version if any
	# the beta version can be extracted from 3rd field xxbxx-*
	echo "$VERSION2" | grep "b" >& /dev/null
	[ $? -ne 0 ] && return $QL_FAIL
	echo "$VERSION1" | grep "b" >& /dev/null
	[ $? -ne 0 ] && return $QL_SUCCESS

	VER1=`echo $VERSION1 | cut -d . -f 3 | sed "s/^.*b//" | sed "s/-.*//"`
	VER2=`echo $VERSION2 | cut -d . -f 3 | sed "s/^.*b//" | sed "s/-.*//"`

	if [ "$VER1" == "" ]; then
		#version 1 contains only b, its a patch
		return $QL_SUCCESS
	fi

	if [ "$VER2" == "" ]; then
		#do not override non-beta with beta
		return $QL_FAIL
	fi

	# hear means both versions have beta attached, compare 
	# and return
	[ $VER1 -gt $VER2 ] && return $QL_SUCCESS	
	[ $VER1 -lt $VER2 ] && return $QL_FAIL	

	#Here means both the version are exactly same with betas
	return $QL_FAIL
}

# --------------------------------------------------------- #
# check_installation ()	                                    #
# Checks if the driver is already installed		    #
# Display the error/warning messages also		    #
# Parameter:						    # 
#	$1	Driver Name				    #
#	$2	Driver version				    #
# Returns: QL_SUCCESS if driver already installed	    # 
#          else returns QL_FAIL 			    #
# --------------------------------------------------------- #
function check_installation() {
	DRIVER_NAME=$1
	DRIVER_VERSION=$2
	debug_print "DRIVER_NAME=${DRIVER_NAME}"

	# check if multiple installations
        # check if we can proceed with the installation
        can_uninstall $DRIVER_NAME
        if [ $? == $QL_FAIL ]; then
		exit 1
        fi

	# check if an older version of driver already installed
	OLD_DRIVER_VERSION=$(rpm -q --qf %{VERSION} $DRIVER_NAME)
	if [ $? = $QL_SUCCESS ]; then
		if [ "$OLD_DRIVER_VERSION" = "$DRIVER_VERSION" ]; then
			echo "QLogic driver $DRIVER_NAME" \
			      "version $DRIVER_VERSION is already installed."
			return $QL_INSTALLED
		else

			# Compare the versions. If greater override the current
			# if not give the warning message
			compare_version $DRIVER_VERSION $OLD_DRIVER_VERSION
			if [ $? = $QL_SUCCESS ]; then # we need to install
				echo "Warning: Found an installed driver. Version: $OLD_DRIVER_VERSION"
				echo "Overriding the already installed version...."
				echo ""
				sleep 4
				return $QL_OLD_INSTALLED
			else
				echo "ERROR: Found an installed driver. Version: $OLD_DRIVER_VERSION"
				echo "Aborting the installation..."
				echo "To install version $DRIVER_VERSION, " \
		              	"uninstall the $OLD_DRIVER_VERSION version first"
			      	echo "using command $QL_INSTALLER --uninstall"	
				return $QL_LATEST_INSTALLED
			fi
		fi
	fi
	return $QL_NOT_INSTALLED #Driver not already installed
} 

# --------------------------------------------------------- #
# check_cli_installed					    #
# Checks if CLI is installed or not.			    #
# If not installed then installs it			    #
#							    #
# Parameter: None 		                            #
# Returns: QL_SUCCESS if installation OK or CLI already	    #
#	   installed else QL_FAIL			    #
# --------------------------------------------------------- #
function check_cli_installed() {
	local ret_status=$QL_SUCCESS

	if [ $QL_FC_INSTALLATION = 1 ]; then
		SCLI=scli

		# Check if scli is installed
		#echo ""
		#echo "Checking scli installation...."
		rpm -q $SCLI >& /dev/null
		ret_status=$?
		if [ `uname -m` = "ia64" ]; then
			SCLI=`ls scli*ia64.rpm`
		elif [ `uname -m` = "ppc64" ]; then
			SCLI=`ls scli*ppc64.rpm`
		else
			SCLI=`ls scli*i386.rpm`
		fi

		if [ $ret_status = $QL_FAIL ]; then
			# Install the scli
					
			if [ -f $SCLI ]; then
				echo "Installing scli...."
				rpm -Uvh $SCLI
				ret_status=$?
			else
				echo "Unable to locate the SCLI rpm..."
				echo "Please install and use SCLI manually."
				ret_status=$QL_FAIL
			fi	
		else
			#check the version of installer and rpm are same
			#if local is greater then re-install
			# compare the scli version into driver version format
			# make the release as betw version, so that the compare
			#version works properly
			INSTALLED_SCLI_VER=`rpm -q --qf %{version}b%{release} scli`
			LOCAL_SCLI_VER=`rpm -qp --qf %{version}b%{release} $SCLI`
			
			compare_version $LOCAL_SCLI_VER $INSTALLED_SCLI_VER
			if [ $? = 0 ]; then
				echo "Installing scli...."
				rpm -e scli
				rpm -Uvh $SCLI
				ret_status=$?
			fi
		fi

		#if all good, then enable SCLI to support QLA200
		if [ $ret_status = $QL_SUCCESS ]; then
			SCLI_PROP_FILE="/opt/QLogic_Corporation/SANsurferCLI/sfcli.properties"
			SCLI_TMP_FILE="/tmp/sfcli.properties"
			SCLI_PROP_NAME="node.hba.qla2xx.support.addon"	
			if [ -f "$SCLI_PROP_FILE" ]; then
				SCLI_PROP_VAL=`cat $SCLI_PROP_FILE | grep "${SCLI_PROP_NAME}.*" | cut -d = -f 2`
				if [ "$SCLI_PROP_VAL" = "" ] || [ "$SCLI_PROP_VAL" = "0" ]; then
					cat "$SCLI_PROP_FILE" | sed "s/${SCLI_PROP_NAME}.*/${SCLI_PROP_NAME}=1/" > $SCLI_TMP_FILE
					if [ -f "$SCLI_TMP_FILE" ]; then
						mv -f $SCLI_TMP_FILE $SCLI_PROP_FILE
					else
						echo "Unable to create tmp scli property file."
					fi
				fi
			else
				echo "Unable to locate SCLI property file."
				echo " "
			fi	
			
		fi
	fi

	if [ $QL_iSCSI_INSTALLATION = 1 ]; then
		SCLI="./scix"
		if [ `uname -m` = "ppc64" ]; then
			SCLI_TGZ="./scix_linPPC*.tgz"
		else
			SCLI_TGZ="./scix_linx86*.tgz"
		fi

		if [ -f $SCLI ]; then
			ret_status=$QL_SUCCESS
		else
			if [ -f $SCLI_TGZ ]; then
				tar -xzf $SCLI_TGZ
				ret_status=$?
			else
				echo "Unable to locate SANsurfer CLI package."
				ret_status=$QL_FAIL
			fi
		fi	
	fi
	return $ret_status
}

# --------------------------------------------------------- #
# set_modules_for_options()                                 #
# Sets the QL_HBA_MODULES arrays to the module name used in #
# modules.conf or modprobe.conf/.local for specifying the   #
# driver command line options				    #
# options qla2300.... or options qla2xxx....	            #
#							    #
# Parameter: None					    #
# Returns: None						    #
# --------------------------------------------------------- #
function set_modules_for_options() {
	#clear the modules array
	QL_HBA_MODULES=( )
	case $KERNEL_MAJ_MIN in
		2.6 )
			QL_HBA_MODULES=( 2xxx )
		;;
		2.4 )

		detect_all_isp
		convert_isp_to_modules
		;;
	esac
} 

# --------------------------------------------------------- #
# is_failover_enabled()                                     #
# Detects if failover is enabled in modules.conf (2.4) or   #
# modprobe.conf/modprobe.conf/.local (2.6)                  #
#							    #
# Parameter:None					    #
# Returns:						    # 
#	QL_SUCCESS: If failover enabled			    #
#	QL_FAIL: If failover disabled			    #
# --------------------------------------------------------- #
function is_failover_enabled() { 
	#get the ql2xfailover parameter from the modprobe
	set_modules_for_options
	for ISP in "${QL_HBA_MODULES[@]}"  
	do
		FAILOVER=`grep "^[[:space:]]*options[[:space:]]\+qla${ISP}" $QL_MOD_CONF | sed "s/.*\(ql2xfailover=.\).*/\1/"`
		#get the value
		if [ "$FAILOVER" = "" ]; then
			return $QL_FAIL
		fi
		FAILOVER_VALUE=`echo $FAILOVER | cut -d = -f 2`
		if [ "$FAILOVER_VALUE" = "1" ]; then
			return $QL_SUCCESS
		fi
	done
	return $QL_FAIL
}

# --------------------------------------------------------- #
# update_configrequired()                                   #
# Enables or disables ConfigReqired 			    #
# and ql2xuseextopts
#							    #
# Parameter:						    #
#	$1	Enable: 1			            #
#		Disable: 0			            #
# Returns: QL_SUCCESS/QL_FAIL
# --------------------------------------------------------- #
function update_configrequired() {
	local OPTION=$1
	# Check if options qla2300 in modules.conf or
	# Check if options qla2xxx in modporbe.conf
	if [ -f $QL_MOD_CONF ]; then
		MODULE=""
		set_modules_for_options
		# Load each of the module
		for ISP in "${QL_HBA_MODULES[@]}"
		do
			OPTION_COUNT=$(cat $QL_MOD_CONF | grep "^options qla$ISP" | wc -l)
			if [ $OPTION_COUNT -gt 1 ]; then
				echo "Incorrect numbers of \"options qla$ISP...\" lines"
				echo "in $QL_MOD_CONF"
				return $QL_FAIL
			fi

			QL_OPTIONS=`cat $QL_MOD_CONF | grep "^options qla$ISP"`
			if [ $? != 0 ]; then
				# if the line is not there, return QL_SUCCESS
				# as SCLI would add it if required
				# in case of enable
				if [ $OPTION = 1 ]; then
					return $QL_SUCCESS
				fi
				return $QL_FAIL
			fi
			
			# only do this if ConfigRequired is there
			echo $QL_OPTIONS | grep "ConfigRequired" >& /dev/null
			if [ $? = $QL_SUCCESS ]; then
				CONFIG_REQ=`echo $QL_OPTIONS | sed "s/.*\(ConfigRequired=.\).*/\1/" | \
					     cut -d = -f 2`
				if [ "$CONFIG_REQ" = "$OPTION" ]; then
					#user setting same value
					#if [ $OPTION = 0 ]; then
					#	echo "Persistent binding already disabled"
					#else
					#	echo "Persistent binding already enabled"
					#fi
					return $QL_FAIL
				fi
				QL_NEW_OPTIONS=`echo $QL_OPTIONS | \
					 sed "s/ConfigRequired=./ConfigRequired=$OPTION/"`
				QL_NEW_OPTIONS=`echo $QL_NEW_OPTIONS | \
					 sed "s/ql2xuseextopts=./ql2xuseextopts=$OPTION/"`
			else
				return $QL_FAIL
			fi

			#Remove the old options from the config file
			grep -v "$QL_OPTIONS" $QL_MOD_CONF > $QL_TMP_MOD_FILE
			if [ -f $QL_TMP_MOD_FILE ]; then
				# Append the new options with config required 1
				echo $QL_NEW_OPTIONS >> $QL_TMP_MOD_FILE
				# mv the  new file to original
				mv -f $QL_TMP_MOD_FILE $QL_MOD_CONF
				if [ $? != $QL_SUCCESS ]; then
					echo "Error on moving $QL_TMP_MOD_FILE to $QL_MOD_CONF."
				fi
			else
				echo "Unable to update modules configuration file."
				return $QL_FAIL
			fi
		done
	else
		echo "Can not locate modules configuration file."
		return  $QL_FAIL
	fi
	
	return $QL_SUCCESS
}

# --------------------------------------------------------- #
# set_persistent_binding()                                  #
# Enable/Disable persistent binding by 			    #
# setting ConfigRequired=1/0    			    #
#							    #
# Parameter:						    #
#	$1	Enable				            #
#		Disable				            #
#	$2	ignore					    #
#		if specified then do not unlaod/load driver #
# Returns: None						    #
# --------------------------------------------------------- #
function set_persistent_binding() {
	
	local OPTION=0;

	case $1 in 
		--enable | -e )
			OPTION=1
		;;
		--disable | -d )
			OPTION=0
		;;
		--update | -u )
			OPTION=2
		;;
		* )
			echo "Invalid parameter for persistent binding"
			echo "Please use one of these:"
			echo "       To disable: $QL_INSTALLER -p -d"
			echo "       To enable:  $QL_INSTALLER -p -e"
			echo "       To update:  $QL_INSTALLER -p -u"
			return
		;;

	esac
	
	if [ "$OPTION" = "2" ]; then # need to update
		echo "SANsurfer FC CLI will be invoked to update the persistent binding."
		echo "Please select option \"7: Target Persistent Binding\" to update persistent binding."
		sleep 2
		# Invoke cli to do the magic
		check_cli_installed
		if [ $? = $QL_SUCCESS ]; then
			scli 2> /dev/null
		fi
		return 
	fi

	# We do not want to change the ConfigRequired 
	#update_configrequired $OPTION
	#if [ $? != $QL_SUCCESS ]; then
	#	return
	#fi

	case $OPTION in 
		0 )

		# Invoke cli to do the magic
		check_cli_installed
		if [ $? = $QL_SUCCESS ]; then
			scli -p all unbind all
			echo ""
			echo "Disabled persistent binding."
			echo ""

		else
			echo ""
			echo "Unable to disable persistent binding." 
			echo ""

		fi
		;;
		1 )
			# run the scli again to enable the persisten binding
			do_persistent_binding
			echo ""
			echo "Enabled persistent binding."
			echo ""

			#if [ $? = 0 ]; then
			#	echo ""
			#	echo "Enabled persistent binding."
			#	echo ""
			#else
			#	echo "Failed to do persistent binding."
			#	return
			#fi	
		;;
	esac
	#create the ramdisk
	create_ramdisk "" $BACKUP #backup
	if [ "$2" = "" ]; then 
		#unload/load the driver
		echo ""
		unload_driver $QL_FC_HBA
		echo ""
		load_driver $QL_FC_HBA
	fi
	
}

# --------------------------------------------------------- #
# display_device_information()                              #
# Once driver is loaded this will display the device	    #
# information. So that user know what are the HBAs and 	    #
# devices connected to it				    #
#							    #
# Parameter: None 		                            #
# Returns: None						    #
# --------------------------------------------------------- #
function display_device_information() {
	local ret_status
	ret_status=$QL_SUCCESS
	check_cli_installed
	ret_status=$?
	if [ $ret_status = $QL_SUCCESS ]; then
		#everything is good, display device info
		echo ""
		echo "Target Information on all HBAs:"
		echo "=============================="
		if [ $QL_FC_INSTALLATION = 1 ]; then
			scli -t all 2>  /dev/null
		fi
		if [ $QL_iSCSI_INSTALLATION = 1 ]; then
			list_iscsi_device_information
		fi
	else
		echo "Please install SANsurfer CLIs for device information"
	fi
}

# --------------------------------------------------------- #
# list_iscsi_device_information()                           #
# This function lists all iSCSI bus, target and lun 	    #
# information						    #
#							    #
# Parameter: None 		                            #
# Returns: None						    #
# --------------------------------------------------------- #
function list_iscsi_device_information() {
	for HBA in `./scix -i | grep "HBA Port.*" | sed "s/^.*HBA Port: //"`
		do

		TGT_LIST=`./scix -t $HBA | grep "Target ID" | sed "s/^Target ID:[[:space:]]\+\([[:xdigit:]]\+\)[[:space:]]\+.*/\1/"`

		for TGT in echo $TGT_LIST
		do
				DEVICE_INFO="`./scix -l $HBA $TGT`"
				if [ $? = 0 ]; then
				echo ""
				echo "Target ID: $TGT"
				echo "------------------------------"
				echo "$DEVICE_INFO"
				fi
		done
	done
	echo ""
}

# --------------------------------------------------------- #
# do_persistent_binding()                                   #
# Uses SCLI to do the persistent binding		    #
# Updates modules.conf/modprobe.(conf/.local) with          #
# This works on rpm -Uvh scli*. So there should be only     #
# one rpm file for scli in the current directory            #
# Configrequired					    #
# We always want to set ConfigRequired=0. SCLI sets it to   #
# 1, this causes new devices to not show up	            #
# Parameter: None 		                            #
# Returns: QL_SUCCESS or QL_FAIL			    #
# --------------------------------------------------------- #
function do_persistent_binding() {
	local ret_status=$QL_SUCCESS
	check_cli_installed
	ret_status=$?
	if [ $ret_status = $QL_SUCCESS ]; then
		#everything is good, do the persistent binding
		echo ""
		echo "Building default persistent binding using SCLI"
		scli -p all bind all 2> /dev/null
		ret_status=$?
	fi

	# irresepective of return status, set ConfigRequired=0
	update_configrequired 0
	return $ret_status
}

# --------------------------------------------------------- #
# check_open_file()					    #
# Chekc an applicaiton has open the driver 		    #
# Parameter:						    # 
# 	$1	Module name 	                            #
# Returns: None						    #
# --------------------------------------------------------- #
function check_open_file() 
{
	IN_USE_ARR=( )
	LSOF=`lsof | grep "[[:space:]]\+.*${1}.*$" | sed "s/[[:space:]]\+.*//"`

	for files in $LSOF 	
	do
		#echo "Files is: $files"
		echo ${IN_USE_ARR[@]} | grep "$files" >& /dev/null
		if [ $? != 0 ]; then
			IN_USE_ARR=( "${IN_USE_ARR[@]}" "$files" )
		fi
	done

	local count=1
	if [ ${#IN_USE_ARR[@]} -gt 0 ]; then
		echo "The module is in use by following"
		echo ""
		for app in "${IN_USE_ARR[@]}"
		do
			echo "$count.$app"
			(( count += 1 ))
		done

		echo ""
		echo "Please close the above application/command OR"
	fi
}

# --------------------------------------------------------- #
# can_uninstall()                                           #
# Check if we can uninstall driver                    	    #
# check for multiple rpm installation			    #
# Parameter: Name of the driver/rpm                        #
# Returns: $QL_SUCCESS if yes else $QL_FAIL                 #
# --------------------------------------------------------- #
function can_uninstall()
{
	local DRIVER_NAME=$1
	local DRIVER_COUNT=`rpm -qa | grep -c $DRIVER_NAME`
	if [ $DRIVER_COUNT -gt 1 ]; then
		echo ""
		echo "There are multiple versions of driver installed."
		DRIVER_RPMS=()
		DRIVERS=`rpm -qa | grep $DRIVER_NAME`
		local count=1
		for DRIVER_RPM in $DRIVERS
		do
			DRIVER_RPMS=("${DRIVER_RPMS[@]}" "$DRIVER_RPM")
			echo "$count. $DRIVER_RPM"
			(( count += 1 ))
		done
		echo "Please uninstall the installed driver manually."
		echo "Example: rpm -e ${DRIVER_RPM[0]}"
		return $QL_FAIL
	fi

	return $QL_SUCCESS
}

# --------------------------------------------------------- #
# can_unload_all()                                          #
# Check if we can unload all the modules                    #
# Parameter: None                                           #
# Returns: $QL_SUCCESS if yes else $QL_FAIL                 #
# --------------------------------------------------------- #
function can_unload_all()
{
        IN_USE=0
        MOD_IN_USE=0

        if [ $QL_FC_INSTALLATION = 1 ];then
                QLA2xx_DEPEND_COUNT=0;
                for MODULE in ${QL_FC_MOD_LIST[@]}

                do
                #echo "Checking qla$MODULE"
                if [ "qla$MODULE" != "qla2xxx" ] &&
                        [ "qla$MODULE" != "qla2xxx_conf" ] &&
                        [ "qla$MODULE" != "qla2300_conf" ] &&
                        [ "qla$MODULE" != "qla2200_conf" ] &&
                        [ "qla$MODULE" != "qla2100_conf" ]; then
                        lsmod | grep "^qla$MODULE[[:space:]].*" >& /dev/null
                        if [ $? = 0 ]; then
                                (( QLA2xx_DEPEND_COUNT += 1 ))
                        fi

 			MOD_IN_USE=`lsmod | grep "^qla$MODULE[[:space:]].*" | awk -F "[[:space:]]+" '{print $3}'`
                        if [ "$MOD_IN_USE" != "0" ] && [ "$MOD_IN_USE" != "" ]; then
                                echo "Module qla$MODULE is in use, installer can not proceed."
                                # check if an application has opened the driver
                                check_open_file qla${MODULE}
                                echo ""
                                echo "Try unloading the module manually using \"modprobe -rv qla$MODULE\""
                                echo "and restart the installation."
                                return $QL_FAIL;
                        fi
                fi
                done

                lsmod | grep "^qla2xxx[[:space:]].*" >& /dev/null
                if [ $? = 0 ]; then
 			IN_USE=`lsmod | grep "^qla2xxx[[:space:]].*" | awk -F "[[:space:]]+" '{print $3}'`
                        if [ "$IN_USE" != "$QLA2xx_DEPEND_COUNT" ]; then
                                echo "Module qla2xxx is in use, installer can not proceed."
                                check_open_file "qla2xxx"
                                echo "Try unloading the module manually using \"modprobe -rv qla2xxx\""
                                echo "and restart the installation."
                                return $QL_FAIL;
                        fi
                fi
        fi

        if [ $QL_iSCSI_INSTALLATION = 1 ];then
                QLA4xxx_DEPEND_COUNT=0;
                for MODULE in ${QL_iSCSI_MOD_LIST[@]}

                do
                lsmod | grep "^qla$MODULE" >& /dev/null
                if [ $? = 0 ]; then
                        IN_USE=`lsmod | grep "^qla$MODULE" | awk -F "[[:space:]]+" '{print $3}'`
                        if [ "$IN_USE" != "$QLA4xxx_DEPEND_COUNT" ]; then
                                echo "Module qla${MODULE} is in use, installer can not proceed."
                                check_open_file qla${MODULE}
                                echo "Try unloading the module manually using \"modprobe -rv qla${MODULE}\""
                                echo "and restart the installation."
                                return $QL_FAIL;
                        fi
                fi
                done
        fi

        return $QL_SUCCESS
}

# --------------------------------------------------------- #
# unload_all()						    #
# Unloads all the module using modprobe -r 		    #
# Parameter:						    # 
# 	$1	Module name 	                            #
# Returns: None.					    #
# --------------------------------------------------------- #
function unload_all() {
        lsmod | grep -wq "^$1"
        if [ $? = $QL_SUCCESS ]; then
                $RM_MOD $1
                if [ $? = $QL_SUCCESS ]; then
                        echo "Unloaded module $1"
                fi
        fi
}

# --------------------------------------------------------- #
# install_2.x_driver ()	                                    #
# Installs the driver from the 2.x series rpm. 		    #
# Installs based on the installed HBAs for FC/iSCSI	    # 
# Parameter: 	 		                            #
#	$1	Driver name = rpm name			    #
#	$2	Driver version				    #
# Returns: QL_SUCCESS on success, non-zero on failure	    #
# --------------------------------------------------------- #
function install_2.x_driver() {
	local ret_status=$QL_SUCCESS
	DRIVER_NAME=$1
	DRIVER_VERSION=$2
	HBA_LIST=""

	if [ $QL_FC_INSTALLATION = 1 ]; then
		LOAD_CMD="load_driver ${QL_FC_HBA} ql2xfailover=0"
	fi

	if [ $QL_iSCSI_INSTALLATION = 1 ]; then
		LOAD_CMD="load_driver ${QL_iSCSI_HBA}"
	fi

 	if [ $QL_UPGRADE = 0 ]; then
		# first check if we can unload all the drivers else return 
		can_unload_all
		if [ $? != $QL_SUCCESS ]; then
			return $QL_FAIL;
		fi	
	fi

	check_installation $DRIVER_NAME $DRIVER_VERSION
	INSTALLATION_STATE=$?
	if [ "$INSTALLATION_STATE" -ge "$QL_OLD_INSTALLED" ]; then #driver already not installed
		QL_RPM_FILE=$DRIVER_NAME-$DRIVER_VERSION-*.rpm # * is to ignore the arch
		debug_print "RPM file $QL_RPM_FILE"
		if [ -e $QL_RPM_FILE ]; then

			if [ $INSTALLATION_STATE = $QL_OLD_INSTALLED ]; then
				rpm -ev $DRIVER_NAME
				ret_status=$?
				rpm -ivh $QL_RPM_FILE
				ret_status=$?
			else # NEW install
				rpm -ivh $QL_RPM_FILE
				ret_status=$?
			fi

			if [ $ret_status != 0 ]; then
				return  $ret_status;
			fi
			echo ""

			if [ $QL_FC_INSTALLATION = 1 ]; then
				#backup the /etc/qla2***.conf file
				backup_conf

				# backup the options qla2300 line 
				backup_options

				# check if failover is enabled, if yes then
				# we should not do persistent binding
				is_failover_enabled
				if [ $? = $QL_SUCCESS ]; then
					QL_DO_BIND=0
					# lets load the driver with default settings
					LOAD_CMD="load_driver ${QL_FC_HBA}"
				else	
					# disable failover by default
					set_options ql2xfailover=0
					if [ $QL_UPGRADE = 1 ]; then # its an upgrade, persistent binding disbaled
						update_configrequired 0
					fi
				fi

				if [ $QL_UPGRADE = 0 ]; then #not an upgrade
					# unload drivers if any
					echo "Unloading any loaded drivers"
					for MODULE in ${QL_FC_MOD_LIST[@]}
					do
						unload_all qla${MODULE}
					done

					# here means driver installed, need to go and
					# do the persistent binding
					if [ $QL_DO_BIND = 1 ]; then
						# 1st: Load the FC drivers without failover
						$LOAD_CMD
						if [ $? = $QL_SUCCESS ]; then
							# 2nd: do the persistent binding
							do_persistent_binding
						else
							echo "Unable to load new driver. Skipping persisten binding..."
							echo "Please use $QL_INSTALLER -p -u to update persistent binding manually"
							echo ""
						fi
					else 
						# Persistent binding is not required
						# make sure that ConfigRequired=0 
						update_configrequired 0	
					fi
				fi
				# 4th: Now create the ramdisk
				convert_isp_to_modules
				HBA_LIST="${QL_HBA_MODULES[@]}"
				# clear out modules configuration file
				# this is required so that the sequence in modules conf. file is correct
				# we need qla2xxx_conf to be the very first module, so we will remove
				QL_CLEAR_MOD=1
				#clear_mod_conf "$HBA_LIST"
				create_ramdisk "$HBA_LIST" $BACKUP # 0 for backup
				ret_status=$?
				if [ $ret_status != $QL_SUCCESS ]; then
					echo "Ramdisk creation failed...."
					# we will still go ahead and try to load 
					# the driver
				fi

				if [ $QL_UPGRADE = 0 ]; then #not an upgrade
					if [ $QL_DO_BIND = 1 ]; then
						# 3rd: Unload the driver so that persistent binding takes
						# effect
						echo ""
						echo "Reloading the QLogic FC HBA drivers...."
						unload_driver ${QL_FC_HBA}
					else
						# 5th: Load the driver
						echo ""
						echo "Going to load QLogic FC HBA driver...."
					fi
					$LOAD_CMD
					ret_status=$?
				fi
				#ignore the return status. WE alredy displayed the
				# reason why load failed. Load failed does not mean
				# installation was not successful
				if [ $ret_status = $QL_SUCCESS ]; then 
					# 6th: Display diagnostics
					display_device_information 2>&1 | tee $QL_DEVICE_INFO
					# Don't care about the return
					# even if this fails, installation is
					# successful

					# see if we have a tape device
					# grep the output of above command
					grep -i "Tape" ./$QL_DEVICE_INFO >& /dev/null
					if [ $? = $QL_SUCCESS ]; then
						echo "Found a tape device, loading st driver"
						modprobe st
					fi
				fi
			else # iSCSI Driver
				if [ $QL_UPGRADE = 0 ]; then 
					# backup the options qla4*** line
					backup_options

					# Load the driver	
					$LOAD_CMD
				fi
				# Now create the ramdisk
				HBA_LIST="${QL_iSCSI_HBA_LIST[@]}"
				create_ramdisk "$HBA_LIST" $BACKUP # 0 for backup
				ret_status=$?
				display_device_information
			fi

			if [ $ret_status != $QL_SUCCESS ]; then
				echo "ERROR: $DRIVER_NAME installation failed"
			else
				ret_status=$QL_SUCCESS
			fi	
		else
			echo "${SPC}Please check the distribution package"
			echo "${SPC}The installation rpm file for $DRIVER_NAME driver is missing"
			ret_status=$QL_FAIL
		fi		
	fi
	return $ret_status;
}

# --------------------------------------------------------- #
# install_driver ()	                                    #
# Installs the driver from the rpm. 			    # 
# Parameter: 						    #
#	$1	FORCE_INSTALLATION = Do not detect HBA	    #
# Returns: QL_SUCCESS on success, QL_FAIL on failure.	    #
# --------------------------------------------------------- #
function install_driver() {
	local ret_status=$QL_SUCCESS;
	debug_print "In install_driver"
	
	display_install_msg $QL_BEGIN
	echo ""
	echo "Kernel version: $KERNEL_VERSION"
	if [ "$DISTRO" != "" ]; then
		echo "Distribution: $DISTRO"
	fi

	if [ -z "$1" ] || [ "$1" != "$QL_FORCE_INSTALLATION" ]; then 		
		# Detect the installed ISPs for FC/iSCSI
		detect_all_isp

		# The $QL_INSTALLED_HBA should indicate if we
		# found any installed HBAs
		HBA_TYPE_COUNT=${#QL_INSTALLED_HBA[@]}
		if [ $HBA_TYPE_COUNT = 0 ]; then #No HBA found
		# Ask user to force installation
			echo "${SPC}Unable to detect any QLogic HBAs on this system"
			echo "${SPC}To force installation issue $QL_INSTALLER --force"
			return $QL_FAIL
		else
			COUNT=1
			echo ""
			echo "Found QLogic Fibre Channel Adapter in the system"
			for HBAS in ${QL_HBA_LIST[@]} 
			do
				echo "${SPC}${COUNT}: QLA$HBAS"
				(( COUNT += 1 ))
			done

			echo "Installation will begin for following driver(s)"
			if [ $QL_FC_INSTALLATION = 1 ]; then
				if [ "${QL_INSTALLED_HBA[0]}" = "$QL_FC_HBA" ]; then
					echo "${SPC}$COUNT: $QL_FC_DRIVER_NAME version: $QL_FC_DRIVER_VERSION"
					(( COUNT += 1 ))
				fi
			fi
			
			if [ $QL_iSCSI_INSTALLATION = 1 ]; then
				if [ "${QL_INSTALLED_HBA[1]}" = "$QL_iSCSI_HBA" ]; then
					echo "${SPC}$COUNT: $QL_iSCSI_DRIVER_NAME version: $QL_iSCSI_DRIVER_VERSION"
				fi
			fi
			echo ""
			sleep 4

		fi	
	fi
		
	# check for compiler
	rpm -q gcc >& /dev/null
	if [ $? != $QL_SUCCESS ]; then # gcc not available
		echo "ERROR: gcc is not installed. Can not process further."
		echo "Please install gcc before running the QLogic Linux HBA driver installation."
	fi
	
	# Call the appropriate install based on the kernel
	# version
	case $KERNEL_MAJ_MIN in
		2.4 | 2.6 )
			debug_print "Installation for 2.x series"
			if [ $QL_FC_INSTALLATION = 1 ]; then
				install_2.x_driver "$QL_FC_DRIVER_NAME" "$QL_FC_DRIVER_VERSION"
				ret_status=$?
			fi
 			
			if [ $ret_status = $QL_SUCCESS ]; then 
				if [ $QL_iSCSI_INSTALLATION = 1 ]; then
					install_2.x_driver "$QL_iSCSI_DRIVER_NAME" "$QL_iSCSI_DRIVER_VERSION"
					ret_status=$?
				fi
			fi
		;;
		* )
			echo "${SPC}Installation not supported for kernel $KERNEL_VERSION"
			ret_status=$QL_FAIL
		;;
	esac
	if [ $ret_status = $QL_SUCCESS ]; then
		# both the installation successful, load the driver
		display_install_msg $QL_DONE
	fi
	return $ret_status
}

# --------------------------------------------------------- #
# uninstall_driver ()	                                    #
# Unload driver by default 				    #
# Uninstalls the driver from the rpm. Should restore old    #
# This should be in reverse order of installation	    #
# Parameter: 	 		                            #
#	$1	Driver name = RPM name			    #
#	$2	Unload driver				    #
#		0 = Unload				    #
#		1 = Do not unload			    #
# Returns: $QL_SUCCESS on success, QL_FAIL on failure.      #
# --------------------------------------------------------- #
function uninstall_driver() {
        debug_print "In uninstall_driver"
	DRIVER_RELEASE_DIR=""
        RPM_NAME=$1
        local UNLOAD_DRIVER=0
        if [ "$2" != "" ]; then
                UNLOAD_DRIVER=$2
        fi

	# check if we can proceed 
	can_uninstall $RPM_NAME
	if [ $? == $QL_FAIL ]; then
                echo "Uninstallation  failed..."
		exit 1
	fi

        # restore the options qla2300/qla2xxx line in modules.conf
        # modprobe.conf/.loca file
        restore_options #::set_driver_param
        rpm -q $RPM_NAME >& /dev/null
        if [ $? = $QL_SUCCESS ]; then
		#get the /usr/src/qlogic/<dir name>
		DRIVER_RELEASE_DIR=`rpm -q --qf %{VERSION}-%{RELEASE} ${RPM_NAME}`
                if [ $UNLOAD_DRIVER = 0 ]; then
                        echo ""
                        echo "Going to unload QLogic driver...."
                        unload_driver
                fi

                echo ""
                rpm -ev $RPM_NAME
                if [ $? != $QL_SUCCESS ]; then
                        echo "Uninstallation  failed..."
                        exit 1
                fi

                # installation complete, we need to remove the files
                # we installed /usr/src/qlogic
                #NOTE: With iSCSI support can not remove this
                #With iSCSI need to remove files one by one for iSCSI and then FC
                if [ -e ${QL_USR_SRC}/${DRIVER_RELEASE_DIR} ]; then
                        rm -rf $QL_USR_SRC/${DRIVER_RELEASE_DIR}
                fi

		#remove the log file as well
		if [ -f ${QL_USR_SRC}/${QL_INSTALL_LOG} ]; then
			rm -rf ${QL_USR_SRC}/${QL_INSTALL_LOG}
		fi
        else
                echo
                echo "ERROR: $RPM_NAME does not seem to be installed"
                echo
                exit 1
        fi

}

# --------------------------------------------------------- #
# convert_isp_to_modules ()	                            #
# Converts the ISP number to the corresponding Module	    #
# Works on the QL_FC_HBA_LIST and output in  QL_HBA_MODULES  #
# Parameter: None	 	                            #
# Returns: None						    # 
# --------------------------------------------------------- #

function convert_isp_to_modules() {
	#clear up the QL_HBA_MODULES array
	QL_HBA_MODULES=( )
	case $KERNEL_MAJ_MIN in
	2.6 )
	for ISP in ${QL_FC_HBA_LIST[@]}
	do
                case $ISP in
                2312 )
                	ISP=2300
                ;;
                6322 )
                        ISP=6312
                ;;
                2400 | 2432 | 2422 )
			ISP=2xxx
                ;;
		esac
		
		echo ${QL_HBA_MODULES[@]} | grep "$ISP" >& /dev/null
		if [ $? != 0 ]; then
			QL_HBA_MODULES=( "${QL_HBA_MODULES[@]}" "$ISP" )
		fi

	done
	;;
	2.4 )
	if [ $QL_FC_INSTALLATION = 1 ]; then
		for ISP in ${QL_FC_HBA_LIST[@]}
		do
			case $ISP in
				2312 | 2322 | 6322 | 6312 )
					ISP=2300
				;;
                		2400 | 2432 | 2422 )
					ISP=2300
				;;
			esac

			echo ${QL_HBA_MODULES[@]} | grep "$ISP" >& /dev/null
			if [ $? != 0 ]; then
				QL_HBA_MODULES=( "${QL_HBA_MODULES[@]}" "$ISP" )
			fi
		done
	fi

	if [ $QL_iSCSI_INSTALLATION = 1 ]; then
		for ISP in ${QL_iSCSI_HBA_LIST[@]}
		do
			case $ISP in
				4010 )
					ISP=4010
				;;
				4022 )
					ISP=4022
					#echo "Not supported: TBD"
				;;
			esac

#			QL_HBA_MODULES[$ISP]=$ISP
			echo ${QL_HBA_MODULES[@]} | grep "$ISP" >& /dev/null
			if [ $? != 0 ]; then
				QL_HBA_MODULES=( "${QL_HBA_MODULES[@]}" "$ISP" )
			fi

		done
	fi
	;;

	esac
}

# --------------------------------------------------------- #
# get_ld_driver_version ()                                  #
# Gets the driver version of the currently loaded module    #
# Parameter: 	 		                            #
#	$1	Module name				    #	
# Returns: Driver version in global:$QL_LD_DRIVER_VERSION   #
# --------------------------------------------------------- #

get_ld_driver_version() {
        # check the proc directory for the driver
        # version
        PROC=/proc/scsi/$1
        VERSION_STR="Driver version"
	NODES=""
	if [ -e "$PROC" ]; then
        	NODES=`ls $PROC`
	fi
        for NODE in $NODES
        do
                VERSION_LINE=`cat $PROC/$NODE | grep "$VERSION_STR"` >& /dev/null
		if [ $? != 0 ]; then
			echo "Unable to detect the loaded driver version"
			QL_LD_DRIVER_VERSION=""
			return
		fi
                VERSION=`echo "$VERSION_LINE" | sed "s/^.*$VERSION_STR //"`
		QL_LD_DRIVER_VERSION=$VERSION	
                #echo "Return : $?"
                break
        done
	return
}
                                                                                                
# --------------------------------------------------------- #
# ld_rm_driver ()	                                    #
# Loads or Unloads  the driver using modprobe		    #
# Parameter: 	 		                            #
#	$1	Command - load_module or unload_module	    #
#	$2	Type of HBA to be loaded FC/iSCSI	    #
#		Pass "" to load both			    #
#	$3-*	Parameters to pass to driver
# Returns: QL_SUCCESS on success, QL_FAIL on failure.	    #
# --------------------------------------------------------- #
function ld_rm_driver() {
	debug_print "In ld_rm_driver"
	
	COMMAND=$1
	DRIVER_TYPE="$2"
	local QLA2XXX_LOADED=0
	detect_all_isp
	#see if any command line parameters
	shift #skip 1
	shift #skip 2
	local PARAM=$* # rest is parameters
	local ret_status=$QL_SUCCESS

	#iSCSI
	if [ $QL_iSCSI_INSTALLATION = 1 ] && 
	   [ "$DRIVER_TYPE" = ""  -o "$DRIVER_TYPE" = "${QL_iSCSI_HBA}" ]; then
		ISP_LIST=`echo "${QL_iSCSI_ISP_LIST[@]}"`
		detect_isp2 "${ISP_LIST}"
		case $KERNEL_MAJ_MIN in
			2.4 )
				if [ ${#QL_HBA_LIST[@]} -gt 0 ]; then
					for ISP in "${QL_HBA_LIST[@]}"
					do
						$COMMAND "qla${ISP}" $PARAM
					done
				fi
			;;
			2.6 )
				if [ ${#QL_HBA_LIST[@]} -gt 0 ]; then
					$COMMAND "qla4xxx"
				fi
			;;
		esac
	fi

	#FC
	if [ $QL_FC_INSTALLATION = 1 ] &&
	   [ "$DRIVER_TYPE" = "" -o "$DRIVER_TYPE" = "${QL_FC_HBA}" ]; then
		LOAD_DRIVER=1
		ISP_LIST=`echo "${QL_FC_ISP_LIST[@]}"`
		debug_print "ISP LIST = $ISP_LIST"
		detect_isp2 "$ISP_LIST"
		case $KERNEL_MAJ_MIN in
			2.4 )
				debug_print "Length of HBA LIST = ${#QL_HBA_LIST[@]}"
				debug_print "${QL_HBA_LIST[@]}"
				# Load/unload *_conf
				HBAS="${QL_FC_HBA_LIST[@]}"
				echo "$HBAS" | grep "2300" >& /dev/null
				if [ $? = 0 ]; then
					#before loading check if already loaded
					$COMMAND "qla2300_conf"
				fi

                                echo "$HBAS" | grep "2200" >& /dev/null
                                if [ $? = 0 ]; then
                                        $COMMAND "qla2200_conf"
                                fi
			;;
			2.6 )
				debug_print "Length of HBA LIST = ${#QL_FC_HBA_LIST[@]}"
				debug_print "HBA LIST: ${QL_FC_HBA_LIST[@]}"
	
				if [ ${#QL_FC_HBA_LIST[@]} -gt 0 ]; then
					
					if [ "$COMMAND" = "load_module" ]; then
						$COMMAND "qla2xxx_conf"
						# load qla2xxx also with failover 
						# disabled
						$COMMAND "qla2xxx" $PARAM
						QLA2XXX_LOADED=1
						# do not use PARAM any more on 2.6
						PARAM=""
					fi
				fi
			;;
		esac

		# traverse the HBA list: Common for 2.4 and 2.6
		convert_isp_to_modules

		debug_print "Length of HBA MODULEs = ${#QL_HBA_MODULES[@]}"
		debug_print "HBA MODULES: ${QL_HBA_MODULES[@]}"

		# Load each of the module
		for ISP in "${QL_HBA_MODULES[@]}"
		do

			#check if qla2xxx is already loaded, do not load 
			# if qla2xxx is already loade
			if [ "$QLA2XXX_LOADED" = "1" ]; then
				if [ "$ISP" = "2xxx" ]; then
					continue;
				fi
			fi
			$COMMAND "qla${ISP}" $PARAM
			if [ $? != $QL_SUCCESS ]; then
				#something went wrong, try loading 
				#other modules but return failure
				ret_status=$QL_FAIL
			fi
		done
	fi
	return $ret_status
}

# --------------------------------------------------------- #
# load_module ()	                                    #
# Loads the module using modprobe -v			    #
# Parameter: 	 		                            #
#	$1	Module name				    #
#	$2-*	Parameters				    #
# Returns: None.					    #
# --------------------------------------------------------- #
function load_module() {
	MODULE=$1
	DRIVER_VERSION=$QL_iSCSI_DRIVER_VERSION

	# Get the type of driver FC/iSCSI
	ISP=`echo $MODULE | sed "s/qla//"`
	echo ${QL_FC_MOD_LIST[@]} | grep "$ISP" >& /dev/null 	
	if [ $? = 0 ]; then #Found module in FC list
		DRIVER_VERSION=$QL_FC_DRIVER_VERSION
		PROC_SCSI_DIR="qla2300"
		if [ "$KERNEL_MAJ_MIN" = "2.6" ]; then
			PROC_SCSI_DIR="qla2xxx" 
		else # 2.4
			echo $MODULE | grep "2200" >& /dev/null
			if [ $? = 0 ]; then
			PROC_SCSI_DIR="qla2200" 
			fi
		fi	
	else
		#Look in the iSCSI list
		echo ${QL_iSCSI_MOD_LIST[@]} | grep "$ISP" >& /dev/null 	
		if [ $? != 0 ]; then #Found module in iSCSI list
			echo "Unable to load the module $MODULE"
			echo "Please try loading manually using following command"
			echo "# modprobe -v $MODULE"		
			return $QL_FAIL
		else
			PROC_SCSI_DIR="$MODULE" 
		fi	
	fi
	# check if driver is not loaded
	lsmod | grep -wq "^$MODULE" 
	if [ $? = $QL_SUCCESS ]; then
		#Compare version of already installed driver from /proc/scsi
		get_ld_driver_version	$PROC_SCSI_DIR 
		if [ "$QL_LD_DRIVER_VERSION" != "" ]; then # fall thru if false
			#Need to remove the v from the version 
			DRIVER_VERSION=`echo $DRIVER_VERSION | sed "s/v//"`
			compare_version $DRIVER_VERSION $QL_LD_DRIVER_VERSION
			if [ $? = $QL_FAIL ]; then
				echo "Module $MODULE is already loaded"
				echo "Execute following to unload and then load the module"
				echo "$QL_INSTALLER -ul $MODULE"
				echo "$QL_INSTALLER -l $MODULE"
				return $QL_FAIL
			else
				#unload the module
				echo "Unloading the already loaded module $MODULE" \
							"version: $QL_LD_DRIVER_VERSION"
				$RM_MOD $MODULE
				if [ $? != $QL_SUCCESS ]; then
					# if this fails then the modules may be in use
					echo "Unable to unload the already loaded module $MODULE"
					#check if module is in use
					IN_USE=`lsmod | grep "^$MODULE[[:space:]].*" | sed "s/.*[[:space:]]\+[0-9]\+[[:space:]]\+[0-9]\+[[:space:]]\+//"`
					if [ "$IN_USE" != "" ]; then
						echo "$IN_USE" | grep "unused" >& /dev/null
						if [ $? != 0 ]; then
							echo "The module is in use by \"$IN_USE\""
							echo "These modules need to be removed before"
							echo "$MODULE can be loaded. Skipping...."
							return $QL_FAIL
						fi
					fi
					# here means we could not detect from lsmod who is
					# using it. 
				
					echo "Please unload any module that could be using $MODULE"
					echo "Or stop the application that could be using $MODULE. Skipping..."
					echo ""
					return $QL_FAIL
				fi	
			fi	
		fi
	fi
	echo "Loading module $MODULE version: $DRIVER_VERSION...."
	#see if any params
	shift #skip module name
	local PARAM=$*
	modprobe $MODULE $PARAM
	if [ $? = $QL_SUCCESS ]; then
		echo "Loaded module $MODULE"
		return $QL_SUCCESS
	else
		echo "Module $MODULE load failed"
		return $QL_FAIL
	fi	
}

# --------------------------------------------------------- #
# unload_module ()	                                    #
# Unloads the module using modprobe -rv /rmmod		    #
# Parameter:						    # 
# 	$1	Module name 	                            #
# Returns: None.					    #
# --------------------------------------------------------- #
function unload_module() {
	lsmod | grep -wq "^$1" 
	if [ $? = $QL_SUCCESS ]; then
		$RM_MOD $1
		if [ $? = $QL_SUCCESS ]; then
			echo "Unloaded module $1"
		else
			echo "Module $1 unload failed"
		fi	
	else
		# Most of the systems unload qla2xxx_conf automatically
		# so do not show this message
		echo $1 | grep "qla.*_conf" >& /dev/null
		if [ $? != 0 ]; then
			echo "$1 module is not loaded"
		fi
	fi
}
 

# --------------------------------------------------------- #
# unload_driver ()	                                    #
# Unloads all the driver using modprobe -rv/rmmod	    #
# Parameter: 					            #
#	$1	Type of HBA Driver to be loaded		    #  
#		QL_FC_HBA or QL_iSCSI_HBA		    #
#		If $1="" then both FC and iSCSI		    #
# Returns: None 					    #
# --------------------------------------------------------- #
function  unload_driver() {
	debug_print "In unload_driver"
	ld_rm_driver "unload_module" $1
}

# --------------------------------------------------------- #
# load_driver ()	                                    #
# loads all the driver using modprobe -v	 	    #
# Parameter: 	 		                            #
#	$1	Driver type (FC/iSCSI)			    #
#	$2-*	Parameters				    #
# Returns: None.					    #
# --------------------------------------------------------- #
function  load_driver() {
	debug_print "In load_driver"
	ld_rm_driver "load_module" $*
	return $?
}

# --------------------------------------------------------- #
# restore_mod_conf() 	                                    #
# Restore any modules that installer removed from the       #
# modules configuration file during installation.	    #
# Parameter:						    #
#	$1	None                                        #
# Returns: None                                             #
# --------------------------------------------------------- #
restore_mod_conf() {
	#get the entries from  $QL_MOD_REMOVED
	# and put them back. Note this operation must
	# be performed after installer changes are removed
	# from modules conf. files
	
	if [ -f $QL_MOD_REMOVED ]; then
		if [ "$QL_DISTRIBUTION" = "$DISTRO_SUSE" ]; then
			local MODULES=`cat $QL_SYSCONF_K | grep INITRD_MODULES |
                        awk 'BEGIN {FS="="} {print $2}'| sed 's/\"//g'`

			for MODULE in `cat $QL_MOD_REMOVED`
			do
				MODULES="$MODULES $MODULE"
			done

                	sed "s/INITRD_MODULES.*/INITRD_MODULES=\"$MODULES\"/"  $QL_SYSCONF_K >/tmp/kernel
                	mv -f /tmp/kernel $QL_SYSCONF_K
		else #RedHat/AsianUx
			
			for SCSI_HBA in `cat $QL_MOD_REMOVED`
			do
				echo $SCSI_HBA >> $QL_MOD_CONF
			done
		fi
	fi
}
# --------------------------------------------------------- #
# clear_mod_conf ()	                                    #
# Clears teh modules conf file so that the moduled sequence #
# is correct. qla2xxx_conf, qla2xxx, qla2300.....	    #
# Parameter:						    #
#	$1	List of modules to be removed from mod. conf#
# Returns: QL_SUCCESS on success, QL_FAIL on failure.       #
# --------------------------------------------------------- #
function clear_mod_conf() {
	MODULE_LIST=( ${QL_FC_ISP_LIST[@]} ) #clean up all

	if [ "$QL_DISTRIBUTION" = "$DISTRO_SUSE" ]; then
		#work on /etc/sysconfig/kernel
		local MODULES=`cat $QL_SYSCONF_K | grep INITRD_MODULES |
                        awk 'BEGIN {FS="="} {print $2}'| sed 's/\"//g'`

		for MODULE in ${MODULE_LIST[@]}
		do
			echo "${MODULES}" | grep "qla${MODULE}" >& /dev/null
			if [ $? = $QL_SUCCESS ]; then
				echo "qla${MODULE}" >> $QL_MOD_REMOVED
			fi
			MODULES=`echo ${MODULES} | sed "s/qla${MODULE}//"`
			
		done

		sed "s/INITRD_MODULES.*/INITRD_MODULES=\"$MODULES\"/"  $QL_SYSCONF_K >/tmp/kernel
        	mv -f /tmp/kernel $QL_SYSCONF_K
	else
		#work on /etc/modprobe.conf
		#or modules.conf
		for MODULE in ${MODULE_LIST[@]}
		do
			SCSI_HBA=`grep "^[[:space:]]*alias[[:space:]]\+scsi_hostadapter.*qla${MODULE}.*" $QL_MOD_CONF`
			if [ "${SCSI_HBA}" != "" ]; then
				echo "${SCSI_HBA}" >> $QL_MOD_REMOVED
			fi
			remove_module_conf qla${MODULE}
		done
	fi
}


# --------------------------------------------------------- #
# create_ramdisk ()	                                    #
# Creates a ramdisk, backups the old version of ramdisk	    #
# Parameter:						    #
#	$1	List of modules to be added in ramdisk      #
#	$2	Create backup (0) or Not (1)
#	$3	FORCE_REBUILD
# Returns: QL_SUCCESS on success, QL_FAIL on failure.       #
# --------------------------------------------------------- #
function create_ramdisk() {
	debug_print "In create_ramdisk"
	local ret_status=$QL_SUCCESS
	# invoke the build script with -d option
	# We can use either the iSCSI or FC build script
	# Look for /usr/src/qla2x00/build_fc_qla2x00.sh
	if [ $2 = $BACKUP ]; then
		backup_sys_mod
	fi
	
	if [ $QL_CLEAR_MOD =  1 ]; then
		clear_mod_conf "$1"
		QL_CLEAR_MOD=0
	fi

	if [ -f $QL_BUILD_SCRIPT ]; then
		$QL_BUILD_SCRIPT -d "$1" $2 "$3"
		ret_status=$?
		if [ $ret_status != $QL_SUCCESS ]; then
			return $ret_status
		fi
	else
		echo "Unable to locate the build script"
		echo "Please make sure QLogic driver is installed"
		return $QL_FAIL
	fi 

	if [ $ret_status = $QL_SUCCESS ]; then
		echo "Ramdisk created."
	fi
	return $QL_SUCCESS
}

# --------------------------------------------------------- #
# build_driver_disk()	                                    #
# Creates driver disk for the current running kernel	    #
# Parameter: None					    #
# Returns: None                                             #
# --------------------------------------------------------- #
function build_driver_disk() {

	#RHEL 3 K 2.4
	#Use mod_devel_kit
	#chekc if driver is installed
	#if not then install it
	#un-compress the mod_devel_kit
	#build the driver disk
	#remove the mod_devel_kit
	#un-install the driver if we installed it	
	source ./build_driver_disk

	#SLES: 
	#Use the directory struct /linux/suse/i686-9.0/install
	#RHEL 4
	#Not known yet
}
# --------------------------------------------------------- #
# check_module_in_initrd				    #
# Check if there is still a module in /etc/sysconfig/kernel #
# in INITRD_MODULES.					    #
# Works on the global QL_INITRD_MOD line set by		    #
# modify_sysconfig_kernel				    #
# Parameters: None					    #
# Returns: QL_SUCCESS: If there still is a module except    #
#	   qla2xxx and qla2xxx_conf			    # 
#	   QL_FAIL: If no more modules			    #
# --------------------------------------------------------- #
function check_module_in_initrd() {
	#check if any of the module except qla2xxx and
	#qla2xxx_conf from the QL_FC_MOD_LIST exist in the
	# QL_INITRD_MOD. If yes return QL_SUCCESS else QL_FAIL
	
	if [ "$QL_INITRD_MOD" = "" ]; then
		return $QL_FAIL
	fi
	
	#loop thru the QL_FC_MOD_LIST array
	for MODULE in ${QL_FC_MOD_LIST[@]}
	do
		case $MODULE in 
			"2xxx" | "2xxx_conf" )
				continue
			;;
		esac
		echo "$QL_INITRD_MOD" | grep "$MODULE\b" >& /dev/null 
		if [ $? = 0 ]; then # $MODULE still there, return found
			return $QL_SUCCESS
		fi
	done
	# if here means the module not there in INITRD_MODULES line
	return $QL_FAIL
}

# --------------------------------------------------------- #
# remove_module						    #
# Removes the passed in module from the INTRD_MODULES  	    #
# line of the /etc/sysconfig/kernel file for SLES	    #
# Works on the global QL_INITRD_MOD var set by		    #
# modify_sysconfig_kernel				    #
# Parameters:						    #
#	$1	Module to be removed			    #
# Returns: QL_SUCCESS on success, QL_FAIL on failure.       #
# --------------------------------------------------------- #
function remove_module() {
	local ret_status=$QL_FAIL
	echo "$QL_INITRD_MOD" | grep "$1\b" >& /dev/null
	if [ $? = $QL_SUCCESS ]; then
		QL_INITRD_MOD=`echo $QL_INITRD_MOD | sed "s/[[:space:]]\+$1\b//" | sed "s/$1\b[[:space:]]\+//"`
		ret_status=$QL_SUCCESS
	fi
	return $ret_status
}

# --------------------------------------------------------- #
# backup_sys_mod					    #
# Creates a backup copy of kernel  and modprobe.conf	    #
# or modules.conf or modprobe.conf.local		    #
# Parameters: $1: Date-Time				    #
# Returns: None                                      	    #
# --------------------------------------------------------- #
backup_sys_mod() {
	local BACKUP_DATE=`date +%m%d%y-%H%M%S`
	if [ "${QL_DISTRIBUTION}" = "${DISTRO_SUSE}" ]; then
		backup_sysconfig_kernel ${BACKUP_DATE}
	fi
	backup_mod_conf ${BACKUP_DATE}
}

# --------------------------------------------------------- #
# backup_sysconfig_kernel				    #
# Creates a backup copy of kernel with current date time    #
# Parameters: $1: Date-Time				    #
# Returns: None                                      	    #
# --------------------------------------------------------- #
backup_sysconfig_kernel() {
	BACKUP_DATE=`date +%m%d%y-%H%M%S`
	if [ "${1}" != "" ]; then
		BACKUP_DATE=$1
	fi

	SAVING_STR="Saved copy of" 
	if [ $QL_FC_INSTALLATION = 1 ]; then
		BACKUP_FILE="$QL_FC_BACKUP_DIR/kernel-$KERNEL_VERSION-${BACKUP_DATE}.bak"
	fi
	if [ $QL_iSCSI_INSTALLATION = 1 ]; then
		BACKUP_FILE="$QL_iSCSI_BACKUP_DIR/kernel-$KERNEL_VERSION-${BACKUP_DATE}.bak"
	fi

#	BACKUP_FILE="$QL_FC_BACKUP_DIR/kernel-$KERNEL_VERSION-${BACKUP_DATE}.bak"
#	echo "QL_SYSCONF_K = $QL_SYSCONF_K"
#	echo "BACKUP_FILE = $BACKUP_FILE"

	cp -f $QL_SYSCONF_K $BACKUP_FILE 
	echo -e ""
	echo -e "$SAVING_STR $QL_SYSCONF_K as"
	echo -e "$BACKUP_FILE"
	echo -e ""
}

# --------------------------------------------------------- #
# prepare_modules_list					    #
# Takes the user input list of modules, validates them     #
# and stores the list in QL_HBA_MODULES			    #
# Parameters:						    #
#	$*	List of modules				    #
# Returns: None						    #
# --------------------------------------------------------- #
function prepare_modules_list() {
	USER_MOD_LIST=( $* )
	# for each user input module verify if it is in our
	# valid modules list, then only add in the 
	# QL_HBA_MODULES
	QL_HBA_MODULES=( )
	for USER_MOD in ${USER_MOD_LIST[@]}
	do
		MODULE=`echo "$USER_MOD" | sed "s/qla//"`
		case $MODULE in 
			"2xxx" | "2xxx_conf" )
				continue
			;;
		esac

		if [ $QL_FC_INSTALLATION = 1 ]; then
			echo "${QL_FC_MOD_LIST[@]}" | grep "$MODULE\b" >& /dev/null
			if [ $? = $QL_SUCCESS ]; then #  valid module
				QL_HBA_MODULES=( "${QL_HBA_MODULES[@]}" $MODULE )
			else
				echo "Invalid module name $USER_MOD, ignoring this module...."
			fi	

		fi

		if [ $QL_iSCSI_INSTALLATION = 1 ]; then
			echo "${QL_iSCSI_MOD_LIST[@]}" | grep "$MODULE\b" >& /dev/null
			if [ $? = $QL_SUCCESS ]; then #  valid module
				QL_HBA_MODULES=( "${QL_HBA_MODULES[@]}" $MODULE )
			else
				echo "Invalid module name $USER_MOD, ignoring this module...."
			fi	
		fi
	done
}

# --------------------------------------------------------- #
# modify_sysconfig_kernel				    #
# Modify the /etc/sysconfig/kernel on SLES to build         #
# the ramdisk                                   	    #
# Parameters:						    #
#	$1	0: Exclude QL Drivers from Ramdisk	    #
#		1: Include QL Drivers from Ramdisk	    #
# Returns: QL_SUCCESS if ramdisk needs to be rebuilt, 	    #
#          QL_FAIL if ramdisk is not to be rebuilt	    #
# --------------------------------------------------------- #
function modify_sysconfig_kernel() {
	BACKUP_DATE=`date +%m%d%y-%H%M%S`
	SAVING_STR="Saved copy of" 
	if [ $QL_FC_INSTALLATION = 1 ]; then
		BACKUP_FILE="$QL_FC_BACKUP_DIR/kernel-$KERNEL_VERSION-${BACKUP_DATE}.bak"
	fi
	if [ $QL_iSCSI_INSTALLATION = 1 ]; then
		BACKUP_FILE="$QL_iSCSI_BACKUP_DIR/kernel-$KERNEL_VERSION-${BACKUP_DATE}.bak"
	fi
	NEED_REBUILD=0

	QL_INITRD_MOD=`grep "^INITRD_MODULES=.*" $QL_SYSCONF_K`
	if [ $? != $QL_SUCCESS ]; then
		return $QL_FAIL;
	fi

	if [ $EXIN = $EXCLUDE ]; then
		#Remove the modules from ramdisk
		if [ ${#QL_HBA_MODULES[@]} -gt 0 ]; then
			#backup original sysconfig/kernel
			cp -f $QL_SYSCONF_K $BACKUP_FILE 
			if [ $QL_FC_INSTALLATION = 1 ]; then
				if [ "$KERNEL_MAJ_MIN" = "2.4" ]; then 
					#2.4
					#remove qlaxx00_conf
					#check if 2200, remove qla2200_conf
					echo ${QL_HBA_MODULES[@]} | grep "2200" >& /dev/null
					if [ $? = $QL_SUCCESS ]; then
						remove_module "qla2200_conf"
						if [ $? = $QL_SUCCESS ]; then
							NEED_REBUILD=1
						fi
					fi
					#check if 2300, remove qla2300_conf
					echo ${QL_HBA_MODULES[@]} | grep "2300" >& /dev/null
					if [ $? = $QL_SUCCESS ]; then
						remove_module "qla2300_conf"
						ret=$?
						if [ $ret = $QL_SUCCESS ]; then
							NEED_REBUILD=1
						fi
					fi
					#remove qlaxx00
					#Done below
				fi
			fi	

			for MODULE in "${QL_HBA_MODULES[@]}"
			do
				remove_module "qla$MODULE"
				if [ $? = $QL_SUCCESS ]; then
					NEED_REBUILD=1
				fi
			done

			if [ $QL_FC_INSTALLATION = 1 ]; then
				if [ "$KERNEL_MAJ_MIN" = "2.6" ]; then 
					# 2.6
					# all modules removed till this point.
					# check if we need to remove qla2xxx and qla2xxx_conf as well
					check_module_in_initrd
					if [ $? = $QL_FAIL ]; then # means we can remove
						#2.6
						#remove qla2xxx
						remove_module "qla2xxx"
						if [ $? = $QL_SUCCESS ]; then
							NEED_REBUILD=1
						fi
						
						#remove qla2xxx_conf
						remove_module "qla2xxx_conf"
						if [ $? = $QL_SUCCESS ]; then
							NEED_REBUILD=1
						fi

					fi
				fi
			fi
		fi
	else # INCLUDE
		#use the create ramdisk with module list
		HBA_LIST="${QL_HBA_MODULES[@]}"
		# Create ramdisk, send "NO" to not rebuild if 
		# all the entries are already there
		create_ramdisk "$HBA_LIST" $BACKUP "NO" 
		NEED_REBUILD=0
	fi

	if [ $NEED_REBUILD = 1 ]; then
		echo -e "$SAVING_STR $QL_SYSCONF_K as"
		echo -e "$BACKUP_FILE"
		echo -e ""

		# Change the original one
		sed "s/INITRD_MODULES.*/$QL_INITRD_MOD/"  $QL_SYSCONF_K > /tmp/kernel
                mv -f /tmp/kernel $QL_SYSCONF_K 
		return $QL_SUCCESS
	fi

	# remove backup if created, it is not required
	if [ -f $BACKUP_FILE ]; then
		rm -f $BACKUP_FILE >& /dev/null
	fi

	return $QL_FAIL
}

# --------------------------------------------------------- #
# backup_mod_conf					    #
# Creates a backup copy of modules/modprobe.conf	    #
# with current date time    				    #
# Parameters:Non					    #
# Returns: None                                      	    #
# --------------------------------------------------------- #
backup_mod_conf() {
	BACKUP_DATE=`date +%m%d%y-%H%M%S`
	if [ "${1}" != "" ]; then
		BACKUP_DATE=$1
	fi
	
	SAVING_STR="Saved copy of"
	if [ $QL_FC_INSTALLATION = 1 ]; then
		BACKUP_FILE="$QL_FC_BACKUP_DIR/$QL_MOD_FILE-$KERNEL_VERSION-${BACKUP_DATE}.bak"
	fi
	if [ $QL_iSCSI_INSTALLATION = 1 ]; then
		BACKUP_FILE="$QL_iSCSI_BACKUP_DIR/$QL_MOD_FILE-$KERNEL_VERSION-${BACKUP_DATE}.bak"
	fi
 
#	BACKUP_FILE="$QL_FC_BACKUP_DIR/$QL_MOD_FILE-$KERNEL_VERSION-${BACKUP_DATE}.bak"
	cp -f $QL_MOD_CONF $BACKUP_FILE 
	echo -e ""
	echo -e "$SAVING_STR $QL_MOD_CONF as"
	echo -e "$BACKUP_FILE"
	echo -e ""
}

# --------------------------------------------------------- #
# check_module_in_modconf				    #
# Check if there is still a module in /etc/modules.cof (2.4)#
# or modprobe.conf (2.6) on Redhat and Asianux		    #
# Check for line scsi_hostadapter* <module name>	    #
# modify_sysconfig_kernel				    #
# Parameters: None					    #
# Returns: QL_SUCCESS: If there still is a module except    #
#	   qla2xxx and qla2xxx_conf			    # 
#	   QL_FAIL: If no more modules			    #
# --------------------------------------------------------- #
function check_module_in_modconf() {
	#check if any of the module except qla2xxx and
	#qla2xxx_conf from the QL_FC_MOD_LIST exist in the
	# $QL_MOD_CONF file
	
	if [ ! -f $QL_MOD_CONF ]; then
		return $QL_FAIL
	fi
	
	#loop thru the QL_FC_MOD_LIST array
	for MODULE in "${QL_FC_MOD_LIST[@]}"
	do
		case $MODULE in 
			"2xxx" | "2xxx_conf" )
				continue
			;;
		esac
		
		grep "^[[:space:]]*alias[[:space:]]\+scsi_hostadapter.*$MODULE" $QL_MOD_CONF >& /dev/null
		if [ $? = 0 ]; then # $MODULE still there, return found
			return $QL_SUCCESS
		fi
	done
	# if here means the module not there in $QL_MOD_CONF
	return $QL_FAIL
}


# --------------------------------------------------------- #
# remove_module_conf					    #
# Removes the passed in module from the /etc/modules.conf   #
# or from /etc/modprobe.conf                     	    #
# Parameters:						    #
#	$1	Module to be removed			    #
#							    #
# Returns: QL_SUCCESS on success, QL_FAIL on failure.       #
# --------------------------------------------------------- #
function remove_module_conf() {
	if [ -f $QL_MOD_CONF ]; then
		#search line alias scsi_hostadapter* qla2***
		# and remove it from it
		 MOD_LINE=`grep "^[[:space:]]*alias[[:space:]]\+scsi_hostadapter.*$1" $QL_MOD_CONF`
		if [ "$MOD_LINE" = "" ]; then
			return $QL_FAIL
		fi
		grep -v "$MOD_LINE" $QL_MOD_CONF > $QL_TMP_MOD_FILE
		if [ -f $QL_TMP_MOD_FILE ]; then
			#move the file to original
			mv -f $QL_TMP_MOD_FILE $QL_MOD_CONF
			return $?
		else
			return $QL_FAIL
		fi
	else
		echo "ERROR: $QL_MOD_CONF file is missing....."
		return $QL_FAIL	
	fi	
}

# --------------------------------------------------------- #
# modify_modules_conf					    #
# Modify the /etc/modules.conf or modprobe.conf  on RHEL    #
# to build the the ramdisk                            	    #
# Parameters:						    #
#	$1	0: Exclude QL Drivers from Ramdisk	    #
#		1: Include QL Drivers from Ramdisk	    #
# Returns: QL_SUCCESS on success, QL_FAIL on failure.       #
# --------------------------------------------------------- #
function modify_modules_conf() {
	NEED_REBUILD=0
	BACKUP_DATE=`date +%m%d%y-%H%M%S`
	SAVING_STR="Saved copy of" 
	BACKUP_FILE="$QL_FC_BACKUP_DIR/$QL_MOD_FILE-$KERNEL_VERSION-${BACKUP_DATE}.bak"
	
	if [ $EXIN = $EXCLUDE ]; then
		#Remove the modules from ramdisk
		if [ ${#QL_HBA_MODULES[@]} -gt 0 ]; then
			#backup origin modules/modprobe.conf
			cp -f $QL_MOD_CONF $BACKUP_FILE 
			if [ "$KERNEL_MAJ_MIN" = "2.4" ]; then 
				#2.4
				#remove qlaxx00_conf
				#check if 2200, remove qla2200_conf
				echo ${QL_HBA_MODULES[@]} | grep "2200"
				if [ $? = $QL_SUCCESS ]; then
					remove_module_conf "qla2200_conf"
					if [ $? = $QL_SUCCESS ]; then
						NEED_REBUILD=1
					fi
				fi
				#check if 2300, remove qla2300_conf
				echo ${QL_HBA_MODULES[@]} | grep "2300" >& /dev/null
				if [ $? = $QL_SUCCESS ]; then
					remove_module_conf "qla2300_conf"
					if [ $? = $QL_SUCCESS ]; then
						NEED_REBUILD=1
					fi
				fi
				#remove qlaxx00
				#Done below
			fi
			for MODULE in "${QL_HBA_MODULES[@]}"
			do
				remove_module_conf "qla$MODULE"
				if [ $? = $QL_SUCCESS ]; then
					NEED_REBUILD=1
				fi
			done
			if [ "$KERNEL_MAJ_MIN" = "2.6" ]; then 
				# 2.6
				# all modules removed till this point.
				# check if we need to remove qla2xxx and qla2xxx_conf as well
				check_module_in_modconf
				if [ $? = $QL_FAIL ]; then # means we can remove
					#2.6
					# Remove scsi_hostadapter* qla2xxx
					remove_module_conf "qla2xxx"
					if [ $? = $QL_SUCCESS ]; then
						NEED_REBUILD=1
					fi
					
					# Remove scsi_hostadapter* qla2xxx_conf
					remove_module_conf "qla2xxx_conf"
					if [ $? = $QL_SUCCESS ]; then
						NEED_REBUILD=1
					fi
				fi
			fi
		fi
	else # INCLUDE
		#use the create ramdisk with module list
		HBA_LIST="${QL_HBA_MODULES[@]}"
		create_ramdisk "$HBA_LIST" $BACKUP  "NO" 

		NEED_REBUILD=0
	fi

	if [ $NEED_REBUILD = 1 ]; then
		echo -e "$SAVING_STR $QL_MOD_CONF as"
		echo -e "$BACKUP_FILE"
		echo -e ""
		return $QL_SUCCESS
	fi

	# remove backup if created, it is not required
	if [ -f $BACKUP_FILE ]; then
		rm -f $BACKUP_FILE >& /dev/null
	fi
	return $QL_FAIL
}
	
# --------------------------------------------------------- #
# exin_ramdisk ()	                                    #
# Modifies the modules.conf/modprobe.conf/modprobe.conf.local#
# to include or exclude the QL driver in RAMDisk	    #
# Parameters:						    #
#	$1	0: Exclude QL Drivers from Ramdisk	    #
#		1: Include QL Drivers from Ramdisk	    #
#	$2	0: Do not detect modules to be included or  #
#		excluded				    #
#		1: Do detect the modules to be included or  #
#		excluded				    #
# Returns: QL_SUCCESS on success, QL_FAIL on failure.       #
# --------------------------------------------------------- #
function exin_ramdisk() {
	EXIN=$1
	EXCLUDE=0
	INCLUDE=1
	local ret_status=$QL_FAIL
	if [ "$2" = "1" ]; then
		detect_all_isp
		convert_isp_to_modules
	fi
	if [ "${QL_DISTRIBUTION}" = "${DISTRO_SUSE}" ]; then
		# Need to modify /etc/sysconfig/kernel
		modify_sysconfig_kernel $EXIN
		ret_status=$?
	else #Redhat/Asianux
		# Need to modify /etc/modules.conf for 2.4 and
		# /etc/modprobe.conf for 2.6
		modify_modules_conf $EXIN
		ret_status=$?
	fi

	if [ $ret_status = $QL_SUCCESS ]; then
		create_ramdisk "" $BACKUP
	fi
}



# --------------------------------------------------------- #
# force_installation ()	                                    #
# Does the installation without probing for the installed   #
# HBAs on the system. Will fail if the rpm is already	    #
# installed						    #
# Parameter: None 		                            #
# Returns: QL_SUCCESS on success, QL_FAIL on failure.	    #
# --------------------------------------------------------- #
function force_installation() {
	debug_print "In force_installation"
	#call install driver with param 1
	install_driver $QL_FORCE_INSTALLATION 2>&1 | tee -a $QL_USR_SRC/$QL_INSTALL_LOG
	return $?
}

# --------------------------------------------------------- #
# install_with_log					    #
# All installation std and stderr output will go the	    #
# log file						    #
# Note: Requires tee					    #
# Parameter: None 		                            #
# Returns: None						    #
# --------------------------------------------------------- #
function install_with_log() {
	debug_print "In install with log"
	echo "" >> $QL_USR_SRC/$QL_INSTALL_LOG
	echo "Installer Version: $QL_INSTALLER_VERSION" >> $QL_USR_SRC/$QL_INSTALL_LOG
	date  >> $QL_USR_SRC/$QL_INSTALL_LOG
	echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"\
		"~~~~~~~~~~~~~~~~~~~~~~~~~~~~" >> $QL_USR_SRC/$QL_INSTALL_LOG
	install_driver 2>&1 | tee -a $QL_USR_SRC/$QL_INSTALL_LOG
}


# --------------------------------------------------------- #
# detect_isp ()		                                    #
# Detects if the installed HBA is of typed FC or iSCSI	    #
# Fills up the global QL_HBA_LIST array with the installed  #
# HBAs							    #
# Parameter:						    # 
#	$1: Array of FC or iSCSI ISPs to be detected	    #
# Returns: QL_SUCCESS if HBA found. QL_FAIL if no HBA found #
# --------------------------------------------------------- #
function detect_isp() {
	ISP_LIST=( `echo "$1"` )
	debug_print "in detect_isp: ISP_LIST" 
	debug_print  ${ISP_LIST[@]}
	local ret_status=$QL_FAIL
	QL_HBA_LIST=() #Empty array
	# Get the list of line which has the keyword qlogic
	# Assumed that qlogic will be there in the output
	LSPCI=`lspci | grep -i qlogic`
	if [ $? = $QL_SUCCESS ]; then
		# check if the installed HBA ISP is one in the
		# input array list
		for LSPCI_LINE in "$LSPCI" 
		do
			for ISP in "${ISP_LIST[@]}"
			do
				echo "$LSPCI_LINE" | grep "$ISP" >& /dev/null
				if [ $? = $QL_SUCCESS ]; then
					debug_print "Found an ISP = $ISP"
					# Store it in our array
 					echo "${QL_HBA_LIST[@]}" | grep "$ISP" >& /dev/null
 					if [ $? != 0 ]; then
 						QL_HBA_LIST=( "${QL_HBA_LIST[@]}" "$ISP" );
 					fi
					ret_status=$QL_SUCCESS;
				fi
			done
		done 
	else
		# Could not find qlogic device
		# This could be because either `lspci` does 
		# not work on this system or QLogic device is
		# not installed on this system. 
		# Ask user to force for installation
		ret_status=$QL_FAIL;
	fi
	return $ret_status;
} 

# --------------------------------------------------------- #
# detect_isp2 () : Faster than detect_isp                   #
# Detects if the installed HBA is of typed FC or iSCSI      #
# Fills up the global QL_HBA_LIST array with the installed  #
# HBAs                                                      #
# Parameter:                                                #
#       $1: Array of FC or iSCSI ISPs to be detected        #
# Returns: QL_SUCCESS if HBA found. QL_FAIL if no HBA found #
# --------------------------------------------------------- #
function detect_isp2() {
        ISP_LIST=( `echo "$1"` )
        local ret_status=$QL_FAIL
        QL_HBA_LIST=() #Empty array
        # Get the list of line which has the keyword qlogic
        # Assumed that qlogic will be there in the output
        LSPCI=`lspci | grep -i qlogic`
        if [ $? = $QL_SUCCESS ]; then
                # check if the installed HBA ISP is one in the
                # input array list
                for LSPCI_LINE in $LSPCI
                do
                        for ISP in "${ISP_LIST[@]}"
                        do
                                echo "$LSPCI_LINE" | grep "$ISP" >& /dev/null
                                if [ $? = $QL_SUCCESS ]; then
                                        debug_print "Found an ISP = $ISP"
                                        # Store it in our array
 					echo "${QL_HBA_LIST[@]}" | grep "$ISP" >& /dev/null
 					if [ $? != 0 ]; then
 						QL_HBA_LIST=( "${QL_HBA_LIST[@]}" "$ISP" );
 					fi
                                        ret_status=$QL_SUCCESS
                                fi
                        done
                done
	else
                # Could not find qlogic device
                # This could be because either `lspci` does
                # not work on this system or QLogic device is
                # not installed on this system.
                # Ask user to force for installation
                ret_status=$QL_FAIL;
        fi
        return $ret_status;

}
                                                                                                 
# --------------------------------------------------------- #
# detect_all_isp ()	                                    #
# Detects if the installed HBA is of typed FC or iSCSI	    #
# Parameter: None					    # 
# Returns: None						    #
# --------------------------------------------------------- #
function detect_all_isp() {
	# 1 Detect FC
	if [ $QL_FC_INSTALLATION = 1 ]; then
		ISP_LIST=`echo "${QL_FC_ISP_LIST[@]}"`
		debug_print "ISP LIST 1 = $ISP_LIST"
		detect_isp2 "$ISP_LIST"
		if [ $? = $QL_SUCCESS ]; then #found FC HBA
			QL_INSTALLED_HBA[0]=$QL_FC_HBA
			QL_FC_HBA_LIST=( ${QL_HBA_LIST[@]} )
		fi
	fi

	# 2 Detect iSCSI
	if [ $QL_iSCSI_INSTALLATION = 1 ]; then
		ISP_LIST=`echo "${QL_iSCSI_ISP_LIST[@]}"`
		debug_print "ISP LIST 1 = $ISP_LIST"
		detect_isp2 "$ISP_LIST"
		if [ $? = $QL_SUCCESS ]; then #found iSCSI HBA
			QL_INSTALLED_HBA[1]=$QL_iSCSI_HBA
			QL_iSCSI_HBA_LIST=( ${QL_HBA_LIST[@]} )
		fi
	fi

	return
}

# --------------------------------------------------------- #
# display_iscsi_help ()                                     #
# Prints the help message for FC driver.                    #
# Parameter: None                                           #
# Returns: None                                             #
# --------------------------------------------------------- #
function display_iscsi_help() {
        echo ""
        echo_b "QLogic Linux HBA Driver Installer v$QL_INSTALLER_VERSION"
        echo ""
        echo ""
        echo "To begin Installation of QLogic HBA driver issue the following command:"
        echo ""
        echo "  # $QL_INSTALLER"
        echo ""
        echo "Usage: $QL_INSTALLER [OPTIONS]"

        echo "  -i,  --install"
        echo "                        The QLogic HBA driver installation does"
        echo "                        following:"
        echo "                            - build and installs the QLogic HBA driver"
        echo "                            - create ramdisk to load driver at boot time"
        echo "                            - load the driver "
        echo "                            - display device information"
        echo "                        Example: # $QL_INSTALLER -i"
        echo ""
        echo "  -up, --upgrade        Upgrade performs following"
        echo "                            - build and installs the QLogic HBA driver"
        echo "                            - create ramdisk to load driver at boot time"
        echo "                            - does not unload current drivers"
        echo ""
        echo "  -dl, --device_list    Display device connected on all HBAs"
        echo ""
        echo "  -u,  --uninstall [ -l|--loaded]"
        echo "                         Uninstall the QLogic HBA driver from the system."
        echo "                         Use option -l or --loaded to keep the drivers"
        echo "                         loaded in the system."
        echo "                         Example:"
        echo "                             Uninstall & unload driver:"
        echo "                                                 $QL_INSTALLER -u"
        echo "                             Uninstall & do not unload driver:"
        echo "                                                 $QL_INSTALLER -u -l"
        echo ""
        echo "  -l,  --load [module-name]  Load the QLogic HBA driver."
        echo "                        By default loads all the drivers"
        echo "                        Example: # $QL_INSTALLER -l qla4010"
        echo "  -ul, --unload [module-name]"
        echo "                        Unload the QLogic HBA driver."
        echo "                        By default unloads all the drivers"
        echo "                        Example: # $QL_INSTALLER -ul qla4022"
        echo ""
        echo "  -br, --buildramdisk [OPTIONS] [module-name]"
        echo -n "                             OPTIONS: --"; echo_b "ex"; echo "clude, -ex"
        echo -n "                               --"; echo_b "in"; echo "clude, -in"
        echo "                        Builds ramdisk by default."
        echo "                        This option can also be used to exclude or"
        echo "                        include QLogic module from the ramdisk"
        echo "                        Example:"
        echo "                              To exclude: # $QL_INSTALLER -br -ex"
        echo "                              To include: # $QL_INSTALLER -br -in"
        echo "                              To exclude or include a specific module"
        echo "                              specify the module name"
        echo "                                           # $QL_INSTALLER -br -in qla4010"
        echo ""
        #echo "  -dd, --driverdisk"
        #echo "                        Creates device driver update disk for the current"
        #echo "                        running kernel $KERNEL_VERSION"
        #echo ""
        echo "  -f, --force"
        echo "                        This option does the installation without probing for"
        echo "                        the installed HBAs on the system. It will fail if the"
        echo "                        rpm is already installed"
        echo ""
        echo "  -o,  --options [-help] [-ignore] (Parm1=Value1) (ParamN=ValueN)..."
        echo "                        Set driver command line parameters"
        echo "                        Example: # $QL_INSTALLER -o ql2xmaxqdepth=32"
        echo "                        Use \"-ignore\" option to not apply the "
        echo "                        parameters immediately. This will prevent "
        echo "                        driver unload & load after setting the "
        echo "                        driver parameters"
        echo "                        Example:"
        echo "                             # $QL_INSTALLER -o -ignore ql4xmaxqdepth=32"
        echo ""
        echo "  -h,  --help, -?       Print this help message"
        echo ""
        echo " To begin installation of QLogic HBA driver issue the following command:"
        echo ""
        echo "  # $QL_INSTALLER"
        echo ""
        return $QL_SUCCESS
}

# --------------------------------------------------------- #
# display_fc_help ()                                        #
# Prints the help message for FC driver.                    #
# Parameter: None                                           #
# Returns: None                                             #
# --------------------------------------------------------- #
function display_help() {
        echo ""
        echo_b "QLogic Linux HBA Driver Installer v$QL_INSTALLER_VERSION"
        echo ""
        echo ""
        echo "To begin Installation of QLogic HBA driver issue the following command:"
        echo ""
        echo "  # $QL_INSTALLER"
        echo ""
        echo "Usage: $QL_INSTALLER [OPTIONS]"

        echo "  -i,  --install [-dp|--disable_persistent_binding]"
        echo "                        The QLogic HBA driver installation does"
        echo "                        following:"
        echo "                            - build and installs the QLogic HBA driver"
        echo "                            - install SNIA HBA API Library"
        echo "                            - create ramdisk to load driver at boot time"
        echo "                            - default persistent binding "
        echo "                            - load the driver "
        echo "                            - display device information"
        echo "                        To disable default persistent binding during"
        echo "                        installation use \"-dp\""
        echo "                        Example: # $QL_INSTALLER -i -dp"
        echo ""
        echo "  -up, --upgrade        Upgrade performs following"
        echo "                            - build and installs the QLogic HBA driver"
        echo "                            - install SNIA HBA API Library"
        echo "                            - create ramdisk to load driver at boot time"
        echo "                            - does not unload current drivers"
        echo "                            - does not do persistent binding"
        echo ""
        echo "  -dl, --device_list    Display device connected on all HBAs"
        echo ""
        echo "  -u,  --uninstall [ -l|--loaded]"
        echo "                         Uninstall the QLogic HBA driver from the system."
        echo "                         Use option -l or --loaded to keep the drivers"
        echo "                         loaded in the system."
        echo "                         Example:"
        echo "                             Uninstall & unload driver:"
        echo "                                                 $QL_INSTALLER -u"
        echo "                             Uninstall & do not unload driver:"
        echo "                                                 $QL_INSTALLER -u -l"
        echo ""
        echo "  -p,  --persistent_binding [OPTIONS] [-i | -ignore ]"
        echo -n "                       OPTIONS: --"; echo_b "d"; echo "isable, -d"
        echo -n "                                --"; echo_b "e"; echo "nable,  -e"
        echo -n "                                --"; echo_b "u"; echo "pdate,  -u"
        echo "                        Disable, Enable or Update  persistent binding"
        echo "                        Example:"
        echo "                               To disable: # $QL_INSTALLER -p -d"
        echo "                               To enable:  # $QL_INSTALLER -p -e"
        echo "                               To update:  # $QL_INSTALLER -p -u"
        echo "                        Disbale persistenet binding will clear out the"
        echo "                        persistenet data."
        echo "                        Note: Update invokes SANsurfer CLI"
        echo "                        Use \"-ignore\" option to not apply the "
        echo "                        persistent binding immediately. This will prevent "
        echo "                        driver unload & load after doing persistent binding"
        echo ""
        echo "  -l,  --load [module-name]  Load the QLogic HBA driver."
        echo "                        By default loads all the drivers"
        echo "                        Example: # $QL_INSTALLER -l qla2300"
        echo "  -ul, --unload [module-name]"
        echo "                        Unload the QLogic HBA driver."
        echo "                        By default unloads all the drivers"
        echo "                        Example: # $QL_INSTALLER -ul qla2300"
        echo ""
        echo "  -br, --buildramdisk [OPTIONS] [module-name]"
        echo -n "                             OPTIONS: --"; echo_b "ex"; echo "clude, -ex"
        echo -n "                               --"; echo_b "in"; echo "clude, -in"
        echo "                        Builds ramdisk by default."
        echo "                        This option can also be used to exclude or"
        echo "                        include QLogic module from the ramdisk"
        echo "                        Example:"
        echo "                              To exclude: # $QL_INSTALLER -br -ex"
        echo "                              To include: # $QL_INSTALLER -br -in"
        echo "                              To exclude or include a specific module"
        echo "                              specify the module name"
        echo "                                           # $QL_INSTALLER -br -in qla2300"
        echo ""
        #echo "  -dd, --driverdisk"
        #echo "                        Creates device driver update disk for the current"
        #echo "                        running kernel $KERNEL_VERSION"
        #echo ""
        echo "  -o,  --options [-help] [-ignore] (Parm1=Value1) (ParamN=ValueN)..."
        echo "                        Set driver command line parameters"
        echo "                        Example: # $QL_INSTALLER -o ql2xmaxqdepth=32"
        echo "                        Use \"-ignore\" option to not apply the "
        echo "                        parameters immediately. This will prevent "
        echo "                        driver unload & load after setting the "
        echo "                        driver parameters"
        echo "                        Example:"
        echo "                             # $QL_INSTALLER -o -ignore ql2xmaxqdepth=32"
        echo ""
        echo "  -nv, --update_nvram <file name>"
        echo "                        Updates NVRAM on all HBAs in the system"
        echo "                        Example: # $QL_INSTALLER -nv <file name>"
        echo ""
        echo "  -b,  --update_bios <file name>"
        echo "                        Updates BIOS on all HBAs in the system"
        echo "                        Example: # $QL_INSTALLER -b <file name>"
        echo ""
        echo "  -s,  --scli"
        echo "                        Invoke SANsurfer FC CLI"
        echo "                        Example: # $QL_INSTALLER -s"
        echo ""
        echo "  -h,  --help, -?       Print this help message"
        echo ""
        echo " To begin installation of QLogic HBA driver issue the following command:"
        echo ""
        echo "  # $QL_INSTALLER"
        echo ""
        return $QL_SUCCESS
}

# --------------------------------------------------------- #
# invalid_option ()	                                    #
# Prints message on invalid options on command line.        #
# Parameter: None 		                            #
# Returns: 0.		 				    #
# --------------------------------------------------------- #
function invalid_option() {
	echo "$QL_INSTALLER: Option '$1' not supported"
 	echo "Try '$QL_INSTALLER --help' for more information."
	return $QL_SUCCESS
}

# Start #

# Check if we are on correct kernel version
# SUPPORTED_KERNEL_VER="" support both 2.4 and 2.6
# SUPPORTED_KERNEL_VER="2.6" support 2.6 only
# SUPPORTED_KERNEL_VER="2.4" support 2.4 only
if [ "$SUPPORTED_KERNEL_VER" != "" ]; then
	if [ "$SUPPORTED_KERNEL_VER" != "$KERNEL_MAJ_MIN" ]; then
		echo "Package-kernel missmatch."
		echo "You are trying to run $QL_INSTALLER on kernel $KERNEL_MAJ_MIN."
		echo "Please get the correct installer and run again." 	
	fi
fi  

# allow installation by root only
if test $EUID -ne 0 ; then
	echo "Must be root to install..."
        exit 1
fi

# check if /sbin and /usr/sbin are in path
check_path

# Set the installation flags
get_installer_type

# Create the log file in /usr/src/qlogic/
mkdir -p $QL_USR_SRC

#include files
if [ -f "./set_driver_param" ]; then
       source ./set_driver_param
else
       echo "set_driver_param file missing" 2>&1 | tee -a $QL_USR_SRC/$QL_INSTALL_LOG
fi

# Get the driver name and version based on the kernel version
get_driver_details

# Set the installation log file name
set_install_log

QL_CHOICE=""

if [ $# = 0 ]; then
# Default option, install
	QL_CHOICE="install_with_log"
else
	# need to loop thru the  args
	until [ -z "$1" ]  # Until all parameters used up...
	do
	case $1 in
		-i | --install )
			# install the driver
			QL_CHOICE="install_with_log" 
		;;

		-up | --upgrade )
			# install the driver
			QL_CHOICE="install_with_log" 
			QL_UPGRADE=1
		;;
		-dl | --device_list )
			display_device_information
			exit 0
		;;
		-u | --uninstall )
			UNLOAD_DRIVER=0
			if [ "$2" = "--loaded" ] || [ "$2" = "-l" ]; then 
				UNLOAD_DRIVER=1	
			fi

			display_uninstall_msg $QL_BEGIN 
			# uninstall all the driver
			if [ $QL_iSCSI_INSTALLATION = 1 ]; then
				uninstall_driver $QL_iSCSI_DRIVER_NAME $UNLOAD_DRIVER
			fi 
			if [ $QL_FC_INSTALLATION = 1 ]; then
				uninstall_driver $QL_FC_DRIVER_NAME $UNLOAD_DRIVER
				#restore /etc/qla2***.conf
				restore_conf
			fi 

			display_uninstall_msg $QL_DONE
			exit 0
		;;
		-l | --load )
			if [ "$2" != "" ]; then 
				#user provided the module name
				load_module $2 
			else
				# load all the driver
				load_driver
			fi
			exit 0
		;;
		-ul | --unload )
			if [ "$2" != "" ]; then 
				#user provided the module name
				unload_module $2
			else

				# unload all the driver
				unload_driver
			fi
			exit 0
		;;
		-br | --ramdisk | --buildramdisk )
			# create the ramdisk
			# User would need to update the modules.cof file
			# and then call this function
			if [ "$2" != "" ]; then
				case $2 in 
					--exclude | -ex )
						DETECT=1
						# check if user provided the module
						if [ "$3" != "" ]; then #we have a list 
							shift
							shift
							prepare_modules_list $*
							DETECT=0
						fi
						exin_ramdisk 0 $DETECT
					;;
					--include | -in ) 
						DETECT=1
						# check if user provided the module
						exin_ramdisk 1 $DETECT
					;;
					-build )
						create_ramdisk "" $BACKUP #backup
					;;
					* )
						echo "Invalid option for build ramdisk"
						echo "Please see help $QL_INSTALLER -h"
					;;
				esac
			else
				create_ramdisk "" $BACKUP #backup
			fi
			exit 0
		;;
#		-dd | --driverdisk )
#			echo "Creating driver disk for - "
#			echo "Kernel verison: $KERNEL_VERSION"
#			echo "Architecture: `uname -m`"
#			build_driver_disk
#			exit 0
#		;;
		-nv | --update_nvram )
			if [ $QL_iSCSI_INSTALLATION = 1 ]; then
				echo ""
				echo "This feature is not supported"
				echo ""
				exit 0
			fi

			# update the nvram
			check_cli_installed
			shift	
			scli -r all $* 2> /dev/null
			exit 0
		;;
		-b | --update_bios )
			if [ $QL_iSCSI_INSTALLATION = 1 ]; then
				echo ""
				echo "This feature is not supported"
				echo ""
				exit 0
			fi

			# update the bios
			check_cli_installed
			shift	
			scli -b all $* 2> /dev/null
			exit $?
		;;
		-s | --scli )
			if [ $QL_iSCSI_INSTALLATION = 1 ]; then
				echo ""
				echo "This feature is not supported"
				echo ""
				exit 0
			fi

			# Invoke sclix
			check_cli_installed
			if [ $? = $QL_SUCCESS ]; then
				scli 2> /dev/null
			fi

			exit $?
		;;
		-dp | --disable_persistent_binding )
			if [ $QL_iSCSI_INSTALLATION = 1 ]; then
				echo ""
				echo "This feature is not supported"
				echo ""
				exit 0
			fi

			QL_CHOICE="install_with_log"
			QL_DO_BIND=0
		;;
		-p | --persistent_binding )
			if [ $QL_iSCSI_INSTALLATION = 1 ]; then
				echo ""
				echo "This feature is not supported"
				echo ""
				exit 0
			fi

			case $3 in
			"-i" | "-ignore" | "" )
			;;
			*)
				echo "Invalid parameter \"$3\", shoudl be -i or -ignore"
				exit 1
			;;
			esac
			set_persistent_binding $2 $3
			exit 0
		;;
		-o | --options )
			# Modify the options in /etc/modules.conf or 
			# modprobe.conf/.local
			LOAD_DRIVER=1
			case $2 in 
				help | -help | -h | -? )
					display_options_help
					exit 0
				;;
				-ignore | ignore | i )
					LOAD_DRIVER=0	
					shift
				;;
			esac
			shift
			set_options $*
			if [ $? = $QL_SUCCESS ]; then
				#create the ramdisk
				create_ramdisk "" $BACKUP #backup
				if [ $LOAD_DRIVER = 1 ]; then
					#unload/load the driver
					echo ""
					if [ $QL_FC_INSTALLATION = 1 ]; then
                                                unload_driver $QL_FC_HBA
                                                echo ""
                                                load_driver $QL_FC_HBA
					fi
					if [ $QL_iSCSI_INSTALLATION = 1 ]; then
                                                unload_driver $QL_iSCSI_HBA
                                                echo ""
                                                load_driver $QL_iSCSI_HBA
					fi

				fi
			fi
			exit 0
		;;
		-f | --force )
			# force installation 
			QL_CHOICE=force_installation
		;;
		-h | --help | -? )
			if [ $QL_FC_INSTALLATION = 1 ]; then
				# display help message
				display_fc_help
			else
				display_iscsi_help
			fi
			exit 0
		;;
		# Support for adding entry in modules.conf
		# Support for removing the entry from modules.conf
		* )
			# invalid option
			invalid_option $*
			exit 0
		;;
	esac
	shift
	done
fi
$QL_CHOICE
# End  #
