# ATTO Linux Driver Makefile

# Figure out what sort of driver we are building

ifeq ($(DRIVER_NAME),)
DRIVER_NAME := $(shell ls *core_x86.o | cut -d_ -f1)
endif

ifeq ($(DRIVER_NAME),)
blankdrivername:
	@echo 
	@echo Error: Unable to detect driver name
	@echo 
	@false
else
ifeq ($(DRIVER_NAME), celerityfc)
PRETTY_NAME := "Celerity FC"
FAMILY_COMPILE_FLAG := "CELERITYFC"
INSTALL_API := "yes"
else
ifeq ($(DRIVER_NAME), express2)
PRETTY_NAME := "EPCI U320"
FAMILY_COMPILE_FLAG := "EXPRESS2"
else
ifeq ($(DRIVER_NAME), esasraid)
PRETTY_NAME := "ESAS RAID"
FAMILY_COMPILE_FLAG := "ESASRAID"
else
ifeq ($(DRIVER_NAME), esashba)
PRETTY_NAME := "ExpressSAS 3GB HBA"
FAMILY_COMPILE_FLAG := "ESASHBA"
NEED_SCSIREQUEST_H := 1
else
ifeq ($(DRIVER_NAME), celerity8fc)
PRETTY_NAME := "Celerity FC 8GB"
FAMILY_COMPILE_FLAG := "CELERITY8FC"
INSTALL_API := "yes"
else
ifeq ($(DRIVER_NAME), esas2hba)
PRETTY_NAME := "ExpressSAS 6GB HBA"
FAMILY_COMPILE_FLAG := "ESAS2HBA"
NEED_SCSIREQUEST_H := 1
else
errordrivername:
	@echo 
	@echo Error: Unknown driver name [$(DRIVER_NAME)]
	@echo 
	@false
endif
endif
endif
endif
endif
endif
endif

# Get the current kernel version.  This makefile assumes
# that the user is compiling the driver for whatever
# kernel they are currently running;  if this is not
# the case, specify the correct kernel header path on
# the 'make' command line with 'KDIR=/correct/path'

ifeq ($(KDIR),)
FULL_KERNEL_VERSION := $(shell uname -r)

# Figure out where the kernel header files are located
KDIR := "/lib/modules/$(FULL_KERNEL_VERSION)/build"
else

# User has specified a different kernel header path,
# try to extract the full kernel version from it
ifneq ($(shell test -f $(KDIR)/include/linux/utsrelease.h || echo 1),1)
FULL_KERNEL_VERSION := $(shell grep UTS_RELEASE $(KDIR)/include/linux/utsrelease.h | cut -d" " -f3,3)
else
ifneq ($(shell test -f $(KDIR)/include/linux/version.h || echo 1),1)
FULL_KERNEL_VERSION := $(shell grep UTS_RELEASE $(KDIR)/include/linux/version.h | cut -d" " -f3,3)
else
FULL_KERNEL_VERSION := "2.6.1-invalid"
endif
endif
endif

# Extract the major & minor version number so we know
# how to proceed in the build (2.4 or 2.6 series kernels)

KERNEL_VERSION := $(shell echo $(FULL_KERNEL_VERSION) | cut -d. -f1,2)

# Figure out if config.h exists

ifneq ($(shell test -f $(KDIR)/include/linux/config.h || echo 1),1)
DEFINE_FLAGS := -DATTO_USE_CONFIG_H
endif

ifeq ($(NEED_SCSIREQUEST_H), 1)
# Some versions of SUSE do not have the "scsi" include directory
# in the kernel build tree.  Figure out if this is the case and
# use the include in the kernel source tree if it exists
ifeq ($(shell test -d $(KDIR)/include/scsi || echo 1),1)
ifeq ($(shell test -d /usr/src/linux/include/scsi || echo 1),1)
noscsiincludes:
	@echo 
	@echo Error: You must install the kernel source code for this driver to build.
	@echo 
	@false
endif
ifneq ($(shell test -f /usr/src/linux/include/scsi/scsi_request.h || echo 1),1)
DEFINE_FLAGS := -DATTO_USE_SCSIREQUEST_H_IN_SRC_TREE
endif
else
# Figure out if scsi_request.h exists

ifneq ($(shell test -f $(KDIR)/include/scsi/scsi_request.h || echo 1),1)
DEFINE_FLAGS := -DATTO_USE_SCSIREQUEST_H
endif
endif
endif

