#!/bin/bash

totalpages=`sysctl dev.pcd.reserved_pages | cut -f3 -d' '`

if [ "$totalpages" == "" ] ; then
echo "dev.pcd.reserved_pages not found in sysctl - is EDT driver loaded?"
exit
fi

dmapages=`expr \( $totalpages \* 512 \) / 513`
sg=`expr $totalpages - $dmapages`

totalmem=`expr $totalpages \* 4096`
dmamem=`expr $dmapages \* 4096`
sgmem=`expr $sg \* 4096`

 
echo "============================="
echo "EDT driver reserved DMA Memory"
echo "============================="
echo
echo "Current setting (assuming 2MB dma buffers)" 
echo
printf "Total mem            = 0x%-8x (%d) bytes\n" $totalmem $totalmem
printf "Total pages          = $totalpages\n"
printf "DMA mem              = 0x%-8x (%d) bytes\n" $dmamem $dmamem
printf "Dma pages            = $dmapages\n"
printf "Scatter-gather mem   = 0x%-8x (%d) bytes\n" $sgmem $sgmem
printf "Scatter-gather pages = $sg\n"
echo
echo

if [ "$1" != "" ] ; then

if [ "$1" == "-h" ] ; then

echo "============================="
echo "$0 :"
echo "============================="
echo "Use a sysctl value to reserve memory for DMA to/from EDT cards"
echo "in the first 4 GB to avoid interference with file caching."
echo 
echo "The value stored for the key dev.pcd.reserved_pages in /etc/sysctl.conf"
echo "represents the total number of 4k pages reserved."
echo "For every 2 MB of DMA memory at least one 4k page of scatter-gather"
echo "memory is required. This will be added to the value requested for DMA memory."
echo "The maximum value allowed by this script is 2 GB of memory, or "
echo "512K pages, to leave sufficient room for other drivers."
echo
echo "Usage: $0 [reserved_size]"
echo
echo "With no arguments $0 will print the current setting."
echo
echo "If reserved_size is less than< 4000 assume it's megabytes reserved"
echo "If reserved_size is less than 1000000 assume it's pages reserved"
echo "Otherwise assume it's bytes reserved"
echo
exit
fi

bytes=$1
echo -n "Argument is "

if [ $bytes -lt 2049 ] ; then
# assume n is megabytes
echo "(MB) = $bytes MB"

bytes=`expr $bytes \* 1024 \* 1024`
elif [ $bytes -lt 1000000 ] ; then
#assume n is pages
echo "(pages) =  $bytes pages"
bytes=`expr $bytes \* 4096`
else
echo "(bytes) =  $bytes bytes"

fi
echo

dmapages=`expr $bytes / 4096`

sg=`expr $dmapages / 512`

bytes=`expr $bytes + \( $sg \* 4096 \)`


totalpages=`expr $dmapages + $sg`

if [ $dmapages -gt 524288 ] ; then
echo
echo "Too much memory requested, max is 2 GB \(524288 pages\)."
echo
exit
fi

totalmem=`expr $totalpages \* 4096`
dmamem=`expr $dmapages \* 4096`
sgmem=`expr $sg \* 4096`
echo "============================="
echo "New setting" 
echo "============================="
echo
printf "Total mem            = 0x%-8x (%d) bytes\n" $totalmem $totalmem
printf "Total pages          = $totalpages\n"
printf "DMA mem              = 0x%-8x (%d) bytes\n" $dmamem $dmamem
printf "Dma pages            = $dmapages\n"
printf "Scatter-gather mem   = 0x%-8x (%d) bytes\n" $sgmem $sgmem
printf "Scatter-gather pages = $sg\n"
echo

totalpages=`expr $dmapages + $sg`

grep dev.pcd.reserved_pages /etc/sysctl.conf > /dev/null

rc=$?

sysctl -w dev.pcd.reserved_pages=$totalpages

cp /etc/sysctl.conf /etc/sysctl.conf.bak

if [ $rc -ne 0 ] ; then

echo "" >> /etc/sysctl.conf
echo "# Controls the number of pages reserved for the EDT driver in low 4 GB of mem" >> /etc/sysctl.conf
echo "dev.pcd.reserved_pages = $totalpages" >> /etc/sysctl.conf

else

grep -v dev.pcd.reserved_pages /etc/sysctl.conf > /tmp/defsysctl
mv /tmp/defsysctl /etc/sysctl.conf
echo "dev.pcd.reserved_pages = $totalpages" >> /etc/sysctl.conf

fi

fi

