obj-m := sprd.o
sprd-objs := sprd_main.o sprd_dev.o sprd_io.o sprd_ctl.o sprd_gc.o sprd_dump.o
ccflags-y := -DDEBUG -g

# Block-layer API feature detection. Distros backport mainline changes
# into kernels whose LINUX_VERSION_CODE still says 5.14 (notably RHEL
# 9.5+), so we grep the headers directly for each symbol we touch.
# One detection macro per symbol used -- never infer one symbol from
# another; piecemeal backports (RHEL 9.0 had QUEUE_FLAG_DISCARD with a
# void submit_bio) are exactly what this mechanism exists to survive.
# Supported floor: vanilla 5.10 / any RHEL 9 (RHEL's "5.14" carries the
# 5.16+ block layer). 5.10-5.13 take the legacy alloc_disk/blk_alloc_queue
# path (no blk_alloc_disk) but keep the same .submit_bio I/O model, which
# exists since 5.9. Below 5.10 is Tier 2 (make_request_fn) and unsupported.
#
# Patterns must stay mawk-compatible: \< \> word boundaries are a GNU
# extension that mawk (the default awk on Debian) SILENTLY fails to
# match, so word edges are spelled as an explicit non-ident class. The
# trailing class is what excludes e.g. GENHD_FL_NO_PART_SCAN.
SPRD_BLKDEV_H := $(srctree)/include/linux/blkdev.h
# genhd.h holds gendisk symbols on <= 5.17; merged into blkdev.h in 5.18.
SPRD_GENHD_H  := $(srctree)/include/linux/genhd.h
# blk_types.h holds struct bio (bi_bdev re-added in 5.12; bi_disk before).
SPRD_BIO_H    := $(srctree)/include/linux/blk_types.h

# Fail loudly if blkdev.h is unreadable: silent detection failure would
# otherwise build a module with a wrong-ABI submit_bio (only a warning on
# GCC < 14) and without discard support on 5.14-5.18.
$(if $(wildcard $(SPRD_BLKDEV_H)),,$(error sprd: cannot read $(SPRD_BLKDEV_H) - kernel headers missing?))
ccflags-y += $(shell awk \
	'/blk_alloc_disk[ \t]*\([^)]*queue_limits/          {a=1} \
	 /QUEUE_FLAG_DISCARD([^A-Za-z0-9_]|$$)/             {b=1} \
	 /blk_qc_t[^;]*\(\*submit_bio\)/                    {c=1} \
	 /BLK_FEAT_SYNCHRONOUS([^A-Za-z0-9_]|$$)/           {d=1} \
	 /QUEUE_FLAG_SYNCHRONOUS([^A-Za-z0-9_]|$$)/         {e=1} \
	 /BLK_FEAT_NOWAIT([^A-Za-z0-9_]|$$)/                {f=1} \
	 /GENHD_FL_NO_PART([^A-Za-z0-9_]|$$)/               {g=1} \
	 /blk_alloc_disk[^A-Za-z0-9_]/                      {h=1} \
	 /int[ \t][^;]*[^A-Za-z0-9_]add_disk[^A-Za-z0-9_]/  {i=1} \
	 /QUEUE_FLAG_NOWAIT([^A-Za-z0-9_]|$$)/              {j=1} \
	 /block_device[ \t]*\*[ \t]*bi_bdev([^A-Za-z0-9_]|$$)/ {k=1} \
	 /set_capacity_and_notify[^A-Za-z0-9_]/             {l=1} \
	 END { if (a) print "-DSPRD_HAS_QUEUE_LIMITS_ALLOC"; \
	       if (b) print "-DSPRD_HAS_QUEUE_FLAG_DISCARD"; \
	       if (c) print "-DSPRD_SUBMIT_BIO_RETURNS_BLK_QC_T"; \
	       if (d) print "-DSPRD_HAS_BLK_FEATURES"; \
	       if (e) print "-DSPRD_HAS_QUEUE_FLAG_SYNCHRONOUS"; \
	       if (f) print "-DSPRD_HAS_BLK_FEAT_NOWAIT"; \
	       if (g) print "-DSPRD_HAS_GENHD_FL_NO_PART"; \
	       if (h) print "-DSPRD_HAS_BLK_ALLOC_DISK"; \
	       if (i) print "-DSPRD_ADD_DISK_RETURNS_INT"; \
	       if (j) print "-DSPRD_HAS_QUEUE_FLAG_NOWAIT"; \
	       if (k) print "-DSPRD_HAS_BIO_BI_BDEV"; \
	       if (l) print "-DSPRD_HAS_SET_CAPACITY_AND_NOTIFY" }' \
	$(SPRD_BLKDEV_H) $(wildcard $(SPRD_GENHD_H)) $(wildcard $(SPRD_BIO_H)) 2>/dev/null)
