#! /usr/bin/ksh
# $Header: sgscan.sh,v 1.13 2002/06/03 14:54:28 rgilson Stab $

#bcpyrght
#***************************************************************************
#* $VRTScprght: Copyright 1993 - 2002 VERITAS Software Corporation, All Rights Reserved $ *
#***************************************************************************
#ecpyrght

# The Media Manager command scsi_command is installed
#	- SG driver is installed
#	- ksh(1), echo(1), awk(1), nawk(1), cut(1), cat(1), and sed(1)
#	  are in /usr/bin
#	- /usr/bin is in your path
#	- /kernel/drv/st.conf is in its default format (one entry per line),
#	  and default strings such as "config", "name", and "target" don't 
#	  appear in any valid configuration entries
#
#  installed in /usr/openv/volmgr/bin
#

progname='sgscan'

Usage="Usage: $progname [all|basic|changer|disk|tape] [conf] [-v]"

MM_SCSI_COMMAND=/usr/openv/volmgr/bin/scsi_command
ST_CONF_FILE=/kernel/drv/st.conf
SG_CONF_FILE=/kernel/drv/sg.conf
TMP_FILE=/tmp/sgscan.tmp.$$

typeset -i verbose=0
typeset -i show_conf=0
mode=none

args=$*

while [ "$1" ]
do
	arg=$1
	case $arg in
	-v)		verbose=1;;
	all)		if [ "$mode" != "none" ]
			then
				echo "$Usage"
				exit 1
			fi
			capmode="All"
			mode=$arg;;
	basic)		if [ "$mode" != "none" ]
			then
				echo "$Usage"
				exit 1
			fi
			capmode="Basic"
			mode=$arg;;
	changer)	if [ "$mode" != "none" ]
			then
				echo "$Usage"
				exit 1
			fi
			capmode="Changer"
			mode=$arg;;
	disk)		if [ "$mode" != "none" ]
			then
				echo "$Usage"
				exit 1
			fi
			capmode="Disk"
			mode=$arg;;
	tape)		if [ "$mode" != "none" ]
			then
				echo "$Usage"
				exit 1
			fi
			capmode="Tape"
			mode=$arg;;
	conf)		show_conf=1;;
	-h|-help|help)	echo "$Usage"
			exit 1;;
	*)		echo "$progname:  invalid argument \"$arg\""
			echo "$Usage"
			exit 1;;
	esac

	shift 1
done

if [ "$mode" = "none" ]
then
	# set default mode
	mode=all
	capmode="All"
fi

# make sure luxadm is in path
/bin/which luxadm | grep 'no luxadm' > /dev/null 2>&1
if [[ $? -ne 0 ]]; then
  hbaports=`luxadm -e port 2>/dev/null | /bin/grep 'SUNW,qlc' |
    /bin/awk ' "CONNECTED" == $2  { print $1 }'`

  if [[ -n $hbaports ]]; then
    for hba in $hbaports; do
      # find all tape devices and medium changers
      portwwn=`luxadm -e dump_map $hba |
        /bin/awk '($6~/0x/ && $6!="0x1f"){print $4}($7~/0x/ && $7!="0x1f"){print $5}'`
      if [[ -n $portwwn ]]; then
        for port in $portwwn; do
          /bin/grep $port $SG_CONF_FILE > /dev/null 2>&1
          if [[ $? -ne 0 ]]; then
            if [ "$title_printed" -eq "0" ]
            then
              echo "#"
              echo "#WARNING: detected StorEdge Network Foundation connected devices not in"
              echo "#         SG configuration file:"
              echo "#"
              title_printed=1
            fi
            echo "#    Device World Wide Port Name $port"
          fi
        done
      fi
    done
  fi
fi
if [ "$title_printed" -eq "1" ]
then
  echo "#"
  echo "#    See /usr/openv/volmgr/MediaMgr_DeviceConfig_Guide.txt chapter"
  echo "#    \"Special configuration for \"Sun StorEdge Network Foundation\" HBA/Driver\""
  echo "#    for information on how to use sg.build and sg.install to"
  echo "#    configure these devices"
  echo "#"
  echo ""
fi

if [ ! -f $MM_SCSI_COMMAND ]
then
	echo "$progname:  cannot access $MM_SCSI_COMMAND"
	exit 1
fi

