#!/usr/bin/make
# Makefile for building Linux ib_peer_mem module for gpudirect support
# $id$
KVER=
ifeq ($(KVER),)
  KVER=$(shell uname -r)
endif

__ARCH=$(shell uname -m)

# PREFIX may be set by the RPM build to set the effective root.
PREFIX=
ifeq ($(shell ls /lib/modules/$(KVER)/build > /dev/null 2>&1 && echo build),)
# SuSE source RPMs
  _KVER=$(shell echo $(KVER) | cut -d "-" -f1,2)
  _KFLA=$(shell echo $(KVER) | cut -d "-" -f3)
  _ARCH=$(shell file -b /lib/modules/$(shell uname -r)/build | cut -d "/" -f5)
  ifeq ($(_ARCH),)
    _ARCH=$(__ARCH)
  endif
  ifeq ($(shell ls /usr/src/linux-$(_KVER)-obj > /dev/null 2>&1 && echo linux),)
    ifeq ($(shell ls /usr/src/kernels/$(KVER)-$(__ARCH) > /dev/null 2>&1 && echo linux),)
      LINUX=
    else
      LINUX=/usr/src/kernels/$(KVER)-$(__ARCH)
      LINUXSRC=$(LINUX)
    endif
  else
    LINUX=/usr/src/linux-$(_KVER)-obj/$(_ARCH)/$(_KFLA)
    LINUXSRC=/usr/src/linux-$(_KVER)
  endif
else
  LINUX=/lib/modules/$(KVER)/build
  ifeq ($(shell ls /lib/modules/$(KVER)/source > /dev/null 2>&1 && echo source),)
    LINUXSRC=$(LINUX)
  else
    LINUXSRC=/lib/modules/$(KVER)/source
  endif
endif

ifeq ($(shell ls $(LINUXSRC)/include/uapi > /dev/null 2>&1 && echo uapi),)
  UAPI=
else
  UAPI=uapi
endif

