#
#  SCSI target mid-level makefile
#
#  Copyright (C) 2015 - 2018 Vladislav Bolkhovitin <vst@vlnb.net>
#  Copyright (C) 2004 - 2005 Leonid Stoljar
#  Copyright (C) 2007 - 2018 Western Digital Corporation
#
#  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, version 2
#  of the License.
#
#  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. See the
#  GNU General Public License for more details.
#
#
# Main targets:
#    all (the default) : make all
#    clean             : clean files
#    extraclean        : clean + clean dependencies
#    install           : install
#    uninstall         : uninstall
#
# Notes :
#    - install and uninstall must be made as root
#

ifndef PREFIX
        PREFIX=/usr/local
endif

SHELL=/bin/bash

DEV_HANDLERS_DIR = dev_handlers

ifneq ($(PATCHLEVEL),)
SCST_INC_DIR := $(KBUILD_EXTMOD)/../include

obj-m := scst.o

scst-y        += scst_main.o
scst-y        += scst_targ.o
scst-y        += scst_lib.o
#scst-y        += scst_proc.o
scst-y        += scst_sysfs.o
scst-y        += scst_mem.o
scst-y        += scst_debug.o
scst-y        += scst_pres.o
scst-y        += scst_no_dlm.o
scst-y        += scst_dlm.o
scst-y        += scst_tg.o
scst-y        += scst_event.o
scst-y        += scst_copy_mgr.o
obj-$(CONFIG_SCST)   += scst.o dev_handlers/

obj-$(BUILD_DEV) += $(DEV_HANDLERS_DIR)/

else
######### BEGIN OUT-OF-TREE RULES #########

ifeq ($(KVER),)
  ifeq ($(KDIR),)
    KVER := $(shell uname -r)
    KDIR := /lib/modules/$(KVER)/build
  else
    KVER := $(strip $(shell						\
	cat $(KDIR)/include/config/kernel.release 2>/dev/null ||	\
	make -s -C $(KDIR) kernelversion))
  endif
else
  KDIR := /lib/modules/$(KVER)/build
endif

ifeq ($(INSTALL_MOD_PATH),)
  export INSTALL_MOD_PATH := $(DESTDIR)
endif

ifeq ($(SCST_INC_DIR),)
SCST_INC_DIR := ../include
endif

SCST_INTF_VER_FILE := $(SCST_INC_DIR)/scst_itf_ver.h

$(SCST_INTF_VER_FILE): $(SCST_INC_DIR)/scst.h $(SCST_INC_DIR)/scst_const.h $(SCST_INC_DIR)/scst_user.h
	echo "/* Autogenerated, don't edit */" >$(SCST_INTF_VER_FILE)
	echo "" >>$(SCST_INTF_VER_FILE)
	echo -n "#define SCST_INTF_VER " >>$(SCST_INTF_VER_FILE)
	echo "\"`sha1sum $(SCST_INC_DIR)/scst.h|awk '{printf $$1}'`\"" >>$(SCST_INTF_VER_FILE)
	echo -n "#define SCST_CONST_INTF_VER " >>$(SCST_INTF_VER_FILE)
	echo "\"`sha1sum $(SCST_INC_DIR)/scst_const.h|awk '{printf $$1}'`\"" >>$(SCST_INTF_VER_FILE)
	echo -n "#define DEV_USER_INTF_VER " >>$(SCST_INTF_VER_FILE)
	echo "\"`sha1sum $(SCST_INC_DIR)/scst_user.h|awk '{printf $$1}'`\"" >>$(SCST_INTF_VER_FILE)

all: $(SCST_INTF_VER_FILE)
	$(MAKE) -C $(KDIR) M=$(shell pwd) BUILD_DEV=m

scst:
	$(MAKE) -C $(KDIR) M=$(shell pwd) BUILD_DEV=n

# The file Modules.symvers has been renamed in the 2.6.18 kernel to
# Module.symvers. Find out which name to use by looking in $(KDIR).
MODULE_SYMVERS:=$(shell if [ -e $(KDIR)/Modules.symvers ]; then \
		       echo Modules.symvers; else echo Module.symvers; fi)

