#!/bin/sh

SEL=`pciconf  -l | awk '$3 ~ "1425$" {split($1, a, "@"); print a[2]}'`
if [ -z "$SEL" ]; then
	echo "No Chelsio card found."
	exit
fi

pci_show_cfg()
{
	pciconf -lbc | sed -E -e :a -e "/@$1	/"'!d' -e :b \
		-e 'n;s/(^[a-z])/\1/;ta' -e bb
}

pci_cfg_read()
{
	ADDR=$2
	[ -n "$3" ] && ADDR="$ADDR:$3"

	pciconf -r -b $1 $ADDR | sed 's/ $//'
}

pci_cfg_writeb()
{
	pciconf -w -b $1 $2 $3
}

pci_clear_error()
{
	V=`pci_cfg_read $1 $2`
	pci_cfg_writeb $1 $2 0x$V
	V=`pci_cfg_read $1 $2`
	[ "$V" != "00" ] && echo "failed to clear error ($2 = 0x$V)"
}

pci_clear_errors()
{
	for i in 0x62 0x304 0x305 0x306 0x307 0x310 0x311 0x312 0x313; do
		pci_clear_error $1 $i
	done
}

pci_show_errors()
{
	V=`pci_cfg_read $1 0x62`
	[ "$V" = "00" ] && return

	echo
	echo "Error 0x$V"

	U=`pci_cfg_read $1 0x304:0x307`
	C=`pci_cfg_read $1 0x310:0x313`
	T=`pci_cfg_read $1 0x314:0x32f`
	D=`pci_cfg_read $1 0x60:0x63`

	echo "Correctable errors: $C"
	echo "Uncorrectable errors: $U"
	echo "devctl: $D"
	echo "Last transaction follows"
	echo "$T"
}

if [ -n "$1" ]; then
	# clear errors
	for sel in $SEL; do
		pci_clear_errors $sel
		pci_show_cfg $sel
		pci_show_errors $sel
	done
	exit
fi

for sel in $SEL; do
	echo
	echo "********** $sel **********"
	pci_show_cfg $sel
	pci_show_errors $sel
done