ifeq ($(BCMMODDIR),)
  ifeq ($(shell ls /lib/modules/$(KVER)/updates > /dev/null 2>&1 && echo 1),1)
    BCMMODDIR=/lib/modules/$(KVER)/updates/
  else
    ifeq ($(shell grep -q "search.*[[:space:]]updates" /etc/depmod.conf > /dev/null 2>&1 && echo 1),1)
      BCMMODDIR=/lib/modules/$(KVER)/updates/
    else
      ifeq ($(shell grep -q "search.*[[:space:]]updates" /etc/depmod.d/* > /dev/null 2>&1 && echo 1),1)
        BCMMODDIR=/lib/modules/$(KVER)/updates/
      else
        BCMMODDIR=/lib/modules/$(KVER)/kernel/
      endif
    endif
  endif
endif

ifeq ($(OFED_VERSION), )
     $(warning Using native IB stack)
     $(warning Please check OS support matrix. Run export OFED_VERSION=OFED-3.18-2 if OFED is installed)
     OFED_VERSION=OFED-NATIVE
endif

#find OFED version and compat-includes
ofed_major=$(filter OFED-3.% OFED-4.%, $(OFED_VERSION))
ifneq ($(ofed_major), )
exists=$(shell if [ -e /usr/src/compat-rdma$(OFED_VERSION) ];\
                then echo y; fi)
ifeq ($(exists), )
$(shell ln -s /usr/src/compat-rdma\
         /usr/src/compat-rdma$(OFED_VERSION))
endif
OFA_BUILD_PATH=/usr/src/compat-rdma$(OFED_VERSION)
OFA_KERNEL_PATH=/usr/src/compat-rdma$(OFED_VERSION)
EXTRA_CFLAGS += -DOFED_3_x
EXTRA_CFLAGS += -include $(OFA_KERNEL_PATH)/include/linux/compat-2.6.h

AUTOCONF_H = -include $(shell /bin/ls -1 $(LINUX)/include/*/autoconf.h 2> /dev/null | head -1)
endif #end non 3.x OFED

ifeq (OFED-NATIVE, $(findstring OFED-NATIVE, $(OFED_VERSION)))
OFA_KERNEL_PATH=$(LINUXSRC)
OFA_BUILD_PATH=$(LINUX)
else
KBUILD_EXTRA_SYMBOLS := $(OFA_BUILD_PATH)/Module.symvers
endif

ifeq ($(shell ls /lib/modules/$(KVER)/source > /dev/null 2>&1 && echo source),)
OFA_KERNEL_PATH=$(OFA_BUILD_PATH)
endif


# Distro specific compilation flags
DISTRO_CFLAG = -D__LINUX

KSRC=$(LINUXSRC)

ifeq ($(USE_NVIDIA_GPU),1)
  ccflags-y += -DUSE_NVIDIA_GPU
endif

ifneq ($(shell grep "DEFINE_DMA_ATTRS" $(LINUXSRC)/include/linux/dma-attrs.h > /dev/null 2>&1 && echo dma_attrs),)
  DISTRO_CFLAG += -DHAVE_DEFINE_DMA_ATTRS
endif

ifneq ($(shell grep "get_user_pages_longterm" $(LINUXSRC)/include/linux/mm.h > /dev/null 2>&1 && echo longterm),)
  DISTRO_CFLAG += -DHAVE_GET_USER_PAGES_LONGTERM
endif

ifneq ($(shell grep "get_user_pages_remote" $(LINUXSRC)/include/linux/mm.h > /dev/null 2>&1 && echo task_struct),)
  DISTRO_CFLAG += -DHAVE_GET_USER_PAGES_REMOTE
endif

ifneq ($(shell grep -o "page_shift" $(OFA_KERNEL_PATH)/include/rdma/ib_umem.h),)
  DISTRO_CFLAG += -DHAVE_IB_UMEM_PAGE_SHIFT
endif

ifneq ($(shell grep -o "page_size" $(OFA_KERNEL_PATH)/include/rdma/ib_umem.h),)
  DISTRO_CFLAG += -DHAVE_IB_UMEM_PAGE_SIZE
endif

ifneq ($(shell grep "ib_umem " $(OFA_KERNEL_PATH)/include/rdma/ib_umem.h -A1| grep -o "ib_device"),)
  DISTRO_CFLAG += -DHAVE_IB_DEVICE_IN_UMEM
endif

ifneq ($(shell grep -o "ib_access_writable" $(OFA_KERNEL_PATH)/include/rdma/ib_verbs.h),)
  DISTRO_CFLAG += -DHAVE_IB_ACCESS_WRITABLE
endif

ifneq ($(shell grep "(*add)" $(OFA_KERNEL_PATH)/include/rdma/ib_verbs.h | grep -o "int"),)
  DISTRO_CFLAG += -DHAVE_IB_CLIENT_ADD_RET
endif

ifeq ($(shell test -e $(LINUXSRC)/include/linux/sched/mm.h && echo -n yes),yes)
  DISTRO_CFLAG += -DHAVE_LINUX_SCHED_MM_H
endif
ifeq ($(shell test -e $(LINUXSRC)/include/linux/sched/signal.h && echo -n yes),yes)
  DISTRO_CFLAG += -DHAVE_LINUX_SCHED__SIGNAL_H
endif

ifneq ($(shell grep "ib_umem_get" $(OFA_KERNEL_PATH)/include/rdma/ib_umem.h | grep -o "udata"),)
  DISTRO_CFLAG += -DHAVE_UDATA_IN_IB_UMEM_GET
endif

ifneq ($(shell grep "ib_umem_get" $(OFA_KERNEL_PATH)/include/rdma/ib_umem.h | grep -o "ib_device"),)
  DISTRO_CFLAG += -DHAVE_IB_DEVICE_IN_IB_UMEM_GET
endif

ifneq ($(shell grep "ib_umem_get" $(OFA_KERNEL_PATH)/include/rdma/ib_umem.h -A1| grep -o "dmasync"),)
  DISTRO_CFLAG += -DHAVE_DMASYNC_IB_UMEM_GET
endif

ifneq ($(shell grep "sg_append_table" $(OFA_KERNEL_PATH)/include/rdma/ib_umem.h > /dev/null 2>&1 && echo sg_append_table),)
  DISTRO_CFLAG += -DHAVE_IB_UMEM_SG_APPEND_TABLE
endif

ifneq ($(shell grep -w "mm_kobj" $(LINUX)/Module.symvers),)
  DISTRO_CFLAG += -DHAVE_MM_KOBJ_EXPORT
endif

EXTRA_CFLAGS += ${DISTRO_CFLAG}

ifneq (OFED-NATIVE, $(findstring OFED-NATIVE, $(OFED_VERSION)))
OFED_INCLUDES := LINUXINCLUDE=' \
                $(AUTOCONF_H) \
                -I$(OFA_KERNEL_PATH)/include \
                -I$(OFA_KERNEL_PATH)/include/uapi \
		 $$(if $$(CONFIG_XEN),-D__XEN_INTERFACE_VERSION__=$$(CONFIG_XEN_INTERFACE_VERSION)) \
		 $$(if $$(CONFIG_XEN),-I$$(KSRC)/arch/x86/include/mach-xen) \
                -I$(OFA_KERNEL_PATH)/arch/$$(SRCARCH)/include/generated/uapi \
                -I$(OFA_KERNEL_PATH)/arch/$$(SRCARCH)/include/generated \
                -Iinclude \
                -I$(KSRC)/include \
                -I$(KSRC)/arch/$$(SRCARCH)/include \
                -I$(KSRC)/include/generated/uapi \
                -I$(KSRC)/include/uapi \
                -I$(KSRC)/arch/$$(SRCARCH)/include/uapi \
                -I$(KSRC)/arch/$$(SRCARCH)/include/generated \
                -I$(KSRC)/arch/$$(SRCARCH)/include/generated/uapi \
                -I$(KDIR)/include/generated/uapi \
                -I$(KDIR)/arch/$$(SRCARCH)/include/generated \
                -I$(KDIR)/arch/$$(SRCARCH)/include/generated/uapi'

OFA_KERNEL_LINK = $(OFA_KERNEL_PATH)
OFA_BUILD_LINK = $(OFA_BUILD_PATH)
endif

cflags-y += $(EXTRA_CFLAGS)

ifneq ($(KERNELRELEASE),)
obj-m += ib_peer_mem.o
ib_peer_mem-y := peer_mem.o peer_umem.o peer_compat.o
else

default:
	make -C $(LINUX) M=$(shell pwd) $(OFED_INCLUDES)

yocto_all:
	$(MAKE) -C $(LINUXSRC) M=$(shell pwd)

modules_install:
	$(MAKE) -C $(LINUXSRC) M=$(shell pwd) modules_install

endif

BCM_DRV = ib_peer_mem.ko

install: default
	echo $(PREFIX)
	echo $(BCMMODDIR)
	echo $(BCM_DRV)
	mkdir -p $(PREFIX)/$(BCMMODDIR);
	install -m 444 $(BCM_DRV) $(PREFIX)/$(BCMMODDIR);

.PHONEY: all clean install

clean:
	$(MAKE) -C $(LINUX) M=$(shell pwd) clean

