#!/bin/bash
# Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#  Redistributions of source code must retain the above copyright
#  notice, this list of conditions and the following disclaimer.
#  Redistributions in binary form must reproduce the above copyright
#  notice, this list of conditions and the following disclaimer in
#  the documentation and/or other materials provided with the
#  distribution.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
#  Script to check that environment is set up correctly for usnic_verbs
# programs to be able to run successfully.

error()
{
	echo $* 1>&2
	exit 1
}

status()
{
	local cq_seen
	local vf_seen
	local vf_numcq
	local vf_numqp
	local vf_qpns
	local vf_list
	us=$1
	num_vf=0
	num_qp=0
	num_cq=0

	for qp in $(/bin/ls -d ${us}/qpn/* 2> /dev/null); do
		set - $(cat ${qp}/summary)
		vfid=${9}
		if [[ -z ${vf_seen[vfid]} ]]; then
			vf_seen[vfid]=1
			vf_list="${vf_list} ${vfid}"
			vf_pid[vfid]=$6
			let num_vf+=1
		fi 

		vf_qpns[vfid]="${vf_qpns[vfid]} ${2}"

		let vf_numqp[vfid]+=1
		let num_qp+=1

		cqn=${15#CQ[}
		cqn=${cqn%]}
		let cq_index=cqn*300+vfid
		if [[ -z "${cq_seen[cq_index]}" ]]; then
			cq_seen[cq_index]=1
			let num_cq+=1
			let vf_numcq[vfid]+=1
		fi
	done

	# produce the output
	cat ${us}/config
	echo
	echo "In use:"
	echo "${num_vf} VFs, ${num_qp} QPs, ${num_cq} CQs"
	
	if (( num_vf == 0 )); then
		return
	fi

	echo
	printf " VF   PID   QPs  CQs  QPNs\n"
	for vfid in ${vf_list}; do
		printf "%3d %6d %3d  %3d   " ${vfid} ${vf_pid[vfid]} \
			${vf_numqp[vfid]} ${vf_numcq[vfid]}
		set - ${vf_qpns[vfid]}
		while [[ -n "$*" ]]; do
			qpn=$1
			shift
			printf "%d" ${qpn}
			if [[ -n "$*" ]]; then
				printf ","
			else
				echo
			fi
		done
	done
}

main()
{
	CLASS_DIR=${CLASS_DIR:-/sys/class}

	if [[ -n $1 ]]; then
		us=${CLASS_DIR}/infiniband/usnic_$1
		[[ -r ${us} ]] || error "usnic_$1 not found"
		status ${us}
	else
		skip=""
		for us in $(/bin/ls -d ${CLASS_DIR}/infiniband/usnic_* \
				2> /dev/null); do
			printf "${skip}"
			status ${us}
			skip="\n\n"
		done
	fi
}
	
main $*
