#!/bin/sh
###############################################################################
# Part of Marvell Yukon/SysKonnect sk98lin Driver for Linux                   #
###############################################################################
# Installation script for Marvell Chip based Ethernet Gigabit Cards           #
# $Revision: 1.36 $                                                            #
# $Date: 2004/08/17 15:29:07 $                                                #
# =========================================================================== #
#                                                                             #
#  Main - Global function                                                     #
#                                                                             #
# Description:                                                                #
#  This file includes all functions and parts of the script                   #
#                                                                             #
# Returns:                                                                    #
#       N/A                                                                   #
# =========================================================================== #
# Usage:                                                                      #
#     ./install.sh                                                            #
#                                                                             #
# =========================================================================== #
# COPYRIGHT NOTICE :                                                          #
#                                                                             #
# (C)Copyright 2003-2004 Marvell(R).                                          #
#                                                                             #
#  This program is free software; you can redistribute it                     # 
#  and/or modify it under the terms of the GNU General Public                 #
#  License as published by the Free Software Foundation; either               #
#  version 2 of the License, or (at your option) any later version.           #
#                                                                             #
#                                                                             #
# WARRANTY DISCLAIMER:                                                        #
#                                                                             #
# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT #
# ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR       #
# FITNESS FOR A PARTICULAR PURPOSE.                                           #
#                                                                             #
# =========================================================================== #
#                                                                             #
#     History:                                                                #
#     2004-07-23 - Insert likely() if not available               (mlindner)  #
#                  Display driver version in the log files                    #
#                  Parameter check changed                                    #
#                  Use /proc/config.gz if available                           #
#     2004-07-01 - Better version.h check                         (mlindner)  #
#     2004-04-26 - New parameter configuration                    (mlindner)  #
#     2004-04-26 - Support for Intel x86_64 arch                  (mlindner)  #
#     2004-02-15 - Support for yukon2 chipsets                    (mlindner)  #
#                  Support for kernel 2.6                                     #
#                  Support for parallel make on SMP-Hosts                     #
#                  Make a patch against the current kernel                    #
#                  Added help option.                                         #
#                  More command line parameters for auto installation         #
#                  Better SMP detection                                       #
#                  Highmem detection                                          #
#                                                                             #
#                                                                             #
###############################################################################


# Functions
###########################################

function message_status ()
{
	# Print a status message 
	# Syntax: message_status STATUS STRING
	# 	STATUS
	#		0) FAILED
	#		1) OK
	#		2) WARN
	# Author: mlindner
	# Returns:
	#       N/A

	if test -z "$LINES" -o -z "$COLUMNS" ; then
		eval `stty size 2>/dev/null | (read L C; \
		echo LINES=${L:-24} COLUMNS=${C:-80})`
	fi
	test $COLUMNS -eq 0 && COLUMNS=80
	esc=`echo -en "\033"`
	error="${esc}[1;31m"
	ok="${esc}[1;32m"
	warn="${esc}[1;33m"
	working="${esc}[1;34m"
	stat=`echo -en "\015${esc}[${COLUMNS}C${esc}[10D"`
	norm=`echo -en "${esc}[m\017"`

	m_ok="${stat}[${ok}   OK   ${norm}]"
	m_failed="${stat}[${error} failed ${norm}]"
	m_warning="${stat}[${warn}  warn  ${norm}]"
	m_working="${stat}${working}  working${norm}"
	if [ "$2" != "working" ]; then
		echo -n " ($2)"
	fi

	case "$1" in
	3)	echo -n "$m_working" ;;
	2)	echo "$m_warning" ;;
	1)	echo "$m_ok" ;;
	0)	echo "$m_failed" ;;
	esac

	return 0;
}

function make_safe_tmp_dir ()
{
	# Generate safe tmp dir
	# Syntax: make_safe_tmp_dir
	# Author: mlindner
	# Returns:
	#       TMP_DIRECTORY

	fname="Create tmp dir"
	echo -n $fname
	message_status 3 "working"
	BASE_TMP_DIR="/tmp"
	if ! [ -e "$BASE_TMP_DIR" ]; then
		BASE_TMP_DIR=`pwd`
		mkdir ${BASE_TMP_DIR}/tmp
		BASE_TMP_DIR=`echo ${BASE_TMP_DIR}/tmp`
	fi	

	TMP_DIR=${BASE_TMP_DIR}/Sk98I`awk 'BEGIN { srand(); for (i=1;i<21;i++) { a=95; while (a > 90 && a < 97) { a=65+int(50*rand())}; printf("%c", a) } }'`

	[ -e "$TMP_DIR" ] && rm -rf $TMP_DIR
	if [ -e "$TMP_DIR" ]; then 
		echo
		echo "My temp dir exists already."
		echo "This looks like a symlink attack!"
		echo 
		echo "*** Aborting"
		echo
		exit 1
	fi

	if [ "$TMP_DIR" = "$BASE_TMP_DIR" -o "$TMP_DIR" = "/" ]; then
		echo 
		echo "\"$TMP_DIR\" is an unacceptable value for the temp dir. Please"
		echo "edit the variable definition for $TMP_DIR and try again."
		echo
		echo "*** Aborting"
		echo
		exit 1
	fi

	mkdir $TMP_DIR
	chmod 700 $TMP_DIR &> /dev/null

	echo -en "\015"
	echo -n $fname
	message_status 1 "$TMP_DIR"
}

