#!/bin/bash

#/*******************************************************************
# * This file is part of the Emulex Linux Device Driver for         *
# * Fibre Channel Host Bus Adapters.                                *
# * Copyright (C) 2003-2006 Emulex.  All rights reserved.           *
# * EMULEX and SLI are trademarks of Emulex.                        *
# * www.emulex.com                                                  *
# *                                                                 *
# * This program is free software; you can redistribute it and/or   *
# * modify it under the terms of version 2 of the GNU General       *
# * Public License as published by the Free Software Foundation.    *
# * This program is distributed in the hope that it will be useful. *
# * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
# * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
# * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
# * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
# * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
# * more details, a copy of which can be found in the file COPYING  *
# * included with this package.                                     *
# *******************************************************************/
######################################################################
#
# install script for Emulex Linux Fibre Channel Driver RPMs
#
INSTALLER_VERSION='$Id: lpfc-install 2906 2006-04-13 18:19:18Z sf_support $'
INSTALLER_VERSION=`echo ${INSTALLER_VERSION} | perl -pe '/\s+([\d\.]*)\s+/;$_="$1\n"'`

# Exit codes:
#   0   Success.
#   1   Unable to determine distribution type.
#   2   Unknown error.
#   5   Invalid command line parameter.
#   6   The Multipulse kit must be removed prior to the installation
#        of the LPFC driver kit.
#  10   Failure uninstalling old driver.
#  12   Other package(s) depend(s) upon packages to be removed.
#  13   The Multipulse kit must be removed prior to the removal of the
#        LPFC driver kit.
#  14   Package revision mismatch errors.
#  15   One or more Emulex Linux LPFC packages already installed.
#  20   Success, system requires reboot to complete installation.
#  25   Success, system requires reboot to complete uninstallation.
#  30   Error installing ramdisk image to LILO configuration.
#  40   Error creating initial ramdisk to load Emulex driver during boot.
#  47   Error creating initial ramdisk.
#  50   Error installing lpfcdriver RPM.
#  56   Error loading lpfc module.
#  60   Kernel source is not installed, scripted RPM cannot continue.
#  70   Compilers are not installed, scripted RPM cannot continue.
#  75   Neither kernel source nor compilers are installed, RPM cannot
#        continue.
# 125   Unable to back up old Emulex driver.
# 127   Unable to uninstall old Emulex driver.
# 130   Error backing up /etc/modprobe.conf.
# 140   Error updating /etc/modprobe.conf.
# 150   Error parsing awk output when unloading driver.
# 255   Error determining script command.

DRIVER_NAME=lpfc
DFCDRIVER_NAME=lpfcdfc
SLES_DRIVER_NAME=lpfcdd
OLD_RPM_BASENAME=${DRIVER_NAME}driver
RPM_BASENAME=${DRIVER_NAME}driver_2.6
RPM_DKMS_BASENAME=${DRIVER_NAME}driver_2.6_dkms
MULTIPULSE_RPM_BASENAME=lpfc_2.6_mpl_module
DFCRPM_BASENAME=lpfc_2.6_ioctl_module
DFCRPM_INBOX_BASENAME=lpfc_2.6_ioctl_inbox
DFCRPM_DKMS_BASENAME=lpfc_2.6_ioctl_module_dkms
DRIVER_VERSION=8.0.16.27
NEW_DFCDRIVER_VERSION=2.0.15
DRIVER_DESCRIPTION="LPFC Driver source RPM"
SCRIPT_RPM_RELEASE=1
INSTALLDIR="/usr/src/lpfc"
SAVEDFILESDIR="/usr/src/lpfc/savedfiles"

DRIVER_DIR=.
INSTALL_SCRIPT=$0

let MAX_LUNS=256
MODPROBE_CONF_ENTRY="options scsi_mod"
MODPROBE_CONF_LUNS="max_luns=${MAX_LUNS}"

MODPROBE_CONF_BACKUP=/etc/modprobe.elx
MODPROBE_CONF_TEMP=/etc/modprobe.conf.elxinstall
MODPROBE_CONF_TEMP2=/etc/modprobe.conf.elxinstall2
KERNEL_CONF_BACKUP=/etc/sysconfig/kernel.elx
KERNEL_CONF_TEMP=/etc/sysconfig/kernel.elxinstall

GENERIC_MESSAGE="Please contact Emulex Technical Support"
HELP_MESSAGE="Please execute '$0 --help' for usage information."

let NEED_SOURCE_PACKAGE=0
let NEED_GCC_PACKAGE=0
let DRIVER_INSTALLED=0

exec_command()
{
    local TEMPFILE
    RETURNVALUE=0
    TEMPFILE=`mktemp /tmp/elx-lpfc-install.XXXXXX`
    if [ "$2" = background ] ; then
	(eval $1 ; echo "RETURNVALUE=$?" >> ${TEMPFILE}) &
	while [ -e ${TEMPFILE} ] && [ ! -s ${TEMPFILE} ] ; do
	    sleep 3
	    echo -en "."
	done
	. ${TEMPFILE}
	rm -f ${TEMPFILE}
    else
	eval $1
	RETURNVALUE=$?
    fi
    echo -en "\n"
    return ${RETURNVALUE}
}

get_distribution ()
{
    ARCH=$(uname -m | sed "s/i686/i386/")
    KERNEL=$(rpm -qf /lib/modules/$(uname -r) --qf "%{VERSION}_%{RELEASE}\n")
    UNAME=$(uname -r)

    if [ -f /etc/asianux-release ] ; then
	# this is an Asianux install
	DISTRIBUTION=asianux
	AX_VERSION=$(rpm -qf /etc/asianux-release --qf "%{VERSION}" | sed "s/[^0-9\.]//g")
	RELEASE=asianux${AX_VERSION}_${KERNEL}
	DRIVER_RPM=${RPM_BASENAME}-${DRIVER_VERSION}-${SCRIPT_RPM_RELEASE}.noarch.rpm
	BOOT_FILE=/etc/rc.d/rc.local
	MESSAGESFILE="/var/log/messages"
	if [ ${ARCH} = "ia64" ] ; then
	    KERNEL_IMAGE_PATH="/boot/efi/efi/asianux/vmlinuz-${UNAME}"
	else
	    KERNEL_IMAGE_PATH="/boot/vmlinuz-${UNAME}"
	fi
	return 0
    elif [ -f /etc/redhat-release ] ; then
        # this is a Red Hat install
	DISTRIBUTION=redhat
        RH_VERSION=$(rpm -qf /etc/redhat-release --qf "%{VERSION}" | sed "s/[^0-9\.]//g")
        RELEASE=rhel${RH_VERSION}_${KERNEL}
        DRIVER_RPM=${RPM_BASENAME}-${DRIVER_VERSION}-${SCRIPT_RPM_RELEASE}.noarch.rpm
	BOOT_FILE=/etc/rc.d/rc.local
	MESSAGESFILE="/var/log/messages"
	if [ ${ARCH} = "ia64" ] ; then
	    KERNEL_IMAGE_PATH="/boot/efi/efi/redhat/vmlinuz-${UNAME}"
	else
	    KERNEL_IMAGE_PATH="/boot/vmlinuz-${UNAME}"
	fi
	return 0
    elif [ -f /etc/SuSE-release ]; then
        # this is a Suse install
	DISTRIBUTION=suse
        SUSE_VERSION=$(rpm -qf /etc/SuSE-release --qf "%{VERSION}" | sed "s/[^0-9\.]//g")
        RELEASE=sles${SUSE_VERSION}_${KERNEL}
        DRIVER_RPM=${RPM_BASENAME}-${DRIVER_VERSION}-${SCRIPT_RPM_RELEASE}.noarch.rpm
	BOOT_FILE=/etc/rc.d/boot.local
	MESSAGESFILE="/var/log/messages /var/log/warn"
	if [ ${ARCH} = "ppc64" ] ; then
	    SLES_KERNEL_IMAGE=vmlinux
	    KERNEL_IMAGE_PATH="/boot/vmlinux"
	else
	    SLES_KERNEL_IMAGE=vmlinuz
	    KERNEL_IMAGE_PATH="/boot/vmlinuz-${UNAME}"
	fi
	return 0
    else
        echo ""
        echo "Unable to determine distribution type"
        return 1
    fi
}

# Function:  num_adapters()
#
# Description:
#   Determine the number of adapters installed on this system.  Dual
#   channel adapters will be reported as the number of channels on the
#   adapter.
#
# Parameters:
#   none.
#
# Returns:
#   The number of adapters installed on this system.
num_adapters()
{
    local NUM_ADAPTERS
    local TEMPFILE
    let NUM_ADAPTERS=0
    TEMPFILE=`mktemp /tmp/elx-lpfc-install-pciids.XXXXXX`

    # First, create a temp file with the PCI IDs of the adapters
    # supported by this driver.
    echo -n "10df  Emulex Corporation" > ${TEMPFILE}
    echo -n "\t1ae5  LP6000 Fibre Channel Host Adapter" >> ${TEMPFILE}
    echo -n "\tf085  LP850 Fibre Channel Adapter" >> ${TEMPFILE}
    echo -n "\tf095  LP952 Fibre Channel Adapter" >> ${TEMPFILE}
    echo -n "\tf098  LP982 Fibre Channel Adapter" >> ${TEMPFILE}
    echo -n "\tf0a1  LP101 Fibre Channel Adapter" >> ${TEMPFILE}
    echo -n "\tf0a5  LP1050 Fibre Channel Adapter" >> ${TEMPFILE}
    echo -n "\tf700  LP7000 Fibre Channel Host Adapter" >> ${TEMPFILE}
    echo -n "\tf800  LP8000 Fibre Channel Host Adapter" >> ${TEMPFILE}
    echo -n "\tf900  LP9000 Fibre Channel Host Adapter" >> ${TEMPFILE}
    echo -n "\tf980  LP9802 Fibre Channel Adapter" >> ${TEMPFILE}
    echo -n "\tfa00  LP10000 Fibre Channel Adapter" >> ${TEMPFILE}
    echo -n "\tfb00  LPx1000 Fibre Channel Adapter" >> ${TEMPFILE}
    echo -n "\tfd00  LP11000 Fibre Channel Adapter" >> ${TEMPFILE}
    echo -n "\tf0d5  LP1150 Fibre Channel Adapter" >> ${TEMPFILE}
    echo -n "\tf0d1  LP111 Fibre Channel Adapter" >> ${TEMPFILE}
    echo -n "\tfe00  LP11000e Fibre Channel Adapter" >> ${TEMPFILE}
    echo -n "\tf0e5  LP1150e Fibre Channel Adapter" >> ${TEMPFILE}

    # Now, execute lspci to determine the number of adapters in the
    # system.
    let NUM_ADAPTERS=$((`/sbin/lspci -d 10df: -i ${TEMPFILE} | wc -l`))

    # Remove the tempfile, since it is no longer needed.
    rm -f ${TEMPFILE}

    return ${NUM_ADAPTERS}
}