install: all
	@if [ -z "$(DESTDIR)" ] && \
        { rpm -q scst || rpm -q scst-devel; } >/dev/null 2>&1; then \
	echo Error: the scst and/or scst-devel RPMs must be uninstalled first; \
	false; fi
	-rm -f $(INSTALL_DIR)/scsi_tgt.ko
	$(MAKE) -C $(KDIR) M=$(shell pwd)/dev_handlers			\
	  modules_install
	$(MAKE) -C $(KDIR) M=$(shell pwd)				\
	  $$([ -n "$(DESTDIR)$(INSTALL_MOD_PATH)" ] && echo DEPMOD=true)\
	  modules_install
	install -d $(INSTALL_DIR_H)
	header_files="backport.h scst.h scst_const.h scst_debug.h	\
		      scst_itf_ver.h scst_sgv.h scst_user.h";		\
	for h in $${header_files}; do					\
	    install -m 644 ../include/$$h $(INSTALL_DIR_H);		\
	done
	rm -f $(INSTALL_DIR_H)/$(MODULE_SYMVERS)
	install -m 644 $(MODULE_SYMVERS) $(INSTALL_DIR_H)
	mkdir -p $(DESTDIR)/var/lib/scst/pr
	mkdir -p $(DESTDIR)/var/lib/scst/dif_tags
	mkdir -p $(DESTDIR)/var/lib/scst/vdev_mode_pages
	@echo "****************************************************************"
	@echo "*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*"
	@echo "*!!                                                          !!*"
	@echo "*!!  Now don't forget to rebuild and reinstall all your      !!*"
	@echo "*!!  target drivers, custom dev handlers and necessary user  !!*"
	@echo "*!!  space applications. Otherwise, because of the versions  !!*"
	@echo "*!!  mismatch, you could have many problems and crashes.     !!*"
	@echo "*!!  See IMPORTANT note in the \"Installation\" section of     !!*"
	@echo "*!!  SCST's README file for more info.                       !!*"
	@echo "*!!                                                          !!*"
	@echo "*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*"
	@echo "****************************************************************"

uninstall:
	cd $(DEV_HANDLERS_DIR) && $(MAKE) $@
	rm -f $(INSTALL_DIR)/scst.ko
	-rmdir $(INSTALL_DIR) 2>/dev/null
	-/sbin/depmod -b $(INSTALL_MOD_PATH)/ -a $(KVER)
	rm -rf $(INSTALL_DIR_H)

########## END OUT-OF-TREE RULES ##########
endif

INSTALL_DIR := $(INSTALL_MOD_PATH)/lib/modules/$(KVER)/extra
INSTALL_DIR_H := $(DESTDIR)$(PREFIX)/include/scst

enable-Wextra = $(shell uname_r="$$(uname -r)"; if [ "$${uname_r%.el5}" = "$${uname_r}" ]; then echo "$(1)"; fi)

EXTRA_CFLAGS += -I$(SCST_INC_DIR) $(call enable-Wextra,-Wextra \
	-Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare) \
	$(shell [ -n "${CONFIG_SCST_NO_DLM}" ] && echo -DCONFIG_SCST_NO_DLM)

#EXTRA_CFLAGS += -DCONFIG_SCST_STRICT_SERIALIZING

EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS

#EXTRA_CFLAGS += -DCONFIG_SCST_USE_EXPECTED_VALUES
#EXTRA_CFLAGS += -DCONFIG_SCST_TEST_IO_IN_SIRQ
#EXTRA_CFLAGS += -DCONFIG_SCST_ABORT_CONSIDER_FINISHED_TASKS_AS_NOT_EXISTING

#EXTRA_CFLAGS += -fno-inline

#EXTRA_CFLAGS += -DCONFIG_SCST_TRACING

EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g -fno-inline -fno-inline-functions
#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_RETRY
#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_OOM
#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_SN
#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_SYSFS_EAGAIN