function unpack_driver ()
{
	# Create tmp dir and unpack the driver
	# Syntax: unpack_driver 
	# Author: mlindner
	# Returns:
	#       N/A


	# Create tmp dir and unpack the driver
	fname="Unpack the sources"
	echo -n $fname
	message_status 3 "working"

	# Archive file not found
	if [ ! -f $drv_name.tar.bz2 ]; then
		echo -en "\015"
		echo -n $fname
		message_status 0 "error"
	 	echo
		echo "Driver package $drv_name.tar.bz2 not found. "; \
		echo "Please download the package again."; \
		echo "+++ Unpack error!!!" >> $logfile 2>&1
		echo $inst_failed
		clean
		exit 1
	
	fi

	echo "+++ Unpack the sources" >> $logfile
	echo "+++ ====================================" >> $logfile
	cd $working_dir
	cp $drv_name.tar.bz2 ${TMP_DIR}/

	cd ${TMP_DIR}
	bunzip2 $drv_name.tar.bz2 &> /dev/null
	echo "+++ tar xfv $drv_name.tar" >> $logfile
	tar xfv $drv_name.tar >> $logfile
	cd ..

	if [ -f ${TMP_DIR}/2.4/skge.c ]; then
		echo -en "\015"
		echo -n $fname
		message_status 1 "done"
	else
		echo -en "\015"
		echo -n $fname
		message_status 0 "error"
	 	echo
		echo "An error has occurred during the unpack proces which prevented "; \
		echo "the installation from completing.                              "; \
		echo "Take a look at the log file install.log for more informations.  "; \
		echo "+++ Unpack error!!!" >> $logfile 2>&1
		echo $inst_failed
		clean
		exit 1
	fi

	# Generate all build dir...
	mkdir ${TMP_DIR}/all
	cp -pr ${TMP_DIR}/common/* ${TMP_DIR}/all
	cp -pr ${TMP_DIR}/${KERNEL_FAMILY}/* ${TMP_DIR}/all
}

function extract_params ()
{
	# Extract all given parameters
	# Syntax:  extract_params
	# Author: mlindner
	# Returns:
	#       N/A

	if [ $# -eq "0" ];then
		# Script invoked with no command-line args?
		return
	fi

	while getopts ":schp" Option
		do
  		case $Option in
			s     ) OPTION_SILENT=1;;
			c     ) OPTION_CLEANUP=1;;
			h     ) OPTION_HELP=1;;
			p     ) OPTION_PATCH=1;;
			*     ) echo "Option $OPTARG ignored";;   # DEFAULT
		esac
	done

	if [ "${OPTION_PATCH}" ]; then
		if [ ! $2 ] || [ ! $3 ]; then
			echo "install: option requires an argument -- p"
			echo "Try "install.sh -h" for more information."
			echo
			exit
		fi
	fi

}


function help ()
{
	echo "Usage: install.sh [OPTIONS]"
	echo "   Install the sk98lin driver or generate a patch"
  	echo "   Example: install.sh"
	echo
	echo "Optional parameters:"
	echo "   -s              install the driver wothout any user interaction"
	echo "   -c              cleanup all sk98lin temp directories"
	echo "   -p [KERNEL_DIR] [PATCH_FILE]         generate a patch"
	echo "   -h              display this help and exit"
	echo "   -v              output version information and exit"
	echo
	echo "Report bugs to <linux@syskonnect.de>."
	exit
}

#################################################################
# Check functions
#################################################################
function check_user_and_tools ()
{
	# Check user informations and the existence of defferent tools
	# Syntax:  check_user_and_tools
	# Author: mlindner
	# Returns:
	#       N/A

	# Check user id
	inst_failed="Installation of $drv_name driver module failed."
	fname="Check user id"
	echo -n $fname
	if [ `id -u` != 0 ] && [ "$INSTALL_MODE" != "PATCH" ]; then
		message_status 0 `id -u`
		echo "+++ Wrong user"  >> $logfile 2>&1
		echo "You must have root privileges to install the $drv_name driver module."
		inst_failed
		clean
		exit 1
	else
		message_status 1 `id -u`
	fi


	# Check kernel version
	export KERNEL_VERSION=`uname -r`
	echo -n "Check kernel version"
	echo "+++ Kernel version ${KERNEL_VERSION}" >> $logfile 2>&1
	
	split_kernel_ver=`echo ${KERNEL_VERSION} | cut -d '.' -f 1`	
	if [ $split_kernel_ver != 2 ]; then
		message_status 0 ${KERNEL_VERSION}
		kernel_check_failed
	fi

	KERNEL_FAMILY="$split_kernel_ver"
	split_kernel_ver=`echo ${KERNEL_VERSION} | cut -d '.' -f 2`	
	if [ $split_kernel_ver != 4 ] && [ $split_kernel_ver != 6 ]; then
		message_status 0 ${KERNEL_VERSION}
		kernel_check_failed
	fi
	KERNEL_FAMILY="$KERNEL_FAMILY.$split_kernel_ver"

	split_kernel_ver=`echo ${KERNEL_VERSION} | cut -d '.' -f 3`
	split_kernel_ver2=`echo $split_kernel_ver | cut -d '-' -f 1`
	KERNEL_MINOR_VERSION=`echo $split_kernel_ver2`
	KERNEL_MAJOR_VERSION=`echo ${KERNEL_VERSION} | cut -d '.' -f 2`
	if [ "$split_kernel_ver2" -lt  13 ] && [ $KERNEL_MAJOR_VERSION == 4 ]; then
		message_status 0 ${KERNEL_VERSION}
		kernel_check_failed
	fi
	message_status 1 ${KERNEL_VERSION}

	echo -n "Check kernel symbol file"
	if [ -f "/proc/ksyms" ]; then
		SYMSFILE="/proc/ksyms"
	fi
	if [ -f "/proc/kallsyms" ]; then
		SYMSFILE="/proc/kallsyms"
	fi

	if [ ! $SYMSFILE ]; then
		if [ -f "/boot/System.map-${KERNEL_VERSION}" ]; then
			SYMSFILE="/boot/System.map-${KERNEL_VERSION}"
		fi
	fi
	message_status 1 $SYMSFILE



	# Check machine type
	fname="Check kernel type"
	echo -n $fname
	message_status 3 "working"
	kernel_machine=`uname -m`
	SYSTEM_NUMBER_OF_CPUS=1;
	MAKE_CPU_FLAG=""
	local no_smp_cpus=0

	# New smp detection (preliminary!)
	smp_count=`cat /proc/cpuinfo | grep processor -c`

	if [ $smp_count -lt 2 ]; then
	# check for smp (step2)
		smp_count=`cat $SYMSFILE | grep smp_call_function$ -c`
		((smp_count=$smp_count + 1))
		no_smp_cpus=1
	fi

	if [ $smp_count -lt 2 ]; then
	# check for smp (step3)
		smp_count=`cat $SYMSFILE | grep smp_call_function_R -c`
		((smp_count=$smp_count + 1))
		no_smp_cpus=1
	fi

	if [ $smp_count -lt 2 ]; then
	# check for smp (step4)
		smp_count=`cat $SYMSFILE | grep smp_prepare_cpus$ -c`
		((smp_count=$smp_count + 1))
		no_smp_cpus=1
	fi
	
	if [ $smp_count -gt 1 ]; then
		echo -en "\015"
		echo -n $fname
		message_status 1 "SMP"

		echo -n "Check number of CPUs"
		if [ $no_smp_cpus == 1 ]; then
			SYSTEM_NUMBER_OF_CPUS=1
			smp_count=1
		else
			SYSTEM_NUMBER_OF_CPUS=$smp_count
			MAKE_CPU_FLAG="-j$SYSTEM_NUMBER_OF_CPUS"
			smp_count=1
		fi
		message_status 1 $SYSTEM_NUMBER_OF_CPUS
	else
		smp_count=0
		echo -en "\015"
		echo -n $fname
		message_status 1 "SP"
	fi

	echo "+++ smp_count=$smp_count" >> $logfile 2>&1
	echo "+++ cpu_number=$SYSTEM_NUMBER_OF_CPUS" >> $logfile 2>&1
	echo "+++ kernel_machine=$kernel_machine" >> $logfile 2>&1

	# Check architecture
	echo -n "Check architecture"

	# Use the arch command at the first
	arch_out=`arch`

	if [ "$arch_out" != "ia64" ] && [ "$arch_out" != "x86_64" ]; then
		# Probably the x86 archtecture...
		# We have to check some infos for prototype CPU detection

		architecture=`cat /proc/cpuinfo | grep "model name" | cut -d ':' -f 2`

		if [ "$architecture" == "" ]; then
		# Architecture not found... 2nd chance
			architecture=`cat /proc/cpuinfo | grep "family" | cut -d ':' -f 2`
			if [ "$architecture" == "" ] && ["$arch_out" == "" ]; then
			# Architecture still not found... :(
				echo "+++ Architecture not found" >> $logfile 2>&1	
				if [ -z ${SK_ARCH} ]; then
				message_status 0 "not found"
				echo "Architecture not detected."
				echo "Please set the architecture manually."
				echo "If you know what you are doing and want to set the"
				echo "architecture, you can do so by setting SK_ARCH system  "
				echo "variable:"
				echo "" 
				echo "  For i386 architecture"
				echo "    Example: export SK_ARCH=\"i386\""
				echo "  For ia64 or ia64-2 architecture"
				echo "    Example: export SK_ARCH=\"ia64\""
				echo "  For Athlon64, Hammer or Opteron architecture"
				echo "    Example: export SK_ARCH=\"x86_64\""
				echo $inst_failed
				clean
				exit 1
				else
				echo "+++ Architecture setted manually: ${SK_ARCH}" >> $logfile 2>&1	
				message_status 1 "m:${SK_ARCH}"
				fi
			else
				message_status 1 "found"
			fi
		else
			message_status 1 "found"
		fi
	else
		architecture=`echo $arch_out`
		message_status 1 "found"
	fi

	# Create the final arch type
	if [ "$architecture" != "ia64" ] && [ "$archtecture" != "x86_64" ]; then
		architecture=`echo $arch_out`
	fi

	echo -n "Set architecture"
	# AMD64, Opteron, Hammer...
	if [ `echo $architecture | grep -i "Opteron" -c` -gt 0 ]; then ARCH=x86_64; fi
	if [ `echo $architecture | grep -i "Athlon HX" -c` -gt 0 ]; then ARCH=x86_64; fi
	if [ `echo $architecture | grep -i "Hammer" -c` -gt 0 ]; then ARCH=x86_64; fi
	if [ `echo $architecture | grep -i "K8" -c` -gt 0 ]; then ARCH=x86_64; fi
	if [ `echo $architecture | grep -i " 15" -c` -gt 0 ]; then ARCH=x86_64; fi
	if [ `echo $architecture | grep -i "AMD Athlon(tm) 64" -c` -gt 0 ]; then ARCH=x86_64; fi
	if [ `echo $architecture | grep -i "x86_64" -c` -gt 0 ]; then ARCH=x86_64; fi

	# IA-64, IA-64 2...
	if [ `echo $architecture | grep -i "ia-64" -c` -gt 0 ]; then ARCH=ia64; fi
	if [ `echo $architecture | grep -i "ia64" -c` -gt 0 ]; then ARCH=ia64; fi
		if [ `echo $architecture | grep -i "itanium" -c` -gt 0 ]; then ARCH=ia64; fi

	if [ -z ${SK_ARCH} ]; then
		if [ "$ARCH" == "" ]; then
			ARCH=`echo i386`
		fi
	else
		ARCH=`echo ${SK_ARCH}`
	fi
	echo "+++ Architecture: $ARCH" >> $logfile 2>&1
	message_status 1 "$ARCH"


	# Check gcc
	echo -n "Check compiler"
	if [ `which gcc` ]; then
		message_status 1 `which gcc`
	else
		message_status 0 "not found"
		echo "+++ Compiler not found" >> $logfile 2>&1	
		inst_failed "You have to install the gcc compiler."
	fi


	# Check mcmodel flags
	echo -n "Check mcmodel flags"
	echo "int main(void) { int i; return; }" >> $TMP_DIR/test.c
	`gcc -mcmodel=kernel $TMP_DIR/test.c -o $TMP_DIR/out.o &> /dev/null`
	if [ $? -gt 0 ]; then
		message_status 1 "32bit"
	else
		if [ "$ARCH" == "x86_64" ]; then
			export MCMODEL="-mcmodel=kernel"
		fi
		if [ "$ARCH" == "ia64" ]; then
			export MCMODEL="-mcmodel=kernel"
		fi
		if [ "$MCMODEL" == "" ]; then
			message_status 1 "32bit"
		else
			message_status 1 "64bit"
		fi
	fi

	# Check module support
	echo -n "Check module support"
	if [ `which insmod` ]; then
		insmod_bin=`which insmod`
		message_status 1 $insmod_bin
	else
		if [ -e /sbin/insmod ]; then
			insmod_bin="/sbin/insmod"
			message_status 1 $insmod_bin
		else
			if [ -e /usr/sbin/insmod ]; then
				insmod_bin=`echo "/usr/sbin/insmod"`
				message_status 1 $insmod_bin
			else
				message_status 0 "not found"
				echo "+++ Insmod not found" >> $logfile 2>&1	
				inst_failed "You have to install the modutils package."
			fi
		fi
	fi


	# Check make 
	echo -n "Check make"
	if [ `which make` ]; then
		message_status 1 `which make`
	else
		message_status 0 "not found"
		echo "+++ Make not found" >> $logfile 2>&1	
		inst_failed "You have to install the make package."
	fi


	# Check archive file
	echo -n "Check archive file"
	if [ -e $drv_name.tar.bz2 ]; then
		message_status 1 "$drv_name"
	else
		message_status 0 "not found"
 		echo "You have to copy the $drv_name.tar.bz2 file into the current"
		echo "$working_dir directory"
		echo "+++ $drv_name.tar.bz package not found" >> $logfile 2>&1	
		echo $inst_failed
		cleanup
		clean
		exit
	fi
}

function check_config ()
{
	# Check and change the config file
	# Syntax: check_config
	# Author: mlindner
	# Returns:
	#       N/A

	# Backup old .config file
	fname="Copy and check .config file"
	echo -n $fname
	message_status 3 "working"

	# Check config
	cp ${KERNEL_SOURCE}/.config ${TMP_DIR}/config
	cp ${KERNEL_SOURCE}/.config ${TMP_DIR}/config-backup
	rm -rf ${TMP_DIR}/newconfig &> /dev/null
	if [ $smp_count == 1 ]; then
		if [ `grep CONFIG_NR_CPUS ${TMP_DIR}/config -c` -gt "0" ]; then
			sed -e 's/# CONFIG_NR_CPUS/CONFIG_NR_CPUS=8/' \
				${TMP_DIR}/config \
				>> ${TMP_DIR}/newconfig
			cp ${TMP_DIR}/newconfig ${TMP_DIR}/config
		else
			sed -e 's/# CONFIG_SMP is not set/CONFIG_SMP=y/' \
				${TMP_DIR}/config \
				>> ${TMP_DIR}/newconfig
		fi
	else
		sed -e 's/CONFIG_SMP=y/# CONFIG_SMP is not set/' \
			${TMP_DIR}/config >> ${TMP_DIR}/newconfig
	fi

	# Set the mem address space
	if [ $HIGHMEM == 1 ]; then
	# Highmem enabled... Turn highmen on.
		sed -e 's/# CONFIG_HIGHMEM4G is not set/CONFIG_HIGHMEM4G=y/' \
			${TMP_DIR}/newconfig &> ${TMP_DIR}/newconfig2
		sed -e 's/CONFIG_HIGHMEM64G=y/# CONFIG_HIGHMEM64G is not set/' \
			${TMP_DIR}/newconfig2 &> ${TMP_DIR}/newconfig
		sed -e 's/CONFIG_NOHIGHMEM=y/# CONFIG_NOHIGHMEM is not set/' \
			${TMP_DIR}/newconfig &> ${TMP_DIR}/newconfig2
		sed -e 's/# CONFIG_HIGHMEM is not set/CONFIG_HIGHMEM=y/' \
			${TMP_DIR}/newconfig2 &> ${TMP_DIR}/newconfig
	else
	# Set highmem back
		sed -e 's/CONFIG_HIGHMEM4G=y/# CONFIG_HIGHMEM4G is not set/' \
			${TMP_DIR}/newconfig &> ${TMP_DIR}/newconfig2
		sed -e 's/CONFIG_HIGHMEM64G=y/# CONFIG_HIGHMEM64G is not set/' \
			${TMP_DIR}/newconfig2 &> ${TMP_DIR}/newconfig
		sed -e 's/# CONFIG_NOHIGHMEM is not set/CONFIG_NOHIGHMEM=y/' \
			${TMP_DIR}/newconfig &> ${TMP_DIR}/newconfig2
		sed -e 's/CONFIG_HIGHMEM=y/# CONFIG_HIGHMEM is not set/' \
			${TMP_DIR}/newconfig2 &> ${TMP_DIR}/newconfig
	fi
		
	# Set version management back
	sed -e 's/CONFIG_MODVERSIONS=y/# CONFIG_MODVERSIONS is not set/' \
		${TMP_DIR}/newconfig &> ${TMP_DIR}/newconfig2

	mv ${TMP_DIR}/newconfig2 ${TMP_DIR}/newconfig

	cp ${TMP_DIR}/newconfig ${KERNEL_SOURCE}/.config

	echo -en "\015"
	echo -n $fname
	message_status 1 "done"
}


function check_kernel_informations ()
{
	# Check kernel and module informations
	# Syntax:  check_kernel_informations
	# Author: mlindner
	# Returns:
	#       N/A


	# Check gcc and kernel version
	GCCNAME=`echo gcc`
	gcc_version=`gcc -v 2>&1 | tail -1`
	gcc_version=`echo $gcc_version | cut -d ' ' -f 3`
	kernel_gcc_version=`cat /proc/version | sed -e "s/^.*gcc version//g"`
	kernel_gcc_version=`echo $kernel_gcc_version | sed -e "s/)//g"`
	kernel_gcc_version=`echo $kernel_gcc_version | cut -d ' ' -f 1`
	echo -n "Check kernel gcc version (${kernel_gcc_version})"

	if [ $kernel_gcc_version != $gcc_version ]; then
		othergccfound=`echo 0`
		PathOfGcc=`which $GCCNAME | sed -e 's/\/gcc//'`
		AllGccInDir=`ls -1 $PathOfGcc | grep ^$GCCNAME`

		for currGcc in $AllGccInDir
		do
			if [ $othergccfound -lt 1 ]; then
				version=`$PathOfGcc/$currGcc -v 2>&1 | tail -1 | awk '{print $3}'`
				# echo "+++ Version of $currGcc is $version +++"
				if [ $kernel_gcc_version == $version ]; then
					GCCNAME=`echo $currGcc`
					othergccfound=`echo 1`
				fi
			fi
		done

		if [ $othergccfound -lt 1 ]; then
			message_status 0 "Kernel:$kernel_gcc_version != gcc:$gcc_version"
			echo "+++ Mismatch!!! Kernel:$kernel_gcc_version != gcc:$gcc_version" >> $logfile 2>&1
			if [ -z ${IGNORE_CC_MISMATCH} ]; then \

			echo "There is a version mismatch between the compiler that was used"
			echo "to build the current running kernel and the compiler which you"
			echo "intend to compile the kernel module with. In most of the cases,"
			echo "this is no problem, but there are cases in which this compiler-"
			echo "mismatch leads to unexpected system crashes"
			echo " "
			echo "If you know what you are doing and want to override this   "; \
			echo "check, you can do so by setting IGNORE_CC_MISMATCH system  "; \
			echo "variable:                                                  "; \
			echo "    Example: export IGNORE_CC_MISMATCH="1"                 "; \
			echo $inst_failed
			cleanup
			clean
			exit 1
			fi
		else
			message_status 1 "use $GCCNAME"
		fi		
	else
		message_status 1 "Kernel:$kernel_gcc_version == gcc:$gcc_version"
	fi
	
	# Check the driver availability
	echo -n "Check $drv_name driver availability"
	check_sk98lin=`lsmod | grep $drv_name -c` 
	if [ $check_sk98lin != 1 ]; then
		message_status 1 "not loaded"
	else
		if [ -z ${IGNORE_SKAVAIL_CHECK} ]; then 
			if [ "$user_sel" == "user installation" ]
			then
				message_status 1 "loaded"
			else
				echo "+++ Driver loaded. OK" >> $logfile 2>&1
				message_status 0 "loaded"
			fi

			if [ -z ${REMOVE_SKDEVICE} ] && [ "$user_sel" != "user installation" ]; then 
			echo
			echo "Driver $drv_name loaded. Please remove the driver with rmmod."
			echo "If you want override this check, you can do so by setting   "
			echo "IGNORE_SKAVAIL_CHECK:"; 
			echo "    Example: export IGNORE_SKAVAIL_CHECK="1"             "
			echo
			echo "If you want to remove the devices and the driver automatically,"
			echo "you can do so by setting REMOVE_SKDEVICE:"
			echo "    Example: export REMOVE_SKDEVICE="1"             "
			echo
			echo "+++ Driver loaded. ERROR!" >> $logfile 2>&1
			echo $inst_failed
			cleanup
			clean
			exit 1
			else
				echo -n "Disconnect devices: "
				for devices in `ls /proc/net/sk98lin`; do
					echo -n "$devices "
					ifconfig $devices down &> /dev/null
				done
				message_status 1 "done"
				echo -n "Remove driver"
				rmmod $drv_name &> /dev/null
				message_status 1 "done"
			fi
		else
			message_status 2 "loaded"
		fi
	fi


	# Check header files
	echo -n "Check kernel header files"
	if [ -d /usr/src/linux/include/linux/ ]; then
		message_status 1 "/usr/src/linux"
		export KERNEL_HEADER="/usr/src/linux/include";
		export KERNEL_SOURCE="/usr/src/linux";
	else
		if [ -d /usr/src/linux-${KERNEL_VERSION}/include/linux/ ]; then
			message_status 1 "/usr/src/linux-${KERNEL_VERSION}"
			export KERNEL_HEADER="/usr/src/linux-${KERNEL_VERSION}/include";
			export KERNEL_SOURCE="/usr/src/linux-${KERNEL_VERSION}";
		else
			kernel_check_dir="linux-$KERNEL_FAMILY"
			if [ -d /usr/src/$kernel_check_dir/include/linux/ ]; then
				message_status 1 "/usr/src/$kernel_check_dir"
				export KERNEL_HEADER="/usr/src/$kernel_check_dir/include";
				export KERNEL_SOURCE="/usr/src/$kernel_check_dir";
			else			
			message_status 0 "not found"
			echo "Kernel header not found. Please install the linux header files "
			echo "development package or crate a symbolic link from the "
			echo "/usr/src/KERNEL_VERSION directory to linux"
			echo "     Example: ln -s /usr/src/KERNEL_VERSION /usr/src/linux"
			echo ""
			echo "+++ Kernel header not found. ln -s /usr/src/KERNEL_VERSION?" >> $logfile 2>&1
			echo $inst_failed
			cleanup
			clean
			exit 1
			fi
   		fi
	fi

	# Check highmem
	echo -n "Check the mem address space"
	if [ `cat $SYMSFILE | grep "kmap_high" -c` -gt 0 ]; then
		message_status 1 "highmem"
		HIGHMEM=1
	else
		message_status 1 "lowmem"
		HIGHMEM=0
	fi

}

function check_kernel_functions ()
{
	# Check some kernel functions and insert a function if
	# available in the kernel
	# Syntax: check_kernel_functions
	# Author: mlindner
	# Returns:
	#       N/A

	fname="Check kernel functions"
	echo -n $fname
	message_status 3 "working"

	if [ "$KERNEL_MAJOR_VERSION" ==  4 ]; then
		if [ "$KERNEL_MINOR_VERSION" -lt  20 ]; then
		# Prepare driver for a new skb_padto function
		# Pads up a buffer to ensure the trailing bytes exist and are
		# blanked. If the buffer already contains sufficient data it
		# is untouched. Returns the buffer, which may be a replacement
		# for the original, or NULL for out of memory - in which case
		# the original buffer is still freed.
		#
		# A similar function is already in the kernel (skb_padto()) but we
		# need a new one. The driver is still used by older kernels without
		# the new kernel function.

		sed -e 's/static void	FreeResources(struct SK_NET_DEVICE \*dev);/\
static struct sk_buff *skb_padto(struct sk_buff *skb,unsigned int len)\
{\
\#ifndef likely\
\#define __builtin_expect(x, expected_value) (x)\
\#define likely(x) __builtin_expect((x),1)\
\#endif\
struct sk_buff *nskb;\
unsigned int size = skb->len + skb->data_len;\
if(likely(size >= len)) return skb;\
if(skb_tailroom(skb) >= len-size) { memset(skb->data+skb->len, 0, len-size);return skb;}\
nskb = skb_copy_expand(skb,skb_headroom(skb),skb_tailroom(skb) + len-size,GFP_ATOMIC);\
kfree_skb(skb);\
if(nskb) memset(nskb->data+nskb->len, 0, len-size);\
return skb;\
}\
\
static void	FreeResources(struct SK_NET_DEVICE \*dev);/' \
			${TMP_DIR}/all/skge.c &> ${TMP_DIR}/all/skge.c2

			mv ${TMP_DIR}/all/skge.c2 ${TMP_DIR}/all/skge.c
 			changes=`echo $changes skb_padto`;
		fi
	fi

	# Change sky2.c on fedora core 2
	if [ -e "/etc/fedora-release" ]; then
		if [ `grep -wc "Fedora Core release 2" /etc/fedora-release` -gt 0 ]; then
			# fedora core 2
			sed -e 's/	dma_addr_t     pPhysMemAddr;/	dma64_addr_t     pPhysMemAddr;/' ${TMP_DIR}/all/sky2.c &> ${TMP_DIR}/all/sky2.c2
			mv ${TMP_DIR}/all/sky2.c2 ${TMP_DIR}/all/sky2.c
 			changes=`echo $changes dma64_addr_t`;
		fi
	fi


	if [ "$changes" == "" ]; then
		changes="nothing"
	fi

	echo -en "\015"
	echo -n $fname
	message_status 1 "Changed: $changes"
}

#################################################################
# Kernel 2.4 make functions
#################################################################
function create_makefile_24 ()
{
	# Create makefile (kernel 2.4 version)
	# Syntax: create_makefile_24
	# Author: mlindner
	# Returns:
	#       N/A

	if [ $1 == "1" ]; then
	{
	echo '# Makefile for Marvell Yukon/SysKonnect SK-98xx/SK-95xx Gigabit'
	echo '# Ethernet Adapter driver'
	echo ''
	echo '# just to get the CONFIG_SMP and CONFIG_MODVERSIONS defines:'
	echo 'ifeq ($(KERNEL_SOURCE)/.config, $(wildcard $(KERNEL_SOURCE)/.config))'
	echo 'include $(KERNEL_SOURCE)/.config'
	echo 'endif'
	echo 'SYSINC =  -I$(KERNEL_HEADER) -I.'
	echo 'SYSDEF = -DLINUX -D__KERNEL__'
	echo 'ifdef CONFIG_SMP'
	echo 'SYSDEF += -D__SMP__'
	echo 'endif'
	echo 'SRCDEF = -DMODULE -O2 -DGENESIS -DSK_DIAG_SUPPORT -DSK_USE_CSUM \'
	echo '         -DYUKON -DYUK2 -DCONFIG_SK98LIN_ZEROCOPY'
	echo 'ifdef CONFIG_MODVERSIONS'
	echo 'SRCDEF += -DMODVERSIONS -include $(KERNEL_HEADER)/linux/modversions.h'
	echo 'SRCDEF += -include $(KERNEL_HEADER)/config/modversions.h '
	echo 'endif'
	echo 'USERDEF='
	echo 'WARNDEF=-Wall -Wimplicit -Wreturn-type -Wswitch -Wformat -Wchar-subscripts \'
	echo '	   -Wparentheses -Wpointer-arith -Wcast-qual -Wno-multichar  \'
	echo '	   -Wno-cast-qual $(MCMODEL)'
	echo 'INCLUDE= $(SYSINC)'
	echo 'DEFINES=  $(SYSDEF) $(SRCDEF) $(USERDEF) $(WARNDEF)'
	echo 'SRCFILES = skge.c kgeinit.c skgesirq.c skxmac2.c skvpd.c skgehwt.c \'
	echo '	   skqueue.c sktimer.c sktwsi.c sklm80.c skrlmt.c skgepnmi.c \'
	echo '	   skaddr.c skcsum.c skproc.c skdim.c sky2.c skethtool.c sky2le.c'
	echo 'OBJECTS =  skge.o skaddr.o skgehwt.o skgeinit.o skgepnmi.o skgesirq.o \'
	echo '	   sktwsi.o sklm80.o skqueue.o skrlmt.o sktimer.o skvpd.o skdim.o\'
	echo '	   skxmac2.o skcsum.o skproc.o sky2.o skethtool.o sky2le.o'
	echo 'DRVBIN = sk98lin.o'
	echo 'LD	= ld'
	echo "CC	= $GCCNAME"
	echo 'CFLAGS	= $(INCLUDE) $(DEFINES)'
	echo 'FILES	= $(SRCFILES) makefile'
	echo 'TARGETS	= $(DRVBIN)'
	echo '.c.o:   $<'
	echo '	$(CC) $(CFLAGS) -c $<'
	echo 'all:  $(OBJECTS)'
	echo '	$(LD) -r -o $(DRVBIN) $(OBJECTS)'
	echo 'clean:'
	echo '	rm *.o'
	echo '*.o: \'
	echo '	h/*.h'
	} &> ${TMP_DIR}/all/Makefile
	else
	cp ${TMP_DIR}/2.4/Makefile ${TMP_DIR}/all/Makefile
	fi
}

function make_driver_24 ()
{
	# Configure, check and build the driver (kernel 2.4)
	# Syntax: make_driver
	# Author: mlindner
	# Returns:
	#       N/A

	# Compile the driver
	echo >> $logfile 2>&1 
	echo "+++ Compile the driver" >> $logfile 2>&1
	echo "+++ ====================================" >> $logfile 2>&1
	cd ${TMP_DIR}/all

	fname="Compile the driver"
	echo -n $fname
	message_status 3 "working"
	make $MAKE_CPU_FLAG >> $logfile 2>&1


	if [ ! -f $drv_name.o ]; then
		echo -en "\015"
		echo -n $fname
		message_status 2 "failed"

		make_dep
		fname="Compile the driver"
		echo -n $fname
		message_status 3 "working"
		make $MAKE_CPU_FLAG >> $logfile 2>&1
	fi


	if [ -f $drv_name.o ]; then
		cp $drv_name.o ../
		echo -en "\015"
		echo -n $fname
		message_status 1 "done"
	else
		echo -en "\015"
		echo -n $fname
		message_status 0 "error"
 		echo
		echo "An error has occurred during the compile proces which prevented "; \
		echo "the installation from completing.                              "; \
		echo "Take a look at the log file install.log for more informations.  "; \
		echo "+++ Compiler error" >> $logfile 2>&1
		echo $inst_failed
		cleanup
		clean
		exit 1
	fi
}


#################################################################
# Kernel 2.6 make functions
#################################################################
function create_makefile_26 ()
{
	# Create makefile (kernel 2.6 version)
	# Syntax: create_makefile_26
	#	1 == change makefile for compilation
	#	1 != don't change
	# Author: mlindner
	# Returns:
	#       N/A


	# we have to use the makefile and change the include dir
	rm -rf ${TMP_DIR}/all/Makefile
 	if [ $1 == "1" ]; then
		rm -rf ${TMP_DIR}/all/Makefile
		local A="`echo | tr '\012' '\001' `"
		local AFirst="Idrivers/net/sk98lin"
		local ALast="I${TMP_DIR}/all"
		sed -e "s$A$AFirst$A$ALast$A" \
			${TMP_DIR}/2.6/Makefile \
			>> ${TMP_DIR}/all/Makefile
	else
		cp ${TMP_DIR}/2.6/Makefile ${TMP_DIR}/all/Makefile
	fi
}

function make_driver_26 ()
{
	# Configure, check and build the driver (kernel 2.4)
	# Syntax: make_driver
	# Author: mlindner
	# Returns:
	#       N/A

	# Compile the driver
	echo >> $logfile 2>&1 
	echo "+++ Compile the driver" >> $logfile 2>&1
	echo "+++ ====================================" >> $logfile 2>&1
	cd ${TMP_DIR}/all

	fname="Compile the kernel"
	echo -n $fname
	message_status 3 "working"
	make $MAKE_CPU_FLAG -C ${KERNEL_SOURCE}  SUBDIRS=${TMP_DIR}/all modules >> $logfile 2>&1

	if [ -f $drv_name.ko ]; then
		cp $drv_name.ko ../
		echo -en "\015"
		echo -n $fname
		message_status 1 "done"
	else
		echo -en "\015"
		echo -n $fname
		message_status 0 "error"
 		echo
		echo "An error has occurred during the compile proces which prevented "; \
		echo "the installation from completing.                              "; \
		echo "Take a look at the log file install.log for more informations.  "; \
		echo "+++ Compiler error" >> $logfile 2>&1
		echo $inst_failed
		cleanup
#		clean
		exit 1
	fi
}

#################################################################
# Messages functions
#################################################################
function header_check_failed ()
{
	# Print a error message and exit 
	# Syntax: header_check_failed
	# Author: mlindner
	# Returns:
	#       N/A

	echo "There is a mismatch between the current running kernel and"
	echo "the header files the kernel module will be compiled with."
	echo " "
	echo "For instance, it might be, that you run kernel version"
	echo "2.4.20, but the header files the kernel module will be"
	echo "compiled with refer to kernel version 2.4.21"
	echo 
	echo "Due to this mismatch, you will not be able to load the "
	echo "driver without the force option (insmod -f $drv_name) after"
	echo "its compilation finished."
	echo " "
	echo "This problem can be resolved by overwriting the current"
	echo "include/version.h (which corresponds to another kernel "
	echo "version), with the include/version.h of the kernel version"
	echo "currently running."
	echo " "
 	echo "BEWARE: OVERWRITE THE FILE ONLY IF YOU HAVE REALLY THE "
	echo "CORRECT HEADER FILE CORRESPONDING TO THE CURRENT RUNNING"
	echo " "
	echo "If you don't have the same kernel version, please install  "; \
	echo "the sources or a new kernel. It's not possible to mix      "; \
	echo "different kernel versions!                                 "; \
	echo "                                                           "; \
	echo "If you know what you are doing and want to override this   "; \
	echo "check, you can do so by setting IGNORE_HEADER_MISMATCH     "; \
	echo "system variable:                                           "; \
	echo "    Example: export IGNORE_HEADER_MISMATCH="1"             "; \
	echo "                                                           "; \
	echo "or change the file ${KERNEL_HEADER}/linux/version.h,       "; \
	echo "remove the define UTS_RELEASE line and insert:             "; \
	echo "#define UTS_RELEASE \"${KERNEL_VERSION}\"                  "; \
	echo "                                                           "; \
	echo "    Your kernel version: ${KERNEL_VERSION}                 "; \
	echo "    Your header version: $header_version                   "; \
	echo $inst_failed
	echo "                                                           "; \
	cleanup
	clean
	exit
}

function kernel_check_failed ()
{
	# Print kernel error informations
	# Syntax:  kernel_check_failed
	# Author: mlindner
	# Returns:

	echo "Kernel version unsupported."
	echo "This driver was developed for the kernel family 2.4.x"
	echo "higher then 2.4.13. If you are still using a old version"
	echo "of the kernel, please uptade to the newest version from"
	echo "ftp://ftp.kernel.org"
	echo "+++ Kernel version unsupported" >> $logfile 2>&1	
	echo $inst_failed
	echo
	cleanup
	clean
	exit
}


#################################################################
# Common kernel functions
#################################################################
function check_driver ()
{
	# Copy the news sources and check the driver
	# Syntax:  check_driver
	# Author: mlindner
	# Returns:
	#       N/A

	echo -n "Copy driver man page into /usr/share/man/man4/"
	rm -rf /usr/share/man/man4/sk98lin.4 &> /dev/null
	rm -rf /usr/share/man/man4/sk98lin.4.gz &> /dev/null
	cp -f sk98lin.4 /usr/share/man/man4/ &> /dev/null
	gzip /usr/share/man/man4/sk98lin.4 &> /dev/null
	message_status 1 "done"

	# Check the driver
	fname="Check the driver"
	echo -n $fname
	message_status 3 "working"

	echo "Check the driver" >> $logfile 2>&1
	echo "====================================" >> $logfile 2>&1
	sync
	sleep 1
	sync
	if [ ${KERNEL_FAMILY} == 2.4 ]; then
		$insmod_bin ./$drv_name.o >> $logfile 2>&1
	else
		$insmod_bin ./$drv_name.ko >> $logfile 2>&1
	fi
	insmod_count=`lsmod | grep $drv_name -c`

	if [ $insmod_count != 1 ]; then
		echo -en "\015"
		echo -n $fname
		message_status 0 "error"	
		echo "An error has occurred during the check proces which prevented  "; \
		echo "the installation from completing.                              "; \
		echo "It's not possible to build a standalone $drv_name driver on this "; \
		echo "host. The kernel don't export a neccesary symbols for the      "; \
		echo "device driver and we aren't able to load the driver.           "; \
		echo 
		echo "Please compile the kernel and the driver manually.             "; \
		echo "The new driver has been installed in the /usr/src/linux        "; \
		echo "directory.                                                     "; \
		echo 
		echo "   1.) Go to the directory /usr/src/linux                      "; \
		echo "   2.) For the console mode, run the command: make menuconfig  "; \
		echo "   3.) Select the options you want to compile into the kernel  "; \
		echo "   4.) Select the menu \"Network Device Support\"              "; \
		echo "   5.) Select \"Ethernet (1000 Mbit)\".                        "; \
		echo "   5.) Mark \"Marvell Yukon/SysKonnect SK-98xx/SK-95xx Gigabit "; \
		echo "       Ethernet Adapter support\" with (M)                     "; \
		echo "   6.) Execute the command:                                    "; \
		echo "           make dep clean bzImage modules modules_install      "; \
		echo "   7.) Install the new kernel                                  "; \

		echo "+++ Check error. Insmod error!" >> $logfile 2>&1
		echo $inst_failed
		return 1
	else
		echo -en "\015"
		echo -n $fname
		message_status 1 "done"
	fi


	# Check driver directory
	if [ ! -e "/lib/modules/${KERNEL_VERSION}/kernel/drivers/net/$drv_name" ]; then
		fname="Create kernel modules driver directory"
		echo -n $fname
		message_status 3 "working"
		mkdir /lib/modules/${KERNEL_VERSION}/kernel/drivers/net/$drv_name
		echo -en "\015"
		echo -n $fname
		message_status 1 "done"
	fi

	# Delete old driver
	fname="Delete old driver"
	echo -n $fname
	message_status 3 "working"
	rm -rf /lib/modules/${KERNEL_VERSION}/kernel/drivers/net/$drv_name/sk98lin.*
	echo -en "\015"
	echo -n $fname
	message_status 1 "done"

	
	# Copy the driver
	fname="Copying driver"
	echo -n $fname
	message_status 3 "working"
	if [ ${KERNEL_FAMILY} == 2.4 ]; then
		cp $drv_name.o \
		/lib/modules/${KERNEL_VERSION}/kernel/drivers/net/$drv_name/
	else
		cp $drv_name.ko \
		/lib/modules/${KERNEL_VERSION}/kernel/drivers/net/$drv_name/$drv_name.ko
	fi
	echo -en "\015"
	echo -n $fname
	message_status 1 "done"

	# Make dependency
	fname="Make dependency"
	echo -n $fname
	message_status 3 "working"
	depmod -a &> /dev/null
	echo -en "\015"
	echo -n $fname
	message_status 1 "done"

}


function copy_driver ()
{
	# Copy driver
	# Syntax: copy_driver
	# Author: mlindner
	# Returns:
	#       N/A

	# Copy sources and check the new driver (only if silent mode disabled)
	if [ ! "${OPTION_SILENT}" ]; then
		check_driver
		retvar=$?
		cleanup
		clean

		if [ $retvar != 1 ]; then
			echo "All done. Driver installed and loaded."
			echo "To load the module manually, proceed as follows:"
			echo "      Enter \"modprobe $drv_name\""
			echo 
			echo "                                                     Have fun..."
		fi
	else
#	if [ ${SK_RPM_BUILD_ROOT} ]; then
#		cp $drv_name.o ${SK_RPM_BUILD_ROOT}
#	fi
		cp $drv_name.o $working_dir
		cleanup
		echo "All done. Driver compiled."
	fi
}


function read_and_change_version_file ()
{
	# Check version.h
	# Syntax: read_and_change_version_file FILE_AS_STRING
	# Author: mlindner
	# Returns:
	#       N/A

	dline_count=0
	rm -rf ${TMP_DIR}/newversion.h
	pure_kernel_version=`echo ${KERNEL_VERSION}`
	pure_kernel_version=`echo $pure_kernel_version | cut -d '-' -f 1`

	while read line  # For as many lines as the input file has...
	do
		line_count=`echo $line | grep -c "UTS_RELEASE"`
		if [ $line_count != 0 ]; then
			if [ $dline_count == 0 ]; then
				version_count=`echo $line | grep -c "$pure_kernel_version"`
				if [ $version_count == 1 ]; then
				# Change line
					echo "#define UTS_RELEASE \"${KERNEL_VERSION}\"" \
						>> ${TMP_DIR}/newversion.h
					dline_count=1
				fi
			fi
		else
			echo "$line" >> ${TMP_DIR}/newversion.h
		fi
	done

	if [ $dline_count == 0 ]; then
		header_check_failed
	fi

	cp ${TMP_DIR}/newversion.h ${KERNEL_HEADER}/linux/version.h
}


function generate_sources_version ()
{
	# Check and generate a correct version.h file
	# Syntax: generate_sources_version
	# Author: mlindner
	# Returns:
	#       N/A

	# We have to "make prepare" if version sill not available
	if [ ! -f ${KERNEL_SOURCE}/include/linux/version.h ]; then
		fname="Execute: make prepare"
		echo -n $fname
		message_status 3 "working"
		cd ${KERNEL_SOURCE}
		make prepare &> /dev/null
		echo -en "\015"
		echo -n $fname
		message_status 1 "done"
	fi

	# Check header version
	echo -n "Check kernel header version"
	header_count=`grep -c RELEASE ${KERNEL_HEADER}/linux/version.h`

	if [ $header_count != 1 ]; then
		message_status 2 "not recognized"
	else	
		header_version=`grep RELEASE ${KERNEL_HEADER}/linux/version.h`
		header_version=`echo $header_version | cut -d '"' -f 2`
		if [ $header_version != ${KERNEL_VERSION} ]; then
			if [ -z ${IGNORE_HEADER_MISMATCH} ]; then
				if [ "$user_sel" == "user installation" ]
				then
					message_status 1 "Kernel:${KERNEL_VERSION} != Header:$header_version"
					echo -n "Save old version.h"
					cp ${KERNEL_HEADER}/linux/version.h ./
					message_status 1 "saved"	

					echo -n "Check and create new version.h"
					tmp_version=`cat ${KERNEL_HEADER}/linux/version.h`
					read_and_change_version_file <<INPUTSTART
$tmp_version
INPUTSTART

					message_status 1 "created"

					# Make dependency
#					make_dep

				else
					message_status 0 "Kernel:${KERNEL_VERSION} != Header:$header_version"
					echo "+++ Kernel:${KERNEL_VERSION} != Header:$header_version" >> $logfile 2>&1
					header_check_failed
				fi
			fi
		else
			message_status 1 "Kernel:${KERNEL_VERSION} == Header:$header_version"
		fi
	fi
}


function generate_config ()
{
	# Check config file; Save old version and modify
	# Syntax: generate_config
	# Author: mlindner
	# Returns:
	#       N/A

	echo -n "Check sources for .config file"
	echo 'while true; do echo -en "\012";done' &> ${TMP_DIR}/enter
	chmod 755 ${TMP_DIR}/enter

	if [ -f ${KERNEL_SOURCE}/.config ]; then
	# Config file available
		message_status 1 "${KERNEL_SOURCE}/.config"

		if [ -f /proc/config.gz ]; then
			copy_proc_fs_config
		fi

		if [ -f ${KERNEL_SOURCE}/drivers/net/$drv_name/$drv_name.o ]; then
			# Driver already generated. Check config
			rm -rf ${KERNEL_SOURCE}/drivers/net/sk98lin/*.o
			# Modversions not available. We have to regenerate the dep
			check_config

			# Regenerate the config file
			rebuild_config_file

			if [ `diff ${TMP_DIR}/config-backup ${KERNEL_SOURCE}/.config | wc -l` -gt 0 ]; then
			# Create dependency
				make_dep
			fi
			
		else
			if [ -f ${KERNEL_HEADER}/linux/version.h ] &&
				[ -f ${KERNEL_SOURCE}/include/linux/autoconf.h ]; then
				# Driver already generated. Check config
					# Modversions not available. We have to regenerate the dep
					check_config

					# Regenerate the config file
					rebuild_config_file

					if [ `diff ${TMP_DIR}/config-backup ${KERNEL_SOURCE}/.config | wc -l` -gt 0 ]; then
					# Create dependency
						make_dep
					fi
			else
			if [ -f ${KERNEL_SOURCE}/drivers/net/$drv_name/.depend ] ||
				[ -f ${KERNEL_SOURCE}/drivers/net/$drv_name/.built-in.o.cmd ]; then
				if [ -f ${KERNEL_HEADER}/linux/modversions.h ] || 
					[ ${KERNEL_FAMILY} == 2.6 ]; then
				# Modversions available. nothing to do
					DONT_CLEANUP_TREE=1;
				else
					# Modversions not available. We have to regenerate the dep
					check_config

					# Regenerate the config file
					rebuild_config_file

					if [ `diff ${TMP_DIR}/config-backup ${KERNEL_SOURCE}/.config | wc -l` -gt 0 ]; then
					# Create dependency
						make_dep
					fi
				fi
			else
				# Change the config file
				check_config

				# Generate the config file
				rebuild_config_file

				# Create dependency
				make_dep
			fi
			fi
		fi
	else
	# Config file _not_ available
		message_status 1 "none"

		# Clean the distriubuted files	
		make_mrproper

		if [ -d ${KERNEL_SOURCE}/configs ]; then
			echo -n "Config files found"
			message_status 1 "${KERNEL_SOURCE}/configs/"

			# restore old config file from an alternative place (RedHat)
			copy_alternative_configs
		fi

		if [ -f /proc/config.gz ]; then
			copy_proc_fs_config
		fi

		# Restore old version.h file
		version_h_management 0

		# Generate the config file (step 1)
		generate_config_file

		# Change the config file
		cp ${KERNEL_SOURCE}/.config ${TMP_DIR}/config-bk2
		check_config

		if [ `diff ${TMP_DIR}/config-bk2 ${KERNEL_SOURCE}/.config | wc -l` -gt 0 ]; then
			# Generate the config file (step 2)
			rebuild_config_file	
		fi

		# Create dependency
		make_dep
	fi
}


function copy_proc_fs_config () {
	# Restore old config file from /proc/ fs
	# Syntax: copy_proc_fs_config
	# Author: mlindner
	# Returns:
	#       N/A

	echo -n "Copying file from proc directory"
	zcat /proc/config.gz &> ${KERNEL_SOURCE}/.config
	message_status 1 "done"
}


function copy_alternative_configs ()
{
	# Restore old config file from an alternative place (RedHat)
	# Syntax: copy_alternative_configs
	# Author: mlindner
	# Returns:
	#       N/A

	echo -n "Copying file from config directory"
	cpu_count=`cat /proc/cpuinfo | grep "cpu family" -c`

	pure_kernel=`echo ${KERNEL_VERSION} | cut -d '-' -f 1`
	mach_config="${KERNEL_SOURCE}/configs/kernel-$pure_kernel-$kernel_machine.config"

	if [ -f $mach_config ]; then
 		if [ $cpu_count != 1 ]; then
			if [ $cpu_count -gt 1 ]; then
				mach_config="${KERNEL_SOURCE}/configs/kernel-$pure_kernel-$kernel_machine-smp.config"
				cp $mach_config ${KERNEL_SOURCE}/.config
				message_status 1 "done"
			else
				message_status 1 "file not found"
			fi
		else
			cp $mach_config ${KERNEL_SOURCE}/.config
			message_status 1 "done"
		fi
	else
		message_status 1 "file not found"
	fi
}


function generate_config_file ()
{
	# Generate a new .config file
	# Syntax: generate_config_file
	# Author: mlindner
	# Returns:
	#       N/A

	fname="Execute: make config"
	echo -n $fname
	message_status 3 "working"
	cd ${KERNEL_SOURCE}
	${TMP_DIR}/enter | make config $MAKE_CPU_FLAG &> /dev/null
	echo -en "\015"
	echo -n $fname
	message_status 1 "done"

}

function rebuild_config_file ()
{
	# Rebuild the .config file
	# Syntax: rebuild_config_file
	# Author: mlindner
	# Returns:
	#       N/A

	fname="Execute: make oldconfig"
	echo -n $fname
	message_status 3 "working"
	cd ${KERNEL_SOURCE}
	${TMP_DIR}/enter | make oldconfig $MAKE_CPU_FLAG &> /dev/null
	returnvalue=$?
	echo -en "\015"
	echo -n $fname
	message_status 1 "done"

	if [ $returnvalue != 0 ]; then
		echo -n "Delete old .config file"
		rm -rf .config
		message_status 1 "done"

		fname="Execute: make oldconfig (step2)"
		echo -n $fname
		message_status 3 "working"
		cd ${KERNEL_SOURCE}
		${TMP_DIR}/enter | make oldconfig $MAKE_CPU_FLAG &> /dev/null
		returnvalue=$?
		echo -en "\015"
		fname="Execute: make oldconfig"
		echo -n $fname
		message_status 1 "done"
	fi
}

function make_dep ()
{
	# Execute make dep
	# Syntax: make_dep
	# Author: mlindner
	# Returns:
	#       N/A

	# Make dep
	if [ ${KERNEL_FAMILY} == 2.4 ]; then
		fname="Execute: make dep"
		echo -n $fname
		message_status 3 "working"
		cd ${KERNEL_SOURCE}
		make dep $MAKE_CPU_FLAG &> /dev/null
		echo -en "\015"
		echo -n $fname
		message_status 1 "done"
	fi

}


function make_mrproper ()
{
	# Execute make mrproper
	# Syntax: make_mrproper
	# Author: mlindner
	# Returns:
	#       N/A

	# Make dep
	fname="Execute: make mrproper"
	echo -n $fname
	message_status 3 "working"
	cd ${KERNEL_SOURCE}
	make mrproper $MAKE_CPU_FLAG &> /dev/null 
	echo -en "\015"
	echo -n $fname
	message_status 1 "done"

}


function version_header_management ()
{
	# Check version header and change it if neccassary
	# Syntax: version_header_management
	# Author: mlindner
	# Returns:
	#       N/A

	# Check header version
	echo -n "Check kernel header version"
	header_count=`grep -c RELEASE ${KERNEL_HEADER}/linux/version.h`

	if [ $header_count != 1 ]; then
		message_status 2 "not recognized"
	else	
		header_version=`grep RELEASE ${KERNEL_HEADER}/linux/version.h`
		header_version=`echo $header_version | cut -d '"' -f 2`
		if [ $header_version != ${KERNEL_VERSION} ]; then
			if [ -z ${IGNORE_HEADER_MISMATCH} ]; then
				if [ "$user_sel" == "user installation" ]
				then
					message_status 1 "Kernel:${KERNEL_VERSION} != Header:$header_version"

					# Backup the version.h file
					version_h_management 1

					echo -n "Check and create new version.h"
					tmp_version=`cat ${KERNEL_HEADER}/linux/version.h`
					read_and_change_version_file <<INPUTSTART
$tmp_version
INPUTSTART

					message_status 1 "created"
				else
					message_status 0 "Kernel:${KERNEL_VERSION} != Header:$header_version"
					echo "+++ Kernel:${KERNEL_VERSION} != Header:$header_version" >> $logfile 2>&1
					header_check_failed
				fi
			fi
		else
			message_status 1 "Kernel:${KERNEL_VERSION} == Header:$header_version"
		fi
	fi
}


function read_and_change_version_file ()
{
	# change version file (version.h)
	# Syntax: read_and_change_version_file FILE_AS_STRING
	# Author: mlindner
	# Returns:
	#       N/A

	dline_count=0
	rm -rf ${TMP_DIR}/newversion.h
	pure_kernel_version=`echo ${KERNEL_VERSION}`
	pure_kernel_version=`echo $pure_kernel_version | cut -d '-' -f 1`

	while read line  # For as many lines as the input file has...
	do
		line_count=`echo $line | grep -c "UTS_RELEASE"`
		if [ $line_count != 0 ]; then
			if [ $dline_count == 0 ]; then
				version_count=`echo $line | grep -c "$pure_kernel_version"`
				if [ $version_count == 1 ]; then
				# Change line
					echo "#define UTS_RELEASE \"${KERNEL_VERSION}\"" \
						>> ${TMP_DIR}/newversion.h
					dline_count=1
				fi
			fi
		else
			echo "$line" >> ${TMP_DIR}/newversion.h
		fi
	done

	if [ $dline_count == 0 ]; then
		header_check_failed
	fi

	cp ${TMP_DIR}/newversion.h ${KERNEL_HEADER}/linux/version.h
}


function version_h_management ()
{
	# Save or restore version.h file
	# Syntax: version_h_management FLAG
	#	FLAG:
	#		1 == Save version.h
	#		1 != Restore version.h
	# Author: mlindner
	# Returns:
	#       N/A

	if [ $1 != 1 ]; then
	# Restore version.h
		if [ "$user_sel" == "user installation" ]; then
			if [ -e ${TMP_DIR}/version.h ]; then
				echo -n "Restore old version.h"
				cp ${TMP_DIR}/version.h ${KERNEL_HEADER}/linux/version.h
				message_status 1 "done"
			fi
		fi
	else
	# Save old version.h file
		if [ -f ${KERNEL_SOURCE}/include/linux/version.h ]; then
			echo -n "Save old version.h file"
			cp ${KERNEL_SOURCE}/include/linux/version.h ${TMP_DIR}/
			message_status 1 "done"
		fi
	fi

}

function autoconf_h_management ()
{
	# Save or restore autoconf.h file
	# Syntax: autoconf_h_management FLAG
	#	FLAG:
	#		1 == Save autoconf.h
	#		1 != Restore autoconf.h
	# Author: mlindner
	# Returns:
	#       N/A

	if [ $1 != 1 ]; then
	# Restore autoconf.h
		if [ "$user_sel" == "user installation" ]; then
			if [ -e ${TMP_DIR}/autoconf.h ]; then
				echo -n "Restore old autoconf.h"
				cp ${TMP_DIR}/autoconf.h ${KERNEL_HEADER}/linux/autoconf.h
				message_status 1 "done"
			fi
		fi
	else
	# Save old autoconf.h file
		if [ -f ${KERNEL_SOURCE}/include/linux/autoconf.h ]; then
			echo -n "Save old autoconf.h file"
			cp ${KERNEL_SOURCE}/include/linux/autoconf.h ${TMP_DIR}/
			message_status 1 "done"
		fi
	fi

}

function dot_config_management ()
{
	# Save or restore config file 
	# Syntax: dot_config_management FLAG
	#	FLAG:
	#		1 == Save .config
	#		1 != Restore .config
	# Author: mlindner
	# Returns:
	#       N/A

	if [ $1 != 1 ]; then
	# Restore .config
		if [ "$user_sel" == "user installation" ]; then
			if [ -e ${TMP_DIR}/config-backup ]; then
				echo -n "Restore old .config"
				cp ${TMP_DIR}/config-backup ${KERNEL_SOURCE}/.config
				message_status 1 "done"
			fi
		fi
	else
	# Save old .config file
		if [ -f ${KERNEL_SOURCE}/include/linux/autoconf.h ]; then
			echo -n "Save old .config file"
			cp ${KERNEL_SOURCE}/.config ${TMP_DIR}/config-backup
			message_status 1 "done"
		fi
	fi

}

#################################################################
# Cleanup functions
#################################################################

function cleanup_trap ()
{
	# Sig handling
	# Syntax: cleanup_trap
	#	FLAG:
	# Author: mlindner
	# Returns:
	#       N/A

	cleanup
	clean
	exit 1
	
}

function cleanup ()
{
	# Restore all files
	# Syntax: cleanup
	# Author: mlindner
	# Returns:
	#       N/A

	
	# Restore version.h
	version_h_management 0

	# Restore old autoconf.h file
	autoconf_h_management 0

	if [ -e ${TMP_DIR}/config ]; then
		if [ ${KERNEL_SOURCE} ]; then
			cp ${TMP_DIR}/config ${KERNEL_SOURCE}/.config
		fi
	fi

	return
}

function clean ()
{
        # Clean temp directory
        # Syntax: clean
        # Author: mlindner
        # Returns:
        #       N/A

	echo -n "Delete temp directories"
 	cd $working_dir
	if [ ${TMP_DIR} ]; then
 		rm -rf ${TMP_DIR}
	else
		rm -rf /tmp/Sk98I*
	fi
 	rm -rf $drv_name.o
	message_status 1 "done"

	return
}


#################################################################
# Generate patch functions
#################################################################
function check_driver_sources ()
{
	# Get some infos from the driver sources dir
	# Syntax: check_driver_sources
	# Author: mlindner
	# Returns:
	#       N/A

	local verstring=`cat ${TMP_DIR}/common/h/skversion.h | grep "VER_STRING"`
	DRIVER_VERSION=`echo $verstring | cut -d '"' -f 2`
	verstring=`cat ${TMP_DIR}/common/h/skversion.h | grep "DRIVER_REL_DATE"`
	DRIVER_REL_DATE=`echo $verstring | cut -d '"' -f 2`
}


function check_headers_for_patch ()
{
	# Get some infos from the Makefile
	# Syntax: check_headers_for_patch
	# Author: mlindner
	# Returns:
	#       N/A

	local mainkernel
	local patchkernel
	local sublevelkernel

	# Check header files
	if [ -d $KERNEL_SOURCE ]; then
		export KERNEL_SOURCE=$KERNEL_SOURCE
	else
		echo
		echo "An error has occurred during the patch proces which prevented "; \
		echo "the installation from completing.                              "; \
		echo "Directory $KERNEL_SOURCE not found!.  "; \
		echo $inst_failed
		cleanup
		clean
		exit 1
	fi

	if [ -f $KERNEL_SOURCE/Makefile ]; then
		export KERNEL_SOURCE=$KERNEL_SOURCE
	else
		echo
		echo "An error has occurred during the patch proces which prevented "; \
		echo "the installation from completing.                              "; \
		echo "Makefile in the directory $KERNEL_SOURCE not found!.  "; \
		echo $inst_failed
		cleanup
		clean
		exit 1
	fi


	# Get main version
	local mainversion=`grep "^VERSION =" $KERNEL_SOURCE/Makefile`
	local vercount=`echo $mainversion | wc -c`
	if [ $vercount -lt 1 ]; then
		mainversion=`grep "^VERSION=" $KERNEL_SOURCE/Makefile`
	fi
	mainkernel=`echo $mainversion | cut -d '=' -f 2 | sed -e "s/ //g"`

	# Get patchlevel
	local patchlevel=`grep "^PATCHLEVEL =" $KERNEL_SOURCE/Makefile`
	vercount=`echo $patchlevel | wc -c`
	if [ $vercount -lt 1 ]; then
		patchlevel=`grep "^PATCHLEVEL=" $KERNEL_SOURCE/Makefile`
	fi
	patchkernel=`echo $patchlevel | cut -d '=' -f 2 | sed -e "s/ //g"`

	# Get sublevel
	local sublevel=`grep "^SUBLEVEL =" $KERNEL_SOURCE/Makefile`
	vercount=`echo $sublevel | wc -c`
	if [ $vercount -lt 1 ]; then
		sublevel=`grep "^SUBLEVEL=" $KERNEL_SOURCE/Makefile`
	fi
	sublevelkernel=`echo $sublevel | cut -d '=' -f 2 | sed -e "s/ //g"`

	# Version checks
	if [ $mainkernel != 2 ]; then
		kernel_check_failed
	fi

	if [ $patchkernel != 4 ] && [ $patchkernel != 6 ]; then
		kernel_check_failed
	fi

	if [ "$sublevelkernel" -lt  13 ] && [ $patchkernel == 4 ]; then
		kernel_check_failed
	fi

	KERNEL_VERSION=`echo "$mainkernel.$patchkernel.$sublevelkernel"`
	KERNEL_FAMILY=`echo "$mainkernel.$patchkernel"`
	KERNEL_MINOR_VERSION=$sublevelkernel
	KERNEL_MAJOR_VERSION=$patchkernel
}


function check_system_for_patch ()
{
	# Get some infos from host
	# Syntax: check_system_for_patch
	# Author: mlindner
	# Returns:
	#       N/A

	# Check kernel version

	export KERNEL_VERSION=`uname -r`	
	split_kernel_ver=`echo ${KERNEL_VERSION} | cut -d '.' -f 1`

	KERNEL_FAMILY="$split_kernel_ver"
	split_kernel_ver=`echo ${KERNEL_VERSION} | cut -d '.' -f 2`
	KERNEL_FAMILY="$KERNEL_FAMILY.$split_kernel_ver"

	split_kernel_ver=`echo ${KERNEL_VERSION} | cut -d '.' -f 3`
	split_kernel_ver2=`echo $split_kernel_ver | cut -d '-' -f 1`
	KERNEL_MINOR_VERSION=`echo $split_kernel_ver2`
	KERNEL_MAJOR_VERSION=`echo ${KERNEL_VERSION} | cut -d '.' -f 2`

	# Check header files
	if [ -d /usr/src/linux/include/linux/ ]; then
		export KERNEL_SOURCE="/usr/src/linux";
	else
		if [ -d /usr/src/linux-${KERNEL_VERSION}/include/linux/ ]; then
			export KERNEL_SOURCE="/usr/src/linux-${KERNEL_VERSION}";
		else
			kernel_check_dir="linux-$KERNEL_FAMILY"
			if [ -d /usr/src/$kernel_check_dir/include/linux/ ]; then
				export KERNEL_SOURCE="/usr/src/$kernel_check_dir";
			fi
   		fi
	fi

}

function get_patch_infos ()
{
	# Interactive formular
	# Syntax: get_patch_infos
	# Author: mlindner
	# Returns:
	#       N/A

	if [ ! ${INSTALL_AUTO} ]; then
		PS3='Choose your favorite installation method: ' # Sets the prompt string.
		echo -n "Kernel source directory (${KERNEL_SOURCE}) : "
		read kernel_source_in
		if [ "$kernel_source_in" != "" ]; then
			KERNEL_SOURCE=$kernel_source_in
		fi
	fi

	# Check the headers
	check_headers_for_patch

	# Check driver version
	check_driver_sources

	if [ ! ${INSTALL_AUTO} ]; then
		drvvertmp=`echo $DRIVER_VERSION | sed -e "s/ //g"`
		PATCH_NAME="$working_dir/sk98lin_v"
		PATCH_NAME="$PATCH_NAME$drvvertmp"
		PATCH_NAME="${PATCH_NAME}_${KERNEL_VERSION}_patch"

		echo -n "Patch name ($PATCH_NAME) : "
		read patch_name_in

		if [ "$patch_name_in" != "" ]; then
			PATCH_NAME=$patch_name_in
		fi
	fi
}


function generate_patch_for_help24 ()
{
	# Generate a patch for the config file
	# Syntax: generate_patch_for_help24
	#	package_root, kernel_root
	# Author: mlindner
	# Returns:
	#       N/A
	fname="Generate Config.help patch"
	echo -n $fname
	message_status 3 "working"
	local packagedir="$1"
	local kerneldir=$2
	local startline
	local totalline
	local splitline
	local count=0
	local splt=0
	local A="`echo | tr '\012' '\001' `"

	# initial cleanup
	rm -rf ${TMP_DIR}/all_sources_patch

	# find the first line of the sk block
	startline=`grep "CONFIG_SK98LIN$" $kerneldir/Documentation/Configure.help -n | cut -d ':' -f 1`
	totalline=`cat $kerneldir/Documentation/Configure.help | wc -l`
	((startline=$startline - 2))
	((splitline=$totalline - $startline))
	((splitline=$splitline - 2))

	head -n $startline $kerneldir/Documentation/Configure.help > ${TMP_DIR}/Configure.help
	cat $packagedir/misc/Configure.help >> ${TMP_DIR}/Configure.help
	tail -n $splitline $kerneldir/Documentation/Configure.help > ${TMP_DIR}/Configuretemp

	# find the end of the block	
	while read line; do
		((count=$count + 1))
		splt=`echo $line | grep CONFIG_ -c`
		if [ $splt -gt 0 ]; then break; fi
	done < ${TMP_DIR}/Configuretemp
	((count=$count - 2))
	((splitline=$splitline - $count))
	tail -n $splitline $kerneldir/Documentation/Configure.help >> ${TMP_DIR}/Configure.help

	# Make diff
	diff -ruN $kerneldir/Documentation/Configure.help ${TMP_DIR}/Configure.help \
		> ${TMP_DIR}/all_sources_patch
	replacement="linux-new/Documentation"
	sed -e "s$A${TMP_DIR}$A$replacement$A" \
		${TMP_DIR}/all_sources_patch &> ${TMP_DIR}/all_sources_patch2
	replacement="linux"
	sed -e "s$A$kerneldir$A$replacement$A" \
		${TMP_DIR}/all_sources_patch2 &> ${TMP_DIR}/all_sources_patch


	# Complete the patch
	if [ -f ${TMP_DIR}/all_sources_patch ] && \
		[ `cat ${TMP_DIR}/all_sources_patch | wc -c` -gt 0 ]; then
		echo "diff -ruN linux/Documentation/Configure.help \
linux-new/Documentation/Configure.help" >> ${PATCH_NAME}
		cat ${TMP_DIR}/all_sources_patch >> ${PATCH_NAME}
	fi

	# Status
	echo -en "\015"
	echo -n $fname
	message_status 1 "done"
}


function generate_patch_for_config24 ()
{
	# Generate a patch for the config file
	# Syntax: generate_patch_for_config
	#	package_root, kernel_root
	# Author: mlindner
	# Returns:
	#       N/A
	fname="Generate Config.in patch"
	echo -n $fname
	message_status 3 "working"
	local packagedir="$1"
	local kerneldir=$2
	local startline
	local totalline
	local splitline
	local count=0
	local splt=0
	local A="`echo | tr '\012' '\001' `"

	# find the first line of the sk block
	startline=`grep "CONFIG_SK98LIN " $kerneldir/drivers/net/Config.in -n | cut -d ':' -f 1`
	totalline=`cat $kerneldir/drivers/net/Config.in | wc -l`


	((startline=$startline - 1))
	((splitline=$totalline - $startline))
	((splitline=$splitline - 1))
	head -n $startline $kerneldir/drivers/net/Config.in > ${TMP_DIR}/Config.in

	# Insert a new description
	echo "dep_tristate 'Marvell Yukon Chipset / SysKonnect SK-98xx Support' CONFIG_SK98LIN \$CONFIG_PCI" >> ${TMP_DIR}/Config.in
	echo 'if [ "$CONFIG_SK98LIN" != "n" ]; then' >> ${TMP_DIR}/Config.in
	echo "	bool '    Use Rx polling (NAPI)' CONFIG_SK98LIN_NAPI" >> ${TMP_DIR}/Config.in
	echo "fi" >> ${TMP_DIR}/Config.in

	tail -n $splitline $kerneldir/drivers/net/Config.in > ${TMP_DIR}/Config.intemp

	# find the end of the block	
	while read line; do
		((count=$count + 1))
		splt=`echo $line | grep "^dep_tristate"  -c`
		if [ $splt -gt 0 ]; then break; fi
	done < ${TMP_DIR}/Config.intemp
	((count=$count - 1))
	((splitline=$splitline - $count))
	tail -n $splitline $kerneldir/drivers/net/Config.in >> ${TMP_DIR}/Config.in

	# Make diff
	diff -ruN $kerneldir/drivers/net/Config.in ${TMP_DIR}/Config.in \
		> ${TMP_DIR}/all_sources_patch
	replacement="linux-new/drivers/net"
	sed -e "s$A${TMP_DIR}$A$replacement$A" \
		${TMP_DIR}/all_sources_patch &> ${TMP_DIR}/all_sources_patch2
	replacement="linux"
	sed -e "s$A$kerneldir$A$replacement$A" \
		${TMP_DIR}/all_sources_patch2 &> ${TMP_DIR}/all_sources_patch

	# Complete the patch
	if [ -f ${TMP_DIR}/all_sources_patch ] && \
		[ `cat ${TMP_DIR}/all_sources_patch | wc -c` -gt 0 ]; then
		echo "diff -ruN linux/drivers/net/Config.in \
linux-new/drivers/net/Config.in" >> ${PATCH_NAME}
		cat ${TMP_DIR}/all_sources_patch >> ${PATCH_NAME}
	fi


	# Status
	echo -en "\015"
	echo -n $fname
	message_status 1 "done"
}


function generate_patch_for_kconfig26 ()
{
	# Generate a patch for the config file (kernel 2.6.x)
	# Syntax: generate_patch_for_kconfig26
	#	package_root, kernel_root
	# Author: mlindner
	# Returns:
	#       N/A
	fname="Generate Kconfig patch"
	echo -n $fname
	message_status 3 "working"

	local packagedir="$1"
	local kerneldir=$2
	local startline
	local totalline
	local splitline
	local count=0
	local splt=0
	local A="`echo | tr '\012' '\001' `"

	# find the first line of the sk block
	startline=`grep "SK98LIN$" $kerneldir/drivers/net/Kconfig -n | cut -d ':' -f 1`
	totalline=`cat $kerneldir/drivers/net/Kconfig | wc -l`
	((startline=$startline - 1))
	((splitline=$totalline - $startline))
	((splitline=$splitline - 2))
	head -n $startline $kerneldir/drivers/net/Kconfig > ${TMP_DIR}/Kconfig
	cat $packagedir/misc/Kconfig >> ${TMP_DIR}/Kconfig
	tail -n $splitline $kerneldir/drivers/net/Kconfig > ${TMP_DIR}/Kconfigtemp

	# find the end of the block	
	while read line; do
		((count=$count + 1))
		splt=`echo $line | grep "^config"  -c`
		if [ $splt -gt 0 ]; then break; fi
	done < ${TMP_DIR}/Kconfigtemp
	((count=$count - 2))
	((splitline=$splitline - $count))
	tail -n $splitline $kerneldir/drivers/net/Kconfig >> ${TMP_DIR}/Kconfig

	# Make diff
	diff -ruN $kerneldir/drivers/net/Kconfig ${TMP_DIR}/Kconfig \
		> ${TMP_DIR}/all_sources_patch
	replacement="linux-new/drivers/net"
	sed -e "s$A${TMP_DIR}$A$replacement$A" \
		${TMP_DIR}/all_sources_patch &> ${TMP_DIR}/all_sources_patch2
	replacement="linux"
	sed -e "s$A$kerneldir$A$replacement$A" \
		${TMP_DIR}/all_sources_patch2 &> ${TMP_DIR}/all_sources_patch


	# Complete the patch
	echo "diff -ruN linux/drivers/net/Kconfig \
linux-new/drivers/net/Kconfig" >> ${PATCH_NAME}
	cat ${TMP_DIR}/all_sources_patch >> ${PATCH_NAME}

	# Status
	echo -en "\015"
	echo -n $fname
	message_status 1 "done"
}


function generate_patch_for_readme ()
{
	# Generate a patch for the readme file
	# Syntax: generate_patch_for_readme
	#	package_root, kernel_root
	# Author: mlindner
	# Returns:
	#       N/A

	fname="Generate readme patch"
	echo -n $fname
	message_status 3 "working"
	local packagedir="$1/all"
	local kerneldir=$2
	local replacement
	local A="`echo | tr '\012' '\001' `"

	# initial cleanup
	rm -rf ${TMP_DIR}/all_sources_patch

	# Make diff
	diff -ruN $kerneldir/Documentation/networking/sk98lin.txt $packagedir/sk98lin.txt \
		> ${TMP_DIR}/all_sources_patch
	replacement="linux-new/drivers/net/sk98lin"
	sed -e "s$A$packagedir$A$replacement$A" \
		${TMP_DIR}/all_sources_patch &> ${TMP_DIR}/all_sources_patch2
	replacement="linux"
	sed -e "s$A$kerneldir$A$replacement$A" \
		${TMP_DIR}/all_sources_patch2 &> ${TMP_DIR}/all_sources_patch


	# Complete the patch
	
	if [ -f ${TMP_DIR}/all_sources_patch ] && \
		[ `cat ${TMP_DIR}/all_sources_patch | wc -c` -gt 0 ]; then
		echo "diff -ruN linux/Documentation/networking/sk98lin.txt \
linux-new/Documentation/networking/sk98lin.txt" >> ${PATCH_NAME}
		cat ${TMP_DIR}/all_sources_patch >> ${PATCH_NAME}
	fi

	# Status
	echo -en "\015"
	echo -n $fname
	message_status 1 "done"
}

function generate_patch_file ()
{
	# Generate a patch for a specific kernel version
	# Syntax: generate_patch_file
	#	package_root, kernel_root
	# Author: mlindner
	# Returns:
	#       N/A

	fname="Kernel version"
	echo -n $fname
	message_status 1 "${KERNEL_VERSION}"

	fname="Driver version"
	echo -n $fname
	message_status 1 "$DRIVER_VERSION"

	fname="Release date"
	echo -n $fname
	message_status 1 "$DRIVER_REL_DATE"

	# Check if some kernel functions are available
	check_kernel_functions

	fname="Generate driver patches"
	echo -n $fname
	message_status 3 "working"
	local packagedir="$1/all"
	local kerneldir=$2
	local replacement
	local line=`echo "-x '\*.\[o4\]' -x '.\*' -x '\*.ko' -x '\*.txt' -x '\*.htm\*' "`
	local A="`echo | tr '\012' '\001' `"

	diff -ruN -x "*.[o4]" -x ".*" -x "*.ko" -x "*.txt" -x "*.htm*" \
		$kerneldir/drivers/net/sk98lin $packagedir > ${TMP_DIR}/all_sources_patch
	replacement="linux-new/drivers/net/sk98lin"
	sed -e "s$A$packagedir$A$replacement$A" \
		${TMP_DIR}/all_sources_patch &> ${TMP_DIR}/all_sources_patch2
	replacement="linux"
	sed -e "s$A$kerneldir$A$replacement$A" \
		${TMP_DIR}/all_sources_patch2 &> ${TMP_DIR}/all_sources_patch
	replacement=`echo ""`
	sed -e "s$A$line$A$A" \
		${TMP_DIR}/all_sources_patch &> ${PATCH_NAME}

	# Status
	echo -en "\015"
	echo -n $fname
	message_status 1 "done"
}


function patch_generation ()
{
	# Generate a patch for a specific kernel version
	# Syntax: patch_generation
	# Author: mlindner
	# Returns:
	#       N/A

	# Check system
	check_system_for_patch

	# Generate safe tmp dir
	make_safe_tmp_dir

	# Create tmp dir and unpack the driver
	unpack_driver
	clear

	# Get user infos
	get_patch_infos

	# Copy files
	cp -pr ${TMP_DIR}/common/* ${TMP_DIR}/all
	cp -pr ${TMP_DIR}/${KERNEL_FAMILY}/* ${TMP_DIR}/all

	# Create makefile
	[ $KERNEL_FAMILY == "2.4" ] && create_makefile_24 0
	[ $KERNEL_FAMILY == "2.6" ] && create_makefile_26 0
	clear

	# Generate a patch for a specific kernel version
	generate_patch_file ${TMP_DIR} $KERNEL_SOURCE

	# Generate a patch for the readme file
	generate_patch_for_readme ${TMP_DIR} $KERNEL_SOURCE

	# Generate a patch for the config file
	if [ "${KERNEL_FAMILY}" == "2.4" ]; then
		generate_patch_for_config24 ${TMP_DIR} $KERNEL_SOURCE
	else
		generate_patch_for_kconfig26 ${TMP_DIR} $KERNEL_SOURCE
	fi

	# Generate a patch for the config file
	if [ "${KERNEL_FAMILY}" == "2.4" ]; then
		generate_patch_for_help24 ${TMP_DIR} $KERNEL_SOURCE
	fi

	# Clear the tmp dirs
	clean

	if [ ! -f ${PATCH_NAME} ] || \
		[ `cat ${PATCH_NAME} | wc -c` == 0 ]; then
		rm -rf ${PATCH_NAME}
		echo
		echo "Patch not generated."
		echo "The sources already installed on the system in the directory "
		echo "     $KERNEL_SOURCE"
		echo "are equal to the sources from the install package."
		echo "This implies that it makes not sense to create the patch, "
		echo "because it'll be of size zero!"
		echo "Don't worry, this is not a failure. It just means, that you"
		echo "already use the latest driver version." 
		echo 
		echo "                                                     Have fun..."

		exit
		
	else
		echo
		echo "All done. Patch successfully generated."
		echo "To apply the patch to the system, proceed as follows:"
		echo "      # cd $KERNEL_SOURCE"
		echo "      # cat ${PATCH_NAME} | patch -p1"
		echo 
		echo "                                                     Have fun..."
		exit
	fi
}



#################################################################
# Main functions
#################################################################
function start_sequence ()
{
	# Print copyright informations, mode selection and check
	# Syntax: start_sequence
	# Author: mlindner
	# Returns:
	#       N/A

	# Start. Choose a installation method and check method
	echo 
	echo "Installation script for $drv_name driver."
	echo "Version $VERSION"
	echo "(C)Copyright 2003-2004 Marvell(R)."
	echo "===================================================="
	echo "Add to your trouble-report the logfile install.log"
	echo "which is located in the  DriverInstall directory."
	echo "===================================================="
	echo 

	# Silent option. Return...
	[ "$OPTION_SILENT" ] && return
	[ "$INSTALL_AUTO" ] && patch_generation


	PS3='Choose your favorite installation method: ' # Sets the prompt string.

	echo

	select user_sel in "user installation" "expert installation" "generate patch" "exit"
	do
		break  # if no 'break' here, keeps looping forever.
	done

	if [ "$user_sel" == "exit" ]; then
		echo "Exit."
		exit
	fi

	if [ "$user_sel" != "user installation" ] && [ "$user_sel" != "expert installation" ] && [ "$user_sel" != "generate patch" ]; then
		echo "Exit."
		exit
	fi

	clear

	if [ "$user_sel" == "user installation" ]; then
		echo "Please read this carfully!"
		echo
		echo "This script will automatically compile and load the $drv_name"
		echo "driver on your host system. Before performing both compilation"
		echo "and loading, it is necessary to shutdown any device using the" 
		echo "$drv_name kernel module and to unload the old $drv_name kernel "
		echo "module. This script will do this automatically per default."
		echo "If you want to shutdown and unload the old $drv_name kernel module"
		echo "manually, run the script in the EXPERT mode."
		echo " "
		echo "Please plug a card into your machine. Without a card we aren't"
		echo "able to check the full driver functionality."
		echo
		echo -n "Do you want proceed? (y/N) "

		old_tty_settings=$(stty -g)		# Save old settings.
		stty -icanon
		Keypress=$(head -c1)
		stty "$old_tty_settings"			# Restore old terminal settings.
		echo "+++ Install mode: User" >> $logfile 2>&1
		echo "+++ Driver version: $VERSION" >> $logfile 2>&1

		if [ "$Keypress" == "Y" ]
		then
			clear
		else
			if [ "$Keypress" == "y" ]
			then
				clear
			else
				echo "Exit"
				clean
				exit 0
			fi
		fi
		
		export REMOVE_SKDEVICE=1

	else
		if [ "$user_sel" == "expert installation" ]; then
			INSTALL_MODE="INSTALL"
			echo "+++ Install mode: Expert" >> $logfile 2>&1
			clear
		else
			clear
			INSTALL_MODE="PATCH"
			patch_generation
		fi
	fi
}

function main_global ()
{
	# Main function
	# Syntax: patch_generation
	# Author: mlindner
	# Returns:
	#       N/A

	# Extract all given parameters
	extract_params $*

	# Run given functions
	if [ "${OPTION_HELP}" ]; then help; fi
	if [ "${OPTION_SILENT}" ]; then user_sel=`echo user`; fi
	if [ "${OPTION_CLEANUP}" ]; then clean; exit 0; fi
	if [ "${OPTION_PATCH}" ]; then
		INSTALL_MODE="PATCH"
		INSTALL_AUTO=1
		KERNEL_SOURCE=$2
		if [ `echo $3 | grep -c "/"` gt 0 ]; then
			PATCH_NAME=$3
		else
			PATCH_NAME=${working_dir}/$3
		fi
	fi

	# Print copyright informations, mode selection and check
	start_sequence

	# Generate safe tmp dir
	make_safe_tmp_dir

	# Check user informations and tools availability
	check_user_and_tools

	# Check kernel and module informations
	check_kernel_informations

	# Create tmp dir and unpack the driver
	unpack_driver

	# Create makefile
	[ $KERNEL_FAMILY == "2.4" ] && create_makefile_24 1
	[ $KERNEL_FAMILY == "2.6" ] && create_makefile_26 1

	# Check config files
	generate_config

	# Check and generate a correct version.h file
	generate_sources_version

	# Check if some kernel functions are available
	check_kernel_functions


	# Configure, check and build the driver
	[ $KERNEL_FAMILY == "2.4" ] && make_driver_24
	[ $KERNEL_FAMILY == "2.6" ] && make_driver_26 1

	# Copy driver
	copy_driver

}


# Start
#####################################################################

drv_name=`echo sk98lin`
VERSION=`echo "7.06 (Aug-20-2004)"`
#drv_name=`echo sk98lin`
working_dir=`pwd`
logfile="$working_dir/install.log"
rm -rf $logfile &> /dev/null
trap cleanup_trap INT TERM
KERNEL_TREE_MAKE=0;
clear

# Run main function
main_global $*

# Exit
exit 0