# Function:  check_for_driver_kit()
#
# Description:
#   Verifies that a version of the Emulex Linux LPFC driver kit is not
#   already installed.
#
# Parameters:
#   none.
#
# Returns:
#   0 - no driver kit is installed.
#   1 - a driver kit is already installed.
#   2 - this version of the driver kits is already installed.
check_for_driver_kit()
{
    local INSTALLEDVERSION
    local retval
    local message
    let message=0

    # Check for the 'lpfcdriver' package.
    INSTALLEDVERSION=$(rpm -q --qf %{VERSION} ${OLD_RPM_BASENAME} 2>/dev/null)
    if [ $? -eq 0 ] ; then
	echo "Version ${INSTALLEDVERSION} of the ${OLD_RPM_BASENAME} package is currently installed."
	let message=$((${message} | 8))
	let retval=1
    fi

    # Check for the 'lpfcdriver_2.6' package.
    INSTALLEDVERSION=$(rpm -q --qf %{VERSION} ${RPM_BASENAME} 2>/dev/null)
    if [ $? -eq 0 ] ; then
	if [ ${INSTALLEDVERSION} = ${DRIVER_VERSION} ] ; then
	    echo "Version ${DRIVER_VERSION} of the ${RPM_BASENAME} package is currently installed."
	    let retval=2
	else
	    echo "Version ${INSTALLEDVERSION} of the ${RPM_BASENAME} package is currently installed."
	    let local major=$(echo ${INSTALLEDVERSION} | sed 's/^\([[:digit:]]*\)\..*/\1/g')
	    if [ ${major} -lt 7 ] ; then
		let message=$((${message} | 4))
	    else
		let message=$((${message} | 8))
	    fi
	    let retval=1
	fi
    fi

    # Print all appropriate messages.
    if [ $((${message} & 1)) -ne 0 ] ; then
	echo -e "Please uninstall by running the lpfc-install script"
	echo -e "before continuing to install any new driver kits."
    elif [ $((${message} & 2)) -ne 0 ] ; then
	echo "Please uninstall by running '$0 --uninstall'."
    elif [ $((${message} & 4)) -ne 0 ] ; then
	    echo "Please uninstall this package using the lpfc-install"
	    echo "script that was used to install that version of the Emulex"
	    echo "Linux LPFC driver kit."
    elif [ $((${message} & 8)) -ne 0 ] ; then
             echo "Please uninstall the ${RPM_BASENAME} driver by using the lpfc-install"
             echo "script contained in the ${INSTALLEDVERSION} package."
             if [ -e ${INSTALLDIR}/lpfc-install ] ; then
                 echo "A copy of the lpfc-install script can be found in ${INSTALLDIR}."
                 echo "Please follow the proper uninstall procedure as described"
                 echo "in the LPFC driver manual."
             fi
    fi

    return ${retval}
}

# Function:  check_for_driver_module()
#
# Description:
#   Determines if this rev's Emulex Linux LPFC module is already installed.
#
# Parameters:
#   none.
#
# Returns:
#   0 - lpfc RPM is installed and all version checking matches.
#   1 - There is a problem with the lpfc RPM.
#   2 - No lpfc RPM is installed.
#   3 - The lpfc driver RPM does not match this revision.
#   4 - A valid lpfc.ko module does not exist in /lib/modules/${UNAME}.
#   5 - The lpfc.ko module does not exist in /lib/modules/${UNAME}.
#   6 - An lpfc.ko module other than ${DRIVER_VERSION} exists in /lib/modules.


check_for_driver_module()
{
    local COMMAND


    # Is lpfcdriver_2.6 module or lpfcdriver_2.6 dkms module installed?
    rpm -q ${RPM_BASENAME} 2>/dev/null 1>/dev/null
    if [ $? -eq 0 ] ; then
	LPFC_INSTALLEDVERSION=$(rpm -q --qf %{VERSION} ${RPM_BASENAME} 2>/dev/null)
	if [ $? -ne 0 ] ; then
	    log_message "WARNING: Cannot get version of ${RPM_BASENAME}."
	    return 1
	fi
	INSTALLEDPACKAGE=${RPM_BASENAME}
    else
	rpm -q ${RPM_DKMS_BASENAME} 2>/dev/null 1>/dev/null
	if [ $? -ne 0 ] ; then
            # No:  Indicate that no package has been installed.
	    INSTALLEDPACKAGE=none
	else
	    LPFC_INSTALLEDVERSION=$(rpm -q --qf %{VERSION} ${RPM_DKMS_BASENAME} 2>/dev/null)
	    if [ $? -ne 0 ] ; then
		log_message "WARNING: Cannot get version of ${RPM_DKMS_BASENAME}."
	        return 1
	    fi
	    INSTALLEDPACKAGE=${RPM_DKMS_BASENAME}
	fi
    fi

    if [ ${INSTALLEDPACKAGE} == "none" ] ; then
	# No LPFC driver installed for this kernel.
	return 2
    fi

    # Do the RPM version and release numbers match what we want?
    if [ ${LPFC_INSTALLEDVERSION} != ${DRIVER_VERSION} ] ; then
	return 3
    fi


    # Does lpfc.ko exist in /lib/modules/$(uname -r)?

    COMMAND="find /lib/modules/${UNAME} -type f -name ${DRIVER_NAME}.ko -o -type f -name ${SLES_DRIVER_NAME}.ko"
    LPFC_MODULEPATH=$(${COMMAND})

    if [ $? -ne 0 ] ; then
	# Error attempting to find lpfc.ko in /lib/modules/$(uname -r).
	echo "WARNING: Error attempting to find ${DRIVER_NAME}.ko in /lib/modules/${UNAME}."
	return 4
    elif [ $(${COMMAND} | wc -l) -eq 0 ] ; then
        # No LPFC driver installed for this kernel.
	echo "WARNING: ${DRIVER_NAME}.ko was not found in /lib/modules/${UNAME}."
	return 5
    elif [ $(${COMMAND} | wc -l) -ne 1 ] ; then
	# Multiple lpfc.ko modules exist in the module path.
	echo "WARNING: Multiple ${DRIVER_NAME}.ko were found in /lib/modules/${UNAME}."
    fi

    # Is lpfc.ko the correct version?
    LPFC_MODULE_STRING="Emulex LightPulse Fibre Channel SCSI driver"
    LPFC_MODULEVERSION=$(strings ${LPFC_MODULEPATH} | grep -e "^${LPFC_MODULE_STRING}" | sed "s/^${LPFC_MODULE_STRING} \(.*\)/\1/")
    if [ "${LPFC_MODULEVERSION}" != "${DRIVER_VERSION}" ] ; then
	return 6
    fi

    return 0
}


# Function compare_versions()
# 
# Description:
#   Examines two version strings and reports which if either is greater.
#
# Parameters:
#   $1 - first version string
#   $2 - second version string
#
# Returns:
#   0 - strings are equal
#   1 - first is greater than second
#   2 - second is greater than first
compare_versions()
{
    local VERSION1
    local VERSION2
    local INDEX
    local RESULT
    local FINISHED

    INDEX=1
    let RESULT=0
    FINISHED=0
    VERSION1=$(echo ${1} | sed 's/^\([[:digit:].]*\)[^0-9\.].*/\1/')
    VERSION2=$(echo ${2} | sed 's/^\([[:digit:].]*\)[^0-9\.].*/\1/')
    while [ ${FINISHED} -eq 0 ] ; do
	PARTIALA=$(echo ${VERSION1} | awk -F "." "{ print \$${INDEX}; }")
	PARTIALB=$(echo ${VERSION2} | awk -F "." "{ print \$${INDEX}; }")
	if [ -z "${PARTIALA}" ] && [ -z "${PARTIALB}" ] ; then
	    let RESULT=0
	    let FINISHED=1
	elif [ -z "${PARTIALA}" ] ; then
	    let RESULT=2
	    let FINISHED=1
	elif [ -z "${PARTIALB}" ] ; then
	    let RESULT=1
	    let FINISHED=1
	elif [ ${PARTIALB} -gt ${PARTIALA} ] ; then
	    let RESULT=2
	    let FINISHED=1
	elif [ ${PARTIALA} -gt ${PARTIALB} ] ; then
	    let RESULT=1
	    let FINISHED=1
	fi
	let INDEX=$((${INDEX}+1))
    done
    return ${RESULT}
}

