#!/bin/sh
#
# picdrv:   This shell script takes care of the ICEPIC driver. 
#
#  Usage: icepic {make|install|remove|start|stop|restart|status}"
#
#    For Symmetric MultiProcessor support, set smp=1 else smp=0
#    For Kernal Module Versioning, set kmv=1 else kmv=0
#    For Capabilities API, set cap=1 else cap=0
#    For new remap_page_range args, set vma=1 else vma=0
#    For new DMA support (2.4.20 and up), set dma=1 else dma=0
#
#    To use chkconfig init management, chk=1 else chk=0 [default]
#
#    added comment lines parsed by chkconfig for init management under
#    IRIX, late Solaris, and RedHat-based Linux
#
#    for 2.4 kernels Cardbus is handled as hotplug PCI, no cb= needed
#
# chkconfig: 35 98 02
# description: make, installation, and init script for the ICEPIC driver
#
#    For autodetect of smp, kmv, dma or cap, set to -1
#
module="picdrv"
device="icepic"
group="sys"
mode="666"
ostype="UNIX"
osname="LINX"
osrep="EEEI"
#
smp=-1
kmv=-1
cap=-1
dma=-1
chk=0
vma=1
#
# RAM For the OS in Mbytes
ram_start=1000
# RAMDISK RAM in Mbytes
ram_sized=1024
# Mappable RAM in Mbytes (at least 4 for PIC self tests)
ram_sizem=20
# These three numbers (in Mby) should total up to your system memory
#
# On systems with physical memory holes the above statment is not true.
# During boot, the Linux kernel takes what you specify in the boot
# options "mem=" statement as a hard limit on the highest physical
# address it will use.  On IA32 systems that corresponds to the
# amount of memory to which you're limiting your system, but on IA64
# systems, for example, it does not.  The IA64 systems have large
# "holes" in the physical memory map.
#
# To compensate for this and determine the correct parameter to pass
# with the "mem=" boot option and to use for "ram_start" above
# (they should be the same number, by the way, unless you have other
# drivers using memory above the reach of Linux), you'll need to know
# the memory map on your machine.
#
# For IA64 machines you can use the EFI command "memmap" to examine
# the physical memory map of the machine.  The safest thing you can do
# with the memory map is pick memory in the uppermost block that contains
# contiguous "available" memory.  For example, an HP RX2600 with 2Gb of
# memory has two contiguous areas of physical memory:
# 0x00000000.00000000 - 0x00000000.3FFFFFFF
# 0x00000040.40000000 - 0x00000040.7FFFFFFF
#
# Pick how much memory you want out of the uppermost region, and set
# your parameters to match.  In the example above, say you want 256Mb
# for the ICE: 128Mb in ram_sized and 128Mb in ram_sizem.  Subtract
# 256Mb from the upper limit on physical memory: 0x40.80000000.
# 0x40.80000000 - 256Mb (0x10000000) = 0x40.70000000.
# You'll use 0x40.70000000 (in megabytes) both as the "mem=" boot
# option and as ram_start.  0x40.70000000 = 0x40700 x 0x100000
# = 0x40700 Mb = 263936Mb.
# For this example, your boot option is "mem=263936M" and your
# ICE parameters are:
ram_start=263936
ram_sized=128
ram_sizem=128
#
# Actually, that doesn't work.  Since the physical addresses are so
# high and the IA64 platforms don't necessarily have tlbs for the PCI
# bus and the ICE doesn't do DAC cycles, we have to keep the memory
# below the 32 bit mark.  Do this by pre-allocating huge pages, and use
# ram_sizem to take a single huge page (currently 256Mb).
ram_start=0
ram_sized=0
ram_sizem=256
#
# Linux will skip over the hole in physical address space and pick up
# the bottom 3/4 of the gigabyte of memory starting at 0x40.40000000,
# and the ICE driver will have the upper 1/4 of that gigabyte.

if [ -d /etc/init.d ]; then 
 initd=init.d
else
 initd=rc.d/init.d
fi

if [ $smp = -1 ]; then
 if echo `uname -a` | grep -q SMP ; then
  smp=1
 else
  smp=0
 fi
fi 

if [ $kmv = -1 ]; then
 if /sbin/ksyms -a | grep pci_devices | grep -q _R ; then
  kmv=1
 else
  kmv=0
 fi
fi 

if [ $cap = -1 ]; then
 cap=0
fi 

if [ $vma = -1 ]; then
 vma=0
fi 

if [ $dma = -1 ]; then
  if [ `uname -m` = "ia64" ]; then
    dma=1
  else
    dma=0
  fi
fi

