#!/bin/bash

# QLogic FC HBA Set Device Timeout Utility
# Copyright (C) 2006 QLogic Corporation (www.qlogic.com)
#
#This program is free software; you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation; either version 2 of the License, or
#(at your option) any later version.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

#--------------------------------------------------------------------------# 
#This script is used to set the timeout on devices connected to QLogic  HBAs 
#The timeout is applied to the commands sent to the target. This will be useful
#where targets need longer time to execute a command during heavy I/O. 
#Setting a longer timeout can reduce the chances of Linux SCSI midlayer aborting
#the tasks.
#---------------------------------------------------------------------------#


QL_SETTIMEOUT_VERSION=1.7
QL_SUCCESS=0
QL_FAIL=1
QL_CALL_AGAIN=2
QL_CALL_RETURNED=3
QL_CALL_AGAIN_NO_WAIT=4
QL_CALL_AGAIN_NO_WAIT1=5
QL_COMMON=0
QL_SETT_SCRIPT=$0
QL_MAX_TO=65536 
QL_MIN_TO=0 
ALL_HOSTS=()
ALL_TARGETS=()

#*****************************************#
# qlu_hit_any_key()
# Waits for user to hit a key
# PARAMETERS : NONE
# RETURNS        : None
#*****************************************#
function qlu_hit_any_key()
{
        echo -n "Hit any key to continue......"
        read -n 1
        clear
}

#*****************************************#
# qlu_is_number()
# Check is input is a number or not
# PARAMETERS : IN Values
# RETURNS        : 0: If number
#*****************************************#
function qlu_is_number()
{
	echo $1 | grep -w "^[0-9]\+$" >& /dev/null
	return $?
}

#*****************************************#
# qlu_display_usage()
# Displays the short usage message
# PARAMETERS : None
# RETURNS        : None
#*****************************************#
function qlu_display_usage()
{
	echo "Usage: $QL_SETT_SCRIPT HOST TARGET TIMEOUT"
	echo "For more information please see help"
	echo "$QL_SETT_SCRIPT -h"
	exit 1
}

# --------------------------------------------------------- #
# 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
}


# --------------------------------------------------------- #
# qlu_settimeout_help ()		                    #
# Prints the help message                                   #
# Parameter: None                                           #
# Returns: None                                             #
# --------------------------------------------------------- #
function qlu_settimeout_help() {
	clear
        echo ""
        echo_b "QLogic Linux Set Device Timeout Utility v$QL_SETTIMEOUT_VERSION"
        echo ""
        echo ""
        echo "Usage: ${QL_SETT_SCRIPT} [OPTIONS]"
        echo ""
        echo " [DEFAULT]"
        echo "				Display timeout of devices connected to all HOSTs"
        echo ""
        echo " [HOST]"
        echo "				Display timeout of devices connected to HOST"
	echo ""
        echo " [HOST] [TARGET]"
        echo "				Display timeout of devices connected to a TARGET on HOST"
        echo ""
        echo " [HOST] [TARGET] [TIMEOUT]"
        echo "				To set timeout on devices connected to a TARGET on HOST"

	echo ""
        echo " -h,  --help, ?"
	echo "				Prints this help message"
	echo ""
        echo " -i,  --interactive"
        echo "				Use this option to use the menu driven program"

}