# Function:  check_for_lpfcdfc_driver_mod()
#
# Description:
#   Verifies that a version of the Emulex Linux LPFC Application Helper 
#   Module (LPFCDFC) is not already installed.
#
# Parameters:
#   none.
#
# Returns:
#   0 - no LPFCDFC module is installed.
#   1 - an LPFCDFC module that matches this lpfc driver is already 
#       installed.
#   2 - an LPFCDFC module that DOES NOT match this lpfc driver, and is
#       part of an apps kit is already installed
#   3 - an LPFCDFC module that DOES NOT match this lpfc driver, and is
#        NOT part of an apps kit is already installed.
#   4 - Error accessing driver module RPMs.
check_for_lpfcdfc_driver_mod()
{

INSTALLEDPACKAGE=none

    # Is lpfc_2.6_ioctl_module or lpfc_2.6_ioctl_module_dkms installed?
    rpm -q ${DFCRPM_BASENAME} 2>/dev/null 1>/dev/null
    if [ $? -eq 0 ] ; then
	INSTALLEDVERSION=$(rpm -q --qf %{VERSION} ${DFCRPM_BASENAME} 2>/dev/null)
	if [ $? -ne 0 ] ; then
	    log_message "FATAL ERROR - cannot get version of ${DFCRPM_BASENAME}."
	    return 4
	fi
	INSTALLEDPACKAGE=${DFCRPM_BASENAME}
    fi
    rpm -q ${DFCRPM_DKMS_BASENAME} 2>/dev/null 1>/dev/null
    if [ $? -eq 0 ] ; then
	INSTALLEDVERSION=$(rpm -q --qf %{VERSION} ${DFCRPM_DKMS_BASENAME} 2>/dev/null)
	if [ $? -ne 0 ] ; then
	    log_message "FATAL ERROR - cannot get version of ${DFCRPM_DKMS_BASENAME}."
	    return 4
	fi
	INSTALLEDPACKAGE=${DFCRPM_DKMS_BASENAME}
    fi
    rpm -q ${DFCRPM_INBOX_BASENAME} 2>/dev/null 1>/dev/null
    if [ $? -eq 0 ] ; then
	INSTALLEDVERSION=$(rpm -q --qf %{VERSION} ${DFCRPM_INBOX_BASENAME} 2>/dev/null)
	if [ $? -ne 0 ] ; then
	    log_message "FATAL ERROR - cannot get version of ${DFCRPM_INBOX_BASENAME}."
	    return 4
	fi
	INSTALLEDPACKAGE=${DFCRPM_INBOX_BASENAME}
    fi

    if [ ${INSTALLEDPACKAGE} != "none" ] ; then
        # Do the RPM version and release numbers match what we want?
	compare_versions ${INSTALLEDVERSION} ${NEW_DFCDRIVER_VERSION}
	case "$?" in
	    0)  # Installed version is equal to LPFCDFC cutoff version.
		return 1 ;;
	    1)  # Installed version is greater than or equal to
		# LPFCDFC cutoff version.
		return 2 ;;
	    2)  # Installed version is less than LPFCDFC cutoff version
	        return 3 ;;
	esac
    fi

    return 0;
}

# Function:  backup_file_to_savedfiles()
#
# Description:
#   Move each file passed as a parameter to the directory specified by
#   the SAVEDFILESDIR shell variable, preserving the original path
#   information under the SAVEDFILESDIR directory.
#
# Parameters:
#   A list of filenames to save.
#
# Returns a bit pattern with the following values:
#   0 on success.
#   1 if the ${SAVEDFILESDIR} does not exist and cannot be created.
#   2 if one or more files could not be saved to ${SAVEDFILESDIR}.
#   4 if one or more original files could not be removed after they were saved.
backup_file_to_savedfiles()
{
    local i
    local RETURNVALUE
    let RETURNVALUE=0

    if [ ! -d ${SAVEDFILESDIR} ] ; then
	mkdir -p ${SAVEDFILESDIR}
	if [ $? -ne 0 ] ; then
	    echo "Error creating ${SAVEDFILESDIR}!"
	    return 1
	fi
    fi

    for i in $@ ; do
	cp --parents $i ${SAVEDFILESDIR}
	if [ $? -ne 0 ] ; then
	    echo "Error copying $i to a safe location!"
	    let RETURNVALUE=$((${RETURNVALUE} | 2))
	fi
	rm -f $i
	if [ $? -ne 0 ] ; then
	    echo "Error removing $i after backup!"
	    let RETURNVALUE=$((${RETURNVALUE} | 4))
	fi
    done

    return ${RETURNVALUE}
}

# Function:  restore_files_from_savedfiles()
#
# Description:
#   Move each file passed as a parameter back to its original
#   location.
#
# Parameters:
#   A list of filenames to restore.
#
# Returns a bit pattern with the following values:
#   0 on success.
#   1 if no files are available to restore.
#   2 if one or more files could not be restored.
#   4 if one or more backup files could not be removed after they were restored.
restore_files_from_savedfiles()
{
    local DIRECTORY
    local BACKUPFILE
    local RETURNVALUE
    let RETURNVALUE=0

    # Return immediately if no files are available to be restored.
    if [ ! -d "${SAVEDFILESDIR}/$1" ] ; then
	if [ -d ${SAVEDFILESDIR} ] ; then
	    rmdir --ignore-fail-on-non-empty -p ${SAVEDFILESDIR}
	fi
	return 1
    fi

    for i in `find ${SAVEDFILESDIR}/$1 -regex "$2"` ; do
	echo -en "\n"
	BACKUPFILE=$(echo $i | sed "s|^${SAVEDFILESDIR}/||")
	DIRECTORY=$(echo ${BACKUPFILE} | sed "s/\(.*\/\)[^\/]*/\1/")
	pushd ${SAVEDFILESDIR} 2>/dev/null 1>/dev/null
	cp --parents ${BACKUPFILE} /
	if [ $? -ne 0 ] ; then
	    echo "Error restoring /${BACKUPFILE}!"
	    let RETURNVALUE=$((${RETURNVALUE} | 2))
	fi
	rm -f ${BACKUPFILE}
	if [ $? -ne 0 ] ; then
	    echo "Error removing backup file ${SAVEDFILESDIR}/${BACKUPFILE}"
	    let RETURNVALUE=$((${RETURNVALUE} | 4))
	fi
	popd 2>/dev/null 1>/dev/null
	rmdir --ignore-fail-on-non-empty -p ${SAVEDFILESDIR}/${DIRECTORY}
    done

    return ${RETURNVALUE}
}

# Function:  unload_old_drivers()
#
# Description:
#   Unload any old lpfc, lpfcdfc, and/or lpfcdd drivers that may be
#   loaded.
#
# Parameters:
#   none.
#
# Returns a bit pattern with the following values:
#   0 - all old drivers unloaded, or no old drivers were loaded.
#   1 - an error occurred while unloading one or more drivers.
#   2 - old driver is being used and cannot be unloaded.
#   4 - old driver is being referenced by another module and cannot be unloaded.
unload_old_drivers()
{
    local drivers
    local retval
    let retval=0

    echo "Checking for old Emulex driver ..."
    drivers=(${DFCDRIVER_NAME} ${DRIVER_NAME} ${SLES_DRIVER_NAME})
    for i in ${drivers[@]} ; do
	unload_driver ${i}
	case "$?" in
	    0) echo "Module '${i}' successfully unloaded." ;;
	    1) echo "An error occurred while unloading ${i}."
		let retval=$((${retval} | 1)) ;;
	    2) echo "The ${i} driver is being used and cannot be unloaded."
		let retval=$((${retval} | 2)) ;;
	    3) echo "The ${i} driver is being referenced by other"
		echo "modules and cannot be unloaded."
		let retval=$((${retval} | 4)) ;;
	    4) ;;
	    *) echo "An unknown error occurred while unloading ${i}."
		let retval=$((${retval} | 1)) ;;
	esac
    done

    return ${retval}
}

# Function:  backup_old_driver()
#
# Description:
#   Move any old drivers from the /lib/modules/${UNAME} directory to a
#   location where they will not be referenced by 'depmod -a', but
#   where they will be available if they need to be restored by the
#   '--uninstall' option to the install script.
#
# Parameters:
#   none.
#
# Returns:
#   0 on success.
backup_old_driver()
{
    # Move old copies of the driver module out of the way.
    backup_file_to_savedfiles `find /lib/modules/${UNAME}/kernel/drivers/ -regex '.*lpf[cn]\(dd\)?\.k?o'`
    if [ $? -ne 0 ] ; then
	echo "Unable to backup old drivers."
	exit 125
    fi
    backup_file_to_savedfiles `find /lib/modules/${UNAME}/kernel/drivers/ -regex '.*lpfc_[0-9]*.k?o'`
    if [ $? -ne 0 ] ; then
	echo "Unable to backup old drivers."
	exit 125
    fi

    return 0
}

# Function:  restore_old_driver()
#
# Description:
#   Move any old drivers saved by the backup_old_driver() function to
#   their original locations.
#
# Parameters:
#   none.
#
# Returns:
#   0 on success.
#   nonzero on failure.
restore_old_driver()
{
    local RETURNVALUE

    echo "Restoring old Emulex drivers..."
    restore_files_from_savedfiles "lib/modules/${UNAME}/kernel/drivers/" '.*lpf[cn]\(dd\)?\.k?o'
    let RETURNVALUE=$?
    restore_files_from_savedfiles "lib/modules/${UNAME}/kernel/drivers/" '.*lpfc_[0-9]*.k?o'
    let RETURNVALUE=$((${RETURNVALUE}|$?))
    depmod -a

    # This function might be called even if no old drivers are
    # available to be restored, so don't fail if the search for files
    # to restore fails.
    case "${RETURNVALUE}" in
	0|1)  let RETURNVALUE=0 ;;
	*)    let RETURNVALUE=${RETURNVALUE} ;;
    esac
    return ${RETURNVALUE}
}

# Function:  configure_sles_sysconfig_kernel()
#
# Description:
#   Configure the /etc/sysconfig/kernel file on SLES installations to
#   load the lpfc driver on boot.
#
# Parameters:
#   none.
#
# Returns:
#   0 - /etc/sysconfig/kernel file not modified.
#   1 - /etc/sysconfig/kernel file modified.
configure_sles_sysconfig_kernel()
{
    local RETURN_VALUE
    let RETURN_VALUE=0

    if [ ${DISTRIBUTION} = "suse" ] ; then
	echo "Configuring /etc/sysconfig/kernel ..."
	if [ $(grep -c -e "^[[:space:]]*INITRD_MODULES[[:space:]]*=[[:space:]]*.*[\"[:space:]]${1}[\"[:space:]]" /etc/sysconfig/kernel) -eq 0 ] ; then
	    cp /etc/sysconfig/kernel ${KERNEL_CONF_BACKUP}
	    echo "Original saved as ${KERNEL_CONF_BACKUP}"
	    sed "s/INITRD_MODULES=\"\(.*\)\"/INITRD_MODULES=\"\1 ${DRIVER_NAME}\"/" /etc/sysconfig/kernel > ${KERNEL_CONF_TEMP}
	    mv -f ${KERNEL_CONF_TEMP} /etc/sysconfig/kernel
	    sed "/^[[:space:]]*INITRD_MODULES[[:space:]]*=.*\".*/ {s/\([\"[:space:]]\)${SLES_DRIVER_NAME}\([\"[:space:]]\)/\1\2/g}" /etc/sysconfig/kernel > ${KERNEL_CONF_TEMP}
	    mv -f ${KERNEL_CONF_TEMP} /etc/sysconfig/kernel
	    let RETURN_VALUE=1
	fi
    fi

    return ${RETURN_VALUE}
}