if [ "$mode" = "tape" -o "$mode" = "all" ]
then
	if [ "$show_conf" -eq "1" ]
	then
		known_tapes=`cat $ST_CONF_FILE | egrep -v "^#|config|name=|target=" | grep "\"" | nawk 'BEGIN { FS ="\"" } { print $2 ":" $6 }'`
		cat $ST_CONF_FILE | egrep -v "^#|config|name=|target=" | grep "\"" | nawk 'BEGIN { FS ="\"" } { print $2 ":" $6 }' > $TMP_FILE
		if [ "$verbose" -eq "1" ]
		then
			echo "Tape device types enabled in the Solaris tape driver, st(7D), configuration file:"
			echo "$known_tapes"
			echo ""
			echo "$capmode devices recognized by the SCSI Generic (sg) driver:"
		fi
	fi
fi

if [ "$mode" = "tape" -o "$mode" = "disk" -o "$mode" = "all" ]
then
	# generate list of tape devices, eg. /dev/rmt/0
	if [ "$mode" = "tape" -o "$mode" = "all" ]
	then
		#
		# generate logical tape list
		# need this format:
		# 	/dev/rmt/0
		#
		tapelist=`/bin/ls /dev/rmt/*mn 2>/dev/null | sort -n | sed 's/mn//'`

		###################################
		# Test hooks
		#for tape in $tapelist; do
		#      echo "tape = $tape"
		#done
		#echo "tapelist = $tapelist"
		###################################
	fi

	# generate list of disk devices, eg. /dev/rdsk/c0t1d0s
	if [ "$mode" = "disk" -o "$mode" = "all" ]
	then
		#
		# generate logical disk list
		# need this format:
		# 	/dev/rdsk/c0t1d0s0
		#
		disklist=`/bin/ls /dev/rdsk/*s0 | sort -n`

		###################################
		# Test hooks
		#for disk in $disklist; do
		#      echo "disk = $disk"
		#done
		#echo "disklist = $disklist"
		###################################
	fi
fi

disk_indicator="dev type 0h"
tape_indicator="dev type 1h"
cdrom_wr_indicator="dev type 4h"
cdrom_indicator="dev type 5h"
changer_indicator="dev type 8h"

######################
#ORIGINAL 3.0 CODE
#for i in /dev/sg/c*t*[dl]0*; do
# 	inquiryOUT=`$MM_SCSI_COMMAND -d $i -inquiry 2>&1`
#	if [ $? -ne 0 ]
#	then
#		echo "${i}: $inquiryOUT"
#	else
#		echo "${i}: `echo \"$inquiryOUT\" | cut -c15-`"
#	fi
#done
######################

