diff options
Diffstat (limited to 'sys/compat/linuxkpi/common/include/linux')
188 files changed, 5526 insertions, 1050 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/acpi.h b/sys/compat/linuxkpi/common/include/linux/acpi.h index 1a9d25e7a7ff..610aa0784cb9 100644 --- a/sys/compat/linuxkpi/common/include/linux/acpi.h +++ b/sys/compat/linuxkpi/common/include/linux/acpi.h @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org> * @@ -24,8 +24,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_ACPI_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/agp_backend.h b/sys/compat/linuxkpi/common/include/linux/agp_backend.h new file mode 100644 index 000000000000..c855fd842970 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/agp_backend.h @@ -0,0 +1,28 @@ +/* Public domain */ + +#ifndef _LINUXKPI_LINUX_AGP_BACKEND_H_ +#define _LINUXKPI_LINUX_AGP_BACKEND_H_ + +#include <sys/types.h> + +struct agp_version { + uint16_t major; + uint16_t minor; +}; + +struct agp_kern_info { + struct agp_version version; + uint16_t vendor; + uint16_t device; + unsigned long mode; + unsigned long aper_base; + size_t aper_size; + int max_memory; + int current_memory; + bool cant_use_aperture; + unsigned long page_mask; +}; + +struct agp_memory; + +#endif /* _LINUXKPI_LINUX_AGP_BACKEND_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/anon_inodes.h b/sys/compat/linuxkpi/common/include/linux/anon_inodes.h index cab5cbd4d67e..c69f6e152b17 100644 --- a/sys/compat/linuxkpi/common/include/linux/anon_inodes.h +++ b/sys/compat/linuxkpi/common/include/linux/anon_inodes.h @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org> * diff --git a/sys/compat/linuxkpi/common/include/linux/apple-gmux.h b/sys/compat/linuxkpi/common/include/linux/apple-gmux.h new file mode 100644 index 000000000000..812a782c57d4 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/apple-gmux.h @@ -0,0 +1,12 @@ +/* Public domain. */ + +#ifndef _LINUXKPI_LINUX_APPLE_GMUX_H +#define _LINUXKPI_LINUX_APPLE_GMUX_H + +static inline bool +apple_gmux_detect(void *a, void *b) +{ + return false; +} + +#endif diff --git a/sys/compat/linuxkpi/common/include/linux/atomic.h b/sys/compat/linuxkpi/common/include/linux/atomic.h index e491283ae6e5..bc76928a7d67 100644 --- a/sys/compat/linuxkpi/common/include/linux/atomic.h +++ b/sys/compat/linuxkpi/common/include/linux/atomic.h @@ -22,8 +22,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_ATOMIC_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/average.h b/sys/compat/linuxkpi/common/include/linux/average.h index 61b2010d6509..4191a351c5c6 100644 --- a/sys/compat/linuxkpi/common/include/linux/average.h +++ b/sys/compat/linuxkpi/common/include/linux/average.h @@ -26,8 +26,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_AVERAGE_H diff --git a/sys/compat/linuxkpi/common/include/linux/backlight.h b/sys/compat/linuxkpi/common/include/linux/backlight.h index 9591a4b671ab..4f8f7440925a 100644 --- a/sys/compat/linuxkpi/common/include/linux/backlight.h +++ b/sys/compat/linuxkpi/common/include/linux/backlight.h @@ -24,8 +24,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_BACKLIGHT_H_ @@ -92,6 +90,13 @@ backlight_force_update(struct backlight_device *bd, int reason) } static inline int +backlight_get_brightness(struct backlight_device *bd) +{ + + return (bd->props.brightness); +} + +static inline int backlight_device_set_brightness(struct backlight_device *bd, int brightness) { @@ -119,4 +124,11 @@ backlight_disable(struct backlight_device *bd) return (backlight_update_status(bd)); } +static inline bool +backlight_is_blank(struct backlight_device *bd) +{ + + return (bd->props.power != 0/* FB_BLANK_UNBLANK */); +} + #endif /* _LINUXKPI_LINUX_BACKLIGHT_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/bcd.h b/sys/compat/linuxkpi/common/include/linux/bcd.h index 8a40da1a330b..385819910454 100644 --- a/sys/compat/linuxkpi/common/include/linux/bcd.h +++ b/sys/compat/linuxkpi/common/include/linux/bcd.h @@ -23,8 +23,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_BCD_H diff --git a/sys/compat/linuxkpi/common/include/linux/bitfield.h b/sys/compat/linuxkpi/common/include/linux/bitfield.h index c22757d54290..a2020d247489 100644 --- a/sys/compat/linuxkpi/common/include/linux/bitfield.h +++ b/sys/compat/linuxkpi/common/include/linux/bitfield.h @@ -26,8 +26,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_BITFIELD_H @@ -127,6 +125,9 @@ _uX_replace_bits(8) #define __bf_shf(x) (__builtin_ffsll(x) - 1) +#define FIELD_FIT(_mask, _value) \ + (!(((typeof(_mask))(_value) << __bf_shf(_mask)) & ~(_mask))) + #define FIELD_PREP(_mask, _value) \ (((typeof(_mask))(_value) << __bf_shf(_mask)) & (_mask)) diff --git a/sys/compat/linuxkpi/common/include/linux/bitmap.h b/sys/compat/linuxkpi/common/include/linux/bitmap.h index 1ae6078966a4..f26a0f99dc03 100644 --- a/sys/compat/linuxkpi/common/include/linux/bitmap.h +++ b/sys/compat/linuxkpi/common/include/linux/bitmap.h @@ -22,8 +22,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_BITMAP_H_ @@ -266,6 +264,27 @@ bitmap_subset(const unsigned long *pa, return (1); } +static inline bool +bitmap_intersects(const unsigned long *pa, const unsigned long *pb, + unsigned size) +{ + const unsigned end = BIT_WORD(size); + const unsigned tail = size & (BITS_PER_LONG - 1); + unsigned i; + + for (i = 0; i != end; i++) + if (pa[i] & pb[i]) + return (true); + + if (tail) { + const unsigned long mask = BITMAP_LAST_WORD_MASK(tail); + + if (pa[end] & pb[end] & mask) + return (true); + } + return (false); +} + static inline void bitmap_complement(unsigned long *dst, const unsigned long *src, const unsigned int size) @@ -289,6 +308,49 @@ bitmap_copy(unsigned long *dst, const unsigned long *src, } static inline void +bitmap_to_arr32(uint32_t *dst, const unsigned long *src, unsigned int size) +{ + const unsigned int end = howmany(size, 32); + +#ifdef __LP64__ + unsigned int i = 0; + while (i < end) { + dst[i++] = (uint32_t)(*src & UINT_MAX); + if (i < end) + dst[i++] = (uint32_t)(*src >> 32); + src++; + } +#else + bitmap_copy((unsigned long *)dst, src, size); +#endif + if ((size % 32) != 0) /* Linux uses BITS_PER_LONG. Seems to be a bug */ + dst[end - 1] &= (uint32_t)(UINT_MAX >> (32 - (size % 32))); +} + +static inline void +bitmap_from_arr32(unsigned long *dst, const uint32_t *src, + unsigned int size) +{ + const unsigned int end = BIT_WORD(size); + const unsigned int tail = size & (BITS_PER_LONG - 1); + +#ifdef __LP64__ + const unsigned int end32 = howmany(size, 32); + unsigned int i = 0; + + while (i < end32) { + dst[i++/2] = (unsigned long) *(src++); + if (i < end32) + dst[i++/2] |= ((unsigned long) *(src++)) << 32; + } +#else + bitmap_copy(dst, (const unsigned long *)src, size); +#endif + if ((size % BITS_PER_LONG) != 0) + dst[end] &= BITMAP_LAST_WORD_MASK(tail); +} + +static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, const unsigned long *src2, const unsigned int size) { @@ -332,6 +394,40 @@ bitmap_xor(unsigned long *dst, const unsigned long *src1, dst[i] = src1[i] ^ src2[i]; } +static inline void +bitmap_shift_right(unsigned long *dst, const unsigned long *src, + unsigned int shift, unsigned int size) +{ + const unsigned int end = BITS_TO_LONGS(size); + const unsigned int tail = size & (BITS_PER_LONG - 1); + const unsigned long mask = BITMAP_LAST_WORD_MASK(tail); + const unsigned int off = BIT_WORD(shift); + const unsigned int rem = shift & (BITS_PER_LONG - 1); + unsigned long left, right; + unsigned int i, srcpos; + + for (i = 0, srcpos = off; srcpos < end; i++, srcpos++) { + right = src[srcpos]; + left = 0; + + if (srcpos == end - 1) + right &= mask; + + if (rem != 0) { + right >>= rem; + if (srcpos + 1 < end) { + left = src[srcpos + 1]; + if (srcpos + 1 == end - 1) + left &= mask; + left <<= (BITS_PER_LONG - rem); + } + } + dst[i] = left | right; + } + if (off != 0) + memset(dst + end - off, 0, off * sizeof(unsigned long)); +} + static inline unsigned long * bitmap_alloc(unsigned int size, gfp_t flags) { diff --git a/sys/compat/linuxkpi/common/include/linux/bitops.h b/sys/compat/linuxkpi/common/include/linux/bitops.h index b6c54b2e6858..1415d5224084 100644 --- a/sys/compat/linuxkpi/common/include/linux/bitops.h +++ b/sys/compat/linuxkpi/common/include/linux/bitops.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_BITOPS_H_ #define _LINUXKPI_LINUX_BITOPS_H_ @@ -56,6 +54,7 @@ #define GENMASK_ULL(h, l) (((~0ULL) >> (BITS_PER_LONG_LONG - (h) - 1)) & ((~0ULL) << (l))) #define BITS_PER_BYTE 8 #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) diff --git a/sys/compat/linuxkpi/common/include/linux/bottom_half.h b/sys/compat/linuxkpi/common/include/linux/bottom_half.h index 1b139c481283..12b170845cbc 100644 --- a/sys/compat/linuxkpi/common/include/linux/bottom_half.h +++ b/sys/compat/linuxkpi/common/include/linux/bottom_half.h @@ -22,8 +22,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_BOTTOM_HALF_H_ #define _LINUXKPI_LINUX_BOTTOM_HALF_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/bsearch.h b/sys/compat/linuxkpi/common/include/linux/bsearch.h index 8cc329aa855c..fb67109e4bba 100644 --- a/sys/compat/linuxkpi/common/include/linux/bsearch.h +++ b/sys/compat/linuxkpi/common/include/linux/bsearch.h @@ -26,8 +26,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_BSEARCH_H diff --git a/sys/compat/linuxkpi/common/include/linux/build_bug.h b/sys/compat/linuxkpi/common/include/linux/build_bug.h new file mode 100644 index 000000000000..6a026376cfc8 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/build_bug.h @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 2017 Mark Johnston <markj@FreeBSD.org> + * Copyright (c) 2018 Johannes Lundberg <johalun0@gmail.com> + * Copyright (c) 2021 The FreeBSD Foundation + * Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org> + * Copyright (c) 2023 Serenity Cyber Security, LLC + * + * Portions of this software were developed by Bjoern A. Zeeb + * 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 unmodified, 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 ``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 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_BUILD_BUG_H_ +#define _LINUXKPI_LINUX_BUILD_BUG_H_ + +#include <sys/param.h> + +#include <linux/compiler.h> + +/* + * BUILD_BUG_ON() can happen inside functions where _Static_assert() does not + * seem to work. Use old-schoold-ish CTASSERT from before commit + * a3085588a88fa58eb5b1eaae471999e1995a29cf but also make sure we do not + * end up with an unused typedef or variable. The compiler should optimise + * it away entirely. + */ +#define _O_CTASSERT(x) _O__CTASSERT(x, __LINE__) +#define _O__CTASSERT(x, y) _O___CTASSERT(x, y) +#define _O___CTASSERT(x, y) while (0) { \ + typedef char __assert_line_ ## y[(x) ? 1 : -1]; \ + __assert_line_ ## y _x __unused; \ + _x[0] = '\0'; \ +} + +#define BUILD_BUG() do { CTASSERT(0); } while (0) +#define BUILD_BUG_ON(x) do { _O_CTASSERT(!(x)) } while (0) +#define BUILD_BUG_ON_MSG(x, msg) BUILD_BUG_ON(x) +#define BUILD_BUG_ON_NOT_POWER_OF_2(x) BUILD_BUG_ON(!powerof2(x)) +#define BUILD_BUG_ON_INVALID(expr) while (0) { (void)(expr); } +#define BUILD_BUG_ON_ZERO(x) ((int)sizeof(struct { int:-((x) != 0); })) + +#define static_assert(x, ...) __static_assert(x, ##__VA_ARGS__, #x) +#define __static_assert(x, msg, ...) _Static_assert(x, msg) + +#endif diff --git a/sys/compat/linuxkpi/common/include/linux/cache.h b/sys/compat/linuxkpi/common/include/linux/cache.h index 6479d5d04d3a..b02b28d08ea9 100644 --- a/sys/compat/linuxkpi/common/include/linux/cache.h +++ b/sys/compat/linuxkpi/common/include/linux/cache.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_CACHE_H_ #define _LINUXKPI_LINUX_CACHE_H_ @@ -35,6 +33,7 @@ #define cache_line_size() CACHE_LINE_SIZE #define L1_CACHE_BYTES CACHE_LINE_SIZE +#define L1_CACHE_ALIGN(x) ALIGN(x, CACHE_LINE_SIZE) #define SMP_CACHE_BYTES L1_CACHE_BYTES diff --git a/sys/compat/linuxkpi/common/include/linux/capability.h b/sys/compat/linuxkpi/common/include/linux/capability.h index 547ee586ad8e..e3dacd4e9f15 100644 --- a/sys/compat/linuxkpi/common/include/linux/capability.h +++ b/sys/compat/linuxkpi/common/include/linux/capability.h @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2015 Rimvydas Jasinskas * All rights reserved. diff --git a/sys/compat/linuxkpi/common/include/linux/cc_platform.h b/sys/compat/linuxkpi/common/include/linux/cc_platform.h new file mode 100644 index 000000000000..01c0de17f7d2 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/cc_platform.h @@ -0,0 +1,20 @@ +/* Public domain. */ + +#ifndef _LINUXKPI_LINUX_CC_PLATFORM_H_ +#define _LINUXKPI_LINUX_CC_PLATFORM_H_ + +#include <linux/types.h> +#include <linux/stddef.h> + +enum cc_attr { + CC_ATTR_MEM_ENCRYPT, +}; + +static inline bool +cc_platform_has(enum cc_attr attr __unused) +{ + + return (false); +} + +#endif /* _LINUXKPI_LINUX_CC_PLATFORM_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/cdev.h b/sys/compat/linuxkpi/common/include/linux/cdev.h index 2befe9b259cb..d989db14c2f8 100644 --- a/sys/compat/linuxkpi/common/include/linux/cdev.h +++ b/sys/compat/linuxkpi/common/include/linux/cdev.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_CDEV_H_ #define _LINUXKPI_LINUX_CDEV_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/clocksource.h b/sys/compat/linuxkpi/common/include/linux/clocksource.h index 8027ed76ec0f..3e7664c3e57e 100644 --- a/sys/compat/linuxkpi/common/include/linux/clocksource.h +++ b/sys/compat/linuxkpi/common/include/linux/clocksource.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_CLOCKSOURCE_H #define _LINUXKPI_LINUX_CLOCKSOURCE_H diff --git a/sys/compat/linuxkpi/common/include/linux/compat.h b/sys/compat/linuxkpi/common/include/linux/compat.h index b6bb5e8ed24b..8a5a6918bb7c 100644 --- a/sys/compat/linuxkpi/common/include/linux/compat.h +++ b/sys/compat/linuxkpi/common/include/linux/compat.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_COMPAT_H_ #define _LINUXKPI_LINUX_COMPAT_H_ @@ -43,17 +41,20 @@ extern int linux_alloc_current(struct thread *, int flags); extern void linux_free_current(struct task_struct *); extern struct domainset *linux_get_vm_domain_set(int node); +#define __current_unallocated(td) \ + __predict_false((td)->td_lkpi_task == NULL) + static inline void linux_set_current(struct thread *td) { - if (__predict_false(td->td_lkpi_task == NULL)) + if (__current_unallocated(td)) lkpi_alloc_current(td, M_WAITOK); } static inline int linux_set_current_flags(struct thread *td, int flags) { - if (__predict_false(td->td_lkpi_task == NULL)) + if (__current_unallocated(td)) return (lkpi_alloc_current(td, flags)); return (0); } @@ -61,4 +62,7 @@ linux_set_current_flags(struct thread *td, int flags) #define compat_ptr(x) ((void *)(uintptr_t)x) #define ptr_to_compat(x) ((uintptr_t)x) +typedef void fpu_safe_exec_cb_t(void *ctx); +void lkpi_fpu_safe_exec(fpu_safe_exec_cb_t func, void *ctx); + #endif /* _LINUXKPI_LINUX_COMPAT_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/compiler.h b/sys/compat/linuxkpi/common/include/linux/compiler.h index 87a37228736f..d59e6faed12d 100644 --- a/sys/compat/linuxkpi/common/include/linux/compiler.h +++ b/sys/compat/linuxkpi/common/include/linux/compiler.h @@ -26,8 +26,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_COMPILER_H_ #define _LINUXKPI_LINUX_COMPILER_H_ @@ -64,10 +62,22 @@ #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 +#define __counted_by(_x) +#endif + #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #define typeof(x) __typeof(x) @@ -87,18 +97,16 @@ #define ___PASTE(a,b) a##b #define __PASTE(a,b) ___PASTE(a,b) -#define ACCESS_ONCE(x) (*(volatile __typeof(x) *)&(x)) - #define WRITE_ONCE(x,v) do { \ barrier(); \ - ACCESS_ONCE(x) = (v); \ + (*(volatile __typeof(x) *)(uintptr_t)&(x)) = (v); \ barrier(); \ } while (0) #define READ_ONCE(x) ({ \ __typeof(x) __var = ({ \ barrier(); \ - ACCESS_ONCE(x); \ + (*(const volatile __typeof(x) *)&(x)); \ }); \ barrier(); \ __var; \ @@ -113,4 +121,7 @@ #define sizeof_field(_s, _m) sizeof(((_s *)0)->_m) +#define is_signed_type(t) ((t)-1 < (t)1) +#define is_unsigned_type(t) ((t)-1 > (t)1) + #endif /* _LINUXKPI_LINUX_COMPILER_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/completion.h b/sys/compat/linuxkpi/common/include/linux/completion.h index 2f58bd5c03e6..26e41a51c10b 100644 --- a/sys/compat/linuxkpi/common/include/linux/completion.h +++ b/sys/compat/linuxkpi/common/include/linux/completion.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_COMPLETION_H_ #define _LINUXKPI_LINUX_COMPLETION_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/container_of.h b/sys/compat/linuxkpi/common/include/linux/container_of.h new file mode 100644 index 000000000000..449507fcf9c1 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/container_of.h @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2010 Isilon Systems, Inc. + * Copyright (c) 2010 iX Systems, Inc. + * Copyright (c) 2010 Panasas, Inc. + * Copyright (c) 2017 Matt Macy <mmacy@FreeBSD.org> + * All rights reserved. + * + * 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 unmodified, 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 ``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 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_CONTAINER_OF_H +#define _LINUXKPI_LINUX_CONTAINER_OF_H + +#include <sys/stdint.h> + +#include <linux/build_bug.h> +#include <linux/stddef.h> + +#define container_of(ptr, type, member) \ +({ \ + const __typeof(((type *)0)->member) *__p = (ptr); \ + (type *)((uintptr_t)__p - offsetof(type, member)); \ +}) + +#define typeof_member(type, member) __typeof(((type *)0)->member) + +#endif diff --git a/sys/compat/linuxkpi/common/include/linux/cpu.h b/sys/compat/linuxkpi/common/include/linux/cpu.h index 53fa9db424c2..43ec3d66a2e3 100644 --- a/sys/compat/linuxkpi/common/include/linux/cpu.h +++ b/sys/compat/linuxkpi/common/include/linux/cpu.h @@ -26,8 +26,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_CPU_H @@ -44,6 +42,8 @@ typedef cpuset_t cpumask_t; extern cpumask_t cpu_online_mask; +cpumask_t *lkpi_get_static_single_cpu_mask(int); + static __inline int cpumask_next(int cpuid, cpumask_t mask) { @@ -73,4 +73,6 @@ cpumask_set_cpu(int cpu, cpumask_t *mask) CPU_SET(cpu, mask); } +#define cpumask_of(_cpu) (lkpi_get_static_single_cpu_mask(_cpu)) + #endif /* _LINUXKPI_LINUX_CPU_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/crc32.h b/sys/compat/linuxkpi/common/include/linux/crc32.h index a93be642fb1a..e6d39fa7c5ff 100644 --- a/sys/compat/linuxkpi/common/include/linux/crc32.h +++ b/sys/compat/linuxkpi/common/include/linux/crc32.h @@ -26,8 +26,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_CRC32_H diff --git a/sys/compat/linuxkpi/common/include/linux/dcache.h b/sys/compat/linuxkpi/common/include/linux/dcache.h index 9f9943a18dc6..992d6f7c2720 100644 --- a/sys/compat/linuxkpi/common/include/linux/dcache.h +++ b/sys/compat/linuxkpi/common/include/linux/dcache.h @@ -22,15 +22,14 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_DCACHE_H #define _LINUXKPI_LINUX_DCACHE_H -struct vnode; -struct pfs_node; +#include <sys/vnode.h> + +#include <fs/pseudofs/pseudofs.h> struct dentry { struct vnode *d_inode; diff --git a/sys/compat/linuxkpi/common/include/linux/debugfs.h b/sys/compat/linuxkpi/common/include/linux/debugfs.h index 6a3273cbbf3c..470b50cb730c 100644 --- a/sys/compat/linuxkpi/common/include/linux/debugfs.h +++ b/sys/compat/linuxkpi/common/include/linux/debugfs.h @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2016-2018, Matthew Macy <mmacy@freebsd.org> * @@ -23,29 +23,96 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_DEBUGFS_H_ #define _LINUXKPI_LINUX_DEBUGFS_H_ #include <linux/fs.h> +#include <linux/module.h> #include <linux/seq_file.h> - #include <linux/types.h> -void debugfs_remove(struct dentry *dentry); +MALLOC_DECLARE(M_DFSINT); + +struct debugfs_reg32 { + char *name; + unsigned long offset; +}; + +struct debugfs_regset32 { + const struct debugfs_reg32 *regs; + int nregs; +}; + +struct debugfs_blob_wrapper { + void *data; + size_t size; +}; + +static inline bool +debugfs_initialized(void) +{ + + return (true); +} struct dentry *debugfs_create_file(const char *name, umode_t mode, - struct dentry *parent, void *data, - const struct file_operations *fops); + struct dentry *parent, void *data, + const struct file_operations *fops); + +/* TODO: We currently ignore the `file_size` argument. */ +struct dentry *debugfs_create_file_size(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct file_operations *fops, + loff_t file_size); + +struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode, +struct dentry *parent, void *data, + const struct file_operations *fops); + +struct dentry *debugfs_create_mode_unsafe(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct file_operations *fops, + const struct file_operations *fops_ro, + const struct file_operations *fops_wo); struct dentry *debugfs_create_dir(const char *name, struct dentry *parent); struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, - const char *dest); + const char *dest); + +void debugfs_remove(struct dentry *dentry); void debugfs_remove_recursive(struct dentry *dentry); -#endif +#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \ + DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt) + +void debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent, + bool *value); +void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent, + uint8_t *value); +void debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent, + uint16_t *value); +void debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent, + uint32_t *value); +void debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent, + uint64_t *value); +void debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, + uint8_t *value); +void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, + uint16_t *value); +void debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, + uint32_t *value); +void debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, + uint64_t *value); +void debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent, + unsigned long *value); +void debugfs_create_atomic_t(const char *name, umode_t mode, struct dentry *parent, + atomic_t *value); + +struct dentry *debugfs_create_blob(const char *name, umode_t mode, + struct dentry *parent, struct debugfs_blob_wrapper *value); + +#endif /* _LINUXKPI_LINUX_DEBUGFS_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/delay.h b/sys/compat/linuxkpi/common/include/linux/delay.h index ea0a8253b09f..f19d1a759c26 100644 --- a/sys/compat/linuxkpi/common/include/linux/delay.h +++ b/sys/compat/linuxkpi/common/include/linux/delay.h @@ -26,8 +26,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_DELAY_H_ #define _LINUXKPI_LINUX_DELAY_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/devcoredump.h b/sys/compat/linuxkpi/common/include/linux/devcoredump.h index eecf5380bfc3..b58c490615ad 100644 --- a/sys/compat/linuxkpi/common/include/linux/devcoredump.h +++ b/sys/compat/linuxkpi/common/include/linux/devcoredump.h @@ -26,8 +26,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_DEVCOREDUMP_H diff --git a/sys/compat/linuxkpi/common/include/linux/device.h b/sys/compat/linuxkpi/common/include/linux/device.h index 1c26cecfd955..668fe9cb8650 100644 --- a/sys/compat/linuxkpi/common/include/linux/device.h +++ b/sys/compat/linuxkpi/common/include/linux/device.h @@ -4,6 +4,10 @@ * Copyright (c) 2010 Panasas, Inc. * Copyright (c) 2013-2016 Mellanox Technologies, Ltd. * All rights reserved. + * Copyright (c) 2021-2022 The FreeBSD Foundation + * + * Portions of this software were developed by Björn Zeeb + * 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 @@ -25,8 +29,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_DEVICE_H_ #define _LINUXKPI_LINUX_DEVICE_H_ @@ -37,21 +39,21 @@ #include <linux/sysfs.h> #include <linux/list.h> #include <linux/compiler.h> -#include <linux/types.h> #include <linux/module.h> #include <linux/workqueue.h> #include <linux/kdev_t.h> #include <linux/backlight.h> #include <linux/pm.h> #include <linux/idr.h> +#include <linux/overflow.h> #include <linux/ratelimit.h> /* via linux/dev_printk.h */ +#include <linux/fwnode.h> #include <asm/atomic.h> #include <sys/bus.h> #include <sys/backlight.h> struct device; -struct fwnode_handle; struct class { const char *name; @@ -67,6 +69,7 @@ struct class { struct dev_pm_ops { int (*prepare)(struct device *dev); + void (*complete)(struct device *dev); int (*suspend)(struct device *dev); int (*suspend_late)(struct device *dev); int (*resume)(struct device *dev); @@ -79,6 +82,7 @@ struct dev_pm_ops { int (*poweroff_late)(struct device *dev); int (*restore)(struct device *dev); int (*restore_early)(struct device *dev); + int (*suspend_noirq)(struct device *dev); int (*runtime_suspend)(struct device *dev); int (*runtime_resume)(struct device *dev); int (*runtime_idle)(struct device *dev); @@ -124,6 +128,8 @@ struct device { spinlock_t devres_lock; struct list_head devres_head; + + struct dev_pm_info power; }; extern struct device linux_root_device; @@ -183,15 +189,31 @@ show_class_attr_string(struct class *class, struct class_attribute_string class_attr_##_name = \ _CLASS_ATTR_STRING(_name, _mode, _str) -#define dev_err(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) -#define dev_crit(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) -#define dev_warn(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) -#define dev_info(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) -#define dev_notice(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) -#define dev_emerg(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) -#define dev_dbg(dev, fmt, ...) do { } while (0) #define dev_printk(lvl, dev, fmt, ...) \ - device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) + device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) + +#define dev_emerg(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) +#define dev_alert(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) +#define dev_crit(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) +#define dev_err(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) +#define dev_warn(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) +#define dev_notice(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) +#define dev_info(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) +#define dev_dbg(dev, fmt, ...) do { } while (0) + +#define dev_WARN(dev, fmt, ...) \ + device_printf((dev)->bsddev, "%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__) + +#define dev_WARN_ONCE(dev, condition, fmt, ...) do { \ + static bool __dev_WARN_ONCE; \ + bool __ret_warn_on = (condition); \ + if (unlikely(__ret_warn_on)) { \ + if (!__dev_WARN_ONCE) { \ + __dev_WARN_ONCE = true; \ + device_printf((dev)->bsddev, "%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__); \ + } \ + } \ +} while (0) #define dev_info_once(dev, ...) do { \ static bool __dev_info_once; \ @@ -201,6 +223,14 @@ show_class_attr_string(struct class *class, } \ } while (0) +#define dev_warn_once(dev, ...) do { \ + static bool __dev_warn_once; \ + if (!__dev_warn_once) { \ + __dev_warn_once = 1; \ + dev_warn(dev, __VA_ARGS__); \ + } \ +} while (0) + #define dev_err_once(dev, ...) do { \ static bool __dev_err_once; \ if (!__dev_err_once) { \ @@ -209,6 +239,14 @@ show_class_attr_string(struct class *class, } \ } while (0) +#define dev_dbg_once(dev, ...) do { \ + static bool __dev_dbg_once; \ + if (!__dev_dbg_once) { \ + __dev_dbg_once = 1; \ + dev_dbg(dev, __VA_ARGS__); \ + } \ +} while (0) + #define dev_err_ratelimited(dev, ...) do { \ static linux_ratelimit_t __ratelimited; \ if (linux_ratelimited(&__ratelimited)) \ @@ -221,6 +259,12 @@ show_class_attr_string(struct class *class, dev_warn(dev, __VA_ARGS__); \ } while (0) +#define dev_dbg_ratelimited(dev, ...) do { \ + static linux_ratelimit_t __ratelimited; \ + if (linux_ratelimited(&__ratelimited)) \ + dev_dbg(dev, __VA_ARGS__); \ +} while (0) + /* 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 *); @@ -239,6 +283,7 @@ int lkpi_devres_destroy(struct device *, void(*release)(struct device *, void *) void lkpi_devres_release_free_list(struct device *); void lkpi_devres_unlink(struct device *, void *); void lkpi_devm_kmalloc_release(struct device *, void *); +#define devm_kfree(_d, _p) lkpi_devm_kmalloc_release(_d, _p) static inline const char * dev_driver_string(const struct device *dev) @@ -525,6 +570,30 @@ device_reprobe(struct device *dev) return (-error); } +static inline void +device_set_wakeup_enable(struct device *dev __unused, bool enable __unused) +{ + + /* + * XXX-BZ TODO This is used by wireless drivers supporting WoWLAN which + * we currently do not support. + */ +} + +static inline int +device_wakeup_enable(struct device *dev) +{ + + device_set_wakeup_enable(dev, true); + return (0); +} + +static inline bool +device_iommu_mapped(struct device *dev __unused) +{ + return (false); +} + #define dev_pm_set_driver_flags(dev, flags) do { \ } while (0) @@ -601,10 +670,32 @@ devm_kmalloc(struct device *dev, size_t size, gfp_t gfp) return (p); } +static inline void * +devm_kmemdup(struct device *dev, const void *src, size_t len, gfp_t gfp) +{ + void *dst; + + if (len == 0) + return (NULL); + + dst = devm_kmalloc(dev, len, gfp); + if (dst != NULL) + memcpy(dst, src, len); + + return (dst); +} + #define devm_kzalloc(_dev, _size, _gfp) \ devm_kmalloc((_dev), (_size), (_gfp) | __GFP_ZERO) #define devm_kcalloc(_dev, _sizen, _size, _gfp) \ devm_kmalloc((_dev), ((_sizen) * (_size)), (_gfp) | __GFP_ZERO) +int lkpi_devm_add_action(struct device *dev, void (*action)(void *), void *data); +#define devm_add_action(dev, action, data) \ + lkpi_devm_add_action(dev, action, data); +int lkpi_devm_add_action_or_reset(struct device *dev, void (*action)(void *), void *data); +#define devm_add_action_or_reset(dev, action, data) \ + lkpi_devm_add_action_or_reset(dev, action, data) + #endif /* _LINUXKPI_LINUX_DEVICE_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/dma-attrs.h b/sys/compat/linuxkpi/common/include/linux/dma-attrs.h index 741e1aa15d67..c9cfa9b621d5 100644 --- a/sys/compat/linuxkpi/common/include/linux/dma-attrs.h +++ b/sys/compat/linuxkpi/common/include/linux/dma-attrs.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_DMA_ATTR_H_ #define _LINUXKPI_LINUX_DMA_ATTR_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/dma-buf-map.h b/sys/compat/linuxkpi/common/include/linux/dma-buf-map.h new file mode 100644 index 000000000000..567ce3b072b3 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/dma-buf-map.h @@ -0,0 +1,91 @@ +/* Public domain. */ + +#ifndef _LINUX_DMA_BUF_MAP_H +#define _LINUX_DMA_BUF_MAP_H + +#include <linux/io.h> +#include <linux/string.h> + +struct dma_buf_map { + union { + void *vaddr_iomem; + void *vaddr; + }; + bool is_iomem; +}; + +static inline void +dma_buf_map_incr(struct dma_buf_map *dbm, size_t n) +{ + if (dbm->is_iomem) + dbm->vaddr_iomem += n; + else + dbm->vaddr += n; +} + +static inline void +dma_buf_map_memcpy_to(struct dma_buf_map *dbm, const void *src, size_t len) +{ + if (dbm->is_iomem) + memcpy_toio(dbm->vaddr_iomem, src, len); + else + memcpy(dbm->vaddr, src, len); +} + +static inline bool +dma_buf_map_is_null(const struct dma_buf_map *dbm) +{ + if (dbm->is_iomem) + return (dbm->vaddr_iomem == NULL); + else + return (dbm->vaddr == NULL); +} + +static inline bool +dma_buf_map_is_set(const struct dma_buf_map *dbm) +{ + if (dbm->is_iomem) + return (dbm->vaddr_iomem != NULL); + else + return (dbm->vaddr != NULL); +} + +static inline bool +dma_buf_map_is_equal( + const struct dma_buf_map *dbm_a, const struct dma_buf_map *dbm_b) +{ + if (dbm_a->is_iomem != dbm_b->is_iomem) + return (false); + + if (dbm_a->is_iomem) + return (dbm_a->vaddr_iomem == dbm_b->vaddr_iomem); + else + return (dbm_a->vaddr == dbm_b->vaddr); +} + +static inline void +dma_buf_map_clear(struct dma_buf_map *dbm) +{ + if (dbm->is_iomem) { + dbm->vaddr_iomem = NULL; + dbm->is_iomem = false; + } else { + dbm->vaddr = NULL; + } +} + +static inline void +dma_buf_map_set_vaddr_iomem(struct dma_buf_map *dbm, void *addr) +{ + dbm->vaddr_iomem = addr; + dbm->is_iomem = true; +} + +static inline void +dma_buf_map_set_vaddr(struct dma_buf_map *dbm, void *addr) +{ + dbm->vaddr = addr; + dbm->is_iomem = false; +} + +#endif diff --git a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h index dd3bbc094dfb..84f0361de765 100644 --- a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h +++ b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_DMA_MAPPING_H_ #define _LINUXKPI_LINUX_DMA_MAPPING_H_ @@ -45,6 +43,7 @@ #include <vm/vm.h> #include <vm/vm_page.h> +#include <vm/uma_align_mask.h> #include <vm/pmap.h> #include <machine/bus.h> @@ -95,6 +94,8 @@ int linux_dma_tag_init(struct device *, u64); int linux_dma_tag_init_coherent(struct device *, u64); 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); dma_addr_t linux_dma_map_phys(struct device *dev, vm_paddr_t phys, size_t len); void linux_dma_unmap(struct device *dev, dma_addr_t dma_addr, size_t size); int linux_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl, @@ -159,13 +160,21 @@ dma_zalloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, return (dma_alloc_coherent(dev, size, dma_handle, flag | __GFP_ZERO)); } +static inline void * +dmam_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, + gfp_t flag) +{ + + return (linuxkpi_dmam_alloc_coherent(dev, size, dma_handle, flag)); +} + static inline void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_addr) { linux_dma_unmap(dev, dma_addr, size); - kmem_free((vm_offset_t)cpu_addr, size); + kmem_free(cpu_addr, size); } static inline dma_addr_t @@ -173,7 +182,7 @@ dma_map_page_attrs(struct device *dev, struct page *page, size_t offset, size_t size, enum dma_data_direction dir, unsigned long attrs) { - return (linux_dma_map_phys(dev, VM_PAGE_TO_PHYS(page) + offset, size)); + return (linux_dma_map_phys(dev, page_to_phys(page) + offset, size)); } /* linux_dma_(un)map_sg_attrs does not support attrs yet */ @@ -188,7 +197,7 @@ dma_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction direction) { - return (linux_dma_map_phys(dev, VM_PAGE_TO_PHYS(page) + offset, size)); + return (linux_dma_map_phys(dev, page_to_phys(page) + offset, size)); } static inline void @@ -278,11 +287,15 @@ dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, { } +#define DMA_MAPPING_ERROR (~(dma_addr_t)0) + static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { - return (dma_addr == 0); + if (dma_addr == 0 || dma_addr == DMA_MAPPING_ERROR) + return (-ENOMEM); + return (0); } static inline unsigned int dma_set_max_seg_size(struct device *dev, @@ -338,7 +351,31 @@ dma_max_mapping_size(struct device *dev) #define dma_unmap_len(p, name) ((p)->name) #define dma_unmap_len_set(p, name, v) (((p)->name) = (v)) -extern int uma_align_cache; -#define dma_get_cache_alignment() uma_align_cache +#define dma_get_cache_alignment() (uma_get_cache_align_mask() + 1) + + +static inline int +dma_map_sgtable(struct device *dev, struct sg_table *sgt, + enum dma_data_direction dir, + unsigned long attrs) +{ + int nents; + + nents = dma_map_sg_attrs(dev, sgt->sgl, sgt->nents, dir, attrs); + if (nents < 0) + return (nents); + sgt->nents = nents; + return (0); +} + +static inline void +dma_unmap_sgtable(struct device *dev, struct sg_table *sgt, + enum dma_data_direction dir, + unsigned long attrs) +{ + + dma_unmap_sg_attrs(dev, sgt->sgl, sgt->nents, dir, attrs); +} + #endif /* _LINUXKPI_LINUX_DMA_MAPPING_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/dmapool.h b/sys/compat/linuxkpi/common/include/linux/dmapool.h index e45472dabc60..8501a32e30b7 100644 --- a/sys/compat/linuxkpi/common/include/linux/dmapool.h +++ b/sys/compat/linuxkpi/common/include/linux/dmapool.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_DMAPOOL_H_ #define _LINUXKPI_LINUX_DMAPOOL_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/dmi.h b/sys/compat/linuxkpi/common/include/linux/dmi.h index 339f622f89b2..d9760ee0324f 100644 --- a/sys/compat/linuxkpi/common/include/linux/dmi.h +++ b/sys/compat/linuxkpi/common/include/linux/dmi.h @@ -24,8 +24,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef __LINUXKPI_LINUX_DMI_H__ @@ -34,6 +32,12 @@ #include <sys/types.h> #include <linux/mod_devicetable.h> +struct dmi_header { + uint8_t type; + uint8_t length; + uint16_t handle; +}; + int linux_dmi_check_system(const struct dmi_system_id *); bool linux_dmi_match(enum dmi_field, const char *); const struct dmi_system_id *linux_dmi_first_match(const struct dmi_system_id *); @@ -44,4 +48,11 @@ const char *linux_dmi_get_system_info(int); #define dmi_first_match(sysid) linux_dmi_first_match(sysid) #define dmi_get_system_info(sysid) linux_dmi_get_system_info(sysid) +static inline int +dmi_walk(void (*callbackf)(const struct dmi_header *, void *), void *arg) +{ + + return (-ENXIO); +} + #endif /* __LINUXKPI_LINUX_DMI_H__ */ diff --git a/sys/compat/linuxkpi/common/include/linux/dynamic_debug.h b/sys/compat/linuxkpi/common/include/linux/dynamic_debug.h new file mode 100644 index 000000000000..12915eec3b68 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/dynamic_debug.h @@ -0,0 +1,8 @@ +/* Public domain. */ + +#ifndef _LINUXKPI_LINUX_DYNAMIC_DEBUG_H +#define _LINUXKPI_LINUX_DYNAMIC_DEBUG_H + +#define DECLARE_DYNDBG_CLASSMAP(a, b, c, ...) + +#endif diff --git a/sys/compat/linuxkpi/common/include/linux/efi.h b/sys/compat/linuxkpi/common/include/linux/efi.h index 03702bba557a..a485b4b1fd94 100644 --- a/sys/compat/linuxkpi/common/include/linux/efi.h +++ b/sys/compat/linuxkpi/common/include/linux/efi.h @@ -29,6 +29,7 @@ #define _LINUXKPI_LINUX_EFI_H_ #include <sys/param.h> +#include <sys/queue.h> #include <sys/linker.h> #include <sys/systm.h> diff --git a/sys/compat/linuxkpi/common/include/linux/err.h b/sys/compat/linuxkpi/common/include/linux/err.h index 693f7962df65..3d19949e641e 100644 --- a/sys/compat/linuxkpi/common/include/linux/err.h +++ b/sys/compat/linuxkpi/common/include/linux/err.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_ERR_H_ #define _LINUXKPI_LINUX_ERR_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/errno.h b/sys/compat/linuxkpi/common/include/linux/errno.h index 72d8af6779a5..ea258587c6f7 100644 --- a/sys/compat/linuxkpi/common/include/linux/errno.h +++ b/sys/compat/linuxkpi/common/include/linux/errno.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_ERRNO_H_ #define _LINUXKPI_LINUX_ERRNO_H_ @@ -34,6 +32,8 @@ #include <sys/errno.h> #define EBADRQC 56 /* Bad request code */ +#define EBADSLT 57 /* Invalid slot */ +#define ENOKEY 126 /* Required key not available */ #define ECHRNG EDOM #define ETIME ETIMEDOUT diff --git a/sys/compat/linuxkpi/common/include/linux/etherdevice.h b/sys/compat/linuxkpi/common/include/linux/etherdevice.h index 219ed55a880d..89cd4c8e0ba0 100644 --- a/sys/compat/linuxkpi/common/include/linux/etherdevice.h +++ b/sys/compat/linuxkpi/common/include/linux/etherdevice.h @@ -21,8 +21,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_ETHERDEVICE_H_ #define _LINUXKPI_LINUX_ETHERDEVICE_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/ethtool.h b/sys/compat/linuxkpi/common/include/linux/ethtool.h index 9195766f752d..f5567cd7ea40 100644 --- a/sys/compat/linuxkpi/common/include/linux/ethtool.h +++ b/sys/compat/linuxkpi/common/include/linux/ethtool.h @@ -23,8 +23,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_ETHTOOL_H_ @@ -32,10 +30,28 @@ #include <linux/types.h> -#define ETHTOOL_FWVERS_LEN 64 +#define ETH_GSTRING_LEN (2 * IF_NAMESIZE) /* Increase if not large enough */ + +#define ETHTOOL_FWVERS_LEN 32 struct ethtool_stats { uint8_t __dummy[0]; }; +enum ethtool_ss { + ETH_SS_STATS, +}; + +struct ethtool_drvinfo { + char driver[32]; + char version[32]; + char fw_version[ETHTOOL_FWVERS_LEN]; + char bus_info[32]; +}; + +struct net_device; +struct ethtool_ops { + void(*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *); +}; + #endif /* _LINUXKPI_LINUX_ETHTOOL_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/eventpoll.h b/sys/compat/linuxkpi/common/include/linux/eventpoll.h new file mode 100644 index 000000000000..e77e6d689f86 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/eventpoll.h @@ -0,0 +1,45 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2022, Jake Freeland <jfree@freebsd.org> + * + * 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 unmodified, 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 ``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 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_EVENTPOLL_H_ +#define _LINUXKPI_LINUX_EVENTPOLL_H_ + +#include <sys/poll.h> + +#define EPOLLIN POLLIN +#define EPOLLPRI POLLPRI +#define EPOLLOUT POLLOUT +#define EPOLLERR POLLERR +#define EPOLLHUP POLLHUP +#define EPOLLNVAL POLLNVAL +#define EPOLLRDNORM POLLRDNORM +#define EPOLLRDBAND POLLRDBAND +#define EPOLLWRNORM POLLWRNORM +#define EPOLLWRBAND POLLWRBAND +#define EPOLLRDHUP POLLRDHUP + +#endif /* _LINUXKPI_LINUX_EVENTPOLL_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/export.h b/sys/compat/linuxkpi/common/include/linux/export.h index e9ac669a535f..f48bd6af45d3 100644 --- a/sys/compat/linuxkpi/common/include/linux/export.h +++ b/sys/compat/linuxkpi/common/include/linux/export.h @@ -21,8 +21,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_EXPORT_H #define _LINUXKPI_LINUX_EXPORT_H diff --git a/sys/compat/linuxkpi/common/include/linux/file.h b/sys/compat/linuxkpi/common/include/linux/file.h index 32db72d771fc..f94e3d89ced1 100644 --- a/sys/compat/linuxkpi/common/include/linux/file.h +++ b/sys/compat/linuxkpi/common/include/linux/file.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_FILE_H_ #define _LINUXKPI_LINUX_FILE_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/firmware.h b/sys/compat/linuxkpi/common/include/linux/firmware.h index ada7d0d73edf..a6330ddafb55 100644 --- a/sys/compat/linuxkpi/common/include/linux/firmware.h +++ b/sys/compat/linuxkpi/common/include/linux/firmware.h @@ -2,6 +2,7 @@ * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2020-2021 The FreeBSD Foundation + * Copyright (c) 2022 Bjoern A. Zeeb * * This software was developed by Björn Zeeb under sponsorship from * the FreeBSD Foundation. @@ -26,8 +27,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_FIRMWARE_H @@ -56,6 +55,8 @@ int linuxkpi_request_firmware(const struct linuxkpi_firmware **, int linuxkpi_firmware_request_nowarn(const struct linuxkpi_firmware **, const char *, struct device *); void linuxkpi_release_firmware(const struct linuxkpi_firmware *); +int linuxkpi_request_partial_firmware_into_buf(const struct linuxkpi_firmware **, + const char *, struct device *, uint8_t *, size_t, size_t); static __inline int @@ -100,6 +101,16 @@ release_firmware(const struct linuxkpi_firmware *fw) linuxkpi_release_firmware(fw); } +static inline int +request_partial_firmware_into_buf(const struct linuxkpi_firmware **fw, + const char *fw_name, struct device *dev, void *buf, size_t buflen, + size_t offset) +{ + + return (linuxkpi_request_partial_firmware_into_buf(fw, fw_name, + dev, buf, buflen, offset)); +} + #define firmware linuxkpi_firmware #endif /* _LINUXKPI_LINUX_FIRMWARE_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/fs.h b/sys/compat/linuxkpi/common/include/linux/fs.h index a21c140d5a9b..a28d5bf97121 100644 --- a/sys/compat/linuxkpi/common/include/linux/fs.h +++ b/sys/compat/linuxkpi/common/include/linux/fs.h @@ -25,13 +25,10 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_FS_H_ #define _LINUXKPI_LINUX_FS_H_ -#include <sys/cdefs.h> #include <sys/param.h> #include <sys/systm.h> #include <sys/conf.h> @@ -45,6 +42,8 @@ #include <linux/dcache.h> #include <linux/capability.h> #include <linux/wait_bit.h> +#include <linux/kernel.h> +#include <linux/mutex.h> struct module; struct kiocb; @@ -250,6 +249,7 @@ nonseekable_open(struct inode *inode, struct file *filp) static inline int simple_open(struct inode *inode, struct file *filp) { + filp->private_data = inode->i_private; return 0; } @@ -298,6 +298,18 @@ no_llseek(struct file *file, loff_t offset, int whence) } static inline loff_t +default_llseek(struct file *file, loff_t offset, int whence) +{ + return (no_llseek(file, offset, whence)); +} + +static inline loff_t +generic_file_llseek(struct file *file, loff_t offset, int whence) +{ + return (no_llseek(file, offset, whence)); +} + +static inline loff_t noop_llseek(struct linux_file *file, loff_t offset, int whence) { @@ -318,4 +330,73 @@ call_mmap(struct linux_file *file, struct vm_area_struct *vma) return (file->f_op->mmap(file, vma)); } +static inline void +i_size_write(struct inode *inode, loff_t i_size) +{ +} + +/* + * simple_read_from_buffer: copy data from kernel-space origin + * buffer into user-space destination buffer + * + * @dest: destination buffer + * @read_size: number of bytes to be transferred + * @ppos: starting transfer position pointer + * @orig: origin buffer + * @buf_size: size of destination and origin buffers + * + * Return value: + * On success, total bytes copied with *ppos incremented accordingly. + * On failure, negative value. + */ +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 *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 (read_size > buf_remain) + read_size = buf_remain; + + /* 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); + +#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt) \ +static inline int \ +__fops ## _open(struct inode *inode, struct file *filp) \ +{ \ + return (simple_attr_open(inode, filp, __get, __set, __fmt)); \ +} \ +static const struct file_operations __fops = { \ + .owner = THIS_MODULE, \ + .open = __fops ## _open, \ + .release = simple_attr_release, \ + .read = simple_attr_read, \ + .write = simple_attr_write, \ + .llseek = no_llseek \ +} + +int simple_attr_open(struct inode *inode, struct file *filp, + int (*get)(void *, uint64_t *), int (*set)(void *, uint64_t), + const char *fmt); + +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_write(struct file *filp, const char *buf, size_t write_size, loff_t *ppos); + #endif /* _LINUXKPI_LINUX_FS_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/fwnode.h b/sys/compat/linuxkpi/common/include/linux/fwnode.h new file mode 100644 index 000000000000..a1fbc1b6d6a3 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/fwnode.h @@ -0,0 +1,10 @@ +/* Public domain. */ + +#ifndef _LINUXKPI_LINUX_FWNODE_H_ +#define _LINUXKPI_LINUX_FWNODE_H_ + +struct fwnode_handle { + struct fwnode_handle *secondary; +}; + +#endif /* _LINUXKPI_LINUX_FWNODE_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/gcd.h b/sys/compat/linuxkpi/common/include/linux/gcd.h index 40523bd6cba6..5ca0540e5102 100644 --- a/sys/compat/linuxkpi/common/include/linux/gcd.h +++ b/sys/compat/linuxkpi/common/include/linux/gcd.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_GCD_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/gfp.h b/sys/compat/linuxkpi/common/include/linux/gfp.h index 6273fa969db8..f6cce379924d 100644 --- a/sys/compat/linuxkpi/common/include/linux/gfp.h +++ b/sys/compat/linuxkpi/common/include/linux/gfp.h @@ -25,13 +25,10 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_GFP_H_ #define _LINUXKPI_LINUX_GFP_H_ -#include <sys/cdefs.h> #include <sys/types.h> #include <sys/systm.h> #include <sys/malloc.h> @@ -47,6 +44,7 @@ #define __GFP_HIGHMEM 0 #define __GFP_ZERO M_ZERO #define __GFP_NORETRY 0 +#define __GFP_NOMEMALLOC 0 #define __GFP_RECLAIM 0 #define __GFP_RECLAIMABLE 0 #define __GFP_RETRY_MAYFAIL 0 @@ -71,6 +69,7 @@ #define GFP_HIGHUSER_MOVABLE M_WAITOK #define GFP_IOFS M_NOWAIT #define GFP_NOIO M_NOWAIT +#define GFP_NOFS M_NOWAIT #define GFP_DMA32 __GFP_DMA32 #define GFP_TEMPORARY M_NOWAIT #define GFP_NATIVE_MASK (M_NOWAIT | M_WAITOK | M_USE_RESERVE | M_ZERO) @@ -80,6 +79,11 @@ CTASSERT((__GFP_DMA32 & GFP_NATIVE_MASK) == 0); CTASSERT((__GFP_BITS_MASK & GFP_NATIVE_MASK) == GFP_NATIVE_MASK); +struct page_frag_cache { + void *va; + int pagecnt_bias; +}; + /* * Resolve a page into a virtual address: * @@ -92,8 +96,11 @@ extern void *linux_page_address(struct page *); /* * Page management for unmapped pages: */ -extern vm_page_t linux_alloc_pages(gfp_t flags, unsigned int order); -extern void linux_free_pages(vm_page_t page, unsigned int order); +extern struct page *linux_alloc_pages(gfp_t flags, unsigned int order); +extern void linux_free_pages(struct page *page, unsigned int order); +void *linuxkpi_page_frag_alloc(struct page_frag_cache *, size_t, gfp_t); +void linuxkpi_page_frag_free(void *); +void linuxkpi__page_frag_cache_drain(struct page *, size_t); static inline struct page * alloc_page(gfp_t flags) @@ -130,6 +137,12 @@ __free_page(struct page *page) linux_free_pages(page, 0); } +static inline struct page * +dev_alloc_pages(unsigned int order) +{ + return (linux_alloc_pages(GFP_ATOMIC, order)); +} + /* * Page management for mapped pages: */ @@ -175,6 +188,27 @@ free_page(uintptr_t addr) linux_free_kmem(addr, 0); } +static inline void * +page_frag_alloc(struct page_frag_cache *pfc, size_t fragsz, gfp_t gfp) +{ + + return (linuxkpi_page_frag_alloc(pfc, fragsz, gfp)); +} + +static inline void +page_frag_free(void *addr) +{ + + linuxkpi_page_frag_free(addr); +} + +static inline void +__page_frag_cache_drain(struct page *page, size_t count) +{ + + linuxkpi__page_frag_cache_drain(page, count); +} + static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags) { diff --git a/sys/compat/linuxkpi/common/include/linux/hardirq.h b/sys/compat/linuxkpi/common/include/linux/hardirq.h index 07f00f076860..f79451dd0d35 100644 --- a/sys/compat/linuxkpi/common/include/linux/hardirq.h +++ b/sys/compat/linuxkpi/common/include/linux/hardirq.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_HARDIRQ_H_ #define _LINUXKPI_LINUX_HARDIRQ_H_ @@ -40,4 +38,14 @@ #define synchronize_irq(irq) _intr_drain((irq)) +/* + * FIXME: In the i915 driver's `intel_engine_cs.c` file, + * `synchronize_hardirq()` was replaced by `synchronize_rcu()` with the + * following comment: + * "Is it enough to wait that all cpu have context-switched?" + * + * See commit f6d50b7af554e21c380486d6f41c8537b265c777 in drm-kmod. + */ +#define synchronize_hardirq(irq) _intr_drain((irq)) + #endif /* _LINUXKPI_LINUX_HARDIRQ_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/hashtable.h b/sys/compat/linuxkpi/common/include/linux/hashtable.h index a7a30143a58e..55755c354959 100644 --- a/sys/compat/linuxkpi/common/include/linux/hashtable.h +++ b/sys/compat/linuxkpi/common/include/linux/hashtable.h @@ -23,8 +23,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_HASHTABLE_H @@ -94,8 +92,6 @@ __hash_node_type_assert(struct hlist_node *node) #define hash_add_rcu(ht, node, key) do { \ struct lkpi_hash_head *__head = &(ht)[hash_min(key, HASH_BITS(ht))]; \ __hash_node_type_assert(node); \ - KASSERT(((struct lkpi_hash_entry *)(node))->entry.cle_prev == NULL, \ - ("node is already on list or was not zeroed")); \ CK_LIST_INSERT_HEAD(&__head->head, \ (struct lkpi_hash_entry *)(node), entry); \ } while (0) diff --git a/sys/compat/linuxkpi/common/include/linux/hdmi.h b/sys/compat/linuxkpi/common/include/linux/hdmi.h new file mode 100644 index 000000000000..c8ec982ff498 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/hdmi.h @@ -0,0 +1,440 @@ +/* + * Copyright (C) 2012 Avionic Design GmbH + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __LINUX_HDMI_H_ +#define __LINUX_HDMI_H_ + +#include <linux/types.h> +#include <linux/device.h> + +enum hdmi_packet_type { + HDMI_PACKET_TYPE_NULL = 0x00, + HDMI_PACKET_TYPE_AUDIO_CLOCK_REGEN = 0x01, + HDMI_PACKET_TYPE_AUDIO_SAMPLE = 0x02, + HDMI_PACKET_TYPE_GENERAL_CONTROL = 0x03, + HDMI_PACKET_TYPE_ACP = 0x04, + HDMI_PACKET_TYPE_ISRC1 = 0x05, + HDMI_PACKET_TYPE_ISRC2 = 0x06, + HDMI_PACKET_TYPE_ONE_BIT_AUDIO_SAMPLE = 0x07, + HDMI_PACKET_TYPE_DST_AUDIO = 0x08, + HDMI_PACKET_TYPE_HBR_AUDIO_STREAM = 0x09, + HDMI_PACKET_TYPE_GAMUT_METADATA = 0x0a, + /* + enum hdmi_infoframe_type */ +}; + +enum hdmi_infoframe_type { + HDMI_INFOFRAME_TYPE_VENDOR = 0x81, + HDMI_INFOFRAME_TYPE_AVI = 0x82, + HDMI_INFOFRAME_TYPE_SPD = 0x83, + HDMI_INFOFRAME_TYPE_AUDIO = 0x84, + HDMI_INFOFRAME_TYPE_DRM = 0x87, +}; + +#define HDMI_IEEE_OUI 0x000c03 +#define HDMI_FORUM_IEEE_OUI 0xc45dd8 +#define HDMI_INFOFRAME_HEADER_SIZE 4 +#define HDMI_AVI_INFOFRAME_SIZE 13 +#define HDMI_SPD_INFOFRAME_SIZE 25 +#define HDMI_AUDIO_INFOFRAME_SIZE 10 +#define HDMI_DRM_INFOFRAME_SIZE 26 +#define HDMI_VENDOR_INFOFRAME_SIZE 4 + +#define HDMI_INFOFRAME_SIZE(type) \ + (HDMI_INFOFRAME_HEADER_SIZE + HDMI_ ## type ## _INFOFRAME_SIZE) + +struct hdmi_any_infoframe { + enum hdmi_infoframe_type type; + unsigned char version; + unsigned char length; +}; + +enum hdmi_colorspace { + HDMI_COLORSPACE_RGB, + HDMI_COLORSPACE_YUV422, + HDMI_COLORSPACE_YUV444, + HDMI_COLORSPACE_YUV420, + HDMI_COLORSPACE_RESERVED4, + HDMI_COLORSPACE_RESERVED5, + HDMI_COLORSPACE_RESERVED6, + HDMI_COLORSPACE_IDO_DEFINED, +}; + +enum hdmi_scan_mode { + HDMI_SCAN_MODE_NONE, + HDMI_SCAN_MODE_OVERSCAN, + HDMI_SCAN_MODE_UNDERSCAN, + HDMI_SCAN_MODE_RESERVED, +}; + +enum hdmi_colorimetry { + HDMI_COLORIMETRY_NONE, + HDMI_COLORIMETRY_ITU_601, + HDMI_COLORIMETRY_ITU_709, + HDMI_COLORIMETRY_EXTENDED, +}; + +enum hdmi_picture_aspect { + HDMI_PICTURE_ASPECT_NONE, + HDMI_PICTURE_ASPECT_4_3, + HDMI_PICTURE_ASPECT_16_9, + HDMI_PICTURE_ASPECT_64_27, + HDMI_PICTURE_ASPECT_256_135, + HDMI_PICTURE_ASPECT_RESERVED, +}; + +enum hdmi_active_aspect { + HDMI_ACTIVE_ASPECT_16_9_TOP = 2, + HDMI_ACTIVE_ASPECT_14_9_TOP = 3, + HDMI_ACTIVE_ASPECT_16_9_CENTER = 4, + HDMI_ACTIVE_ASPECT_PICTURE = 8, + HDMI_ACTIVE_ASPECT_4_3 = 9, + HDMI_ACTIVE_ASPECT_16_9 = 10, + HDMI_ACTIVE_ASPECT_14_9 = 11, + HDMI_ACTIVE_ASPECT_4_3_SP_14_9 = 13, + HDMI_ACTIVE_ASPECT_16_9_SP_14_9 = 14, + HDMI_ACTIVE_ASPECT_16_9_SP_4_3 = 15, +}; + +enum hdmi_extended_colorimetry { + HDMI_EXTENDED_COLORIMETRY_XV_YCC_601, + HDMI_EXTENDED_COLORIMETRY_XV_YCC_709, + HDMI_EXTENDED_COLORIMETRY_S_YCC_601, + HDMI_EXTENDED_COLORIMETRY_OPYCC_601, + HDMI_EXTENDED_COLORIMETRY_OPRGB, + + /* The following EC values are only defined in CEA-861-F. */ + HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM, + HDMI_EXTENDED_COLORIMETRY_BT2020, + HDMI_EXTENDED_COLORIMETRY_RESERVED, +}; + +enum hdmi_quantization_range { + HDMI_QUANTIZATION_RANGE_DEFAULT, + HDMI_QUANTIZATION_RANGE_LIMITED, + HDMI_QUANTIZATION_RANGE_FULL, + HDMI_QUANTIZATION_RANGE_RESERVED, +}; + +/* non-uniform picture scaling */ +enum hdmi_nups { + HDMI_NUPS_UNKNOWN, + HDMI_NUPS_HORIZONTAL, + HDMI_NUPS_VERTICAL, + HDMI_NUPS_BOTH, +}; + +enum hdmi_ycc_quantization_range { + HDMI_YCC_QUANTIZATION_RANGE_LIMITED, + HDMI_YCC_QUANTIZATION_RANGE_FULL, +}; + +enum hdmi_content_type { + HDMI_CONTENT_TYPE_GRAPHICS, + HDMI_CONTENT_TYPE_PHOTO, + HDMI_CONTENT_TYPE_CINEMA, + HDMI_CONTENT_TYPE_GAME, +}; + +enum hdmi_metadata_type { + HDMI_STATIC_METADATA_TYPE1 = 0, +}; + +enum hdmi_eotf { + HDMI_EOTF_TRADITIONAL_GAMMA_SDR, + HDMI_EOTF_TRADITIONAL_GAMMA_HDR, + HDMI_EOTF_SMPTE_ST2084, + HDMI_EOTF_BT_2100_HLG, +}; + +struct hdmi_avi_infoframe { + enum hdmi_infoframe_type type; + unsigned char version; + unsigned char length; + enum hdmi_colorspace colorspace; + enum hdmi_scan_mode scan_mode; + enum hdmi_colorimetry colorimetry; + enum hdmi_picture_aspect picture_aspect; + enum hdmi_active_aspect active_aspect; + bool itc; + enum hdmi_extended_colorimetry extended_colorimetry; + enum hdmi_quantization_range quantization_range; + enum hdmi_nups nups; + unsigned char video_code; + enum hdmi_ycc_quantization_range ycc_quantization_range; + enum hdmi_content_type content_type; + unsigned char pixel_repeat; + unsigned short top_bar; + unsigned short bottom_bar; + unsigned short left_bar; + unsigned short right_bar; +}; + +/* DRM Infoframe as per CTA 861.G spec */ +struct hdmi_drm_infoframe { + enum hdmi_infoframe_type type; + unsigned char version; + unsigned char length; + enum hdmi_eotf eotf; + enum hdmi_metadata_type metadata_type; + struct { + u16 x, y; + } display_primaries[3]; + struct { + u16 x, y; + } white_point; + u16 max_display_mastering_luminance; + u16 min_display_mastering_luminance; + u16 max_cll; + u16 max_fall; +}; + +void hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame); +ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer, + size_t size); +ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame, + void *buffer, size_t size); +int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame); +int hdmi_drm_infoframe_init(struct hdmi_drm_infoframe *frame); +ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame, void *buffer, + size_t size); +ssize_t hdmi_drm_infoframe_pack_only(const struct hdmi_drm_infoframe *frame, + void *buffer, size_t size); +int hdmi_drm_infoframe_check(struct hdmi_drm_infoframe *frame); +int hdmi_drm_infoframe_unpack_only(struct hdmi_drm_infoframe *frame, + const void *buffer, size_t size); + +enum hdmi_spd_sdi { + HDMI_SPD_SDI_UNKNOWN, + HDMI_SPD_SDI_DSTB, + HDMI_SPD_SDI_DVDP, + HDMI_SPD_SDI_DVHS, + HDMI_SPD_SDI_HDDVR, + HDMI_SPD_SDI_DVC, + HDMI_SPD_SDI_DSC, + HDMI_SPD_SDI_VCD, + HDMI_SPD_SDI_GAME, + HDMI_SPD_SDI_PC, + HDMI_SPD_SDI_BD, + HDMI_SPD_SDI_SACD, + HDMI_SPD_SDI_HDDVD, + HDMI_SPD_SDI_PMP, +}; + +struct hdmi_spd_infoframe { + enum hdmi_infoframe_type type; + unsigned char version; + unsigned char length; + char vendor[8]; + char product[16]; + enum hdmi_spd_sdi sdi; +}; + +int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame, + const char *vendor, const char *product); +ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer, + size_t size); +ssize_t hdmi_spd_infoframe_pack_only(const struct hdmi_spd_infoframe *frame, + void *buffer, size_t size); +int hdmi_spd_infoframe_check(struct hdmi_spd_infoframe *frame); + +enum hdmi_audio_coding_type { + HDMI_AUDIO_CODING_TYPE_STREAM, + HDMI_AUDIO_CODING_TYPE_PCM, + HDMI_AUDIO_CODING_TYPE_AC3, + HDMI_AUDIO_CODING_TYPE_MPEG1, + HDMI_AUDIO_CODING_TYPE_MP3, + HDMI_AUDIO_CODING_TYPE_MPEG2, + HDMI_AUDIO_CODING_TYPE_AAC_LC, + HDMI_AUDIO_CODING_TYPE_DTS, + HDMI_AUDIO_CODING_TYPE_ATRAC, + HDMI_AUDIO_CODING_TYPE_DSD, + HDMI_AUDIO_CODING_TYPE_EAC3, + HDMI_AUDIO_CODING_TYPE_DTS_HD, + HDMI_AUDIO_CODING_TYPE_MLP, + HDMI_AUDIO_CODING_TYPE_DST, + HDMI_AUDIO_CODING_TYPE_WMA_PRO, + HDMI_AUDIO_CODING_TYPE_CXT, +}; + +enum hdmi_audio_sample_size { + HDMI_AUDIO_SAMPLE_SIZE_STREAM, + HDMI_AUDIO_SAMPLE_SIZE_16, + HDMI_AUDIO_SAMPLE_SIZE_20, + HDMI_AUDIO_SAMPLE_SIZE_24, +}; + +enum hdmi_audio_sample_frequency { + HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM, + HDMI_AUDIO_SAMPLE_FREQUENCY_32000, + HDMI_AUDIO_SAMPLE_FREQUENCY_44100, + HDMI_AUDIO_SAMPLE_FREQUENCY_48000, + HDMI_AUDIO_SAMPLE_FREQUENCY_88200, + HDMI_AUDIO_SAMPLE_FREQUENCY_96000, + HDMI_AUDIO_SAMPLE_FREQUENCY_176400, + HDMI_AUDIO_SAMPLE_FREQUENCY_192000, +}; + +enum hdmi_audio_coding_type_ext { + /* Refer to Audio Coding Type (CT) field in Data Byte 1 */ + HDMI_AUDIO_CODING_TYPE_EXT_CT, + + /* + * The next three CXT values are defined in CEA-861-E only. + * They do not exist in older versions, and in CEA-861-F they are + * defined as 'Not in use'. + */ + HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC, + HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC_V2, + HDMI_AUDIO_CODING_TYPE_EXT_MPEG_SURROUND, + + /* The following CXT values are only defined in CEA-861-F. */ + HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC, + HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_V2, + HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC, + HDMI_AUDIO_CODING_TYPE_EXT_DRA, + HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_SURROUND, + HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC_SURROUND = 10, +}; + +struct hdmi_audio_infoframe { + enum hdmi_infoframe_type type; + unsigned char version; + unsigned char length; + unsigned char channels; + enum hdmi_audio_coding_type coding_type; + enum hdmi_audio_sample_size sample_size; + enum hdmi_audio_sample_frequency sample_frequency; + enum hdmi_audio_coding_type_ext coding_type_ext; + unsigned char channel_allocation; + unsigned char level_shift_value; + bool downmix_inhibit; + +}; + +int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame); +ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, + void *buffer, size_t size); +ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame, + void *buffer, size_t size); +int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame); + +enum hdmi_3d_structure { + HDMI_3D_STRUCTURE_INVALID = -1, + HDMI_3D_STRUCTURE_FRAME_PACKING = 0, + HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE, + HDMI_3D_STRUCTURE_LINE_ALTERNATIVE, + HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL, + HDMI_3D_STRUCTURE_L_DEPTH, + HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH, + HDMI_3D_STRUCTURE_TOP_AND_BOTTOM, + HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF = 8, +}; + + +struct hdmi_vendor_infoframe { + enum hdmi_infoframe_type type; + unsigned char version; + unsigned char length; + unsigned int oui; + u8 vic; + enum hdmi_3d_structure s3d_struct; + unsigned int s3d_ext_data; +}; + +/* HDR Metadata as per 861.G spec */ +struct hdr_static_metadata { + __u8 eotf; + __u8 metadata_type; + __u16 max_cll; + __u16 max_fall; + __u16 min_cll; +}; + +/** + * struct hdr_sink_metadata - HDR sink metadata + * + * Metadata Information read from Sink's EDID + */ +struct hdr_sink_metadata { + /** + * @metadata_type: Static_Metadata_Descriptor_ID. + */ + __u32 metadata_type; + /** + * @hdmi_type1: HDR Metadata Infoframe. + */ + union { + struct hdr_static_metadata hdmi_type1; + }; +}; + +int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame); +ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, + void *buffer, size_t size); +ssize_t hdmi_vendor_infoframe_pack_only(const struct hdmi_vendor_infoframe *frame, + void *buffer, size_t size); +int hdmi_vendor_infoframe_check(struct hdmi_vendor_infoframe *frame); + +union hdmi_vendor_any_infoframe { + struct { + enum hdmi_infoframe_type type; + unsigned char version; + unsigned char length; + unsigned int oui; + } any; + struct hdmi_vendor_infoframe hdmi; +}; + +/** + * union hdmi_infoframe - overall union of all abstract infoframe representations + * @any: generic infoframe + * @avi: avi infoframe + * @spd: spd infoframe + * @vendor: union of all vendor infoframes + * @audio: audio infoframe + * @drm: Dynamic Range and Mastering infoframe + * + * This is used by the generic pack function. This works since all infoframes + * have the same header which also indicates which type of infoframe should be + * packed. + */ +union hdmi_infoframe { + struct hdmi_any_infoframe any; + struct hdmi_avi_infoframe avi; + struct hdmi_spd_infoframe spd; + union hdmi_vendor_any_infoframe vendor; + struct hdmi_audio_infoframe audio; + struct hdmi_drm_infoframe drm; +}; + +ssize_t hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, + size_t size); +ssize_t hdmi_infoframe_pack_only(const union hdmi_infoframe *frame, + void *buffer, size_t size); +int hdmi_infoframe_check(union hdmi_infoframe *frame); +int hdmi_infoframe_unpack(union hdmi_infoframe *frame, + const void *buffer, size_t size); +void hdmi_infoframe_log(const char *level, struct device *dev, + const union hdmi_infoframe *frame); + +#endif /* _DRM_HDMI_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/highmem.h b/sys/compat/linuxkpi/common/include/linux/highmem.h index 53efbec06385..f770bef6b3b7 100644 --- a/sys/compat/linuxkpi/common/include/linux/highmem.h +++ b/sys/compat/linuxkpi/common/include/linux/highmem.h @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2010 Isilon Systems, Inc. * Copyright (c) 2016 Matthew Macy (mmacy@mattmacy.io) @@ -47,19 +47,20 @@ #define PageHighMem(p) (0) -static inline vm_page_t +static inline struct page * kmap_to_page(void *addr) { + return (virt_to_page(addr)); } static inline void * -kmap(vm_page_t page) +kmap(struct page *page) { struct sf_buf *sf; if (PMAP_HAS_DMAP) { - return ((void *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(page))); + return ((void *)PHYS_TO_DMAP(page_to_phys(page))); } else { sched_pin(); sf = sf_buf_alloc(page, SFB_NOWAIT | SFB_CPUPRIVATE); @@ -72,7 +73,7 @@ kmap(vm_page_t page) } static inline void * -kmap_atomic_prot(vm_page_t page, pgprot_t prot) +kmap_atomic_prot(struct page *page, pgprot_t prot) { vm_memattr_t attr = pgprot2cachemode(prot); @@ -86,13 +87,21 @@ kmap_atomic_prot(vm_page_t page, pgprot_t prot) } static inline void * -kmap_atomic(vm_page_t page) +kmap_atomic(struct page *page) { + return (kmap_atomic_prot(page, VM_PROT_ALL)); } +static inline void * +kmap_local_page_prot(struct page *page, pgprot_t prot) +{ + + return (kmap_atomic_prot(page, prot)); +} + static inline void -kunmap(vm_page_t page) +kunmap(struct page *page) { struct sf_buf *sf; @@ -111,8 +120,16 @@ kunmap(vm_page_t page) static inline void kunmap_atomic(void *vaddr) { + if (!PMAP_HAS_DMAP) kunmap(virt_to_page(vaddr)); } +static inline void +kunmap_local(void *addr) +{ + + kunmap_atomic(addr); +} + #endif /* _LINUXKPI_LINUX_HIGHMEM_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/hrtimer.h b/sys/compat/linuxkpi/common/include/linux/hrtimer.h index 23e707d906b4..88f9487d0b85 100644 --- a/sys/compat/linuxkpi/common/include/linux/hrtimer.h +++ b/sys/compat/linuxkpi/common/include/linux/hrtimer.h @@ -21,8 +21,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_HRTIMER_H_ @@ -32,6 +30,7 @@ #include <sys/_mutex.h> #include <linux/ktime.h> +#include <linux/rbtree.h> #include <linux/timer.h> enum hrtimer_mode { @@ -53,6 +52,7 @@ struct hrtimer { }; #define hrtimer_active(hrtimer) linux_hrtimer_active(hrtimer) +#define hrtimer_try_to_cancel(hrtimer) linux_hrtimer_try_to_cancel(hrtimer) #define hrtimer_cancel(hrtimer) linux_hrtimer_cancel(hrtimer) #define hrtimer_init(hrtimer, clock, mode) do { \ @@ -79,6 +79,7 @@ struct hrtimer { } while (0) bool linux_hrtimer_active(struct hrtimer *); +int linux_hrtimer_try_to_cancel(struct hrtimer *); int linux_hrtimer_cancel(struct hrtimer *); void linux_hrtimer_init(struct hrtimer *); void linux_hrtimer_set_expires(struct hrtimer *, ktime_t); diff --git a/sys/compat/linuxkpi/common/include/linux/i2c.h b/sys/compat/linuxkpi/common/include/linux/i2c.h index 0bb8b470edd7..f24d282586f6 100644 --- a/sys/compat/linuxkpi/common/include/linux/i2c.h +++ b/sys/compat/linuxkpi/common/include/linux/i2c.h @@ -46,6 +46,7 @@ #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0 #define I2C_FUNC_10BIT_ADDR 0 +#define I2C_CLASS_HWMON 0x1 #define I2C_CLASS_DDC 0x8 #define I2C_CLASS_SPD 0x80 @@ -58,6 +59,7 @@ struct i2c_adapter { const struct i2c_lock_operations *lock_ops; const struct i2c_algorithm *algo; + const struct i2c_adapter_quirks *quirks; void *algo_data; int retries; @@ -82,6 +84,29 @@ struct i2c_lock_operations { void (*unlock_bus)(struct i2c_adapter *, unsigned int); }; +struct i2c_adapter_quirks { + uint64_t flags; + int max_num_msgs; + uint16_t max_write_len; + uint16_t max_read_len; + uint16_t max_comb_1st_msg_len; + uint16_t max_comb_2nd_msg_len; +}; + +#define I2C_AQ_COMB BIT(0) +#define I2C_AQ_COMB_WRITE_FIRST BIT(1) +#define I2C_AQ_COMB_READ_SECOND BIT(2) +#define I2C_AQ_COMB_SAME_ADDR BIT(3) +#define I2C_AQ_COMB_WRITE_THEN_READ \ + (I2C_AQ_COMB | I2C_AQ_COMB_WRITE_FIRST | \ + I2C_AQ_COMB_READ_SECOND | I2C_AQ_COMB_SAME_ADDR) +#define I2C_AQ_NO_CLK_STRETCH BIT(4) +#define I2C_AQ_NO_ZERO_LEN_READ BIT(5) +#define I2C_AQ_NO_ZERO_LEN_WRITE BIT(6) +#define I2C_AQ_NO_ZERO_LEN \ + (I2C_AQ_NO_ZERO_LEN_READ | I2C_AQ_NO_ZERO_LEN_WRITE) +#define I2C_AQ_NO_REP_START BIT(7) + int lkpi_i2c_add_adapter(struct i2c_adapter *adapter); int lkpi_i2c_del_adapter(struct i2c_adapter *adapter); @@ -100,7 +125,7 @@ do_i2c_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int nmsgs) retries = adapter->retries == 0 ? 1 : adapter->retries; for (; retries != 0; retries--) { - if (adapter->algo->master_xfer != NULL) + if (adapter->algo != NULL && adapter->algo->master_xfer != NULL) ret = adapter->algo->master_xfer(adapter, msgs, nmsgs); else ret = lkpi_i2cbb_transfer(adapter, msgs, nmsgs); @@ -116,7 +141,7 @@ i2c_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int nmsgs) { int ret; - if (!adapter->algo) + if (adapter->algo == NULL && adapter->algo_data == NULL) return (-EOPNOTSUPP); if (adapter->lock_ops) diff --git a/sys/compat/linuxkpi/common/include/linux/idr.h b/sys/compat/linuxkpi/common/include/linux/idr.h index 5310fcf9950c..ca3f8171ff44 100644 --- a/sys/compat/linuxkpi/common/include/linux/idr.h +++ b/sys/compat/linuxkpi/common/include/linux/idr.h @@ -25,14 +25,13 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_IDR_H_ #define _LINUXKPI_LINUX_IDR_H_ #include <sys/param.h> #include <sys/lock.h> +#include <sys/limits.h> #include <sys/mutex.h> #include <linux/types.h> @@ -134,6 +133,12 @@ ida_get_new(struct ida *ida, int *p_id) } static inline int +ida_alloc_min(struct ida *ida, unsigned int min, gfp_t gfp) +{ + return (ida_simple_get(ida, min, UINT_MAX, gfp)); +} + +static inline int ida_alloc_max(struct ida *ida, unsigned int max, gfp_t gfp) { diff --git a/sys/compat/linuxkpi/common/include/linux/ieee80211.h b/sys/compat/linuxkpi/common/include/linux/ieee80211.h index 6698b84dc1ca..2000e7480ff8 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-2021 The FreeBSD Foundation + * Copyright (c) 2020-2023 The FreeBSD Foundation * * This software was developed by Björn Zeeb under sponsorship from * the FreeBSD Foundation. @@ -24,8 +24,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_IEEE80211_H @@ -62,9 +60,9 @@ struct ieee80211_mmie_16 { #define IEEE80211_INVAL_HW_QUEUE ((uint8_t)-1) -#define IEEE80211_MAX_AMPDU_BUF_HT 0x40 -#define IEEE80211_MAX_AMPDU_BUF 256 /* for HE? */ +#define IEEE80211_MAX_AMPDU_BUF_HT IEEE80211_AGGR_BAWMAX #define IEEE80211_MAX_AMPDU_BUF_HE 256 +#define IEEE80211_MAX_AMPDU_BUF_EHT 1024 #define IEEE80211_MAX_FRAME_LEN 2352 #define IEEE80211_MAX_DATA_LEN (2300 + IEEE80211_CRC_LEN) @@ -132,16 +130,22 @@ enum wlan_ht_cap_sm_ps { #define WLAN_KEY_LEN_WEP40 5 #define WLAN_KEY_LEN_WEP104 13 +#define WLAN_KEY_LEN_TKIP 32 #define WLAN_KEY_LEN_CCMP 16 +#define WLAN_KEY_LEN_GCMP 16 +#define WLAN_KEY_LEN_AES_CMAC 16 #define WLAN_KEY_LEN_GCMP_256 32 +#define WLAN_KEY_LEN_BIP_CMAC_256 32 +#define WLAN_KEY_LEN_BIP_GMAC_128 16 +#define WLAN_KEY_LEN_BIP_GMAC_256 32 /* 802.11-2020, 9.4.2.55.3, Table 9-185 Subfields of the A-MPDU Parameters field */ enum ieee80211_min_mpdu_start_spacing { IEEE80211_HT_MPDU_DENSITY_NONE = 0, #if 0 IEEE80211_HT_MPDU_DENSITY_XXX = 1, /* 1/4 us */ - IEEE80211_HT_MPDU_DENSITY_YYY = 2, /* 1/2 us */ #endif + IEEE80211_HT_MPDU_DENSITY_0_5 = 2, /* 1/2 us */ IEEE80211_HT_MPDU_DENSITY_1 = 3, /* 1 us */ IEEE80211_HT_MPDU_DENSITY_2 = 4, /* 2 us */ IEEE80211_HT_MPDU_DENSITY_4 = 5, /* 4us */ @@ -159,6 +163,7 @@ enum ieee80211_min_mpdu_start_spacing { #define IEEE80211_FCTL_FROMDS (IEEE80211_FC1_DIR_FROMDS << 8) #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_FTYPE_MGMT IEEE80211_FC0_TYPE_MGT #define IEEE80211_FTYPE_CTL IEEE80211_FC0_TYPE_CTL @@ -170,8 +175,12 @@ enum ieee80211_min_mpdu_start_spacing { #define IEEE80211_STYPE_DISASSOC IEEE80211_FC0_SUBTYPE_DISASSOC #define IEEE80211_STYPE_AUTH IEEE80211_FC0_SUBTYPE_AUTH #define IEEE80211_STYPE_DEAUTH IEEE80211_FC0_SUBTYPE_DEAUTH +#define IEEE80211_STYPE_CTS IEEE80211_FC0_SUBTYPE_CTS +#define IEEE80211_STYPE_RTS IEEE80211_FC0_SUBTYPE_RTS #define IEEE80211_STYPE_ACTION IEEE80211_FC0_SUBTYPE_ACTION -#define IEEE80211_STYPE_QOS_DATA IEEE80211_FC0_SUBTYPE_QOS +#define IEEE80211_STYPE_QOS_DATA IEEE80211_FC0_SUBTYPE_QOS_DATA +#define IEEE80211_STYPE_QOS_NULLFUNC IEEE80211_FC0_SUBTYPE_QOS_NULL +#define IEEE80211_STYPE_QOS_CFACK 0xd0 /* XXX-BZ reserved? */ #define IEEE80211_NUM_ACS 4 /* net8021::WME_NUM_AC */ @@ -188,11 +197,12 @@ enum ieee80211_min_mpdu_start_spacing { #define IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK 8 /* TODO FIXME ax? */ #define IEEE80211_HE_PPE_THRES_INFO_HEADER_SIZE 16 /* TODO FIXME ax? */ -#define IEEE80211_HT_OP_MODE_PROTECTION 0x03 /* MASK */ -#define IEEE80211_HT_OP_MODE_PROTECTION_NONE 0x00 -#define IEEE80211_HT_OP_MODE_PROTECTION_20MHZ 0x01 -#define IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED 0x02 -#define IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER 0x03 +/* 802.11-2012, Table 8-130-HT Operation element fields and subfields, HT Protection */ +#define IEEE80211_HT_OP_MODE_PROTECTION IEEE80211_HTINFO_OPMODE /* Mask. */ +#define IEEE80211_HT_OP_MODE_PROTECTION_NONE IEEE80211_HTINFO_OPMODE_PURE /* No protection */ +#define IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER IEEE80211_HTINFO_OPMODE_PROTOPT /* Nonmember protection */ +#define IEEE80211_HT_OP_MODE_PROTECTION_20MHZ IEEE80211_HTINFO_OPMODE_HT20PR /* 20 MHz protection */ +#define IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED IEEE80211_HTINFO_OPMODE_MIXED /* Non-HT mixed */ /* 9.6.13.1, Table 9-342 TDLS Action field values. */ @@ -211,15 +221,19 @@ enum ieee80211_tdls_action_code { /* 11-255 reserved */ }; -/* 9.4.2.27, Table 9-135. Extended Capabilities field. */ +/* 802.11-2020 9.4.2.26, Table 9-153. Extended Capabilities field. */ /* This is split up into octets CAPA1 = octet 1, ... */ #define WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING BIT(2 % 8) #define WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT BIT(22 % 8) +#define WLAN_EXT_CAPA3_TIMING_MEASUREMENT_SUPPORT BIT(23 % 8) #define WLAN_EXT_CAPA8_OPMODE_NOTIF BIT(62 % 8) +#define WLAN_EXT_CAPA8_MAX_MSDU_IN_AMSDU_LSB BIT(63 % 8) +#define WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB BIT(64 % 8) +#define WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT BIT(77 % 8) +#define WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT BIT(78 % 8) +#define WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT BIT(79 % 8) -#define WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT BIT(5) /* XXX */ -#define WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT BIT(7) /* XXX */ -#define WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT BIT(6) /* XXX */ +#define WLAN_EXT_CAPA11_EMA_SUPPORT 0x00 /* XXX TODO FIXME */ /* iwlwifi/mvm/utils:: for (ac = IEEE80211_AC_VO; ac <= IEEE80211_AC_VI; ac++) */ @@ -243,6 +257,8 @@ enum ieee80211_ac_numbers { /* XXX net80211 calls these IEEE80211_HTCAP_* */ #define IEEE80211_HT_CAP_LDPC_CODING 0x0001 /* IEEE80211_HTCAP_LDPC */ #define IEEE80211_HT_CAP_SUP_WIDTH_20_40 0x0002 /* IEEE80211_HTCAP_CHWIDTH40 */ +#define IEEE80211_HT_CAP_SM_PS 0x000c /* IEEE80211_HTCAP_SMPS */ +#define IEEE80211_HT_CAP_SM_PS_SHIFT 2 #define IEEE80211_HT_CAP_GRN_FLD 0x0010 /* IEEE80211_HTCAP_GREENFIELD */ #define IEEE80211_HT_CAP_SGI_20 0x0020 /* IEEE80211_HTCAP_SHORTGI20 */ #define IEEE80211_HT_CAP_SGI_40 0x0040 /* IEEE80211_HTCAP_SHORTGI40 */ @@ -251,8 +267,6 @@ enum ieee80211_ac_numbers { #define IEEE80211_HT_CAP_RX_STBC_SHIFT 8 /* IEEE80211_HTCAP_RXSTBC_S */ #define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 /* IEEE80211_HTCAP_MAXAMSDU */ #define IEEE80211_HT_CAP_DSSSCCK40 0x1000 /* IEEE80211_HTCAP_DSSSCCK40 */ -#define IEEE80211_HT_CAP_SM_PS 0x000c /* IEEE80211_HTCAP_SMPS */ -#define IEEE80211_HT_CAP_SM_PS_SHIFT 2 #define IEEE80211_HT_CAP_LSIG_TXOP_PROT 0x8000 /* IEEE80211_HTCAP_LSIGTXOPPROT */ #define IEEE80211_HT_MCS_TX_DEFINED 0x0001 @@ -262,6 +276,8 @@ enum ieee80211_ac_numbers { #define IEEE80211_HT_MCS_RX_HIGHEST_MASK 0x3ff #define IEEE80211_HT_MCS_MASK_LEN 10 +#define IEEE80211_MLD_MAX_NUM_LINKS 15 + struct ieee80211_mcs_info { uint8_t rx_mask[IEEE80211_HT_MCS_MASK_LEN]; uint16_t rx_highest; @@ -269,13 +285,6 @@ struct ieee80211_mcs_info { uint8_t __reserved[3]; }; -struct vht_mcs { - uint16_t rx_mcs_map; - uint16_t rx_highest; - uint16_t tx_mcs_map; - uint16_t tx_highest; -}; - /* 802.11-2020, 9.4.2.55.1 HT Capabilities element structure */ struct ieee80211_ht_cap { uint16_t cap_info; @@ -286,12 +295,10 @@ struct ieee80211_ht_cap { uint8_t antenna_selection_info; }; -struct ieee80211_vht_cap { - __le32 vht_cap_info; - struct vht_mcs supp_mcs; -}; - #define IEEE80211_HT_MAX_AMPDU_FACTOR 13 +#define IEEE80211_HE_HT_MAX_AMPDU_FACTOR 16 +#define IEEE80211_HE_VHT_MAX_AMPDU_FACTOR 20 +#define IEEE80211_HE_6GHZ_MAX_AMPDU_FACTOR 13 enum ieee80211_ht_max_ampdu_len { IEEE80211_HT_MAX_AMPDU_64K @@ -357,11 +364,11 @@ enum ieee80211_smps_mode { /* net80211::IEEE80211_S_* different but represents the state machine. */ /* Note: order here is important! */ enum ieee80211_sta_state { - IEEE80211_STA_NOTEXIST, - IEEE80211_STA_NONE, - IEEE80211_STA_AUTH, - IEEE80211_STA_ASSOC, - IEEE80211_STA_AUTHORIZED, /* 802.1x */ + IEEE80211_STA_NOTEXIST = 0, + IEEE80211_STA_NONE = 1, + IEEE80211_STA_AUTH = 2, + IEEE80211_STA_ASSOC = 3, + IEEE80211_STA_AUTHORIZED = 4, /* 802.1x */ }; enum ieee80211_sta_rx_bw { @@ -393,12 +400,20 @@ enum ieee80211_tx_info_flags { IEEE80211_TX_CTL_HW_80211_ENCAP = BIT(16), IEEE80211_TX_CTL_USE_MINRATE = BIT(17), IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(18), + IEEE80211_TX_CTL_LDPC = BIT(19), + IEEE80211_TX_CTL_STBC = BIT(20), +}; + +enum ieee80211_tx_status_flags { + IEEE80211_TX_STATUS_ACK_SIGNAL_VALID = BIT(0), }; enum ieee80211_tx_control_flags { /* XXX TODO .. right shift numbers */ IEEE80211_TX_CTRL_PORT_CTRL_PROTO = BIT(0), IEEE80211_TX_CTRL_PS_RESPONSE = BIT(1), + IEEE80211_TX_CTRL_RATE_INJECT = BIT(2), + IEEE80211_TX_CTRL_MLO_LINK = 0xF0000000, /* This is IEEE80211_LINK_UNSPECIFIED on the high bits. */ }; enum ieee80211_tx_rate_flags { @@ -413,6 +428,8 @@ enum ieee80211_tx_rate_flags { IEEE80211_TX_RC_USE_SHORT_PREAMBLE = BIT(7), }; +#define IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED -128 + #define IEEE80211_HT_CTL_LEN 4 struct ieee80211_hdr { /* net80211::ieee80211_frame_addr4 */ @@ -434,6 +451,16 @@ struct ieee80211_hdr_3addr { /* net80211::ieee80211_frame */ __le16 seq_ctrl; }; +struct ieee80211_qos_hdr { /* net80211:ieee80211_qosframe */ + __le16 frame_control; + __le16 duration_id; + uint8_t addr1[ETH_ALEN]; + uint8_t addr2[ETH_ALEN]; + uint8_t addr3[ETH_ALEN]; + __le16 seq_ctrl; + __le16 qos_ctrl; +}; + struct ieee80211_vendor_ie { }; @@ -447,7 +474,7 @@ enum ieee80211_category { WLAN_CATEGORY_BACK = 3, }; -/* 9.3.3.2 Format of Management frames */ +/* 80211-2020 9.3.3.2 Format of Management frames */ struct ieee80211_mgmt { __le16 frame_control; __le16 duration_id; @@ -480,6 +507,16 @@ struct ieee80211_mgmt { uint8_t category; /* 9.6.8 Public Action details */ union { + /* 9.6.2.5 TPC Report frame format */ + struct { + uint8_t spec_mgmt; + uint8_t dialog_token; + /* uint32_t tpc_rep_elem:: */ + uint8_t tpc_elem_id; + uint8_t tpc_elem_length; + uint8_t tpc_elem_tx_power; + uint8_t tpc_elem_link_margin; + } tpc_report; /* 9.6.8.33 Fine Timing Measurement frame format */ struct { uint8_t dialog_token; @@ -500,11 +537,28 @@ struct ieee80211_mgmt { /* Optional follows... */ uint8_t variable[0]; } addba_req; + /* XXX */ + struct { + uint8_t dialog_token; + } wnm_timing_msr; } u; } action; } u; }; +struct ieee80211_cts { /* net80211::ieee80211_frame_cts */ + __le16 frame_control; + __le16 duration; + uint8_t ra[ETH_ALEN]; +} __packed; + +struct ieee80211_rts { /* net80211::ieee80211_frame_rts */ + __le16 frame_control; + __le16 duration; + uint8_t ra[ETH_ALEN]; + uint8_t ta[ETH_ALEN]; +} __packed; + #define MHZ_TO_KHZ(_f) ((_f) * 1000) #define DBI_TO_MBI(_g) ((_g) * 100) #define MBI_TO_DBI(_x) ((_x) / 100) @@ -535,12 +589,13 @@ enum ieee80211_eid { WLAN_EID_HT_CAPABILITY = 45, /* IEEE80211_ELEMID_HTCAP */ WLAN_EID_RSN = 48, /* IEEE80211_ELEMID_RSN */ WLAN_EID_EXT_SUPP_RATES = 50, + WLAN_EID_EXT_NON_INHERITANCE = 56, WLAN_EID_EXT_CHANSWITCH_ANN = 60, WLAN_EID_MULTIPLE_BSSID = 71, /* IEEE80211_ELEMID_MULTIBSSID */ WLAN_EID_MULTI_BSSID_IDX = 85, WLAN_EID_EXT_CAPABILITY = 127, WLAN_EID_VHT_CAPABILITY = 191, /* IEEE80211_ELEMID_VHT_CAP */ - WLAN_EID_VENDOR_SPECIFIC = 221, + WLAN_EID_VENDOR_SPECIFIC = 221, /* IEEE80211_ELEMID_VENDOR */ }; enum ieee80211_eid_ext { @@ -639,6 +694,12 @@ struct ieee80211_bssid_index { int bssid_index; }; +enum ieee80211_reg_ap_power { + IEEE80211_REG_LPI_AP, + IEEE80211_REG_SP_AP, + IEEE80211_REG_VLP_AP, +}; + /* net80211: IEEE80211_IS_CTL() */ static __inline bool ieee80211_is_ctl(__le16 fc) @@ -669,9 +730,8 @@ ieee80211_is_data_qos(__le16 fc) { __le16 v; - fc &= htole16(IEEE80211_FC0_SUBTYPE_QOS | IEEE80211_FC0_TYPE_MASK | - IEEE80211_FC0_VERSION_MASK); - v = htole16(IEEE80211_FC0_QOSDATA); + fc &= htole16(IEEE80211_FC0_SUBTYPE_QOS_DATA | IEEE80211_FC0_TYPE_MASK); + v = htole16(IEEE80211_FC0_SUBTYPE_QOS_DATA | IEEE80211_FC0_TYPE_DATA); return (fc == v); } @@ -711,9 +771,9 @@ ieee80211_hdrlen(__le16 fc) if ((fc & htole16(IEEE80211_FC1_DIR_MASK << 8)) == htole16(IEEE80211_FC1_DIR_DSTODS << 8)) size += IEEE80211_ADDR_LEN; - if ((fc & htole16(IEEE80211_FC0_SUBTYPE_QOS | + if ((fc & htole16(IEEE80211_FC0_SUBTYPE_QOS_DATA | IEEE80211_FC0_TYPE_MASK)) == - htole16(IEEE80211_FC0_SUBTYPE_QOS | + htole16(IEEE80211_FC0_SUBTYPE_QOS_DATA | IEEE80211_FC0_TYPE_DATA)) size += sizeof(uint16_t); } diff --git a/sys/compat/linuxkpi/common/include/linux/if_arp.h b/sys/compat/linuxkpi/common/include/linux/if_arp.h index abd30eac49c9..6201c3a1c284 100644 --- a/sys/compat/linuxkpi/common/include/linux/if_arp.h +++ b/sys/compat/linuxkpi/common/include/linux/if_arp.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_IF_ARP_H_ #define _LINUXKPI_LINUX_IF_ARP_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/if_ether.h b/sys/compat/linuxkpi/common/include/linux/if_ether.h index 178b778ec736..3735ad2f5527 100644 --- a/sys/compat/linuxkpi/common/include/linux/if_ether.h +++ b/sys/compat/linuxkpi/common/include/linux/if_ether.h @@ -4,6 +4,10 @@ * Copyright (c) 2010 Panasas, Inc. * Copyright (c) 2013 Mellanox Technologies, Ltd. * All rights reserved. + * Copyright (c) 2021-2022 The FreeBSD Foundation + * + * Portions of this software were developed by Björn Zeeb + * 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 @@ -25,8 +29,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_IF_ETHER_H_ #define _LINUXKPI_LINUX_IF_ETHER_H_ @@ -55,6 +57,9 @@ #define ETH_P_8021AD ETHERTYPE_QINQ #define ETH_P_PAE ETHERTYPE_PAE #define ETH_P_802_2 ETHERTYPE_8023 +#define ETH_P_IPX ETHERTYPE_IPX +#define ETH_P_AARP ETHERTYPE_AARP +#define ETH_P_802_3_MIN 0x05DD /* See comment in sys/net/ethernet.h */ #define ETH_P_LINK_CTL 0x886C /* ITU-T G.989.2 */ #define ETH_P_TDLS 0x890D /* 802.11z-2010, see wpa. */ diff --git a/sys/compat/linuxkpi/common/include/linux/if_vlan.h b/sys/compat/linuxkpi/common/include/linux/if_vlan.h index 7c5531f6ec11..3d1c61db1882 100644 --- a/sys/compat/linuxkpi/common/include/linux/if_vlan.h +++ b/sys/compat/linuxkpi/common/include/linux/if_vlan.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_IF_VLAN_H_ #define _LINUXKPI_LINUX_IF_VLAN_H_ @@ -44,7 +42,7 @@ static inline int is_vlan_dev(struct ifnet *ifp) { - return (ifp->if_type == IFT_L2VLAN); + return (if_gettype(ifp) == IFT_L2VLAN); } static inline uint16_t diff --git a/sys/compat/linuxkpi/common/include/linux/in.h b/sys/compat/linuxkpi/common/include/linux/in.h index ae2be5be1799..5cc92416c7da 100644 --- a/sys/compat/linuxkpi/common/include/linux/in.h +++ b/sys/compat/linuxkpi/common/include/linux/in.h @@ -25,15 +25,12 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_IN_H_ #define _LINUXKPI_LINUX_IN_H_ #include "opt_inet.h" -#include <sys/cdefs.h> #include <sys/param.h> #include <sys/systm.h> #include <netinet/in.h> diff --git a/sys/compat/linuxkpi/common/include/linux/in6.h b/sys/compat/linuxkpi/common/include/linux/in6.h index 5f5f548de06d..79be45b6819a 100644 --- a/sys/compat/linuxkpi/common/include/linux/in6.h +++ b/sys/compat/linuxkpi/common/include/linux/in6.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_IN6_H_ #define _LINUXKPI_LINUX_IN6_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/interrupt.h b/sys/compat/linuxkpi/common/include/linux/interrupt.h index 905a29a77f91..d5f9a0ae7a47 100644 --- a/sys/compat/linuxkpi/common/include/linux/interrupt.h +++ b/sys/compat/linuxkpi/common/include/linux/interrupt.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_INTERRUPT_H_ #define _LINUXKPI_LINUX_INTERRUPT_H_ @@ -42,7 +40,12 @@ typedef irqreturn_t (*irq_handler_t)(int, void *); -#define IRQF_SHARED RF_SHAREABLE +#define IRQF_SHARED 0x0004 /* Historically */ +#define IRQF_NOBALANCING 0 + +#define IRQ_DISABLE_UNLAZY 0 + +#define IRQ_NOTCONNECTED (1U << 31) int lkpi_request_irq(struct device *, unsigned int, irq_handler_t, irq_handler_t, unsigned long, const char *, void *); @@ -71,6 +74,14 @@ request_threaded_irq(int irq, irq_handler_t handler, } static inline int +devm_request_irq(struct device *dev, int irq, + irq_handler_t handler, unsigned long flags, const char *name, void *arg) +{ + + return (lkpi_request_irq(dev, irq, handler, NULL, flags, name, arg)); +} + +static inline int devm_request_threaded_irq(struct device *dev, int irq, irq_handler_t handler, irq_handler_t thread_handler, unsigned long flags, const char *name, void *arg) @@ -92,6 +103,12 @@ disable_irq(unsigned int irq) lkpi_disable_irq(irq); } +static inline void +disable_irq_nosync(unsigned int irq) +{ + lkpi_disable_irq(irq); +} + static inline int bind_irq_to_cpu(unsigned int irq, int cpu_id) { @@ -111,22 +128,36 @@ devm_free_irq(struct device *xdev, unsigned int irq, void *p) } static inline int -irq_set_affinity_hint(int vector, cpumask_t *mask) +irq_set_affinity_hint(int vector, const cpumask_t *mask) { int error; if (mask != NULL) - error = intr_setaffinity(vector, CPU_WHICH_IRQ, mask); + error = intr_setaffinity(vector, CPU_WHICH_IRQ, __DECONST(cpumask_t *, mask)); else error = intr_setaffinity(vector, CPU_WHICH_IRQ, cpuset_root); return (-error); } +static inline struct msi_desc * +irq_get_msi_desc(unsigned int irq) +{ + + return (lkpi_pci_msi_desc_alloc(irq)); +} + +static inline void +irq_set_status_flags(unsigned int irq __unused, unsigned long flags __unused) +{ +} + /* * LinuxKPI tasklet support */ +struct tasklet_struct; typedef void tasklet_func_t(unsigned long); +typedef void tasklet_callback_t(struct tasklet_struct *); struct tasklet_struct { TAILQ_ENTRY(tasklet_struct) entry; @@ -135,6 +166,8 @@ struct tasklet_struct { volatile u_int tasklet_state; atomic_t count; unsigned long data; + tasklet_callback_t *callback; + bool use_callback; }; #define DECLARE_TASKLET(_name, _func, _data) \ @@ -142,6 +175,11 @@ struct tasklet_struct _name = { .func = (_func), .data = (_data) } #define tasklet_hi_schedule(t) tasklet_schedule(t) +/* Some other compat code in the tree has this defined as well. */ +#define from_tasklet(_dev, _t, _field) \ + container_of(_t, typeof(*(_dev)), _field) + +void tasklet_setup(struct tasklet_struct *, tasklet_callback_t *); extern void tasklet_schedule(struct tasklet_struct *); extern void tasklet_kill(struct tasklet_struct *); extern void tasklet_init(struct tasklet_struct *, tasklet_func_t *, @@ -152,5 +190,6 @@ extern void tasklet_disable_nosync(struct tasklet_struct *); extern int tasklet_trylock(struct tasklet_struct *); extern void tasklet_unlock(struct tasklet_struct *); extern void tasklet_unlock_wait(struct tasklet_struct *ts); +#define tasklet_unlock_spin_wait(ts) tasklet_unlock_wait(ts) #endif /* _LINUXKPI_LINUX_INTERRUPT_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/interval_tree.h b/sys/compat/linuxkpi/common/include/linux/interval_tree.h index 3f8e0cb743d9..1eb8a2fb9181 100644 --- a/sys/compat/linuxkpi/common/include/linux/interval_tree.h +++ b/sys/compat/linuxkpi/common/include/linux/interval_tree.h @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org> * diff --git a/sys/compat/linuxkpi/common/include/linux/interval_tree_generic.h b/sys/compat/linuxkpi/common/include/linux/interval_tree_generic.h index 2ee615fda159..3ed6e105cbda 100644 --- a/sys/compat/linuxkpi/common/include/linux/interval_tree_generic.h +++ b/sys/compat/linuxkpi/common/include/linux/interval_tree_generic.h @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Mark Kettenis <kettenis@OpenBSD.org> * Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org> diff --git a/sys/compat/linuxkpi/common/include/linux/io-64-nonatomic-lo-hi.h b/sys/compat/linuxkpi/common/include/linux/io-64-nonatomic-lo-hi.h new file mode 100644 index 000000000000..844b3ef171d5 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/io-64-nonatomic-lo-hi.h @@ -0,0 +1,65 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2022 Felix Palmen + * + * 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_IO_64_NONATOMIC_LO_HI_H_ +#define _LINUXKPI_LINUX_IO_64_NONATOMIC_LO_HI_H_ + +#include <linux/io.h> + +static inline uint64_t +lo_hi_readq(const volatile void *addr) +{ + const volatile uint32_t *p = addr; + uint32_t l, h; + + __io_br(); + l = le32toh(__raw_readl(p)); + h = le32toh(__raw_readl(p + 1)); + __io_ar(); + + return (l + ((uint64_t)h << 32)); +} + +static inline void +lo_hi_writeq(uint64_t v, volatile void *addr) +{ + volatile uint32_t *p = addr; + + __io_bw(); + __raw_writel(htole32(v), p); + __raw_writel(htole32(v >> 32), p + 1); + __io_aw(); +} + +#ifndef readq +#define readq(addr) lo_hi_readq(addr) +#endif + +#ifndef writeq +#define writeq(v, addr) lo_hi_writeq(v, addr) +#endif + +#endif /* _LINUXKPI_LINUX_IO_64_NONATOMIC_LO_HI_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/io-mapping.h b/sys/compat/linuxkpi/common/include/linux/io-mapping.h index 5c24f1ff8659..f5f2fbc5c2cb 100644 --- a/sys/compat/linuxkpi/common/include/linux/io-mapping.h +++ b/sys/compat/linuxkpi/common/include/linux/io-mapping.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_IO_MAPPING_H_ @@ -37,6 +35,7 @@ #include <linux/types.h> #include <linux/io.h> +#include <linux/mm.h> #include <linux/slab.h> struct io_mapping { @@ -93,6 +92,18 @@ io_mapping_unmap_atomic(void *vaddr) } static inline void * +io_mapping_map_local_wc(struct io_mapping *mapping, unsigned long offset) +{ + + return (io_mapping_map_atomic_wc(mapping, offset)); +} + +static inline void +io_mapping_unmap_local(void *vaddr __unused) +{ +} + +static inline void * io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset, unsigned long size) { @@ -100,6 +111,17 @@ io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset, return ((char *)mapping->mem + offset); } +int lkpi_io_mapping_map_user(struct io_mapping *iomap, + struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, + unsigned long size); + +static inline int +io_mapping_map_user(struct io_mapping *iomap, struct vm_area_struct *vma, + unsigned long addr, unsigned long pfn, unsigned long size) +{ + return (lkpi_io_mapping_map_user(iomap, vma, addr, pfn, size)); +} + static inline void io_mapping_unmap(void *vaddr) { diff --git a/sys/compat/linuxkpi/common/include/linux/io.h b/sys/compat/linuxkpi/common/include/linux/io.h index e12f9b36a9a1..bce70ed0cb8d 100644 --- a/sys/compat/linuxkpi/common/include/linux/io.h +++ b/sys/compat/linuxkpi/common/include/linux/io.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_IO_H_ #define _LINUXKPI_LINUX_IO_H_ @@ -37,6 +35,7 @@ #include <machine/vm.h> #include <linux/compiler.h> +#include <linux/err.h> #include <linux/types.h> #if !defined(__arm__) #include <asm/set_memory.h> @@ -351,6 +350,16 @@ ioread32be(const volatile void *addr) } #define ioread32be(addr) ioread32be(addr) +#ifdef __LP64__ +#undef ioread64 +static inline uint64_t +ioread64(const volatile void *addr) +{ + return (readq(addr)); +} +#define ioread64(addr) ioread64(addr) +#endif + #undef iowrite8 static inline void iowrite8(uint8_t v, volatile void *addr) @@ -403,6 +412,13 @@ _ioremap_attr(vm_paddr_t _phys_addr, unsigned long _size, int _attr) } #endif +struct device; +static inline void * +devm_ioremap(struct device *dev, resource_size_t offset, resource_size_t size) +{ + return (NULL); +} + #ifdef VM_MEMATTR_DEVICE #define ioremap_nocache(addr, size) \ _ioremap_attr((addr), (size), VM_MEMATTR_DEVICE) @@ -424,7 +440,7 @@ _ioremap_attr(vm_paddr_t _phys_addr, unsigned long _size, int _attr) #else #define ioremap_wc(addr, size) ioremap_nocache(addr, size) #endif -#define ioremap_wb(addr, size) \ +#define ioremap_cache(addr, size) \ _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_BACK) void iounmap(void *addr); @@ -433,9 +449,9 @@ void iounmap(void *addr); #define memcpy_toio(a, b, c) memcpy((a), (b), (c)) static inline void -__iowrite32_copy(void *to, void *from, size_t count) +__iowrite32_copy(void *to, const void *from, size_t count) { - uint32_t *src; + const uint32_t *src; uint32_t *dst; int i; @@ -444,10 +460,10 @@ __iowrite32_copy(void *to, void *from, size_t count) } static inline void -__iowrite64_copy(void *to, void *from, size_t count) +__iowrite64_copy(void *to, const void *from, size_t count) { #ifdef __LP64__ - uint64_t *src; + const uint64_t *src; uint64_t *dst; int i; @@ -458,6 +474,32 @@ __iowrite64_copy(void *to, void *from, size_t count) #endif } +static inline void +__ioread32_copy(void *to, const void *from, size_t count) +{ + const uint32_t *src; + uint32_t *dst; + int i; + + for (i = 0, src = from, dst = to; i < count; i++, src++, dst++) + *dst = __raw_readl(src); +} + +static inline void +__ioread64_copy(void *to, const void *from, size_t count) +{ +#ifdef __LP64__ + const uint64_t *src; + uint64_t *dst; + int i; + + for (i = 0, src = from, dst = to; i < count; i++, src++, dst++) + *dst = __raw_readq(src); +#else + __ioread32_copy(to, from, count * 2); +#endif +} + enum { MEMREMAP_WB = 1 << 0, MEMREMAP_WT = 1 << 1, @@ -470,7 +512,7 @@ memremap(resource_size_t offset, size_t size, unsigned long flags) void *addr = NULL; if ((flags & MEMREMAP_WB) && - (addr = ioremap_wb(offset, size)) != NULL) + (addr = ioremap_cache(offset, size)) != NULL) goto done; if ((flags & MEMREMAP_WT) && (addr = ioremap_wt(offset, size)) != NULL) @@ -489,6 +531,8 @@ memunmap(void *addr) iounmap(addr); } +#define IOMEM_ERR_PTR(err) (void __iomem *)ERR_PTR(err) + #define __MTRR_ID_BASE 1 int lkpi_arch_phys_wc_add(unsigned long, unsigned long); void lkpi_arch_phys_wc_del(int); @@ -501,14 +545,25 @@ void lkpi_arch_phys_wc_del(int); static inline int arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size) { + vm_offset_t va; - return (set_memory_wc(start, size >> PAGE_SHIFT)); + va = PHYS_TO_DMAP(start); + +#ifdef VM_MEMATTR_WRITE_COMBINING + return (-pmap_change_attr(va, size, VM_MEMATTR_WRITE_COMBINING)); +#else + return (-pmap_change_attr(va, size, VM_MEMATTR_UNCACHEABLE)); +#endif } static inline void arch_io_free_memtype_wc(resource_size_t start, resource_size_t size) { - set_memory_wb(start, size >> PAGE_SHIFT); + vm_offset_t va; + + va = PHYS_TO_DMAP(start); + + pmap_change_attr(va, size, VM_MEMATTR_WRITE_BACK); } #endif diff --git a/sys/compat/linuxkpi/common/include/linux/ioctl.h b/sys/compat/linuxkpi/common/include/linux/ioctl.h index b1b5443fa150..77c01224e6a5 100644 --- a/sys/compat/linuxkpi/common/include/linux/ioctl.h +++ b/sys/compat/linuxkpi/common/include/linux/ioctl.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_IOCTL_H_ #define _LINUXKPI_LINUX_IOCTL_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/iommu.h b/sys/compat/linuxkpi/common/include/linux/iommu.h new file mode 100644 index 000000000000..391d9778a0c8 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/iommu.h @@ -0,0 +1,29 @@ +/* Public domain. */ + +#ifndef _LINUXKPI_LINUX_IOMMU_H_ +#define _LINUXKPI_LINUX_IOMMU_H_ + +#include <linux/device.h> + +#define __IOMMU_DOMAIN_PAGING (1U << 0) +#define __IOMMU_DOMAIN_DMA_API (1U << 1) +#define __IOMMU_DOMAIN_PT (1U << 2) +#define __IOMMU_DOMAIN_DMA_FQ (1U << 3) + +#define IOMMU_DOMAIN_BLOCKED (0U) +#define IOMMU_DOMAIN_IDENTITY (__IOMMU_DOMAIN_PT) +#define IOMMU_DOMAIN_UNMANAGED (__IOMMU_DOMAIN_PAGING) +#define IOMMU_DOMAIN_DMA (__IOMMU_DOMAIN_PAGING | __IOMMU_DOMAIN_DMA_API) +#define IOMMU_DOMAIN_DMA_FQ (__IOMMU_DOMAIN_PAGING | __IOMMU_DOMAIN_DMA_API | __IOMMU_DOMAIN_DMA_FQ) + +struct iommu_domain { + unsigned int type; +}; + +static inline struct iommu_domain * +iommu_get_domain_for_dev(struct device *dev __unused) +{ + return (NULL); +} + +#endif /* _LINUXKPI_LINUX_IOMMU_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/iopoll.h b/sys/compat/linuxkpi/common/include/linux/iopoll.h index 478d875c846c..8d0498a26da1 100644 --- a/sys/compat/linuxkpi/common/include/linux/iopoll.h +++ b/sys/compat/linuxkpi/common/include/linux/iopoll.h @@ -23,8 +23,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_IOPOLL_H diff --git a/sys/compat/linuxkpi/common/include/linux/ioport.h b/sys/compat/linuxkpi/common/include/linux/ioport.h new file mode 100644 index 000000000000..444f3ad94602 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/ioport.h @@ -0,0 +1,57 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2023 Serenity Cyber Security, LLC. + * + * 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_IOPORT_H +#define _LINUXKPI_LINUX_IOPORT_H + +#include <linux/compiler.h> +#include <linux/types.h> + +#define DEFINE_RES_MEM(_start, _size) \ + (struct resource) { \ + .start = (_start), \ + .end = (_start) + (_size) - 1, \ + } + +struct resource { + resource_size_t start; + resource_size_t end; +}; + +static inline resource_size_t +resource_size(const struct resource *r) +{ + return (r->end - r->start + 1); +} + +static inline bool +resource_contains(struct resource *a, struct resource *b) +{ + return (a->start <= b->start && a->end >= b->end); +} + +#endif diff --git a/sys/compat/linuxkpi/common/include/linux/iosys-map.h b/sys/compat/linuxkpi/common/include/linux/iosys-map.h new file mode 100644 index 000000000000..66c442b8668f --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/iosys-map.h @@ -0,0 +1,161 @@ +/* Public domain. */ + +#ifndef _LINUXKPI_LINUX_IOSYS_MAP_H +#define _LINUXKPI_LINUX_IOSYS_MAP_H + +#include <linux/io.h> +#include <linux/string.h> + +struct iosys_map { + union { + void *vaddr_iomem; + void *vaddr; + }; + bool is_iomem; +#ifdef __OpenBSD__ + bus_space_handle_t bsh; + bus_size_t size; +#endif +}; + +#define IOSYS_MAP_INIT_OFFSET(_ism_src_p, _off) ({ \ + struct iosys_map ism_dst = *(_ism_src_p); \ + iosys_map_incr(&ism_dst, _off); \ + ism_dst; \ +}) + +static inline void +iosys_map_incr(struct iosys_map *ism, size_t n) +{ + if (ism->is_iomem) + ism->vaddr_iomem += n; + else + ism->vaddr += n; +} + +static inline void +iosys_map_memcpy_to(struct iosys_map *ism, size_t off, const void *src, + size_t len) +{ + if (ism->is_iomem) + memcpy_toio(ism->vaddr_iomem + off, src, len); + else + memcpy(ism->vaddr + off, src, len); +} + +static inline bool +iosys_map_is_null(const struct iosys_map *ism) +{ + if (ism->is_iomem) + return (ism->vaddr_iomem == NULL); + else + return (ism->vaddr == NULL); +} + +static inline bool +iosys_map_is_set(const struct iosys_map *ism) +{ + if (ism->is_iomem) + return (ism->vaddr_iomem != NULL); + else + return (ism->vaddr != NULL); +} + +static inline bool +iosys_map_is_equal(const struct iosys_map *ism_a, + const struct iosys_map *ism_b) +{ + if (ism_a->is_iomem != ism_b->is_iomem) + return (false); + + if (ism_a->is_iomem) + return (ism_a->vaddr_iomem == ism_b->vaddr_iomem); + else + return (ism_a->vaddr == ism_b->vaddr); +} + +static inline void +iosys_map_clear(struct iosys_map *ism) +{ + if (ism->is_iomem) { + ism->vaddr_iomem = NULL; + ism->is_iomem = false; + } else { + ism->vaddr = NULL; + } +} + +static inline void +iosys_map_set_vaddr_iomem(struct iosys_map *ism, void *addr) +{ + ism->vaddr_iomem = addr; + ism->is_iomem = true; +} + +static inline void +iosys_map_set_vaddr(struct iosys_map *ism, void *addr) +{ + ism->vaddr = addr; + ism->is_iomem = false; +} + +static inline void +iosys_map_memset(struct iosys_map *ism, size_t off, int value, size_t len) +{ + if (ism->is_iomem) + memset_io(ism->vaddr_iomem + off, value, len); + else + memset(ism->vaddr + off, value, len); +} + +#ifdef __LP64__ +#define _iosys_map_readq(_addr) readq(_addr) +#define _iosys_map_writeq(_val, _addr) writeq(_val, _addr) +#else +#define _iosys_map_readq(_addr) ({ \ + uint64_t val; \ + memcpy_fromio(&val, _addr, sizeof(uint64_t)); \ + val; \ +}) +#define _iosys_map_writeq(_val, _addr) \ + memcpy_toio(_addr, &(_val), sizeof(uint64_t)) +#endif + +#define iosys_map_rd(_ism, _off, _type) ({ \ + _type val; \ + if ((_ism)->is_iomem) { \ + void *addr = (_ism)->vaddr_iomem + (_off); \ + val = _Generic(val, \ + uint8_t : readb(addr), \ + uint16_t: readw(addr), \ + uint32_t: readl(addr), \ + uint64_t: _iosys_map_readq(addr)); \ + } else \ + val = READ_ONCE(*(_type *)((_ism)->vaddr + (_off))); \ + val; \ +}) +#define iosys_map_wr(_ism, _off, _type, _val) ({ \ + _type val = (_val); \ + if ((_ism)->is_iomem) { \ + void *addr = (_ism)->vaddr_iomem + (_off); \ + _Generic(val, \ + uint8_t : writeb(val, addr), \ + uint16_t: writew(val, addr), \ + uint32_t: writel(val, addr), \ + uint64_t: _iosys_map_writeq(val, addr)); \ + } else \ + WRITE_ONCE(*(_type *)((_ism)->vaddr + (_off)), val); \ +}) + +#define iosys_map_rd_field(_ism, _off, _type, _field) ({ \ + _type *s; \ + iosys_map_rd(_ism, (_off) + offsetof(_type, _field), \ + __typeof(s->_field)); \ +}) +#define iosys_map_wr_field(_ism, _off, _type, _field, _val) ({ \ + _type *s; \ + iosys_map_wr(_ism, (_off) + offsetof(_type, _field), \ + __typeof(s->_field), _val); \ +}) + +#endif diff --git a/sys/compat/linuxkpi/common/include/linux/ip.h b/sys/compat/linuxkpi/common/include/linux/ip.h index 11f4aed180d1..137cf89e7dcb 100644 --- a/sys/compat/linuxkpi/common/include/linux/ip.h +++ b/sys/compat/linuxkpi/common/include/linux/ip.h @@ -26,8 +26,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_IP_H diff --git a/sys/compat/linuxkpi/common/include/linux/irq_work.h b/sys/compat/linuxkpi/common/include/linux/irq_work.h index ec71a7ee094f..7c4019bc0242 100644 --- a/sys/compat/linuxkpi/common/include/linux/irq_work.h +++ b/sys/compat/linuxkpi/common/include/linux/irq_work.h @@ -24,8 +24,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_IRQ_WORK_H_ @@ -51,7 +49,12 @@ typedef void (*irq_work_func_t)(struct irq_work *); struct irq_work { struct task irq_task; - struct llist_node llnode; + union { + struct llist_node llnode; + struct { + struct llist_node llist; + } node; + }; irq_work_func_t func; }; diff --git a/sys/compat/linuxkpi/common/include/linux/irqdomain.h b/sys/compat/linuxkpi/common/include/linux/irqdomain.h new file mode 100644 index 000000000000..c7788e51cc89 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/irqdomain.h @@ -0,0 +1,10 @@ +/* Public domain. */ + +#ifndef _LINUXKPI_LINUX_IRQDOMAIN_H +#define _LINUXKPI_LINUX_IRQDOMAIN_H + +#include <linux/mutex.h> +#include <linux/of.h> +#include <linux/radix-tree.h> + +#endif diff --git a/sys/compat/linuxkpi/common/include/linux/irqreturn.h b/sys/compat/linuxkpi/common/include/linux/irqreturn.h index 8fbb0217573d..ff2618449d5e 100644 --- a/sys/compat/linuxkpi/common/include/linux/irqreturn.h +++ b/sys/compat/linuxkpi/common/include/linux/irqreturn.h @@ -22,8 +22,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_IRQRETURN_H diff --git a/sys/compat/linuxkpi/common/include/linux/jhash.h b/sys/compat/linuxkpi/common/include/linux/jhash.h index 1bab37f22b5d..25e2c04f1965 100644 --- a/sys/compat/linuxkpi/common/include/linux/jhash.h +++ b/sys/compat/linuxkpi/common/include/linux/jhash.h @@ -20,8 +20,6 @@ * * I've modified Bob's hash to be useful in the Linux kernel, and * any bugs present are surely my fault. -DaveM - * - * $FreeBSD$ */ /* NOTE: Arguments are modified. */ diff --git a/sys/compat/linuxkpi/common/include/linux/jiffies.h b/sys/compat/linuxkpi/common/include/linux/jiffies.h index 76c9c6a749c1..d5cb6e14860e 100644 --- a/sys/compat/linuxkpi/common/include/linux/jiffies.h +++ b/sys/compat/linuxkpi/common/include/linux/jiffies.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_JIFFIES_H_ #define _LINUXKPI_LINUX_JIFFIES_H_ @@ -40,7 +38,7 @@ #define jiffies ticks #define jiffies_64 ticks -#define jiffies_to_msecs(x) (((int64_t)(int)(x)) * 1000 / hz) +#define jiffies_to_msecs(x) ((unsigned int)(((int64_t)(int)(x)) * 1000 / hz)) #define MAX_JIFFY_OFFSET ((INT_MAX >> 1) - 1) diff --git a/sys/compat/linuxkpi/common/include/linux/kconfig.h b/sys/compat/linuxkpi/common/include/linux/kconfig.h new file mode 100644 index 000000000000..c1d186b56e1f --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/kconfig.h @@ -0,0 +1,76 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 The FreeBSD Foundation + * + * This software was developed by Björn Zeeb 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_KCONFIG_H_ +#define _LINUXKPI_LINUX_KCONFIG_H_ + +/* + * Checking if an option is defined would be easy if we could do CPP inside CPP. + * The defined case whether -Dxxx or -Dxxx=1 are easy to deal with. In either + * case the defined value is "1". A more general -Dxxx=<c> case will require + * more effort to deal with all possible "true" values. Hope we do not have + * to do this as well. + * The real problem is the undefined case. To avoid this problem we do the + * concat/varargs trick: "yyy" ## xxx can make two arguments if xxx is "1" + * by having a #define for yyy_1 which is "ignore,". + * Otherwise we will just get "yyy". + * Need to be careful about variable substitutions in macros though. + * This way we make a (true, false) problem a (don't care, true, false) or a + * (don't care true, false). Then we can use a variadic macro to only select + * the always well known and defined argument #2. And that seems to be + * exactly what we need. Use 1 for true and 0 for false to also allow + * #if IS_*() checks pre-compiler checks which do not like #if true. + */ +#define ___XAB_1 dontcare, +#define ___IS_XAB(_ignore, _x, ...) (_x) +#define __IS_XAB(_x) ___IS_XAB(_x 1, 0) +#define _IS_XAB(_x) __IS_XAB(__CONCAT(___XAB_, _x)) + +/* This is if CONFIG_ccc=y. */ +#define IS_BUILTIN(_x) _IS_XAB(_x) +/* This is if CONFIG_ccc=m. */ +#define IS_MODULE(_x) _IS_XAB(_x ## _MODULE) +/* This is if CONFIG_ccc is compiled in(=y) or a module(=m). */ +#define IS_ENABLED(_x) (IS_BUILTIN(_x) || IS_MODULE(_x)) +/* + * This is weird case. If the CONFIG_ccc is builtin (=y) this returns true; + * or if the CONFIG_ccc is a module (=m) and the caller is built as a module + * (-DMODULE defined) this returns true, but if the callers is not a module + * (-DMODULE not defined, which means caller is BUILTIN) then it returns + * false. In other words, a module can reach the kernel, a module can reach + * a module, but the kernel cannot reach a module, and code never compiled + * cannot be reached either. + * XXX -- I'd hope the module-to-module case would be handled by a proper + * module dependency definition (MODULE_DEPEND() in FreeBSD). + */ +#define IS_REACHABLE(_x) (IS_BUILTIN(_x) || \ + (IS_MODULE(_x) && IS_BUILTIN(MODULE))) + +#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 f2a5b53effec..988dd771254a 100644 --- a/sys/compat/linuxkpi/common/include/linux/kdev_t.h +++ b/sys/compat/linuxkpi/common/include/linux/kdev_t.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_KDEV_T_H_ #define _LINUXKPI_LINUX_KDEV_T_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/kernel.h b/sys/compat/linuxkpi/common/include/linux/kernel.h index 4987c582f0f3..ed4320e80fa7 100644 --- a/sys/compat/linuxkpi/common/include/linux/kernel.h +++ b/sys/compat/linuxkpi/common/include/linux/kernel.h @@ -26,13 +26,10 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_KERNEL_H_ #define _LINUXKPI_LINUX_KERNEL_H_ -#include <sys/cdefs.h> #include <sys/types.h> #include <sys/systm.h> #include <sys/param.h> @@ -44,18 +41,25 @@ #include <sys/time.h> #include <linux/bitops.h> +#include <linux/build_bug.h> #include <linux/compiler.h> +#include <linux/container_of.h> +#include <linux/limits.h> #include <linux/stringify.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/types.h> +#include <linux/typecheck.h> #include <linux/jiffies.h> #include <linux/log2.h> +#include <linux/kconfig.h> #include <asm/byteorder.h> +#include <asm/cpufeature.h> +#include <asm/processor.h> #include <asm/uaccess.h> -#include <machine/stdarg.h> +#include <linux/stdarg.h> #define KERN_CONT "" #define KERN_EMERG "<0>" @@ -67,19 +71,6 @@ #define KERN_INFO "<6>" #define KERN_DEBUG "<7>" -#define U8_MAX ((u8)~0U) -#define S8_MAX ((s8)(U8_MAX >> 1)) -#define S8_MIN ((s8)(-S8_MAX - 1)) -#define U16_MAX ((u16)~0U) -#define S16_MAX ((s16)(U16_MAX >> 1)) -#define S16_MIN ((s16)(-S16_MAX - 1)) -#define U32_MAX ((u32)~0U) -#define S32_MAX ((s32)(U32_MAX >> 1)) -#define S32_MIN ((s32)(-S32_MAX - 1)) -#define U64_MAX ((u64)~0ULL) -#define S64_MAX ((s64)(U64_MAX >> 1)) -#define S64_MIN ((s64)(-S64_MAX - 1)) - #define S8_C(x) x #define U8_C(x) x ## U #define S16_C(x) x @@ -89,28 +80,6 @@ #define S64_C(x) x ## LL #define U64_C(x) x ## ULL -/* - * BUILD_BUG_ON() can happen inside functions where _Static_assert() does not - * seem to work. Use old-schoold-ish CTASSERT from before commit - * a3085588a88fa58eb5b1eaae471999e1995a29cf but also make sure we do not - * end up with an unused typedef or variable. The compiler should optimise - * it away entirely. - */ -#define _O_CTASSERT(x) _O__CTASSERT(x, __LINE__) -#define _O__CTASSERT(x, y) _O___CTASSERT(x, y) -#define _O___CTASSERT(x, y) while (0) { \ - typedef char __assert_line_ ## y[(x) ? 1 : -1]; \ - __assert_line_ ## y _x; \ - _x[0] = '\0'; \ -} - -#define BUILD_BUG() do { CTASSERT(0); } while (0) -#define BUILD_BUG_ON(x) do { _O_CTASSERT(!(x)) } while (0) -#define BUILD_BUG_ON_MSG(x, msg) BUILD_BUG_ON(x) -#define BUILD_BUG_ON_NOT_POWER_OF_2(x) BUILD_BUG_ON(!powerof2(x)) -#define BUILD_BUG_ON_INVALID(expr) while (0) { (void)(expr); } -#define BUILD_BUG_ON_ZERO(x) ((int)sizeof(struct { int:-((x) != 0); })) - #define BUG() panic("BUG at %s:%d", __FILE__, __LINE__) #define BUG_ON(cond) do { \ if (cond) { \ @@ -163,6 +132,8 @@ extern int linuxkpi_warn_dump_stack; #define printk(...) printf(__VA_ARGS__) #define vprintk(f, a) vprintf(f, a) +#define PTR_IF(x, p) ((x) ? (p) : NULL) + #define asm __asm extern void linux_dump_stack(void); @@ -293,12 +264,6 @@ extern int linuxkpi_debug; }) #endif -#define container_of(ptr, type, member) \ -({ \ - const __typeof(((type *)0)->member) *__p = (ptr); \ - (type *)((uintptr_t)__p - offsetof(type, member)); \ -}) - #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define u64_to_user_ptr(val) ((void *)(uintptr_t)(val)) @@ -434,19 +399,8 @@ kstrtou16(const char *cp, unsigned int base, u16 *res) static inline int kstrtou32(const char *cp, unsigned int base, u32 *res) { - char *end; - unsigned long temp; - *res = temp = strtoul(cp, &end, base); - - /* skip newline character, if any */ - if (*end == '\n') - end++; - if (*cp == 0 || *end != 0) - return (-EINVAL); - if (temp != (u32)temp) - return (-ERANGE); - return (0); + return (kstrtouint(cp, base, res)); } static inline int @@ -527,7 +481,7 @@ kstrtoint_from_user(const char __user *s, size_t count, unsigned int base, static inline int kstrtouint_from_user(const char __user *s, size_t count, unsigned int base, - int *p) + unsigned int *p) { char buf[36] = {}; @@ -541,6 +495,14 @@ kstrtouint_from_user(const char __user *s, size_t count, unsigned int base, } 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)); +} + +static inline int kstrtou8_from_user(const char __user *s, size_t count, unsigned int base, u8 *p) { @@ -622,12 +584,6 @@ mult_frac(uintmax_t x, uintmax_t multiplier, uintmax_t divisor) return ((q * multiplier) + ((r * multiplier) / divisor)); } -static inline int64_t -abs64(int64_t x) -{ - return (x < 0 ? -x : x); -} - typedef struct linux_ratelimit { struct timeval lasttime; int counter; @@ -639,12 +595,6 @@ linux_ratelimited(linux_ratelimit_t *rl) return (ppsratecheck(&rl->lasttime, &rl->counter, 1)); } -#define struct_size(ptr, field, num) ({ \ - const size_t __size = offsetof(__typeof(*(ptr)), field); \ - const size_t __max = (SIZE_MAX - __size) / sizeof((ptr)->field[0]); \ - ((num) > __max) ? SIZE_MAX : (__size + sizeof((ptr)->field[0]) * (num)); \ -}) - #define __is_constexpr(x) \ __builtin_constant_p(x) @@ -654,31 +604,10 @@ linux_ratelimited(linux_ratelimit_t *rl) */ #define is_signed(datatype) (((datatype)-1 / (datatype)2) == (datatype)0) -/* - * The type_max() macro below returns the maxium positive value the - * passed data type can hold. - */ -#define type_max(datatype) ( \ - (sizeof(datatype) >= 8) ? (is_signed(datatype) ? INT64_MAX : UINT64_MAX) : \ - (sizeof(datatype) >= 4) ? (is_signed(datatype) ? INT32_MAX : UINT32_MAX) : \ - (sizeof(datatype) >= 2) ? (is_signed(datatype) ? INT16_MAX : UINT16_MAX) : \ - (is_signed(datatype) ? INT8_MAX : UINT8_MAX) \ -) - -/* - * The type_min() macro below returns the minimum value the passed - * data type can hold. For unsigned types the minimum value is always - * zero. For signed types it may vary. - */ -#define type_min(datatype) ( \ - (sizeof(datatype) >= 8) ? (is_signed(datatype) ? INT64_MIN : 0) : \ - (sizeof(datatype) >= 4) ? (is_signed(datatype) ? INT32_MIN : 0) : \ - (sizeof(datatype) >= 2) ? (is_signed(datatype) ? INT16_MIN : 0) : \ - (is_signed(datatype) ? INT8_MIN : 0) \ -) - #define TAINT_WARN 0 #define test_taint(x) (0) +#define add_taint(x,y) do { \ + } while (0) static inline int _h2b(const char c) @@ -711,49 +640,49 @@ hex2bin(uint8_t *bindst, const char *hexsrc, size_t binlen) return (0); } +static inline bool +mac_pton(const char *macin, uint8_t *macout) +{ + const char *s, *d; + uint8_t mac[6], hx, lx;; + int i; + + if (strlen(macin) < (3 * 6 - 1)) + return (false); + + i = 0; + s = macin; + do { + /* Should we also support '-'-delimiters? */ + d = strchrnul(s, ':'); + hx = lx = 0; + while (s < d) { + /* Fail on abc:123:xxx:... */ + if ((d - s) > 2) + return (false); + /* We do support non-well-formed strings: 3:45:6:... */ + if ((d - s) > 1) { + hx = _h2b(*s); + if (hx < 0) + return (false); + s++; + } + lx = _h2b(*s); + if (lx < 0) + return (false); + s++; + } + mac[i] = (hx << 4) | lx; + i++; + if (i >= 6) + return (false); + } while (d != NULL && *d != '\0'); + + memcpy(macout, mac, 6); + return (true); +} + #define DECLARE_FLEX_ARRAY(_t, _n) \ struct { struct { } __dummy_ ## _n; _t _n[0]; } -/* - * Checking if an option is defined would be easy if we could do CPP inside CPP. - * The defined case whether -Dxxx or -Dxxx=1 are easy to deal with. In either - * case the defined value is "1". A more general -Dxxx=<c> case will require - * more effort to deal with all possible "true" values. Hope we do not have - * to do this as well. - * The real problem is the undefined case. To avoid this problem we do the - * concat/varargs trick: "yyy" ## xxx can make two arguments if xxx is "1" - * by having a #define for yyy_1 which is "ignore,". - * Otherwise we will just get "yyy". - * Need to be careful about variable substitutions in macros though. - * This way we make a (true, false) problem a (don't care, true, false) or a - * (don't care true, false). Then we can use a variadic macro to only select - * the always well known and defined argument #2. And that seems to be - * exactly what we need. Use 1 for true and 0 for false to also allow - * #if IS_*() checks pre-compiler checks which do not like #if true. - */ -#define ___XAB_1 dontcare, -#define ___IS_XAB(_ignore, _x, ...) (_x) -#define __IS_XAB(_x) ___IS_XAB(_x 1, 0) -#define _IS_XAB(_x) __IS_XAB(__CONCAT(___XAB_, _x)) - -/* This is if CONFIG_ccc=y. */ -#define IS_BUILTIN(_x) _IS_XAB(_x) -/* This is if CONFIG_ccc=m. */ -#define IS_MODULE(_x) _IS_XAB(_x ## _MODULE) -/* This is if CONFIG_ccc is compiled in(=y) or a module(=m). */ -#define IS_ENABLED(_x) (IS_BUILTIN(_x) || IS_MODULE(_x)) -/* - * This is weird case. If the CONFIG_ccc is builtin (=y) this returns true; - * or if the CONFIG_ccc is a module (=m) and the caller is built as a module - * (-DMODULE defined) this returns true, but if the callers is not a module - * (-DMODULE not defined, which means caller is BUILTIN) then it returns - * false. In other words, a module can reach the kernel, a module can reach - * a module, but the kernel cannot reach a module, and code never compiled - * cannot be reached either. - * XXX -- I'd hope the module-to-module case would be handled by a proper - * module dependency definition (MODULE_DEPEND() in FreeBSD). - */ -#define IS_REACHABLE(_x) (IS_BUILTIN(_x) || \ - (IS_MODULE(_x) && IS_BUILTIN(MODULE))) - #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 6ba1528d965c..d2f570781661 100644 --- a/sys/compat/linuxkpi/common/include/linux/kfifo.h +++ b/sys/compat/linuxkpi/common/include/linux/kfifo.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG + * Copyright (c) 2022 Bjoern A. Zeeb * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,7 +28,95 @@ #ifndef _LINUXKPI_LINUX_KFIFO_H_ #define _LINUXKPI_LINUX_KFIFO_H_ +#include <sys/types.h> + +#include <linux/slab.h> +#include <linux/gfp.h> + #define INIT_KFIFO(x) 0 #define DECLARE_KFIFO(x, y, z) +#define DECLARE_KFIFO_PTR(_name, _type) \ + struct kfifo_ ## _name { \ + size_t total; \ + size_t count; \ + size_t first; \ + size_t last; \ + _type *head; \ + } _name + +#define kfifo_len(_kf) \ +({ \ + (_kf)->count; \ +}) + +#define kfifo_is_empty(_kf) \ +({ \ + ((_kf)->count == 0) ? true : false; \ +}) + +#define kfifo_is_full(_kf) \ +({ \ + ((_kf)->count == (_kf)->total) ? true : false; \ +}) + +#define kfifo_put(_kf, _e) \ +({ \ + bool _rc; \ + \ + /* Would overflow. */ \ + if (kfifo_is_full(_kf)) { \ + _rc = false; \ + } else { \ + (_kf)->head[(_kf)->last] = (_e); \ + (_kf)->count++; \ + (_kf)->last++; \ + if ((_kf)->last > (_kf)->total) \ + (_kf)->last = 0; \ + _rc = true; \ + } \ + \ + _rc; \ +}) + +#define kfifo_get(_kf, _e) \ +({ \ + bool _rc; \ + \ + if (kfifo_is_empty(_kf)) { \ + _rc = false; \ + } else { \ + *(_e) = (_kf)->head[(_kf)->first]; \ + (_kf)->count--; \ + (_kf)->first++; \ + if ((_kf)->first > (_kf)->total) \ + (_kf)->first = 0; \ + _rc = true; \ + } \ + \ + _rc; \ +}) + +#define kfifo_alloc(_kf, _s, _gfp) \ +({ \ + int _error; \ + \ + (_kf)->head = kmalloc(sizeof(__typeof(*(_kf)->head)) * (_s), _gfp); \ + if ((_kf)->head == NULL) \ + _error = ENOMEM; \ + else { \ + (_kf)->total = (_s); \ + _error = 0; \ + } \ + \ + _error; \ +}) + +#define kfifo_free(_kf) \ +({ \ + kfree((_kf)->head); \ + (_kf)->head = NULL; \ + (_kf)->total = (_kf)->count = (_kf)->first = (_kf)->last = 0; \ +}) + #endif /* _LINUXKPI_LINUX_KFIFO_H_*/ diff --git a/sys/compat/linuxkpi/common/include/linux/kmod.h b/sys/compat/linuxkpi/common/include/linux/kmod.h index b8e8a483210f..b3cbe2ed2e02 100644 --- a/sys/compat/linuxkpi/common/include/linux/kmod.h +++ b/sys/compat/linuxkpi/common/include/linux/kmod.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_KMOD_H_ #define _LINUXKPI_LINUX_KMOD_H_ @@ -41,9 +39,8 @@ #define request_module(...) \ ({\ char modname[128]; \ - int fileid; \ snprintf(modname, sizeof(modname), __VA_ARGS__); \ - kern_kldload(curthread, modname, &fileid); \ + kern_kldload(curthread, modname, NULL); \ }) #define request_module_nowait request_module diff --git a/sys/compat/linuxkpi/common/include/linux/kobject.h b/sys/compat/linuxkpi/common/include/linux/kobject.h index ad25058028fc..512f47f9e4b4 100644 --- a/sys/compat/linuxkpi/common/include/linux/kobject.h +++ b/sys/compat/linuxkpi/common/include/linux/kobject.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_KOBJECT_H_ #define _LINUXKPI_LINUX_KOBJECT_H_ @@ -37,8 +35,12 @@ #include <linux/kref.h> #include <linux/list.h> #include <linux/slab.h> +#include <linux/spinlock.h> +#include <linux/wait.h> +#include <linux/workqueue.h> struct kobject; +struct kset; struct sysctl_oid; #define KOBJ_CHANGE 0x01 @@ -47,6 +49,7 @@ struct kobj_type { void (*release)(struct kobject *kobj); const struct sysfs_ops *sysfs_ops; struct attribute **default_attrs; + const struct attribute_group **default_groups; }; extern const struct kobj_type linux_kfree_type; @@ -58,6 +61,7 @@ struct kobject { const struct kobj_type *ktype; struct list_head entry; struct sysctl_oid *oidp; + struct kset *kset; }; extern struct kobject *mm_kobj; @@ -78,6 +82,17 @@ struct kobj_attribute { const char *buf, size_t count); }; +struct kset_uevent_ops { + /* TODO */ +}; + +struct kset { + struct list_head list; + spinlock_t list_lock; + struct kobject kobj; + const struct kset_uevent_ops *uevent_ops; +}; + static inline void kobject_init(struct kobject *kobj, const struct kobj_type *ktype) { @@ -155,4 +170,41 @@ kobject_uevent_env(struct kobject *kobj, int action, char *envp[]) */ } +void kset_init(struct kset *kset); +int kset_register(struct kset *kset); +void kset_unregister(struct kset *kset); +struct kset * kset_create_and_add(const char *name, + const struct kset_uevent_ops *u, struct kobject *parent_kobj); + +static inline struct kset * +to_kset(struct kobject *kobj) +{ + if (kobj != NULL) + return container_of(kobj, struct kset, kobj); + else + return NULL; +} + +static inline struct kset * +kset_get(struct kset *kset) +{ + if (kset != NULL) { + struct kobject *kobj; + + kobj = kobject_get(&kset->kobj); + return to_kset(kobj); + } else { + return NULL; + } +} + +static inline void +kset_put(struct kset *kset) +{ + if (kset != NULL) + kobject_put(&kset->kobj); +} + +void linux_kobject_kfree_name(struct kobject *kobj); + #endif /* _LINUXKPI_LINUX_KOBJECT_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/kref.h b/sys/compat/linuxkpi/common/include/linux/kref.h index 2c59794f4ddc..47d61c9ee316 100644 --- a/sys/compat/linuxkpi/common/include/linux/kref.h +++ b/sys/compat/linuxkpi/common/include/linux/kref.h @@ -26,8 +26,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_KREF_H_ #define _LINUXKPI_LINUX_KREF_H_ @@ -43,6 +41,7 @@ #include <asm/atomic.h> struct kref { + /* XXX In Linux this is a refcount_t */ atomic_t refcount; }; @@ -50,28 +49,28 @@ static inline void kref_init(struct kref *kref) { - refcount_init(&kref->refcount.counter, 1); + refcount_init((uint32_t *)&kref->refcount, 1); } static inline unsigned int kref_read(const struct kref *kref) { - return (atomic_read(&kref->refcount)); + return (refcount_load(__DECONST(u_int32_t *, &kref->refcount))); } static inline void kref_get(struct kref *kref) { - refcount_acquire(&kref->refcount.counter); + refcount_acquire((uint32_t *)&kref->refcount); } static inline int kref_put(struct kref *kref, void (*rel)(struct kref *kref)) { - if (refcount_release(&kref->refcount.counter)) { + if (refcount_release((uint32_t *)&kref->refcount)) { rel(kref); return 1; } @@ -83,7 +82,7 @@ kref_put_lock(struct kref *kref, void (*rel)(struct kref *kref), spinlock_t *lock) { - if (refcount_release(&kref->refcount.counter)) { + if (refcount_release((uint32_t *)&kref->refcount)) { spin_lock(lock); rel(kref); return (1); @@ -97,7 +96,7 @@ kref_sub(struct kref *kref, unsigned int count, { while (count--) { - if (refcount_release(&kref->refcount.counter)) { + if (refcount_release((uint32_t *)&kref->refcount)) { rel(kref); return 1; } @@ -109,16 +108,16 @@ static inline int __must_check kref_get_unless_zero(struct kref *kref) { - return atomic_add_unless(&kref->refcount, 1, 0); + return refcount_acquire_if_not_zero((uint32_t *)&kref->refcount); } static inline int kref_put_mutex(struct kref *kref, void (*release)(struct kref *kref), struct mutex *lock) { WARN_ON(release == NULL); - if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) { + if (unlikely(!refcount_release_if_not_last((uint32_t *)&kref->refcount))) { mutex_lock(lock); - if (unlikely(!atomic_dec_and_test(&kref->refcount))) { + if (unlikely(!refcount_release((uint32_t *)&kref->refcount))) { mutex_unlock(lock); return 0; } diff --git a/sys/compat/linuxkpi/common/include/linux/kthread.h b/sys/compat/linuxkpi/common/include/linux/kthread.h index 49309cd47a40..1fde734fd767 100644 --- a/sys/compat/linuxkpi/common/include/linux/kthread.h +++ b/sys/compat/linuxkpi/common/include/linux/kthread.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_KTHREAD_H_ #define _LINUXKPI_LINUX_KTHREAD_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/ktime.h b/sys/compat/linuxkpi/common/include/linux/ktime.h index e0722aa2589b..53c2abd64fc6 100644 --- a/sys/compat/linuxkpi/common/include/linux/ktime.h +++ b/sys/compat/linuxkpi/common/include/linux/ktime.h @@ -24,8 +24,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_KTIME_H @@ -71,6 +69,12 @@ ktime_to_ms(ktime_t kt) return (ktime_divns(kt, NSEC_PER_MSEC)); } +static inline ktime_t +ms_to_ktime(uint64_t ms) +{ + return (ms * NSEC_PER_MSEC); +} + static inline struct timeval ktime_to_timeval(ktime_t kt) { @@ -190,6 +194,7 @@ timespec64_to_ns(struct timespec64 *ts) #define ktime_get_ts(ts) getnanouptime(ts) #define ktime_get_ts64(ts) getnanouptime(ts) #define ktime_get_raw_ts64(ts) getnanouptime(ts) +#define ktime_get_real_ts64(ts) getnanotime(ts) #define getrawmonotonic64(ts) getnanouptime(ts) static inline int64_t @@ -263,4 +268,13 @@ ktime_get_raw_ns(void) return (ktime_to_ns(timespec_to_ktime(ts))); } +static inline uint64_t +ktime_get_raw_fast_ns(void) +{ + struct timespec ts; + + getnanouptime(&ts); + return (ktime_to_ns(timespec_to_ktime(ts))); +} + #endif /* _LINUXKPI_LINUX_KTIME_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/leds.h b/sys/compat/linuxkpi/common/include/linux/leds.h new file mode 100644 index 000000000000..f7ee7a68dcf5 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/leds.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2022 Bjoern A. Zeeb + * + * 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_LEDS_H +#define _LINUXKPI_LINUX_LEDS_H + +enum led_brightness { + __DUMMY, +}; + +struct led_classdev { + const char *name; + const char *default_trigger; + int (*blink_set)(struct led_classdev *, unsigned long *, unsigned long *); + void (*brightness_set)(struct led_classdev *, enum led_brightness); +}; + +#endif /* _LINUXKPI_LINUX_LEDS_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/limits.h b/sys/compat/linuxkpi/common/include/linux/limits.h new file mode 100644 index 000000000000..716366033bb3 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/limits.h @@ -0,0 +1,47 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2023 Serenity Cyber Security, LLC. + * + * 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_LIMITS_H +#define _LINUXKPI_LINUX_LIMITS_H + +#include <sys/types.h> +#include <sys/stdint.h> + +#define U8_MAX UINT8_MAX +#define S8_MAX INT8_MAX +#define S8_MIN INT8_MIN +#define U16_MAX UINT16_MAX +#define S16_MAX INT16_MAX +#define S16_MIN INT16_MIN +#define U32_MAX UINT32_MAX +#define S32_MAX INT32_MAX +#define S32_MIN INT32_MIN +#define U64_MAX UINT64_MAX +#define S64_MAX INT64_MAX +#define S64_MIN INT64_MIN + +#endif diff --git a/sys/compat/linuxkpi/common/include/linux/list.h b/sys/compat/linuxkpi/common/include/linux/list.h index 80ac57fecf6d..eecb517d780e 100644 --- a/sys/compat/linuxkpi/common/include/linux/list.h +++ b/sys/compat/linuxkpi/common/include/linux/list.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_LIST_H_ #define _LINUXKPI_LINUX_LIST_H_ @@ -86,14 +84,6 @@ #define LINUX_LIST_HEAD(name) \ struct list_head name = LINUX_LIST_HEAD_INIT(name) -#ifndef LIST_HEAD_DEF -#define LIST_HEAD_DEF -struct list_head { - struct list_head *next; - struct list_head *prev; -}; -#endif - static inline void INIT_LIST_HEAD(struct list_head *list) { @@ -154,7 +144,7 @@ list_replace_init(struct list_head *old, struct list_head *new) } static inline void -linux_list_add(struct list_head *new, struct list_head *prev, +__list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { @@ -235,6 +225,11 @@ list_del_init(struct list_head *entry) #define list_for_each_prev(p, h) for (p = (h)->prev; p != (h); p = (p)->prev) +#define list_for_each_prev_safe(p, n, h) \ + for (p = (h)->prev, n = (p)->prev; \ + p != (h); \ + p = n, n = (p)->prev) + #define list_for_each_entry_from_reverse(p, h, field) \ for (; &p->field != (h); \ p = list_prev_entry(p, field)) @@ -243,14 +238,14 @@ static inline void list_add(struct list_head *new, struct list_head *head) { - linux_list_add(new, head, head->next); + __list_add(new, head, head->next); } static inline void list_add_tail(struct list_head *new, struct list_head *head) { - linux_list_add(new, head->prev, head); + __list_add(new, head->prev, head); } static inline void @@ -474,6 +469,20 @@ static inline int list_is_last(const struct list_head *list, return list->next == head; } +static inline size_t +list_count_nodes(const struct list_head *list) +{ + const struct list_head *lh; + size_t count; + + count = 0; + list_for_each(lh, list) { + count++; + } + + return (count); +} + #define hlist_entry(ptr, type, field) container_of(ptr, type, field) #define hlist_for_each(p, head) \ @@ -504,7 +513,12 @@ static inline int list_is_last(const struct list_head *list, (pos) && ({ n = (pos)->member.next; 1; }); \ pos = hlist_entry_safe(n, typeof(*(pos)), member)) +#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300 +extern void list_sort(void *priv, struct list_head *head, int (*cmp)(void *priv, + const struct list_head *a, const struct list_head *b)); +#else extern void list_sort(void *priv, struct list_head *head, int (*cmp)(void *priv, struct list_head *a, struct list_head *b)); +#endif #endif /* _LINUXKPI_LINUX_LIST_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/lockdep.h b/sys/compat/linuxkpi/common/include/linux/lockdep.h index 2289db7756d4..a379e191aad7 100644 --- a/sys/compat/linuxkpi/common/include/linux/lockdep.h +++ b/sys/compat/linuxkpi/common/include/linux/lockdep.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_LOCKDEP_H_ @@ -48,8 +46,13 @@ struct pin_cookie { #define lockdep_set_current_reclaim_state(g) do { } while (0) #define lockdep_clear_current_reclaim_state() do { } while (0) #define lockdep_init_map(_map, _name, _key, _x) do { } while(0) +#define lockdep_register_key(key) do { } while(0) +#define lockdep_unregister_key(key) do { } while(0) #ifdef INVARIANTS +#define lockdep_assert(cond) do { WARN_ON(!cond); } while (0) +#define lockdep_assert_once(cond) do { WARN_ON_ONCE(!cond); } while (0) + #define lockdep_assert_not_held(m) do { \ struct lock_object *__lock = (struct lock_object *)(m); \ LOCK_CLASS(__lock)->lc_assert(__lock, LA_UNLOCKED); \ @@ -65,6 +68,8 @@ struct pin_cookie { LOCK_CLASS(__lock)->lc_assert(__lock, LA_LOCKED | LA_NOTRECURSED); \ } while (0) +#define lockdep_assert_none_held_once() do { } while (0) + static __inline bool lockdep_is_held(void *__m) { @@ -77,8 +82,12 @@ lockdep_is_held(void *__m) #define lockdep_is_held_type(_m, _t) lockdep_is_held(_m) #else +#define lockdep_assert(cond) do { } while (0) +#define lockdep_assert_once(cond) do { } while (0) + #define lockdep_assert_not_held(m) do { (void)(m); } while (0) #define lockdep_assert_held(m) do { (void)(m); } while (0) +#define lockdep_assert_none_held_once() do { } while (0) #define lockdep_assert_held_once(m) do { (void)(m); } while (0) diff --git a/sys/compat/linuxkpi/common/include/linux/log2.h b/sys/compat/linuxkpi/common/include/linux/log2.h index 4c356136ca98..27e91a8bdbe0 100644 --- a/sys/compat/linuxkpi/common/include/linux/log2.h +++ b/sys/compat/linuxkpi/common/include/linux/log2.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_LOG2_H_ #define _LINUXKPI_LINUX_LOG2_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/math64.h b/sys/compat/linuxkpi/common/include/linux/math64.h index f708f1ae81fa..cae5e30b08df 100644 --- a/sys/compat/linuxkpi/common/include/linux/math64.h +++ b/sys/compat/linuxkpi/common/include/linux/math64.h @@ -23,14 +23,13 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_MATH64_H #define _LINUXKPI_LINUX_MATH64_H #include <sys/stdint.h> +#include <sys/systm.h> #define do_div(n, base) ({ \ uint32_t __base = (base); \ @@ -109,6 +108,54 @@ mul_u64_u32_div(uint64_t x, uint32_t y, uint32_t div) } static inline uint64_t +mul_u64_u64_div_u64(uint64_t x, uint64_t y, uint64_t z) +{ + uint64_t res, rem; + uint64_t x1, y1, y1z; + + res = rem = 0; + x1 = x; + y1z = y / z; + y1 = y - y1z * z; + + /* + * INVARIANT: x * y = res * z + rem + (y1 + y1z * z) * x1 + * INVARIANT: y1 < z + * INVARIANT: rem < z + */ + while (x1 > 0) { + /* Handle low bit. */ + if (x1 & 1) { + x1 &= ~1; + res += y1z; + rem += y1; + if ((rem < y1) || (rem >= z)) { + res += 1; + rem -= z; + } + } + + /* Shift x1 right and (y1 + y1z * z) left */ + x1 >>= 1; + if ((y1 * 2 < y1) || (y1 * 2 >= z)) { + y1z = y1z * 2 + 1; + y1 = y1 * 2 - z; + } else { + y1z *= 2; + y1 *= 2; + } + } + + KASSERT(res * z + rem == x * y, ("%s: res %ju * z %ju + rem %ju != " + "x %ju * y %ju", __func__, (uintmax_t)res, (uintmax_t)z, + (uintmax_t)rem, (uintmax_t)x, (uintmax_t)y)); + KASSERT(rem < z, ("%s: rem %ju >= z %ju\n", __func__, + (uintmax_t)rem, (uintmax_t)z)); + + return (res); +} + +static inline uint64_t mul_u64_u32_shr(uint64_t x, uint32_t y, unsigned int shift) { uint32_t hi, lo; diff --git a/sys/compat/linuxkpi/common/include/linux/mhi.h b/sys/compat/linuxkpi/common/include/linux/mhi.h new file mode 100644 index 000000000000..2e0b74f29def --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/mhi.h @@ -0,0 +1,220 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2022-2023 Bjoern A. Zeeb + * + * 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_MHI_H +#define _LINUXKPI_LINUX_MHI_H + +#include <linux/types.h> + +/* Modem Host Interface (MHI) */ + +/* XXX FIXME */ +#define MHI_DB_BRST_DISABLE 0 +#define MHI_ER_CTRL 0 + +enum mhi_callback { + MHI_CB_SYS_ERROR, + MHI_CB_BW_REQ, + MHI_CB_EE_MISSION_MODE, + MHI_CB_EE_RDDM, + MHI_CB_FATAL_ERROR, + MHI_CB_IDLE, + MHI_CB_LPM_ENTER, + MHI_CB_LPM_EXIT, + MHI_CB_PENDING_DATA, +}; + +struct mhi_channel_config { + const char *name; + int auto_queue, dir, doorbell, doorbell_mode_switch, ee_mask, event_ring, lpm_notify, num, num_elements, offload_channel, pollcfg; +}; + +struct mhi_event_config { + int client_managed, data_type, hardware_event, irq, irq_moderation_ms, mode, num_elements, offload_channel, priority; +}; + +struct mhi_device { +}; + +struct mhi_controller_config { + const struct mhi_channel_config *ch_cfg; + struct mhi_event_config *event_cfg; + + int buf_len, max_channels, num_channels, num_events, use_bounce_buf; + + uint32_t timeout_ms; +}; + +struct mhi_controller { + struct device *cntrl_dev; + struct mhi_device *mhi_dev; + void *regs; + int *irq; + const char *fw_image; + + bool fbc_download; + size_t rddm_size; + size_t sbl_size; + size_t seg_len; + size_t reg_len; + int nr_irqs; + unsigned long irq_flags; + uint32_t timeout_ms; + + dma_addr_t iova_start; + dma_addr_t iova_stop; + + int (*runtime_get)(struct mhi_controller *); + void (*runtime_put)(struct mhi_controller *); + void (*status_cb)(struct mhi_controller *, enum mhi_callback); + int (*read_reg)(struct mhi_controller *, void __iomem *, uint32_t *); + void (*write_reg)(struct mhi_controller *, void __iomem *, uint32_t); +}; + +/* -------------------------------------------------------------------------- */ + +struct mhi_controller *linuxkpi_mhi_alloc_controller(void); +void linuxkpi_mhi_free_controller(struct mhi_controller *); +int linuxkpi_mhi_register_controller(struct mhi_controller *, + const struct mhi_controller_config *); +void linuxkpi_mhi_unregister_controller(struct mhi_controller *); + +/* -------------------------------------------------------------------------- */ + +static inline struct mhi_controller * +mhi_alloc_controller(void) +{ + + /* Keep allocations internal to our implementation. */ + return (linuxkpi_mhi_alloc_controller()); +} + +static inline void +mhi_free_controller(struct mhi_controller *mhi_ctrl) +{ + + linuxkpi_mhi_free_controller(mhi_ctrl); +} + +static inline int +mhi_register_controller(struct mhi_controller *mhi_ctrl, + const struct mhi_controller_config *cfg) +{ + + return (linuxkpi_mhi_register_controller(mhi_ctrl, cfg)); +} + +static inline void +mhi_unregister_controller(struct mhi_controller *mhi_ctrl) +{ + + linuxkpi_mhi_unregister_controller(mhi_ctrl); +} + +/* -------------------------------------------------------------------------- */ + +static __inline int +mhi_device_get_sync(struct mhi_device *mhi_dev) +{ + /* XXX TODO */ + return (-1); +} + +static __inline void +mhi_device_put(struct mhi_device *mhi_dev) +{ + /* XXX TODO */ +} + +/* -------------------------------------------------------------------------- */ + +static __inline int +mhi_prepare_for_power_up(struct mhi_controller *mhi_ctrl) +{ + /* XXX TODO */ + return (0); +} + +static __inline int +mhi_sync_power_up(struct mhi_controller *mhi_ctrl) +{ + /* XXX TODO */ + return (0); +} + +static __inline int +mhi_async_power_up(struct mhi_controller *mhi_ctrl) +{ + /* XXX TODO */ + return (0); +} + +static __inline void +mhi_power_down(struct mhi_controller *mhi_ctrl, bool x) +{ + /* XXX TODO */ +} + +static __inline void +mhi_unprepare_after_power_down(struct mhi_controller *mhi_ctrl) +{ + /* XXX TODO */ +} + +/* -------------------------------------------------------------------------- */ + +static __inline int +mhi_pm_suspend(struct mhi_controller *mhi_ctrl) +{ + /* XXX TODO */ + return (0); +} + +static __inline int +mhi_pm_resume(struct mhi_controller *mhi_ctrl) +{ + /* XXX TODO */ + return (0); +} + +static __inline int +mhi_pm_resume_force(struct mhi_controller *mhi_ctrl) +{ + /* XXX TODO */ + return (0); +} + +/* -------------------------------------------------------------------------- */ + +static __inline int +mhi_force_rddm_mode(struct mhi_controller *mhi_ctrl) +{ + /* XXX TODO */ + return (0); +} + +#endif /* _LINUXKPI_LINUX_MHI_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/miscdevice.h b/sys/compat/linuxkpi/common/include/linux/miscdevice.h index 1aa37454ffed..c66006a6b78e 100644 --- a/sys/compat/linuxkpi/common/include/linux/miscdevice.h +++ b/sys/compat/linuxkpi/common/include/linux/miscdevice.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_MISCDEVICE_H_ #define _LINUXKPI_LINUX_MISCDEVICE_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/mm.h b/sys/compat/linuxkpi/common/include/linux/mm.h index a266b5913625..109bfffe7d6a 100644 --- a/sys/compat/linuxkpi/common/include/linux/mm.h +++ b/sys/compat/linuxkpi/common/include/linux/mm.h @@ -27,8 +27,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_MM_H_ #define _LINUXKPI_LINUX_MM_H_ @@ -40,6 +38,9 @@ #include <linux/pfn.h> #include <linux/list.h> #include <linux/mmap_lock.h> +#include <linux/overflow.h> +#include <linux/shrinker.h> +#include <linux/page.h> #include <asm/pgtable.h> @@ -55,6 +56,8 @@ CTASSERT((VM_PROT_ALL & -(1 << 8)) == 0); #define VM_WRITE VM_PROT_WRITE #define VM_EXEC VM_PROT_EXECUTE +#define VM_ACCESS_FLAGS (VM_READ | VM_WRITE | VM_EXEC) + #define VM_PFNINTERNAL (1 << 8) /* FreeBSD private flag to vm_insert_pfn() */ #define VM_MIXEDMAP (1 << 9) #define VM_NORESERVE (1 << 10) @@ -143,11 +146,20 @@ struct vm_operations_struct { }; struct sysinfo { - uint64_t totalram; - uint64_t totalhigh; - uint32_t mem_unit; + uint64_t totalram; /* Total usable main memory size */ + uint64_t freeram; /* Available memory size */ + uint64_t totalhigh; /* Total high memory size */ + uint64_t freehigh; /* Available high memory size */ + uint32_t mem_unit; /* Memory unit size in bytes */ }; +static inline struct page * +virt_to_head_page(const void *p) +{ + + return (virt_to_page(p)); +} + /* * Compute log2 of the power of two rounded up count of pages * needed for size bytes. @@ -217,11 +229,15 @@ apply_to_page_range(struct mm_struct *mm, unsigned long address, int zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, unsigned long size); +int lkpi_remap_pfn_range(struct vm_area_struct *vma, + unsigned long start_addr, unsigned long start_pfn, unsigned long size, + pgprot_t prot); + static inline int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, unsigned long size, pgprot_t prot) { - return (-ENOTSUP); + return (lkpi_remap_pfn_range(vma, addr, pfn, size, prot)); } static inline unsigned long @@ -233,44 +249,73 @@ vma_pages(struct vm_area_struct *vma) #define offset_in_page(off) ((unsigned long)(off) & (PAGE_SIZE - 1)) static inline void -set_page_dirty(struct vm_page *page) +set_page_dirty(struct page *page) { vm_page_dirty(page); } static inline void -mark_page_accessed(struct vm_page *page) +mark_page_accessed(struct page *page) { vm_page_reference(page); } static inline void -get_page(struct vm_page *page) +get_page(struct page *page) { vm_page_wire(page); } extern long get_user_pages(unsigned long start, unsigned long nr_pages, - int gup_flags, struct page **, + unsigned int gup_flags, struct page **, struct vm_area_struct **); +static inline long +pin_user_pages(unsigned long start, unsigned long nr_pages, + unsigned int gup_flags, struct page **pages, + struct vm_area_struct **vmas) +{ + return get_user_pages(start, nr_pages, gup_flags, pages, vmas); +} + extern int __get_user_pages_fast(unsigned long start, int nr_pages, int write, struct page **); +static inline int +pin_user_pages_fast(unsigned long start, int nr_pages, + unsigned int gup_flags, struct page **pages) +{ + return __get_user_pages_fast( + start, nr_pages, !!(gup_flags & FOLL_WRITE), pages); +} + extern long get_user_pages_remote(struct task_struct *, struct mm_struct *, unsigned long start, unsigned long nr_pages, - int gup_flags, struct page **, + unsigned int gup_flags, struct page **, struct vm_area_struct **); +static inline long +pin_user_pages_remote(struct task_struct *task, struct mm_struct *mm, + unsigned long start, unsigned long nr_pages, + unsigned int gup_flags, struct page **pages, + struct vm_area_struct **vmas) +{ + return get_user_pages_remote( + task, mm, start, nr_pages, gup_flags, pages, vmas); +} + static inline void -put_page(struct vm_page *page) +put_page(struct page *page) { vm_page_unwire(page, PQ_ACTIVE); } +#define unpin_user_page(page) put_page(page) +#define unpin_user_pages(pages, npages) release_pages(pages, npages) + #define copy_highpage(to, from) pmap_copy_page(from, to) static inline pgprot_t @@ -279,7 +324,19 @@ vm_get_page_prot(unsigned long vm_flags) return (vm_flags & VM_PROT_ALL); } -static inline vm_page_t +static inline void +vm_flags_set(struct vm_area_struct *vma, unsigned long flags) +{ + vma->vm_flags |= flags; +} + +static inline void +vm_flags_clear(struct vm_area_struct *vma, unsigned long flags) +{ + vma->vm_flags &= ~flags; +} + +static inline struct page * vmalloc_to_page(const void *addr) { vm_paddr_t paddr; @@ -304,10 +361,31 @@ unlock_page(struct page *page) extern int is_vmalloc_addr(const void *addr); void si_meminfo(struct sysinfo *si); +static inline unsigned long +totalram_pages(void) +{ + return ((unsigned long)physmem); +} + #define unmap_mapping_range(...) lkpi_unmap_mapping_range(__VA_ARGS__) void lkpi_unmap_mapping_range(void *obj, loff_t const holebegin __unused, loff_t const holelen, int even_cows __unused); #define PAGE_ALIGNED(p) __is_aligned(p, PAGE_SIZE) +void vma_set_file(struct vm_area_struct *vma, struct linux_file *file); + +static inline void +might_alloc(gfp_t gfp_mask __unused) +{ +} + +#define is_cow_mapping(flags) (false) + +static inline bool +want_init_on_free(void) +{ + return (false); +} + #endif /* _LINUXKPI_LINUX_MM_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/mm_types.h b/sys/compat/linuxkpi/common/include/linux/mm_types.h index 2a7b33d15054..c08e2511725b 100644 --- a/sys/compat/linuxkpi/common/include/linux/mm_types.h +++ b/sys/compat/linuxkpi/common/include/linux/mm_types.h @@ -22,8 +22,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_MM_TYPES_H_ @@ -31,6 +29,7 @@ #include <linux/types.h> #include <linux/page.h> +#include <linux/rbtree.h> #include <linux/rwsem.h> #include <asm/atomic.h> diff --git a/sys/compat/linuxkpi/common/include/linux/mman.h b/sys/compat/linuxkpi/common/include/linux/mman.h new file mode 100644 index 000000000000..eff80759b4cd --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/mman.h @@ -0,0 +1,38 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2022 Jean-Sébastien Pédron <dumbbell@FreeBSD.org> + * + * 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 _LINUX_MMAN_H +#define _LINUX_MMAN_H + +/* + * In Linux, <linux/mman.h> includes <linux/percpu_counter.h>, which includes + * <linux/smp.h>. + */ +#include <linux/smp.h> + +#endif /* _LINUX_MMAN_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/mmu_context.h b/sys/compat/linuxkpi/common/include/linux/mmu_context.h index afcc9cf07249..4c1bc61b3edb 100644 --- a/sys/compat/linuxkpi/common/include/linux/mmu_context.h +++ b/sys/compat/linuxkpi/common/include/linux/mmu_context.h @@ -21,8 +21,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_MMU_CONTEXT_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/mmu_notifier.h b/sys/compat/linuxkpi/common/include/linux/mmu_notifier.h index 395f41c36a65..2492a6a3bd4f 100644 --- a/sys/compat/linuxkpi/common/include/linux/mmu_notifier.h +++ b/sys/compat/linuxkpi/common/include/linux/mmu_notifier.h @@ -22,8 +22,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_MMU_NOTIFIER_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/mmzone.h b/sys/compat/linuxkpi/common/include/linux/mmzone.h new file mode 100644 index 000000000000..49cc218c6fce --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/mmzone.h @@ -0,0 +1,11 @@ +/* Public domain. */ + +#ifndef _LINUX_MMZONE_H +#define _LINUX_MMZONE_H + +#include <linux/mm_types.h> +#include <linux/page-flags.h> + +#define MAX_ORDER 11 + +#endif diff --git a/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h b/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h index 441faab6df81..87bd6ec24bce 100644 --- a/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h +++ b/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h @@ -24,23 +24,27 @@ * 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. - * - * $FreeBSD$ */ #ifndef __LINUXKPI_LINUX_MOD_DEVICETABLE_H__ #define __LINUXKPI_LINUX_MOD_DEVICETABLE_H__ +#include <linux/types.h> + enum dmi_field { DMI_NONE, DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_BIOS_DATE, + DMI_BIOS_RELEASE, + DMI_EC_FIRMWARE_RELEASE, DMI_SYS_VENDOR, DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_PRODUCT_SERIAL, DMI_PRODUCT_UUID, + DMI_PRODUCT_SKU, + DMI_PRODUCT_FAMILY, DMI_BOARD_VENDOR, DMI_BOARD_NAME, DMI_BOARD_VERSION, @@ -52,6 +56,7 @@ enum dmi_field { DMI_CHASSIS_SERIAL, DMI_CHASSIS_ASSET_TAG, DMI_STRING_MAX, + DMI_OEM_STRING, }; struct dmi_strmatch { @@ -70,4 +75,9 @@ struct dmi_system_id { #define DMI_MATCH(a, b) { .slot = a, .substr = b } #define DMI_EXACT_MATCH(a, b) { .slot = a, .substr = b, .exact_match = 1 } +#define I2C_NAME_SIZE 20 +#define I2C_MODULE_PREFIX "i2c:" + +#define ACPI_ID_LEN 16 + #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 ac7dfc07e468..9d98ef7cf3db 100644 --- a/sys/compat/linuxkpi/common/include/linux/module.h +++ b/sys/compat/linuxkpi/common/include/linux/module.h @@ -25,13 +25,10 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_MODULE_H_ #define _LINUXKPI_LINUX_MODULE_H_ -#include <sys/cdefs.h> #include <sys/types.h> #include <sys/param.h> #include <sys/module.h> diff --git a/sys/compat/linuxkpi/common/include/linux/moduleparam.h b/sys/compat/linuxkpi/common/include/linux/moduleparam.h index d9485de88f56..b61bbce495ea 100644 --- a/sys/compat/linuxkpi/common/include/linux/moduleparam.h +++ b/sys/compat/linuxkpi/common/include/linux/moduleparam.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_MODULEPARAM_H_ #define _LINUXKPI_LINUX_MODULEPARAM_H_ @@ -90,6 +88,15 @@ LINUXKPI_PARAM_NAME(name), LINUXKPI_PARAM_PERM(perm), &(var), 0, \ LINUXKPI_PARAM_DESC(name))) +#define LINUXKPI_PARAM_bint(name, var, perm) \ + LINUXKPI_PARAM_int(name, var, perm) + +#define LINUXKPI_PARAM_hexint(name, var, perm) \ + extern const char LINUXKPI_PARAM_DESC(name)[]; \ + LINUXKPI_PARAM_PASS(SYSCTL_UINT(LINUXKPI_PARAM_PARENT, OID_AUTO, \ + LINUXKPI_PARAM_NAME(name), LINUXKPI_PARAM_PERM(perm), &(var), 0, \ + LINUXKPI_PARAM_DESC(name))) + #define LINUXKPI_PARAM_long(name, var, perm) \ extern const char LINUXKPI_PARAM_DESC(name)[]; \ LINUXKPI_PARAM_PASS(SYSCTL_LONG(LINUXKPI_PARAM_PARENT, OID_AUTO, \ diff --git a/sys/compat/linuxkpi/common/include/linux/mutex.h b/sys/compat/linuxkpi/common/include/linux/mutex.h index 7af95e9d2dc5..1d85ba20baca 100644 --- a/sys/compat/linuxkpi/common/include/linux/mutex.h +++ b/sys/compat/linuxkpi/common/include/linux/mutex.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_MUTEX_H_ #define _LINUXKPI_LINUX_MUTEX_H_ @@ -36,6 +34,8 @@ #include <sys/lock.h> #include <sys/sx.h> +#include <linux/kernel.h> +#include <linux/list.h> #include <linux/spinlock.h> #include <asm/atomic.h> diff --git a/sys/compat/linuxkpi/common/include/linux/net.h b/sys/compat/linuxkpi/common/include/linux/net.h index 5438fccb8512..a5172f3f31eb 100644 --- a/sys/compat/linuxkpi/common/include/linux/net.h +++ b/sys/compat/linuxkpi/common/include/linux/net.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_NET_H_ #define _LINUXKPI_LINUX_NET_H_ @@ -47,26 +45,27 @@ sock_create_kern(int family, int type, int proto, struct socket **res) } static inline int -sock_getname(struct socket *so, struct sockaddr *addr, int *sockaddr_len, +sock_getname(struct socket *so, struct sockaddr *sa, int *sockaddr_len, int peer) { - struct sockaddr *nam; int error; - nam = NULL; + /* + * XXXGL: we can't use sopeeraddr()/sosockaddr() here since with + * INVARIANTS they would check if supplied sockaddr has enough + * length. Such notion doesn't even exist in Linux KPI. + */ if (peer) { - if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) + if ((so->so_state & SS_ISCONNECTED) == 0) return (-ENOTCONN); - error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, &nam); + error = so->so_proto->pr_peeraddr(so, sa); } else - error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, &nam); + error = so->so_proto->pr_sockaddr(so, sa); if (error) return (-error); - *addr = *nam; - *sockaddr_len = addr->sa_len; + *sockaddr_len = sa->sa_len; - free(nam, M_SONAME); return (0); } diff --git a/sys/compat/linuxkpi/common/include/linux/net_dim.h b/sys/compat/linuxkpi/common/include/linux/net_dim.h index 08a8bb758c32..4fe3e39210e7 100644 --- a/sys/compat/linuxkpi/common/include/linux/net_dim.h +++ b/sys/compat/linuxkpi/common/include/linux/net_dim.h @@ -31,8 +31,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $FreeBSD$ */ /* This file implements Dynamic Interrupt Moderation, DIM */ diff --git a/sys/compat/linuxkpi/common/include/linux/netdev_features.h b/sys/compat/linuxkpi/common/include/linux/netdev_features.h index e21d1965bec6..06e88d107708 100644 --- a/sys/compat/linuxkpi/common/include/linux/netdev_features.h +++ b/sys/compat/linuxkpi/common/include/linux/netdev_features.h @@ -24,8 +24,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_NETDEV_FEATURES_H_ #define _LINUXKPI_LINUX_NETDEV_FEATURES_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/netdevice.h b/sys/compat/linuxkpi/common/include/linux/netdevice.h index f8c03f92b025..3d2b309909b4 100644 --- a/sys/compat/linuxkpi/common/include/linux/netdevice.h +++ b/sys/compat/linuxkpi/common/include/linux/netdevice.h @@ -5,7 +5,7 @@ * Copyright (c) 2013-2019 Mellanox Technologies, Ltd. * All rights reserved. * Copyright (c) 2020-2021 The FreeBSD Foundation - * Copyright (c) 2020-2021 Bjoern A. Zeeb + * Copyright (c) 2020-2022 Bjoern A. Zeeb * * Portions of this software were developed by Björn Zeeb * under sponsorship from the FreeBSD Foundation. @@ -30,8 +30,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_NETDEVICE_H #define _LINUXKPI_LINUX_NETDEVICE_H @@ -53,6 +51,7 @@ #include <net/if_var.h> #include <net/if_dl.h> +#include <linux/kernel.h> #include <linux/bitops.h> #include <linux/list.h> #include <linux/device.h> @@ -105,9 +104,6 @@ struct net_device_ops { }; struct net_device { - /* BSD specific for compat. */ - struct ifnet bsdifp; - /* net_device fields seen publicly. */ /* XXX can we later make some aliases to ifnet? */ char name[IFNAMSIZ]; @@ -134,6 +130,7 @@ struct net_device { /* Not properly typed as-of now. */ int flags, type; int name_assign_type, needed_headroom; + int threaded; void (*priv_destructor)(struct net_device *); @@ -182,6 +179,30 @@ int unregister_inetaddr_notifier(struct notifier_block *); #define NAPI_POLL_WEIGHT 64 /* budget */ +/* + * There are drivers directly testing napi state bits, so we need to publicly + * expose them. If you ask me, those accesses should be hid behind an + * inline function and the bit flags not be directly exposed. + */ +enum napi_state_bits { + /* + * Official Linux flags encountered. + */ + NAPI_STATE_SCHED = 1, + + /* + * Our internal versions (for now). + */ + /* Do not schedule new things while we are waiting to clear things. */ + LKPI_NAPI_FLAG_DISABLE_PENDING = 0, + /* To synchronise that only one poll is ever running. */ + LKPI_NAPI_FLAG_IS_SCHEDULED = 1, + /* If trying to schedule while poll is running. Need to re-schedule. */ + LKPI_NAPI_FLAG_LOST_RACE_TRY_AGAIN = 2, + /* When shutting down forcefully prevent anything from running task/poll. */ + LKPI_NAPI_FLAG_SHUTDOWN = 3, +}; + struct napi_struct { TAILQ_ENTRY(napi_struct) entry; @@ -191,11 +212,12 @@ struct napi_struct { int budget; int rx_count; + /* * These flags mostly need to be checked/changed atomically * (multiple together in some cases). */ - volatile unsigned long _flags; + volatile unsigned long state; /* FreeBSD internal. */ /* Use task for now, so we can easily switch between direct and task. */ @@ -204,11 +226,11 @@ struct napi_struct { void linuxkpi_init_dummy_netdev(struct net_device *); void linuxkpi_netif_napi_add(struct net_device *, struct napi_struct *, - int(*napi_poll)(struct napi_struct *, int), int); + int(*napi_poll)(struct napi_struct *, int)); void linuxkpi_netif_napi_del(struct napi_struct *); bool linuxkpi_napi_schedule_prep(struct napi_struct *); void linuxkpi___napi_schedule(struct napi_struct *); -void linuxkpi_napi_schedule(struct napi_struct *); +bool linuxkpi_napi_schedule(struct napi_struct *); void linuxkpi_napi_reschedule(struct napi_struct *); bool linuxkpi_napi_complete_done(struct napi_struct *, int); bool linuxkpi_napi_complete(struct napi_struct *); @@ -218,8 +240,8 @@ void linuxkpi_napi_synchronize(struct napi_struct *); #define init_dummy_netdev(_n) \ linuxkpi_init_dummy_netdev(_n) -#define netif_napi_add(_nd, _ns, _p, _b) \ - linuxkpi_netif_napi_add(_nd, _ns, _p, _b) +#define netif_napi_add(_nd, _ns, _p) \ + linuxkpi_netif_napi_add(_nd, _ns, _p) #define netif_napi_del(_n) \ linuxkpi_netif_napi_del(_n) #define napi_schedule_prep(_n) \ @@ -241,6 +263,22 @@ void linuxkpi_napi_synchronize(struct napi_struct *); #define napi_synchronize(_n) \ linuxkpi_napi_synchronize(_n) + +static inline void +netif_napi_add_tx(struct net_device *dev, struct napi_struct *napi, + int(*napi_poll)(struct napi_struct *, int)) +{ + + netif_napi_add(dev, napi, napi_poll); +} + +static inline bool +napi_is_scheduled(struct napi_struct *napi) +{ + + return (test_bit(LKPI_NAPI_FLAG_IS_SCHEDULED, &napi->state)); +} + /* -------------------------------------------------------------------------- */ static inline void @@ -283,6 +321,134 @@ synchronize_net(void) synchronize_rcu(); } +static __inline void +netif_receive_skb_list(struct list_head *head) +{ + + pr_debug("%s: TODO\n", __func__); +} + +static __inline int +napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) +{ + + pr_debug("%s: TODO\n", __func__); + return (-1); +} + +static __inline void +ether_setup(struct net_device *ndev) +{ + + pr_debug("%s: TODO\n", __func__); +} + +static __inline void +dev_net_set(struct net_device *ndev, void *p) +{ + + pr_debug("%s: TODO\n", __func__); +} + +static __inline int +dev_set_threaded(struct net_device *ndev, bool threaded) +{ + + pr_debug("%s: TODO\n", __func__); + return (-ENODEV); +} + +/* -------------------------------------------------------------------------- */ + +static __inline bool +netif_carrier_ok(struct net_device *ndev) +{ + pr_debug("%s: TODO\n", __func__); + return (false); +} + +static __inline void +netif_carrier_off(struct net_device *ndev) +{ + pr_debug("%s: TODO\n", __func__); +} + +static __inline void +netif_carrier_on(struct net_device *ndev) +{ + pr_debug("%s: TODO\n", __func__); +} + +/* -------------------------------------------------------------------------- */ + +static __inline bool +netif_queue_stopped(struct net_device *ndev) +{ + pr_debug("%s: TODO\n", __func__); + return (false); +} + +static __inline void +netif_stop_queue(struct net_device *ndev) +{ + pr_debug("%s: TODO\n", __func__); +} + +static __inline void +netif_wake_queue(struct net_device *ndev) +{ + pr_debug("%s: TODO\n", __func__); +} + +/* -------------------------------------------------------------------------- */ + +static __inline int +register_netdevice(struct net_device *ndev) +{ + + /* assert rtnl_locked? */ + pr_debug("%s: TODO\n", __func__); + return (0); +} + +static __inline int +register_netdev(struct net_device *ndev) +{ + int error; + + /* lock */ + error = register_netdevice(ndev); + /* unlock */ + pr_debug("%s: TODO\n", __func__); + return (error); +} + +static __inline void +unregister_netdev(struct net_device *ndev) +{ + pr_debug("%s: TODO\n", __func__); +} + +static __inline void +unregister_netdevice(struct net_device *ndev) +{ + pr_debug("%s: TODO\n", __func__); +} + +/* -------------------------------------------------------------------------- */ + +static __inline void +netif_rx(struct sk_buff *skb) +{ + pr_debug("%s: TODO\n", __func__); +} + +static __inline void +netif_rx_ni(struct sk_buff *skb) +{ + pr_debug("%s: TODO\n", __func__); +} + /* -------------------------------------------------------------------------- */ struct net_device *linuxkpi_alloc_netdev(size_t, const char *, uint32_t, @@ -306,5 +472,6 @@ netdev_priv(const struct net_device *ndev) #define rtnl_lock() do { } while(0) #define rtnl_unlock() do { } while(0) +#define rcu_dereference_rtnl(x) READ_ONCE(x) #endif /* _LINUXKPI_LINUX_NETDEVICE_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/nl80211.h b/sys/compat/linuxkpi/common/include/linux/nl80211.h index a85abfc10453..5b43ff675e19 100644 --- a/sys/compat/linuxkpi/common/include/linux/nl80211.h +++ b/sys/compat/linuxkpi/common/include/linux/nl80211.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2020-2021 The FreeBSD Foundation + * Copyright (c) 2020-2023 The FreeBSD Foundation * * This software was developed by Björn Zeeb under sponsorship from * the FreeBSD Foundation. @@ -24,8 +24,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_NL80211_H @@ -80,6 +78,8 @@ enum nl80211_reg_rule_flags { NL80211_RRF_NO_160MHZ = BIT(8), NL80211_RRF_NO_HE = BIT(9), NL80211_RRF_NO_OFDM = BIT(10), + NL80211_RRF_NO_320MHZ = BIT(11), + NL80211_RRF_NO_EHT = BIT(12), }; #define NL80211_RRF_NO_HT40 (NL80211_RRF_NO_HT40MINUS|NL80211_RRF_NO_HT40PLUS) @@ -145,6 +145,7 @@ enum nl80211_chan_width { NL80211_CHAN_WIDTH_160, NL80211_CHAN_WIDTH_5, NL80211_CHAN_WIDTH_10, + NL80211_CHAN_WIDTH_320, }; enum nl80211_iftype { @@ -161,6 +162,7 @@ enum nl80211_iftype { NL80211_IFTYPE_MESH_POINT, NL80211_IFTYPE_WDS, NL80211_IFTYPE_OCB, + NL80211_IFTYPE_NAN, /* Keep this last. */ NUM_NL80211_IFTYPES @@ -225,6 +227,9 @@ enum nl80211_ext_feature { NL80211_EXT_FEATURE_FILS_DISCOVERY, NL80211_EXT_FEATURE_RADAR_BACKGROUND, NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP, + NL80211_EXT_FEATURE_BEACON_PROTECTION, + NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT, + NL80211_EXT_FEATURE_PUNCT, /* Keep this last. */ NUM_NL80211_EXT_FEATURES @@ -248,10 +253,14 @@ enum nl80211_sta_info { NL80211_STA_INFO_TX_BITRATE, NL80211_STA_INFO_TX_PACKETS, NL80211_STA_INFO_TX_BYTES, + NL80211_STA_INFO_TX_BYTES64, + NL80211_STA_INFO_RX_BYTES64, NL80211_STA_INFO_TX_FAILED, NL80211_STA_INFO_TX_RETRIES, NL80211_STA_INFO_RX_DURATION, NL80211_STA_INFO_TX_DURATION, + NL80211_STA_INFO_ACK_SIGNAL, + NL80211_STA_INFO_ACK_SIGNAL_AVG, }; enum nl80211_ftm_stats { @@ -321,6 +330,37 @@ enum nl80211_he_gi { NL80211_RATE_INFO_HE_GI_3_2, }; +enum nl80211_he_ltf { + NL80211_RATE_INFO_HE_1XLTF, + NL80211_RATE_INFO_HE_2XLTF, + NL80211_RATE_INFO_HE_4XLTF, +}; + +enum nl80211_eht_gi { + NL80211_RATE_INFO_EHT_GI_0_8, + NL80211_RATE_INFO_EHT_GI_1_6, + NL80211_RATE_INFO_EHT_GI_3_2, +}; + +enum nl80211_eht_ru_alloc { + NL80211_RATE_INFO_EHT_RU_ALLOC_26, + NL80211_RATE_INFO_EHT_RU_ALLOC_52, + NL80211_RATE_INFO_EHT_RU_ALLOC_52P26, + NL80211_RATE_INFO_EHT_RU_ALLOC_106, + NL80211_RATE_INFO_EHT_RU_ALLOC_106P26, + NL80211_RATE_INFO_EHT_RU_ALLOC_242, + NL80211_RATE_INFO_EHT_RU_ALLOC_484, + NL80211_RATE_INFO_EHT_RU_ALLOC_484P242, + NL80211_RATE_INFO_EHT_RU_ALLOC_996, + NL80211_RATE_INFO_EHT_RU_ALLOC_996P484, + NL80211_RATE_INFO_EHT_RU_ALLOC_996P484P242, + NL80211_RATE_INFO_EHT_RU_ALLOC_2x996, + NL80211_RATE_INFO_EHT_RU_ALLOC_2x996P484, + NL80211_RATE_INFO_EHT_RU_ALLOC_3x996, + NL80211_RATE_INFO_EHT_RU_ALLOC_3x996P484, + NL80211_RATE_INFO_EHT_RU_ALLOC_4x996, +}; + enum nl80211_dfs_regions { NL80211_DFS_UNSET, NL80211_DFS_FCC, @@ -328,11 +368,16 @@ enum nl80211_dfs_regions { NL80211_DFS_JP, }; +enum nl80211_dfs_state { + NL80211_DFS_USABLE, +}; + enum nl80211_sar_type { NL80211_SAR_TYPE_POWER, }; #define NL80211_VHT_NSS_MAX 8 +#define NL80211_HE_NSS_MAX 8 enum nl80211_tid_cfg_attr { NL80211_TID_CONFIG_ATTR_NOACK, @@ -342,6 +387,7 @@ enum nl80211_tid_cfg_attr { NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL, NL80211_TID_CONFIG_ATTR_RETRY_LONG, NL80211_TID_CONFIG_ATTR_AMPDU_CTRL, + NL80211_TID_CONFIG_ATTR_AMSDU_CTRL, }; enum nl80211_tid_config { @@ -366,7 +412,13 @@ enum nl80211_probe_resp_offload_support { NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P, }; +enum nl80211_user_reg_hint_type { + NL80211_USER_REG_HINT_USER, +}; + #define NL80211_KCK_LEN 16 +#define NL80211_KCK_EXT_LEN 24 #define NL80211_KEK_LEN 16 +#define NL80211_KEK_EXT_LEN 32 #define NL80211_REPLAY_CTR_LEN 8 #endif /* _LINUXKPI_LINUX_NL80211_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/notifier.h b/sys/compat/linuxkpi/common/include/linux/notifier.h index bd822d73d5e3..9302a1ce4606 100644 --- a/sys/compat/linuxkpi/common/include/linux/notifier.h +++ b/sys/compat/linuxkpi/common/include/linux/notifier.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_NOTIFIER_H_ #define _LINUXKPI_LINUX_NOTIFIER_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/numa.h b/sys/compat/linuxkpi/common/include/linux/numa.h index b51a92951f3f..6b227e177a64 100644 --- a/sys/compat/linuxkpi/common/include/linux/numa.h +++ b/sys/compat/linuxkpi/common/include/linux/numa.h @@ -24,8 +24,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_NUMA_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/of.h b/sys/compat/linuxkpi/common/include/linux/of.h new file mode 100644 index 000000000000..fb4554a8ddbc --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/of.h @@ -0,0 +1,33 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2023 Serenity Cyber Security, LLC. + * + * 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_OF_H +#define _LINUXKPI_LINUX_OF_H + +#include <linux/kobject.h> + +#endif diff --git a/sys/compat/linuxkpi/common/include/linux/overflow.h b/sys/compat/linuxkpi/common/include/linux/overflow.h index d2e15d8d2383..9ba9b9500f11 100644 --- a/sys/compat/linuxkpi/common/include/linux/overflow.h +++ b/sys/compat/linuxkpi/common/include/linux/overflow.h @@ -1,53 +1,349 @@ -/*- - * Copyright (c) 2020 The FreeBSD Foundation - * - * This software was developed by Emmanuel Vadot 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. - * - * $FreeBSD$ - */ - -#ifndef __LINUXKPI_LINUX_OVERFLOW_H__ -#define __LINUXKPI_LINUX_OVERFLOW_H__ - -#include <sys/stdint.h> -#include <sys/types.h> - -#define check_add_overflow(a, b, c) \ - __builtin_add_overflow(a, b, c) - -#define check_mul_overflow(a, b, c) \ - __builtin_mul_overflow(a, b, c) - -static inline size_t -array_size(size_t x, size_t y) +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +#ifndef _LINUXKPI_LINUX_OVERFLOW_H +#define _LINUXKPI_LINUX_OVERFLOW_H + +#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 + * type. These macros may also be useful elsewhere. It would seem more obvious + * to do something like: + * + * #define type_min(T) (T)(is_signed_type(T) ? (T)1 << (8*sizeof(T)-1) : 0) + * #define type_max(T) (T)(is_signed_type(T) ? ((T)1 << (8*sizeof(T)-1)) - 1 : ~(T)0) + * + * Unfortunately, the middle expressions, strictly speaking, have + * undefined behaviour, and at least some versions of gcc warn about + * the type_max expression (but not if -fsanitize=undefined is in + * effect; in that case, the warning is deferred to runtime...). + * + * The slightly excessive casting in type_min is to make sure the + * macros also produce sensible values for the exotic type _Bool. [The + * overflow checkers only almost work for _Bool, but that's + * a-feature-not-a-bug, since people shouldn't be doing arithmetic on + * _Bools. Besides, the gcc builtins don't allow _Bool* as third + * argument.] + * + * Idea stolen from + * https://mail-index.netbsd.org/tech-misc/2007/02/05/0000.html - + * credit to Christian Biere. + */ +#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type))) +#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T))) +#define type_min(T) ((T)((T)-type_max(T)-(T)1)) + +/* + * 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) { - size_t retval; + return unlikely(overflow); +} + +/** + * check_add_overflow() - Calculate addition with overflow checking + * @a: first addend + * @b: second addend + * @d: pointer to store sum + * + * Returns 0 on success. + * + * *@d holds the results of the attempted addition, but is not considered + * "safe for use" on a non-zero return value, which indicates that the + * sum has overflowed or been truncated. + */ +#define check_add_overflow(a, b, d) \ + __must_check_overflow(__builtin_add_overflow(a, b, d)) + +/** + * check_sub_overflow() - Calculate subtraction with overflow checking + * @a: minuend; value to subtract from + * @b: subtrahend; value to subtract from @a + * @d: pointer to store difference + * + * Returns 0 on success. + * + * *@d holds the results of the attempted subtraction, but is not considered + * "safe for use" on a non-zero return value, which indicates that the + * difference has underflowed or been truncated. + */ +#define check_sub_overflow(a, b, d) \ + __must_check_overflow(__builtin_sub_overflow(a, b, d)) + +/** + * check_mul_overflow() - Calculate multiplication with overflow checking + * @a: first factor + * @b: second factor + * @d: pointer to store product + * + * Returns 0 on success. + * + * *@d holds the results of the attempted multiplication, but is not + * considered "safe for use" on a non-zero return value, which indicates + * that the product has overflowed or been truncated. + */ +#define check_mul_overflow(a, b, d) \ + __must_check_overflow(__builtin_mul_overflow(a, b, d)) + +/** + * check_shl_overflow() - Calculate a left-shifted value and check overflow + * @a: Value to be shifted + * @s: How many bits left to shift + * @d: Pointer to where to store the result + * + * Computes *@d = (@a << @s) + * + * Returns true if '*@d' cannot hold the result or when '@a << @s' doesn't + * make sense. Example conditions: + * + * - '@a << @s' causes bits to be lost when stored in *@d. + * - '@s' is garbage (e.g. negative) or so large that the result of + * '@a << @s' is guaranteed to be 0. + * - '@a' is negative. + * - '@a << @s' sets the sign bit, if any, in '*@d'. + * + * '*@d' will hold the results of the attempted shift, but is not + * considered "safe for use" if true is returned. + */ +#define check_shl_overflow(a, s, d) __must_check_overflow(({ \ + typeof(a) _a = a; \ + typeof(s) _s = s; \ + typeof(d) _d = d; \ + u64 _a_full = _a; \ + unsigned int _to_shift = \ + is_non_negative(_s) && _s < 8 * sizeof(*d) ? _s : 0; \ + *_d = (_a_full << _to_shift); \ + (_to_shift != _s || is_negative(*_d) || is_negative(_a) || \ + (*_d >> _to_shift) != _a); \ +})) + +#define __overflows_type_constexpr(x, T) ( \ + is_unsigned_type(typeof(x)) ? \ + (x) > type_max(typeof(T)) : \ + is_unsigned_type(typeof(T)) ? \ + (x) < 0 || (x) > type_max(typeof(T)) : \ + (x) < type_min(typeof(T)) || (x) > type_max(typeof(T))) + +#define __overflows_type(x, T) ({ \ + typeof(T) v = 0; \ + check_add_overflow((x), v, &v); \ +}) + +/** + * overflows_type - helper for checking the overflows between value, variables, + * or data type + * + * @n: source constant value or variable to be checked + * @T: destination variable or data type proposed to store @x + * + * Compares the @x expression for whether or not it can safely fit in + * the storage of the type in @T. @x and @T can have different types. + * If @x is a constant expression, this will also resolve to a constant + * expression. + * + * Returns: true if overflow can occur, false otherwise. + */ +#define overflows_type(n, T) \ + __builtin_choose_expr(__is_constexpr(n), \ + __overflows_type_constexpr(n, T), \ + __overflows_type(n, T)) - if (__builtin_mul_overflow(x, y, &retval)) - retval = SIZE_MAX; - return (retval); +/** + * castable_to_type - like __same_type(), but also allows for casted literals + * + * @n: variable or constant value + * @T: variable or data type + * + * Unlike the __same_type() macro, this allows a constant value as the + * first argument. If this value would not overflow into an assignment + * of the second argument's type, it returns true. Otherwise, this falls + * back to __same_type(). + */ +#define castable_to_type(n, T) \ + __builtin_choose_expr(__is_constexpr(n), \ + !__overflows_type_constexpr(n, T), \ + __same_type(n, T)) + +/** + * size_mul() - Calculate size_t multiplication with saturation at SIZE_MAX + * @factor1: first factor + * @factor2: second factor + * + * Returns: calculate @factor1 * @factor2, both promoted to size_t, + * 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) +{ + size_t bytes; + + if (check_mul_overflow(factor1, factor2, &bytes)) + return SIZE_MAX; + + return bytes; +} + +/** + * size_add() - Calculate size_t addition with saturation at SIZE_MAX + * @addend1: first addend + * @addend2: second addend + * + * Returns: calculate @addend1 + @addend2, both promoted to size_t, + * 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) +{ + size_t bytes; + + if (check_add_overflow(addend1, addend2, &bytes)) + return SIZE_MAX; + + return bytes; +} + +/** + * size_sub() - Calculate size_t subtraction with saturation at SIZE_MAX + * @minuend: value to subtract from + * @subtrahend: value to subtract from @minuend + * + * Returns: calculate @minuend - @subtrahend, both promoted to size_t, + * with any overflow causing the return value to be SIZE_MAX. For + * composition with the size_add() and size_mul() helpers, neither + * 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) +{ + size_t bytes; + + if (minuend == SIZE_MAX || subtrahend == SIZE_MAX || + check_sub_overflow(minuend, subtrahend, &bytes)) + return SIZE_MAX; + + return bytes; } -#endif /* __LINUXKPI_LINUX_OVERFLOW_H__ */ +/** + * array_size() - Calculate size of 2-dimensional array. + * @a: dimension one + * @b: dimension two + * + * Calculates size of 2-dimensional array: @a * @b. + * + * Returns: number of bytes needed to represent the array or SIZE_MAX on + * overflow. + */ +#define array_size(a, b) size_mul(a, b) + +/** + * array3_size() - Calculate size of 3-dimensional array. + * @a: dimension one + * @b: dimension two + * @c: dimension three + * + * Calculates size of 3-dimensional array: @a * @b * @c. + * + * Returns: number of bytes needed to represent the array or SIZE_MAX on + * overflow. + */ +#define array3_size(a, b, c) size_mul(size_mul(a, b), c) + +/** + * flex_array_size() - Calculate size of a flexible array member + * within an enclosing structure. + * @p: Pointer to the structure. + * @member: Name of the flexible array member. + * @count: Number of elements in the array. + * + * Calculates size of a flexible array of @count number of @member + * elements, at the end of structure @p. + * + * Return: number of bytes needed or SIZE_MAX on overflow. + */ +#define flex_array_size(p, member, count) \ + __builtin_choose_expr(__is_constexpr(count), \ + (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ + size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) + +/** + * struct_size() - Calculate size of structure with trailing flexible array. + * @p: Pointer to the structure. + * @member: Name of the array member. + * @count: Number of elements in the array. + * + * Calculates size of memory needed for structure of @p followed by an + * array of @count number of @member elements. + * + * Return: number of bytes needed or SIZE_MAX on overflow. + */ +#define struct_size(p, member, count) \ + __builtin_choose_expr(__is_constexpr(count), \ + sizeof(*(p)) + flex_array_size(p, member, count), \ + size_add(sizeof(*(p)), flex_array_size(p, member, count))) + +/** + * struct_size_t() - Calculate size of structure with trailing flexible array + * @type: structure type name. + * @member: Name of the array member. + * @count: Number of elements in the array. + * + * Calculates size of memory needed for structure @type followed by an + * array of @count number of @member elements. Prefer using struct_size() + * when possible instead, to keep calculations associated with a specific + * instance variable of type @type. + * + * Return: number of bytes needed or SIZE_MAX on overflow. + */ +#define struct_size_t(type, member, count) \ + struct_size((type *)NULL, member, count) + +/** + * _DEFINE_FLEX() - helper macro for DEFINE_FLEX() family. + * Enables caller macro to pass (different) initializer. + * + * @type: structure type name, including "struct" keyword. + * @name: Name for a variable to define. + * @member: Name of the array member. + * @count: Number of elements in the array; must be compile-time const. + * @initializer: initializer expression (could be empty for no init). + */ +#define _DEFINE_FLEX(type, name, member, count, initializer) \ + _Static_assert(__builtin_constant_p(count), \ + "onstack flex array members require compile-time const count"); \ + union { \ + u8 bytes[struct_size_t(type, member, count)]; \ + type obj; \ + } name##_u initializer; \ + type *name = (type *)&name##_u + +/** + * DEFINE_FLEX() - Define an on-stack instance of structure with a trailing + * flexible array member. + * + * @type: structure type name, including "struct" keyword. + * @name: Name for a variable to define. + * @member: Name of the array member. + * @count: Number of elements in the array; must be compile-time const. + * + * Define a zeroed, on-stack, instance of @type structure with a trailing + * flexible array member. + * Use __struct_size(@name) to get compile-time size of it afterwards. + */ +#define DEFINE_FLEX(type, name, member, count) \ + _DEFINE_FLEX(type, name, member, count, = {}) + +#endif /* _LINUXKPI_LINUX_OVERFLOW_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/page-flags.h b/sys/compat/linuxkpi/common/include/linux/page-flags.h new file mode 100644 index 000000000000..9dd49c8492a5 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/page-flags.h @@ -0,0 +1,34 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2022 Jean-Sébastien Pédron <dumbbell@FreeBSD.org> + * + * 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_PAGEFLAGS_H_ +#define _LINUXKPI_LINUX_PAGEFLAGS_H_ + +#define PageHighMem(p) (0) + +#endif /* _LINUXKPI_LINUX_PAGEFLAGS_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/page.h b/sys/compat/linuxkpi/common/include/linux/page.h index b582966b49c3..aa5acac4f5fe 100644 --- a/sys/compat/linuxkpi/common/include/linux/page.h +++ b/sys/compat/linuxkpi/common/include/linux/page.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_PAGE_H_ #define _LINUXKPI_LINUX_PAGE_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/pagemap.h b/sys/compat/linuxkpi/common/include/linux/pagemap.h index f3c8c04aa13e..7244b61257dc 100644 --- a/sys/compat/linuxkpi/common/include/linux/pagemap.h +++ b/sys/compat/linuxkpi/common/include/linux/pagemap.h @@ -24,8 +24,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_PAGEMAP_H_ @@ -33,6 +31,13 @@ #include <linux/mm.h> #include <linux/highmem.h> +#include <linux/vmalloc.h> + +#define invalidate_mapping_pages(...) \ + linux_invalidate_mapping_pages(__VA_ARGS__) + +unsigned long linux_invalidate_mapping_pages(vm_object_t obj, pgoff_t start, + pgoff_t end); static inline void release_pages(struct page **pages, int nr) diff --git a/sys/compat/linuxkpi/common/include/linux/pagevec.h b/sys/compat/linuxkpi/common/include/linux/pagevec.h index 4224124c4fe4..9ba8ff8effa0 100644 --- a/sys/compat/linuxkpi/common/include/linux/pagevec.h +++ b/sys/compat/linuxkpi/common/include/linux/pagevec.h @@ -13,7 +13,7 @@ struct pagevec { uint8_t nr; - struct vm_page *pages[PAGEVEC_SIZE]; + struct page *pages[PAGEVEC_SIZE]; }; static inline unsigned int @@ -41,7 +41,7 @@ pagevec_count(struct pagevec *pvec) } static inline unsigned int -pagevec_add(struct pagevec *pvec, struct vm_page *page) +pagevec_add(struct pagevec *pvec, struct page *page) { pvec->pages[pvec->nr++] = page; return PAGEVEC_SIZE - pvec->nr; diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h index 0652a250c697..be3b13f07e53 100644 --- a/sys/compat/linuxkpi/common/include/linux/pci.h +++ b/sys/compat/linuxkpi/common/include/linux/pci.h @@ -4,7 +4,7 @@ * Copyright (c) 2010 Panasas, Inc. * Copyright (c) 2013-2016 Mellanox Technologies, Ltd. * All rights reserved. - * Copyright (c) 2020-2021 The FreeBSD Foundation + * Copyright (c) 2020-2022 The FreeBSD Foundation * * Portions of this software were developed by Björn Zeeb * under sponsorship from the FreeBSD Foundation. @@ -29,8 +29,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_PCI_H_ #define _LINUXKPI_LINUX_PCI_H_ @@ -44,7 +42,6 @@ #include <sys/module.h> #include <sys/nv.h> #include <sys/pciio.h> -#include <sys/rman.h> #include <dev/pci/pcivar.h> #include <dev/pci/pcireg.h> #include <dev/pci/pci_private.h> @@ -57,6 +54,7 @@ #include <linux/compiler.h> #include <linux/errno.h> #include <asm/atomic.h> +#include <asm/memtype.h> #include <linux/device.h> #include <linux/pci_ids.h> #include <linux/pm.h> @@ -96,6 +94,7 @@ MODULE_PNP_INFO("U32:vendor;U32:device;V32:subvendor;V32:subdevice", \ #define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) #define PCI_FUNC(devfn) ((devfn) & 0x07) #define PCI_BUS_NUM(devfn) (((devfn) >> 8) & 0xff) +#define PCI_DEVID(bus, devfn) ((((uint16_t)(bus)) << 8) | (devfn)) #define PCI_VDEVICE(_vendor, _device) \ .vendor = PCI_VENDOR_ID_##_vendor, .device = (_device), \ @@ -106,9 +105,14 @@ MODULE_PNP_INFO("U32:vendor;U32:device;V32:subvendor;V32:subdevice", \ #define to_pci_dev(n) container_of(n, struct pci_dev, dev) -#define PCI_VENDOR_ID PCIR_DEVVENDOR +#define PCI_STD_NUM_BARS 6 +#define PCI_BASE_ADDRESS_0 PCIR_BARS +#define PCI_BASE_ADDRESS_MEM_TYPE_64 PCIM_BAR_MEM_64 +#define PCI_VENDOR_ID PCIR_VENDOR +#define PCI_DEVICE_ID PCIR_DEVICE #define PCI_COMMAND PCIR_COMMAND #define PCI_COMMAND_INTX_DISABLE PCIM_CMD_INTxDIS +#define PCI_COMMAND_MEMORY PCIM_CMD_MEMEN #define PCI_EXP_DEVCTL PCIER_DEVICE_CTL /* Device Control */ #define PCI_EXP_LNKCTL PCIER_LINK_CTL /* Link Control */ #define PCI_EXP_LNKCTL_ASPM_L0S PCIEM_LINK_CTL_ASPMC_L0S @@ -142,24 +146,38 @@ MODULE_PNP_INFO("U32:vendor;U32:device;V32:subvendor;V32:subdevice", \ #define PCI_EXP_TYPE_DOWNSTREAM PCIEM_TYPE_DOWNSTREAM_PORT /* Downstream Port */ #define PCI_EXP_FLAGS_SLOT PCIEM_FLAGS_SLOT /* Slot implemented */ #define PCI_EXP_TYPE_RC_EC PCIEM_TYPE_ROOT_EC /* Root Complex Event Collector */ +#define PCI_EXP_LNKSTA_CLS PCIEM_LINK_STA_SPEED +#define PCI_EXP_LNKSTA_CLS_8_0GB 0x0003 /* Current Link Speed 8.0GT/s */ #define PCI_EXP_LNKCAP_SLS_2_5GB 0x01 /* Supported Link Speed 2.5GT/s */ #define PCI_EXP_LNKCAP_SLS_5_0GB 0x02 /* Supported Link Speed 5.0GT/s */ -#define PCI_EXP_LNKCAP_SLS_8_0GB 0x04 /* Supported Link Speed 8.0GT/s */ -#define PCI_EXP_LNKCAP_SLS_16_0GB 0x08 /* Supported Link Speed 16.0GT/s */ +#define PCI_EXP_LNKCAP_SLS_8_0GB 0x03 /* Supported Link Speed 8.0GT/s */ +#define PCI_EXP_LNKCAP_SLS_16_0GB 0x04 /* Supported Link Speed 16.0GT/s */ +#define PCI_EXP_LNKCAP_SLS_32_0GB 0x05 /* Supported Link Speed 32.0GT/s */ +#define PCI_EXP_LNKCAP_SLS_64_0GB 0x06 /* Supported Link Speed 64.0GT/s */ #define PCI_EXP_LNKCAP_MLW 0x03f0 /* Maximum Link Width */ #define PCI_EXP_LNKCAP2_SLS_2_5GB 0x02 /* Supported Link Speed 2.5GT/s */ #define PCI_EXP_LNKCAP2_SLS_5_0GB 0x04 /* Supported Link Speed 5.0GT/s */ #define PCI_EXP_LNKCAP2_SLS_8_0GB 0x08 /* Supported Link Speed 8.0GT/s */ #define PCI_EXP_LNKCAP2_SLS_16_0GB 0x10 /* Supported Link Speed 16.0GT/s */ +#define PCI_EXP_LNKCAP2_SLS_32_0GB 0x20 /* Supported Link Speed 32.0GT/s */ +#define PCI_EXP_LNKCAP2_SLS_64_0GB 0x40 /* Supported Link Speed 64.0GT/s */ #define PCI_EXP_LNKCTL2_TLS 0x000f #define PCI_EXP_LNKCTL2_TLS_2_5GT 0x0001 /* Supported Speed 2.5GT/s */ #define PCI_EXP_LNKCTL2_TLS_5_0GT 0x0002 /* Supported Speed 5GT/s */ #define PCI_EXP_LNKCTL2_TLS_8_0GT 0x0003 /* Supported Speed 8GT/s */ #define PCI_EXP_LNKCTL2_TLS_16_0GT 0x0004 /* Supported Speed 16GT/s */ #define PCI_EXP_LNKCTL2_TLS_32_0GT 0x0005 /* Supported Speed 32GT/s */ +#define PCI_EXP_LNKCTL2_TLS_64_0GT 0x0006 /* Supported Speed 64GT/s */ #define PCI_EXP_LNKCTL2_ENTER_COMP 0x0010 /* Enter Compliance */ #define PCI_EXP_LNKCTL2_TX_MARGIN 0x0380 /* Transmit Margin */ +#define PCI_MSI_ADDRESS_LO PCIR_MSI_ADDR +#define PCI_MSI_ADDRESS_HI PCIR_MSI_ADDR_HIGH +#define PCI_MSI_FLAGS PCIR_MSI_CTRL +#define PCI_MSI_FLAGS_ENABLE PCIM_MSICTRL_MSI_ENABLE +#define PCI_MSIX_FLAGS PCIR_MSIX_CTRL +#define PCI_MSIX_FLAGS_ENABLE PCIM_MSIXCTRL_MSIX_ENABLE + #define PCI_EXP_LNKCAP_CLKPM 0x00040000 #define PCI_EXP_DEVSTA_TRPND 0x0020 @@ -173,6 +191,8 @@ enum pci_bus_speed { PCIE_SPEED_5_0GT, PCIE_SPEED_8_0GT, PCIE_SPEED_16_0GT, + PCIE_SPEED_32_0GT, + PCIE_SPEED_64_0GT, }; enum pcie_link_width { @@ -201,6 +221,8 @@ typedef int pci_power_t; #define PCI_POWER_ERROR PCI_POWERSTATE_UNKNOWN +extern const char *pci_power_names[6]; + #define PCI_ERR_ROOT_COMMAND PCIR_AER_ROOTERR_CMD #define PCI_ERR_ROOT_ERR_SRC PCIR_AER_COR_SOURCE_ID @@ -213,6 +235,7 @@ typedef int pci_power_t; #define PCI_IRQ_LEGACY 0x01 #define PCI_IRQ_MSI 0x02 #define PCI_IRQ_MSIX 0x04 +#define PCI_IRQ_ALL_TYPES (PCI_IRQ_MSIX|PCI_IRQ_MSI|PCI_IRQ_LEGACY) struct pci_dev; @@ -240,6 +263,7 @@ struct pci_driver { struct pci_bus { struct pci_dev *self; + /* struct pci_bus *parent */ int domain; int number; }; @@ -269,10 +293,31 @@ _pci_exit(void) \ module_init(_pci_init); \ module_exit(_pci_exit) +struct msi_msg { + uint32_t data; +}; + +struct pci_msi_desc { + struct { + bool is_64; + } msi_attrib; +}; + +struct msi_desc { + struct msi_msg msg; + struct pci_msi_desc pci; +}; + +struct msix_entry { + int entry; + int vector; +}; + /* * If we find drivers accessing this from multiple KPIs we may have to * refcount objects of this structure. */ +struct resource; struct pci_mmio_region { TAILQ_ENTRY(pci_mmio_region) next; struct resource *res; @@ -286,6 +331,7 @@ struct pci_dev { struct pci_driver *pdrv; struct pci_bus *bus; struct pci_dev *root; + pci_power_t current_state; uint16_t device; uint16_t vendor; uint16_t subsystem_vendor; @@ -294,39 +340,58 @@ struct pci_dev { unsigned int devfn; uint32_t class; uint8_t revision; + uint8_t msi_cap; + uint8_t msix_cap; bool managed; /* devres "pcim_*(). */ bool want_iomap_res; bool msi_enabled; bool msix_enabled; phys_addr_t rom; size_t romlen; + struct msi_desc **msi_desc; + char *path_name; + spinlock_t pcie_cap_lock; TAILQ_HEAD(, pci_mmio_region) mmio; }; -/* We need some meta-struct to keep track of these for devres. */ -struct pci_devres { - bool enable_io; - /* PCIR_MAX_BAR_0 + 1 = 6 => BIT(0..5). */ - uint8_t region_mask; - struct resource *region_table[PCIR_MAX_BAR_0 + 1]; /* Not needed. */ -}; -struct pcim_iomap_devres { - void *mmio_table[PCIR_MAX_BAR_0 + 1]; - struct resource *res_table[PCIR_MAX_BAR_0 + 1]; -}; - int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name); int pci_alloc_irq_vectors(struct pci_dev *pdev, int minv, int maxv, unsigned int flags); +bool pci_device_is_present(struct pci_dev *pdev); + +int linuxkpi_pcim_enable_device(struct pci_dev *pdev); +void __iomem **linuxkpi_pcim_iomap_table(struct pci_dev *pdev); +void *linuxkpi_pci_iomap(struct pci_dev *pdev, int mmio_bar, int mmio_size); +void linuxkpi_pci_iounmap(struct pci_dev *pdev, void *res); +int linuxkpi_pcim_iomap_regions(struct pci_dev *pdev, uint32_t mask, + const char *name); +int linuxkpi_pci_request_regions(struct pci_dev *pdev, const char *res_name); +void linuxkpi_pci_release_region(struct pci_dev *pdev, int bar); +void linuxkpi_pci_release_regions(struct pci_dev *pdev); +int linuxkpi_pci_enable_msix(struct pci_dev *pdev, struct msix_entry *entries, + int nreq); /* Internal helper function(s). */ struct pci_dev *lkpinew_pci_dev(device_t); -struct pci_devres *lkpi_pci_devres_get_alloc(struct pci_dev *pdev); void lkpi_pci_devres_release(struct device *, void *); -struct resource *_lkpi_pci_iomap(struct pci_dev *pdev, int bar, int mmio_size); -struct pcim_iomap_devres *lkpi_pcim_iomap_devres_find(struct pci_dev *pdev); -void lkpi_pcim_iomap_table_release(struct device *, void *); +struct pci_dev *lkpi_pci_get_device(uint16_t, uint16_t, struct pci_dev *); +struct msi_desc *lkpi_pci_msi_desc_alloc(int); +struct device *lkpi_pci_find_irq_dev(unsigned int irq); +int _lkpi_pci_enable_msi_range(struct pci_dev *pdev, int minvec, int maxvec); + +static inline bool +dev_is_pci(struct device *dev) +{ + + return (device_get_devclass(dev->bsddev) == devclass_find("pci")); +} + +static inline uint16_t +pci_dev_id(struct pci_dev *pdev) +{ + return (PCI_DEVID(pdev->bus->number, pdev->devfn)); +} static inline int pci_resource_type(struct pci_dev *pdev, int bar) @@ -343,56 +408,6 @@ pci_resource_type(struct pci_dev *pdev, int bar) return (SYS_RES_MEMORY); } -struct resource_list_entry *linux_pci_reserve_bar(struct pci_dev *pdev, - struct resource_list *rl, int type, int rid); - -static inline struct resource_list_entry * -linux_pci_get_rle(struct pci_dev *pdev, int type, int rid, bool reserve_bar) -{ - struct pci_devinfo *dinfo; - struct resource_list *rl; - struct resource_list_entry *rle; - - dinfo = device_get_ivars(pdev->dev.bsddev); - rl = &dinfo->resources; - rle = resource_list_find(rl, type, rid); - /* Reserve resources for this BAR if needed. */ - if (rle == NULL && reserve_bar) - rle = linux_pci_reserve_bar(pdev, rl, type, rid); - return (rle); -} - -static inline struct resource_list_entry * -linux_pci_get_bar(struct pci_dev *pdev, int bar, bool reserve) -{ - int type; - - type = pci_resource_type(pdev, bar); - if (type < 0) - return (NULL); - bar = PCIR_BAR(bar); - return (linux_pci_get_rle(pdev, type, bar, reserve)); -} - -static inline struct device * -linux_pci_find_irq_dev(unsigned int irq) -{ - struct pci_dev *pdev; - struct device *found; - - found = NULL; - spin_lock(&pci_lock); - list_for_each_entry(pdev, &pci_devices, links) { - if (irq == pdev->dev.irq || - (irq >= pdev->dev.irq_start && irq < pdev->dev.irq_end)) { - found = &pdev->dev; - break; - } - } - spin_unlock(&pci_lock); - return (found); -} - /* * All drivers just seem to want to inspect the type not flags. */ @@ -410,8 +425,7 @@ pci_resource_flags(struct pci_dev *pdev, int bar) static inline const char * pci_name(struct pci_dev *d) { - - return device_get_desc(d->dev.bsddev); + return d->path_name; } static inline void * @@ -527,73 +541,10 @@ done: return (pdev->bus->self); } -static inline struct pci_devres * -lkpi_pci_devres_find(struct pci_dev *pdev) -{ - - if (!pdev->managed) - return (NULL); - - return (lkpi_pci_devres_get_alloc(pdev)); -} - -static inline void -pci_release_region(struct pci_dev *pdev, int bar) -{ - struct resource_list_entry *rle; - struct pci_devres *dr; - struct pci_mmio_region *mmio, *p; - - if ((rle = linux_pci_get_bar(pdev, bar, false)) == NULL) - return; - - /* - * As we implicitly track the requests we also need to clear them on - * release. Do clear before resource release. - */ - dr = lkpi_pci_devres_find(pdev); - if (dr != NULL) { - KASSERT(dr->region_table[bar] == rle->res, ("%s: pdev %p bar %d" - " region_table res %p != rel->res %p\n", __func__, pdev, - bar, dr->region_table[bar], rle->res)); - dr->region_table[bar] = NULL; - dr->region_mask &= ~(1 << bar); - } - - TAILQ_FOREACH_SAFE(mmio, &pdev->mmio, next, p) { - if (rle->res != (void *)rman_get_bushandle(mmio->res)) - continue; - TAILQ_REMOVE(&pdev->mmio, mmio, next); - free(mmio, M_DEVBUF); - } - - bus_release_resource(pdev->dev.bsddev, rle->type, rle->rid, rle->res); -} - -static inline void -pci_release_regions(struct pci_dev *pdev) -{ - int i; - - for (i = 0; i <= PCIR_MAX_BAR_0; i++) - pci_release_region(pdev, i); -} - -static inline int -pci_request_regions(struct pci_dev *pdev, const char *res_name) -{ - int error; - int i; - - for (i = 0; i <= PCIR_MAX_BAR_0; i++) { - error = pci_request_region(pdev, i, res_name); - if (error && error != -ENODEV) { - pci_release_regions(pdev); - return (error); - } - } - return (0); -} +#define pci_release_region(pdev, bar) linuxkpi_pci_release_region(pdev, bar) +#define pci_release_regions(pdev) linuxkpi_pci_release_regions(pdev) +#define pci_request_regions(pdev, res_name) \ + linuxkpi_pci_request_regions(pdev, res_name) static inline void lkpi_pci_disable_msix(struct pci_dev *pdev) @@ -604,7 +555,7 @@ lkpi_pci_disable_msix(struct pci_dev *pdev) /* * The MSIX IRQ numbers associated with this PCI device are no * longer valid and might be re-assigned. Make sure - * linux_pci_find_irq_dev() does no longer see them by + * lkpi_pci_find_irq_dev() does no longer see them by * resetting their references to zero: */ pdev->dev.irq_start = 0; @@ -762,11 +713,6 @@ void linux_pci_unregister_drm_driver(struct pci_driver *pdrv); #define pci_register_driver(pdrv) linux_pci_register_driver(pdrv) #define pci_unregister_driver(pdrv) linux_pci_unregister_driver(pdrv) -struct msix_entry { - int entry; - int vector; -}; - /* * Enable msix, positive errors indicate actual number of available * vectors. Negative errors are failures. @@ -774,42 +720,7 @@ struct msix_entry { * NB: define added to prevent this definition of pci_enable_msix from * clashing with the native FreeBSD version. */ -#define pci_enable_msix(...) \ - linux_pci_enable_msix(__VA_ARGS__) - -static inline int -pci_enable_msix(struct pci_dev *pdev, struct msix_entry *entries, int nreq) -{ - struct resource_list_entry *rle; - int error; - int avail; - int i; - - avail = pci_msix_count(pdev->dev.bsddev); - if (avail < nreq) { - if (avail == 0) - return -EINVAL; - return avail; - } - avail = nreq; - if ((error = -pci_alloc_msix(pdev->dev.bsddev, &avail)) != 0) - return error; - /* - * Handle case where "pci_alloc_msix()" may allocate less - * interrupts than available and return with no error: - */ - if (avail < nreq) { - pci_release_msi(pdev->dev.bsddev); - return avail; - } - rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1, false); - pdev->dev.irq_start = rle->start; - pdev->dev.irq_end = rle->start + avail; - for (i = 0; i < nreq; i++) - entries[i].vector = pdev->dev.irq_start + i; - pdev->msix_enabled = true; - return (0); -} +#define pci_enable_msix(...) linuxkpi_pci_enable_msix(__VA_ARGS__) #define pci_enable_msix_range(...) \ linux_pci_enable_msix_range(__VA_ARGS__) @@ -843,24 +754,8 @@ pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, static inline int pci_enable_msi(struct pci_dev *pdev) { - struct resource_list_entry *rle; - int error; - int avail; - avail = pci_msi_count(pdev->dev.bsddev); - if (avail < 1) - return -EINVAL; - - avail = 1; /* this function only enable one MSI IRQ */ - if ((error = -pci_alloc_msi(pdev->dev.bsddev, &avail)) != 0) - return error; - - rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1, false); - pdev->dev.irq_start = rle->start; - pdev->dev.irq_end = rle->start + avail; - pdev->irq = rle->start; - pdev->msi_enabled = true; - return (0); + return (_lkpi_pci_enable_msi_range(pdev, 1, 1)); } static inline int @@ -879,35 +774,9 @@ static inline void pci_disable_sriov(struct pci_dev *dev) { } -static inline void * -pci_iomap(struct pci_dev *pdev, int mmio_bar, int mmio_size) -{ - struct resource *res; - - res = _lkpi_pci_iomap(pdev, mmio_bar, mmio_size); - if (res == NULL) - return (NULL); - /* This is a FreeBSD extension so we can use bus_*(). */ - if (pdev->want_iomap_res) - return (res); - return ((void *)rman_get_bushandle(res)); -} - -static inline void -pci_iounmap(struct pci_dev *pdev, void *res) -{ - struct pci_mmio_region *mmio, *p; - - TAILQ_FOREACH_SAFE(mmio, &pdev->mmio, next, p) { - if (res != (void *)rman_get_bushandle(mmio->res)) - continue; - bus_release_resource(pdev->dev.bsddev, - mmio->type, mmio->rid, mmio->res); - TAILQ_REMOVE(&pdev->mmio, mmio, next); - free(mmio, M_DEVBUF); - return; - } -} +#define pci_iomap(pdev, mmio_bar, mmio_size) \ + linuxkpi_pci_iomap(pdev, mmio_bar, mmio_size) +#define pci_iounmap(pdev, res) linuxkpi_pci_iounmap(pdev, res) static inline void lkpi_pci_save_state(struct pci_dev *pdev) @@ -926,6 +795,13 @@ lkpi_pci_restore_state(struct pci_dev *pdev) #define pci_save_state(dev) lkpi_pci_save_state(dev) #define pci_restore_state(dev) lkpi_pci_restore_state(dev) +static inline int +pci_reset_function(struct pci_dev *pdev) +{ + + return (-ENOSYS); +} + #define DEFINE_PCI_DEVICE_TABLE(_table) \ const struct pci_device_id _table[] __devinitdata @@ -1110,6 +986,7 @@ static bool pcie_capability_reg_implemented(struct pci_dev *dev, int pos) static inline int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *dst) { + *dst = 0; if (pos & 3) return -EINVAL; @@ -1122,6 +999,7 @@ pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *dst) static inline int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *dst) { + *dst = 0; if (pos & 3) return -EINVAL; @@ -1144,21 +1022,40 @@ pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val) } static inline int -pcie_capability_set_word(struct pci_dev *dev, int pos, uint16_t val) +pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, + uint16_t clear, uint16_t set) { int error; uint16_t v; + if (pos == PCI_EXP_LNKCTL || pos == PCI_EXP_RTCTL) + spin_lock(&dev->pcie_cap_lock); + error = pcie_capability_read_word(dev, pos, &v); - if (error != 0) - return (error); + if (error == 0) { + v &= ~clear; + v |= set; + error = pcie_capability_write_word(dev, pos, v); + } - v |= val; + if (pos == PCI_EXP_LNKCTL || pos == PCI_EXP_RTCTL) + spin_unlock(&dev->pcie_cap_lock); - error = pcie_capability_write_word(dev, pos, v); return (error); } +static inline int +pcie_capability_set_word(struct pci_dev *dev, int pos, uint16_t val) +{ + return (pcie_capability_clear_and_set_word(dev, pos, 0, val)); +} + +static inline int +pcie_capability_clear_word(struct pci_dev *dev, int pos, uint16_t val) +{ + return (pcie_capability_clear_and_set_word(dev, pos, val, 0)); +} + static inline int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed, enum pcie_link_width *width) { @@ -1208,6 +1105,10 @@ pcie_get_speed_cap(struct pci_dev *dev) return (PCIE_SPEED_8_0GT); if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_16_0GB) return (PCIE_SPEED_16_0GT); + if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_32_0GB) + return (PCIE_SPEED_32_0GT); + if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_64_0GB) + return (PCIE_SPEED_64_0GT); } else { /* pre-r3.0 */ lnkcap = pci_read_config(root, pos + PCIER_LINK_CAP, 4); if (lnkcap & PCI_EXP_LNKCAP_SLS_2_5GB) @@ -1218,6 +1119,10 @@ pcie_get_speed_cap(struct pci_dev *dev) return (PCIE_SPEED_8_0GT); if (lnkcap & PCI_EXP_LNKCAP_SLS_16_0GB) return (PCIE_SPEED_16_0GT); + if (lnkcap & PCI_EXP_LNKCAP_SLS_32_0GB) + return (PCIE_SPEED_32_0GT); + if (lnkcap & PCI_EXP_LNKCAP_SLS_64_0GB) + return (PCIE_SPEED_64_0GT); } return (PCI_SPEED_UNKNOWN); } @@ -1245,6 +1150,10 @@ PCIE_SPEED2MBS_ENC(enum pci_bus_speed spd) { switch(spd) { + case PCIE_SPEED_64_0GT: + return (64000 * 128 / 130); + case PCIE_SPEED_32_0GT: + return (32000 * 128 / 130); case PCIE_SPEED_16_0GT: return (16000 * 128 / 130); case PCIE_SPEED_8_0GT: @@ -1275,6 +1184,12 @@ pcie_bandwidth_available(struct pci_dev *pdev, return (nwidth * PCIE_SPEED2MBS_ENC(nspeed)); } +static inline bool +pcie_aspm_enabled(struct pci_dev *pdev) +{ + return (false); +} + static inline struct pci_dev * pcie_find_root_port(struct pci_dev *pdev) { @@ -1307,6 +1222,29 @@ pci_stop_and_remove_bus_device(struct pci_dev *pdev) { } +static inline int +pci_rescan_bus(struct pci_bus *pbus) +{ + device_t *devlist, parent; + int devcount, error; + + if (!device_is_attached(pbus->self->dev.bsddev)) + return (0); + /* pci_rescan_method() will work on the pcib (parent). */ + error = BUS_RESCAN(pbus->self->dev.bsddev); + if (error != 0) + return (0); + + parent = device_get_parent(pbus->self->dev.bsddev); + error = device_get_children(parent, &devlist, &devcount); + if (error != 0) + return (0); + if (devcount != 0) + free(devlist, M_TEMP); + + return (devcount); +} + /* * The following functions can be used to attach/detach the LinuxKPI's * PCI device runtime. The pci_driver and pci_device_id pointer is @@ -1401,63 +1339,17 @@ struct pci_dev *lkpi_pci_get_class(unsigned int class, struct pci_dev *from); /* -------------------------------------------------------------------------- */ -static inline int -pcim_enable_device(struct pci_dev *pdev) -{ - struct pci_devres *dr; - int error; - - /* Here we cannot run through the pdev->managed check. */ - dr = lkpi_pci_devres_get_alloc(pdev); - if (dr == NULL) - return (-ENOMEM); - - /* If resources were enabled before do not do it again. */ - if (dr->enable_io) - return (0); - - error = pci_enable_device(pdev); - if (error == 0) - dr->enable_io = true; - - /* This device is not managed. */ - pdev->managed = true; - - return (error); -} - -static inline void __iomem ** -pcim_iomap_table(struct pci_dev *pdev) -{ - struct pcim_iomap_devres *dr; - - dr = lkpi_pcim_iomap_devres_find(pdev); - if (dr == NULL) - return (NULL); - - /* - * If the driver has manually set a flag to be able to request the - * resource to use bus_read/write_<n>, return the shadow table. - */ - if (pdev->want_iomap_res) - return ((void **)dr->res_table); - - /* This is the Linux default. */ - return (dr->mmio_table); -} +#define pcim_enable_device(pdev) linuxkpi_pcim_enable_device(pdev) +#define pcim_iomap_table(pdev) linuxkpi_pcim_iomap_table(pdev) +#define pcim_iomap_regions(pdev, mask, name) \ + linuxkpi_pcim_iomap_regions(pdev, mask, name) static inline int pcim_iomap_regions_request_all(struct pci_dev *pdev, uint32_t mask, char *name) { - struct pcim_iomap_devres *dr; - void *res; - uint32_t mappings, requests, req_mask; + uint32_t requests, req_mask; int bar, error; - dr = lkpi_pcim_iomap_devres_find(pdev); - if (dr == NULL) - return (-ENOMEM); - /* Request all the BARs ("regions") we do not iomap. */ req_mask = ((1 << (PCIR_MAX_BAR_0 + 1)) - 1) & ~mask; for (bar = requests = 0; requests != req_mask; bar++) { @@ -1469,44 +1361,34 @@ pcim_iomap_regions_request_all(struct pci_dev *pdev, uint32_t mask, char *name) requests |= (1 << bar); } - /* Now iomap all the requested (by "mask") ones. */ - for (bar = mappings = 0; mappings != mask; bar++) { - if ((mask & (1 << bar)) == 0) - continue; - - /* Request double is not allowed. */ - if (dr->mmio_table[bar] != NULL) { - device_printf(pdev->dev.bsddev, "%s: bar %d %p\n", - __func__, bar, dr->mmio_table[bar]); - goto err; - } - - res = _lkpi_pci_iomap(pdev, bar, 0); - if (res == NULL) - goto err; - dr->mmio_table[bar] = (void *)rman_get_bushandle(res); - dr->res_table[bar] = res; - - mappings |= (1 << bar); - } + error = pcim_iomap_regions(pdev, mask, name); + if (error != 0) + goto err; return (0); err: for (bar = PCIR_MAX_BAR_0; bar >= 0; bar--) { - if ((mappings & (1 << bar)) != 0) { - res = dr->mmio_table[bar]; - if (res == NULL) - continue; - pci_iounmap(pdev, res); - } else if ((requests & (1 << bar)) != 0) { + if ((requests & (1 << bar)) != 0) pci_release_region(pdev, bar); - } } return (-EINVAL); } +/* + * We cannot simply re-define pci_get_device() as we would normally do + * and then hide it in linux_pci.c as too many semi-native drivers still + * include linux/pci.h and run into the conflict with native PCI. Linux drivers + * using pci_get_device() need to be changed to call linuxkpi_pci_get_device(). + */ +static inline struct pci_dev * +linuxkpi_pci_get_device(uint16_t vendor, uint16_t device, struct pci_dev *odev) +{ + + return (lkpi_pci_get_device(vendor, device, odev)); +} + /* This is a FreeBSD extension so we can use bus_*(). */ static inline void linuxkpi_pcim_want_to_use_bus_functions(struct pci_dev *pdev) @@ -1533,6 +1415,17 @@ pci_ignore_hotplug(struct pci_dev *pdev) { } +static inline const char * +pci_power_name(pci_power_t state) +{ + int pstate = state + 1; + + if (pstate >= 0 && pstate < nitems(pci_power_names)) + return (pci_power_names[pstate]); + else + return (pci_power_names[0]); +} + static inline int pcie_get_readrq(struct pci_dev *dev) { @@ -1544,4 +1437,45 @@ pcie_get_readrq(struct pci_dev *dev) return (128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12)); } +static inline bool +pci_is_enabled(struct pci_dev *pdev) +{ + + return ((pci_read_config(pdev->dev.bsddev, PCIR_COMMAND, 2) & + PCIM_CMD_BUSMASTEREN) != 0); +} + +static inline int +pci_wait_for_pending_transaction(struct pci_dev *pdev) +{ + + return (0); +} + +static inline int +pci_assign_resource(struct pci_dev *pdev, int bar) +{ + + return (0); +} + +static inline int +pci_irq_vector(struct pci_dev *pdev, unsigned int vector) +{ + + if (!pdev->msix_enabled && !pdev->msi_enabled) { + if (vector != 0) + return (-EINVAL); + return (pdev->irq); + } + + if (pdev->msix_enabled || pdev->msi_enabled) { + if ((pdev->dev.irq_start + vector) >= pdev->dev.irq_end) + return (-EINVAL); + return (pdev->dev.irq_start + vector); + } + + return (-ENXIO); +} + #endif /* _LINUXKPI_LINUX_PCI_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/pci_ids.h b/sys/compat/linuxkpi/common/include/linux/pci_ids.h index 519d1b6eb663..2f02d6ad1c14 100644 --- a/sys/compat/linuxkpi/common/include/linux/pci_ids.h +++ b/sys/compat/linuxkpi/common/include/linux/pci_ids.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_PCI_IDS_H @@ -41,23 +39,30 @@ #define PCI_BASE_CLASS_BRIDGE 0x06 #define PCI_CLASS_BRIDGE_ISA 0x0601 +#define PCI_CLASS_ACCELERATOR_PROCESSING 0x1200 + /* XXX We should really generate these and use them throughout the tree. */ #define PCI_VENDOR_ID_APPLE 0x106b #define PCI_VENDOR_ID_ASUSTEK 0x1043 +#define PCI_VENDOR_ID_ATHEROS 0x168c #define PCI_VENDOR_ID_ATI 0x1002 #define PCI_VENDOR_ID_BROADCOM 0x14e4 #define PCI_VENDOR_ID_DELL 0x1028 #define PCI_VENDOR_ID_HP 0x103c #define PCI_VENDOR_ID_IBM 0x1014 #define PCI_VENDOR_ID_INTEL 0x8086 +#define PCI_VENDOR_ID_ITTIM 0x0b48 +#define PCI_VENDOR_ID_MEDIATEK 0x14c3 #define PCI_VENDOR_ID_MELLANOX 0x15b3 +#define PCI_VENDOR_ID_QCOM 0x17cb #define PCI_VENDOR_ID_REALTEK 0x10ec #define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4 #define PCI_VENDOR_ID_SERVERWORKS 0x1166 #define PCI_VENDOR_ID_SONY 0x104d #define PCI_VENDOR_ID_TOPSPIN 0x1867 +#define PCI_VENDOR_ID_UBIQUITI 0x0777 #define PCI_VENDOR_ID_VIA 0x1106 #define PCI_SUBVENDOR_ID_REDHAT_QUMRANET 0x1af4 #define PCI_DEVICE_ID_ATI_RADEON_QY 0x5159 diff --git a/sys/compat/linuxkpi/common/include/linux/pfn.h b/sys/compat/linuxkpi/common/include/linux/pfn.h index 675f5d21364a..26d47b9bc3b1 100644 --- a/sys/compat/linuxkpi/common/include/linux/pfn.h +++ b/sys/compat/linuxkpi/common/include/linux/pfn.h @@ -22,8 +22,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_PFN_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/pfn_t.h b/sys/compat/linuxkpi/common/include/linux/pfn_t.h index 48fb4f59a3c6..f22289802cb8 100644 --- a/sys/compat/linuxkpi/common/include/linux/pfn_t.h +++ b/sys/compat/linuxkpi/common/include/linux/pfn_t.h @@ -22,8 +22,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_PFN_T_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/pid.h b/sys/compat/linuxkpi/common/include/linux/pid.h index be7c9384d4cf..60cb9f725b21 100644 --- a/sys/compat/linuxkpi/common/include/linux/pid.h +++ b/sys/compat/linuxkpi/common/include/linux/pid.h @@ -22,8 +22,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_PID_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/platform_device.h b/sys/compat/linuxkpi/common/include/linux/platform_device.h new file mode 100644 index 000000000000..6853e709cb70 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/platform_device.h @@ -0,0 +1,97 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020-2022 Bjoern A. Zeeb + * + * 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_PLATFORM_DEVICE_H +#define _LINUXKPI_LINUX_PLATFORM_DEVICE_H + +#include <linux/kernel.h> +#include <linux/device.h> + +struct platform_device { + const char *name; + int id; + bool id_auto; + struct device dev; +}; + +struct platform_driver { + int (*remove)(struct platform_device *); + struct device_driver driver; +}; + +#define dev_is_platform(dev) (false) +#define to_platform_device(dev) (NULL) + +static __inline int +platform_driver_register(struct platform_driver *pdrv) +{ + + pr_debug("%s: TODO\n", __func__); + return (-ENXIO); +} + +static __inline void * +dev_get_platdata(struct device *dev) +{ + + pr_debug("%s: TODO\n", __func__); + return (NULL); +} + +static __inline int +platform_driver_probe(struct platform_driver *pdrv, + int(*pd_probe_f)(struct platform_device *)) +{ + + pr_debug("%s: TODO\n", __func__); + return (-ENODEV); +} + +static __inline void +platform_driver_unregister(struct platform_driver *pdrv) +{ + + pr_debug("%s: TODO\n", __func__); + return; +} + +static __inline int +platform_device_register(struct platform_device *pdev) +{ + pr_debug("%s: TODO\n", __func__); + return (0); +} + +static __inline void +platform_device_unregister(struct platform_device *pdev) +{ + + pr_debug("%s: TODO\n", __func__); + return; +} + +#endif /* _LINUXKPI_LINUX_PLATFORM_DEVICE_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/pm.h b/sys/compat/linuxkpi/common/include/linux/pm.h index d67cebb9764a..871c7b587864 100644 --- a/sys/compat/linuxkpi/common/include/linux/pm.h +++ b/sys/compat/linuxkpi/common/include/linux/pm.h @@ -26,17 +26,20 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_PM_H #define _LINUXKPI_LINUX_PM_H +#include <linux/kernel.h> /* pr_debug */ +#include <asm/atomic.h> + /* Needed but breaks linux_usb.c */ /* #include <linux/completion.h> */ /* #include <linux/wait.h> */ +struct device; + typedef struct pm_message { int event; } pm_message_t; @@ -44,23 +47,50 @@ typedef struct pm_message { struct dev_pm_domain { }; +struct dev_pm_info { + atomic_t usage_count; +}; + #define PM_EVENT_FREEZE 0x0001 #define PM_EVENT_SUSPEND 0x0002 +#define pm_sleep_ptr(_p) \ + IS_ENABLED(CONFIG_PM_SLEEP) ? (_p) : NULL + #ifdef CONFIG_PM_SLEEP #define SIMPLE_DEV_PM_OPS(_name, _suspendfunc, _resumefunc) \ const struct dev_pm_ops _name = { \ - .suspend = _suspendfunc, \ - .resume = _resumefunc, \ - .freeze = _suspendfunc, \ - .thaw = _resumefunc, \ - .poweroff = _suspendfunc, \ - .restore = _resumefunc, \ + .suspend = _suspendfunc, \ + .resume = _resumefunc, \ + .freeze = _suspendfunc, \ + .thaw = _resumefunc, \ + .poweroff = _suspendfunc, \ + .restore = _resumefunc, \ +} + +#define DEFINE_SIMPLE_DEV_PM_OPS(_name, _suspendfunc, _resumefunc) \ +const struct dev_pm_ops _name = { \ + .suspend = _suspendfunc, \ + .resume = _resumefunc, \ + .freeze = _suspendfunc, \ + .thaw = _resumefunc, \ + .poweroff = _suspendfunc, \ + .restore = _resumefunc, \ } #else #define SIMPLE_DEV_PM_OPS(_name, _suspendfunc, _resumefunc) \ const struct dev_pm_ops _name = { \ } +#define DEFINE_SIMPLE_DEV_PM_OPS(_name, _suspendfunc, _resumefunc) \ +const struct dev_pm_ops _name = { \ +} #endif +static inline void +pm_wakeup_event(struct device *dev __unused, unsigned int x __unused) +{ + + pr_debug("%s: TODO\n", __func__); +} + #endif /* _LINUXKPI_LINUX_PM_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/pm_qos.h b/sys/compat/linuxkpi/common/include/linux/pm_qos.h index 8a9b3bdbd1ef..47c41a819ba8 100644 --- a/sys/compat/linuxkpi/common/include/linux/pm_qos.h +++ b/sys/compat/linuxkpi/common/include/linux/pm_qos.h @@ -23,8 +23,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_PM_QOS_H diff --git a/sys/compat/linuxkpi/common/include/linux/pm_runtime.h b/sys/compat/linuxkpi/common/include/linux/pm_runtime.h index 42c96a92b1ad..616dd508e562 100644 --- a/sys/compat/linuxkpi/common/include/linux/pm_runtime.h +++ b/sys/compat/linuxkpi/common/include/linux/pm_runtime.h @@ -40,4 +40,10 @@ pm_runtime_get_if_active(struct device *dev, bool x) return 1; } +static inline int +pm_runtime_suspended(struct device *dev) +{ + return 0; +} + #endif /* _LINUXKPI_LINUX_PM_RUNTIME_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/poll.h b/sys/compat/linuxkpi/common/include/linux/poll.h index ff83fb1959f6..3acb3c740954 100644 --- a/sys/compat/linuxkpi/common/include/linux/poll.h +++ b/sys/compat/linuxkpi/common/include/linux/poll.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_POLL_H_ #define _LINUXKPI_LINUX_POLL_H_ @@ -34,6 +32,7 @@ #include <sys/poll.h> #include <sys/fcntl.h> +#include <linux/eventpoll.h> #include <linux/wait.h> #include <linux/file.h> diff --git a/sys/compat/linuxkpi/common/include/linux/power_supply.h b/sys/compat/linuxkpi/common/include/linux/power_supply.h index cf8a937b04ad..8855cfff0539 100644 --- a/sys/compat/linuxkpi/common/include/linux/power_supply.h +++ b/sys/compat/linuxkpi/common/include/linux/power_supply.h @@ -24,8 +24,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_POWER_SUPPLY_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/preempt.h b/sys/compat/linuxkpi/common/include/linux/preempt.h index b8deb23d7089..32177d4a980c 100644 --- a/sys/compat/linuxkpi/common/include/linux/preempt.h +++ b/sys/compat/linuxkpi/common/include/linux/preempt.h @@ -22,8 +22,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_PREEMPT_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/prefetch.h b/sys/compat/linuxkpi/common/include/linux/prefetch.h index aa997d50a3f3..71839f0ca191 100644 --- a/sys/compat/linuxkpi/common/include/linux/prefetch.h +++ b/sys/compat/linuxkpi/common/include/linux/prefetch.h @@ -24,8 +24,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_PREFETCH_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/printk.h b/sys/compat/linuxkpi/common/include/linux/printk.h index 317c6232bbc5..933d5aa6f94a 100644 --- a/sys/compat/linuxkpi/common/include/linux/printk.h +++ b/sys/compat/linuxkpi/common/include/linux/printk.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_PRINTK_H_ #define _LINUXKPI_LINUX_PRINTK_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h b/sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h new file mode 100644 index 000000000000..aad46cc25b1b --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h @@ -0,0 +1,75 @@ +/*- + * Copyright (c) 2023 The FreeBSD Foundation + * + * This software was developed by Björn Zeeb 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_PTP_CLOCK_KERNEL_H +#define _LINUXKPI_LINUX_PTP_CLOCK_KERNEL_H + +#include <linux/types.h> +#include <linux/device.h> +#include <linux/kernel.h> /* pr_debug */ +#include <linux/ktime.h> /* system_device_crosststamp */ + +/* This very likely belongs elsewhere. */ +struct system_device_crosststamp { + ktime_t device; + ktime_t sys_realtime; + ktime_t sys_monotonic_raw; /* name guessed based on comment */ +}; + +struct ptp_clock_info { + char name[32]; + int max_adj; + void *owner; /* THIS_MODULE */ + int (*adjfine)(struct ptp_clock_info *, long); + 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 *); +}; + +static inline struct ptp_clock * +ptp_clock_register(struct ptp_clock_info *ptpci, struct device *dev) +{ + + pr_debug("%s: TODO\n", __func__); + return (NULL); +} + +static inline void +ptp_clock_unregister(struct ptp_clock *ptpc) +{ + pr_debug("%s: TODO\n", __func__); +} + +static inline int +ptp_clock_index(struct ptp_clock *ptpc) +{ + pr_debug("%s: TODO\n", __func__); + return (0); +} + +#endif /* _LINUXKPI_LINUX_PTP_CLOCK_KERNEL_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/qrtr.h b/sys/compat/linuxkpi/common/include/linux/qrtr.h new file mode 100644 index 000000000000..1d2af0efdce2 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/qrtr.h @@ -0,0 +1,41 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2022 Bjoern A. Zeeb + * + * 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_QRTR_H +#define _LINUXKPI_LINUX_QRTR_H + +/* Qualcomm IPC Router (QRTR) */ + +#include <sys/socket.h> + +struct sockaddr_qrtr { + sa_family_t sq_family; + uint32_t sq_node; + uint32_t sq_port; +}; + +#endif /* _LINUXKPI_LINUX_QRTR_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/radix-tree.h b/sys/compat/linuxkpi/common/include/linux/radix-tree.h index 86620614fb36..a1204cb20a79 100644 --- a/sys/compat/linuxkpi/common/include/linux/radix-tree.h +++ b/sys/compat/linuxkpi/common/include/linux/radix-tree.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_RADIX_TREE_H_ #define _LINUXKPI_LINUX_RADIX_TREE_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/random.h b/sys/compat/linuxkpi/common/include/linux/random.h index fafb87cae9fe..808c5bc55974 100644 --- a/sys/compat/linuxkpi/common/include/linux/random.h +++ b/sys/compat/linuxkpi/common/include/linux/random.h @@ -4,6 +4,10 @@ * Copyright (c) 2010 Panasas, Inc. * Copyright (c) 2013-2016 Mellanox Technologies, Ltd. * All rights reserved. + * Copyright 2023 The FreeBSD Foundation + * + * Portions of this software was developed by Björn Zeeb + * 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 @@ -25,8 +29,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_RANDOM_H_ @@ -36,8 +38,6 @@ #include <sys/random.h> #include <sys/libkern.h> -#define get_random_u32() get_random_int() - static inline void get_random_bytes(void *buf, int nbytes) { @@ -54,6 +54,30 @@ get_random_int(void) return (val); } +#define get_random_u32() get_random_int() + +/* + * See "Fast Random Integer Generation in an Interval" by Daniel Lemire + * [https://arxiv.org/pdf/1805.10941.pdf] for implementation insights. + */ +static inline uint32_t +get_random_u32_inclusive(uint32_t floor, uint32_t ceil) +{ + uint64_t x; + uint32_t t, v; + + MPASS(ceil >= floor); + + v = get_random_u32(); + t = ceil - floor + 1; + x = (uint64_t)t * v; + while (x < t) + x = (uint64_t)t * get_random_u32(); + v = x >> 32; + + return (floor + v); +} + static inline u_long get_random_long(void) { @@ -63,6 +87,21 @@ get_random_long(void) return (val); } +static inline uint64_t +get_random_u64(void) +{ + uint64_t val; + + get_random_bytes(&val, sizeof(val)); + return (val); +} + +static inline uint32_t +get_random_u32_below(uint32_t max) +{ + return (arc4random_uniform(max)); +} + static __inline uint32_t prandom_u32(void) { diff --git a/sys/compat/linuxkpi/common/include/linux/rbtree.h b/sys/compat/linuxkpi/common/include/linux/rbtree.h index de5ef0d6a3ce..78bf938eb000 100644 --- a/sys/compat/linuxkpi/common/include/linux/rbtree.h +++ b/sys/compat/linuxkpi/common/include/linux/rbtree.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_RBTREE_H_ #define _LINUXKPI_LINUX_RBTREE_H_ @@ -41,8 +39,8 @@ struct rb_node { RB_ENTRY(rb_node) __entry; }; -#define rb_left __entry.rbe_left -#define rb_right __entry.rbe_right +#define rb_left __entry.rbe_link[_RB_L] +#define rb_right __entry.rbe_link[_RB_R] /* * We provide a false structure that has the same bit pattern as tree.h @@ -74,8 +72,11 @@ RB_PROTOTYPE(linux_root, rb_node, __entry, panic_cmp); #define RB_EMPTY_NODE(node) (RB_PARENT(node, __entry) == node) #define RB_CLEAR_NODE(node) RB_SET_PARENT(node, node, __entry) -#define rb_insert_color(node, root) \ - linux_root_RB_INSERT_COLOR((struct linux_root *)(root), (node)) +#define rb_insert_color(node, root) do { \ + if (rb_parent(node)) \ + linux_root_RB_INSERT_COLOR((struct linux_root *)(root), \ + rb_parent(node), (node)); \ +} while (0) #define rb_erase(node, root) \ linux_root_RB_REMOVE((struct linux_root *)(root), (node)) #define rb_next(node) RB_NEXT(linux_root, NULL, (node)) @@ -132,11 +133,12 @@ rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root) { - RB_SWAP_CHILD((struct linux_root *)root, victim, new, __entry); - if (victim->rb_left) - RB_SET_PARENT(victim->rb_left, new, __entry); - if (victim->rb_right) - RB_SET_PARENT(victim->rb_right, new, __entry); + RB_SWAP_CHILD((struct linux_root *)root, rb_parent(victim), + victim, new, __entry); + if (RB_LEFT(victim, __entry)) + RB_SET_PARENT(RB_LEFT(victim, __entry), new, __entry); + if (RB_RIGHT(victim, __entry)) + RB_SET_PARENT(RB_RIGHT(victim, __entry), new, __entry); *new = *victim; } @@ -144,7 +146,9 @@ static inline void rb_insert_color_cached(struct rb_node *node, struct rb_root_cached *root, bool leftmost) { - linux_root_RB_INSERT_COLOR((struct linux_root *)&root->rb_root, node); + if (rb_parent(node)) + linux_root_RB_INSERT_COLOR((struct linux_root *)&root->rb_root, + rb_parent(node), node); if (leftmost) root->rb_leftmost = node; } diff --git a/sys/compat/linuxkpi/common/include/linux/rculist.h b/sys/compat/linuxkpi/common/include/linux/rculist.h index e0c3f79d9e5a..066ed92b7996 100644 --- a/sys/compat/linuxkpi/common/include/linux/rculist.h +++ b/sys/compat/linuxkpi/common/include/linux/rculist.h @@ -23,8 +23,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_RCULIST_H_ @@ -44,6 +42,11 @@ &(pos)->member != (head); \ pos = list_entry_rcu((pos)->member.next, typeof(*(pos)), member)) +#define list_for_each_entry_from_rcu(pos, head, member) \ + for (; \ + &(pos)->member != (head); \ + pos = list_entry_rcu((pos)->member.next, typeof(*(pos)), member)) + #define list_for_each_entry_lockless(pos, head, member) \ list_for_each_entry_rcu(pos, head, member) diff --git a/sys/compat/linuxkpi/common/include/linux/rcupdate.h b/sys/compat/linuxkpi/common/include/linux/rcupdate.h index 3599616430af..95332217f8f5 100644 --- a/sys/compat/linuxkpi/common/include/linux/rcupdate.h +++ b/sys/compat/linuxkpi/common/include/linux/rcupdate.h @@ -22,8 +22,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_RCUPDATE_H_ #define _LINUXKPI_LINUX_RCUPDATE_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/refcount.h b/sys/compat/linuxkpi/common/include/linux/refcount.h index 7c055fb32029..61947485945d 100644 --- a/sys/compat/linuxkpi/common/include/linux/refcount.h +++ b/sys/compat/linuxkpi/common/include/linux/refcount.h @@ -24,8 +24,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_REFCOUNT_H @@ -79,4 +77,15 @@ refcount_dec_and_lock_irqsave(refcount_t *ref, spinlock_t *lock, return (false); } +/* + * struct kref uses atomic_t and not refcount_t so + * we differ from Linux here. + */ +static inline bool +refcount_dec_and_test(atomic_t *r) +{ + + return (atomic_dec_and_test(r)); +} + #endif /* __LINUXKPI_LINUX_REFCOUNT_H__ */ diff --git a/sys/compat/linuxkpi/common/include/linux/rhashtable.h b/sys/compat/linuxkpi/common/include/linux/rhashtable.h new file mode 100644 index 000000000000..c6958b6ee5f3 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/rhashtable.h @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2023 Bjoern A. Zeeb + * + * 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_RHASHTABLE_H +#define _LINUXKPI_LINUX_RHASHTABLE_H + +#include <linux/kernel.h> /* pr_debug */ + +struct rhash_head { +}; + +struct rhashtable_params { + uint16_t head_offset; + uint16_t key_len; + uint16_t key_offset; + uint16_t nelem_hint; + bool automatic_shrinking; +}; + +struct rhashtable { +}; + +static inline int +rhashtable_init(struct rhashtable *rht, + const struct rhashtable_params *params) +{ + + pr_debug("%s: TODO\n", __func__); + return (-1); +} + +static inline void +rhashtable_destroy(struct rhashtable *rht) +{ + pr_debug("%s: TODO\n", __func__); +} + +static inline void * +rhashtable_lookup_fast(struct rhashtable *rht, const void *key, + const struct rhashtable_params params) +{ + + pr_debug("%s: TODO\n", __func__); + return (NULL); +} + +static inline void * +rhashtable_lookup_get_insert_fast(struct rhashtable *rht, + struct rhash_head *obj, const struct rhashtable_params params) +{ + + pr_debug("%s: TODO\n", __func__); + return (NULL); +} + +static inline int +rhashtable_remove_fast(struct rhashtable *rht, + struct rhash_head *obj, const struct rhashtable_params params) +{ + + pr_debug("%s: TODO\n", __func__); + return (-ENOENT); +} + +#endif /* _LINUXKPI_LINUX_RHASHTABLE_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/rwlock.h b/sys/compat/linuxkpi/common/include/linux/rwlock.h index e7557d29e77a..8c1ee36ac4de 100644 --- a/sys/compat/linuxkpi/common/include/linux/rwlock.h +++ b/sys/compat/linuxkpi/common/include/linux/rwlock.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_RWLOCK_H_ #define _LINUXKPI_LINUX_RWLOCK_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/rwsem.h b/sys/compat/linuxkpi/common/include/linux/rwsem.h index fc3580bc186e..b7a800b12e18 100644 --- a/sys/compat/linuxkpi/common/include/linux/rwsem.h +++ b/sys/compat/linuxkpi/common/include/linux/rwsem.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_RWSEM_H_ #define _LINUXKPI_LINUX_RWSEM_H_ @@ -46,6 +44,7 @@ struct rw_semaphore { #define down_read(_rw) sx_slock(&(_rw)->sx) #define up_read(_rw) sx_sunlock(&(_rw)->sx) #define down_read_trylock(_rw) !!sx_try_slock(&(_rw)->sx) +#define down_read_killable(_rw) linux_down_read_killable(_rw) #define down_write_trylock(_rw) !!sx_try_xlock(&(_rw)->sx) #define down_write_killable(_rw) linux_down_write_killable(_rw) #define downgrade_write(_rw) sx_downgrade(&(_rw)->sx) @@ -80,6 +79,7 @@ linux_init_rwsem(struct rw_semaphore *rw, const char *name) sx_init_flags(&rw->sx, name, SX_NOWITNESS); } +extern int linux_down_read_killable(struct rw_semaphore *); extern int linux_down_write_killable(struct rw_semaphore *); #endif /* _LINUXKPI_LINUX_RWSEM_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/scatterlist.h b/sys/compat/linuxkpi/common/include/linux/scatterlist.h index a3da30e1b9a7..e462d5c649f1 100644 --- a/sys/compat/linuxkpi/common/include/linux/scatterlist.h +++ b/sys/compat/linuxkpi/common/include/linux/scatterlist.h @@ -27,8 +27,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_SCATTERLIST_H_ #define _LINUXKPI_LINUX_SCATTERLIST_H_ @@ -99,6 +97,12 @@ struct sg_dma_page_iter { #define for_each_sg(sglist, sg, sgmax, iter) \ for (iter = 0, sg = (sglist); iter < (sgmax); iter++, sg = sg_next(sg)) +#define for_each_sgtable_sg(sgt, sg, i) \ + for_each_sg((sgt)->sgl, sg, (sgt)->orig_nents, i) + +#define for_each_sgtable_page(sgt, iter, pgoffset) \ + for_each_sg_page((sgt)->sgl, iter, (sgt)->orig_nents, pgoffset) + #define for_each_sgtable_dma_sg(sgt, sg, iter) \ for_each_sg((sgt)->sgl, sg, (sgt)->nents, iter) @@ -152,7 +156,7 @@ sg_next(struct scatterlist *sg) static inline vm_paddr_t sg_phys(struct scatterlist *sg) { - return (VM_PAGE_TO_PHYS(sg_page(sg)) + sg->offset); + return (page_to_phys(sg_page(sg)) + sg->offset); } static inline void * @@ -321,18 +325,40 @@ sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask) return (ret); } +#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300 +static inline struct scatterlist * +__sg_alloc_table_from_pages(struct sg_table *sgt, + struct page **pages, unsigned int count, + unsigned long off, unsigned long size, + unsigned int max_segment, + struct scatterlist *prv, unsigned int left_pages, + gfp_t gfp_mask) +#else static inline int __sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages, unsigned int count, unsigned long off, unsigned long size, unsigned int max_segment, gfp_t gfp_mask) +#endif { unsigned int i, segs, cur, len; int rc; - struct scatterlist *s; + struct scatterlist *s, *sg_iter; + +#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300 + if (prv != NULL) { + panic( + "Support for prv != NULL not implemented in " + "__sg_alloc_table_from_pages()"); + } +#endif if (__predict_false(!max_segment || offset_in_page(max_segment))) +#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300 + return (ERR_PTR(-EINVAL)); +#else return (-EINVAL); +#endif len = 0; for (segs = i = 1; i < count; ++i) { @@ -344,13 +370,25 @@ __sg_alloc_table_from_pages(struct sg_table *sgt, } } if (__predict_false((rc = sg_alloc_table(sgt, segs, gfp_mask)))) +#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300 + return (ERR_PTR(rc)); +#else return (rc); +#endif cur = 0; - for_each_sg(sgt->sgl, s, sgt->orig_nents, i) { + for_each_sg(sgt->sgl, sg_iter, sgt->orig_nents, i) { unsigned long seg_size; unsigned int j; + /* + * We need to make sure that when we exit this loop "s" has the + * last sg in the chain so we can call sg_mark_end() on it. + * Only set this inside the loop since sg_iter will be iterated + * until it is NULL. + */ + s = sg_iter; + len = 0; for (j = cur + 1; j < count; ++j) { len += PAGE_SIZE; @@ -365,7 +403,16 @@ __sg_alloc_table_from_pages(struct sg_table *sgt, off = 0; cur = j; } + KASSERT(s != NULL, ("s is NULL after loop in __sg_alloc_table_from_pages()")); + +#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300 + if (left_pages == 0) + sg_mark_end(s); + + return (s); +#else return (0); +#endif } static inline int @@ -375,8 +422,27 @@ sg_alloc_table_from_pages(struct sg_table *sgt, gfp_t gfp_mask) { +#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300 + return (PTR_ERR_OR_ZERO(__sg_alloc_table_from_pages(sgt, pages, count, off, size, + SCATTERLIST_MAX_SEGMENT, NULL, 0, gfp_mask))); +#else return (__sg_alloc_table_from_pages(sgt, pages, count, off, size, SCATTERLIST_MAX_SEGMENT, gfp_mask)); +#endif +} + +static inline int +sg_alloc_table_from_pages_segment(struct sg_table *sgt, + struct page **pages, unsigned int count, unsigned int off, + unsigned long size, unsigned int max_segment, gfp_t gfp_mask) +{ +#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300 + return (PTR_ERR_OR_ZERO(__sg_alloc_table_from_pages(sgt, pages, count, off, size, + max_segment, NULL, 0, gfp_mask))); +#else + return (__sg_alloc_table_from_pages(sgt, pages, count, off, size, + max_segment, gfp_mask)); +#endif } static inline int @@ -587,7 +653,7 @@ sg_pcopy_to_buffer(struct scatterlist *sgl, unsigned int nents, break; vaddr = (char *)sf_buf_kva(sf); } else - vaddr = (char *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(page)); + vaddr = (char *)PHYS_TO_DMAP(page_to_phys(page)); memcpy(buf, vaddr + sg->offset + offset, len); if (!PMAP_HAS_DMAP) sf_buf_free(sf); diff --git a/sys/compat/linuxkpi/common/include/linux/sched.h b/sys/compat/linuxkpi/common/include/linux/sched.h index 24014e71cda6..8cb6b12100d5 100644 --- a/sys/compat/linuxkpi/common/include/linux/sched.h +++ b/sys/compat/linuxkpi/common/include/linux/sched.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_SCHED_H_ #define _LINUXKPI_LINUX_SCHED_H_ @@ -50,6 +48,8 @@ #include <linux/spinlock.h> #include <linux/time.h> +#include <linux/sched/mm.h> + #include <asm/atomic.h> #define MAX_SCHEDULE_TIMEOUT INT_MAX diff --git a/sys/compat/linuxkpi/common/include/linux/sched/mm.h b/sys/compat/linuxkpi/common/include/linux/sched/mm.h new file mode 100644 index 000000000000..c26d99378974 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/sched/mm.h @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG + * + * 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_SCHED_MM_H_ +#define _LINUXKPI_LINUX_SCHED_MM_H_ + +#include <linux/gfp.h> + +#define fs_reclaim_acquire(x) do { \ + } while (0) +#define fs_reclaim_release(x) do { \ + } while (0) +#define memalloc_nofs_save(x) 0 +#define memalloc_nofs_restore(x) do { \ + } while (0) +#define memalloc_noreclaim_save(x) 0 +#define memalloc_noreclaim_restore(x) do { \ + } while (0) + +#endif /* _BSD_LKPI_LINUX_SCHED_MM_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/semaphore.h b/sys/compat/linuxkpi/common/include/linux/semaphore.h index da1fc73b1776..4b1a1502e589 100644 --- a/sys/compat/linuxkpi/common/include/linux/semaphore.h +++ b/sys/compat/linuxkpi/common/include/linux/semaphore.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_SEMAPHORE_H_ #define _LINUXKPI_LINUX_SEMAPHORE_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/seq_file.h b/sys/compat/linuxkpi/common/include/linux/seq_file.h index 9ab5ecce7768..d8b327f59538 100644 --- a/sys/compat/linuxkpi/common/include/linux/seq_file.h +++ b/sys/compat/linuxkpi/common/include/linux/seq_file.h @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2016-2018, Matthew Macy <mmacy@freebsd.org> * @@ -23,8 +23,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_SEQ_FILE_H_ @@ -32,11 +30,13 @@ #include <linux/types.h> #include <linux/fs.h> -#include <sys/sbuf.h> +#include <linux/string_helpers.h> #undef file #define inode vnode +MALLOC_DECLARE(M_LSEQ); + #define DEFINE_SHOW_ATTRIBUTE(__name) \ static int __name ## _open(struct inode *inode, struct linux_file *file) \ { \ @@ -51,11 +51,9 @@ static const struct file_operations __name ## _fops = { \ .release = single_release, \ } -struct seq_operations; - struct seq_file { - struct sbuf *buf; - + struct sbuf *buf; + size_t size; const struct seq_operations *op; const struct linux_file *file; void *private; @@ -70,18 +68,26 @@ struct seq_operations { ssize_t seq_read(struct linux_file *, char *, 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); +bool seq_has_overflowed(struct seq_file *m); + +void *__seq_open_private(struct linux_file *, const struct seq_operations *, int); +int seq_release_private(struct inode *, struct linux_file *); int seq_open(struct linux_file *f, const struct seq_operations *op); int seq_release(struct inode *inode, struct linux_file *file); off_t seq_lseek(struct linux_file *file, off_t offset, int whence); int single_open(struct linux_file *, int (*)(struct seq_file *, void *), void *); +int single_open_size(struct linux_file *, int (*)(struct seq_file *, void *), void *, size_t); int single_release(struct inode *, struct linux_file *); -#define seq_printf(m, fmt, ...) sbuf_printf((m)->buf, (fmt), ##__VA_ARGS__) +void lkpi_seq_vprintf(struct seq_file *m, const char *fmt, va_list args); +void lkpi_seq_printf(struct seq_file *m, const char *fmt, ...); -#define seq_puts(m, str) sbuf_printf((m)->buf, str) -#define seq_putc(m, str) sbuf_putc((m)->buf, str) +#define seq_vprintf(...) lkpi_seq_vprintf(__VA_ARGS__) +#define seq_printf(...) lkpi_seq_printf(__VA_ARGS__) #define file linux_file diff --git a/sys/compat/linuxkpi/common/include/linux/seqlock.h b/sys/compat/linuxkpi/common/include/linux/seqlock.h index 6e81e7a0fa45..48e42efc10fe 100644 --- a/sys/compat/linuxkpi/common/include/linux/seqlock.h +++ b/sys/compat/linuxkpi/common/include/linux/seqlock.h @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org> * @@ -31,8 +31,10 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/cdefs.h> #include <sys/lock.h> #include <sys/mutex.h> +#include <sys/rwlock.h> #include <sys/seqc.h> struct lock_class_key; @@ -48,6 +50,12 @@ struct seqlock { }; typedef struct seqlock seqlock_t; +struct seqcount_mutex { + seqc_t seqc; +}; +typedef struct seqcount_mutex seqcount_mutex_t; +typedef struct seqcount_mutex seqcount_ww_mutex_t; + static inline void __seqcount_init(struct seqcount *seqcount, const char *name __unused, struct lock_class_key *key __unused) @@ -57,16 +65,43 @@ __seqcount_init(struct seqcount *seqcount, const char *name __unused, #define seqcount_init(seqcount) __seqcount_init(seqcount, NULL, NULL) static inline void -write_seqcount_begin(struct seqcount *seqcount) +seqcount_mutex_init(struct seqcount_mutex *seqcount, void *mutex __unused) { - seqc_sleepable_write_begin(&seqcount->seqc); + seqcount->seqc = 0; } +#define seqcount_ww_mutex_init(seqcount, ww_mutex) \ + seqcount_mutex_init((seqcount), (ww_mutex)) + +#define write_seqcount_begin(s) \ + _Generic(*(s), \ + struct seqcount: seqc_sleepable_write_begin, \ + struct seqcount_mutex: seqc_write_begin \ + )(&(s)->seqc) + +#define write_seqcount_end(s) \ + _Generic(*(s), \ + struct seqcount: seqc_sleepable_write_end, \ + struct seqcount_mutex: seqc_write_end \ + )(&(s)->seqc) + static inline void -write_seqcount_end(struct seqcount *seqcount) +lkpi_write_seqcount_invalidate(seqc_t *seqcp) { - seqc_sleepable_write_end(&seqcount->seqc); + atomic_thread_fence_rel(); + *seqcp += SEQC_MOD * 2; } +#define write_seqcount_invalidate(s) lkpi_write_seqcount_invalidate(&(s)->seqc) + +#define read_seqcount_begin(s) seqc_read(&(s)->seqc) +#define raw_read_seqcount(s) seqc_read_any(&(s)->seqc) + +static inline seqc_t +lkpi_seqprop_sequence(const seqc_t *seqcp) +{ + return (atomic_load_int(__DECONST(seqc_t *, seqcp))); +} +#define seqprop_sequence(s) lkpi_seqprop_sequence(&(s)->seqc) /* * XXX: Are predicts from inline functions still not honored by clang? @@ -76,18 +111,6 @@ write_seqcount_end(struct seqcount *seqcount) #define read_seqcount_retry(seqcount, gen) \ (!seqc_consistent(&(seqcount)->seqc, gen)) -static inline unsigned -read_seqcount_begin(const struct seqcount *seqcount) -{ - return (seqc_read(&seqcount->seqc)); -} - -static inline unsigned -raw_read_seqcount(const struct seqcount *seqcount) -{ - return (seqc_read_any(&seqcount->seqc)); -} - static inline void seqlock_init(struct seqlock *seqlock) { diff --git a/sys/compat/linuxkpi/common/include/linux/shmem_fs.h b/sys/compat/linuxkpi/common/include/linux/shmem_fs.h index 240d26c47685..efa2c855fe7d 100644 --- a/sys/compat/linuxkpi/common/include/linux/shmem_fs.h +++ b/sys/compat/linuxkpi/common/include/linux/shmem_fs.h @@ -25,20 +25,22 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_SHMEM_FS_H_ #define _LINUXKPI_LINUX_SHMEM_FS_H_ -/* Shared memory support */ -unsigned long linux_invalidate_mapping_pages(vm_object_t, pgoff_t, pgoff_t); -struct page *linux_shmem_read_mapping_page_gfp(vm_object_t, int, gfp_t); -struct linux_file *linux_shmem_file_setup(const char *, loff_t, unsigned long); -void linux_shmem_truncate_range(vm_object_t, loff_t, loff_t); +#include <linux/file.h> +#include <linux/mempolicy.h> +#include <linux/pagemap.h> +#include <linux/swap.h> -#define invalidate_mapping_pages(...) \ - linux_invalidate_mapping_pages(__VA_ARGS__) +/* Shared memory support */ +struct page *linux_shmem_read_mapping_page_gfp(vm_object_t obj, int pindex, + gfp_t gfp); +struct linux_file *linux_shmem_file_setup(const char *name, loff_t size, + unsigned long flags); +void linux_shmem_truncate_range(vm_object_t obj, loff_t lstart, + loff_t lend); #define shmem_read_mapping_page(...) \ linux_shmem_read_mapping_page_gfp(__VA_ARGS__, 0) diff --git a/sys/compat/linuxkpi/common/include/linux/shrinker.h b/sys/compat/linuxkpi/common/include/linux/shrinker.h index 05f702e62fd5..a865241cc7cb 100644 --- a/sys/compat/linuxkpi/common/include/linux/shrinker.h +++ b/sys/compat/linuxkpi/common/include/linux/shrinker.h @@ -21,16 +21,16 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_SHRINKER_H_ #define _LINUXKPI_LINUX_SHRINKER_H_ #include <sys/queue.h> +#include <linux/gfp.h> struct shrink_control { + gfp_t gfp_mask; unsigned long nr_to_scan; unsigned long nr_scanned; }; @@ -49,8 +49,14 @@ struct shrinker { int linuxkpi_register_shrinker(struct shrinker *s); void linuxkpi_unregister_shrinker(struct shrinker *s); +void linuxkpi_synchronize_shrinkers(void); +#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 60000 +#define register_shrinker(s, ...) linuxkpi_register_shrinker(s) +#else #define register_shrinker(s) linuxkpi_register_shrinker(s) +#endif #define unregister_shrinker(s) linuxkpi_unregister_shrinker(s) +#define synchronize_shrinkers() linuxkpi_synchronize_shrinkers() #endif /* _LINUXKPI_LINUX_SHRINKER_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/sizes.h b/sys/compat/linuxkpi/common/include/linux/sizes.h index b132eedff933..d8a6e75192f6 100644 --- a/sys/compat/linuxkpi/common/include/linux/sizes.h +++ b/sys/compat/linuxkpi/common/include/linux/sizes.h @@ -24,14 +24,13 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_SIZES_H_ #define _LINUXKPI_LINUX_SIZES_H_ #define SZ_1K (1024 * 1) +#define SZ_2K (1024 * 2) #define SZ_4K (1024 * 4) #define SZ_8K (1024 * 8) #define SZ_16K (1024 * 16) @@ -43,9 +42,22 @@ #define SZ_1M (1024 * 1024 * 1) #define SZ_2M (1024 * 1024 * 2) +#define SZ_4M (1024 * 1024 * 4) #define SZ_8M (1024 * 1024 * 8) #define SZ_16M (1024 * 1024 * 16) #define SZ_32M (1024 * 1024 * 32) #define SZ_64M (1024 * 1024 * 64) +#define SZ_128M (1024 * 1024 * 128) +#define SZ_256M (1024 * 1024 * 256) +#define SZ_512M (1024 * 1024 * 512) + +#define SZ_1G (1024 * 1024 * 1024 * 1) +#define SZ_2G (1024 * 1024 * 1024 * 2) +#define SZ_4G (1024 * 1024 * 1024 * 4) +#define SZ_8G (1024 * 1024 * 1024 * 8) +#define SZ_16G (1024 * 1024 * 1024 * 16) +#define SZ_32G (1024 * 1024 * 1024 * 32) + +#define SZ_64T (1024 * 1024 * 1024 * 1024 * 64) #endif diff --git a/sys/compat/linuxkpi/common/include/linux/skbuff.h b/sys/compat/linuxkpi/common/include/linux/skbuff.h index d3a795344f86..ee3f427aa6e9 100644 --- a/sys/compat/linuxkpi/common/include/linux/skbuff.h +++ b/sys/compat/linuxkpi/common/include/linux/skbuff.h @@ -1,6 +1,6 @@ /*- - * Copyright (c) 2020-2022 The FreeBSD Foundation - * Copyright (c) 2021-2022 Bjoern A. Zeeb + * Copyright (c) 2020-2023 The FreeBSD Foundation + * Copyright (c) 2021-2023 Bjoern A. Zeeb * * This software was developed by Björn Zeeb under sponsorship from * the FreeBSD Foundation. @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ /* @@ -46,6 +44,7 @@ #include <linux/gfp.h> #include <linux/compiler.h> #include <linux/spinlock.h> +#include <linux/ktime.h> /* #define SKB_DEBUG */ #ifdef SKB_DEBUG @@ -85,12 +84,25 @@ enum sk_buff_pkt_type { PACKET_OTHERHOST, }; +struct skb_shared_hwtstamps { + ktime_t hwtstamp; +}; + #define NET_SKB_PAD max(CACHE_LINE_SIZE, 32) +#define SKB_DATA_ALIGN(_x) roundup2(_x, CACHE_LINE_SIZE) struct sk_buff_head { /* XXX TODO */ - struct sk_buff *next; - struct sk_buff *prev; + union { + struct { + struct sk_buff *next; + struct sk_buff *prev; + }; + struct sk_buff_head_l { + struct sk_buff *next; + struct sk_buff *prev; + } list; + }; size_t qlen; spinlock_t lock; }; @@ -143,8 +155,10 @@ struct sk_buff { uint16_t l4hdroff; /* transport header offset from *head */ uint32_t priority; uint16_t qmap; /* queue mapping */ - uint16_t _spareu16_0; + uint16_t _flags; /* Internal flags. */ +#define _SKB_FLAGS_SKBEXTFRAG 0x0001 enum sk_buff_pkt_type pkt_type; + uint16_t mac_header; /* offset of mac_header */ /* "Scratch" area for layers to store metadata. */ /* ??? I see sizeof() operations so probably an array. */ @@ -174,6 +188,7 @@ struct sk_buff { struct sk_buff *linuxkpi_alloc_skb(size_t, gfp_t); struct sk_buff *linuxkpi_dev_alloc_skb(size_t, gfp_t); +struct sk_buff *linuxkpi_build_skb(void *, size_t); void linuxkpi_kfree_skb(struct sk_buff *); struct sk_buff *linuxkpi_skb_copy(struct sk_buff *, gfp_t); @@ -241,6 +256,16 @@ dev_kfree_skb_irq(struct sk_buff *skb) dev_kfree_skb(skb); } +static inline struct sk_buff * +build_skb(void *data, unsigned int fragsz) +{ + struct sk_buff *skb; + + skb = linuxkpi_build_skb(data, fragsz); + SKB_TRACE(skb); + return (skb); +} + /* -------------------------------------------------------------------------- */ /* XXX BZ review this one for terminal condition as Linux "queues" are special. */ @@ -467,6 +492,7 @@ skb_add_rx_frag(struct sk_buff *skb, int fragno, struct page *page, shinfo->frags[fragno].size = size; shinfo->nr_frags = fragno + 1; skb->len += size; + skb->data_len += size; skb->truesize += truesize; /* XXX TODO EXTEND truesize? */ @@ -514,8 +540,8 @@ __skb_insert(struct sk_buff *new, struct sk_buff *prev, struct sk_buff *next, SKB_TRACE_FMT(new, "prev %p next %p q %p", prev, next, q); new->prev = prev; new->next = next; - next->prev = new; - prev->next = new; + ((struct sk_buff_head_l *)next)->prev = new; + ((struct sk_buff_head_l *)prev)->next = new; q->qlen++; } @@ -525,7 +551,7 @@ __skb_queue_after(struct sk_buff_head *q, struct sk_buff *skb, { SKB_TRACE_FMT(q, "skb %p new %p", skb, new); - __skb_insert(new, skb, skb->next, q); + __skb_insert(new, skb, ((struct sk_buff_head_l *)skb)->next, q); } static inline void @@ -538,24 +564,30 @@ __skb_queue_before(struct sk_buff_head *q, struct sk_buff *skb, } static inline void -__skb_queue_tail(struct sk_buff_head *q, struct sk_buff *skb) +__skb_queue_tail(struct sk_buff_head *q, struct sk_buff *new) { - struct sk_buff *s; - SKB_TRACE2(q, skb); - q->qlen++; - s = (struct sk_buff *)q; - s->prev->next = skb; - skb->prev = s->prev; - skb->next = s; - s->prev = skb; + SKB_TRACE2(q, new); + __skb_queue_before(q, (struct sk_buff *)q, new); } static inline void -skb_queue_tail(struct sk_buff_head *q, struct sk_buff *skb) +skb_queue_tail(struct sk_buff_head *q, struct sk_buff *new) +{ + SKB_TRACE2(q, new); + return (__skb_queue_tail(q, new)); +} + +static inline struct sk_buff * +skb_peek(struct sk_buff_head *q) { + struct sk_buff *skb; + + skb = q->next; SKB_TRACE2(q, skb); - return (__skb_queue_tail(q, skb)); + if (skb == (struct sk_buff *)q) + return (NULL); + return (skb); } static inline struct sk_buff * @@ -736,13 +768,6 @@ skb_frag_size(const skb_frag_t *frag) return (-1); } -static inline bool -skb_is_nonlinear(struct sk_buff *skb) -{ - SKB_TRACE(skb); - return ((skb->data_len > 0) ? true : false); -} - #define skb_walk_frags(_skb, _frag) \ for ((_frag) = (_skb); false; (_frag)++) @@ -773,7 +798,7 @@ static inline void skb_free_frag(void *frag) { - SKB_TODO(); + page_frag_free(frag); } static inline struct sk_buff * @@ -800,25 +825,44 @@ skb_mark_not_on_list(struct sk_buff *skb) } static inline void +___skb_queue_splice(const struct sk_buff_head *from, + struct sk_buff *p, struct sk_buff *n) +{ + struct sk_buff *b, *e; + + b = from->next; + e = from->prev; + + b->prev = p; + ((struct sk_buff_head_l *)p)->next = b; + e->next = n; + ((struct sk_buff_head_l *)n)->prev = e; +} + +static inline void skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to) { - struct sk_buff *b, *e, *n; SKB_TRACE2(from, to); if (skb_queue_empty(from)) return; - /* XXX do we need a barrier around this? */ - b = from->next; - e = from->prev; - n = to->next; + ___skb_queue_splice(from, (struct sk_buff *)to, to->next); + to->qlen += from->qlen; + __skb_queue_head_init(from); +} - b->prev = (struct sk_buff *)to; - to->next = b; - e->next = n; - n->prev = e; +static inline void +skb_queue_splice_tail_init(struct sk_buff_head *from, struct sk_buff_head *to) +{ + + SKB_TRACE2(from, to); + + if (skb_queue_empty(from)) + return; + ___skb_queue_splice(from, to->prev, (struct sk_buff *)to); to->qlen += from->qlen; __skb_queue_head_init(from); } @@ -847,6 +891,13 @@ skb_network_header(struct sk_buff *skb) return (skb->head + skb->l3hdroff); } +static inline bool +skb_is_nonlinear(struct sk_buff *skb) +{ + SKB_TRACE(skb); + return ((skb->data_len > 0) ? true : false); +} + static inline int __skb_linearize(struct sk_buff *skb) { @@ -856,6 +907,13 @@ __skb_linearize(struct sk_buff *skb) } static inline int +skb_linearize(struct sk_buff *skb) +{ + + return (skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0); +} + +static inline int pskb_expand_head(struct sk_buff *skb, int x, int len, gfp_t gfp) { SKB_TRACE(skb); @@ -889,35 +947,42 @@ skb_header_cloned(struct sk_buff *skb) } static inline uint8_t * -skb_mac_header(struct sk_buff *skb) +skb_mac_header(const struct sk_buff *skb) { SKB_TRACE(skb); - SKB_TODO(); - return (NULL); + return (skb->head + skb->mac_header); } static inline void -skb_orphan(struct sk_buff *skb) +skb_reset_mac_header(struct sk_buff *skb) { SKB_TRACE(skb); - SKB_TODO(); + skb->mac_header = skb->data - skb->head; } static inline void -skb_reset_mac_header(struct sk_buff *skb) +skb_set_mac_header(struct sk_buff *skb, const size_t len) { SKB_TRACE(skb); - SKB_TODO(); + skb_reset_mac_header(skb); + skb->mac_header += len; } -static inline struct sk_buff * -skb_peek(struct sk_buff_head *q) +static inline struct skb_shared_hwtstamps * +skb_hwtstamps(struct sk_buff *skb) { - SKB_TRACE(q); + SKB_TRACE(skb); SKB_TODO(); return (NULL); } +static inline void +skb_orphan(struct sk_buff *skb) +{ + SKB_TRACE(skb); + SKB_TODO(); +} + static inline __sum16 csum_unfold(__sum16 sum) { @@ -936,7 +1001,10 @@ skb_reset_tail_pointer(struct sk_buff *skb) { SKB_TRACE(skb); +#ifdef SKB_DOING_OFFSETS_US_NOT skb->tail = (uint8_t *)(uintptr_t)(skb->data - skb->head); +#endif + skb->tail = skb->data; SKB_TRACE(skb); } @@ -965,14 +1033,6 @@ skb_copy_from_linear_data(const struct sk_buff *skb, void *dst, size_t len) memcpy(dst, skb->data, len); } -static inline struct sk_buff * -build_skb(void *data, unsigned int fragsz) -{ - - SKB_TODO(); - return (NULL); -} - static inline int skb_pad(struct sk_buff *skb, int pad) { @@ -998,13 +1058,35 @@ napi_consume_skb(struct sk_buff *skb, int budget) SKB_TODO(); } -static inline bool -skb_linearize(struct sk_buff *skb) +static inline struct sk_buff * +napi_build_skb(void *data, size_t len) { + SKB_TODO(); + return (NULL); +} + +static inline uint32_t +skb_get_hash(struct sk_buff *skb) +{ SKB_TRACE(skb); SKB_TODO(); - return (false); + return (0); +} + +static inline void +skb_mark_for_recycle(struct sk_buff *skb) +{ + SKB_TRACE(skb); + SKB_TODO(); +} + +static inline int +skb_cow_head(struct sk_buff *skb, unsigned int headroom) +{ + SKB_TRACE(skb); + SKB_TODO(); + return (-1); } #define SKB_WITH_OVERHEAD(_s) \ diff --git a/sys/compat/linuxkpi/common/include/linux/slab.h b/sys/compat/linuxkpi/common/include/linux/slab.h index 1228c4d07aa6..298306b6ea05 100644 --- a/sys/compat/linuxkpi/common/include/linux/slab.h +++ b/sys/compat/linuxkpi/common/include/linux/slab.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_SLAB_H_ #define _LINUXKPI_LINUX_SLAB_H_ @@ -43,6 +41,7 @@ MALLOC_DECLARE(M_KMALLOC); +#define kmalloc(size, flags) lkpi_kmalloc(size, flags) #define kvmalloc(size, flags) kmalloc(size, flags) #define kvzalloc(size, flags) kmalloc(size, (flags) | __GFP_ZERO) #define kvcalloc(n, size, flags) kvmalloc_array(n, size, (flags) | __GFP_ZERO) @@ -55,7 +54,6 @@ MALLOC_DECLARE(M_KMALLOC); #define vmalloc_node(size, node) __vmalloc_node(size, GFP_KERNEL, node) #define vmalloc_user(size) __vmalloc(size, GFP_KERNEL | __GFP_ZERO, 0) #define vmalloc(size) __vmalloc(size, GFP_KERNEL, 0) -#define __kmalloc(...) kmalloc(__VA_ARGS__) /* * Prefix some functions with linux_ to avoid namespace conflict @@ -67,6 +65,7 @@ MALLOC_DECLARE(M_KMALLOC); #define kmem_cache_zalloc(...) lkpi_kmem_cache_zalloc(__VA_ARGS__) #define kmem_cache_free(...) lkpi_kmem_cache_free(__VA_ARGS__) #define kmem_cache_destroy(...) linux_kmem_cache_destroy(__VA_ARGS__) +#define kmem_cache_shrink(x) (0) #define KMEM_CACHE(__struct, flags) \ linux_kmem_cache_create(#__struct, sizeof(struct __struct), \ @@ -89,6 +88,9 @@ struct linux_kmem_cache; /* drm-kmod 5.4 compat */ #define kfree_async(ptr) kfree(ptr); +#define ZERO_SIZE_PTR ((void *)16) +#define ZERO_OR_NULL_PTR(x) ((x) == NULL || (x) == ZERO_SIZE_PTR) + static inline gfp_t linux_check_m_flags(gfp_t flags) { @@ -105,7 +107,7 @@ linux_check_m_flags(gfp_t flags) } static inline void * -kmalloc(size_t size, gfp_t flags) +__kmalloc(size_t size, gfp_t flags) { return (malloc(MAX(size, sizeof(struct llist_node)), M_KMALLOC, linux_check_m_flags(flags))); @@ -177,11 +179,24 @@ krealloc(void *ptr, size_t size, gfp_t flags) return (realloc(ptr, size, M_KMALLOC, linux_check_m_flags(flags))); } +static inline void * +krealloc_array(void *ptr, size_t n, size_t size, gfp_t flags) +{ + if (WOULD_OVERFLOW(n, size)) { + return NULL; + } + + return (realloc(ptr, n * size, M_KMALLOC, linux_check_m_flags(flags))); +} + extern void linux_kfree_async(void *); static inline void kfree(const void *ptr) { + if (ZERO_OR_NULL_PTR(ptr)) + return; + if (curthread->td_critnest != 0) linux_kfree_async(__DECONST(void *, ptr)); else @@ -191,6 +206,9 @@ kfree(const void *ptr) static __inline void kfree_sensitive(const void *ptr) { + if (ZERO_OR_NULL_PTR(ptr)) + return; + zfree(__DECONST(void *, ptr), M_KMALLOC); } @@ -200,6 +218,7 @@ ksize(const void *ptr) return (malloc_usable_size(ptr)); } +extern void *lkpi_kmalloc(size_t size, gfp_t flags); extern struct linux_kmem_cache *linux_kmem_cache_create(const char *name, size_t size, size_t align, unsigned flags, linux_kmem_ctor_t *ctor); extern void *lkpi_kmem_cache_alloc(struct linux_kmem_cache *, gfp_t); diff --git a/sys/compat/linuxkpi/common/include/linux/smp.h b/sys/compat/linuxkpi/common/include/linux/smp.h index c6d011fceb5f..b057953e6282 100644 --- a/sys/compat/linuxkpi/common/include/linux/smp.h +++ b/sys/compat/linuxkpi/common/include/linux/smp.h @@ -22,13 +22,13 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_SMP_H_ #define _LINUXKPI_LINUX_SMP_H_ +#include <asm/smp.h> + /* * Important note about the use of the function provided below: * 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 new file mode 100644 index 000000000000..b0aec2d4afbd --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h @@ -0,0 +1,60 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2022-2023 Bjoern A. Zeeb + * + * 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_SOC_MEDIATEK_MTK_WED_H +#define _LINUXKPI_LINUX_SOC_MEDIATEK_MTK_WED_H + +struct mtk_wed_device { +}; + +#define WED_WO_STA_REC 0x6 + +#define mtk_wed_device_start(_dev, _mask) do { } while(0) +#define mtk_wed_device_detach(_dev) do { } while(0) +#define mtk_wed_device_irq_get(_dev, _mask) 0 +#define mtk_wed_device_irq_set_mask(_dev, _mask) do { } while(0) +#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) (-ENODEV) +#define mtk_wed_device_dma_reset(_dev) do {} while (0) +#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _entry) \ + do {} while (0) +#define mtk_wed_device_stop(_dev) do { } while(0) + +static inline bool +mtk_wed_device_active(struct mtk_wed_device *dev __unused) +{ + + return (false); +} + +static inline bool +mtk_wed_get_rx_capa(struct mtk_wed_device *dev __unused) +{ + + return (false); +} + +#endif /* _LINUXKPI_LINUX_SOC_MEDIATEK_MTK_WED_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/soc/qcom/qmi.h b/sys/compat/linuxkpi/common/include/linux/soc/qcom/qmi.h new file mode 100644 index 000000000000..647eaf271d87 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/soc/qcom/qmi.h @@ -0,0 +1,173 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2022-2023 Bjoern A. Zeeb + * + * 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_SOC_QCOM_QMI_H +#define _LINUXKPI_LINUX_SOC_QCOM_QMI_H + +/* QMI (Qualcomm MSM Interface) */ + +#include <linux/qrtr.h> + +enum soc_qcom_qmi_data_type { + QMI_EOTI, + QMI_DATA_LEN, + QMI_OPT_FLAG, + QMI_UNSIGNED_1_BYTE, + QMI_UNSIGNED_2_BYTE, + QMI_UNSIGNED_4_BYTE, + QMI_UNSIGNED_8_BYTE, + QMI_SIGNED_4_BYTE_ENUM, + QMI_STRUCT, + QMI_STRING, +}; + +#define QMI_RESULT_SUCCESS_V01 __LINE__ +#define QMI_INDICATION __LINE__ + +struct qmi_handle; + +enum soc_qcom_qmi_array_type { + NO_ARRAY, + STATIC_ARRAY, + VAR_LEN_ARRAY, +}; + +/* Should this become an enum? */ +#define QMI_COMMON_TLV_TYPE 0 + +struct qmi_elem_info { + enum soc_qcom_qmi_data_type data_type; + uint32_t elem_len; + uint32_t elem_size; + enum soc_qcom_qmi_array_type array_type; + uint8_t tlv_type; + uint32_t offset; + const struct qmi_elem_info *ei_array; +}; + +struct qmi_response_type_v01 { + uint16_t result; + uint16_t error; +}; + +struct qmi_txn { +}; + +struct qmi_service { + uint32_t node; + uint32_t port; +}; + +struct qmi_msg_handler { + uint32_t type; + uint32_t msg_id; + const struct qmi_elem_info *ei; + size_t decoded_size; + void (*fn)(struct qmi_handle *, struct sockaddr_qrtr *, struct qmi_txn *, const void *); +}; + +struct qmi_ops { + int (*new_server)(struct qmi_handle *, struct qmi_service *); + void (*del_server)(struct qmi_handle *, struct qmi_service *); +}; + +struct qmi_handle { + int sock; + + const struct qmi_msg_handler *handler; + struct qmi_ops ops; +}; + + +/* XXX-TODO need implementation somewhere... it is not in ath1xk* */ +extern struct qmi_elem_info qmi_response_type_v01_ei[]; + +static inline int +qmi_handle_init(struct qmi_handle *handle, size_t resp_len_max, + const struct qmi_ops *ops, const struct qmi_msg_handler *handler) +{ + + handle->handler = handler; + if (ops != NULL) + handle->ops = *ops; + + /* We will find out what else to do here. */ + /* XXX TODO */ + + return (0); +} + +static __inline int +qmi_add_lookup(struct qmi_handle *handle, uint32_t service, uint32_t version, + uint32_t service_ins_id) +{ + + /* XXX TODO */ + return (0); +} + +static __inline void +qmi_handle_release(struct qmi_handle *handle) +{ + + /* XXX TODO */ +} + +static __inline int +qmi_send_request(struct qmi_handle *handle, void *x, struct qmi_txn *txn, + uint32_t msd_id, size_t len, const struct qmi_elem_info *ei, void *req) +{ + + /* XXX TODO */ + return (-ENXIO); +} + +static __inline void +qmi_txn_cancel(struct qmi_txn *txn) +{ + + /* XXX TODO */ +} + +static __inline int +qmi_txn_init(struct qmi_handle *handle, struct qmi_txn *txn, + const struct qmi_elem_info *ei, void *resp) +{ + + /* XXX TODO */ + return (-ENXIO); +} + +static __inline int +qmi_txn_wait(struct qmi_txn *txn, uint64_t jiffies) +{ + + /* XXX TODO */ + return (-ENXIO); +} + +#endif /* _LINUXKPI_LINUX_SOC_QCOM_QMI_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/socket.h b/sys/compat/linuxkpi/common/include/linux/socket.h index 3afb9bdfe3ba..638ee058c2f5 100644 --- a/sys/compat/linuxkpi/common/include/linux/socket.h +++ b/sys/compat/linuxkpi/common/include/linux/socket.h @@ -25,14 +25,23 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_SOCKET_H_ #define _LINUXKPI_LINUX_SOCKET_H_ #include <sys/socket.h> +#define AF_QIPCRTR 42 + +static inline int +kernel_connect(int sd, struct sockaddr *sa, size_t salen, int flags) +{ + + /* kern_connectat()? It is used for sockaddr_qrtr by ath1xk/qmi. */ + pr_debug("%s: TODO\n", __func__); + return (-EINVAL); +} + #ifdef notyet static inline int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len) diff --git a/sys/compat/linuxkpi/common/include/linux/sort.h b/sys/compat/linuxkpi/common/include/linux/sort.h index 91ccd7ff83c4..e6196d1f41c7 100644 --- a/sys/compat/linuxkpi/common/include/linux/sort.h +++ b/sys/compat/linuxkpi/common/include/linux/sort.h @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org> * diff --git a/sys/compat/linuxkpi/common/include/linux/spinlock.h b/sys/compat/linuxkpi/common/include/linux/spinlock.h index a87cb7180b28..4bc1e2a2d431 100644 --- a/sys/compat/linuxkpi/common/include/linux/spinlock.h +++ b/sys/compat/linuxkpi/common/include/linux/spinlock.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_SPINLOCK_H_ #define _LINUXKPI_LINUX_SPINLOCK_H_ @@ -128,6 +126,7 @@ typedef struct { } while (0) #define spin_unlock_irqrestore(_l, flags) do { \ + (void)(flags); \ spin_unlock(_l); \ } while (0) diff --git a/sys/compat/linuxkpi/common/include/linux/srcu.h b/sys/compat/linuxkpi/common/include/linux/srcu.h index 0742d25d11ac..b42c28a1311b 100644 --- a/sys/compat/linuxkpi/common/include/linux/srcu.h +++ b/sys/compat/linuxkpi/common/include/linux/srcu.h @@ -22,8 +22,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_SRCU_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/stackdepot.h b/sys/compat/linuxkpi/common/include/linux/stackdepot.h new file mode 100644 index 000000000000..df223d46be6e --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/stackdepot.h @@ -0,0 +1,32 @@ +/*- + * Copyright (c) 2022 Beckhoff Automation GmbH & Co. KG + * + * 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_STACKDEPOT_H_ +#define _LINUXKPI_LINUX_STACKDEPOT_H_ + +typedef bool depot_stack_handle_t; + +#endif /* _LINUXKPI_LINUX_STACKDEPOT_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/stdarg.h b/sys/compat/linuxkpi/common/include/linux/stdarg.h new file mode 100644 index 000000000000..ab2fdf7534e5 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/stdarg.h @@ -0,0 +1,33 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org> + * + * 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 unmodified, 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 ``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 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_STDARG_H_ +#define _LINUXKPI_STDARG_H_ + +#include <machine/stdarg.h> + +#endif /* _LINUXKPI_STDARG_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/stddef.h b/sys/compat/linuxkpi/common/include/linux/stddef.h new file mode 100644 index 000000000000..a3bc6b13765e --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/stddef.h @@ -0,0 +1,15 @@ +/* Public domain */ + +#ifndef _LINUXKPI_LINUX_STDDEF_H_ +#define _LINUXKPI_LINUX_STDDEF_H_ + +#include <sys/stddef.h> + +#define struct_group(NAME, ...) \ + union { \ + struct { __VA_ARGS__ }; \ + struct { __VA_ARGS__ } NAME; \ + } + +#endif /* _LINUXKPI_LINUX_STDDEF_H_ */ + diff --git a/sys/compat/linuxkpi/common/include/linux/string.h b/sys/compat/linuxkpi/common/include/linux/string.h index 7a118bb17c48..9e1818a38594 100644 --- a/sys/compat/linuxkpi/common/include/linux/string.h +++ b/sys/compat/linuxkpi/common/include/linux/string.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_STRING_H_ #define _LINUXKPI_LINUX_STRING_H_ @@ -39,6 +37,8 @@ #include <linux/uaccess.h> #include <linux/err.h> #include <linux/bitops.h> /* for BITS_PER_LONG */ +#include <linux/overflow.h> +#include <linux/stdarg.h> #include <sys/libkern.h> @@ -99,6 +99,15 @@ kmemdup(const void *src, size_t len, gfp_t gfp) } static inline char * +strndup_user(const char __user *ustr, long n) +{ + if (n < 1) + return (ERR_PTR(-EINVAL)); + + return (memdup_user_nul(ustr, n - 1)); +} + +static inline char * kstrdup(const char *string, gfp_t gfp) { char *retval; @@ -197,6 +206,30 @@ strscpy(char* dst, const char* src, size_t len) return (-E2BIG); } +static inline ssize_t +strscpy_pad(char* dst, const char* src, size_t len) +{ + + bzero(dst, len); + + return (strscpy(dst, src, len)); +} + +static inline char * +strnchr(const char *cp, size_t n, int ch) +{ + char *p; + + for (p = __DECONST(char *, cp); n--; ++p) { + if (*p == ch) + return (p); + if (*p == '\0') + break; + } + + return (NULL); +} + static inline void * memset32(uint32_t *b, uint32_t c, size_t len) { @@ -227,4 +260,40 @@ memset_p(void **p, void *v, size_t n) return (memset64((uint64_t *)p, (uintptr_t)v, n)); } +static inline void +memcpy_and_pad(void *dst, size_t dstlen, const void *src, size_t len, int ch) +{ + + if (len >= dstlen) { + memcpy(dst, src, dstlen); + } else { + memcpy(dst, src, len); + /* Pad with given padding character. */ + memset((char *)dst + len, ch, dstlen - len); + } +} + +#define memset_startat(ptr, bytepat, smember) \ +({ \ + uint8_t *_ptr = (uint8_t *)(ptr); \ + int _c = (int)(bytepat); \ + size_t _o = offsetof(typeof(*(ptr)), smember); \ + memset(_ptr + _o, _c, sizeof(*(ptr)) - _o); \ +}) + +#define memset_after(ptr, bytepat, smember) \ +({ \ + uint8_t *_ptr = (uint8_t *)(ptr); \ + int _c = (int)(bytepat); \ + size_t _o = offsetofend(typeof(*(ptr)), smember); \ + memset(_ptr + _o, _c, sizeof(*(ptr)) - _o); \ +}) + +static inline void +memzero_explicit(void *p, size_t s) +{ + memset(p, 0, s); + __asm__ __volatile__("": :"r"(p) :"memory"); +} + #endif /* _LINUXKPI_LINUX_STRING_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/string_helpers.h b/sys/compat/linuxkpi/common/include/linux/string_helpers.h new file mode 100644 index 000000000000..1bdff2730361 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/string_helpers.h @@ -0,0 +1,69 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2023 Jean-Sébastien Pédron <dumbbell@FreeBSD.org> + * + * 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 unmodified, 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 ``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 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_STRING_HELPERS_H_ +#define _LINUXKPI_LINUX_STRING_HELPERS_H_ + +#include <sys/types.h> + +static inline const char * +str_yes_no(bool value) +{ + if (value) + return "yes"; + else + return "no"; +} + +static inline const char * +str_on_off(bool value) +{ + if (value) + return "on"; + else + return "off"; +} + +static inline const char * +str_enabled_disabled(bool value) +{ + if (value) + return "enabled"; + else + return "disabled"; +} + +static inline const char * +str_enable_disable(bool value) +{ + if (value) + return "enable"; + else + return "disable"; +} + +#endif diff --git a/sys/compat/linuxkpi/common/include/linux/stringify.h b/sys/compat/linuxkpi/common/include/linux/stringify.h index bfdf99a30f2f..9345bdc441aa 100644 --- a/sys/compat/linuxkpi/common/include/linux/stringify.h +++ b/sys/compat/linuxkpi/common/include/linux/stringify.h @@ -22,8 +22,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_STRINGIFY_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/suspend.h b/sys/compat/linuxkpi/common/include/linux/suspend.h new file mode 100644 index 000000000000..dacecbebdc08 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/suspend.h @@ -0,0 +1,23 @@ +/* Public domain. */ + +#ifndef _LINUXKPI_LINUX_SUSPEND_H_ +#define _LINUXKPI_LINUX_SUSPEND_H_ + +typedef int suspend_state_t; + +extern suspend_state_t pm_suspend_target_state; + +#define PM_SUSPEND_ON 0 +#define PM_SUSPEND_TO_IDLE 1 +#define PM_SUSPEND_STANDBY 2 +#define PM_SUSPEND_MEM 3 +#define PM_SUSPEND_MIN PM_SUSPEND_TO_IDLE +#define PM_SUSPEND_MAX 4 + +static inline int +pm_suspend_via_firmware(void) +{ + return 0; +} + +#endif /* _LINUXKPI_LINUX_SUSPEND_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/swap.h b/sys/compat/linuxkpi/common/include/linux/swap.h index a080895bed98..a353d353cd33 100644 --- a/sys/compat/linuxkpi/common/include/linux/swap.h +++ b/sys/compat/linuxkpi/common/include/linux/swap.h @@ -22,13 +22,18 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_SWAP_H_ #define _LINUXKPI_LINUX_SWAP_H_ +#include <sys/param.h> +#include <sys/domainset.h> +#include <sys/queue.h> +#include <sys/proc.h> +#include <sys/pcpu.h> + +#include <vm/vm.h> #include <vm/swap_pager.h> #include <vm/vm_pageout.h> diff --git a/sys/compat/linuxkpi/common/include/linux/sysfs.h b/sys/compat/linuxkpi/common/include/linux/sysfs.h index 0b6b479d9362..b5ad73e4460b 100644 --- a/sys/compat/linuxkpi/common/include/linux/sysfs.h +++ b/sys/compat/linuxkpi/common/include/linux/sysfs.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_SYSFS_H_ #define _LINUXKPI_LINUX_SYSFS_H_ @@ -37,6 +35,7 @@ #include <linux/kobject.h> #include <linux/stringify.h> +#include <linux/mm.h> struct sysfs_ops { ssize_t (*show)(struct kobject *, struct attribute *, char *); @@ -55,7 +54,10 @@ struct attribute_group { .attr = { .name = __stringify(_name), .mode = _mode }, \ .show = _show, .store = _store, \ } -#define __ATTR_RO(_name) __ATTR(_name, 0444, _name##_show, NULL) +#define __ATTR_RO(_name) { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = _name##_show, \ +} #define __ATTR_WO(_name) __ATTR(_name, 0200, NULL, _name##_store) #define __ATTR_RW(_name) __ATTR(_name, 0644, _name##_show, _name##_store) #define __ATTR_NULL { .attr = { .name = NULL } } @@ -154,6 +156,21 @@ sysfs_remove_file(struct kobject *kobj, const struct attribute *attr) } static inline int +sysfs_create_link(struct kobject *kobj __unused, + struct kobject *target __unused, const char *name __unused) +{ + /* TODO */ + + return (0); +} + +static inline void +sysfs_remove_link(struct kobject *kobj, const char *name) +{ + /* TODO (along with sysfs_create_link) */ +} + +static inline int sysfs_create_files(struct kobject *kobj, const struct attribute * const *attrs) { int error = 0; @@ -246,7 +263,7 @@ sysfs_unmerge_group(struct kobject *kobj, const struct attribute_group *grp) struct attribute **attr; struct sysctl_oid *oidp; - SLIST_FOREACH(oidp, SYSCTL_CHILDREN(kobj->oidp), oid_link) { + SYSCTL_FOREACH(oidp, SYSCTL_CHILDREN(kobj->oidp)) { if (strcmp(oidp->oid_name, grp->name) != 0) continue; for (attr = grp->attrs; *attr != NULL; attr++) { @@ -295,6 +312,42 @@ sysfs_streq(const char *s1, const char *s2) return (l1 == l2 && strncmp(s1, s2, l1) == 0); } +static inline int +sysfs_emit(char *buf, const char *fmt, ...) +{ + va_list args; + int i; + + if (!buf || offset_in_page(buf)) { + pr_warn("invalid sysfs_emit: buf:%p\n", buf); + return (0); + } + + va_start(args, fmt); + i = vscnprintf(buf, PAGE_SIZE, fmt, args); + va_end(args); + + return (i); +} + +static inline int +sysfs_emit_at(char *buf, int at, const char *fmt, ...) +{ + va_list args; + int i; + + if (!buf || offset_in_page(buf) || at < 0 || at >= PAGE_SIZE) { + pr_warn("invalid sysfs_emit: buf:%p at:%d\n", buf, at); + return (0); + } + + va_start(args, fmt); + i = vscnprintf(buf + at, PAGE_SIZE - at, fmt, args); + va_end(args); + + return (i); +} + #define sysfs_attr_init(attr) do {} while(0) #endif /* _LINUXKPI_LINUX_SYSFS_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/tcp.h b/sys/compat/linuxkpi/common/include/linux/tcp.h index cfc64b8c7e53..3e461d8e7075 100644 --- a/sys/compat/linuxkpi/common/include/linux/tcp.h +++ b/sys/compat/linuxkpi/common/include/linux/tcp.h @@ -26,8 +26,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_TCP_H diff --git a/sys/compat/linuxkpi/common/include/linux/time.h b/sys/compat/linuxkpi/common/include/linux/time.h index c7a41a83f4aa..6c9a781d5e0e 100644 --- a/sys/compat/linuxkpi/common/include/linux/time.h +++ b/sys/compat/linuxkpi/common/include/linux/time.h @@ -22,12 +22,12 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_TIME_H_ #define _LINUXKPI_LINUX_TIME_H_ +#define MSEC_PER_SEC 1000L + #define NSEC_PER_USEC 1000L #define NSEC_PER_MSEC 1000000L #define NSEC_PER_SEC 1000000000L @@ -40,6 +40,8 @@ #include <sys/time.h> #include <sys/stdint.h> +#include <linux/math64.h> + static inline struct timeval ns_to_timeval(const int64_t nsec) { @@ -117,6 +119,8 @@ ns_to_timespec(const int64_t nsec) return (ts); } +#define ns_to_timespec64(_x) ns_to_timespec(_x) + static inline int timespec_valid(const struct timespec *ts) { diff --git a/sys/compat/linuxkpi/common/include/linux/timer.h b/sys/compat/linuxkpi/common/include/linux/timer.h index 3432bfc46c4f..8bea082c3e6c 100644 --- a/sys/compat/linuxkpi/common/include/linux/timer.h +++ b/sys/compat/linuxkpi/common/include/linux/timer.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_TIMER_H_ #define _LINUXKPI_LINUX_TIMER_H_ @@ -83,6 +81,8 @@ extern void add_timer(struct timer_list *); extern void add_timer_on(struct timer_list *, int cpu); extern int del_timer(struct timer_list *); extern int del_timer_sync(struct timer_list *); +extern int timer_delete_sync(struct timer_list *); +extern int timer_shutdown_sync(struct timer_list *); #define timer_pending(timer) callout_pending(&(timer)->callout) #define round_jiffies(j) \ diff --git a/sys/compat/linuxkpi/common/include/linux/tracepoint.h b/sys/compat/linuxkpi/common/include/linux/tracepoint.h index 0171427439f9..8ce7992306b9 100644 --- a/sys/compat/linuxkpi/common/include/linux/tracepoint.h +++ b/sys/compat/linuxkpi/common/include/linux/tracepoint.h @@ -23,8 +23,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_TRACEPOINT_H @@ -37,7 +35,13 @@ #define TP_printk(...) #define TRACE_EVENT(_name, _proto, _args, _struct, _assign, _printk) \ -static void trace_ ## _name(_proto) \ +static inline void trace_ ## _name(_proto) \ +{ \ +} + +#define DECLARE_EVENT_CLASS(...) +#define DEFINE_EVENT(_x, _name, _proto, _args) \ +static inline void trace_ ## _name(_proto) \ { \ } diff --git a/sys/compat/linuxkpi/common/include/linux/types.h b/sys/compat/linuxkpi/common/include/linux/types.h index dab5e6ddce42..b11ce1cdd805 100644 --- a/sys/compat/linuxkpi/common/include/linux/types.h +++ b/sys/compat/linuxkpi/common/include/linux/types.h @@ -25,13 +25,10 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_TYPES_H_ #define _LINUXKPI_LINUX_TYPES_H_ -#include <sys/cdefs.h> #include <sys/types.h> #include <sys/param.h> #include <sys/systm.h> @@ -79,6 +76,14 @@ typedef unsigned long kernel_ulong_t; typedef unsigned long irq_hw_number_t; +#ifndef LIST_HEAD_DEF +#define LIST_HEAD_DEF +struct list_head { + struct list_head *next; + struct list_head *prev; +}; +#endif + struct rcu_head { void *raw[2]; } __aligned(sizeof(void *)); diff --git a/sys/compat/linuxkpi/common/include/linux/uaccess.h b/sys/compat/linuxkpi/common/include/linux/uaccess.h index c62a94e8e044..660e84e6af3b 100644 --- a/sys/compat/linuxkpi/common/include/linux/uaccess.h +++ b/sys/compat/linuxkpi/common/include/linux/uaccess.h @@ -26,8 +26,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_UACCESS_H_ @@ -89,4 +87,29 @@ pagefault_disabled(void) return ((curthread->td_pflags & TDP_NOFAULTING) != 0); } +static inline int +__copy_to_user_inatomic(void __user *to, const void *from, unsigned n) +{ + + return (copyout_nofault(from, to, n) != 0 ? n : 0); +} +#define __copy_to_user_inatomic_nocache(to, from, n) \ + __copy_to_user_inatomic((to), (from), (n)) + +static inline unsigned long +__copy_from_user_inatomic(void *to, const void __user *from, + unsigned long n) +{ + /* + * XXXKIB. Equivalent Linux function is implemented using + * MOVNTI for aligned moves. For unaligned head and tail, + * normal move is performed. As such, it is not incorrect, if + * only somewhat slower, to use normal copyin. All uses + * except shmem_pwrite_fast() have the destination mapped WC. + */ + return ((copyin_nofault(__DECONST(void *, from), to, n) != 0 ? n : 0)); +} +#define __copy_from_user_inatomic_nocache(to, from, n) \ + __copy_from_user_inatomic((to), (from), (n)) + #endif /* _LINUXKPI_LINUX_UACCESS_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/udp.h b/sys/compat/linuxkpi/common/include/linux/udp.h index 44c0763a1eeb..f3cd40cf8bb7 100644 --- a/sys/compat/linuxkpi/common/include/linux/udp.h +++ b/sys/compat/linuxkpi/common/include/linux/udp.h @@ -26,8 +26,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_UDP_H diff --git a/sys/compat/linuxkpi/common/include/linux/usb.h b/sys/compat/linuxkpi/common/include/linux/usb.h index 3b7c8a2cde78..d9649dcb5471 100644 --- a/sys/compat/linuxkpi/common/include/linux/usb.h +++ b/sys/compat/linuxkpi/common/include/linux/usb.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*- * Copyright (c) 2007 Luigi Rizzo - Universita` di Pisa. All rights reserved. * Copyright (c) 2007 Hans Petter Selasky. All rights reserved. diff --git a/sys/compat/linuxkpi/common/include/linux/utsname.h b/sys/compat/linuxkpi/common/include/linux/utsname.h new file mode 100644 index 000000000000..3239801ca17b --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/utsname.h @@ -0,0 +1,51 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2023 Bjoern A. Zeeb + * + * 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_UTSNAME_H +#define _LINUXKPI_LINUX_UTSNAME_H + +#include <sys/types.h> +#include <sys/jail.h> + +struct _utsname { + char release[OSRELEASELEN]; +}; + +struct uts_namespace { + struct _utsname name; +}; + +extern struct uts_namespace init_uts_ns; + +static inline struct _utsname * +init_utsname(void) +{ + + return &init_uts_ns.name; +} + +#endif /* _LINUXKPI_LINUX_UTSNAME_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/uuid.h b/sys/compat/linuxkpi/common/include/linux/uuid.h index 31a018497f78..4f6f4a8b34f0 100644 --- a/sys/compat/linuxkpi/common/include/linux/uuid.h +++ b/sys/compat/linuxkpi/common/include/linux/uuid.h @@ -1,7 +1,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (c) 2021 The FreeBSD Foundation + * Copyright (c) 2021,2023 The FreeBSD Foundation * * This software was developed by Björn Zeeb under sponsorship from * the FreeBSD Foundation. @@ -26,13 +26,13 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_UUID_H #define _LINUXKPI_LINUX_UUID_H +#include <linux/random.h> + #define UUID_STRING_LEN 36 #define GUID_INIT(x0_3, x4_5, x6_7, x8, x9, x10, x11, x12, x13, x14, x15) \ @@ -59,4 +59,19 @@ typedef struct { char x[16]; } guid_t; +static inline void +guid_gen(guid_t *g) +{ + + get_random_bytes(g, 16); + g->x[7] = (g->x[7] & 0x0f) | 0x40; + g->x[8] = (g->x[8] & 0x3f) | 0x80; +} + +static inline void +guid_copy(guid_t *dst, const guid_t *src) +{ + memcpy(dst, src, sizeof(*dst)); +} + #endif /* _LINUXKPI_LINUX_UUID_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/vgaarb.h b/sys/compat/linuxkpi/common/include/linux/vgaarb.h new file mode 100644 index 000000000000..d43a88136864 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/vgaarb.h @@ -0,0 +1,281 @@ +/* + * The VGA aribiter manages VGA space routing and VGA resource decode to + * allow multiple VGA devices to be used in a system in a safe way. + * + * (C) Copyright 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org> + * (C) Copyright 2007 Paulo R. Zanoni <przanoni@gmail.com> + * (C) Copyright 2007, 2009 Tiago Vignatti <vignatti@freedesktop.org> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS + * IN THE SOFTWARE. + * + */ + +#ifndef _LINUXKPI_LINUX_VGA_H_ +#define _LINUXKPI_LINUX_VGA_H_ + +#include <video/vga.h> + +/* Legacy VGA regions */ +#define VGA_RSRC_NONE 0x00 +#define VGA_RSRC_LEGACY_IO 0x01 +#define VGA_RSRC_LEGACY_MEM 0x02 +#define VGA_RSRC_LEGACY_MASK (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM) +/* Non-legacy access */ +#define VGA_RSRC_NORMAL_IO 0x04 +#define VGA_RSRC_NORMAL_MEM 0x08 + +/* Passing that instead of a pci_dev to use the system "default" + * device, that is the one used by vgacon. Archs will probably + * have to provide their own vga_default_device(); + */ +#define VGA_DEFAULT_DEVICE (NULL) + +struct pci_dev; + +/* For use by clients */ + +/** + * vga_set_legacy_decoding + * + * @pdev: pci device of the VGA card + * @decodes: bit mask of what legacy regions the card decodes + * + * Indicates to the arbiter if the card decodes legacy VGA IOs, + * legacy VGA Memory, both, or none. All cards default to both, + * the card driver (fbdev for example) should tell the arbiter + * if it has disabled legacy decoding, so the card can be left + * out of the arbitration process (and can be safe to take + * interrupts at any time. + */ +#if defined(CONFIG_VGA_ARB) +extern void vga_set_legacy_decoding(struct pci_dev *pdev, + unsigned int decodes); +#else +static inline void vga_set_legacy_decoding(struct pci_dev *pdev, + unsigned int decodes) { }; +#endif + +/** + * vga_get - acquire & locks VGA resources + * + * @pdev: pci device of the VGA card or NULL for the system default + * @rsrc: bit mask of resources to acquire and lock + * @interruptible: blocking should be interruptible by signals ? + * + * This function acquires VGA resources for the given + * card and mark those resources locked. If the resource requested + * are "normal" (and not legacy) resources, the arbiter will first check + * whether the card is doing legacy decoding for that type of resource. If + * yes, the lock is "converted" into a legacy resource lock. + * The arbiter will first look for all VGA cards that might conflict + * and disable their IOs and/or Memory access, including VGA forwarding + * on P2P bridges if necessary, so that the requested resources can + * be used. Then, the card is marked as locking these resources and + * the IO and/or Memory accesse are enabled on the card (including + * VGA forwarding on parent P2P bridges if any). + * This function will block if some conflicting card is already locking + * one of the required resources (or any resource on a different bus + * segment, since P2P bridges don't differenciate VGA memory and IO + * afaik). You can indicate whether this blocking should be interruptible + * by a signal (for userland interface) or not. + * Must not be called at interrupt time or in atomic context. + * If the card already owns the resources, the function succeeds. + * Nested calls are supported (a per-resource counter is maintained) + */ + +#if defined(CONFIG_VGA_ARB) +extern int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible); +#else +static inline int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible) { return 0; } +#endif + +/** + * vga_get_interruptible + * + * Shortcut to vga_get + */ + +static inline int vga_get_interruptible(struct pci_dev *pdev, + unsigned int rsrc) +{ + return vga_get(pdev, rsrc, 1); +} + +/** + * vga_get_uninterruptible + * + * Shortcut to vga_get + */ + +static inline int vga_get_uninterruptible(struct pci_dev *pdev, + unsigned int rsrc) +{ + return vga_get(pdev, rsrc, 0); +} + +/** + * vga_tryget - try to acquire & lock legacy VGA resources + * + * @pdev: pci devivce of VGA card or NULL for system default + * @rsrc: bit mask of resources to acquire and lock + * + * This function performs the same operation as vga_get(), but + * will return an error (-EBUSY) instead of blocking if the resources + * are already locked by another card. It can be called in any context + */ + +#if defined(CONFIG_VGA_ARB) +extern int vga_tryget(struct pci_dev *pdev, unsigned int rsrc); +#else +static inline int vga_tryget(struct pci_dev *pdev, unsigned int rsrc) { return 0; } +#endif + +/** + * vga_put - release lock on legacy VGA resources + * + * @pdev: pci device of VGA card or NULL for system default + * @rsrc: but mask of resource to release + * + * This function releases resources previously locked by vga_get() + * or vga_tryget(). The resources aren't disabled right away, so + * that a subsequence vga_get() on the same card will succeed + * immediately. Resources have a counter, so locks are only + * released if the counter reaches 0. + */ + +#if defined(CONFIG_VGA_ARB) +extern void vga_put(struct pci_dev *pdev, unsigned int rsrc); +#else +#define vga_put(pdev, rsrc) +#endif + + +/** + * vga_default_device + * + * This can be defined by the platform. The default implementation + * is rather dumb and will probably only work properly on single + * vga card setups and/or x86 platforms. + * + * If your VGA default device is not PCI, you'll have to return + * NULL here. In this case, I assume it will not conflict with + * any PCI card. If this is not true, I'll have to define two archs + * hooks for enabling/disabling the VGA default device if that is + * possible. This may be a problem with real _ISA_ VGA cards, in + * addition to a PCI one. I don't know at this point how to deal + * with that card. Can theirs IOs be disabled at all ? If not, then + * I suppose it's a matter of having the proper arch hook telling + * us about it, so we basically never allow anybody to succeed a + * vga_get()... + */ + +#ifdef CONFIG_VGA_ARB +extern struct pci_dev *vga_default_device(void); +extern void vga_set_default_device(struct pci_dev *pdev); +#else +static inline struct pci_dev *vga_default_device(void) { return NULL; }; +static inline void vga_set_default_device(struct pci_dev *pdev) { }; +#endif + +/** + * vga_conflicts + * + * Architectures should define this if they have several + * independent PCI domains that can afford concurrent VGA + * decoding + */ + +#ifndef __ARCH_HAS_VGA_CONFLICT +static inline int vga_conflicts(struct pci_dev *p1, struct pci_dev *p2) +{ + return 1; +} +#endif + +/** + * vga_client_register + * + * @pdev: pci device of the VGA client + * @cookie: client cookie to be used in callbacks + * @irq_set_state: irq state change callback + * @set_vga_decode: vga decode change callback + * + * return value: 0 on success, -1 on failure + * Register a client with the VGA arbitration logic + * + * Clients have two callback mechanisms they can use. + * irq enable/disable callback - + * If a client can't disable its GPUs VGA resources, then we + * need to be able to ask it to turn off its irqs when we + * turn off its mem and io decoding. + * set_vga_decode + * If a client can disable its GPU VGA resource, it will + * get a callback from this to set the encode/decode state + * + * Rationale: we cannot disable VGA decode resources unconditionally + * some single GPU laptops seem to require ACPI or BIOS access to the + * VGA registers to control things like backlights etc. + * Hopefully newer multi-GPU laptops do something saner, and desktops + * won't have any special ACPI for this. + * They driver will get a callback when VGA arbitration is first used + * by userspace since we some older X servers have issues. + */ +#if defined(CONFIG_VGA_ARB) +#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51501 +int vga_client_register(struct pci_dev *pdev, + unsigned int (*set_vga_decode)(struct pci_dev *pdev, bool state)); +#elif defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51500 +int vga_client_register(struct pci_dev *pdev, void *cookie, + unsigned int (*set_vga_decode)(void *cookie, bool state)); +#else +int vga_client_register(struct pci_dev *pdev, void *cookie, + void (*irq_set_state)(void *cookie, bool state), + unsigned int (*set_vga_decode)(void *cookie, bool state)); +#endif +#else +#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51501 +static inline int vga_client_register(struct pci_dev *pdev, + unsigned int (*set_vga_decode)(struct pci_dev *pdev, bool state)) +#elif defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51500 +static inline int vga_client_register(struct pci_dev *pdev, void *cookie, + unsigned int (*set_vga_decode)(void *cookie, bool state)) +#else +static inline int vga_client_register(struct pci_dev *pdev, void *cookie, + void (*irq_set_state)(void *cookie, bool state), + unsigned int (*set_vga_decode)(void *cookie, bool state)) +#endif +{ + return 0; +} + +static inline int vga_client_unregister(struct pci_dev *pdev) +{ +#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51501 + return (vga_client_register(NULL, NULL)); +#elif defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51500 + return (vga_client_register(NULL, NULL, NULL)); +#else + return (vga_client_register(NULL, NULL, NULL, NULL)); +#endif +} +#endif + +#endif /* _LINUXKPI_LINUX_VGA_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/vmalloc.h b/sys/compat/linuxkpi/common/include/linux/vmalloc.h index 450db0f761f2..00650a2df9b6 100644 --- a/sys/compat/linuxkpi/common/include/linux/vmalloc.h +++ b/sys/compat/linuxkpi/common/include/linux/vmalloc.h @@ -25,12 +25,11 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_VMALLOC_H_ #define _LINUXKPI_LINUX_VMALLOC_H_ +#include <linux/overflow.h> #include <linux/page.h> #define VM_MAP 0x0000 diff --git a/sys/compat/linuxkpi/common/include/linux/wait.h b/sys/compat/linuxkpi/common/include/linux/wait.h index 09cb5918b84b..d50003d44955 100644 --- a/sys/compat/linuxkpi/common/include/linux/wait.h +++ b/sys/compat/linuxkpi/common/include/linux/wait.h @@ -26,8 +26,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_WAIT_H_ diff --git a/sys/compat/linuxkpi/common/include/linux/wait_bit.h b/sys/compat/linuxkpi/common/include/linux/wait_bit.h index 66c1149da432..573798590b73 100644 --- a/sys/compat/linuxkpi/common/include/linux/wait_bit.h +++ b/sys/compat/linuxkpi/common/include/linux/wait_bit.h @@ -24,8 +24,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef __LINUXKPI_LINUX_WAITBIT_H__ diff --git a/sys/compat/linuxkpi/common/include/linux/workqueue.h b/sys/compat/linuxkpi/common/include/linux/workqueue.h index 7ced4270e1db..1c9df9fcb74d 100644 --- a/sys/compat/linuxkpi/common/include/linux/workqueue.h +++ b/sys/compat/linuxkpi/common/include/linux/workqueue.h @@ -25,8 +25,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_WORKQUEUE_H_ #define _LINUXKPI_LINUX_WORKQUEUE_H_ @@ -190,6 +188,9 @@ do { \ #define delayed_work_pending(dwork) \ linux_work_pending(&(dwork)->work) +#define cancel_work(work) \ + linux_cancel_work(work) + #define cancel_delayed_work(dwork) \ linux_cancel_delayed_work(dwork) @@ -245,6 +246,7 @@ extern void linux_destroy_workqueue(struct workqueue_struct *); extern bool linux_queue_work_on(int cpu, struct workqueue_struct *, struct work_struct *); extern bool linux_queue_delayed_work_on(int cpu, struct workqueue_struct *, struct delayed_work *, unsigned delay); +extern bool linux_cancel_work(struct work_struct *); extern bool linux_cancel_delayed_work(struct delayed_work *); extern bool linux_cancel_work_sync(struct work_struct *); extern bool linux_cancel_delayed_work_sync(struct delayed_work *); diff --git a/sys/compat/linuxkpi/common/include/linux/ww_mutex.h b/sys/compat/linuxkpi/common/include/linux/ww_mutex.h index 82ba7a55a7e8..9219755bb78e 100644 --- a/sys/compat/linuxkpi/common/include/linux/ww_mutex.h +++ b/sys/compat/linuxkpi/common/include/linux/ww_mutex.h @@ -22,8 +22,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_WW_MUTEX_H_ #define _LINUXKPI_LINUX_WW_MUTEX_H_ @@ -61,6 +59,8 @@ struct ww_mutex { } \ SYSINIT(name, SI_SUB_LOCK, SI_ORDER_SECOND, name##_init, NULL) +#define DEFINE_WD_CLASS(name) DEFINE_WW_CLASS(name) + #define ww_mutex_is_locked(_m) \ sx_xlocked(&(_m)->base.sx) @@ -70,8 +70,13 @@ struct ww_mutex { #define ww_mutex_lock_slow_interruptible(_m, _x) \ ww_mutex_lock_interruptible(_m, _x) +#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51600 +static inline int __must_check +ww_mutex_trylock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx __unused) +#else static inline int __must_check ww_mutex_trylock(struct ww_mutex *lock) +#endif { return (mutex_trylock(&lock->base)); } diff --git a/sys/compat/linuxkpi/common/include/linux/xarray.h b/sys/compat/linuxkpi/common/include/linux/xarray.h index 408906867479..d293a8f7c2a3 100644 --- a/sys/compat/linuxkpi/common/include/linux/xarray.h +++ b/sys/compat/linuxkpi/common/include/linux/xarray.h @@ -22,8 +22,6 @@ * 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. - * - * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_XARRAY_H_ #define _LINUXKPI_LINUX_XARRAY_H_ @@ -31,6 +29,7 @@ #include <linux/gfp.h> #include <linux/radix-tree.h> #include <linux/err.h> +#include <linux/kconfig.h> #include <sys/lock.h> #include <sys/mutex.h> @@ -45,6 +44,9 @@ #define XA_ERROR(x) \ ERR_PTR(x) +#define xa_is_err(x) \ + IS_ERR(x) + #define xa_limit_32b XA_LIMIT(0, 0xFFFFFFFF) #define XA_ASSERT_LOCKED(xa) mtx_assert(&(xa)->mtx, MA_OWNED) @@ -87,6 +89,27 @@ void *__xa_store(struct xarray *, uint32_t, void *, gfp_t); bool __xa_empty(struct xarray *); void *__xa_next(struct xarray *, unsigned long *, bool); +#define xa_store_irq(xa, index, ptr, gfp) \ + xa_store((xa), (index), (ptr), (gfp)) + +#define xa_erase_irq(xa, index) \ + xa_erase((xa), (index)) + +#define xa_lock_irq(xa) xa_lock(xa) +#define xa_unlock_irq(xa) xa_unlock(xa) + +#define xa_lock_irqsave(xa, flags) \ + do { \ + xa_lock((xa)); \ + flags = 0; \ + } while (0) + +#define xa_unlock_irqrestore(xa, flags) \ + do { \ + xa_unlock((xa)); \ + flags == 0; \ + } while (0) + static inline int xa_err(void *ptr) { |