# Function:  unconfigure_sles_sysconfig_kernel()
#
# Description:
#   Configure the /etc/sysconfig/kernel file on SLES installations to
#   not load the lpfc driver on boot.
#
# Parameters:
#   none.
#
# Returns:
#   0 - /etc/sysconfig/kernel file not modified.
#   1 - /etc/sysconfig/kernel file modified.
unconfigure_sles_sysconfig_kernel()
{
    local MODIFIED_FILE
    local RETURN_VALUE
    let MODIFIED_FILE=0
    let RETURN_VALUE=0

    if [ ${DISTRIBUTION} = "suse" ] && [ $(find /lib/modules/$(uname -r) -name ${SLES_DRIVER_NAME}.ko -type f | wc -l) -ne 0 ] ; then
	echo "Configuring /etc/sysconfig/kernel ..."
	cp -f /etc/sysconfig/kernel ${KERNEL_CONF_BACKUP}
	while [ -n "$1" ] ; do
	    if [ $(grep -c -e "^[[:space:]]*INITRD_MODULES[[:space:]]*=[[:space:]]*.*[\"[:space:]]${1}[\"[:space:]]" /etc/sysconfig/kernel) -ne 0 ] ; then
		sed "/^[[:space:]]*INITRD_MODULES[[:space:]]*=.*\".*/ {s/\([\"[:space:]]\)${1}\([\"[:space:]]\)/\1${SLES_DRIVER_NAME}\2/g}" /etc/sysconfig/kernel > ${KERNEL_CONF_TEMP}
		mv -f ${KERNEL_CONF_TEMP} /etc/sysconfig/kernel
		let MODIFIED_FILE=$((${MODIFIED_FILE}+1))
		let RETURN_VALUE=1
	    fi
	    shift
	done

	if [ ${MODIFIED_FILE} -ne 0 ] ; then
	    echo "Original saved as ${KERNEL_CONF_BACKUP}"
	else
	    rm ${KERNEL_CONF_BACKUP}
	fi
    fi

    return ${RETURN_VALUE}
}

# Function:  backup_modprobe_conf()
#
# Description:
#   Copy the file /etc/modprobe.conf to the file specified by the the
#   first positional parameter, failing with exit code 130 if the copy
#   fails.
#
# Parameters:
#   File to which /etc/modprobe.conf should be copied.
#
# Returns:
#   0 on success,
#   exit code 130 on failure.
backup_modprobe_conf()
{
    # Make a working copy of /etc/modprobe.conf.
    cp -f /etc/modprobe.conf $1
    if [ $? -ne 0 ] ; then
	echo ""
	echo "Error backup up /etc/modprobe.conf"
	echo ${GENERIC_MESSAGE}
	exit 130
    fi

    return 0
}

# Function:  configure_modprobe_conf()
#
# Description:
#   Add /etc/modprobe.conf scsihostadapter references to each driver
#   passed as a parameter.
#
# Parameters:
#   A list of driver modules.
#
# Returns a bit pattern with the following values:
#  0 if the /etc/modprobe.conf file is not modified,
#  1 if the /etc/modprobe.conf file is modified.
#  8 if an "alias scsi_hostadapter off" entry exists in modprobe.conf.
configure_modprobe_conf()
{
    local RETURN_VALUE
    local MAX_REF
    let RETURN_VALUE=0

    echo "Configuring /etc/modprobe.conf ..."
    backup_modprobe_conf ${MODPROBE_CONF_TEMP}

    # If SLES, remove references to old lpfcdd driver.
    if [ $(grep -c -e "^alias[[:space:]]\+scsi_hostadapter[[:digit:]]*[[:space:]]\+${SLES_DRIVER_NAME}[[:space:]]*\$" /etc/modprobe.conf) -ne 0 ] ; then
        grep -v -e "^alias[[:space:]]\+scsi_hostadapter[[:digit:]]*[[:space:]]\+${SLES_DRIVER_NAME}[[:space:]]*\$" ${MODPROBE_CONF_TEMP} > ${MODPROBE_CONF_TEMP2}
	mv -f ${MODPROBE_CONF_TEMP2} ${MODPROBE_CONF_TEMP}
	let RETURN_VALUE=$((${RETURN_VALUE}|1))
    fi

    # Calculate the highest scsi_hostadapterXX value in use.
    MAX_REF=$(grep -e "^[[:space:]]*alias[[:space:]]\+scsi_hostadapter[[:digit:]]\+[[:space:]]\+" /etc/modprobe.conf | sed 's/^.*[[:space:]]scsi_hostadapter\([[:digit:]]\+\)[[:space:]].*$/\1/' | awk '{if (s < $1) s=$1} END {print s}')
    let MAX_REF=$((${MAX_REF}+1))

    # Add or modify the 'options scsi_mod' line in /etc/modprobe.conf
    # file if necessary.
    local SCSI_MOD_COUNT
    local SCSI_MOD_ENTRY
    local SCSI_MOD_ENTRY_ORIGINAL
    let SCSI_MOD_COUNT=$(grep -c -e "^[[:space:]]*options[[:space:]]\\+scsi_mod[[:space:]]\\+" ${MODPROBE_CONF_TEMP})
    SCSI_MOD_ENTRY=$(grep -e "^[[:space:]]*options[[:space:]]\\+scsi_mod[[:space:]]\\+" ${MODPROBE_CONF_TEMP})
    SCSI_MOD_ENTRY_ORIGINAL=${SCSI_MOD_ENTRY}
    if [ ${SCSI_MOD_COUNT} -eq 1 ] ; then
	# An 'options scsi_mod' line already exists.  Make sure it
        # meets the needs of the lpfc module.
	local CHANGES
	let CHANGES=0
	# First, check the "max_luns" entry.
	local LUNS_ENTRY
	LUNS_ENTRY=$(echo ${SCSI_MOD_ENTRY} | grep -e 'max_luns=[[:digit:]]\+')
	if [ -n "${LUNS_ENTRY}" ] ; then
	    LUNS_ENTRY=$(echo ${LUNS_ENTRY} | sed 's/.*\(max_luns=[[:digit:]]\+\).*/\1/')
	fi
	if [ -z "${LUNS_ENTRY}" ] ; then
	    SCSI_MOD_ENTRY="${SCSI_MOD_ENTRY} max_luns=${MAX_LUNS}"
	    let CHANGES=1
	elif [ $(echo ${LUNS_ENTRY} | sed "s/max_luns=//") -lt ${MAX_LUNS} ] ; then
	    SCSI_MOD_ENTRY=$(echo ${SCSI_MOD_ENTRY} | sed "s/max_luns=[[:digit:]]\+/max_luns=${MAX_LUNS}/")
	    let CHANGES=1
	fi
	if [ ${CHANGES} -ne 0 ] ; then
	    grep -v "${SCSI_MOD_ENTRY_ORIGINAL}" ${MODPROBE_CONF_TEMP} > ${MODPROBE_CONF_TEMP2}
	    echo ${SCSI_MOD_ENTRY} >> ${MODPROBE_CONF_TEMP2}
	    mv -f ${MODPROBE_CONF_TEMP2} ${MODPROBE_CONF_TEMP}
	    let RETURN_VALUE=$((${RETURN_VALUE}|1))
	fi

    elif [ ${SCSI_MOD_COUNT} -eq 0 ] ; then
	# No 'options scsi_mod' line exists.  Write one that meets
        # the needs of the lpfc module.
	local LINE_TO_WRITE
	LINE_TO_WRITE=$(echo "${MODPROBE_CONF_ENTRY} ${MODPROBE_CONF_LUNS}")
	echo "${LINE_TO_WRITE}" >> ${MODPROBE_CONF_TEMP}
	let RETURN_VALUE=$((${RETURN_VALUE}|1))
    else
	# Multple 'options scsi_mod' lines exist.  Bail.
	let RETURN_VALUE=$((${RETURN_VALUE}|4))
    fi

    # Check for the presence of "alias scsi_hostadapter off" entry.
    local SCSI_OFF
    let SCSI_OFF=$(grep -c -e "^[[:space:]]*alias[[:space:]]\+scsi_hostadapter[[:space:]]\+off[[:space:]]*" /etc/modprobe.conf)
    if [ ${SCSI_OFF} -ne 0 ] ; then
	let RETURN_VALUE=$((${RETURN_VALUE}|8))
    fi

    # Add apppropriate number of references for each driver passed to
    # this function.
    while [ -n "$1" ] && [ -n "$2" ] ; do
	local NUM_REFS
	let NUM_REFS=$(grep -c -e "^[[:space:]]*alias[[:space:]]\\+scsi_hostadapter[[:digit:]]\\+[[:space:]]\\+${1}[[:space:]]*\$" ${MODPROBE_CONF_TEMP})
	while [ ${NUM_REFS} -lt $2 ] ; do
	    echo "alias scsi_hostadapter${MAX_REF} ${1}" >> ${MODPROBE_CONF_TEMP}
	    let MAX_REF=$((${MAX_REF}+1))
	    let NUM_REFS=$((${NUM_REFS}+1))
	    let RETURN_VALUE=$((${RETURN_VALUE}|1))
	done
	shift
	shift
    done

    # Back up and then update /etc/modprobe.conf if changes are
    # necessary.
    if [ ${RETURN_VALUE} -ne 0 ] ; then
	# Save one pre-existing backup.
	if [ -e /etc/modprobe.elx ] ; then
	    mv -f ${MODPROBE_CONF_BACKUP} ${MODPROBE_CONF_BACKUP}.old
	fi

	# Backup up /etc/modprobe.conf.
	cp -f /etc/modprobe.conf ${MODPROBE_CONF_BACKUP}
	if [ $? -ne 0 ] ; then
	    echo ""
	    echo "Error backing up /etc/modprobe.conf"
	    echo ${GENERIC_MESSAGE}
	    exit 130
	fi
	echo "Original saved as ${MODPROBE_CONF_BACKUP}"

	# Update /etc/modprobe.conf with the changes.
	mv -f ${MODPROBE_CONF_TEMP} /etc/modprobe.conf
	if [ $? -ne 0 ] ; then
	    echo ""
	    echo "Error updating /etc/modprobe.conf"
	    echo ${GENERIC_MESSAGE}
	    exit 140
	fi
    else
	# Remove the unmodified temp file.
	rm -f ${MODPROBE_CONF_TEMP}
    fi

    return ${RETURN_VALUE}
}

