aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/linuxkpi/common/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/linuxkpi/common/include/linux')
-rw-r--r--sys/compat/linuxkpi/common/include/linux/acpi.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ascii85.h46
-rw-r--r--sys/compat/linuxkpi/common/include/linux/bcm47xx_nvram.h21
-rw-r--r--sys/compat/linuxkpi/common/include/linux/bcma/bcma.h29
-rw-r--r--sys/compat/linuxkpi/common/include/linux/bcma/bcma_regs.h17
-rw-r--r--sys/compat/linuxkpi/common/include/linux/bitops.h24
-rw-r--r--sys/compat/linuxkpi/common/include/linux/cec-funcs.h16
-rw-r--r--sys/compat/linuxkpi/common/include/linux/cec.h3
-rw-r--r--sys/compat/linuxkpi/common/include/linux/cgroup.h9
-rw-r--r--sys/compat/linuxkpi/common/include/linux/cleanup.h127
-rw-r--r--sys/compat/linuxkpi/common/include/linux/compiler.h48
-rw-r--r--sys/compat/linuxkpi/common/include/linux/compiler_attributes.h49
-rw-r--r--sys/compat/linuxkpi/common/include/linux/compiler_types.h58
-rw-r--r--sys/compat/linuxkpi/common/include/linux/device.h31
-rw-r--r--sys/compat/linuxkpi/common/include/linux/dma-mapping.h21
-rw-r--r--sys/compat/linuxkpi/common/include/linux/eventfd.h54
-rw-r--r--sys/compat/linuxkpi/common/include/linux/file.h5
-rw-r--r--sys/compat/linuxkpi/common/include/linux/font.h33
-rw-r--r--sys/compat/linuxkpi/common/include/linux/fs.h45
-rw-r--r--sys/compat/linuxkpi/common/include/linux/gfp.h6
-rw-r--r--sys/compat/linuxkpi/common/include/linux/hardirq.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/hex.h44
-rw-r--r--sys/compat/linuxkpi/common/include/linux/highmem.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/i2c.h7
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ieee80211.h44
-rw-r--r--sys/compat/linuxkpi/common/include/linux/instruction_pointer.h15
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ioport.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kconfig.h35
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kdev_t.h15
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kernel.h68
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kfifo.h26
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kmsg_dump.h93
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kstrtox.h57
-rw-r--r--sys/compat/linuxkpi/common/include/linux/linux_logo.h19
-rw-r--r--sys/compat/linuxkpi/common/include/linux/memcontrol.h43
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mfd/core.h49
-rw-r--r--sys/compat/linuxkpi/common/include/linux/minmax.h6
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mod_devicetable.h7
-rw-r--r--sys/compat/linuxkpi/common/include/linux/module.h18
-rw-r--r--sys/compat/linuxkpi/common/include/linux/netdevice.h24
-rw-r--r--sys/compat/linuxkpi/common/include/linux/notifier.h5
-rw-r--r--sys/compat/linuxkpi/common/include/linux/overflow.h144
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pci.h70
-rw-r--r--sys/compat/linuxkpi/common/include/linux/platform_data/brcmfmac.h185
-rw-r--r--sys/compat/linuxkpi/common/include/linux/printk.h10
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/radix-tree.h35
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ratelimit.h7
-rw-r--r--sys/compat/linuxkpi/common/include/linux/regulator/consumer.h17
-rw-r--r--sys/compat/linuxkpi/common/include/linux/seq_buf.h73
-rw-r--r--sys/compat/linuxkpi/common/include/linux/seq_file.h4
-rw-r--r--sys/compat/linuxkpi/common/include/linux/siphash.h168
-rw-r--r--sys/compat/linuxkpi/common/include/linux/sizes.h11
-rw-r--r--sys/compat/linuxkpi/common/include/linux/skbuff.h9
-rw-r--r--sys/compat/linuxkpi/common/include/linux/slab.h28
-rw-r--r--sys/compat/linuxkpi/common/include/linux/soc/airoha/airoha_offload.h48
-rw-r--r--sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h14
-rw-r--r--sys/compat/linuxkpi/common/include/linux/sort.h7
-rw-r--r--sys/compat/linuxkpi/common/include/linux/spinlock.h31
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ssb/ssb_regs.h25
-rw-r--r--sys/compat/linuxkpi/common/include/linux/string.h16
-rw-r--r--sys/compat/linuxkpi/common/include/linux/string_choices.h26
-rw-r--r--sys/compat/linuxkpi/common/include/linux/suspend.h6
-rw-r--r--sys/compat/linuxkpi/common/include/linux/swap.h7
-rw-r--r--sys/compat/linuxkpi/common/include/linux/sysfs.h34
-rw-r--r--sys/compat/linuxkpi/common/include/linux/uuid.h27
-rw-r--r--sys/compat/linuxkpi/common/include/linux/wait.h7
67 files changed, 1961 insertions, 271 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/acpi.h b/sys/compat/linuxkpi/common/include/linux/acpi.h
index 3e1ec1b20626..a764a975c983 100644
--- a/sys/compat/linuxkpi/common/include/linux/acpi.h
+++ b/sys/compat/linuxkpi/common/include/linux/acpi.h
@@ -32,7 +32,7 @@
#include <linux/device.h>
#include <linux/uuid.h>
-#if defined(__aarch64__) || defined(__amd64__) || defined(__i386__)
+#if defined(__aarch64__) || defined(__amd64__) || defined(__i386__) || defined(__riscv)
#include <acpi/acpi.h>
#include <acpi/acpi_bus.h>
diff --git a/sys/compat/linuxkpi/common/include/linux/ascii85.h b/sys/compat/linuxkpi/common/include/linux/ascii85.h
new file mode 100644
index 000000000000..06777a130e41
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/ascii85.h
@@ -0,0 +1,46 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2026 The FreeBSD Foundation
+ */
+
+#ifndef _LINUXKPI_LINUX_ASCII85_H_
+#define _LINUXKPI_LINUX_ASCII85_H_
+
+#include <sys/param.h>
+
+#define ASCII85_BUFSZ 6
+
+static inline long
+ascii85_encode_len(long in_len)
+{
+ long out_len;
+
+ out_len = howmany(in_len, 4);
+
+ return (out_len);
+}
+
+static inline const char *
+ascii85_encode(uint32_t in, char *out)
+{
+ int i;
+
+ if (in == 0) {
+ out[0] = 'z';
+ out[1] = '\0';
+ return (out);
+ }
+
+ for (i = ASCII85_BUFSZ - 2; i >= 0; i--) {
+ out[i] = in % 85;
+ out[i] += 33;
+
+ in /= 85;
+ }
+ out[ASCII85_BUFSZ - 1] = '\0';
+
+ return (out);
+}
+
+#endif /* _LINUXKPI_LINUX_ASCII85_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/bcm47xx_nvram.h b/sys/compat/linuxkpi/common/include/linux/bcm47xx_nvram.h
new file mode 100644
index 000000000000..744101a2f8b1
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/bcm47xx_nvram.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2025 Bjoern A. Zeeb
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_LINUX_BCM47XX_NVRAM_H
+#define _LINUXKPI_LINUX_BCM47XX_NVRAM_H
+
+static inline char *
+bcm47xx_nvram_get_contents(size_t *x __unused)
+{
+ return (NULL);
+};
+
+static inline void
+bcm47xx_nvram_release_contents(const char *x __unused)
+{
+};
+
+#endif /* _LINUXKPI_LINUX_BCM47XX_NVRAM_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/bcma/bcma.h b/sys/compat/linuxkpi/common/include/linux/bcma/bcma.h
new file mode 100644
index 000000000000..3840c3a420e5
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/bcma/bcma.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2025 Bjoern A. Zeeb
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_LINUX_BCMA_BCMA_H
+#define _LINUXKPI_LINUX_BCMA_BCMA_H
+
+#define BCMA_CORE_80211 0x812
+#define BCMA_CORE_ARM_CA7 0x847
+#define BCMA_CORE_ARM_CM3 0x82A
+#define BCMA_CORE_ARM_CR4 0x83E
+#define BCMA_CORE_CHIPCOMMON 0x800
+#define BCMA_CORE_GCI 0x840
+#define BCMA_CORE_INTERNAL_MEM 0x80E
+#define BCMA_CORE_PCIE2 0x83C
+#define BCMA_CORE_PMU 0x827
+#define BCMA_CORE_SDIO_DEV 0x829
+#define BCMA_CORE_SYS_MEM 0x849
+
+/* XXX not sure where these belong. */
+#define BCMA_CC_CAP_EXT_AOB_PRESENT 0x00000040
+#define BCMA_CC_PMU_CTL_RES_SHIFT 13
+#define BCMA_CC_PMU_CTL_RES_RELOAD 0x2
+#define BCMA_CC_SROM_CONTROL_OTPSEL 0x00000010
+#define BCMA_CC_SROM_CONTROL_OTP_PRESENT 0x00000020
+
+#endif /* _LINUXKPI_LINUX_BCMA_BCMA_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/bcma/bcma_regs.h b/sys/compat/linuxkpi/common/include/linux/bcma/bcma_regs.h
new file mode 100644
index 000000000000..0a4cdddf7a73
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/bcma/bcma_regs.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2025 Bjoern A. Zeeb
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_LINUX_BCMA_BCMA_REGS_H
+#define _LINUXKPI_LINUX_BCMA_BCMA_REGS_H
+
+#define BCMA_IOCTL 0x0408
+#define BCMA_IOCTL_CLK 0x0001
+#define BCMA_IOCTL_FGC 0x0002
+
+#define BCMA_RESET_CTL 0x0800
+#define BCMA_RESET_CTL_RESET 0x0001
+
+#endif /* _LINUXKPI_LINUX_BCMA_BCMA_REGS_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/bitops.h b/sys/compat/linuxkpi/common/include/linux/bitops.h
index 8fac80820f30..125081ab5b74 100644
--- a/sys/compat/linuxkpi/common/include/linux/bitops.h
+++ b/sys/compat/linuxkpi/common/include/linux/bitops.h
@@ -51,12 +51,6 @@
#define BITS_PER_TYPE(t) (sizeof(t) * BITS_PER_BYTE)
#define BITS_TO_BYTES(n) howmany((n), BITS_PER_BYTE)
-#define hweight8(x) bitcount((uint8_t)(x))
-#define hweight16(x) bitcount16(x)
-#define hweight32(x) bitcount32(x)
-#define hweight64(x) bitcount64(x)
-#define hweight_long(x) bitcountl(x)
-
#if __has_builtin(__builtin_popcountg)
#define HWEIGHT8(x) (__builtin_popcountg((uint8_t)(x)))
#define HWEIGHT16(x) (__builtin_popcountg((uint16_t)(x)))
@@ -70,6 +64,12 @@
#define HWEIGHT64(x) (__const_bitcount64((uint64_t)(x)))
#endif
+#define hweight8(x) (__builtin_constant_p(x) ? HWEIGHT8(x) : bitcount((uint8_t)(x)))
+#define hweight16(x) (__builtin_constant_p(x) ? HWEIGHT16(x) : bitcount16(x))
+#define hweight32(x) (__builtin_constant_p(x) ? HWEIGHT32(x) : bitcount32(x))
+#define hweight64(x) (__builtin_constant_p(x) ? HWEIGHT64(x) : bitcount64(x))
+#define hweight_long(x) bitcountl(x)
+
static inline int
__ffs(int mask)
{
@@ -437,4 +437,16 @@ sign_extend32(uint32_t value, int index)
return ((int32_t)(value << shift) >> shift);
}
+static inline uint64_t
+rol64(uint64_t word, unsigned int shift)
+{
+ return ((word << (shift & 63)) | (word >> ((-shift) & 63)));
+}
+
+static inline uint32_t
+rol32(uint32_t word, unsigned int shift)
+{
+ return ((word << (shift & 31)) | (word >> ((-shift) & 31)));
+}
+
#endif /* _LINUXKPI_LINUX_BITOPS_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/cec-funcs.h b/sys/compat/linuxkpi/common/include/linux/cec-funcs.h
new file mode 100644
index 000000000000..1107b04e4e08
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/cec-funcs.h
@@ -0,0 +1,16 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025-2026 The FreeBSD Foundation
+ * Copyright (c) 2025-2026 Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
+ *
+ * This software was developed by Jean-Sébastien Pédron under sponsorship
+ * from the FreeBSD Foundation.
+ */
+
+#ifndef _LINUXKPI_LINUX_CEC_FUNCS_H_
+#define _LINUXKPI_LINUX_CEC_FUNCS_H_
+
+#include <linux/cec.h>
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/cec.h b/sys/compat/linuxkpi/common/include/linux/cec.h
index e0854d87d85c..b08d891537a9 100644
--- a/sys/compat/linuxkpi/common/include/linux/cec.h
+++ b/sys/compat/linuxkpi/common/include/linux/cec.h
@@ -3,6 +3,9 @@
#ifndef _LINUXKPI_LINUX_CEC_H_
#define _LINUXKPI_LINUX_CEC_H_
+#include <linux/types.h>
+#include <linux/string.h>
+
#define CEC_PHYS_ADDR_INVALID 0xffff
#endif /* _LINUXKPI_LINUX_CEC_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/cgroup.h b/sys/compat/linuxkpi/common/include/linux/cgroup.h
index a9dd22fd0f4c..c75404fd6cf3 100644
--- a/sys/compat/linuxkpi/common/include/linux/cgroup.h
+++ b/sys/compat/linuxkpi/common/include/linux/cgroup.h
@@ -29,6 +29,15 @@
#ifndef _LINUXKPI_LINUX_CGROUP_H_
#define _LINUXKPI_LINUX_CGROUP_H_
+#include <linux/sched.h>
+#include <linux/nodemask.h>
+#include <linux/list.h>
+#include <linux/rculist.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+#include <linux/jump_label.h>
+#include <linux/types.h>
+#include <linux/refcount.h>
#include <linux/kernel_stat.h>
#endif /* _LINUXKPI_LINUX_CGROUP_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/cleanup.h b/sys/compat/linuxkpi/common/include/linux/cleanup.h
index 5bb146f082ed..fb21a81f121b 100644
--- a/sys/compat/linuxkpi/common/include/linux/cleanup.h
+++ b/sys/compat/linuxkpi/common/include/linux/cleanup.h
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2024-2025 The FreeBSD Foundation
+ * Copyright (c) 2024-2026 The FreeBSD Foundation
*
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
@@ -10,18 +10,26 @@
#ifndef _LINUXKPI_LINUX_CLEANUP_H
#define _LINUXKPI_LINUX_CLEANUP_H
+#include <linux/err.h>
+
+#define CLEANUP_NAME(_n, _s) __CONCAT(__CONCAT(cleanup_, _n), _s)
+
#define __cleanup(_f) __attribute__((__cleanup__(_f)))
+#define DECLARE(_n, _x) \
+ CLEANUP_NAME(_n, _t) _x __cleanup(CLEANUP_NAME(_n, _destroy)) = \
+ CLEANUP_NAME(_n, _create)
+
/*
* Note: "_T" are special as they are exposed into common code for
* statements. Extra care should be taken when changing the code.
*/
#define DEFINE_GUARD(_n, _dt, _lock, _unlock) \
\
- typedef _dt guard_ ## _n ## _t; \
+ typedef _dt CLEANUP_NAME(_n, _t); \
\
static inline _dt \
- guard_ ## _n ## _create( _dt _T) \
+ CLEANUP_NAME(_n, _create)( _dt _T) \
{ \
_dt c; \
\
@@ -30,7 +38,7 @@
} \
\
static inline void \
- guard_ ## _n ## _destroy(_dt *t) \
+ CLEANUP_NAME(_n, _destroy)(_dt *t) \
{ \
_dt _T; \
\
@@ -39,9 +47,10 @@
}
/* We need to keep these calls unique. */
+#define _guard(_n, _x) \
+ DECLARE(_n, _x)
#define guard(_n) \
- guard_ ## _n ## _t guard_ ## _n ## _ ## __COUNTER__ \
- __cleanup(guard_ ## _n ## _destroy) = guard_ ## _n ## _create
+ _guard(_n, guard_ ## _n ## _ ## __COUNTER__)
#define DEFINE_FREE(_n, _t, _f) \
static inline void \
@@ -56,38 +65,100 @@
#define __free(_n) __cleanup(__free_##_n)
/*
- * Given this is a _0 version it should likely be broken up into parts.
- * But we have no idead what a _1, _2, ... version would do different
- * until we see a call.
- * This is used for a not-real-type (rcu). We use a bool to "simulate"
- * the lock held. Also _T still special, may not always be used, so tag
- * with __unused (or better the LinuxKPI __maybe_unused).
+ * Our initial version go broken up. Some simplifications like using
+ * "bool" for the lock had to be changed to a more general type.
+ * _T is still special and, like other bits, may not always be used,
+ * so tag with __unused (or better the LinuxKPI __maybe_unused).
*/
-#define DEFINE_LOCK_GUARD_0(_n, _lock, _unlock, ...) \
+#define _DEFINE_LOCK_GUARD_0(_n, _lock) \
+ static inline CLEANUP_NAME(_n, _t) \
+ CLEANUP_NAME(_n, _create)(void) \
+ { \
+ CLEANUP_NAME(_n, _t) _tmp; \
+ CLEANUP_NAME(_n, _t) *_T __maybe_unused; \
+ \
+ _tmp.lock = (void *)1; \
+ _T = &_tmp; \
+ _lock; \
+ return (_tmp); \
+ }
+
+#define _DEFINE_LOCK_GUARD_1(_n, _type, _lock) \
+ static inline CLEANUP_NAME(_n, _t) \
+ CLEANUP_NAME(_n, _create)(_type *l) \
+ { \
+ CLEANUP_NAME(_n, _t) _tmp; \
+ CLEANUP_NAME(_n, _t) *_T __maybe_unused; \
\
+ _tmp.lock = l; \
+ _T = &_tmp; \
+ _lock; \
+ return (_tmp); \
+ }
+
+#define _GUARD_IS_ERR(_v) \
+ ({ \
+ uintptr_t x = (uintptr_t)(void *)(_v); \
+ IS_ERR_VALUE(x); \
+ })
+
+#define __is_cond_ptr(_n) \
+ CLEANUP_NAME(_n, _is_cond)
+#define __guard_ptr(_n) \
+ CLEANUP_NAME(_n, _ptr)
+
+#define _DEFINE_CLEANUP_IS_CONDITIONAL(_n, _b) \
+ static const bool CLEANUP_NAME(_n, _is_cond) __maybe_unused = _b
+
+#define _DEFINE_GUARD_LOCK_PTR(_n, _lp) \
+ static inline void * \
+ CLEANUP_NAME(_n, _lock_ptr)(CLEANUP_NAME(_n, _t) *_T) \
+ { \
+ void *_p; \
+ \
+ _p = (void *)(uintptr_t)*(_lp); \
+ if (IS_ERR(_p)) \
+ _p = NULL; \
+ return (_p); \
+ }
+
+#define _DEFINE_UNLOCK_GUARD(_n, _type, _unlock, ...) \
typedef struct { \
- bool lock; \
+ _type *lock; \
__VA_ARGS__; \
- } guard_ ## _n ## _t; \
+ } CLEANUP_NAME(_n, _t); \
\
static inline void \
- guard_ ## _n ## _destroy(guard_ ## _n ## _t *_T) \
+ CLEANUP_NAME(_n, _destroy)(CLEANUP_NAME(_n, _t) *_T) \
{ \
- if (_T->lock) { \
+ if (!_GUARD_IS_ERR(_T->lock)) { \
_unlock; \
} \
} \
\
- static inline guard_ ## _n ## _t \
- guard_ ## _n ## _create(void) \
- { \
- guard_ ## _n ## _t _tmp; \
- guard_ ## _n ## _t *_T __maybe_unused; \
- \
- _tmp.lock = true; \
- _T = &_tmp; \
- _lock; \
- return (_tmp); \
- }
+ _DEFINE_GUARD_LOCK_PTR(_n, &_T->lock)
+
+#define DEFINE_LOCK_GUARD_0(_n, _lock, _unlock, ...) \
+ _DEFINE_CLEANUP_IS_CONDITIONAL(_n, false); \
+ _DEFINE_UNLOCK_GUARD(_n, void, _unlock, __VA_ARGS__) \
+ _DEFINE_LOCK_GUARD_0(_n, _lock)
+
+/* This allows the type to be set. */
+#define DEFINE_LOCK_GUARD_1(_n, _t, _lock, _unlock, ...) \
+ _DEFINE_CLEANUP_IS_CONDITIONAL(_n, false); \
+ _DEFINE_UNLOCK_GUARD(_n, _t, _unlock, __VA_ARGS__) \
+ _DEFINE_LOCK_GUARD_1(_n, _t, _lock)
+
+#define _scoped_guard(_n, _l, ...) \
+ for (DECLARE(_n, _scoped)(__VA_ARGS__); \
+ 1 /*__guard_ptr(_n)(&_scoped) || !__is_cond_ptr(_n) */; \
+ ({ goto _l; })) \
+ if (0) { \
+_l: \
+ break; \
+ } else
+
+#define scoped_guard(_n, ...) \
+ _scoped_guard(_n, ___label_ ## __COUNTER__, ##__VA_ARGS__)
#endif /* _LINUXKPI_LINUX_CLEANUP_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/compiler.h b/sys/compat/linuxkpi/common/include/linux/compiler.h
index 4146c829b936..90d907dd4d45 100644
--- a/sys/compat/linuxkpi/common/include/linux/compiler.h
+++ b/sys/compat/linuxkpi/common/include/linux/compiler.h
@@ -33,48 +33,18 @@
#include <sys/cdefs.h>
#include <sys/endian.h>
-#define __user
-#define __kernel
-#define __safe
-#define __force
-#define __nocast
-#define __iomem
-#define __chk_user_ptr(x) ((void)0)
-#define __chk_io_ptr(x) ((void)0)
-#define __builtin_warning(x, y...) (1)
-#define __acquires(x)
-#define __releases(x)
-#define __acquire(x) do { } while (0)
-#define __release(x) do { } while (0)
-#define __cond_lock(x,c) (c)
+#include <compat/linuxkpi/common/include/linux/compiler_types.h>
+
#define __bitwise
#define __devinitdata
-#ifndef __deprecated
-#define __deprecated
-#endif
#define __init
#define __initconst
#define __devinit
#define __devexit
#define __exit
-#define __rcu
-#define __percpu
-#define __weak __weak_symbol
-#define __malloc
-#define __attribute_const__ __attribute__((__const__))
-#undef __always_inline
-#define __always_inline inline
-#define noinline __noinline
-#define noinline_for_stack __noinline
#define ____cacheline_aligned __aligned(CACHE_LINE_SIZE)
#define ____cacheline_aligned_in_smp __aligned(CACHE_LINE_SIZE)
-#define fallthrough /* FALLTHROUGH */ do { } while(0)
-#if __has_attribute(__nonstring__)
-#define __nonstring __attribute__((__nonstring__))
-#else
-#define __nonstring
-#endif
#if __has_attribute(__counted_by__)
#define __counted_by(_x) __attribute__((__counted_by__(_x)))
#else
@@ -93,24 +63,12 @@
#define typeof(x) __typeof(x)
#define uninitialized_var(x) x = x
-#define __maybe_unused __unused
-#define __always_unused __unused
-#define __must_check __result_use_check
-
-#define __printf(a,b) __printflike(a,b)
-
-#define __diag_push()
-#define __diag_pop()
-#define __diag_ignore_all(...)
#define barrier() __asm__ __volatile__("": : :"memory")
#define lower_32_bits(n) ((u32)(n))
#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
-#define ___PASTE(a,b) a##b
-#define __PASTE(a,b) ___PASTE(a,b)
-
#define WRITE_ONCE(x,v) do { \
barrier(); \
(*(volatile __typeof(x) *)(uintptr_t)&(x)) = (v); \
@@ -129,8 +87,6 @@
#define lockless_dereference(p) READ_ONCE(p)
#define _AT(T,X) ((T)(X))
-
-#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
#define __must_be_array(a) __same_type(a, &(a)[0])
#define sizeof_field(_s, _m) sizeof(((_s *)0)->_m)
diff --git a/sys/compat/linuxkpi/common/include/linux/compiler_attributes.h b/sys/compat/linuxkpi/common/include/linux/compiler_attributes.h
new file mode 100644
index 000000000000..42908bb6c2b5
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/compiler_attributes.h
@@ -0,0 +1,49 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2010 Isilon Systems, Inc.
+ * Copyright (c) 2010 iX Systems, Inc.
+ * Copyright (c) 2010 Panasas, Inc.
+ * Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
+ * Copyright (c) 2015 François Tigeot
+ * All rights reserved.
+ */
+
+#ifndef _LINUXKPI_LINUX_COMPILER_ATTRIBUTES_H_
+#define _LINUXKPI_LINUX_COMPILER_ATTRIBUTES_H_
+
+#include <sys/cdefs.h>
+
+#define __attribute_const__ __attribute__((__const__))
+
+#ifndef __deprecated
+#define __deprecated
+#endif
+
+#define fallthrough /* FALLTHROUGH */ do { } while(0)
+
+#undef __always_inline
+#define __always_inline inline
+
+#define __printf(a,b) __printflike(a,b)
+
+#define __malloc
+
+#define noinline __noinline
+
+#if __has_attribute(__nonstring__)
+#define __nonstring __attribute__((__nonstring__))
+#else
+#define __nonstring
+#endif
+
+#define noinline_for_stack __noinline
+
+#define __maybe_unused __unused
+#define __always_unused __unused
+
+#define __must_check __result_use_check
+
+#define __weak __weak_symbol
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/compiler_types.h b/sys/compat/linuxkpi/common/include/linux/compiler_types.h
new file mode 100644
index 000000000000..25e69f5afd8e
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/compiler_types.h
@@ -0,0 +1,58 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2010 Isilon Systems, Inc.
+ * Copyright (c) 2010 iX Systems, Inc.
+ * Copyright (c) 2010 Panasas, Inc.
+ * Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
+ * Copyright (c) 2015 François Tigeot
+ * All rights reserved.
+ */
+
+#ifndef _LINUXKPI_LINUX_COMPILER_TYPES_H_
+#define _LINUXKPI_LINUX_COMPILER_TYPES_H_
+
+#include <sys/cdefs.h>
+
+#include <compat/linuxkpi/common/include/linux/compiler_attributes.h>
+
+#define __kernel
+#define __user
+#define __iomem
+#define __percpu
+#define __rcu
+#define __chk_user_ptr(x) ((void)0)
+#define __chk_io_ptr(x) ((void)0)
+#define __acquires(x)
+#define __releases(x)
+#define __acquire(x) do { } while (0)
+#define __release(x) do { } while (0)
+#define __cond_lock(x,c) (c)
+#define __force
+#define __nocast
+#define __safe
+#define __builtin_warning(x, y...) (1)
+
+#define ___PASTE(a,b) a##b
+#define __PASTE(a,b) ___PASTE(a,b)
+
+#define __diag_push()
+#define __diag_pop()
+#define __diag_ignore_all(...)
+
+#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
+
+/*
+ * __builtin_counted_by_ref was introduced to
+ * - gcc in e7380688fa59 with a first release tag of gcc-15.1.0,
+ * - llvm in 7475156d49406 with a first release tag of llvmorg-20.1.0-rc1
+ * but cannot be used before 23 (22.x.y possibly) (see 09a3d830a888).
+ */
+#if (__has_builtin(__builtin_counted_by_ref)) && \
+ (!defined(__clang__) || (__clang_major__ >= 23))
+#define __flex_counter(_field) __builtin_counted_by_ref(_field)
+#else
+#define __flex_counter(_field) ((void *)NULL)
+#endif
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/device.h b/sys/compat/linuxkpi/common/include/linux/device.h
index 8834f1799e61..2913810923f1 100644
--- a/sys/compat/linuxkpi/common/include/linux/device.h
+++ b/sys/compat/linuxkpi/common/include/linux/device.h
@@ -267,6 +267,30 @@ show_class_attr_string(struct class *class,
dev_dbg(dev, __VA_ARGS__); \
} while (0)
+static inline int
+dev_err_probe(const struct device *dev, int err, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+
+ /*
+ * On Linux, they look at the error code to determine if the message
+ * should be logged (not logged if -ENOMEM) and at which log level.
+ */
+ device_printf(dev->bsddev, fmt, args);
+
+ va_end(args);
+
+ return (err);
+}
+
+#define dev_err_ptr_probe(dev, err, fmt, ...) \
+ ERR_PTR(dev_err_probe((dev), (err), fmt, ##__VA_ARGS__)
+
+#define dev_err_cast_probe(dev, err, fmt, ...) \
+ ERR_PTR(dev_err_probe((dev), PTR_ERR(err), fmt, ##__VA_ARGS__)
+
/* Public and LinuxKPI internal devres functions. */
void *lkpi_devres_alloc(void(*release)(struct device *, void *), size_t, gfp_t);
void lkpi_devres_add(struct device *, void *);
@@ -701,6 +725,13 @@ devm_kmemdup(struct device *dev, const void *src, size_t len, gfp_t gfp)
return (dst);
}
+static inline void *
+devm_kmemdup_array(struct device *dev, const void *src, size_t n, size_t len,
+ gfp_t gfp)
+{
+ return (devm_kmemdup(dev, src, size_mul(n, len), gfp));
+}
+
#define devm_kzalloc(_dev, _size, _gfp) \
devm_kmalloc((_dev), (_size), (_gfp) | __GFP_ZERO)
diff --git a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h
index 2d8e1196d3d3..5e5d40ef8339 100644
--- a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h
+++ b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h
@@ -96,6 +96,8 @@ void *linux_dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag);
void *linuxkpi_dmam_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag);
+void linuxkpi_dmam_free_coherent(struct device *dev, size_t size,
+ void *addr, dma_addr_t dma_handle);
dma_addr_t linux_dma_map_phys(struct device *dev, vm_paddr_t phys, size_t len); /* backward compat */
dma_addr_t lkpi_dma_map_phys(struct device *, vm_paddr_t, size_t,
enum dma_data_direction, unsigned long);
@@ -104,10 +106,10 @@ void lkpi_dma_unmap(struct device *, dma_addr_t, size_t,
enum dma_data_direction, unsigned long);
int linux_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
int nents, enum dma_data_direction direction,
- unsigned long attrs __unused);
+ unsigned long attrs);
void linux_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
int nents __unused, enum dma_data_direction direction,
- unsigned long attrs __unused);
+ unsigned long attrs);
void linuxkpi_dma_sync(struct device *, dma_addr_t, size_t, bus_dmasync_op_t);
static inline int
@@ -181,6 +183,13 @@ dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
kmem_free(cpu_addr, size);
}
+static inline void
+dmam_free_coherent(struct device *dev, size_t size, void *addr,
+ dma_addr_t dma_handle)
+{
+ linuxkpi_dmam_free_coherent(dev, size, addr, dma_handle);
+}
+
static inline dma_addr_t
dma_map_page_attrs(struct device *dev, struct page *page, size_t offset,
size_t size, enum dma_data_direction direction, unsigned long attrs)
@@ -192,10 +201,10 @@ dma_map_page_attrs(struct device *dev, struct page *page, size_t offset,
/* linux_dma_(un)map_sg_attrs does not support attrs yet */
#define dma_map_sg_attrs(dev, sgl, nents, dir, attrs) \
- linux_dma_map_sg_attrs(dev, sgl, nents, dir, 0)
+ linux_dma_map_sg_attrs(dev, sgl, nents, dir, attrs)
#define dma_unmap_sg_attrs(dev, sg, nents, dir, attrs) \
- linux_dma_unmap_sg_attrs(dev, sg, nents, dir, 0)
+ linux_dma_unmap_sg_attrs(dev, sg, nents, dir, attrs)
static inline dma_addr_t
dma_map_page(struct device *dev, struct page *page,
@@ -352,10 +361,10 @@ dma_max_mapping_size(struct device *dev)
}
#define dma_map_single_attrs(dev, ptr, size, dir, attrs) \
- _dma_map_single_attrs(dev, ptr, size, dir, 0)
+ _dma_map_single_attrs(dev, ptr, size, dir, attrs)
#define dma_unmap_single_attrs(dev, dma_addr, size, dir, attrs) \
- _dma_unmap_single_attrs(dev, dma_addr, size, dir, 0)
+ _dma_unmap_single_attrs(dev, dma_addr, size, dir, attrs)
#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0)
#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0)
diff --git a/sys/compat/linuxkpi/common/include/linux/eventfd.h b/sys/compat/linuxkpi/common/include/linux/eventfd.h
new file mode 100644
index 000000000000..d167d4b7d189
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/eventfd.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2025 The FreeBSD Foundation
+ * Copyright (c) 2025 Jean-Sébastien Pédron
+ *
+ * This software was developed by Jean-Sébastien Pédron under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_EVENTFD_H_
+#define _LINUXKPI_LINUX_EVENTFD_H_
+
+#include <sys/eventfd.h>
+
+#include <linux/wait.h>
+#include <linux/err.h>
+#include <linux/percpu-defs.h>
+#include <linux/percpu.h>
+#include <linux/sched.h>
+
+/*
+ * Linux uses `struct eventfd_ctx`, but FreeBSD defines `struct eventfd`. Here,
+ * we define a synonym to the FreeBSD structure. This allows to keep Linux code
+ * unmodified.
+ */
+#define eventfd_ctx eventfd
+
+#define eventfd_ctx_fdget lkpi_eventfd_ctx_fdget
+struct eventfd_ctx *lkpi_eventfd_ctx_fdget(int fd);
+
+#define eventfd_ctx_put lkpi_eventfd_ctx_put
+void lkpi_eventfd_ctx_put(struct eventfd_ctx *ctx);
+
+#endif /* _LINUXKPI_LINUX_EVENTFD_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/file.h b/sys/compat/linuxkpi/common/include/linux/file.h
index f6e988c2d88e..be12d5f1bccf 100644
--- a/sys/compat/linuxkpi/common/include/linux/file.h
+++ b/sys/compat/linuxkpi/common/include/linux/file.h
@@ -39,6 +39,11 @@
#include <linux/fs.h>
#include <linux/slab.h>
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/cleanup.h>
+
struct linux_file;
#undef file
diff --git a/sys/compat/linuxkpi/common/include/linux/font.h b/sys/compat/linuxkpi/common/include/linux/font.h
new file mode 100644
index 000000000000..45daa00b61f0
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/font.h
@@ -0,0 +1,33 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025-2026 The FreeBSD Foundation
+ * Copyright (c) 2025-2026 Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
+ *
+ * This software was developed by Jean-Sébastien Pédron under sponsorship
+ * from the FreeBSD Foundation.
+ */
+
+#ifndef _LINUXKPI_LINUX_FONT_H_
+#define _LINUXKPI_LINUX_FONT_H_
+
+#include <linux/types.h>
+
+struct font_desc {
+ const char *name;
+ const void *data;
+ int idx;
+ unsigned int width;
+ unsigned int height;
+ unsigned int charcount;
+ int pref;
+};
+
+static inline const struct font_desc *
+get_default_font(int xres, int yres, unsigned long *font_w,
+ unsigned long *font_h)
+{
+ return (NULL);
+}
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/fs.h b/sys/compat/linuxkpi/common/include/linux/fs.h
index f1568ad6282d..749a9fd22d3d 100644
--- a/sys/compat/linuxkpi/common/include/linux/fs.h
+++ b/sys/compat/linuxkpi/common/include/linux/fs.h
@@ -133,8 +133,11 @@ do { \
typedef int (*filldir_t)(void *, const char *, int, off_t, u64, unsigned);
+typedef unsigned int fop_flags_t;
+
struct file_operations {
struct module *owner;
+ fop_flags_t fop_flags; /* Unused on FreeBSD. */
ssize_t (*read)(struct linux_file *, char __user *, size_t, off_t *);
ssize_t (*write)(struct linux_file *, const char __user *, size_t, off_t *);
unsigned int (*poll) (struct linux_file *, struct poll_table_struct *);
@@ -182,6 +185,14 @@ struct file_operations {
int (*setlease)(struct file *, long, struct file_lock **);
#endif
};
+
+#define FOP_BUFFER_RASYNC (1 << 0)
+#define FOP_BUFFER_WASYNC (1 << 1)
+#define FOP_MMAP_SYNC (1 << 2)
+#define FOP_DIO_PARALLEL_WRITE (1 << 3)
+#define FOP_HUGE_PAGES (1 << 4)
+#define FOP_UNSIGNED_OFFSET (1 << 5)
+
#define fops_get(fops) (fops)
#define replace_fops(f, fops) ((f)->f_op = (fops))
@@ -364,27 +375,23 @@ static inline ssize_t
simple_read_from_buffer(void __user *dest, size_t read_size, loff_t *ppos,
void *orig, size_t buf_size)
{
- void *p, *read_pos = ((char *) orig) + *ppos;
+ void *read_pos = ((char *) orig) + *ppos;
size_t buf_remain = buf_size - *ppos;
+ ssize_t num_read;
- if (buf_remain < 0 || buf_remain > buf_size)
- return -EINVAL;
+ if (*ppos >= buf_size || read_size == 0)
+ return (0);
if (read_size > buf_remain)
read_size = buf_remain;
- /*
- * XXX At time of commit only debugfs consumers could be
- * identified. If others will use this function we may
- * have to revise this: normally we would call copy_to_user()
- * here but lindebugfs will return the result and the
- * copyout is done elsewhere for us.
- */
- p = memcpy(dest, read_pos, read_size);
- if (p != NULL)
- *ppos += read_size;
-
- return (read_size);
+ /* copy_to_user returns number of bytes NOT read */
+ num_read = read_size - copy_to_user(dest, read_pos, read_size);
+ if (num_read == 0)
+ return -EFAULT;
+ *ppos += num_read;
+
+ return (num_read);
}
MALLOC_DECLARE(M_LSATTR);
@@ -415,11 +422,13 @@ int simple_attr_open(struct inode *inode, struct file *filp,
int simple_attr_release(struct inode *inode, struct file *filp);
-ssize_t simple_attr_read(struct file *filp, char *buf, size_t read_size, loff_t *ppos);
+ssize_t simple_attr_read(struct file *filp, char __user *buf, size_t read_size,
+ loff_t *ppos);
-ssize_t simple_attr_write(struct file *filp, const char *buf, size_t write_size, loff_t *ppos);
+ssize_t simple_attr_write(struct file *filp, const char __user *buf,
+ size_t write_size, loff_t *ppos);
-ssize_t simple_attr_write_signed(struct file *filp, const char *buf,
+ssize_t simple_attr_write_signed(struct file *filp, const char __user *buf,
size_t write_size, loff_t *ppos);
#endif /* _LINUXKPI_LINUX_FS_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/gfp.h b/sys/compat/linuxkpi/common/include/linux/gfp.h
index 7a32e7862338..e8380e326eda 100644
--- a/sys/compat/linuxkpi/common/include/linux/gfp.h
+++ b/sys/compat/linuxkpi/common/include/linux/gfp.h
@@ -58,7 +58,8 @@
#define __GFP_WAIT M_WAITOK
#define __GFP_DMA32 (1U << 24) /* LinuxKPI only */
#define __GFP_NORETRY (1U << 25) /* LinuxKPI only */
-#define __GFP_BITS_SHIFT 26
+#define __GFP_THISNODE (1U << 26) /* Unimplemented */
+#define __GFP_BITS_SHIFT 27
#define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1)
#define __GFP_NOFAIL M_WAITOK
@@ -80,6 +81,9 @@
CTASSERT((__GFP_DMA32 & GFP_NATIVE_MASK) == 0);
CTASSERT((__GFP_BITS_MASK & GFP_NATIVE_MASK) == GFP_NATIVE_MASK);
+#define __default_gfp(_discard, _arg_or_default, ...) _arg_or_default
+#define default_gfp(...) __default_gfp(, ##__VA_ARGS__, GFP_KERNEL)
+
struct page_frag_cache {
void *va;
int pagecnt_bias;
diff --git a/sys/compat/linuxkpi/common/include/linux/hardirq.h b/sys/compat/linuxkpi/common/include/linux/hardirq.h
index f79451dd0d35..c6cbf1a34f14 100644
--- a/sys/compat/linuxkpi/common/include/linux/hardirq.h
+++ b/sys/compat/linuxkpi/common/include/linux/hardirq.h
@@ -31,6 +31,7 @@
#include <linux/types.h>
#include <linux/lockdep.h>
+#include <linux/preempt.h>
#include <sys/param.h>
#include <sys/bus.h>
diff --git a/sys/compat/linuxkpi/common/include/linux/hex.h b/sys/compat/linuxkpi/common/include/linux/hex.h
new file mode 100644
index 000000000000..7e9f499cfb1b
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/hex.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2022-2026 Bjoern A. Zeeb
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_LINUX_HEX_H_
+#define _LINUXKPI_LINUX_HEX_H_
+
+#include <linux/types.h>
+#include <linux/errno.h>
+
+static inline int
+_h2b(const char c)
+{
+
+ if (c >= '0' && c <= '9')
+ return (c - '0');
+ if (c >= 'a' && c <= 'f')
+ return (10 + c - 'a');
+ if (c >= 'A' && c <= 'F')
+ return (10 + c - 'A');
+ return (-EINVAL);
+}
+
+static inline int
+hex2bin(uint8_t *bindst, const char *hexsrc, size_t binlen)
+{
+ int hi4, lo4;
+
+ while (binlen > 0) {
+ hi4 = _h2b(*hexsrc++);
+ lo4 = _h2b(*hexsrc++);
+ if (hi4 < 0 || lo4 < 0)
+ return (-EINVAL);
+
+ *bindst++ = (hi4 << 4) | lo4;
+ binlen--;
+ }
+
+ return (0);
+}
+
+#endif /* _LINUXKPI_LINUX_HEX_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/highmem.h b/sys/compat/linuxkpi/common/include/linux/highmem.h
index 58a9cdcdf60f..dc1c4fe2f299 100644
--- a/sys/compat/linuxkpi/common/include/linux/highmem.h
+++ b/sys/compat/linuxkpi/common/include/linux/highmem.h
@@ -45,6 +45,7 @@
#include <linux/mm.h>
#include <linux/page.h>
+#include <linux/hardirq.h>
#define PageHighMem(p) (0)
diff --git a/sys/compat/linuxkpi/common/include/linux/i2c.h b/sys/compat/linuxkpi/common/include/linux/i2c.h
index f24d282586f6..a6a4ee85d584 100644
--- a/sys/compat/linuxkpi/common/include/linux/i2c.h
+++ b/sys/compat/linuxkpi/common/include/linux/i2c.h
@@ -31,7 +31,14 @@
#include <sys/errno.h>
#include <sys/systm.h>
+#include <linux/bits.h>
+#include <linux/mod_devicetable.h>
#include <linux/device.h>
+#include <linux/sched.h>
+#include <linux/mutex.h>
+#include <linux/regulator/consumer.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
#define I2C_MAX_ADAPTER_NAME_LENGTH 32
diff --git a/sys/compat/linuxkpi/common/include/linux/ieee80211.h b/sys/compat/linuxkpi/common/include/linux/ieee80211.h
index 12160df43915..b8f29560f200 100644
--- a/sys/compat/linuxkpi/common/include/linux/ieee80211.h
+++ b/sys/compat/linuxkpi/common/include/linux/ieee80211.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2020-2025 The FreeBSD Foundation
+ * Copyright (c) 2020-2026 The FreeBSD Foundation
*
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
@@ -51,8 +51,16 @@ extern int linuxkpi_debug_80211;
#define IMPROVE(fmt, ...) if (linuxkpi_debug_80211 & D80211_IMPROVE) \
printf("%s:%d: XXX LKPI80211 IMPROVE " fmt "\n", __func__, __LINE__, ##__VA_ARGS__)
-
-/* 9.4.2.55 Management MIC element (CMAC-256, GMAC-128, and GMAC-256). */
+/* 802.11-2024, 9.4.2.53 MME. */
+/* BIP-CMAC-128 */
+struct ieee80211_mmie {
+ uint8_t element_id;
+ uint8_t length;
+ uint16_t key_id;
+ uint8_t ipn[6];
+ uint8_t mic[8];
+};
+/* BIP-CMAC-256, BIP-GMAC-128, BIP-GMAC-256 */
struct ieee80211_mmie_16 {
uint8_t element_id;
uint8_t length;
@@ -92,8 +100,6 @@ struct ieee80211_mmie_16 {
#define IEEE80211_MAX_RTS_THRESHOLD 2346 /* net80211::IEEE80211_RTS_MAX */
-#define IEEE80211_MIN_ACTION_SIZE 23 /* ? */
-
/* Wi-Fi Peer-to-Peer (P2P) Technical Specification */
#define IEEE80211_P2P_OPPPS_CTWINDOW_MASK 0x7f
#define IEEE80211_P2P_OPPPS_ENABLE_BIT BIT(7)
@@ -108,7 +114,18 @@ struct ieee80211_mmie_16 {
#define IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT 0x0100
enum ieee80211_rate_flags {
- IEEE80211_RATE_SHORT_PREAMBLE = BIT(0),
+ IEEE80211_RATE_SHORT_PREAMBLE = BIT(0), /* 2.4Ghz, CCK */
+ IEEE80211_RATE_SUPPORTS_5MHZ = BIT(1),
+ IEEE80211_RATE_SUPPORTS_10MHZ = BIT(2),
+ IEEE80211_RATE_ERP_G = BIT(3),
+
+ /*
+ * According to documentation these are flags initialized internally.
+ * See lkpi_wiphy_band_annotate().
+ */
+ IEEE80211_RATE_MANDATORY_A = BIT(4),
+ IEEE80211_RATE_MANDATORY_G = BIT(5),
+ IEEE80211_RATE_MANDATORY_B = BIT(6),
};
enum ieee80211_rate_control_changed_flags {
@@ -200,6 +217,7 @@ enum ieee80211_min_mpdu_start_spacing {
#define IEEE80211_FCTL_TODS (IEEE80211_FC1_DIR_TODS << 8)
#define IEEE80211_FCTL_MOREFRAGS (IEEE80211_FC1_MORE_FRAG << 8)
#define IEEE80211_FCTL_PM (IEEE80211_FC1_PWR_MGT << 8)
+#define IEEE80211_FCTL_MOREDATA (IEEE80211_FC1_MORE_DATA << 8)
#define IEEE80211_FTYPE_MGMT IEEE80211_FC0_TYPE_MGT
#define IEEE80211_FTYPE_CTL IEEE80211_FC0_TYPE_CTL
@@ -461,18 +479,6 @@ enum ieee80211_tx_control_flags {
IEEE80211_TX_CTRL_MLO_LINK = 0xF0000000, /* This is IEEE80211_LINK_UNSPECIFIED on the high bits. */
};
-enum ieee80211_tx_rate_flags {
- /* XXX TODO .. right shift numbers */
- IEEE80211_TX_RC_40_MHZ_WIDTH = BIT(0),
- IEEE80211_TX_RC_80_MHZ_WIDTH = BIT(1),
- IEEE80211_TX_RC_160_MHZ_WIDTH = BIT(2),
- IEEE80211_TX_RC_GREEN_FIELD = BIT(3),
- IEEE80211_TX_RC_MCS = BIT(4),
- IEEE80211_TX_RC_SHORT_GI = BIT(5),
- IEEE80211_TX_RC_VHT_MCS = BIT(6),
- IEEE80211_TX_RC_USE_SHORT_PREAMBLE = BIT(7),
-};
-
#define IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED -128
#define IEEE80211_HT_CTL_LEN 4
@@ -614,6 +620,8 @@ struct ieee80211_mgmt {
} u;
} __packed __aligned(2);
+#define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u)
+
struct ieee80211_cts { /* net80211::ieee80211_frame_cts */
__le16 frame_control;
__le16 duration;
diff --git a/sys/compat/linuxkpi/common/include/linux/instruction_pointer.h b/sys/compat/linuxkpi/common/include/linux/instruction_pointer.h
new file mode 100644
index 000000000000..200a8c3f1d5e
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/instruction_pointer.h
@@ -0,0 +1,15 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2021 Neel Chauhan
+ * Copyright (c) 2026 The FreeBSD Foundation
+ */
+
+#ifndef _LINUXKPI_LINUX_INSTRUCTION_POINTER_H_
+#define _LINUXKPI_LINUX_INSTRUCTION_POINTER_H_
+
+#define _RET_IP_ __builtin_return_address(0)
+
+#define _THIS_IP_ ((unsigned long)0) /* TODO: _THIS_IP_ not implemented. */
+
+#endif /* _LINUXKPI_LINUX_INSTRUCTION_POINTER_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/ioport.h b/sys/compat/linuxkpi/common/include/linux/ioport.h
index 763af2de7c4f..68f28cec4ec4 100644
--- a/sys/compat/linuxkpi/common/include/linux/ioport.h
+++ b/sys/compat/linuxkpi/common/include/linux/ioport.h
@@ -41,6 +41,7 @@ struct resource {
resource_size_t start;
resource_size_t end;
const char *name;
+ unsigned long flags;
};
static inline resource_size_t
diff --git a/sys/compat/linuxkpi/common/include/linux/kconfig.h b/sys/compat/linuxkpi/common/include/linux/kconfig.h
index c1d186b56e1f..529d41991900 100644
--- a/sys/compat/linuxkpi/common/include/linux/kconfig.h
+++ b/sys/compat/linuxkpi/common/include/linux/kconfig.h
@@ -73,4 +73,39 @@
#define IS_REACHABLE(_x) (IS_BUILTIN(_x) || \
(IS_MODULE(_x) && IS_BUILTIN(MODULE)))
+/*
+ * On Linux, the CONFIG_PGTABLE_LEVELS value is defined by the config/build
+ * system. Here, we take the per-architecture default value defined in
+ * `arch/$ARCH/Kconfig` files upstream.
+ */
+#if defined(__amd64__)
+
+#define CONFIG_PGTABLE_LEVELS 4
+
+#elif defined(__aarch64__)
+
+#define CONFIG_PGTABLE_LEVELS 4
+
+#elif defined(__i386__)
+
+#define CONFIG_PGTABLE_LEVELS 2
+
+#elif defined(__powerpc__)
+
+#if defined(__powerpc64__)
+#define CONFIG_PGTABLE_LEVELS 4
+#else
+#define CONFIG_PGTABLE_LEVELS 2
+#endif
+
+#elif defined(__riscv)
+
+#if defined(__riscv_xlen) && __riscv_xlen == 64
+#define CONFIG_PGTABLE_LEVELS 5
+#else
+#define CONFIG_PGTABLE_LEVELS 2
+#endif
+
+#endif
+
#endif /* _LINUXKPI_LINUX_KCONFIG_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/kdev_t.h b/sys/compat/linuxkpi/common/include/linux/kdev_t.h
index 988dd771254a..964b7078e7f5 100644
--- a/sys/compat/linuxkpi/common/include/linux/kdev_t.h
+++ b/sys/compat/linuxkpi/common/include/linux/kdev_t.h
@@ -31,6 +31,21 @@
#include <sys/types.h>
+/*
+ * The encoding of major/minor on FreeBSD is complex to take into account the
+ * compatibility with 16-bit dev_t (see <sys/types.h>). It is not possible to
+ * use a simple shift and thus, we can't have a proper definition of
+ * `MINORBITS`.
+ *
+ * At the time this is added to linuxkpi, this is used by the DRM generic code
+ * as the upper limit to allocate an ID using an xarray. It is not used to
+ * decode a minor, therefore any arbitrary value here is fine in this context.
+ *
+ * On Linux, the value is set to 20. Because of the above, we reuse this value,
+ * even so it does not correspond to the actual minor encoding on FreeBSD.
+ */
+#define MINORBITS 20
+
#define MAJOR(dev) major(dev)
#define MINOR(dev) minor(dev)
#define MKDEV(ma, mi) makedev(ma, mi)
diff --git a/sys/compat/linuxkpi/common/include/linux/kernel.h b/sys/compat/linuxkpi/common/include/linux/kernel.h
index 11a13cbd49b4..e3ac4a05612c 100644
--- a/sys/compat/linuxkpi/common/include/linux/kernel.h
+++ b/sys/compat/linuxkpi/common/include/linux/kernel.h
@@ -55,6 +55,8 @@
#include <linux/jiffies.h>
#include <linux/log2.h>
#include <linux/kconfig.h>
+#include <linux/instruction_pointer.h>
+#include <linux/hex.h>
#include <asm/byteorder.h>
#include <asm/cpufeature.h>
@@ -267,8 +269,6 @@ extern int linuxkpi_debug;
#define u64_to_user_ptr(val) ((void *)(uintptr_t)(val))
-#define _RET_IP_ __builtin_return_address(0)
-
#define offsetofend(t, m) \
(offsetof(t, m) + sizeof((((t *)0)->m)))
@@ -306,37 +306,6 @@ linux_ratelimited(linux_ratelimit_t *rl)
#define add_taint(x,y) do { \
} while (0)
-static inline int
-_h2b(const char c)
-{
-
- if (c >= '0' && c <= '9')
- return (c - '0');
- if (c >= 'a' && c <= 'f')
- return (10 + c - 'a');
- if (c >= 'A' && c <= 'F')
- return (10 + c - 'A');
- return (-EINVAL);
-}
-
-static inline int
-hex2bin(uint8_t *bindst, const char *hexsrc, size_t binlen)
-{
- int hi4, lo4;
-
- while (binlen > 0) {
- hi4 = _h2b(*hexsrc++);
- lo4 = _h2b(*hexsrc++);
- if (hi4 < 0 || lo4 < 0)
- return (-EINVAL);
-
- *bindst++ = (hi4 << 4) | lo4;
- binlen--;
- }
-
- return (0);
-}
-
static inline bool
mac_pton(const char *macin, uint8_t *macout)
{
@@ -382,4 +351,37 @@ mac_pton(const char *macin, uint8_t *macout)
#define DECLARE_FLEX_ARRAY(_t, _n) \
struct { struct { } __dummy_ ## _n; _t _n[0]; }
+/*
+ * The following functions/macros are debug/diagnostics tools. They default to
+ * no-ops, except `might_sleep()` which uses `WITNESS_WARN()` on FreeBSD.
+ */
+static inline void
+__might_resched(const char *file, int line, unsigned int offsets)
+{
+}
+
+static inline void
+__might_sleep(const char *file, int line)
+{
+}
+
+static inline void
+might_fault(void)
+{
+}
+
+#define might_sleep() \
+ WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "might_sleep()")
+
+#define might_sleep_if(cond) do { \
+ if (cond) { might_sleep(); } \
+} while (0)
+
+#define might_resched() do { } while (0)
+#define cant_sleep() do { } while (0)
+#define cant_migrate() do { } while (0)
+#define sched_annotate_sleep() do { } while (0)
+#define non_block_start() do { } while (0)
+#define non_block_end() do { } while (0)
+
#endif /* _LINUXKPI_LINUX_KERNEL_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/kfifo.h b/sys/compat/linuxkpi/common/include/linux/kfifo.h
index d2f570781661..b0d0c17f07e4 100644
--- a/sys/compat/linuxkpi/common/include/linux/kfifo.h
+++ b/sys/compat/linuxkpi/common/include/linux/kfifo.h
@@ -33,8 +33,26 @@
#include <linux/slab.h>
#include <linux/gfp.h>
-#define INIT_KFIFO(x) 0
-#define DECLARE_KFIFO(x, y, z)
+/*
+ * INIT_KFIFO() is used to initialize the structure declared with
+ * DECLARE_KFIFO(). It doesn't work with DECLARE_KFIFO_PTR().
+ */
+#define INIT_KFIFO(_kf) \
+ ({ \
+ (_kf).total = nitems((_kf).head); \
+ (_kf).count = 0; \
+ (_kf).first = 0; \
+ (_kf).last = 0; \
+ })
+
+#define DECLARE_KFIFO(_name, _type, _size) \
+ struct kfifo_ ## _name { \
+ size_t total; \
+ size_t count; \
+ size_t first; \
+ size_t last; \
+ _type head[_size]; \
+ } _name
#define DECLARE_KFIFO_PTR(_name, _type) \
struct kfifo_ ## _name { \
@@ -71,7 +89,7 @@
(_kf)->head[(_kf)->last] = (_e); \
(_kf)->count++; \
(_kf)->last++; \
- if ((_kf)->last > (_kf)->total) \
+ if ((_kf)->last >= (_kf)->total) \
(_kf)->last = 0; \
_rc = true; \
} \
@@ -89,7 +107,7 @@
*(_e) = (_kf)->head[(_kf)->first]; \
(_kf)->count--; \
(_kf)->first++; \
- if ((_kf)->first > (_kf)->total) \
+ if ((_kf)->first >= (_kf)->total) \
(_kf)->first = 0; \
_rc = true; \
} \
diff --git a/sys/compat/linuxkpi/common/include/linux/kmsg_dump.h b/sys/compat/linuxkpi/common/include/linux/kmsg_dump.h
new file mode 100644
index 000000000000..539981c54d1b
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/kmsg_dump.h
@@ -0,0 +1,93 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025-2026 The FreeBSD Foundation
+ * Copyright (c) 2025-2026 Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
+ *
+ * This software was developed by Jean-Sébastien Pédron under sponsorship
+ * from the FreeBSD Foundation.
+ */
+
+#ifndef _LINUXKPI_LINUX_KMSG_DUMP_H_
+#define _LINUXKPI_LINUX_KMSG_DUMP_H_
+
+#include <linux/errno.h>
+#include <linux/list.h>
+
+#include <linux/kernel.h> /* For pr_debug() */
+
+enum kmsg_dump_reason {
+ KMSG_DUMP_UNDEF,
+ KMSG_DUMP_PANIC,
+ KMSG_DUMP_OOPS,
+ KMSG_DUMP_EMERG,
+ KMSG_DUMP_SHUTDOWN,
+ KMSG_DUMP_MAX
+};
+
+struct kmsg_dump_iter {
+ uint64_t cur_seq;
+ uint64_t next_seq;
+};
+
+struct kmsg_dumper {
+ struct list_head list;
+ void (*dump)(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason);
+ enum kmsg_dump_reason max_reason;
+ bool registered;
+};
+
+static inline void
+kmsg_dump(enum kmsg_dump_reason reason)
+{
+ pr_debug("TODO");
+}
+
+static inline bool
+kmsg_dump_get_line(struct kmsg_dump_iter *iter, bool syslog,
+ const char *line, size_t size, size_t *len)
+{
+ pr_debug("TODO");
+
+ return (false);
+}
+
+static inline bool
+kmsg_dump_get_buffer(struct kmsg_dump_iter *iter, bool syslog,
+ char *buf, size_t size, size_t *len)
+{
+ pr_debug("TODO");
+
+ return (false);
+}
+
+static inline void
+kmsg_dump_rewind(struct kmsg_dump_iter *iter)
+{
+ pr_debug("TODO");
+}
+
+static inline int
+kmsg_dump_register(struct kmsg_dumper *dumper)
+{
+ pr_debug("TODO");
+
+ return (-EINVAL);
+}
+
+static inline int
+kmsg_dump_unregister(struct kmsg_dumper *dumper)
+{
+ pr_debug("TODO");
+
+ return (-EINVAL);
+}
+
+static inline const char *
+kmsg_dump_reason_str(enum kmsg_dump_reason reason)
+{
+ pr_debug("TODO");
+
+ return ("Unknown");
+}
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/kstrtox.h b/sys/compat/linuxkpi/common/include/linux/kstrtox.h
index 5da99de24197..05bf94dd375d 100644
--- a/sys/compat/linuxkpi/common/include/linux/kstrtox.h
+++ b/sys/compat/linuxkpi/common/include/linux/kstrtox.h
@@ -74,14 +74,17 @@ static inline int
kstrtoul(const char *cp, unsigned int base, unsigned long *res)
{
char *end;
+ unsigned long temp;
- *res = strtoul(cp, &end, base);
+ temp = strtoul(cp, &end, base);
/* skip newline character, if any */
if (*end == '\n')
end++;
if (*cp == 0 || *end != 0)
return (-EINVAL);
+
+ *res = temp;
return (0);
}
@@ -89,14 +92,17 @@ static inline int
kstrtol(const char *cp, unsigned int base, long *res)
{
char *end;
+ long temp;
- *res = strtol(cp, &end, base);
+ temp = strtol(cp, &end, base);
/* skip newline character, if any */
if (*end == '\n')
end++;
if (*cp == 0 || *end != 0)
return (-EINVAL);
+
+ *res = temp;
return (0);
}
@@ -106,7 +112,7 @@ kstrtoint(const char *cp, unsigned int base, int *res)
char *end;
long temp;
- *res = temp = strtol(cp, &end, base);
+ temp = strtol(cp, &end, base);
/* skip newline character, if any */
if (*end == '\n')
@@ -115,6 +121,8 @@ kstrtoint(const char *cp, unsigned int base, int *res)
return (-EINVAL);
if (temp != (int)temp)
return (-ERANGE);
+
+ *res = (int)temp;
return (0);
}
@@ -124,7 +132,7 @@ kstrtouint(const char *cp, unsigned int base, unsigned int *res)
char *end;
unsigned long temp;
- *res = temp = strtoul(cp, &end, base);
+ temp = strtoul(cp, &end, base);
/* skip newline character, if any */
if (*end == '\n')
@@ -133,6 +141,8 @@ kstrtouint(const char *cp, unsigned int base, unsigned int *res)
return (-EINVAL);
if (temp != (unsigned int)temp)
return (-ERANGE);
+
+ *res = (unsigned int)temp;
return (0);
}
@@ -142,7 +152,7 @@ kstrtou8(const char *cp, unsigned int base, uint8_t *res)
char *end;
unsigned long temp;
- *res = temp = strtoul(cp, &end, base);
+ temp = strtoul(cp, &end, base);
/* skip newline character, if any */
if (*end == '\n')
@@ -151,6 +161,8 @@ kstrtou8(const char *cp, unsigned int base, uint8_t *res)
return (-EINVAL);
if (temp != (uint8_t)temp)
return (-ERANGE);
+
+ *res = (uint8_t)temp;
return (0);
}
@@ -160,7 +172,7 @@ kstrtou16(const char *cp, unsigned int base, uint16_t *res)
char *end;
unsigned long temp;
- *res = temp = strtoul(cp, &end, base);
+ temp = strtoul(cp, &end, base);
/* skip newline character, if any */
if (*end == '\n')
@@ -169,20 +181,20 @@ kstrtou16(const char *cp, unsigned int base, uint16_t *res)
return (-EINVAL);
if (temp != (uint16_t)temp)
return (-ERANGE);
+
+ *res = (uint16_t)temp;
return (0);
}
static inline int
kstrtou32(const char *cp, unsigned int base, uint32_t *res)
{
-
return (kstrtouint(cp, base, res));
}
static inline int
kstrtos32(const char *cp, unsigned int base, int32_t *res)
{
-
return (kstrtoint(cp, base, res));
}
@@ -190,14 +202,17 @@ static inline int
kstrtos64(const char *cp, unsigned int base, int64_t *res)
{
char *end;
+ quad_t temp;
- *res = strtoq(cp, &end, base);
+ temp = strtoq(cp, &end, base);
/* skip newline character, if any */
if (*end == '\n')
end++;
if (*cp == 0 || *end != 0)
return (-EINVAL);
+
+ *res = (int64_t)temp;
return (0);
}
@@ -208,17 +223,20 @@ kstrtoll(const char *cp, unsigned int base, long long *res)
}
static inline int
-kstrtou64(const char *cp, unsigned int base, u64 *res)
+kstrtou64(const char *cp, unsigned int base, uint64_t *res)
{
char *end;
+ u_quad_t temp;
- *res = strtouq(cp, &end, base);
+ temp = strtouq(cp, &end, base);
/* skip newline character, if any */
if (*end == '\n')
end++;
if (*cp == 0 || *end != 0)
return (-EINVAL);
+
+ *res = (uint64_t)temp;
return (0);
}
@@ -231,22 +249,16 @@ kstrtoull(const char *cp, unsigned int base, unsigned long long *res)
static inline int
kstrtobool(const char *s, bool *res)
{
- int len;
-
- if (s == NULL || (len = strlen(s)) == 0 || res == NULL)
+ if (s == NULL || *s == '\0')
return (-EINVAL);
- /* skip newline character, if any */
- if (s[len - 1] == '\n')
- len--;
-
- if (len == 1 && strchr("yY1", s[0]) != NULL)
+ if (strchr("eEtTyY1", s[0]) != NULL)
*res = true;
- else if (len == 1 && strchr("nN0", s[0]) != NULL)
+ else if (strchr("dDfFnN0", s[0]) != NULL)
*res = false;
- else if (strncasecmp("on", s, len) == 0)
+ else if (strncasecmp("on", s, 2) == 0)
*res = true;
- else if (strncasecmp("off", s, len) == 0)
+ else if (strncasecmp("of", s, 2) == 0)
*res = false;
else
return (-EINVAL);
@@ -302,7 +314,6 @@ static inline int
kstrtou32_from_user(const char __user *s, size_t count, unsigned int base,
unsigned int *p)
{
-
return (kstrtouint_from_user(s, count, base, p));
}
diff --git a/sys/compat/linuxkpi/common/include/linux/linux_logo.h b/sys/compat/linuxkpi/common/include/linux/linux_logo.h
new file mode 100644
index 000000000000..cb60ba50f6a5
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/linux_logo.h
@@ -0,0 +1,19 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2026 The FreeBSD Foundation
+ */
+
+#ifndef _LINUXKPI_LINUX_LINUX_LOGO_H_
+#define _LINUXKPI_LINUX_LINUX_LOGO_H_
+
+struct linux_logo {
+ int type;
+ unsigned int width;
+ unsigned int height;
+ unsigned int clutsize;
+ const unsigned char *clut;
+ const unsigned char *data;
+};
+
+#endif /* _LINUXKPI_LINUX_LINUX_LOGO_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/memcontrol.h b/sys/compat/linuxkpi/common/include/linux/memcontrol.h
new file mode 100644
index 000000000000..57fadf9af60f
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/memcontrol.h
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2025 The FreeBSD Foundation
+ * Copyright (c) 2025 Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
+ *
+ * This software was developed by Jean-Sébastien Pédron under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#ifndef _LINUXKPI_LINUX_MEMCONTROL_H_
+#define _LINUXKPI_LINUX_MEMCONTROL_H_
+
+#include <linux/cgroup.h>
+#include <linux/hardirq.h>
+#include <linux/jump_label.h>
+#include <linux/kernel.h>
+#include <linux/eventfd.h>
+#include <linux/mm.h>
+#include <linux/page-flags.h>
+#include <linux/shrinker.h>
+
+#endif /* defined(_LINUXKPI_LINUX_MEMCONTROL_H_) */
diff --git a/sys/compat/linuxkpi/common/include/linux/mfd/core.h b/sys/compat/linuxkpi/common/include/linux/mfd/core.h
new file mode 100644
index 000000000000..1a69a3803b5d
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/mfd/core.h
@@ -0,0 +1,49 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2026 The FreeBSD Foundation
+ */
+
+#ifndef _LINUXKPI_LINUX_MFD_CORE_H_
+#define _LINUXKPI_LINUX_MFD_CORE_H_
+
+#include <linux/platform_device.h>
+
+/*
+ * <linux/ioport.h> is not included by Linux, but we need it here to get the
+ * definition of `struct resource`.
+ *
+ * At least the amdgpu DRM driver (amdgpu_isp.c at the time of this writing)
+ * needs the structure without including this header: it relies on an implicit
+ * include of <linux/ioport.h> from <linux/pci.h>, which we can't have due to
+ * conflict with the FreeBSD native `struct resource`.
+ */
+#include <linux/ioport.h>
+
+#include <linux/kernel.h> /* pr_debug */
+
+struct resource;
+struct mfd_cell {
+ const char *name;
+ void *platform_data;
+ size_t pdata_size;
+ int num_resources;
+ const struct resource *resources;
+};
+
+static inline int
+mfd_add_hotplug_devices(struct device *parent,
+ const struct mfd_cell *cells, int n_devs)
+{
+ pr_debug("%s: TODO\n", __func__);
+
+ return (0);
+}
+
+static inline void
+mfd_remove_devices(struct device *parent)
+{
+ pr_debug("%s: TODO\n", __func__);
+}
+
+#endif /* _LINUXKPI_LINUX_MFD_CORE_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/minmax.h b/sys/compat/linuxkpi/common/include/linux/minmax.h
index d48958f0899f..5040d7f9141e 100644
--- a/sys/compat/linuxkpi/common/include/linux/minmax.h
+++ b/sys/compat/linuxkpi/common/include/linux/minmax.h
@@ -60,6 +60,9 @@
type __max2 = (y); \
__max1 > __max2 ? __max1 : __max2; })
+#define MIN_T(type, x, y) MIN((type)(x), (type)(y))
+#define MAX_T(type, x, y) MAX((type)(x), (type)(y))
+
#define clamp_t(type, _x, min, max) min_t(type, max_t(type, _x, min), max)
#define clamp(x, lo, hi) min(max(x, lo), hi)
#define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi)
@@ -71,4 +74,7 @@
b = _swap_tmp; \
} while (0)
+/* XXX would have to make sure both are unsigned. */
+#define umin(x, y) MIN(x, y)
+
#endif /* _LINUXKPI_LINUX_MINMAX_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h b/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h
index 87bd6ec24bce..b345b98325e1 100644
--- a/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h
+++ b/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h
@@ -30,6 +30,7 @@
#define __LINUXKPI_LINUX_MOD_DEVICETABLE_H__
#include <linux/types.h>
+#include <linux/uuid.h>
enum dmi_field {
DMI_NONE,
@@ -80,4 +81,10 @@ struct dmi_system_id {
#define ACPI_ID_LEN 16
+/* -----------------------------------------------------------------------------
+ * USB
+ */
+/* struct usb_device_id is defined in sys/dev/usb/usbdi.h. */
+/* MODULE_DEVICE_TABLE_BUS_usb we have in usb.h. */
+
#endif /* __LINUXKPI_LINUX_MOD_DEVICETABLE_H__ */
diff --git a/sys/compat/linuxkpi/common/include/linux/module.h b/sys/compat/linuxkpi/common/include/linux/module.h
index 079dacf8df6c..fbe57cbbed82 100644
--- a/sys/compat/linuxkpi/common/include/linux/module.h
+++ b/sys/compat/linuxkpi/common/include/linux/module.h
@@ -53,6 +53,24 @@
#define MODULE_SUPPORTED_DEVICE(name)
#define MODULE_IMPORT_NS(_name)
+/* Linux has an empty element at the end of the ID table -> nitems() - 1. */
+#define MODULE_DEVICE_TABLE(_bus, _table) \
+ \
+static device_method_t _ ## _bus ## _ ## _table ## _methods[] = { \
+ DEVMETHOD_END \
+}; \
+ \
+static driver_t _ ## _bus ## _ ## _table ## _driver = { \
+ "lkpi_" #_bus #_table, \
+ _ ## _bus ## _ ## _table ## _methods, \
+ 0 \
+}; \
+ \
+DRIVER_MODULE(lkpi_ ## _table, _bus, _ ## _bus ## _ ## _table ## _driver,\
+ 0, 0); \
+ \
+MODULE_DEVICE_TABLE_BUS_ ## _bus(_bus, _table)
+
/*
* THIS_MODULE is used to differentiate modules on Linux. We currently
* completely stub out any Linux struct module usage, but THIS_MODULE is still
diff --git a/sys/compat/linuxkpi/common/include/linux/netdevice.h b/sys/compat/linuxkpi/common/include/linux/netdevice.h
index cf27753bcb80..dfed5fbd61b4 100644
--- a/sys/compat/linuxkpi/common/include/linux/netdevice.h
+++ b/sys/compat/linuxkpi/common/include/linux/netdevice.h
@@ -160,6 +160,30 @@ struct net_device {
#define SET_NETDEV_DEV(_ndev, _dev) (_ndev)->dev.parent = _dev;
+enum net_device_path_type {
+ DEV_PATH_MTK_WDMA,
+};
+
+struct net_device_path {
+ enum net_device_path_type type;
+ const struct net_device *dev;
+ /* We assume there's a struct per type. */
+ union {
+ struct {
+ uint16_t wcid;
+ uint8_t wdma_idx;
+ uint8_t queue;
+ uint8_t bss;
+ uint8_t amsdu;
+ } mtk_wdma;
+ };
+};
+
+struct net_device_path_ctx {
+ const struct net_device *dev;
+};
+
+
/* -------------------------------------------------------------------------- */
/* According to linux::ipoib_main.c. */
struct netdev_notifier_info {
diff --git a/sys/compat/linuxkpi/common/include/linux/notifier.h b/sys/compat/linuxkpi/common/include/linux/notifier.h
index 9302a1ce4606..4fe43255c648 100644
--- a/sys/compat/linuxkpi/common/include/linux/notifier.h
+++ b/sys/compat/linuxkpi/common/include/linux/notifier.h
@@ -32,6 +32,11 @@
#include <sys/types.h>
#include <sys/eventhandler.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/rwsem.h>
+#include <linux/srcu.h>
+
#define NOTIFY_DONE 0
#define NOTIFY_OK 0x0001
#define NOTIFY_STOP_MASK 0x8000
diff --git a/sys/compat/linuxkpi/common/include/linux/overflow.h b/sys/compat/linuxkpi/common/include/linux/overflow.h
index e811037b8ecc..4326f05e6d07 100644
--- a/sys/compat/linuxkpi/common/include/linux/overflow.h
+++ b/sys/compat/linuxkpi/common/include/linux/overflow.h
@@ -4,9 +4,7 @@
#include <linux/compiler.h>
#include <linux/limits.h>
-#ifdef __linux__
#include <linux/const.h>
-#endif
/*
* We need to compute the minimum and maximum values representable in a given
@@ -38,19 +36,13 @@
#define __type_min(T) ((T)((T)-type_max(T)-(T)1))
#define type_min(t) __type_min(typeof(t))
-/*
- * Avoids triggering -Wtype-limits compilation warning,
- * while using unsigned data types to check a < 0.
- */
-#define is_non_negative(a) ((a) > 0 || (a) == 0)
-#define is_negative(a) (!(is_non_negative(a)))
/*
* Allows for effectively applying __must_check to a macro so we can have
* both the type-agnostic benefits of the macros while also being able to
* enforce that the return value is, in fact, checked.
*/
-static inline bool __must_check __must_check_overflow(bool overflow)
+static __always_inline bool __must_check __must_check_overflow(bool overflow)
{
return unlikely(overflow);
}
@@ -203,9 +195,9 @@ static inline bool __must_check __must_check_overflow(bool overflow)
typeof(d) _d = d; \
unsigned long long _a_full = _a; \
unsigned int _to_shift = \
- is_non_negative(_s) && _s < 8 * sizeof(*d) ? _s : 0; \
+ _s >= 0 && _s < 8 * sizeof(*d) ? _s : 0; \
*_d = (_a_full << _to_shift); \
- (_to_shift != _s || is_negative(*_d) || is_negative(_a) || \
+ (_to_shift != _s || *_d < 0 || _a < 0 || \
(*_d >> _to_shift) != _a); \
}))
@@ -241,6 +233,76 @@ static inline bool __must_check __must_check_overflow(bool overflow)
__overflows_type(n, T))
/**
+ * range_overflows() - Check if a range is out of bounds
+ * @start: Start of the range.
+ * @size: Size of the range.
+ * @max: Exclusive upper boundary.
+ *
+ * A strict check to determine if the range [@start, @start + @size) is
+ * invalid with respect to the allowable range [0, @max). Any range
+ * starting at or beyond @max is considered an overflow, even if @size is 0.
+ *
+ * Returns: true if the range is out of bounds.
+ */
+#define range_overflows(start, size, max) ({ \
+ typeof(start) start__ = (start); \
+ typeof(size) size__ = (size); \
+ typeof(max) max__ = (max); \
+ (void)(&start__ == &size__); \
+ (void)(&start__ == &max__); \
+ start__ >= max__ || size__ > max__ - start__; \
+})
+
+/**
+ * range_overflows_t() - Check if a range is out of bounds
+ * @type: Data type to use.
+ * @start: Start of the range.
+ * @size: Size of the range.
+ * @max: Exclusive upper boundary.
+ *
+ * Same as range_overflows() but forcing the parameters to @type.
+ *
+ * Returns: true if the range is out of bounds.
+ */
+#define range_overflows_t(type, start, size, max) \
+ range_overflows((type)(start), (type)(size), (type)(max))
+
+/**
+ * range_end_overflows() - Check if a range's endpoint is out of bounds
+ * @start: Start of the range.
+ * @size: Size of the range.
+ * @max: Exclusive upper boundary.
+ *
+ * Checks only if the endpoint of a range (@start + @size) exceeds @max.
+ * Unlike range_overflows(), a zero-sized range at the boundary (@start == @max)
+ * is not considered an overflow. Useful for iterator-style checks.
+ *
+ * Returns: true if the endpoint exceeds the boundary.
+ */
+#define range_end_overflows(start, size, max) ({ \
+ typeof(start) start__ = (start); \
+ typeof(size) size__ = (size); \
+ typeof(max) max__ = (max); \
+ (void)(&start__ == &size__); \
+ (void)(&start__ == &max__); \
+ start__ > max__ || size__ > max__ - start__; \
+})
+
+/**
+ * range_end_overflows_t() - Check if a range's endpoint is out of bounds
+ * @type: Data type to use.
+ * @start: Start of the range.
+ * @size: Size of the range.
+ * @max: Exclusive upper boundary.
+ *
+ * Same as range_end_overflows() but forcing the parameters to @type.
+ *
+ * Returns: true if the endpoint exceeds the boundary.
+ */
+#define range_end_overflows_t(type, start, size, max) \
+ range_end_overflows((type)(start), (type)(size), (type)(max))
+
+/**
* castable_to_type - like __same_type(), but also allows for casted literals
*
* @n: variable or constant value
@@ -265,7 +327,7 @@ static inline bool __must_check __must_check_overflow(bool overflow)
* with any overflow causing the return value to be SIZE_MAX. The
* lvalue must be size_t to avoid implicit type conversion.
*/
-static inline size_t __must_check size_mul(size_t factor1, size_t factor2)
+static __always_inline size_t __must_check size_mul(size_t factor1, size_t factor2)
{
size_t bytes;
@@ -284,7 +346,7 @@ static inline size_t __must_check size_mul(size_t factor1, size_t factor2)
* with any overflow causing the return value to be SIZE_MAX. The
* lvalue must be size_t to avoid implicit type conversion.
*/
-static inline size_t __must_check size_add(size_t addend1, size_t addend2)
+static __always_inline size_t __must_check size_add(size_t addend1, size_t addend2)
{
size_t bytes;
@@ -305,7 +367,7 @@ static inline size_t __must_check size_add(size_t addend1, size_t addend2)
* argument may be SIZE_MAX (or the result with be forced to SIZE_MAX).
* The lvalue must be size_t to avoid implicit type conversion.
*/
-static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
+static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
{
size_t bytes;
@@ -391,6 +453,18 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
struct_size((type *)NULL, member, count)
/**
+ * struct_offset() - Calculate the offset of a member within a struct
+ * @p: Pointer to the struct
+ * @member: Name of the member to get the offset of
+ *
+ * Calculates the offset of a particular @member of the structure pointed
+ * to by @p.
+ *
+ * Return: number of bytes to the location of @member.
+ */
+#define struct_offset(p, member) (offsetof(typeof(*(p)), member))
+
+/**
* __DEFINE_FLEX() - helper macro for DEFINE_FLEX() family.
* Enables caller macro to pass arbitrary trailing expressions
*
@@ -472,4 +546,46 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
(__member_size((name)->array) / sizeof(*(name)->array) + \
__must_be_array((name)->array))
+/**
+ * typeof_flex_counter() - Return the type of the counter variable of a given
+ * flexible array member annotated by __counted_by().
+ * @FAM: Instance of flexible array member within a given struct.
+ *
+ * Returns: "size_t" if no annotation exists.
+ */
+#define typeof_flex_counter(FAM) \
+ typeof(_Generic(__flex_counter(FAM), \
+ void *: (size_t)0, \
+ default: *__flex_counter(FAM)))
+
+/**
+ * overflows_flex_counter_type() - Check if the counter associated with the
+ * given flexible array member can represent
+ * a value.
+ * @TYPE: Type of the struct that contains the @FAM.
+ * @FAM: Member name of the FAM within @TYPE.
+ * @COUNT: Value to check against the __counted_by annotated @FAM's counter.
+ *
+ * Returns: true if @COUNT can be represented in the @FAM's counter. When
+ * @FAM is not annotated with __counted_by(), always returns true.
+ */
+#define overflows_flex_counter_type(TYPE, FAM, COUNT) \
+ (overflows_type(COUNT, typeof_flex_counter(((TYPE *)NULL)->FAM)))
+
+/**
+ * __set_flex_counter() - Set the counter associated with the given flexible
+ * array member that has been annoated by __counted_by().
+ * @FAM: Instance of flexible array member within a given struct.
+ * @COUNT: Value to store to the __counted_by annotated @FAM_PTR's counter.
+ *
+ * This is a no-op if no annotation exists. Count needs to be checked with
+ * overflows_flex_counter_type() before using this function.
+ */
+#define __set_flex_counter(FAM, COUNT) \
+({ \
+ *_Generic(__flex_counter(FAM), \
+ void *: &(size_t){ 0 }, \
+ default: __flex_counter(FAM)) = (COUNT); \
+})
+
#endif /* _LINUXKPI_LINUX_OVERFLOW_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h
index 06336bf963d6..ba68a9ee0dc3 100644
--- a/sys/compat/linuxkpi/common/include/linux/pci.h
+++ b/sys/compat/linuxkpi/common/include/linux/pci.h
@@ -60,6 +60,17 @@
#include <linux/pci_ids.h>
#include <linux/pm.h>
+/*
+ * <linux/ioport.h> should be included here, like Linux, but we can't have that
+ * because Linux `struct resource` definition would conflict with FreeBSD
+ * native definition.
+ *
+ * At least the amdgpu DRM driver (amdgpu_isp.c at the time of this writing)
+ * relies on this indirect include to get the definition of Linux `struct
+ * resource`. As a workaround, we include <linux/ioport.h> from
+ * <linux/mfd/core.h>.
+ */
+
#include <linux/kernel.h> /* pr_debug */
struct pci_device_id {
@@ -76,24 +87,6 @@ struct pci_device_id {
MODULE_PNP_INFO("U32:vendor;U32:device;V32:subvendor;V32:subdevice", \
_bus, lkpi_ ## _table, _table, nitems(_table) - 1)
-/* Linux has an empty element at the end of the ID table -> nitems() - 1. */
-#define MODULE_DEVICE_TABLE(_bus, _table) \
- \
-static device_method_t _ ## _bus ## _ ## _table ## _methods[] = { \
- DEVMETHOD_END \
-}; \
- \
-static driver_t _ ## _bus ## _ ## _table ## _driver = { \
- "lkpi_" #_bus #_table, \
- _ ## _bus ## _ ## _table ## _methods, \
- 0 \
-}; \
- \
-DRIVER_MODULE(lkpi_ ## _table, _bus, _ ## _bus ## _ ## _table ## _driver,\
- 0, 0); \
- \
-MODULE_DEVICE_TABLE_BUS_ ## _bus(_bus, _table)
-
#define PCI_ANY_ID -1U
#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
@@ -253,6 +246,20 @@ extern const char *pci_power_names[6];
#define PCI_IRQ_LEGACY PCI_IRQ_INTX
#endif
+/*
+ * Linux PCI code uses `PCI_SET_ERROR_RESPONSE()` to indicate to the caller of
+ * a `pci_read_*()` function that the read failed. An example of failure is
+ * whether the device was disconnected. It is a bit weird because Linux
+ * `pci_read_*()` can return an error value, as the read value is stored in a
+ * integer passed by pointer.
+ *
+ * We don't set PCI_ERROR_RESPONSE anywhere as of this commit, but the DRM
+ * drivers started to use `PCI_POSSIBLE_ERROR()`.
+ */
+#define PCI_ERROR_RESPONSE (~0ULL)
+#define PCI_SET_ERROR_RESPONSE(val) (*(val) = ((typeof(*(val))) PCI_ERROR_RESPONSE))
+#define PCI_POSSIBLE_ERROR(val) ((val) == ((typeof(val)) PCI_ERROR_RESPONSE))
+
struct pci_dev;
struct pci_driver {
@@ -1122,19 +1129,28 @@ pci_num_vf(struct pci_dev *dev)
static inline enum pci_bus_speed
pcie_get_speed_cap(struct pci_dev *dev)
{
+ struct pci_dev *pbus;
device_t root;
uint32_t lnkcap, lnkcap2;
int error, pos;
- root = device_get_parent(dev->dev.bsddev);
- if (root == NULL)
- return (PCI_SPEED_UNKNOWN);
- root = device_get_parent(root);
- if (root == NULL)
- return (PCI_SPEED_UNKNOWN);
- root = device_get_parent(root);
- if (root == NULL)
- return (PCI_SPEED_UNKNOWN);
+ /*
+ * We should always be called on a PCI device.
+ * The only current consumer I could find was amdgpu which either
+ * calls us directly on a pdev(drmn?) or with the result of
+ * pci_upstream_bridge().
+ *
+ * Treat "drmn" as special again as it is not a PCI device.
+ */
+ if (dev->pdrv != NULL && dev->pdrv->isdrm) {
+ pbus = pci_upstream_bridge(dev);
+ if (pbus == NULL)
+ return (PCI_SPEED_UNKNOWN);
+ } else
+ pbus = dev;
+
+ /* "root" may be misleading as it may not be that. */
+ root = pbus->dev.bsddev;
if (pci_get_vendor(root) == PCI_VENDOR_ID_VIA ||
pci_get_vendor(root) == PCI_VENDOR_ID_SERVERWORKS)
diff --git a/sys/compat/linuxkpi/common/include/linux/platform_data/brcmfmac.h b/sys/compat/linuxkpi/common/include/linux/platform_data/brcmfmac.h
new file mode 100644
index 000000000000..ec99b7b73d1d
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/platform_data/brcmfmac.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2016 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _LINUX_BRCMFMAC_PLATFORM_H
+#define _LINUX_BRCMFMAC_PLATFORM_H
+
+
+#define BRCMFMAC_PDATA_NAME "brcmfmac"
+
+#define BRCMFMAC_COUNTRY_BUF_SZ 4
+
+
+/*
+ * Platform specific driver functions and data. Through the platform specific
+ * device data functions and data can be provided to help the brcmfmac driver to
+ * operate with the device in combination with the used platform.
+ */
+
+
+/**
+ * Note: the brcmfmac can be loaded as module or be statically built-in into
+ * the kernel. If built-in then do note that it uses module_init (and
+ * module_exit) routines which equal device_initcall. So if you intend to
+ * create a module with the platform specific data for the brcmfmac and have
+ * it built-in to the kernel then use a higher initcall then device_initcall
+ * (see init.h). If this is not done then brcmfmac will load without problems
+ * but will not pickup the platform data.
+ *
+ * When the driver does not "detect" platform driver data then it will continue
+ * without reporting anything and just assume there is no data needed. Which is
+ * probably true for most platforms.
+ */
+
+/**
+ * enum brcmf_bus_type - Bus type identifier. Currently SDIO, USB and PCIE are
+ * supported.
+ */
+enum brcmf_bus_type {
+ BRCMF_BUSTYPE_SDIO,
+ BRCMF_BUSTYPE_USB,
+ BRCMF_BUSTYPE_PCIE
+};
+
+
+/**
+ * struct brcmfmac_sdio_pd - SDIO Device specific platform data.
+ *
+ * @txglomsz: SDIO txglom size. Use 0 if default of driver is to be
+ * used.
+ * @drive_strength: is the preferred drive_strength to be used for the SDIO
+ * pins. If 0 then a default value will be used. This is
+ * the target drive strength, the exact drive strength
+ * which will be used depends on the capabilities of the
+ * device.
+ * @oob_irq_supported: does the board have support for OOB interrupts. SDIO
+ * in-band interrupts are relatively slow and for having
+ * less overhead on interrupt processing an out of band
+ * interrupt can be used. If the HW supports this then
+ * enable this by setting this field to true and configure
+ * the oob related fields.
+ * @oob_irq_nr,
+ * @oob_irq_flags: the OOB interrupt information. The values are used for
+ * registering the irq using request_irq function.
+ * @broken_sg_support: flag for broken sg list support of SDIO host controller.
+ * Set this to true if the SDIO host controller has higher
+ * align requirement than 32 bytes for each scatterlist
+ * item.
+ * @sd_head_align: alignment requirement for start of data buffer.
+ * @sd_sgentry_align: length alignment requirement for each sg entry.
+ * @reset: This function can get called if the device communication
+ * broke down. This functionality is particularly useful in
+ * case of SDIO type devices. It is possible to reset a
+ * dongle via sdio data interface, but it requires that
+ * this is fully functional. This function is chip/module
+ * specific and this function should return only after the
+ * complete reset has completed.
+ */
+struct brcmfmac_sdio_pd {
+ int txglomsz;
+ unsigned int drive_strength;
+ bool oob_irq_supported;
+ unsigned int oob_irq_nr;
+ unsigned long oob_irq_flags;
+ bool broken_sg_support;
+ unsigned short sd_head_align;
+ unsigned short sd_sgentry_align;
+ void (*reset)(void);
+};
+
+/**
+ * struct brcmfmac_pd_cc_entry - Struct for translating user space country code
+ * (iso3166) to firmware country code and
+ * revision.
+ *
+ * @iso3166: iso3166 alpha 2 country code string.
+ * @cc: firmware country code string.
+ * @rev: firmware country code revision.
+ */
+struct brcmfmac_pd_cc_entry {
+ char iso3166[BRCMFMAC_COUNTRY_BUF_SZ];
+ char cc[BRCMFMAC_COUNTRY_BUF_SZ];
+ s32 rev;
+};
+
+/**
+ * struct brcmfmac_pd_cc - Struct for translating country codes as set by user
+ * space to a country code and rev which can be used by
+ * firmware.
+ *
+ * @table_size: number of entries in table (> 0)
+ * @table: array of 1 or more elements with translation information.
+ */
+struct brcmfmac_pd_cc {
+ int table_size;
+ struct brcmfmac_pd_cc_entry table[];
+};
+
+/**
+ * struct brcmfmac_pd_device - Device specific platform data. (id/rev/bus_type)
+ * is the unique identifier of the device.
+ *
+ * @id: ID of the device for which this data is. In case of SDIO
+ * or PCIE this is the chipid as identified by chip.c In
+ * case of USB this is the chipid as identified by the
+ * device query.
+ * @rev: chip revision, see id.
+ * @bus_type: The type of bus. Some chipid/rev exist for different bus
+ * types. Each bus type has its own set of settings.
+ * @feature_disable: Bitmask of features to disable (override), See feature.c
+ * in brcmfmac for details.
+ * @country_codes: If available, pointer to struct for translating country
+ * codes.
+ * @bus: Bus specific (union) device settings. Currently only
+ * SDIO.
+ */
+struct brcmfmac_pd_device {
+ unsigned int id;
+ unsigned int rev;
+ enum brcmf_bus_type bus_type;
+ unsigned int feature_disable;
+ struct brcmfmac_pd_cc *country_codes;
+ union {
+ struct brcmfmac_sdio_pd sdio;
+ } bus;
+};
+
+/**
+ * struct brcmfmac_platform_data - BRCMFMAC specific platform data.
+ *
+ * @power_on: This function is called by the brcmfmac driver when the module
+ * gets loaded. This can be particularly useful for low power
+ * devices. The platform spcific routine may for example decide to
+ * power up the complete device. If there is no use-case for this
+ * function then provide NULL.
+ * @power_off: This function is called by the brcmfmac when the module gets
+ * unloaded. At this point the devices can be powered down or
+ * otherwise be reset. So if an actual power_off is not supported
+ * but reset is supported by the devices then reset the devices
+ * when this function gets called. This can be particularly useful
+ * for low power devices. If there is no use-case for this
+ * function then provide NULL.
+ */
+struct brcmfmac_platform_data {
+ void (*power_on)(void);
+ void (*power_off)(void);
+ char *fw_alternative_path;
+ int device_count;
+ struct brcmfmac_pd_device devices[];
+};
+
+
+#endif /* _LINUX_BRCMFMAC_PLATFORM_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/printk.h b/sys/compat/linuxkpi/common/include/linux/printk.h
index d2d197682782..066ec900f04e 100644
--- a/sys/compat/linuxkpi/common/include/linux/printk.h
+++ b/sys/compat/linuxkpi/common/include/linux/printk.h
@@ -48,7 +48,13 @@ int __lkpi_hexdump_printf(void *, const char *, ...) __printflike(2, 3);
void lkpi_hex_dump(int(*)(void *, const char *, ...), void *arg1,
const char *, const char *, const int, const int, const int,
- const void *, size_t, const bool);
+ const void *, size_t, const bool, const bool);
+
+#define hex_dump_to_buffer(buf, len, rowsize, groupsize, linebuf, linebuflen, ascii) \
+ lkpi_hex_dump_to_buffer((buf), (len), (rowsize), (groupsize), (linebuf), (linebuflen), (ascii))
+
+int lkpi_hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
+ int groupsize, char *linebuf, size_t linebuflen, bool ascii);
static inline void
print_hex_dump(const char *level, const char *prefix_str,
@@ -56,7 +62,7 @@ print_hex_dump(const char *level, const char *prefix_str,
const void *buf, size_t len, const bool ascii)
{
lkpi_hex_dump(__lkpi_hexdump_printf, NULL, level, prefix_str, prefix_type,
- rowsize, groupsize, buf, len, ascii);
+ rowsize, groupsize, buf, len, ascii, true);
}
static inline void
diff --git a/sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h b/sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h
index aad46cc25b1b..6491cbeab7e2 100644
--- a/sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h
+++ b/sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h
@@ -49,6 +49,7 @@ struct ptp_clock_info {
int (*adjtime)(struct ptp_clock_info *, s64);
int (*getcrosststamp)(struct ptp_clock_info *, struct system_device_crosststamp *);
int (*gettime64)(struct ptp_clock_info *, struct timespec *);
+ int (*settime64)(struct ptp_clock_info *, const struct timespec *);
};
static inline struct ptp_clock *
diff --git a/sys/compat/linuxkpi/common/include/linux/radix-tree.h b/sys/compat/linuxkpi/common/include/linux/radix-tree.h
index 1019697303db..7182f4a9e407 100644
--- a/sys/compat/linuxkpi/common/include/linux/radix-tree.h
+++ b/sys/compat/linuxkpi/common/include/linux/radix-tree.h
@@ -38,12 +38,19 @@
#define RADIX_TREE_MAX_HEIGHT \
howmany(sizeof(long) * NBBY, RADIX_TREE_MAP_SHIFT)
+#define RADIX_TREE_MAX_TAGS 3
+#define RADIX_TREE_TAG_LONGS RADIX_TREE_MAP_SIZE
+
#define RADIX_TREE_ENTRY_MASK 3UL
#define RADIX_TREE_EXCEPTIONAL_ENTRY 2UL
#define RADIX_TREE_EXCEPTIONAL_SHIFT 2
+#define RADIX_TREE_ITER_TAG_MASK 0x0f
+#define RADIX_TREE_ITER_TAGGED 0x10
+
struct radix_tree_node {
void *slots[RADIX_TREE_MAP_SIZE];
+ unsigned long tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS];
int count;
};
@@ -51,6 +58,8 @@ struct radix_tree_root {
struct radix_tree_node *rnode;
gfp_t gfp_mask;
int height;
+ /* Linux stores root tags inside `gfp_mask`. */
+ unsigned long tags[RADIX_TREE_MAX_TAGS];
};
struct radix_tree_iter {
@@ -64,9 +73,22 @@ struct radix_tree_iter {
#define RADIX_TREE(name, mask) \
struct radix_tree_root name = RADIX_TREE_INIT(mask)
-#define radix_tree_for_each_slot(slot, root, iter, start) \
- for ((iter)->index = (start); \
- radix_tree_iter_find(root, iter, &(slot)); (iter)->index++)
+#define radix_tree_for_each_slot(slot, root, iter, start) \
+ for ((iter)->index = (start); \
+ radix_tree_iter_find(root, iter, &(slot), 0); \
+ (iter)->index++)
+
+#define radix_tree_for_each_slot_tagged(slot, root, iter, start, tag) \
+ for ((iter)->index = (start); \
+ radix_tree_iter_find(root, iter, &(slot), \
+ RADIX_TREE_ITER_TAGGED | tag); \
+ (iter)->index++)
+
+static inline void *
+radix_tree_deref_slot(void **slot)
+{
+ return (*slot);
+}
static inline int
radix_tree_exception(void *arg)
@@ -78,7 +100,12 @@ void *radix_tree_lookup(const struct radix_tree_root *, unsigned long);
void *radix_tree_delete(struct radix_tree_root *, unsigned long);
int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
int radix_tree_store(struct radix_tree_root *, unsigned long, void **);
-bool radix_tree_iter_find(const struct radix_tree_root *, struct radix_tree_iter *, void ***);
+bool radix_tree_iter_find(const struct radix_tree_root *, struct radix_tree_iter *, void ***, int);
void radix_tree_iter_delete(struct radix_tree_root *, struct radix_tree_iter *, void **);
+void *radix_tree_tag_set(struct radix_tree_root *root, unsigned long index, unsigned int tag);
+void *radix_tree_tag_clear(struct radix_tree_root *root, unsigned long index, unsigned int tag);
+int radix_tree_tagged(const struct radix_tree_root *root, unsigned int tag);
+unsigned int radix_tree_gang_lookup(const struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items);
+unsigned int radix_tree_gang_lookup_tag(const struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items, unsigned int tag);
#endif /* _LINUXKPI_LINUX_RADIX_TREE_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/ratelimit.h b/sys/compat/linuxkpi/common/include/linux/ratelimit.h
index 9585b4b994d7..fdef57c7882d 100644
--- a/sys/compat/linuxkpi/common/include/linux/ratelimit.h
+++ b/sys/compat/linuxkpi/common/include/linux/ratelimit.h
@@ -14,4 +14,11 @@ struct ratelimit_state {
#define ratelimit_state_init(x, y, z)
#define ratelimit_set_flags(x, y)
+#define WARN_RATELIMIT(condition, ...) ({ \
+ bool __ret_warn_on = (condition); \
+ if (unlikely(__ret_warn_on)) \
+ pr_warn_ratelimited(__VA_ARGS__); \
+ unlikely(__ret_warn_on); \
+})
+
#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/regulator/consumer.h b/sys/compat/linuxkpi/common/include/linux/regulator/consumer.h
new file mode 100644
index 000000000000..d6c23575bc83
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/regulator/consumer.h
@@ -0,0 +1,17 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025-2026 The FreeBSD Foundation
+ * Copyright (c) 2025-2026 Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
+ *
+ * This software was developed by Jean-Sébastien Pédron under sponsorship
+ * from the FreeBSD Foundation.
+ */
+
+#ifndef _LINUXKPI_LINUX_REGULATOR_CONSUMER_H_
+#define _LINUXKPI_LINUX_REGULATOR_CONSUMER_H_
+
+#include <linux/err.h>
+#include <linux/suspend.h>
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/seq_buf.h b/sys/compat/linuxkpi/common/include/linux/seq_buf.h
new file mode 100644
index 000000000000..d6246a40e6f7
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/seq_buf.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2025-2026 The FreeBSD Foundation
+ * Copyright (c) 2025-2026 Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
+ *
+ * This software was developed by Jean-Sébastien Pédron under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_LINUX_SEQ_BUF_H_
+#define _LINUXKPI_LINUX_SEQ_BUF_H_
+
+#include <linux/bug.h>
+#include <linux/minmax.h>
+#include <linux/seq_file.h>
+#include <linux/types.h>
+
+struct seq_buf {
+ char *buffer;
+ size_t size;
+ size_t len;
+};
+
+#define DECLARE_SEQ_BUF(NAME, SIZE) \
+ struct seq_buf NAME = { \
+ .buffer = (char[SIZE]) { 0 }, \
+ .size = SIZE, \
+ }
+
+static inline void
+seq_buf_clear(struct seq_buf *s)
+{
+ s->len = 0;
+ if (s->size > 0)
+ s->buffer[0] = '\0';
+}
+
+static inline void
+seq_buf_set_overflow(struct seq_buf *s)
+{
+ s->len = s->size + 1;
+}
+
+static inline bool
+seq_buf_has_overflowed(struct seq_buf *s)
+{
+ return (s->len > s->size);
+}
+
+static inline bool
+seq_buf_buffer_left(struct seq_buf *s)
+{
+ if (seq_buf_has_overflowed(s))
+ return (0);
+
+ return (s->size - s->len);
+}
+
+#define seq_buf_init(s, buf, size) linuxkpi_seq_buf_init((s), (buf), (size))
+void linuxkpi_seq_buf_init(struct seq_buf *s, char *buf, unsigned int size);
+
+#define seq_buf_printf(s, f, ...) linuxkpi_seq_buf_printf((s), (f), __VA_ARGS__)
+int linuxkpi_seq_buf_printf(struct seq_buf *s, const char *fmt, ...) \
+ __printflike(2, 3);
+
+#define seq_buf_vprintf(s, f, a) linuxkpi_seq_buf_vprintf((s), (f), (a))
+int linuxkpi_seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args);
+
+#define seq_buf_str(s) linuxkpi_seq_buf_str((s))
+const char * linuxkpi_seq_buf_str(struct seq_buf *s);
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/seq_file.h b/sys/compat/linuxkpi/common/include/linux/seq_file.h
index 47da16ab8688..786c09bd6a20 100644
--- a/sys/compat/linuxkpi/common/include/linux/seq_file.h
+++ b/sys/compat/linuxkpi/common/include/linux/seq_file.h
@@ -85,7 +85,7 @@ struct seq_operations {
int (*show) (struct seq_file *m, void *v);
};
-ssize_t seq_read(struct linux_file *, char *, size_t, off_t *);
+ssize_t seq_read(struct linux_file *, char __user *, size_t, off_t *);
int seq_write(struct seq_file *seq, const void *data, size_t len);
void seq_putc(struct seq_file *m, char c);
void seq_puts(struct seq_file *m, const char *str);
@@ -115,7 +115,7 @@ seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,
int rowsize, int groupsize, const void *buf, size_t len, bool ascii)
{
lkpi_hex_dump(__lkpi_hexdump_sbuf_printf, m->buf, NULL, prefix_str, prefix_type,
- rowsize, groupsize, buf, len, ascii);
+ rowsize, groupsize, buf, len, ascii, true);
}
#define file linux_file
diff --git a/sys/compat/linuxkpi/common/include/linux/siphash.h b/sys/compat/linuxkpi/common/include/linux/siphash.h
new file mode 100644
index 000000000000..9153e77382e1
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/siphash.h
@@ -0,0 +1,168 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+/* Copyright (C) 2016-2022 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ *
+ * SipHash: a fast short-input PRF
+ * https://131002.net/siphash/
+ *
+ * This implementation is specifically for SipHash2-4 for a secure PRF
+ * and HalfSipHash1-3/SipHash1-3 for an insecure PRF only suitable for
+ * hashtables.
+ */
+
+#ifndef _LINUX_SIPHASH_H
+#define _LINUX_SIPHASH_H
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#define SIPHASH_ALIGNMENT __alignof__(u64)
+typedef struct {
+ u64 key[2];
+} siphash_key_t;
+
+#define siphash_aligned_key_t siphash_key_t __aligned(16)
+
+static inline bool siphash_key_is_zero(const siphash_key_t *key)
+{
+ return !(key->key[0] | key->key[1]);
+}
+
+u64 __siphash_aligned(const void *data, size_t len, const siphash_key_t *key);
+u64 __siphash_unaligned(const void *data, size_t len, const siphash_key_t *key);
+
+u64 siphash_1u64(const u64 a, const siphash_key_t *key);
+u64 siphash_2u64(const u64 a, const u64 b, const siphash_key_t *key);
+u64 siphash_3u64(const u64 a, const u64 b, const u64 c,
+ const siphash_key_t *key);
+u64 siphash_4u64(const u64 a, const u64 b, const u64 c, const u64 d,
+ const siphash_key_t *key);
+u64 siphash_1u32(const u32 a, const siphash_key_t *key);
+u64 siphash_3u32(const u32 a, const u32 b, const u32 c,
+ const siphash_key_t *key);
+
+static inline u64 siphash_2u32(const u32 a, const u32 b,
+ const siphash_key_t *key)
+{
+ return siphash_1u64((u64)b << 32 | a, key);
+}
+static inline u64 siphash_4u32(const u32 a, const u32 b, const u32 c,
+ const u32 d, const siphash_key_t *key)
+{
+ return siphash_2u64((u64)b << 32 | a, (u64)d << 32 | c, key);
+}
+
+
+static inline u64 ___siphash_aligned(const __le64 *data, size_t len,
+ const siphash_key_t *key)
+{
+ if (__builtin_constant_p(len) && len == 4)
+ return siphash_1u32(le32_to_cpup((const __le32 *)data), key);
+ if (__builtin_constant_p(len) && len == 8)
+ return siphash_1u64(le64_to_cpu(data[0]), key);
+ if (__builtin_constant_p(len) && len == 16)
+ return siphash_2u64(le64_to_cpu(data[0]), le64_to_cpu(data[1]),
+ key);
+ if (__builtin_constant_p(len) && len == 24)
+ return siphash_3u64(le64_to_cpu(data[0]), le64_to_cpu(data[1]),
+ le64_to_cpu(data[2]), key);
+ if (__builtin_constant_p(len) && len == 32)
+ return siphash_4u64(le64_to_cpu(data[0]), le64_to_cpu(data[1]),
+ le64_to_cpu(data[2]), le64_to_cpu(data[3]),
+ key);
+ return __siphash_aligned(data, len, key);
+}
+
+/**
+ * siphash - compute 64-bit siphash PRF value
+ * @data: buffer to hash
+ * @size: size of @data
+ * @key: the siphash key
+ */
+static inline u64 siphash(const void *data, size_t len,
+ const siphash_key_t *key)
+{
+ if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ||
+ !IS_ALIGNED((unsigned long)data, SIPHASH_ALIGNMENT))
+ return __siphash_unaligned(data, len, key);
+ return ___siphash_aligned(data, len, key);
+}
+
+#define HSIPHASH_ALIGNMENT __alignof__(unsigned long)
+typedef struct {
+ unsigned long key[2];
+} hsiphash_key_t;
+
+u32 __hsiphash_aligned(const void *data, size_t len,
+ const hsiphash_key_t *key);
+u32 __hsiphash_unaligned(const void *data, size_t len,
+ const hsiphash_key_t *key);
+
+u32 hsiphash_1u32(const u32 a, const hsiphash_key_t *key);
+u32 hsiphash_2u32(const u32 a, const u32 b, const hsiphash_key_t *key);
+u32 hsiphash_3u32(const u32 a, const u32 b, const u32 c,
+ const hsiphash_key_t *key);
+u32 hsiphash_4u32(const u32 a, const u32 b, const u32 c, const u32 d,
+ const hsiphash_key_t *key);
+
+static inline u32 ___hsiphash_aligned(const __le32 *data, size_t len,
+ const hsiphash_key_t *key)
+{
+ if (__builtin_constant_p(len) && len == 4)
+ return hsiphash_1u32(le32_to_cpu(data[0]), key);
+ if (__builtin_constant_p(len) && len == 8)
+ return hsiphash_2u32(le32_to_cpu(data[0]), le32_to_cpu(data[1]),
+ key);
+ if (__builtin_constant_p(len) && len == 12)
+ return hsiphash_3u32(le32_to_cpu(data[0]), le32_to_cpu(data[1]),
+ le32_to_cpu(data[2]), key);
+ if (__builtin_constant_p(len) && len == 16)
+ return hsiphash_4u32(le32_to_cpu(data[0]), le32_to_cpu(data[1]),
+ le32_to_cpu(data[2]), le32_to_cpu(data[3]),
+ key);
+ return __hsiphash_aligned(data, len, key);
+}
+
+/**
+ * hsiphash - compute 32-bit hsiphash PRF value
+ * @data: buffer to hash
+ * @size: size of @data
+ * @key: the hsiphash key
+ */
+static inline u32 hsiphash(const void *data, size_t len,
+ const hsiphash_key_t *key)
+{
+ if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ||
+ !IS_ALIGNED((unsigned long)data, HSIPHASH_ALIGNMENT))
+ return __hsiphash_unaligned(data, len, key);
+ return ___hsiphash_aligned(data, len, key);
+}
+
+/*
+ * These macros expose the raw SipHash and HalfSipHash permutations.
+ * Do not use them directly! If you think you have a use for them,
+ * be sure to CC the maintainer of this file explaining why.
+ */
+
+#define SIPHASH_PERMUTATION(a, b, c, d) ( \
+ (a) += (b), (b) = rol64((b), 13), (b) ^= (a), (a) = rol64((a), 32), \
+ (c) += (d), (d) = rol64((d), 16), (d) ^= (c), \
+ (a) += (d), (d) = rol64((d), 21), (d) ^= (a), \
+ (c) += (b), (b) = rol64((b), 17), (b) ^= (c), (c) = rol64((c), 32))
+
+#define SIPHASH_CONST_0 0x736f6d6570736575ULL
+#define SIPHASH_CONST_1 0x646f72616e646f6dULL
+#define SIPHASH_CONST_2 0x6c7967656e657261ULL
+#define SIPHASH_CONST_3 0x7465646279746573ULL
+
+#define HSIPHASH_PERMUTATION(a, b, c, d) ( \
+ (a) += (b), (b) = rol32((b), 5), (b) ^= (a), (a) = rol32((a), 16), \
+ (c) += (d), (d) = rol32((d), 8), (d) ^= (c), \
+ (a) += (d), (d) = rol32((d), 7), (d) ^= (a), \
+ (c) += (b), (b) = rol32((b), 13), (b) ^= (c), (c) = rol32((c), 16))
+
+#define HSIPHASH_CONST_0 0U
+#define HSIPHASH_CONST_1 0U
+#define HSIPHASH_CONST_2 0x6c796765U
+#define HSIPHASH_CONST_3 0x74656462U
+
+#endif /* _LINUX_SIPHASH_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/sizes.h b/sys/compat/linuxkpi/common/include/linux/sizes.h
index d8a6e75192f6..430ad3ec427d 100644
--- a/sys/compat/linuxkpi/common/include/linux/sizes.h
+++ b/sys/compat/linuxkpi/common/include/linux/sizes.h
@@ -29,6 +29,17 @@
#ifndef _LINUXKPI_LINUX_SIZES_H_
#define _LINUXKPI_LINUX_SIZES_H_
+#define SZ_1 1
+#define SZ_2 2
+#define SZ_4 4
+#define SZ_8 8
+#define SZ_16 16
+#define SZ_32 32
+#define SZ_64 64
+#define SZ_128 128
+#define SZ_256 256
+#define SZ_512 512
+
#define SZ_1K (1024 * 1)
#define SZ_2K (1024 * 2)
#define SZ_4K (1024 * 4)
diff --git a/sys/compat/linuxkpi/common/include/linux/skbuff.h b/sys/compat/linuxkpi/common/include/linux/skbuff.h
index 2e560a120e41..c43d6daff5ee 100644
--- a/sys/compat/linuxkpi/common/include/linux/skbuff.h
+++ b/sys/compat/linuxkpi/common/include/linux/skbuff.h
@@ -770,7 +770,7 @@ ___skb_queue_splice(const struct sk_buff_head *from,
}
static inline void
-skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to)
+skb_queue_splice(const struct sk_buff_head *from, struct sk_buff_head *to)
{
SKB_TRACE2(from, to);
@@ -780,6 +780,13 @@ skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to)
___skb_queue_splice(from, (struct sk_buff *)to, to->next);
to->qlen += from->qlen;
+}
+
+static inline void
+skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to)
+{
+
+ skb_queue_splice(from, to);
__skb_queue_head_init(from);
}
diff --git a/sys/compat/linuxkpi/common/include/linux/slab.h b/sys/compat/linuxkpi/common/include/linux/slab.h
index 0e649e1e3c4a..8d023eaddadd 100644
--- a/sys/compat/linuxkpi/common/include/linux/slab.h
+++ b/sys/compat/linuxkpi/common/include/linux/slab.h
@@ -4,7 +4,7 @@
* Copyright (c) 2010 Panasas, Inc.
* Copyright (c) 2013-2021 Mellanox Technologies, Ltd.
* All rights reserved.
- * Copyright (c) 2024-2025 The FreeBSD Foundation
+ * Copyright (c) 2024-2026 The FreeBSD Foundation
*
* Portions of this software were developed by Björn Zeeb
* under sponsorship from the FreeBSD Foundation.
@@ -51,6 +51,22 @@ MALLOC_DECLARE(M_KMALLOC);
#define kvcalloc(n, size, flags) kvmalloc_array(n, size, (flags) | __GFP_ZERO)
#define kzalloc(size, flags) kmalloc(size, (flags) | __GFP_ZERO)
#define kzalloc_node(size, flags, node) kmalloc_node(size, (flags) | __GFP_ZERO, node)
+#define kzalloc_obj(_p, ...) \
+ kzalloc(sizeof(typeof(_p)), default_gfp(__VA_ARGS__))
+#define kzalloc_objs(_p, _n, ...) \
+ kzalloc(size_mul((_n), sizeof(typeof(_p))), default_gfp(__VA_ARGS__))
+#define kzalloc_flex(_p, _field, _n, ...) \
+({ \
+ const size_t __n = (_n); \
+ const size_t __psize = struct_size_t(typeof(_p), _field, __n); \
+ typeof(_p) *__p_obj; \
+ \
+ __p_obj = kzalloc(__psize, default_gfp(__VA_ARGS__)); \
+ if (__p_obj != NULL) \
+ __set_flex_counter(__p_obj->_field, __n); \
+ \
+ __p_obj; \
+})
#define kfree_const(ptr) kfree(ptr)
#define kfree_async(ptr) kfree(ptr) /* drm-kmod 5.4 compat */
#define vzalloc(size) __vmalloc(size, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO, 0)
@@ -104,7 +120,7 @@ void *lkpi_kmalloc(size_t, gfp_t);
void *lkpi_kvmalloc(size_t, gfp_t);
void *lkpi___kmalloc(size_t, gfp_t);
void *lkpi___kmalloc_node(size_t, gfp_t, int);
-void *lkpi_krealloc(void *, size_t, gfp_t);
+void *lkpi_krealloc(const void *, size_t, gfp_t);
void lkpi_kfree(const void *);
static inline gfp_t
@@ -143,8 +159,14 @@ kmalloc_node(size_t size, gfp_t flags, int node)
return (lkpi___kmalloc_node(size, flags, node));
}
+#define kmalloc_obj(_p, ...) \
+ kmalloc(sizeof(typeof(_p)), default_gfp(__VA_ARGS__))
+
+#define kmalloc_objs(_p, _n, ...) \
+ kmalloc(size_mul((_n) * sizeof(typeof(_p))), default_gfp(__VA_ARGS__))
+
static inline void *
-krealloc(void *ptr, size_t size, gfp_t flags)
+krealloc(const void *ptr, size_t size, gfp_t flags)
{
return (lkpi_krealloc(ptr, size, flags));
}
diff --git a/sys/compat/linuxkpi/common/include/linux/soc/airoha/airoha_offload.h b/sys/compat/linuxkpi/common/include/linux/soc/airoha/airoha_offload.h
new file mode 100644
index 000000000000..ade0b06d839f
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/soc/airoha/airoha_offload.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2026 Bjoern A. Zeeb
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_LINUX_SOC_AIROHA_AIROHA_OFFLOAD_H
+#define _LINUXKPI_LINUX_SOC_AIROHA_AIROHA_OFFLOAD_H
+
+#include <linux/kernel.h> /* pr_debug */
+
+enum airoha_npu_wlan_get_cmd {
+ __dummy_airoha_npu_wlan_get_cmd,
+};
+enum airoha_npu_wlan_set_cmd {
+ __dummy_airoha_npu_wlan_set_cmd,
+};
+
+struct airoha_npu {
+};
+struct airoha_npu_rx_dma_desc {
+};
+struct airoha_npu_tx_dma_desc {
+};
+
+static __inline int
+airoha_npu_wlan_send_msg(void *npu, int ifindex,
+ enum airoha_npu_wlan_set_cmd cmd, void *val, size_t len, gfp_t gfp)
+{
+ pr_debug("%s: TODO\n", __func__);
+ return (-EOPNOTSUPP);
+}
+
+static __inline int
+airoha_npu_wlan_get_msg(void *npu, int ifindex,
+ enum airoha_npu_wlan_get_cmd cmd, void *val, size_t len, gfp_t gfp)
+{
+ pr_debug("%s: TODO\n", __func__);
+ return (-EOPNOTSUPP);
+}
+
+static __inline void
+airoha_npu_wlan_enable_irq(struct airoha_npu *npu, int q)
+{
+ pr_debug("%s: TODO\n", __func__);
+}
+
+#endif /* _LINUXKPI_LINUX_SOC_AIROHA_AIROHA_OFFLOAD_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h b/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h
index 2b9c6ae4911e..64daa8c78c9d 100644
--- a/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h
+++ b/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2022-2025 Bjoern A. Zeeb
+ * Copyright (c) 2022-2026 Bjoern A. Zeeb
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -37,7 +37,13 @@ mtk_wed_device_active(struct mtk_wed_device *dev __unused)
static inline bool
mtk_wed_get_rx_capa(struct mtk_wed_device *dev __unused)
{
+ pr_debug("%s: TODO\n", __func__);
+ return (false);
+}
+static inline bool
+mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev __unused)
+{
pr_debug("%s: TODO\n", __func__);
return (false);
}
@@ -66,6 +72,12 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev __unused)
{
return (false);
}
+
+static inline bool
+mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev __unused)
+{
+ return (false);
+}
#endif /* CONFIG_NET_MEDIATEK_SOC_WED */
#endif /* _LINUXKPI_LINUX_SOC_MEDIATEK_MTK_WED_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/sort.h b/sys/compat/linuxkpi/common/include/linux/sort.h
index e6196d1f41c7..972c8514e6fb 100644
--- a/sys/compat/linuxkpi/common/include/linux/sort.h
+++ b/sys/compat/linuxkpi/common/include/linux/sort.h
@@ -34,8 +34,13 @@
#include <sys/libkern.h>
#define sort(base, num, size, cmp, swap) do { \
- BUILD_BUG_ON_ZERO(swap); \
+ BUILD_BUG_ON(swap); \
qsort(base, num, size, cmp); \
} while (0)
+#define sort_r(base, num, size, cmp, swap, priv) do { \
+ BUILD_BUG_ON(swap); \
+ qsort_r(base, num, size, cmp, priv); \
+} while (0)
+
#endif /* _LINUXKPI_LINUX_SORT_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/spinlock.h b/sys/compat/linuxkpi/common/include/linux/spinlock.h
index dc10b0457153..a786cbab5e13 100644
--- a/sys/compat/linuxkpi/common/include/linux/spinlock.h
+++ b/sys/compat/linuxkpi/common/include/linux/spinlock.h
@@ -36,10 +36,12 @@
#include <sys/mutex.h>
#include <sys/kdb.h>
+#include <linux/cleanup.h>
#include <linux/compiler.h>
#include <linux/rwlock.h>
#include <linux/bottom_half.h>
#include <linux/lockdep.h>
+#include <linux/preempt.h>
typedef struct mtx spinlock_t;
@@ -178,4 +180,33 @@ _atomic_dec_and_lock_irqsave(atomic_t *cnt, spinlock_t *lock,
return (0);
}
+/*
+ * struct raw_spinlock
+ */
+
+typedef struct raw_spinlock {
+ struct mtx lock;
+} raw_spinlock_t;
+
+#define raw_spin_lock_init(rlock) \
+ mtx_init(&(rlock)->lock, spin_lock_name("lnxspin_raw"), \
+ NULL, MTX_DEF | MTX_NOWITNESS | MTX_NEW)
+
+#define raw_spin_lock(rl) spin_lock(&(rl)->lock)
+#define raw_spin_trylock(rl) spin_trylock(&(rl)->lock)
+#define raw_spin_unlock(rl) spin_unlock(&(rl)->lock)
+
+#define raw_spin_lock_irqsave(rl, f) spin_lock_irqsave(&(rl)->lock, (f))
+#define raw_spin_trylock_irqsave(rl, f) spin_trylock_irqsave(&(rl)->lock, (f))
+#define raw_spin_unlock_irqrestore(rl, f) spin_unlock_irqrestore(&(rl)->lock, (f))
+
+/*
+ * cleanup.h related pre-defined cases.
+ */
+DEFINE_LOCK_GUARD_1(spinlock_irqsave,
+ spinlock_t,
+ spin_lock_irqsave(_T->lock, _T->flags),
+ spin_unlock_irqrestore(_T->lock, _T->flags),
+ unsigned long flags)
+
#endif /* _LINUXKPI_LINUX_SPINLOCK_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/ssb/ssb_regs.h b/sys/compat/linuxkpi/common/include/linux/ssb/ssb_regs.h
new file mode 100644
index 000000000000..e1c18b6b632a
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/ssb/ssb_regs.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2025 Bjoern A. Zeeb
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_LINUX_SSB_SSB_REGS_H
+#define _LINUXKPI_LINUX_SSB_SSB_REGS_H
+
+#define SSB_IDHIGH_RCHI 0x00007000
+#define SSB_IDHIGH_RCHI_SHIFT 8
+#define SSB_IDHIGH_RCLO 0x0000000F
+#define SSB_IDLOW_INITIATOR 0x00000080
+#define SSB_IMSTATE_BUSY 0x01800000
+#define SSB_IMSTATE_IBE 0x00020000
+#define SSB_IMSTATE_REJECT 0x02000000
+#define SSB_IMSTATE_TO 0x00040000
+#define SSB_TMSHIGH_BUSY 0x00000004
+#define SSB_TMSHIGH_SERR 0x00000001
+#define SSB_TMSLOW_CLOCK 0x00010000
+#define SSB_TMSLOW_FGC 0x00020000
+#define SSB_TMSLOW_REJECT 0x00000002
+#define SSB_TMSLOW_RESET 0x00000001
+
+#endif /* _LINUXKPI_LINUX_SSB_SSB_REGS_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/string.h b/sys/compat/linuxkpi/common/include/linux/string.h
index f7b64560d254..0b858e7af623 100644
--- a/sys/compat/linuxkpi/common/include/linux/string.h
+++ b/sys/compat/linuxkpi/common/include/linux/string.h
@@ -303,6 +303,22 @@ memcpy_and_pad(void *dst, size_t dstlen, const void *src, size_t len, int ch)
}
}
+#define strtomem(dst, src) do { \
+ size_t dstlen = ARRAY_SIZE(dst); \
+ size_t srclen = __builtin_object_size(src, 1); \
+ srclen = MIN(srclen, dstlen); \
+ srclen = strnlen(src, srclen); \
+ memcpy(dst, src, srclen); \
+} while (0)
+
+#define strtomem_pad(dst, src, pad) do { \
+ size_t dstlen = ARRAY_SIZE(dst); \
+ size_t srclen = __builtin_object_size(src, 1); \
+ srclen = MIN(srclen, dstlen); \
+ srclen = strnlen(src, srclen); \
+ memcpy_and_pad(dst, dstlen, src, srclen, pad); \
+} while (0)
+
#define memset_startat(ptr, bytepat, smember) \
({ \
uint8_t *_ptr = (uint8_t *)(ptr); \
diff --git a/sys/compat/linuxkpi/common/include/linux/string_choices.h b/sys/compat/linuxkpi/common/include/linux/string_choices.h
index 74aa3fd019b2..db540d3e7d40 100644
--- a/sys/compat/linuxkpi/common/include/linux/string_choices.h
+++ b/sys/compat/linuxkpi/common/include/linux/string_choices.h
@@ -33,39 +33,33 @@
static inline const char *
str_yes_no(bool value)
{
- if (value)
- return "yes";
- else
- return "no";
+ return (value ? "yes" : "no");
}
static inline const char *
str_on_off(bool value)
{
- if (value)
- return "on";
- else
- return "off";
+ return (value ? "on" : "off");
}
static inline const char *
str_enabled_disabled(bool value)
{
- if (value)
- return "enabled";
- else
- return "disabled";
+ return (value ? "enabled" : "disabled");
}
static inline const char *
str_enable_disable(bool value)
{
- if (value)
- return "enable";
- else
- return "disable";
+ return (value ? "enable" : "disable");
}
#define str_disable_enable(_v) str_enable_disable(!(_v))
+static inline const char *
+str_read_write(bool value)
+{
+ return (value ? "read" : "write");
+}
+
#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/suspend.h b/sys/compat/linuxkpi/common/include/linux/suspend.h
index dacecbebdc08..3d5d5d594127 100644
--- a/sys/compat/linuxkpi/common/include/linux/suspend.h
+++ b/sys/compat/linuxkpi/common/include/linux/suspend.h
@@ -3,6 +3,12 @@
#ifndef _LINUXKPI_LINUX_SUSPEND_H_
#define _LINUXKPI_LINUX_SUSPEND_H_
+#include <linux/swap.h>
+#include <linux/notifier.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/mm.h>
+
typedef int suspend_state_t;
extern suspend_state_t pm_suspend_target_state;
diff --git a/sys/compat/linuxkpi/common/include/linux/swap.h b/sys/compat/linuxkpi/common/include/linux/swap.h
index 5828db7ae392..9c1db9677f9e 100644
--- a/sys/compat/linuxkpi/common/include/linux/swap.h
+++ b/sys/compat/linuxkpi/common/include/linux/swap.h
@@ -37,7 +37,14 @@
#include <vm/swap_pager.h>
#include <vm/vm_pageout.h>
+#include <linux/spinlock.h>
+#include <linux/mmzone.h>
+#include <linux/list.h>
+#include <linux/memcontrol.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
#include <linux/pagemap.h>
+#include <linux/atomic.h>
#include <linux/page-flags.h>
static inline long
diff --git a/sys/compat/linuxkpi/common/include/linux/sysfs.h b/sys/compat/linuxkpi/common/include/linux/sysfs.h
index 470c224a9778..7c8c4e2e32b9 100644
--- a/sys/compat/linuxkpi/common/include/linux/sysfs.h
+++ b/sys/compat/linuxkpi/common/include/linux/sysfs.h
@@ -43,13 +43,6 @@ struct sysfs_ops {
size_t);
};
-struct attribute_group {
- const char *name;
- mode_t (*is_visible)(struct kobject *,
- struct attribute *, int);
- struct attribute **attrs;
-};
-
struct bin_attribute {
struct attribute attr;
size_t size;
@@ -59,6 +52,14 @@ struct bin_attribute {
struct bin_attribute *, char *, loff_t, size_t);
};
+struct attribute_group {
+ const char *name;
+ mode_t (*is_visible)(struct kobject *,
+ struct attribute *, int);
+ struct attribute **attrs;
+ struct bin_attribute **bin_attrs;
+};
+
#define __ATTR(_name, _mode, _show, _store) { \
.attr = { .name = __stringify(_name), .mode = _mode }, \
.show = _show, .store = _store, \
@@ -370,6 +371,7 @@ static inline int
sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp)
{
struct attribute **attr;
+ struct bin_attribute **bin_attr;
struct sysctl_oid *oidp;
/* Don't create the group node if grp->name is undefined. */
@@ -378,11 +380,19 @@ sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp)
OID_AUTO, grp->name, CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, grp->name);
else
oidp = kobj->oidp;
- for (attr = grp->attrs; *attr != NULL; attr++) {
+ for (attr = grp->attrs; attr != NULL && *attr != NULL; attr++) {
SYSCTL_ADD_OID(NULL, SYSCTL_CHILDREN(oidp), OID_AUTO,
(*attr)->name, CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_MPSAFE,
kobj, (uintptr_t)*attr, sysctl_handle_attr, "A", "");
}
+ for (bin_attr = grp->bin_attrs;
+ bin_attr != NULL && *bin_attr != NULL;
+ bin_attr++) {
+ SYSCTL_ADD_OID(NULL, SYSCTL_CHILDREN(oidp), OID_AUTO,
+ (*bin_attr)->attr.name,
+ CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_MPSAFE,
+ kobj, (uintptr_t)*bin_attr, sysctl_handle_bin_attr, "", "");
+ }
return (0);
}
@@ -434,14 +444,20 @@ static inline void
sysfs_unmerge_group(struct kobject *kobj, const struct attribute_group *grp)
{
struct attribute **attr;
+ struct bin_attribute **bin_attr;
struct sysctl_oid *oidp;
SYSCTL_FOREACH(oidp, SYSCTL_CHILDREN(kobj->oidp)) {
if (strcmp(oidp->oid_name, grp->name) != 0)
continue;
- for (attr = grp->attrs; *attr != NULL; attr++) {
+ for (attr = grp->attrs; attr != NULL && *attr != NULL; attr++) {
sysctl_remove_name(oidp, (*attr)->name, 1, 1);
}
+ for (bin_attr = grp->bin_attrs;
+ bin_attr != NULL && *bin_attr != NULL;
+ bin_attr++) {
+ sysctl_remove_name(oidp, (*bin_attr)->attr.name, 1, 1);
+ }
}
}
diff --git a/sys/compat/linuxkpi/common/include/linux/uuid.h b/sys/compat/linuxkpi/common/include/linux/uuid.h
index 4f6f4a8b34f0..0765ef4dcc1e 100644
--- a/sys/compat/linuxkpi/common/include/linux/uuid.h
+++ b/sys/compat/linuxkpi/common/include/linux/uuid.h
@@ -33,6 +33,7 @@
#include <linux/random.h>
+#define UUID_SIZE 16
#define UUID_STRING_LEN 36
#define GUID_INIT(x0_3, x4_5, x6_7, x8, x9, x10, x11, x12, x13, x14, x15) \
@@ -59,6 +60,8 @@ typedef struct {
char x[16];
} guid_t;
+extern const guid_t guid_null;
+
static inline void
guid_gen(guid_t *g)
{
@@ -68,10 +71,34 @@ guid_gen(guid_t *g)
g->x[8] = (g->x[8] & 0x3f) | 0x80;
}
+static inline bool
+guid_equal(const guid_t *u1, const guid_t *u2)
+{
+ return (memcmp(u1, u2, sizeof(guid_t)) == 0);
+}
+
static inline void
guid_copy(guid_t *dst, const guid_t *src)
{
memcpy(dst, src, sizeof(*dst));
}
+static inline void
+import_guid(guid_t *dst, const uint8_t *src)
+{
+ memcpy(dst, src, sizeof(guid_t));
+}
+
+static inline void
+export_guid(uint8_t *dst, const guid_t *src)
+{
+ memcpy(dst, src, sizeof(guid_t));
+}
+
+static inline bool
+guid_is_null(const guid_t *guid)
+{
+ return (guid_equal(guid, &guid_null));
+}
+
#endif /* _LINUXKPI_LINUX_UUID_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/wait.h b/sys/compat/linuxkpi/common/include/linux/wait.h
index 03ddce2c06f5..698a1056b713 100644
--- a/sys/compat/linuxkpi/common/include/linux/wait.h
+++ b/sys/compat/linuxkpi/common/include/linux/wait.h
@@ -43,13 +43,6 @@
#define SKIP_SLEEP() (SCHEDULER_STOPPED() || kdb_active)
-#define might_sleep() \
- WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "might_sleep()")
-
-#define might_sleep_if(cond) do { \
- if (cond) { might_sleep(); } \
-} while (0)
-
struct wait_queue;
struct wait_queue_head;