#*****************************************#
# modify_devices()
# Changes the timeout of specified device
# PARAMETERS : HOST TARGET AND TIMEOUT
# RETURNS : NONE
#*****************************************#
function modify_devices ()
{
local RET=1
local L_WC=0
local L_HOST=${1}
local L_TARGET=${2}
local L_TO=${3}

echo ""
while [ $RET -ne 0 ]
do
  if  [ ${L_TO} -ge ${QL_MIN_TO} ] && [ ${L_TO} -le ${QL_MAX_TO} ]; then 
           get_luns ${L_HOST} ${L_TARGET}
           if [ $? -eq 0 ]; then
                 #echo "No LUN for this host,target pair"
                 return 1
           else
    		echo "Modifying the devices......"
    		echo ""
	        echo -e "DEVICE\t\t\t\tOLD TIMEOUT\t\tNEW TIMEOUT" 
                 QL_SORTED_LUNS=(`echo ${QL_LUNS[@]} | sed "s/ /\\n/g" | sort -n`)
                   cd /sys/class/scsi_device
                   for LUN in ${QL_SORTED_LUNS[@]}
                   do
                       cd ${L_HOST}\:0\:${L_TARGET}\:${LUN}/device
                       echo_b "${L_HOST}:0:${L_TARGET}:${LUN}"
                       L_WC=`echo ${L_HOST}:0:${L_TARGET}:${LUN} | wc -m`
                       qlu_is_number $L_WC
                       if [ $? -eq 0 ]; then
                            if [ $L_WC -lt 9 ]; then
                                 echo -en "\t\t\t\t"
                            elif [ $L_WC -lt 17 ]; then
                                   echo -en "\t\t\t"
                            elif [ $L_WC -lt 25 ]; then
                                   echo -en "\t\t"
                            else
                                  echo -en "\t"
                            fi
		       else
				echo -e "\t"
	 	       fi
	     
		echo -en "`cat timeout`"
		echo ${L_TO} > timeout
		echo -e "\t\t\t`cat timeout`"
		cd ../..
          done | more
         RET=0
      fi
 else
      while [ $RET -ne 0 ]   
      do
         echo -en "Select new timeout in the range [$QL_MIN_TO - $QL_MAX_TO] : "
         read L_TO
	 qlu_is_number $L_TO
	 RET=$?
	 if [ $RET -ne 0 ] ; then
		echo "Please enter a numeric value : "
	 fi
      done
        RET=1
 fi
done
}

# --------------------------------------------------------- #
# get_hosts ()                                              #
# Detects all the targets connected to given host and fills #
# ALL_TARGETS array                                         #
# Parameters : 					            #		 
#         	NONE                                        #
# Returns :                                                 #
#               Number of hosts                             #
# --------------------------------------------------------- #