# Save the current directory

ifeq ($(PWD),)
PWD := $(shell pwd)
endif

# Figure out which architecture we are on
# This determines which core file to link to,
# and which attofc*.so library to install.

ifeq ($(ARCH),)
ARCH := $(shell uname -m | sed -e s/i.86/i386/)
endif

# i386 section (ia32)
ifeq ($(ARCH), i386)
    CORE_TYPE    := x86
    ATTOFC_TYPE  := x86
    ARCH_CFLAG   := -DOS_32BIT -march=i486
    ARCH_LD      := -m elf_i386

ifeq ($(KERNEL_VERSION),2.6)
# Extract the subminor version & force CONFIG_REGPARM if necessary
# (2.6.20 and greater always use -mregparm=3)

KERNEL_SUBMINOR_VERSION := $(shell echo $(FULL_KERNEL_VERSION) | cut -d. -f3,3 | cut -d- -f1,1)

ifeq ($(shell test $(KERNEL_SUBMINOR_VERSION) -lt 20 || echo 1),1)
CONFIG_REGPARM=1
endif
endif

# Kernel was built with -mregparm=3

    ifdef CONFIG_REGPARM
	CORE_TYPE    := x86_regparm
    endif
endif

# ia64 section (Itanium)
ifeq ($(ARCH),ia64)
    CORE_TYPE    := ia64
    ATTOFC_TYPE  := ia64
    ARCH_CFLAG   := -DOS_64BIT
    ifeq ($(KERNEL_VERSION),2.4)
	ARCH_CFLAG   += -ffixed-r13 -mfixed-range=f10-f15,f32-f127 \
			-falign-functions=32 -frename-registers    \
			--param max-inline-insns=5000
	ARCH_LD      := -m elf64_ia64
    endif
endif

# x86_64 section (AMD64/EM64T)
ifeq ($(ARCH),x86_64)
    CORE_TYPE    := x86_64
    ATTOFC_TYPE  := x86_64
    ARCH_CFLAG   := -DOS_64BIT
    ifeq ($(KERNEL_VERSION),2.4)
	ARCH_CFLAG   += -mcmodel=kernel -mno-red-zone -DATTO_USE_KERNEL24_SCSI_TAPE_WORKAROUND
	ARCH_LD      := -m elf_x86_64
    endif
endif


# Finished product names

CORE_NAME    := $(DRIVER_NAME)_core_$(CORE_TYPE).o
ATTOFC_NAME  := attofc_$(ATTOFC_TYPE).so

all: checkkernel
	@echo
	@echo "ATTO $(PRETTY_NAME) Driver Makefile"
	@echo
ifeq ($(DRIVER_NAME), celerityfc)
	@echo "Celerity FC HBA driver & SNIA HBA API library"
	@echo
else
ifeq ($(DRIVER_NAME), celerity8fc)
	@echo "Celerity FC 8GB HBA driver & SNIA HBA API library"
	@echo
endif
endif
	@echo "Detected kernel version:  $(FULL_KERNEL_VERSION)"
	@echo "Kernel build directory:   $(KDIR)"
ifdef CONFIG_REGPARM
	@echo "Architecture:             $(ARCH) (regparm)"
else
	@echo "Architecture:             $(ARCH)"
endif
	@echo
	@echo "Options:"
	@echo "   make install     - build & install the drivers (recommended)"
	@echo "   make modules     - build the drivers (but do not install)"
	@echo "   make clean       - delete previously built drivers and objects"
	@echo

checkkernel:
ifneq ($(KERNEL_VERSION),2.6)
ifneq ($(KERNEL_VERSION),2.4)
	@echo "This driver only works with Linux kernel version 2.4 or 2.6"
	@echo "You appear to be running kernel version $(KERNEL_VERSION)"
	@false
endif
endif
	@true

KERNEL_HEADERS := -I$(KDIR)/include
MODULE_ROOT    := /lib/modules/$(FULL_KERNEL_VERSION)/kernel/drivers
DEFINE_FLAGS   += -D$(FAMILY_COMPILE_FLAG)

# if you want to print some debugging info to
# the syslog, uncomment this line:
#DEFINE_FLAGS += -DATTO_DEBUG

# ...and if you want even more, uncomment this one too:
#DEFINE_FLAGS += -DATTO_DEBUG_LOUD