# If defined, makes SCST zero allocated data buffers.
# Undefining it considerably improves performance and eases CPU load,
# but could create a security hole (information leakage), so
# enable it if you have strict security requirements.
#EXTRA_CFLAGS += -DSCST_STRICT_SECURITY

clean:
	rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend Modules.symvers \
		Module.symvers Module.markers modules.order
	rm -rf .tmp_versions
	cd $(DEV_HANDLERS_DIR) && $(MAKE) $@

extraclean: clean
	rm -f $(SCST_INTF_VER_FILE)
	cd $(DEV_HANDLERS_DIR) && $(MAKE) $@
	rm -f *.orig *.rej

2release:
	sed -i.aa s/"^E\?XTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ Makefile
	grep "^#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS" Makefile >/dev/null
	sed -i.aa s/"^#\?EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/"EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/ Makefile
	grep "^EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING" Makefile >/dev/null
	sed -i.aa s/"^E\?XTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g -fno-inline -fno-inline-functions"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g -fno-inline -fno-inline-functions"/ Makefile
	grep "^#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g -fno-inline -fno-inline-functions" Makefile >/dev/null
	rm Makefile.aa
	cd $(DEV_HANDLERS_DIR) && $(MAKE) $@

2debug:
	sed -i.aa s/"^#\?EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ Makefile
	grep "^EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS" Makefile >/dev/null
	sed -i.aa s/"^E\?XTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/ Makefile
	grep "^#EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING" Makefile >/dev/null
	sed -i.aa s/"^#\?EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g -fno-inline -fno-inline-functions"/"EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g -fno-inline -fno-inline-functions"/ Makefile
	grep "^EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g -fno-inline -fno-inline-functions" Makefile >/dev/null
	rm Makefile.aa
	cd $(DEV_HANDLERS_DIR) && $(MAKE) $@

2perf:
	sed -i.aa s/"^E\?XTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ Makefile
	grep "^#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS" Makefile >/dev/null
	sed -i.aa s/"^E\?XTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/ Makefile
	grep "^#EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING" Makefile >/dev/null
	sed -i.aa s/"^E\?XTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g -fno-inline -fno-inline-functions"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g -fno-inline -fno-inline-functions"/ Makefile
	grep "^#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g -fno-inline -fno-inline-functions" Makefile >/dev/null
	rm Makefile.aa
	cd $(DEV_HANDLERS_DIR) && $(MAKE) $@

disable_proc:
	sed -i.aa s/"^#\?define CONFIG_SCST_PROC"/"\/* #define CONFIG_SCST_PROC *\/"/ ../include/scst.h
	grep "^\/\* #define CONFIG_SCST_PROC \*\/" ../include/scst.h >/dev/null
	rm ../include/scst.h.aa
	sed -i.aa s/"^s\?cst-y        += scst_proc.o"/"#scst\-y        += scst_proc.o"/ Makefile
	grep "^#scst\-y        += scst_proc.o" Makefile >/dev/null
	sed -i.aa s/"^#\?scst\-y        += scst_sysfs.o"/"scst\-y        += scst_sysfs.o"/ Makefile
	grep "^scst\-y        += scst_sysfs.o" Makefile >/dev/null
	rm Makefile.aa

enable_proc:
	sed -i.aa s/"^\/\?\* #define CONFIG_SCST_PROC \*\/"/"#define CONFIG_SCST_PROC"/ ../include/scst.h
	grep "^#define CONFIG_SCST_PROC" ../include/scst.h >/dev/null
	rm ../include/scst.h.aa
	sed -i.aa s/"^#\?scst\-y        += scst_proc.o"/"scst\-y        += scst_proc.o"/ Makefile
	grep "^scst\-y        += scst_proc.o" Makefile >/dev/null
	sed -i.aa s/"^s\?cst\-y        += scst_sysfs.o"/"#scst\-y        += scst_sysfs.o"/ Makefile
	grep "^#scst\-y        += scst_sysfs.o" Makefile >/dev/null
	rm Makefile.aa

.PHONY: all install uninstall clean extraclean 2release 2debug 2perf disable_proc enable_proc
