Index: sys/compat/linuxkpi/common/include/asm/unaligned.h =================================================================== --- /dev/null +++ sys/compat/linuxkpi/common/include/asm/unaligned.h @@ -0,0 +1,78 @@ +/*- + * 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. + * + * $FreeBSD$ + */ + +#ifndef _ASM_UNALIGNED_H +#define _ASM_UNALIGNED_H + +#include +#include + +static __inline uint32_t +get_unaligned_le32(const void *p) +{ + + return (le32_to_cpup((const __le32 *)p)); +} + +static __inline void +put_unaligned_le32(__le32 v, void *p) +{ + __le32 x; + + x = cpu_to_le32(v); + memcpy(p, &x, sizeof(x)); +} + +static __inline void +put_unaligned_le64(__le64 v, void *p) +{ + __le64 x; + + x = cpu_to_le64(v); + memcpy(p, &x, sizeof(x)); +} + +static __inline uint16_t +get_unaligned_be16(const void *p) +{ + + return (be16_to_cpup((const __be16 *)p)); +} + +static __inline uint32_t +get_unaligned_be32(const void *p) +{ + + return (be32_to_cpup((const __be32 *)p)); +} + +#endif /* _ASM_UNALIGNED_H */ Index: sys/compat/linuxkpi/common/include/linux/kernel.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/kernel.h +++ sys/compat/linuxkpi/common/include/linux/kernel.h @@ -593,4 +593,45 @@ #define TAINT_WARN 0 #define test_taint(x) (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= 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. + */ +#define ___XAB_1 dontcare, +#define ___IS_XAB(_ignore, _x, ...) (_x) +#define __IS_XAB(_x) ___IS_XAB(_x true, false) +#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 /* _LINUX_KERNEL_H_ */ Index: sys/compat/linuxkpi/common/include/linux/kobject.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/kobject.h +++ sys/compat/linuxkpi/common/include/linux/kobject.h @@ -41,6 +41,8 @@ struct kobject; struct sysctl_oid; +#define KOBJ_CHANGE 0x01 + struct kobj_type { void (*release)(struct kobject *kobj); const struct sysfs_ops *sysfs_ops; @@ -151,4 +153,16 @@ int kobject_init_and_add(struct kobject *kobj, const struct kobj_type *ktype, struct kobject *parent, const char *fmt, ...); +static __inline void +kobject_uevent_env(struct kobject *kobj, int action, char *envp[]) +{ + + /* + * iwlwifi(4) sends an INACCESSIBLE event when it detects that the card + * (pice endpoint) is gone and it attempts a removal cleanup. + * Not sure if we do anything related to udev/sysfs at the moment or + * need a shortcut or simply ignore it (for now). + */ +} + #endif /* _LINUX_KOBJECT_H_ */ Index: sys/compat/linuxkpi/common/include/linux/lockdep.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/lockdep.h +++ sys/compat/linuxkpi/common/include/linux/lockdep.h @@ -42,6 +42,7 @@ #define lockdep_set_class_and_name(lock, key, name) #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) #ifdef INVARIANTS #define lockdep_assert_held(m) do { \ Index: sys/compat/linuxkpi/common/include/linux/pm.h =================================================================== --- /dev/null +++ sys/compat/linuxkpi/common/include/linux/pm.h @@ -0,0 +1,52 @@ +/*- + * 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. + * + * $FreeBSD$ + */ + +#ifndef _LINUXKPI_LINUX_PM_H +#define _LINUXKPI_LINUX_PM_H + +#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, \ +} +#else +#define SIMPLE_DEV_PM_OPS(_name, _suspendfunc, _resumefunc) \ +const struct dev_pm_ops _name = { \ +} +#endif + +#endif /* _LINUXKPI_LINUX_PM_H */ Index: sys/compat/linuxkpi/common/include/linux/scatterlist.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/scatterlist.h +++ sys/compat/linuxkpi/common/include/linux/scatterlist.h @@ -32,6 +32,9 @@ #ifndef _LINUX_SCATTERLIST_H_ #define _LINUX_SCATTERLIST_H_ +#include +#include + #include #include #include @@ -479,4 +482,55 @@ return (nth_page(sg_page(piter->sg), piter->sg_pgoffset)); } +static __inline size_t +sg_pcopy_from_buffer(struct scatterlist *sgl, unsigned int nents, + const void *buf, size_t buflen, off_t skip) +{ + struct sg_page_iter piter; + struct page *page; + struct sf_buf *sf; + size_t len, copied; + char *p, *b; + + if (buflen == 0) + return (0); + + b = __DECONST(char *, buf); + copied = 0; + sched_pin(); + for_each_sg_page(sgl, &piter, nents, 0) { + + /* Skip to the start. */ + if (piter.sg->length <= skip) { + skip -= piter.sg->length; + continue; + } + + /* See how much to copy. */ + KASSERT(((piter.sg->length - skip) != 0 && (buflen != 0)), + ("%s: sg len %u - skip %ju || buflen %zu is 0\n", + __func__, piter.sg->length, (uintmax_t)skip, buflen)); + len = min(piter.sg->length - skip, buflen); + + page = sg_page_iter_page(&piter); + sf = sf_buf_alloc(page, SFB_CPUPRIVATE | SFB_NOWAIT); + if (sf == NULL) + break; + p = (char *)sf_buf_kva(sf) + piter.sg_pgoffset + skip; + memcpy(p, b, len); + sf_buf_free(sf); + + copied += len; + /* Either we exactly filled the page, or we are done. */ + buflen -= len; + if (buflen == 0) + break; + skip -= len; + b += len; + } + sched_unpin(); + + return (copied); +} + #endif /* _LINUX_SCATTERLIST_H_ */