case "$1" in
  make)
	echo "Making ICE driver for SymMultiProc=$smp ModVer=$kmv NewVma=$vma NewDMA=$dma"
	rm -f *.o *~ core
	incdir="/lib/modules/`uname -r`/build/include"
	if [ ! -d $incdir ]; then
	  incdir="/usr/src/linux/include"
	fi
	INCLUDES="-I$incdir -I/usr/include -I../../inc"
	FLAGS="-D__KERNEL__ -DMODULE -DEXPORT_SYMTAB"
	if [ $kmv != 0 ]; then
  	  INCLUDES="$INCLUDES -include $incdir/linux/modversions.h"
  	  FLAGS="$FLAGS -DMODVERSIONS"
	fi
	if [ $smp != 0 ]; then
  	  FLAGS="$FLAGS -D__SMP__"
	fi
	if [ $vma == 0 ]; then
  	  FLAGS="$FLAGS -DOLDVMA"
	fi
        RAMFLAGS=""
	if [ $dma == 1 ]; then
  	  FLAGS="$FLAGS -D_USENEWDMA"
          RAMFLAGS="-D_USENEWDMA"
	fi
	gcc -c picdrv.c $FLAGS -O -Wall $INCLUDES \
	  -DRAM_START=$ram_start -DRAM_SIZED=$ram_sized -DRAM_SIZEM=$ram_sizem \
	  -D_$ostype -D_$osname -D_$osrep 
        if [ `uname -m` != "ia64" ]; then
	  cc -o setram -D_$ostype -D_$osname -D_$osrep $RAMFLAGS -I../../inc ../../lib/setram.c 
        fi
	if [ $cap != 0 ]; then
	  cc -o setraw ../../lib/setraw.c -lcap
	  chown root setraw
	  chmod u+s setraw
	fi
        echo "If you see remap_page_range errors, change vma=x at the top of this script"
	;;
  install)
	VER=`cat /proc/version | awk '{ print $3 }' `
	echo "Installing ICE driver for kernel build $VER"
	install -d /lib/modules/$VER/misc 
	install -c picdrv.o /lib/modules/$VER/misc
	install -c icepic /etc/$initd/icepic
        if [ `uname -m` != "ia64" ]; then
	  install -c setram /etc/$initd/setram
        fi
	if [ $chk = 1 ]; then
	  echo "Using chkconfig init utility"
	  /sbin/chkconfig --add icepic
	else
	  ln -f -s /etc/$initd/icepic /etc/rc.d/rc5.d/S98icepic
	  ln -f -s /etc/$initd/icepic /etc/rc.d/rc3.d/S98icepic
	  ln -f -s /etc/$initd/icepic /etc/rc.d/rc0.d/K98icepic
	fi
	rm -f /dev/pmem
	ln -s /dev/icepic0 /dev/pmem
	;;
  remove)
	if [ $chk = 1 ]; then
	 echo "Using chkconfig init utility"
	 /sbin/chkconfig --del icepic
	else
	 rm -f /etc/$initd/setram
	 rm -f /etc/$initd/icepic
	 rm -f /etc/rc.d/rc0.d/K98icepic
	 rm -f /etc/rc.d/rc3.d/S98icepic
	 rm -f /etc/rc.d/rc5.d/S98icepic
	 rm -f /etc/pcmcia/icepic
	fi
	rm -f /dev/pmem
	;;
  start)
	# remove stale nodes
	rm -f /dev/${device}[0-9]
	rm -f /dev/${device}1[0-1]
	# load driver module
	/sbin/insmod $module
	devnos="0 1 2 3 4 5 6 7 8 9 10 11"

	# extract dynamic major number
	major=`cat /proc/devices | awk "\\$2==\"$device\" {print \\$1}"`

	# create new nodes 
	if [ "$major" = "" ]; then
	  echo "No icepic driver found"
	else
	  for i in $devnos
	  do
	    mknod /dev/${device}${i} c $major $i
	  done
	  chgrp $group /dev/${device}?
	  chmod $mode /dev/${device}?
	fi
	# set RAM allocation
        if [ `uname -m` != "ia64" ]; then
	  /etc/$initd/setram $ram_start $ram_sized $ram_sizem
        fi
	;;
  stop)
	# unload driver module
	/sbin/rmmod $module

	# remove stale nodes
	rm -f /dev/${device}[0-9]
	rm -f /dev/${device}1[0-1]
	;;
  check)
	;;
  restart)
	$0 stop
	$0 start
	;;
  status)
        ;;
  *)
	echo "Usage: icepic {make|install|remove|start|stop|restart|status}"
	exit 1
esac

exit 0