function get_hosts
{
	ls -d /sys/bus/pci/drivers/qla*/*/host* &> /dev/null
	if [ $? -eq 0 ]; then
		ALL_HOSTS=( `ls -d /sys/bus/pci/drivers/qla*/*/host* | sed -e "s/.*host//"` )
	fi
		
        return ${#ALL_HOSTS[@]}
}

# --------------------------------------------------------- #
# get_targets ()                                            #
# Detects all the targets connected to given host and fills #
# ALL_TARGETS array                                          #
# Parameters :                                              #
#              HOST                                         #
# Returns :                                                 #
#           Number of targets                               #
# --------------------------------------------------------- #
function get_targets
{
local HOST=$1
local TARGET
local TARGETS=()
        if [ -e /sys/class/scsi_host/host$HOST/device/ ]; then
                cd /sys/class/scsi_host/host$HOST/device/

                ls -d rport-$HOST:0-* &> /dev/null
                if [ $? -eq 0 ]; then
                        ALL_TARGETS=( `ls -d rport-$HOST:0-* | sed "s/rport-$HOST:0-//"` )
                fi

                ls -d target$HOST:0:* &> /dev/null
                if [ $? -eq 0 ]; then
                        ALL_TARGETS=( `ls -d target$HOST:0:* | sed "s/target$HOST:0://"` )
                fi
                
		ls -d $HOST:0:* &> /dev/null
		if [ $? -eq 0 ]; then
			TARGETS=`ls -d $HOST:0:* | sed "s/$HOST:0:\(.*\):.*/\1/"`
			for TARGET in $TARGETS
			do
				echo "${ALL_TARGETS[@]}" | grep -w $TARGET >& /dev/null
				if [ $? -ne 0 ]; then
					ALL_TARGETS=(${ALL_TARGETS[@]} $TARGET)
				fi
			done
                fi

        fi
        return ${#ALL_TARGETS[@]}
}

# --------------------------------------------------------- #
# get_luns ()                                               #
# Detects all the LUNS connected to given TARGET and fills  #
# QL_LUNS array                                             #
# Parameters :                                              #
#              <HOST> <TARGET>                              #
# Returns :                                                 #
#           Number of LUNS                                  #
# --------------------------------------------------------- #

function get_luns
{
        local HOST=${1}
        local TARGET=${2}

        if [ -e /sys/class/scsi_host/host$HOST/device/target${HOST}:0:${TARGET} ]; then
                cd /sys/class/scsi_host/host$HOST/device/target${HOST}:0:${TARGET}/
        elif [ -e /sys/class/scsi_host/host$HOST/device/rport-$HOST:0-$TARGET/target${HOST}:0:${TARGET} ]; then
                cd /sys/class/scsi_host/host$HOST/device/rport-$HOST:0-$TARGET/target${HOST}:0:${TARGET}/
        fi

        QL_LUNS=( `ls -d $HOST:0:$TARGET:* 2> /dev/null | sed "s/$HOST:0:$TARGET://"` )
        return ${#QL_LUNS[@]}
}

#*****************************************#
# display_timeout()
# Displays the timeout of specified device
# PARAMETERS : HOST & TARGET
# RETURNS : NONE
#*****************************************#

function display_timeout
{
   local L_WC
   local L_HOST=${1}
   local L_TARGET=${2}

 get_luns ${L_HOST} ${L_TARGET}
        if [ $? -eq 0 ]; then
                echo "No LUNS for HOST:$L_HOST TARGET:$L_TARGET "
        else
                echo ""
                echo -e "DEVICE\t\t\t\tTIMEOUT"
                QL_SORTED_LUNS=(`echo ${QL_LUNS[@]} | sed "s/ /\\n/g" | sort -n`)
                cd /sys/class/scsi_device
                for LUN in ${QL_SORTED_LUNS[@]}
                do
                        cd ${L_HOST}\:0\:${L_TARGET}\:${LUN}/device
                        echo_b "${L_HOST}:0:${L_TARGET}:${LUN}"
                        L_WC=`echo ${L_HOST}:0:${L_TARGET}:${LUN} | wc -m`
			qlu_is_number $L_WC
                        if [ $? -eq 0 ]; then
                            if [ $L_WC -lt 9 ]; then
                                 echo -en "\t\t\t\t"
                            elif [ $L_WC -lt 17 ]; then
                                   echo -en "\t\t\t"
                            elif [ $L_WC -lt 25 ]; then
                                   echo -en "\t\t"
                            else
                                  echo -en "\t"
                            fi
                       else
                                echo -e "\t"
                       fi

                       echo -e "`cat timeout`"
                       cd ../..
                   done | more
          fi
}

#*****************************************#
# display_selective_dev() 
# Displays the timeout of specified device
# PARAMETERS :NONE 
# RETURNS : NONE
#*****************************************#

function display_selective_dev
{
	local L_WC
	local L_GO_BACK=0
	local L_QUIT=0
	local SEL_HOST		
	local SEL_TARGET
   	local SC2_CHOICE=0
   	local SC3_CHOICE=0

get_hosts
STATUS=$QL_CALL_AGAIN # to adjust with while loop
while [ $STATUS -eq $QL_CALL_AGAIN ]
do	
	clear
	LN=1 # Line number
	echo "Select  HOST "
	for HOST in ${ALL_HOSTS[@]}
	do
		echo "	$LN. Host $HOST"
		LN=$((LN+1))
	done
	echo "	$LN. GO BACK TO PREVIOUS MENU"
	L_GO_BACK=$LN
	LN=$((LN+1))

	echo "	$LN. QUIT"
	echo ""
	echo -n "Please select one of the options above : "
	read SC2_CHOICE  # read user choice for qlu_screen_2
	if [ "$SC1_CHOICE" == "" ]; then
		continue
	fi	
	case $SC2_CHOICE in
		q | Q | quit | $LN )
		exit 0
		;;
	esac

	if [ $SC2_CHOICE -ge 1 ] && [ $SC2_CHOICE -lt $LN ]; then 
		STATUS=$QL_CALL_RETURNED
	fi
done

if [ $SC2_CHOICE -ne $L_GO_BACK ]; then
	SEL_HOST=${ALL_HOSTS[((${SC2_CHOICE} - 1))]}
else
	return $QL_CALL_AGAIN_NO_WAIT
fi

STATUS=$QL_CALL_AGAIN # to adjust with while loop
while [ $STATUS -eq $QL_CALL_AGAIN ]
do	
	clear
	LN=1 # Line number
	echo "Select Target for HOST${SEL_HOST}"

	get_targets ${SEL_HOST}
	for TARGETS in ${ALL_TARGETS[@]}
	do
		echo "	$LN. Target $TARGETS"
		LN=$((LN+1))
	done

	echo "	$LN. GO BACK TO PREVIOUS MENU"
	L_GO_BACK=$LN
	LN=$((LN+1))
	echo "	$LN. QUIT"
	L_QUIT=$LN

	echo ""
	echo "Please select one of the options above : "
	read SC3_CHOICE # read user choice for qlu_screen_3
	case $SC3_CHOICE in
		q | Q | quit | $L_QUIT )
		exit 0
		;;
	esac

	if [ $SC3_CHOICE -ge 1 ] && [ $SC3_CHOICE -lt $LN ]; then
		STATUS=$QL_CALL_RETURNED
	fi
done
if [ $SC2_CHOICE -ne $L_GO_BACK ]; then
	SEL_TARGET=${ALL_TARGETS[((${SC3_CHOICE} - 1))]}
else
	return $QL_CALL_AGAIN_NO_WAIT1
fi
	get_luns ${SEL_HOST} ${SEL_TARGET}
	if [ $? -eq 0 ]; then
		echo "No LUNS for HOST:$SEL_HOST TARGET:$SEL_TARGET "
	else
		echo ""
		echo -e "DEVICE\t\t\t\tTIMEOUT"
		QL_SORTED_LUNS=(`echo ${QL_LUNS[@]} | sed "s/ /\\n/g" | sort -n`)
		cd /sys/class/scsi_device
		for LUN in ${QL_SORTED_LUNS[@]}
		do
			cd ${SEL_HOST}\:0\:${SEL_TARGET}\:${LUN}/device
			echo_b "${SEL_HOST}:0:${SEL_TARGET}:${LUN}" 
			L_WC=`echo ${SEL_HOST}:0:${SEL_TARGET}:${LUN} | wc -m`
			qlu_is_number $L_WC
			if [ $? -eq 0 ]; then
		   	    if [ $L_WC -lt 9 ]; then
		 	         echo -en "\t\t\t\t"
		            elif [ $L_WC -lt 17 ]; then
		   	           echo -en "\t\t\t"
 		            elif [ $L_WC -lt 25 ]; then
			           echo -en "\t\t"
		            else
		 	          echo -en "\t"
		            fi
		       else
                                echo -e "\t"
                       fi
 
	               echo -e "`cat timeout`" 
                       cd ../..
		done 
          fi
return $QL_CALL_RETURNED
} 

#*****************************************#
# display_all()                           #
# Display timeout of all devices,         #
# internally calls display_timeout        # 
# PARAMETERS : HOST / ALL                 #
# RETURNS    : NONE                       #
#*****************************************#	

function display_all()
{
local OPTION=${1}
local HOST_LIST=()

echo "${1}" | grep "^[0-9]" &> /dev/null
if [ $? -eq 0 ]; then
	get_hosts
	echo "${ALL_HOSTS[@]}" | grep -w "${1}" &> /dev/null
	if [ $? -ne 0 ]; then
		echo "ERROR: HOST $1 not found on the system"
		exit 1
	else
		HOST_LIST=($1)
	fi
elif [ "$OPTION" == "ALL" ]; then
	get_hosts
	HOST_LIST=( `echo ${ALL_HOSTS[@]}` )
else
	exit 1
fi

for HOST in ${HOST_LIST[@]}
do
	get_targets $HOST
	if [ $? -eq 0 ]; then
		echo "No TARGET connected to HOST$HOST"
	else
		for TARGET in ${ALL_TARGETS[@]}
		do
			display_timeout $HOST $TARGET 	
		done
	fi
done
}

#*****************************************#
# all_devices()
# Changes timeout of all devices,
# internally calls modify_devices
# PARAMETERS : TIMEOUT (if QL_COMMON =1)
#              else
#              NONE
# RETURNS    : NONE
#*****************************************#

function all_devices ()
{

BACK=$QL_CALL_AGAIN # to adjust with while loop
while [ $BACK -eq $QL_CALL_AGAIN ]
do
	STATUS=$QL_CALL_AGAIN # to adjust with while loop
	while [ $STATUS -eq $QL_CALL_AGAIN ]
	do
		clear
		LN=1 # Line number
		echo "Select option: "
		echo "	1. MODIFY TIMEOUT"
		echo "	2. DISPLAY TIMEOUT"
		echo "	3. GO BACK TO PREVIOUS MENU"
		echo "	4. QUIT "
		echo ""
		echo -n "Please select one of the options above : "
		read SC2_CHOICE # read user choice for qlu_screen_2

		case $SC2_CHOICE in
			q | Q | quit | 4 )
			exit 0
			;;
		esac

		if [ $SC2_CHOICE -ge 1 ] && [ $SC2_CHOICE -lt 4 ]; then
			STATUS=$QL_CALL_RETURNED
		fi
	done

	if [ $SC2_CHOICE -ne 3 ]; then
		if [ $SC2_CHOICE -eq 1 ]; then
			modify_all_devices
			BACK=$QL_CALL_AGAIN
			qlu_hit_any_key
		else
			display_all ALL | more
			BACK=$QL_CALL_AGAIN
			qlu_hit_any_key
		fi
	else
		return $QL_CALL_AGAIN_NO_WAIT
	fi
done

return $QL_CALL_RETURNED
}

#*****************************************#
# modify_all_devices()
# Changes timeout of all devices, 
# internally calls modify_devices
# PARAMETERS : TIMEOUT (if QL_COMMON =1)
#	       else 
#	       NONE
# RETURNS    : NONE
#*****************************************#

function modify_all_devices ()
{

local RET=1
# Clean ALL_TARGETS() first
ALL_TARGETS=()
cd /sys/class/scsi_device
get_hosts
for HOST in ${ALL_HOSTS[@]}
do
ls $HOST:0:*:*/device/timeout >& /dev/null
if [ $? -eq 0 ]; then
	for TARGET in `ls -d $HOST:0:* 2> /dev/null | sed -e "s/$HOST:0://" | sed -e "s/:.*//"`
	do
		#echo " target value $TARGETS"
		echo ${ALL_TARGETS[@]} | grep "$TARGET\b" >& /dev/null
		if [ $? -ne 0 ]; then
			ALL_TARGETS=(${ALL_TARGETS[@]} $TARGET)
		fi
	done

	for TARGET in ${ALL_TARGETS[@]}
	do
		if [ $QL_COMMON -eq 0 ]; then
			while [ $RET -ne 0 ]
			do
				echo -n "Enter new timeout for HOST $HOST and TARGET $TARGET: "
				read N_TIMEOUT
				qlu_is_number $N_TIMEOUT
				RET=$?	
				if [ $RET -ne 0 ]; then
					echo "Please enter a numeric value"
				fi
			done
			RET=1
		else 
			N_TIMEOUT=$1
		fi
		modify_devices ${HOST} ${TARGET} ${N_TIMEOUT}	
	done
fi
done
}

#*****************************************#
# modify_sel_device ()
# Changes timeout of selected HOST
# internally calls modify_devices
# PARAMETERS : HOST
# RETURNS    : $QL_CALL_RETURNED
#*****************************************#
function modify_sel_device ()
{
clear
local SEL_HOST=$1
local SC2_CHOICE=0
local L_GO_BACK=0
local L_QUIT=0
local RET=1

cd /sys/class/scsi_device

ls $SEL_HOST:0:*:*/device/timeout >& /dev/null
if [ $? -ne 0 ]; then
	echo "No Targets connected to Host $SEL_HOST"
	return $QL_CALL_RETURNED
fi
for TARGETS in `ls -d $SEL_HOST:0:* | sed -e "s/$SEL_HOST:0://" | sed -e "s/:.*//"`
do
	#echo " target value $TARGETS"
	echo ${ALL_TARGETS[@]} | grep "$TARGETS\b" >& /dev/null
	if [ $? -ne 0 ]; then
		ALL_TARGETS=(${ALL_TARGETS[@]} $TARGETS)
	fi
done

BACK=$QL_CALL_AGAIN
while [ $BACK -eq $QL_CALL_AGAIN ]
do
	STATUS=$QL_CALL_AGAIN # to adjust with while loop
	while [ $STATUS -eq $QL_CALL_AGAIN ]
	do	
		clear
		LN=1 # Line number
		echo "Select Target for HOST${SEL_HOST}"
		for TARGETS in ${ALL_TARGETS[@]}
		do
			echo "	$LN. Target $TARGETS"
			LN=$((LN+1))
		done
		echo "	$LN. GO BACK TO MAIN MENU"
			L_GO_BACK=$LN
			LN=$((LN+1))
		echo "	$LN. QUIT"
			L_QUIT=$LN
		echo ""
		echo -n "Please select one of the options above : "
		read SC2_CHOICE # read user choice for qlu_screen_2
	
		case $SC2_CHOICE in
			q | Q | quit | $L_QUIT )
			exit 0
			;;
		esac

		if [ $SC2_CHOICE -ge 1 ] && [ $SC2_CHOICE -lt $LN ]; then
			STATUS=$QL_CALL_RETURNED
		fi
	done
	if [ $SC2_CHOICE -ne $L_GO_BACK ]; then
		SEL_TARGET=${ALL_TARGETS[((${SC2_CHOICE} - 1))]}
		echo ""
		AGAIN=$QL_CALL_AGAIN # to adjust with while loop
		while [ $AGAIN -eq $QL_CALL_AGAIN ]
		do
			STATUS=$QL_CALL_AGAIN # to adjust with while loop
			while [ $STATUS -eq $QL_CALL_AGAIN ]
			do
        			clear
		        	LN=1 # Line number
	        		echo "Select option: "
				echo "	1. MODIFY TIMEOUT"
				echo "	2. DISPLAY TIMEOUT"
				echo "	3. GO BACK TO PREVIOUS MENU"
				echo "	4. GO BACK TO MAIN MENU"
				echo "	5. QUIT	"
				echo ""
				echo -n "Please select one of the options above : "
				read SC2_CHOICE # read user choice for qlu_screen_2
				case $SC2_CHOICE in
					q | Q | quit | 5 )
					exit 0
					;;
				esac

				if [ $SC2_CHOICE -ge 1 ] && [ $SC2_CHOICE -le 4 ]; then
					STATUS=$QL_CALL_RETURNED
				fi
			done
			if [ $SC2_CHOICE -eq 1 ]; then
				while [ $RET -ne 0 ]
				do
					echo -n "Please enter new timeout for selected device : "
					read N_TIMEOUT
					qlu_is_number $N_TIMEOUT
					RET=$?
					if [ $RET -ne 0 ]; then
						echo "Please enter a numeric value"
					fi
				done
				RET=1
				modify_devices ${SEL_HOST} ${SEL_TARGET} ${N_TIMEOUT}
				AGAIN=$QL_CALL_AGAIN # to adjust with while loop
				qlu_hit_any_key
			fi
			if [ $SC2_CHOICE -eq 2 ]; then
				display_timeout ${SEL_HOST} ${SEL_TARGET}
				AGAIN=$QL_CALL_AGAIN # to adjust with while loop
				qlu_hit_any_key
			fi
			if [ $SC2_CHOICE -eq 3 ]; then
				AGAIN=$QL_CALL_RETURNED
				BACK=$QL_CALL_AGAIN 
			fi
			if [ $SC2_CHOICE -eq 4 ]; then
				return $QL_CALL_AGAIN_NO_WAIT
			fi
		done
	else
		return $QL_CALL_AGAIN_NO_WAIT
	fi
done
return $QL_CALL_RETURNED
}


#*****************************************#
# qlu_main_screen ()
# Displays the main screen of the program
# Accepts and validates the input
# PARAMETERS : NONE
# RETURNS    : $QL_CALL_AGAIN
#*****************************************#
function qlu_main_screen ()
{
local RET=1
local HOST=0
local TARGET 
	
get_hosts
STATUS=$QL_CALL_AGAIN # to adjust with while loop
while [ $STATUS -eq $QL_CALL_AGAIN ]
do
	clear
	echo_b " Welcome to QLogic Set Device Timeout Utility"
	echo ""
	echo "=============================================="
	echo ""
	echo "MAIN MENU"
	LN=1  # LN for Line Number
	for HOST in ${ALL_HOSTS[@]}
	do
		echo "	$LN. HOST${HOST}" #1
		LN=$((LN+1)) #2
	done

	echo "	$LN. SELECT ALL HOSTS" #2
	echo "	$((LN+1)). SET COMMON TIMEOUT FOR ALL HOSTS"  #3
	echo "	$((LN+2)). QUIT"  #4
	echo ""
	echo -n "Please select one of the options above : "
	read SC1_CHOICE # read user choice for qlu_screen_2 
	
	TEMP=$((LN+2)) #4
	case $SC1_CHOICE in
		q | Q | quit | $TEMP )
		exit 0
		;;
	esac

	if [ $SC1_CHOICE -ge 1 ] && [ $SC1_CHOICE -le $((LN+2)) ]; then
		STATUS=$QL_CALL_RETURNED
	fi
done

TEMP=$((LN+1)) #3
#Choice 1
if [ $SC1_CHOICE -lt ${LN} ] && [ $SC1_CHOICE -gt 0 ]; then #0<choice<2
	SEL_HOST=${ALL_HOSTS[((${SC1_CHOICE} - 1))]}
	modify_sel_device $SEL_HOST
	if [ $? -eq $QL_CALL_AGAIN_NO_WAIT ]; then
		return $QL_CALL_AGAIN_NO_WAIT
	fi
	return $QL_CALL_AGAIN

#Choice	3
elif [ $SC1_CHOICE -eq $TEMP ]; then

	while [ $RET -ne 0 ]
	do
		echo -n "Enter the common timeout : "
		read N_TIMEOUT
		qlu_is_number $N_TIMEOUT
		RET=$?
		if [ $RET -ne 0 ]; then
			echo "Please enter a numeric value"
		fi
	done
	RET=1

	QL_COMMON=1
	modify_all_devices $N_TIMEOUT
	QL_COMMON=0
	return $QL_CALL_AGAIN

#Choice 2	
elif [ $SC1_CHOICE -eq $LN ]; then
	QL_COMMON=0
	all_devices
	STATUS=$?
	if [ $STATUS -eq $QL_CALL_AGAIN_NO_WAIT ]; then
		return $QL_CALL_AGAIN_NO_WAIT 
	else
		return $QL_CALL_AGAIN
	fi
else
	return $QL_CALL_AGAIN
fi
}

# Start
#check if /sys exist, if not cannot do anything
if [ ! -e /sys/class/scsi_device ]; then
	echo "Could not find /sys/class/scsi_device, cannot proceed."
	echo "Please make sure sysfs filesystem is mounted."
	exit 1
fi

if [ $# -ne 0 ]; then
	# need to loop thru the  args
	until [ -z "$1" ]  # Until all parameters used up...
	do
		case $1 in
			-i | --interactive )
				STATUS=$QL_CALL_AGAIN
				clear
				while [ $STATUS -eq $QL_CALL_AGAIN ]
				do
					qlu_main_screen
					STATUS=$?
					if [ $STATUS -eq $QL_CALL_AGAIN_NO_WAIT ]; then
						STATUS=$QL_CALL_AGAIN;	
					else
						qlu_hit_any_key
					fi
				done
				exit 0
			;;

			-h | --help | \? )
				qlu_settimeout_help
				exit 0
			;;
			* )
				#get host/target/timeout
				IN_HOST=${1}
				IN_TARGET=${2}
				IN_TIMEOUT=${3}

				#validate if valid HOST
				get_hosts
				HOST_LIST=( `echo "${ALL_HOSTS[@]}"` )
				echo "${HOST_LIST[@]}" | grep "${IN_HOST}\b" &> /dev/null
				if [ $? -ne 0 ]; then
					echo "Host: $IN_HOST is not a QLogic HBA"
					exit 1
				fi

				if [ $# -eq 3 ]; then                            
					get_targets ${IN_HOST}
					echo "${ALL_TARGETS[@]}" | grep "${IN_TARGET}\b" &> /dev/null
					if [ $? -ne 0 ]; then
						echo "Enter valid TARGET"
						qlu_display_usage
					        exit 0
					fi
					qlu_is_number ${IN_TIMEOUT}
					if [ $? -ne 0 ]; then
						echo "Input should be a number"
						qlu_display_usage
                        	        else  
					     modify_devices ${IN_HOST} ${IN_TARGET} ${IN_TIMEOUT}
					     exit 0
					fi
				fi								
				#here means user specified only HOST/TARGET
				if [ $# -eq 2 ]; then
					get_targets ${IN_HOST}
					echo "${ALL_TARGETS[@]}" | grep "${IN_TARGET}\b" &> /dev/null
					if [ $? -ne 0 ]; then
						echo "Enter valid TARGET"
						qlu_display_usage
					        exit 0
					fi	
						display_timeout	${IN_HOST} ${IN_TARGET}
						exit 0
                                else
					display_all ${IN_HOST} | more
                                fi
			;;
			
		esac
	     shift
	done
else
        display_all ALL | more
	#qlu_display_usage
fi