# Function:  unconfigure_modprobe_conf()
#
# Description:
#   Remove any references in /etc/modprobe.conf to all driver modules
#   passed as parameters to this function.
#
# Parameters:
#   A list of driver modules.
#
# Returns a bit pattern with the following values:
#   0 if the /etc/modprobe.conf file is not modified,
#   1 if the /etc/modprobe.conf file is modified.
unconfigure_modprobe_conf()
{
    local RETURN_VALUE
    let RETURN_VALUE=0

    echo "Configuring /etc/modprobe.conf ..."
    backup_modprobe_conf ${MODPROBE_CONF_TEMP}

    # Modify "alias scsi_hostadapter" messages if necessary.
    if [ ${DISTRIBUTION} = "suse" ] && [ $(find /lib/modules/$(uname -r) -name ${SLES_DRIVER_NAME}.ko -type f | wc -l) -ne 0 ] ; then
	while [ -n "$1" ] ; do
	    if [ $(grep -c -e "^alias[[:space:]]\+scsi_hostadapter[[:digit:]]*[[:space:]]\+${1}[[:space:]]*\$" /etc/modprobe.conf) -ne 0 ] ; then
		cat ${MODPROBE_CONF_TEMP} | sed "s/^\(alias[[:space:]]\+scsi_hostadapter[[:digit:]]*[[:space:]]\+\)${1}\([[:space:]]*\)\$/\1${SLES_DRIVER_NAME}\2/" > ${MODPROBE_CONF_TEMP2}
		mv -f ${MODPROBE_CONF_TEMP2} ${MODPROBE_CONF_TEMP}
		let RETURN_VALUE=$((${RETURN_VALUE}|1))
	    fi
	    shift
	done
    fi

    # Remove or modify the 'options scsi_mod' line in
    # /etc/modules.conf.
    local SCSI_MOD_COUNT
    local SCSI_MOD_ENTRY
    local SCSI_MOD_ENTRY_ORIGINAL
    let SCSI_MOD_COUNT=$(grep -c -e "^[[:space:]]*options[[:space:]]\\+scsi_mod[[:space:]]\\+" ${MODPROBE_CONF_TEMP})
    SCSI_MOD_ENTRY=$(grep -e "^[[:space:]]*options[[:space:]]\\+scsi_mod[[:space:]]\\+" ${MODPROBE_CONF_TEMP})
    SCSI_MOD_ENTRY_ORIGINAL=${SCSI_MOD_ENTRY}
    if [ ${SCSI_MOD_COUNT} -eq 1 ] ; then
	# An 'options scsi_mod' line already exists.  Make sure it
        # matches the one written by lpfc-install during installation.
	local TEMP
	TEMP=$(grep -e "^options[[:space:]]\+scsi_mod[[:space:]]\+" /etc/modprobe.conf)
	TEMP=$(echo ${TEMP} | sed "s/options[[:space:]]\+scsi_mod[[:space:]]\+//")
	TEMP=$(echo ${TEMP} | sed "s/max_luns=${MAX_LUNS}//")
	TEMP=$(echo ${TEMP} | sed "s/[[:space:]]*//g")
	if [ -z "${TEMP}" ] ; then
	    # The "options scsi_mod" line matches the default that
	    # is written by lpfc-install during installation.
	    # Completely remove it.
	    grep -v -e "^options[[:space:]]\+scsi_mod[[:space:]]\+" ${MODPROBE_CONF_TEMP} > ${MODPROBE_CONF_TEMP2}
	    mv -f ${MODPROBE_CONF_TEMP2} ${MODPROBE_CONF_TEMP}
	    let RETURN_VALUE=$((${RETURN_VALUE}|1))
	else
	    # The "options scsi_mod" line does not match the
	    # default written by lpfc-install on installation; it
	    # was either modified by lpfc-install during
	    # installation or edited by the user afterwards.
	    # Prompt the user to manually edit the
	    # /etc/modules.conf file.
	    let RETURN_VALUE=$((${RETURN_VALUE}|8))
	fi
    elif [ ${SCSI_MOD_COUNT} -ne 0 ] ; then
	# Multple 'options scsi_mod' lines exist.  Bail.
	let RETURN_VALUE=$((${RETURN_VALUE}|4))
    fi

    if [ $((${RETURN_VALUE} & 1)) -ne 0 ] ; then
	if [ -e /etc/modprobe.elx ] ; then
	    mv -f ${MODPROBE_CONF_BACKUP} ${MODPROBE_CONF_BACKUP}.old
	fi
	cp -f /etc/modprobe.conf ${MODPROBE_CONF_BACKUP}
	if [ $? -ne 0 ] ; then
	    echo ""
	    echo "Error backing up /etc/modprobe.conf"
	    echo ${GENERIC_MESSAGE}
	    exit 130
	fi
	echo "Original saved as ${MODPROBE_CONF_BACKUP}"
	mv -f ${MODPROBE_CONF_TEMP} /etc/modprobe.conf
	if [ $? -ne 0 ] ; then
	    echo ""
	    echo "Error updating /etc/modprobe.conf"
	    echo ${GENERIC_MESSAGE}
	    exit 140
	fi
    else
	rm -f ${MODPROBE_CONF_TEMP}
    fi

    return ${RETURN_VALUE}
}

configure_ramdisk()
{
    local RETURN_VALUE
    local NUM_ADAPTERS
    let RETURN_VALUE=0

    echo "Configuring ramdisk..."
    num_adapters
    let NUM_ADAPTERS=$?
    configure_modprobe_conf ${DRIVER_NAME} ${NUM_ADAPTERS}
    let RETURN_VALUE=$((${RETURN_VALUE} | $?))

    configure_sles_sysconfig_kernel ${DRIVER_NAME}
    let RETURN_VALUE=$((${RETURN_VALUE} | $?))

    return ${RETURN_VALUE}
}

unconfigure_ramdisk()
{
    local RETURN_VALUE
    let RETURN_VALUE=0

    unconfigure_modprobe_conf ${DRIVER_NAME}
    let RETURN_VALUE=$((${RETURN_VALUE} | $?))

    unconfigure_sles_sysconfig_kernel ${DRIVER_NAME}
    let RETURN_VALUE=$((${RETURN_VALUE} | $?))

    return ${RETURN_VALUE}
}

update_lilo()
{
    echo "Updating LILO configuration ..." 
    /sbin/lilo 2>/dev/null 1>/dev/null
    if [ $? -ne 0 ] ; then
	echo "Error installing ramdisk image into LILO configuration file."
	echo ${GENERIC_MESSAGE}
	exit 30;
    fi
}

# Function:  backup_files_to_elx()
#
# Description:
#   Copy each file passed as a parameter to filename.elx.
#
# Parameters:
#   A list of filenames to back up.
#
# Returns:
#   Nothing.
backup_files_to_elx()
{
    for i in $@ ; do
	cp -f $i $i.elx
	if [ $? -ne 0 ] ; then
	    echo "Error $? copying $i to $i.elx"
	else
	    echo "Original ramdisk image $i saved as $i.elx"
	fi
    done
}

# Function:  create_ramdisk()
#
# Description:
#   Creates a ramdisk image for the currently running kernel.
#
# Parameters:
#   none.
#
# Returns:
#   Nothing.
create_ramdisk()
{
    if [ ${DISTRIBUTION} = "redhat" ] ||
	[ ${DISTRIBUTION} = "asianux" ] ; then
	# Configure ramdisk for Red Hat Linux or Asianux.
	if [ ${ARCH} = "ia64" ] ; then
	    INITRDFILE="/boot/efi/efi/${DISTRIBUTION}/initrd-${UNAME}.img"
	else
	    INITRDFILE="/boot/initrd-${UNAME}.img"
	fi
	backup_files_to_elx ${INITRDFILE}
	echo -n "Creating ramdisk ."
	exec_command "/sbin/mkinitrd --allow-missing -f ${INITRDFILE} ${UNAME}" background
	if [ $? -ne 0 ] ; then
	    echo "Could not create ramdisk image.  Restoring original ramdisk ..."
	    cp -f /boot/initrd-${UNAME}.img.elx /boot/initrd-${UNAME}.img
	    echo "Original ramdisk restored."
	    echo ""
	    echo "Please run '${INSTALL_SCRIPT} --uninstall' to remove any partially"
	    echo "installed components of the Emulex driver and utility applications."
	    exit 40
	fi
    else
	# Configure ramdisk configuration file for SuSE Linux Enterprise Server.
	if [ ${ARCH} = "ppc64" ] ; then
	    INITRDFILES="/boot/initrd"
	else
	    INITRDFILES="/boot/initrd /boot/initrd.shipped"
	fi
	backup_files_to_elx ${INITRDFILE}

	echo -n "Creating ramdisk ."
	if [ ${ARCH} = "i386" ] ; then
	    exec_command "/sbin/mk_initrd -i initrd-${UNAME} -k ${SLES_KERNEL_IMAGE}-${UNAME} >/dev/null 2>&1" background
	else
	    exec_command "/sbin/mk_initrd -i initrd -k ${SLES_KERNEL_IMAGE} >/dev/null 2>&1" background
	fi
	if [ $? -ne 0 ] ; then
	    echo "Could not create ramdisk image.  Restoring original ramdisk ..."
	    cp -f /boot/initrd.shipped.elx /boot/initrd.shipped && cp -f /boot/initrd.elx /boot/initrd
	    if [ $? -ne 0 ] ; then
		echo "Original ramdisks restored."
	    else
		echo "Original ramdisks could not be restored - error $?"
	    fi
	    echo ""
	    echo "Please run '${INSTALL_SCRIPT} --uninstall' to remove any partially"
	    echo "installed components of the Emulex driver and utility applications."
	    exit 40
	fi
    fi
    depmod
    if [ ${ARCH} = "ppc64" ] && [ ${DISTRIBUTION} = "suse" ] ; then
	update_lilo
    fi

    return 0
}