ifeq ($(KERNEL_VERSION),2.6)
# start of stuff for 2.6.x kernels

$(DRIVER_NAME)-objs := $(CORE_NAME) oswrap.o osutil.o
attocfg-objs	   := atto_cfg.o
obj-m		  := $(DRIVER_NAME).o attocfg.o
EXTRA_CFLAGS	   += -I$(KDIR)/drivers/scsi -I$(obj) -DLINUX $(ARCH_CFLAG) $(DEFINE_FLAGS)
EXTRA_LDFLAGS	  := -d

src ?= .
obj ?= .

# These here should never be used, as they're just a stub for
# kbuild, so that it doesn't try to build the core files

$(obj)/$(CORE_NAME):
	@echo
	@echo
	@echo "ERROR: Core file $(CORE_NAME) is missing!"
	@echo
	@echo
	@false

modules:
	@echo "Architecture is $(ARCH) ($(CORE_TYPE))"
	@$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) ARCH=$(ARCH) DRIVER_NAME=$(DRIVER_NAME) modules
	@echo "$(DRIVER_NAME) and attocfg modules built"

ifeq ($(INSTALL_API), "yes")
install: modules api_install
else
install: modules
endif
	@mkdir -p $(MODULE_ROOT)
	@mkdir -p $(MODULE_ROOT)/scsi
	@install -m 0744 -o root -g root $(DRIVER_NAME).ko $(MODULE_ROOT)/scsi
	@install -m 0744 -o root -g root attocfg.ko	   $(MODULE_ROOT)
	@depmod -ae $(FULL_KERNEL_VERSION)
ifeq ($(INSTALL_API), "yes")
	@echo "Modules and library installed"
else
	@echo "Modules installed"
endif
endif


ifeq ($(KERNEL_VERSION),2.4)
# start of stuff for 2.4.x kernels

DEFINE_FLAGS += -DLINUX -D__KERNEL__ -DMODULE -DMODVERSIONS

CFLAGS := -Wall $(DEFINE_FLAGS) \
	  -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce \
	  -pipe -falign-loops=2 -falign-jumps=2 -falign-functions=2 \
	  -DCONFIG_X86_LOCAL_APIC $(ARCH_CFLAG) \
	  -I$(KDIR)/include -I$(PWD) \
	  -I$(KDIR)/drivers/scsi -O2

ATTO_INCLUDES := oswrap.h
ATTO_OBJS := $(CORE_NAME) oswrap.o osutil.o

$(DRIVER_NAME): $(ATTO_OBJS)
	@ld $(ARCH_LD) -r -o $(DRIVER_NAME).o $(ATTO_OBJS)
	@echo "$(DRIVER_NAME) module built"

oswrap.o: oswrap.c $(ATTO_INCLUDES)
	@$(CC) $(CFLAGS) -c oswrap.c

osutil.o: osutil.c $(ATTO_INCLUDES)
	@$(CC) $(CFLAGS) -c osutil.c

modules: $(DRIVER_NAME)

ifeq ($(INSTALL_API), "yes")
install: modules api_install
else
install: modules
endif
	@mkdir -p $(MODULE_ROOT)
	@mkdir -p $(MODULE_ROOT)/scsi
	@cp $(DRIVER_NAME).o $(MODULE_ROOT)/scsi
	@/sbin/depmod -a $(FULL_KERNEL_VERSION)
ifeq ($(INSTALL_API), "yes")
	@echo "Module and library installed"
else
	@echo "Module installed"
endif
endif

clean:
	@rm -f oswrap.o $(DRIVER_NAME).o osutil.o attocfg.o atto_cfg.o *.ko
	@rm -f \.*o.cmd *.mod.*

ifeq ($(INSTALL_API), "yes")
api_install:    $(ATTOFC_NAME) checkkernel
		@rm -f /usr/lib/attofc.so
		@cp $(ATTOFC_NAME) /usr/lib
		@if [ -f /etc/hba.conf ]; then \
		    mv /etc/hba.conf /etc/hba.conf.orig; \
		    grep -v attofc /etc/hba.conf.orig > /etc/hba.conf; \
		    true; \
		fi;
		@echo "com.attotech.$(DRIVER_NAME)   /usr/lib/$(ATTOFC_NAME)" >> /etc/hba.conf
		@echo "ATTO SNIA HBA API library installation completed"
endif
