#!/usr/bin/ksh

######################################################################
# This script will automagically find the offset of the offset in the
# DISK_SPECIFIC struct of "ds_read_count", which apparently has
# changed in Digital UNIX V4.0D, and may change again.  In "storage.c",
# look for the definition of RC_OFF, and set it too the result of this
# script.  Set the following three offsets to the same relative offsets
# from RC_OFF (4, 8, and 12).
#
# this script must be run as root.  It is, however, harmless.  It
# uses DBX exclusively to look at kernel values.
######################################################################

TMPFILE="/tmp/findoff.$$"

function DBXCommand
{
	typeset INPUT=$1
	typeset LINE=$2
	#print -u2 - "INPUT=[$INPUT]"
	dbx -k /vmunix <<_EOF_ > $TMPFILE 2> /dev/null
$INPUT
_EOF_
	if [[ $LINE = "" ]]; then
		typeset OUT=$(tail -1 $TMPFILE)
	else
		typeset OUT=$(grep $LINE $TMPFILE)
	fi
	print - "$OUT"
}

PTRADR=$(DBXCommand "px &camdb_didarr_ptr")
print "&DIDARR_PTR=	$PTRADR"

PTR="0x$(DBXCommand "${PTRADR}/X" | awk '{print $2}')"
print "DIDARR_PTR=	$PTR"

FIRSTDID="0x$(DBXCommand "${PTR}/X" | awk '{print $2}')"
print - "FIRSTDID=	$FIRSTDID"

CAM_PTR=$(DBXCommand "p *(SCSI_DID *)$FIRSTDID" "cam_ptr")
CAM_PTR=$(print - "$CAM_PTR" | sed -e 's/^.*cam_ptr = //' -e 's/ = .*$//')
print - "CAM_PTR=	$CAM_PTR"

PDRV=$(DBXCommand "p *(PDRV_DEVICE3 *)$CAM_PTR" "pd_spec_flink")
PDRV=$(print - "$PDRV"|sed -e 's/.*pd_spec_flink = //')
print - "PDRV=		$PDRV"


DS=$(DBXCommand "p *(PD_SPEC_INFO *)$PDRV" "spec_ptr")
DS=$(print - "$DS"|sed -e 's/.*spec_ptr = //')
print - "DISK_SPECIFIC=	$DS"

RC_ADR=$(DBXCommand "p &(*(DISK_SPECIFIC *)$DS).ds_read_count")
print - "ds_read_count=	$RC_ADR"

DS_BIG=$(print - "$DS"|tr a-f A-F|sed 's/^0x//')
RC_BIG=$(print - "$RC_ADR"|tr a-f A-F|sed 's/^0x//')

dc <<_EOF_ > $TMPFILE
16 i
$RC_BIG $DS_BIG - p
_EOF_

OFF=$(cat $TMPFILE)
rm $TMPFILE

print - "\nOFFSET of ds_read_count = $OFF (this is the only real interesting value)"