# Function:  examine_build_configuration()
#
# Description:
#   Examines the system to verify that source package for the
#   currently running kernel and the gcc package are installed.
#
# Parameters:
#   none.
#
# Returns:
#   0 - The system is ready for installation of the LPFC driver.
#   1 - The kernel source needs to be installed.
#   2 - The gcc compiler package needs to be installed.
#   3 - Both the kernel source and gcc need to be installed.
examine_build_configuration()
{
    let ERRORCONDITION=0

    if [ ${DISTRIBUTION} = "redhat" ] ; then
	echo "Looking for kernel development package ..."
	KERNELDEVEL=$(rpm -qf ${KERNEL_IMAGE_PATH} --qf "%{NAME}-devel-%{VERSION}-%{RELEASE}\n")
	if [ $? -ne 0 ] ; then
	    let ERRORCONDITION=4
	else
	    KERNELSOURCEVERSION=$(rpm -q ${KERNELDEVEL} 2>/dev/null)
	    if [ $? -ne 0 ]
		then
		let ERRORCONDITION=1
	    fi
	fi
    else
	echo "Looking for kernel source package ..."
	KERNELDEVEL=$(rpm -qf ${KERNEL_IMAGE_PATH} --qf "kernel-source-%{VERSION}-%{RELEASE}")
	if [ $? -ne 0 ] ; then
	    let ERRORCONDITION=4
	else
	    KERNELSOURCEVERSION=$(rpm -q ${KERNELDEVEL} 2>/dev/null)
	    if [ $? -ne 0 ]
		then
		let ERRORCONDITION=1
	    fi
	fi
    fi

    echo "Looking for compilers ..."
    GCCVERSION=$(rpm -q --qf %{VERSION}-%{RELEASE} gcc)
    if [ $? -ne 0 ]
	then
	if [ ${ERRORCONDITION} -eq 0 ]
	    then
	    let ERRORCONDITION=2
	else
	    let ERRORCONDITION=3
	fi
    fi

    if [ ${ERRORCONDITION} -eq 1 ] ; then
	echo ""
	echo "RPM cannot be installed: ${KERNELDEVEL} package is required."
	let NEED_SOURCE_PACKAGE=1
        return 1
    elif [ ${ERRORCONDITION} -eq 2 ] ; then
	echo ""
	echo "RPM cannot be installed: gcc package is required."
	let NEED_GCC_PACKAGE=1
	return 2
    elif [ ${ERRORCONDITION} -eq 3 ] ; then
	echo "RPM cannot be installed ; kernel source and gcc packages are required."
	let NEED_SOURCE_PACKAGE=1
	let NEED_GCC_PACKAGE=1
	return 3
    elif [ ${ERRORCONDITION} -eq 4 ] ; then
	echo "RPM cannot be installed: kernel version could not be determined."
	return 4
    fi

    return 0
}

# Function:  install_rpm()
#
# Description:
#   Installed the specified RPM package.
#
# Parameters:
#   $1 - Package description.
#   $2 - Package Directory.
#   $3 - Package file name.
#   $4 - Package name.
#
# Returns:
#    0 - RPM successfully installed.
#    2 - A version of the package is already installed.
#    4 - An error occurred during RPM test.
#    5 - An error occurred during RPM installation.
#    6 - Could not find RPM file in specified path.
install_rpm()
{
    INSTALLEDVERSION=$(rpm -q --qf %{VERSION} $4 2>/dev/null)
    if [ $? -eq 0 ] ; then
	return 2
    fi
    echo "Searching for $1 from $2 ..."
    if [ ! -e $2/$3 ] ; then
	echo "Could not find $1 in path $2/$3!"
	return 6
    fi
    rpm -Uhv $2/$3 --test 2>/dev/null 1>/dev/null
    if [ $? -ne 0 ]; then
	echo ""
	echo "Error during RPM test"
	return 4
    else
	echo "Installing package ..."
	rpm -Uhv $2/$3
	if [ $? -ne 0 ]; then
	    echo ""
	    echo "Error during RPM installation"
	    return 5
	else
	    depmod -a
	    DRIVER_INSTALLED=1
	fi
    fi

    return 0
}

# Function:  load_driver()
#
# Description:
#   Load the specified driver.
#
# Parameters:
#   $1 - name of the driver to be loaded.
#   $2 - description of the driver to be loaded.
load_driver()
{
    echo -en "Loading $2 ."
    exec_command "modprobe $1" background
    if [ $? -ne 0 ]; then
	echo ""
	echo "Error loading $2"
	echo "Please refer to the following file(s) for more information"
	echo "about this driver load failure:"
	for mesg in ${MESSAGESFILE} ; do
	    echo -e "\t$mesg"
	done
	return 1
    fi
}

# Function:  install_basedriver_rpm()
#
# Description:
#   Install the base driver RPM.
#
# Parameters:
#   $1 = 0  if driver is to be loaded after installation,
#   $1 != 0 if driver is not to be loaded after installation.
#
# Returns:
#    0 - RPM installed, or version of package currently installed
#         matches version of package to be installed.
#    1 - Error during RPM installation.
#    2 - Old package already installed.
#    3 - The current version of this package is already installed.
install_basedriver_rpm()
{
    install_rpm "${DRIVER_DESCRIPTION}" "`pwd`/${DRIVER_DIR}" ${DRIVER_RPM} ${RPM_BASENAME}
    RETURNVALUE=$?
    if [ ${RETURNVALUE} -eq 2 ] ; then
	if [ ${INSTALLEDVERSION} = ${DRIVER_VERSION} ] ; then
	    echo "${DRIVER_DESCRIPTION} version ${DRIVER_VERSION} already installed."
	    return 3
	else
	    echo "Another version of the ${DRIVER_DESCRIPTION} is already installed."
	    echo "Please execute '$0 --uninstall' to remove old versions of the"
	    echo "Emulex driver kit."
	    return 2
	fi
    elif [ ${RETURNVALUE} -ne 0 ] ; then
	echo "Error installing ${DRIVER_DESCRIPTION}."
	return 3
    fi

    return 0
}

# Function:  load_lpfcdriver_module
#
# Description:
#   Loads the lpfc module.
#
# Parameters:
#   none.
#
# Returns:
#    0 - lpfc module loaded.
#    1 - error loading lpfc module.
load_lpfcdriver_module()
{
    load_driver ${DRIVER_NAME} "LPFC Driver"
    if [ $? -ne 0 ] ; then
	echo ${GENERIC_MESSAGE}
	return 1
    fi

    return 0
}

# Function:  remove_rpm_package()
#
# Description:
#   Remove the specified RPM package if it is installed and if no
#   other packages depend on the virtual packages it provides.
#
# Returns:
#   0 - At least one RPM uninstalled, others may not have been
#        installed.
#   1 - Error during RPM removal.
#   2 - Other packages depend on the package to be removed.
#   3 - No packages were installed.
remove_rpm_package()
{
    local retval
    let retval=3

    while [ -n "$1" ]; do
	rpm -q $1 2>/dev/null 1>/dev/null
	if [ $? -eq 0 ] ; then
	    PACKAGES=$(rpm -q --whatrequires $1 2>&1)
	    if [ $? -ne 0 ] ; then
		echo "Removing $2 ..."
		rpm -e $1
		if [ $? -eq 0 ] ; then
		    let retval=0
		else
		    echo "An error occurred while uninstalling $1"
		    return 1
		fi
	    else
		echo "The following packages depend on $1:"
		echo "${PACKAGES}"
		return 2
	    fi
	fi
	shift
	shift
    done

    return ${retval}
}

remove_file()
{
    if [ -e $1 ] ; then
	rm -f $1
	if [ $? -ne 0 ] ; then
	    echo "An error occurred while removing $1"
	    return 1
	fi
    fi

    return 0
}

remove_dir()
{
    if [ -d $1 ] ; then
	rmdir $1
	if [ $? -ne -0 ] ; then
	    echo "An error occurred while removing $1"
	    return 1
	fi
    fi

    return 0
}

# Function:  unload_driver()
#
# Description:
#   Unload the specified driver if it is loaded and unused.
#
# Parameters:
#   $1 - Name of module to be unloaded.
#
# Returns:
#   0 - module successfully unloaded
#   1 - an error occurred while unloading the module.
#   2 - module is being used and cannot be unloaded.
#   3 - module is being referenced by other modules and cannot be
#       unloaded.
#   4 - module was not loaded.
#   
unload_driver()
{
    LSMOD=$(lsmod | grep -e "^$1\?[[:space:]]\+[[:digit:]]\+[[:space:]]\+[[:digit:]]\+")
    if [ $? -ne 0 ] || [ -z "${LSMOD}" ] ; then
	return 4
    fi

    AWK_MODULE=`echo ${LSMOD} | awk -F '[[:space:]]+' '{ print $1; }'`
    let AWK_USECOUNT=`echo ${LSMOD} | awk -F '[[:space:]]+' '{ print $3; }'`
    AWK_REFERENCES=`echo ${LSMOD} | awk -F '[[:space:]]+' '{ print $4; }'`

    if [ ${AWK_MODULE} != $1 ] ; then
	echo "ERROR - module found is not the module we're looking for."
	echo "AWK_MODULE=${AWK_MODULE}"
	echo "MODULE=$1"
	exit 150
    fi

    if [ ${AWK_USECOUNT} -eq 0 ] ; then
	if [ -z ${AWK_REFERENCES} ] || [ ${AWK_REFERENCES} = "(unused)" ] ; then
	    rmmod $1
	    if [ $? -ne 0 ] ; then
		echo "An error occurred while unloading $1"
		return 1
	    fi
	else
	    return 3
	fi
    else
	return 2
    fi

    return 0
}