typeset -i devcount=0
for i in /dev/sg/c*t*[dl]*; do
	devcount=$(($devcount+1))
 	inqOUT[$devcount]=`$MM_SCSI_COMMAND -d $i -inquiry 2>&1`
	if [ $? -ne 0 ]
	then
		if [ "$mode" = "basic" -o "$mode" = "all" ]
		then
			# print error message
			echo "${i}: ${inqOUT[$devcount]}"
		fi
		continue
	fi

	if [ "$mode" = "basic" ]
	then
		# strip off the leading string "Inquiry data: "
		echo "${i}: `echo \"${inqOUT[$devcount]}\" | cut -c15-`"
		continue
	fi

	if [ "`echo \"${inqOUT[$devcount]}\" | grep \"${disk_indicator}\" | wc -l`" -eq "1" ]
	then
		if [ "`echo \"${inqOUT[$devcount]}\" | awk 'BEGIN { FS=":" } { print $2 }'`" = " $disk_indicator" ]
		then
			devtype=None
		else
			devtype=Disk
		fi
	elif [ "`echo \"${inqOUT[$devcount]}\" | grep \"${tape_indicator}\" | wc -l`" -eq "1" ]
	then
		devtype=Tape
	elif [ "`echo \"${inqOUT[$devcount]}\" | grep \"${cdrom_wr_indicator}\" | wc -l`" -eq "1" ]
	then
		devtype=Cdrom-writer
	elif [ "`echo \"${inqOUT[$devcount]}\" | grep \"${cdrom_indicator}\" | wc -l`" -eq "1" ]
	then
		devtype=Cdrom
	elif [ "`echo \"${inqOUT[$devcount]}\" | grep \"${changer_indicator}\" | wc -l`" -eq "1" ]
	then
		devtype=Changer
	else
		devtype=Unknown
	fi

	#
	# Separate the vendor/model/microcode info from the rest of the output of scsi_command
	# BEFORE: Inquiry data: removable dev type 1h DEC     DLT2000         8414
	# AFTER: DEC     DLT2000         8414
	#
	inqProdInfo=`echo "${inqOUT[$devcount]}" | nawk 'BEGIN { FS = "dev type "} { print substr($2,4) }'`
	if [ "XXX$inqProdInfo" = "XXX" ]
	then
		# no device present
		continue
	fi

	if [ "$show_conf" -eq "1" ]
	then
		# save non-microcode version of inq data for later comparison
		inqProdModel=`echo "$inqProdInfo" | awk '{ print substr($NL,1,length($NL)-4) }' | nawk 'BEGIN { FS = "[ ]*$" } { print $1 }'`
	fi

	if [ "$verbose" -eq "0" ]
	then
		# strip off microcode (last 4 characters), then any trailing blanks
		inqProdInfo=`echo "$inqProdInfo" | awk '{ print substr($NL,1,length($NL)-4) }' | nawk 'BEGIN { FS = "[ ]*$" } { print $1 }'`
	fi

	if [ "$mode" = "disk" ]
	then
		if [ "$devtype" != "Disk" ]
		then
			continue
		fi
	elif [ "$mode" = "tape" ]
	then
		if [ "$devtype" != "Tape" ]
		then
			continue
		fi
	elif [ "$mode" = "changer" ]
	then
	        ##
                ## Add special case for the IBM     03590B11.  This device is both at tape drive AND a changer
	        ##
		InqString=`echo "$inqProdInfo" | awk '{ print substr($0,1,16) }'`
	        if [  "IBM     03590B11" = "$InqString" ]
 	        then
		        echo "${i}: \"$inqProdInfo\""
	        fi		

		if [ "$devtype" != "Changer" ]
		then
			continue
		fi
	fi

	if [ "$devtype" = "Changer" -o "$devtype" = "Cdrom" -o "$devtype" = "Cdrom-writer" ]
	then
		if [ "$mode" = "all" ]
		then
			echo "${i}: $devtype: \"$inqProdInfo\""
		else
			echo "${i}: \"$inqProdInfo\""
		fi
		continue
	fi

	hard_sg_path=`/usr/bin/ls -al ${i} | awk '{ print $11 }' | awk 'BEGIN { FS=":" } { print $1 }' | sed -e 's/sg@/XX/'`

	if [ "$devtype" = "Disk" ]
	then
		disk_path="???"
		for disk in $disklist; do
			hard_rdsk_path=`/usr/bin/ls -al $disk | awk '{ print $11 }' | awk 'BEGIN { FS=":" } { print $1 }' | sed -e 's/sd@/XX/' -e 's/:\*\$//'`
			# DEBUG echo "comparing $hard_sg_path TO $hard_rdsk_path"

			if [ "$hard_sg_path" = "$hard_rdsk_path" ]
			then
				# remove the trailing s0
				disk_path=`echo $disk | sed 's/s0//'`
			fi

		done

		# display disk info
		if [ "$mode" = "all" ]
		then
			echo "${i}: $devtype ($disk_path): \"$inqProdInfo\""
		else
			echo "${i}: ($disk_path): \"$inqProdInfo\""
		fi

	elif [ "$devtype" = "Tape" ]
	then
		tape_path="???"
		for tape in $tapelist; do
			hard_rmt_path=`/usr/bin/ls -al $tape | awk '{ print $11 }' | awk 'BEGIN { FS=":" } { print $1 }' | sed -e 's/st@/XX/' -e 's/:\*\$//'`
		# echo "comparing $hard_sg_path TO $hard_rmt_path"

			if [ "$hard_sg_path" = "$hard_rmt_path" ]
			then
				tape_path=$tape
			fi

		done

		if [ "$show_conf" -eq "1" ]
		then
			conf_type="`cat $TMP_FILE | nawk -v ProdModel="$inqProdModel" 'BEGIN { FS = ":"; found = 0 } { len=length($1); confProdModel=substr(ProdModel,1,len); if (match(confProdModel,$1)) { print $2 ; found = 1 ; break } } END { if (!found) print "NOT-IN-ST-CONFIG-FILE"}'`"

			conf_type_str=": $conf_type"
		else
			conf_type_str=""
		fi

		# display tape info
		if [ "$mode" = "all" ]
		then
	                ##
                	## Add special case for the IBM     03590B11.  This device is both at tape drive AND a changer
	                ##
		        InqString=`echo "$inqProdInfo" | awk '{ print substr($0,1,16) }'`
	                if [  "IBM     03590B11" = "$InqString" ]
 	                then
			      echo "${i}: Changer: \"$inqProdInfo\" $conf_type_str"
	                fi			
			echo "${i}: $devtype ($tape_path): \"$inqProdInfo\" $conf_type_str"
		else
			echo "${i}: ($tape_path): \"$inqProdInfo\" $conf_type_str"
		fi

	fi
done

if [ "$mode" = "tape" -o "$mode" = "all" ]
then
	if [ "$show_conf" -eq "1" ]
	then
		rm -f $TMP_FILE
	fi
fi

exit 0