print_help()
{
    echo ""
    echo "$0 will by default install version ${DRIVER_VERSION} of the"
    echo "Emulex Linux Fibre Channel drivers.  The following options may"
    echo "also be used:"
    echo ""
    echo "   --configramdisk   - Configure and build a ramdisk image that loads the"
    echo "                        Emulex driver when the system is booted with the"
    echo "                        current kernel."
    echo "   --createramdisk   - Create a new ramdisk image.  Use this option after"
    echo "                        you have modified driver parameters in the"
    echo "                        /etc/modprobe.conf file."
    echo "-u,--uninstall       - Uninstall previously installed driver kit."
    echo "   --unconfigramdisk - Configure and build a ramdisk image that does not"
    echo "                        load the Emulex driver when the system is booted"
    echo "                        with the current kernel."
}

uninstall_kit()
{
    let UNINSTALL_ERRORS=0
    let REBOOT_REQUIRED=0
    let NOREBOOT_REQUIRED=0
    let CREATE_RAMDISK=0

    echo "Checking for Emulex driver packages ..."
    rpm -q --quiet ${MULTIPULSE_RPM_BASENAME}
    if [ $? -eq 0 ] ; then
	echo "Please remove the Emulex Multipulse kit and then run"
	echo "'$0 --uninstall' again."
	exit 13
    fi

    # Check to make sure the current LPFC driver's RPM is installed. This to cover
    # the case where the user tries to uninstall a previous/older LPFC driver kit using 
    # this newer uninstall process.

    check_for_driver_module

    case "$?" in
        2) echo "Version ${DRIVER_VERSION} of the ${RPM_BASENAME} RPM package is not installed."
	   exit 14;;
        3) echo "Version ${LPFC_INSTALLEDVERSION} of the ${RPM_BASENAME} package is currently"
	   echo "installed. Please uninstall the ${RPM_BASENAME} driver by using the lpfc-install"
	   echo "script contained in the ${LPFC_INSTALLEDVERSION} package." 
	   if [ -e ${INSTALLDIR}/lpfc-install ] ; then
	       echo "A copy of the lpfc-install script can be found in ${INSTALLDIR}."
	       echo "Please follow the proper uninstall procedure as described"
	       echo "in the LPFC driver manual."
	   fi
    	   exit 14;;

        6) echo "Version ${LPFC_MODULEVERSION} of the lpfc driver in /lib/modules/${UNAME}"
	   echo "is not the same version ${DRIVER_VERSION} of the driver you are uninstalling."
	   exit 14;;
    esac

    # If LPFCDFC module is installed (RPM exists) output a warning and exit.
    echo "Checking for Emulex LPFCDFC driver packages ..."
    check_for_lpfcdfc_driver_mod
    case "$?" in
	1) echo "The Application Helper Module version ${INSTALLEDVERSION} of the"
           echo "${INSTALLEDPACKAGE} RPM is installed." 
	   echo "Please remove the ${INSTALLEDPACKAGE} package first by using the "
           echo "Applications Kit uninstall procedure, and then run this process again."
	   exit 12 ;;
	2) echo "An incorrect Application Helper Module version ${INSTALLEDVERSION} of the " 
	   echo "${INSTALLEDPACKAGE} RPM is installed."
	   echo "Please remove the ${INSTALLEDPACKAGE} package first, by using the "
	   echo "Applications Kit uninstall procedure, and then run this process again."
	   echo
	   exit 12  ;; 
	3) DFC_KIT_UNINSTALLER="/usr/src/lpfcdfc/ioctl-install"
	   echo "An incorrect Application Helper Module version ${INSTALLEDVERSION} of the " 
	   echo "${INSTALLEDPACKAGE} RPM is installed."
	   echo "Please remove the ${INSTALLEDPACKAGE} package first and then run this process again."
           if [ -e ${DFC_KIT_UNINSTALLER} ] ; then
	       echo "To remove the  ${INSTALLEDPACKAGE} package please use the ${DFC_KIT_UNINSTALLER} script."
	   fi
	   exit 12  ;;
	4) # check_for_lpfcdfc_driver_mod() hit a fatal error.  Exiting.
	   exit 12  ;;
    esac

    remove_rpm_package "${OLD_RPM_BASENAME}" "Old LPFC Driver Source RPM" \
	"${RPM_BASENAME}" "LPFC Driver source RPM"
    case "$?" in
	0)  let CREATE_RAMDISK=1 ;;
	1)  let UNINSTALL_ERRORS=${UNINSTALL_ERRORS}+1 ;;
	2)  echo "Please remove the dependent packages and then"
	    echo "run '$0 --uninstall' again."
	    exit 12 ;;
	3)  ;;
	*)  let UNINSTALL_ERRORS=${UNINSTALL_ERRORS}+1 ;;
    esac

    # Remove a bunch of files.
    files=( "/lib/modules/${UNAME}/kernel/drivers/scsi/lpfc/lpfc.ko" )
    for i in ${files[@]} ; do
	remove_file $i || let UNINSTALL_ERRORS=${UNINSTALL_ERRORS}+1
    done
#    remove_dir  "/lib/modules/${UNAME}/kernel/drivers/scsi/lpfc/" || let UNINSTALL_ERRORS=${UNINSTALL_ERRORS}+1

    # Unload a bunch of drivers.
    drivers=(${DFCDRIVER_NAME} ${DRIVER_NAME})
    for i in ${drivers[@]} ; do
	unload_driver ${i}
	case "$?" in
	    0|4) ;;
	    1)  echo "An error occurred while unloading ${i}."
		let UNINSTALL_ERRORS=${UNINSTALL_ERRORS}+1 ;;
	    2)  MESGS="${MESGS}\no The ${i} driver is being used and cannot be unloaded."
		let REBOOT_REQUIRED=${REBOOT_REQUIRED}+1 ;;
	    3)  MESGS="${MESGS}\no The ${i} driver is being referenced by other"
		MESGS="${MESGS}\n  modules and cannot be unloaded."
		let REBOOT_REQUIRED=${REBOOT_REQUIRED}+1 ;;
	    *)  echo "An unknown error occurred while uninstalling ${i}."
		let UNINSTALL_ERRORS=${UNINSTALL_ERRORS}+1 ;;
	esac
    done

    # Perform some SLES-specific processing.
    if [ ${DISTRIBUTION} = "suse" ]; then
	TMPFILE=/tmp/lpfc-uninstall-$$
	cp ${BOOT_FILE} ${TMPFILE}
	sed -e "/# load Emulex lpfcdd driver/d" -e "/modprobe ${DRIVER_NAME}/d"\
	    ${TMPFILE} > ${BOOT_FILE}
	rm ${TMPFILE}
	chmod a+x ${BOOT_FILE}
    fi
    restore_old_driver

    # Rebuild the ramdisk, if necessary.
    local TEMPVALUE
    unconfigure_ramdisk
    let TEMPVALUE=$?
    if [ $((${TEMPVALUE} & 1)) -ne 0 ] || [ ${CREATE_RAMDISK} -ne 0 ] ; then
	if [ $(pwd) == ${INSTALLDIR} ] ; then
	    cd /usr/src
	fi
	create_ramdisk
	case "$?" in
	    0) echo "The ramdisk for this kernel has been updated." ;;
	    *) let UNINSTALL_ERRORS=${UNINSTALL_ERRORS}+1 ;;
	esac
    fi

    # Check for any uninstall errors.
    local TOTAL_MESSAGES
    let TOTAL_MESSAGES=$((${REBOOT_REQUIRED}+${NOREBOOT_REQUIRED}))
    if [ ${UNINSTALL_ERRORS} -ne 0 ] ; then
	echo ""
	echo "Uninstallation of Emulex drivers was not successful."
	echo "${GENERIC_MESSAGE}"
	exit 10
    elif [ ${TOTAL_MESSAGES} -ne 0 ] ; then
	echo -en "\n${TOTAL_MESSAGES} message"
	if [ ${TOTAL_MESSAGES} -ne 1 ] ; then
	    echo -n "s"
	fi
	echo -e " generated during uninstallation:\n${MESGS}\n"
	if [ ${REBOOT_REQUIRED} -gt 0 ] ; then
	    echo "Please reboot this system to complete the uninstallation"
	    echo "of the Emulex LPFC driver kit."
	    exit 25
	fi
	exit 0
    else
	echo "Uninstallation complete."
	exit 0
    fi
}

install_kit()
{
    check_for_driver_kit || exit 15

    # If LPFCDFC module is installed (RPM exists) output a warning and exit.
    echo "Checking for Emulex LPFCDFC driver packages ..."
    check_for_lpfcdfc_driver_mod
    case "$?" in
        2) echo "An incorrect Application Helper Module version ${INSTALLEDVERSION} of the "
           echo "${INSTALLEDPACKAGE} RPM is installed." 
	   echo "Please remove the ${INSTALLEDPACKAGE} package first by using the"
	   echo "Applications Kit uninstall procedure and then run this process again."
           echo
           exit 12  ;;
        3) DFC_KIT_UNINSTALLER="/usr/src/lpfcdfc/ioctl-install"
           echo "An incorrect Application Helper Module version ${INSTALLEDVERSION} of the "
           echo "${INSTALLEDPACKAGE} RPM is installed."
	   echo "Please remove the ${INSTALLEDPACKAGE} package first and then run this process again."
           if [ -e ${DFC_KIT_UNINSTALLER} ] ; then
               echo "To remove the ${INSTALLEDPACKAGE} package please use the ${DFC_KIT_UNINSTALLER} script."
           fi
           exit 12  ;;
        4) # check_for_lpfcdfc_driver_mod() hit a fatal error.  Exiting.
           exit 12  ;;
    esac
    let DRIVER_UNLOADED=0
    let REBOOT_REQUIRED=0
    let NOREBOOT_REQUIRED=0
    let CREATE_RAMDISK=0
    unload_old_drivers
    case "$?" in
	0)
	    ;;
	1|3|5|7)
	    echo ""
	    echo ${GENERIC_MESSAGE}
	    exit 127 ;;
	2|4|6)
	    MESGS="${MESGS}\no An old Emulex Linux LPFC driver could not be unloaded"
	    MESGS="${MESGS}\n  prior to the installation of the new driver kit."
	    let REBOOT_REQUIRED=$((${REBOOT_REQUIRED}+1))
	    let DRIVER_UNLOADED=1
	    ;;
	*)
	    echo ""
	    echo ${GENERIC_MESSAGE}
	    exit 127 ;;
    esac

    backup_old_driver

    examine_build_configuration || {
	if [ ${NEED_SOURCE_PACKAGE} == 1 ] && [ ${NEED_GCC_PACKAGE} == 1 ]
	    then
	    echo ""
	    echo "${INSTALL_SCRIPT} was unable to successfully build and load a driver."
	    echo "Please install the appropriate kernel source code and development"
	    echo "environment, and then re-run ${INSTALL_SCRIPT}"
	    exit 75
	elif [ ${NEED_SOURCE_PACKAGE} == 1 ]
	    then
	    echo ""
	    echo "${INSTALL_SCRIPT} was unable to successfully build and load a driver."
	    echo "Please install the appropriate kernel development RPM and then re-run"
	    echo "${INSTALL_SCRIPT}"
	    exit 60
	elif [ ${NEED_GCC_PACKAGE} == 1 ]
	    then
	    echo ""
	    echo "${INSTALL_SCRIPT} was unable to successfully build and load a driver."
	    echo "Please install the appropriate development environment, and then"
	    echo "re-run ${INSTALL_SCRIPT}"
	    exit 70
	else
	    echo ${GENERIC_MESSAGE}
	fi
	exit 2    
    }

    # Check if the Multipulse driver is installed before proceeding
    # with the installation of the LPFC driver.
    rpm -q --quiet ${MULTIPULSE_RPM_BASENAME}
    if [ $? -eq 0 ] ; then
	echo "Please remove the Emulex Multipulse kit and then run"
	echo "'$0' again."
	exit 6
    fi

    install_basedriver_rpm
    let RETVAL=$?
    if [ ${RETVAL} -eq 0 ] ; then
	let CREATE_RAMDISK=1
    elif [ ${RETVAL} -ne 3 ] ; then
	exit 50
    fi

    if [ ${DRIVER_UNLOADED} -eq 0 ] ; then
	load_lpfcdriver_module || {
	    exit 56
	}
    fi

    echo "Package installation complete"

    if [ ${DRIVER_INSTALLED} -ne 0 ] || [ ${CREATE_RAMDISK} -ne 0 ] ; then
	local TEMPVALUE
	configure_ramdisk
	let TEMPVALUE=$?
	if [ $((${TEMPVALUE} & 1)) -ne 0 ] || [ ${CREATE_RAMDISK} -ne 0 ] ; then
	    create_ramdisk
	    case "$?" in
		0)  MESGS="${MESGS}\no The ramdisk for this kernel has been updated."
		    let REBOOT_REQUIRED=$((${REBOOT_REQUIRED}+1)) ;;
		*)  echo "Error creating the ramdisk."
		    exit 40 ;;
	    esac
	fi
	if [ $((${TEMPVALUE} & 2)) -ne 0 ] ; then
	    MESGS="${MESGS}\no The 'options scsi_mod' line in /etc/modprobe.conf contains"
	    MESGS="${MESGS}\n  an invalid value for the 'scsi_allow_ghost_devices' option."
	    MESGS="${MESGS}\n  The LPFC driver requires this option to have a value of 1."
	    MESGS="${MESGS}\n  Please adjust the configuration of any drivers that require"
	    MESGS="${MESGS}\n  the current value of this option, set this option to '1', and"
	    MESGS="${MESGS}\n  then execute:"
	    MESGS="${MESGS}\n  ${0} --createramdisk"
	    let NOREBOOT_REQUIRED=$((${NOREBOOT_REQUIRED}+1))
	fi
	if [ $((${TEMPVALUE} & 4)) -ne 0 ] ; then
	    MESGS="${MESGS}\no Multiple 'options scsi_mod' lines exist in /etc/modprobe.conf."
	    MESGS="${MESGS}\n  Please remove the redundant lines and then execute:"
	    MESGS="${MESGS}\n  ${0} --configramdisk"
	    let NOREBOOT_REQUIRED=$((${NOREBOOT_REQUIRED}+1))
	fi
	if [ $((${TEMPVALUE} & 8)) -ne 0 ] ; then
	    MESGS="${MESGS}\no An 'alias scsi_hostadapter off' entry exists in the"
	    MESGS="${MESGS}\n  /etc/modprobe.conf file.  Please resolve any configuration"
	    MESGS="${MESGS}\n  that depends on this entry, remove the entry, and then"
	    MESGS="${MESGS}\n  execute:"
	    MESGS="${MESGS}\n  ${0} --configramdisk"
	fi
	chmod a+x ${BOOT_FILE}
    fi

    # Installation complete.  Print reboot messages if necessary.
    local TOTAL_MESSAGES
    let TOTAL_MESSAGES=$((${REBOOT_REQUIRED}+${NOREBOOT_REQUIRED}))
    if [ ${TOTAL_MESSAGES} -ne 0 ] ; then
	echo -en "\n${TOTAL_MESSAGES} message"
	if [ ${TOTAL_MESSAGES} -ne 1 ] ; then
	    echo -n "s"
	fi
	echo -e " generated during installation:\n${MESGS}"
	if [ ${REBOOT_REQUIRED} -gt 0 ] ; then
	    echo -e "\nPlease reboot this system to complete the installation"
	fi
	echo "of the Emulex LPFC driver kit."
    else
	echo ""
	echo "Installation complete."
    fi
    if [ ${REBOOT_REQUIRED} -gt 0 ] ; then
	exit 20
    else
	exit 0
    fi
}

echo "Emulex LPFC Driver Installer Version ${INSTALLER_VERSION}"
# Process the parameters
SCRIPT_COMMAND="install"
while [ $# -ne 0 ] ; do
    case "$1" in
	--configramdisk|configureramdisk)
	    SCRIPT_COMMAND="configramdisk"
	    ;;
	--createramdisk)
	    SCRIPT_COMMAND="createramdisk"
	    ;;
	-h|--help)
	    print_help
	    exit 0
	    ;;
	-u|--uninstall)
	    SCRIPT_COMMAND="uninstall"
	    ;;
	--unconfigramdisk|unconfigureramdisk)
	    SCRIPT_COMMAND="unconfigramdisk"
	    ;;
	--)
	    break
	    ;;
	*)
	    echo "Invalid option - $1"
	    SCRIPT_COMMAND="badoption"
	    ;;
    esac
    shift
done

# Exit if an invalid parameter was specified by the user.
if [ -n "${SCRIPT_COMMAND}" ] && [ ${SCRIPT_COMMAND} = "badoption" ] ; then
    echo ${HELP_MESSAGE}
    exit 5
fi
    
echo "Determining distribution type and kernel version ..."

if ! get_distribution; then
   echo ${GENERIC_MESSAGE}
   exit 1
fi

# cd to the package directory
cd ${0%/*}

if [ -z "${SCRIPT_COMMAND}" ] ; then
    echo "Fatal error - SCRIPT_COMMAND has no value."
    exit 255
elif [ ${SCRIPT_COMMAND} = "uninstall" ] ; then
    uninstall_kit
elif [ ${SCRIPT_COMMAND} = "install" ] ; then
    install_kit
elif [ ${SCRIPT_COMMAND} = "createramdisk" ] ; then
    create_ramdisk
    case "$?" in
	0)
	    echo "The ramdisk for this kernel has been updated."
	    ;;
	*)
	    echo "Error creating a ramdisk image for the running kernel."
	    exit 47
	    ;;
    esac
elif [ ${SCRIPT_COMMAND} = "configramdisk" ] ; then
    configure_ramdisk
	let TEMPVALUE=$?
	if [ $((${TEMPVALUE} & 1)) -ne 0 ] ; then
	    create_ramdisk
	    case "$?" in
		0)
		    echo "The ramdisk for this kernel has been updated."
		    ;;
		*)
		    echo "Error creating ramdisk image for the running kernel."
		    exit 40
		    ;;
	    esac
	fi
	if [ $((${TEMPVALUE} & 2)) -ne 0 ] ; then
	    echo "The 'options scsi_mod' line in /etc/modprobe.conf contains"
	    echo "an invalid value for the 'scsi_allow_ghost_devices' option."
	    echo "The LPFC driver requires this option to have a value of 1."
	    echo "Please adjust the configuration of any drivers that require"
	    echo "the current value of this option, set this option to '1', and"
	    echo "then execute:"
	    echo "${0} --createramdisk"
	fi
	if [ $((${TEMPVALUE} & 4)) -ne 0 ] ; then
	    echo "Multiple 'options scsi_mod' lines exist in /etc/modprobe.conf."
	    echo "Please remove the redundant lines and then execute:"
	    echo "  ${0} --configramdisk"
	fi
	if [ $((${TEMPVALUE} & 8)) -ne 0 ] ; then
	    echo "An 'alias scsi_hostadapter off' entry exists in the"
	    echo "/etc/modprobe.conf file.  Please resolve any configuration"
	    echo "that depends on this entry, remove the entry, and then"
	    echo "execute:"
	    echo "  ${0} --configramdisk"
	fi
elif [ ${SCRIPT_COMMAND} = "unconfigramdisk" ] ; then
    unconfigure_ramdisk
    let TEMPVALUE=$?
    if [ $((${TEMPVALUE} & 1)) -ne 0 ] ; then
	create_ramdisk
	case "$?" in
	    0) echo "The ramdisk for this kernel has been updated." ;;
	    *) let UNINSTALL_ERRORS=${UNINSTALL_ERRORS}+1 ;;
	esac
    fi
else
    echo "Fatal error - invalid value for SCRIPT_COMMAND."
    exit 255
fi

exit 0
