summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-08-15 11:49:31 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-08-15 11:49:31 +0000
commitde6fc2e39bc1d88511b62ed3a6834a6f0cd6b3a4 (patch)
tree75e7ac246ee145e2bd1c97480e08e1c8bc027dd4
parent8460d7540b226f37a2f58b9f652e34e2fb6df3a7 (diff)
parentbec053ffe01ddc571fb09d1758708c407c33ddfd (diff)
downloadsrc-test-de6fc2e39bc1d88511b62ed3a6834a6f0cd6b3a4.tar.gz
src-test-de6fc2e39bc1d88511b62ed3a6834a6f0cd6b3a4.zip
Notes
-rw-r--r--Makefile.inc123
-rw-r--r--UPDATING5
-rwxr-xr-xcddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh16
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh38
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh38
-rwxr-xr-xcddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh16
-rw-r--r--etc/mtree/BSD.usr.dist4
-rw-r--r--lib/libbsnmp/Makefile1
-rw-r--r--lib/libbsnmp/tests/Makefile11
-rw-r--r--lib/libbsnmp/tests/bsnmpd_test.c53
-rw-r--r--lib/libc/gen/Makefile.inc1
-rw-r--r--lib/libc/gen/Symbol.map2
-rw-r--r--lib/libc/gen/scandir-compat11.c31
-rw-r--r--lib/libc/gen/scandir.c5
-rw-r--r--lib/libc/gen/syslog.c23
-rw-r--r--lib/liblua/Makefile2
-rw-r--r--lib/liblua/luaconf.h9
-rw-r--r--lib/libpmc/libpmc.c22
-rw-r--r--libexec/flua/Makefile1
-rwxr-xr-xlibexec/rc/rc.d/ipfilter1
-rwxr-xr-xlibexec/rc/rc.d/ipmon2
-rwxr-xr-xlibexec/rc/rc.d/ipnat1
-rwxr-xr-xlibexec/rc/rc.d/netif2
-rwxr-xr-xlibexec/rc/rc.d/netwait2
-rwxr-xr-xlibexec/rc/rc.d/securelevel2
-rw-r--r--release/packages/binutils.ucl6
-rw-r--r--release/packages/caroot.ucl6
-rw-r--r--release/packages/clang.ucl6
-rw-r--r--release/packages/gdb.ucl6
-rwxr-xr-xrelease/packages/generate-ucl.sh3
-rw-r--r--release/packages/groff.ucl6
-rw-r--r--release/packages/jail.ucl6
-rw-r--r--release/packages/kernel.ucl6
-rw-r--r--release/packages/lld.ucl6
-rw-r--r--release/packages/lldb.ucl6
-rw-r--r--release/packages/runtime.ucl6
-rw-r--r--release/packages/ssh.ucl6
-rw-r--r--release/packages/svn.ucl6
-rw-r--r--release/packages/template.ucl6
-rw-r--r--release/packages/unbound.ucl6
-rw-r--r--release/packages/utilities.ucl6
-rw-r--r--sbin/ifconfig/ifconfig.c1
-rw-r--r--sbin/ipfw/ipfw.833
-rw-r--r--sbin/ipfw/ipfw2.c20
-rw-r--r--secure/lib/libssl/Makefile2
-rw-r--r--share/man/man4/Makefile2
-rw-r--r--share/man/man4/cp2112.487
-rw-r--r--share/man/man9/Makefile5
-rw-r--r--share/man/man9/prng.999
-rw-r--r--share/mk/bsd.linker.mk16
-rw-r--r--share/mk/src.opts.mk8
-rw-r--r--share/mk/sys.mk1
-rwxr-xr-xstand/common/newvers.sh6
-rw-r--r--stand/i386/loader/Makefile2
-rw-r--r--sys/arm/allwinner/aw_cir.c52
-rw-r--r--sys/arm64/include/armreg.h15
-rw-r--r--sys/arm64/rockchip/if_dwc_rk.c542
-rw-r--r--sys/cam/nvme/nvme_da.c6
-rw-r--r--sys/cam/nvme/nvme_xpt.c70
-rw-r--r--sys/compat/linprocfs/linprocfs.c40
-rw-r--r--sys/compat/linuxkpi/common/include/linux/bitops.h10
-rw-r--r--sys/compat/linuxkpi/common/include/linux/sched.h5
-rw-r--r--sys/compat/linuxkpi/common/include/linux/wait.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/wait_bit.h64
-rw-r--r--sys/compat/linuxkpi/common/src/linux_compat.c6
-rw-r--r--sys/compat/linuxkpi/common/src/linux_rcu.c18
-rw-r--r--sys/compat/netbsd/dvcfg.h67
-rw-r--r--sys/conf/files1
-rw-r--r--sys/conf/kern.pre.mk4
-rw-r--r--sys/contrib/pcg-c/include/pcg_variants.h44
-rw-r--r--sys/dev/dwc/if_dwc.c25
-rw-r--r--sys/dev/dwc/if_dwc.h4
-rw-r--r--sys/dev/dwc/if_dwc_if.m14
-rw-r--r--sys/dev/dwc/if_dwcvar.h1
-rw-r--r--sys/dev/gpio/gpiokeys.c94
-rw-r--r--sys/dev/hwpmc/hwpmc_arm64.c24
-rw-r--r--sys/dev/hwpmc/pmc_events.h43
-rw-r--r--sys/dev/ice/ice_common.h17
-rw-r--r--sys/dev/ixl/i40e_prototype.h2
-rw-r--r--sys/dev/nvd/nvd.c15
-rw-r--r--sys/dev/nvme/nvme_sim.c6
-rw-r--r--sys/dev/usb/misc/cp2112.c680
-rw-r--r--sys/fs/devfs/devfs.h5
-rw-r--r--sys/fs/devfs/devfs_devs.c6
-rw-r--r--sys/fs/devfs/devfs_int.h3
-rw-r--r--sys/fs/devfs/devfs_vnops.c160
-rw-r--r--sys/fs/nfs/nfs.h1
-rw-r--r--sys/fs/nfs/nfs_commonkrpc.c6
-rw-r--r--sys/fs/nfs/nfs_commonsubs.c21
-rw-r--r--sys/fs/nfs/nfs_var.h4
-rw-r--r--sys/fs/nfsclient/nfs_clcomsubs.c2
-rw-r--r--sys/fs/nfsclient/nfs_clrpcops.c2
-rw-r--r--sys/fs/nfsclient/nfs_clvfsops.c4
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c8
-rw-r--r--sys/kern/kern_conf.c30
-rw-r--r--sys/kern/kern_environment.c124
-rw-r--r--sys/kern/kern_proc.c4
-rw-r--r--sys/kern/subr_prng.c131
-rw-r--r--sys/kern/sys_pipe.c60
-rw-r--r--sys/kern/tty.c4
-rw-r--r--sys/kern/vfs_lookup.c12
-rw-r--r--sys/kern/vfs_subr.c247
-rw-r--r--sys/kern/vfs_syscalls.c11
-rw-r--r--sys/libkern/random.c35
-rw-r--r--sys/modules/linux/Makefile4
-rw-r--r--sys/modules/linux64/Makefile2
-rw-r--r--sys/net/if_lagg.c5
-rw-r--r--sys/net/iflib.c86
-rw-r--r--sys/net/iflib.h4
-rw-r--r--sys/net/route.c106
-rw-r--r--sys/net/route.h9
-rw-r--r--sys/net/route/route_ctl.c144
-rw-r--r--sys/net/route/route_ctl.h5
-rw-r--r--sys/net/route/route_var.h10
-rw-r--r--sys/net/route/shared.h3
-rw-r--r--sys/net/rtsock.c10
-rw-r--r--sys/netinet/cc/cc_cubic.c62
-rw-r--r--sys/netinet/in_mcast.c9
-rw-r--r--sys/netinet/in_proto.c3
-rw-r--r--sys/netinet/in_rmx.c24
-rw-r--r--sys/netinet/in_var.h7
-rw-r--r--sys/netinet/sctputil.c2
-rw-r--r--sys/netinet/tcp_input.c11
-rw-r--r--sys/netinet/tcp_sack.c31
-rw-r--r--sys/netinet/tcp_syncache.c41
-rw-r--r--sys/netinet/tcp_syncache.h4
-rw-r--r--sys/netinet/tcp_var.h8
-rw-r--r--sys/netinet6/in6.c3
-rw-r--r--sys/netinet6/in6_mcast.c9
-rw-r--r--sys/netinet6/in6_proto.c5
-rw-r--r--sys/netinet6/in6_rmx.c33
-rw-r--r--sys/netinet6/in6_var.h3
-rw-r--r--sys/netinet6/scope6.c4
-rw-r--r--sys/netinet6/scope6_var.h3
-rw-r--r--sys/netpfil/ipfw/ip_fw2.c18
-rw-r--r--sys/riscv/include/pcpu.h2
-rw-r--r--sys/riscv/include/pcpu_aux.h3
-rw-r--r--sys/riscv/include/stack.h6
-rw-r--r--sys/riscv/riscv/db_trace.c18
-rw-r--r--sys/riscv/riscv/locore.S23
-rw-r--r--sys/riscv/riscv/stack_machdep.c19
-rw-r--r--sys/riscv/riscv/trap.c23
-rw-r--r--sys/riscv/riscv/unwind.c6
-rw-r--r--sys/rpc/clnt.h2
-rw-r--r--sys/sys/domain.h9
-rw-r--r--sys/sys/namei.h39
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/pipe.h2
-rw-r--r--sys/sys/pmc.h3
-rw-r--r--sys/sys/prng.h20
-rw-r--r--sys/sys/smp.h2
-rw-r--r--sys/sys/vnode.h9
-rw-r--r--sys/vm/uma_core.c11
-rw-r--r--sys/vm/vm_meter.c3
-rw-r--r--sys/vm/vm_page.c2
-rw-r--r--sys/vm/vm_page.h1
-rw-r--r--sys/vm/vm_pageout.c214
-rw-r--r--sys/vm/vm_pagequeue.h9
-rw-r--r--tests/sys/fs/fusefs/forget.cc3
-rw-r--r--tools/build/Makefile10
-rw-r--r--tools/debugscripts/kgdb67
-rw-r--r--tools/tools/locale/Makefile185
-rw-r--r--tools/tools/locale/README84
-rw-r--r--tools/tools/locale/etc/final-maps/map.UTF-8554
-rw-r--r--tools/tools/locale/patch/patch-UnicodeData.txt29
-rwxr-xr-xtools/tools/locale/tools/cldr2def.pl5
-rwxr-xr-xtools/tools/locale/tools/convert_map.pl5
-rwxr-xr-xtools/tools/locale/tools/finalize38
-rwxr-xr-xtools/tools/locale/tools/utf8-rollup.pl31
-rw-r--r--usr.bin/fortune/fortune/fortune.c9
-rw-r--r--usr.bin/fortune/strfile/strfile.c18
-rw-r--r--usr.bin/script/script.c19
-rw-r--r--usr.bin/tput/tput.163
-rw-r--r--usr.sbin/crunch/crunchgen/crunchgen.c36
-rw-r--r--usr.sbin/pwd_mkdb/bootstrap/pwd.h2
175 files changed, 3866 insertions, 1824 deletions
diff --git a/Makefile.inc1 b/Makefile.inc1
index 00abab63d24b3..9223123b1e1b4 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -180,7 +180,7 @@ MK_SYSTEM_LINKER= no
.if defined(CROSS_TOOLCHAIN_PREFIX)
CROSS_BINUTILS_PREFIX?=${CROSS_TOOLCHAIN_PREFIX}
.endif
-XBINUTILS= AS AR LD NM OBJCOPY RANLIB SIZE STRINGS
+XBINUTILS= AS AR LD NM OBJCOPY RANLIB SIZE STRINGS STRIPBIN
.for BINUTIL in ${XBINUTILS}
.if defined(CROSS_BINUTILS_PREFIX) && \
exists(${CROSS_BINUTILS_PREFIX}/${${BINUTIL}})
@@ -552,6 +552,13 @@ SOURCE_DATE_EPOCH= ${TIMEEPOCHNOW:gmtime}
SOURCE_DATE_EPOCH= ${PKG_TIMESTAMP}
.endif
+PKG_NAME_PREFIX?= FreeBSD
+PKG_MAINTAINER?= re@FreeBSD.org
+PKG_WWW?= https://www.FreeBSD.org
+.export PKG_NAME_PREFIX
+.export PKG_MAINTAINER
+.export PKG_WWW
+
.if !defined(_MKSHOWCONFIG)
_CPUTYPE!= MAKEFLAGS= CPUTYPE=${_TARGET_CPUTYPE} ${MAKE} -f /dev/null \
-m ${.CURDIR}/share/mk MK_AUTO_OBJ=no -V CPUTYPE
@@ -748,7 +755,7 @@ CROSSENV+= CC="${XCC} ${XCFLAGS}" CXX="${XCXX} ${XCXXFLAGS} ${XCFLAGS}" \
AS="${XAS}" AR="${XAR}" LD="${XLD}" LLVM_LINK="${XLLVM_LINK}" \
NM=${XNM} OBJCOPY="${XOBJCOPY}" \
RANLIB=${XRANLIB} STRINGS=${XSTRINGS} \
- SIZE="${XSIZE}"
+ SIZE="${XSIZE}" STRIPBIN="${XSTRIPBIN}"
.if defined(CROSS_BINUTILS_PREFIX) && exists(${CROSS_BINUTILS_PREFIX})
# In the case of xdev-build tools, CROSS_BINUTILS_PREFIX won't be a
@@ -1906,6 +1913,9 @@ create-kernel-packages-flavor${flavor:C,^""$,${_default_flavor},}: _pkgbootstrap
-e "s/%COMMENT%/FreeBSD ${INSTALLKERNEL} kernel ${flavor}/" \
-e "s/%DESC%/FreeBSD ${INSTALLKERNEL} kernel ${flavor}/" \
-e "s/ %VCS_REVISION%/${VCS_REVISION}/" \
+ -e "s/%PKG_NAME_PREFIX%/${PKG_NAME_PREFIX}/" \
+ -e "s/%PKG_MAINTAINER%/${PKG_MAINTAINER}/" \
+ -e "s|%PKG_WWW%|${PKG_WWW}|" \
${SRCDIR}/release/packages/kernel.ucl \
> ${KSTAGEDIR}/${DISTDIR}/kernel.${INSTALLKERNEL}${flavor}.ucl ; \
awk -F\" ' \
@@ -1939,6 +1949,9 @@ create-kernel-packages-extra-flavor${flavor:C,^""$,${_default_flavor},}-${_kerne
-e "s/%COMMENT%/FreeBSD ${_kernel} kernel ${flavor}/" \
-e "s/%DESC%/FreeBSD ${_kernel} kernel ${flavor}/" \
-e "s/ %VCS_REVISION%/${VCS_REVISION}/" \
+ -e "s/%PKG_NAME_PREFIX%/${PKG_NAME_PREFIX}/" \
+ -e "s/%PKG_MAINTAINER%/${PKG_MAINTAINER}/" \
+ -e "s|%PKG_WWW%|${PKG_WWW}|" \
${SRCDIR}/release/packages/kernel.ucl \
> ${KSTAGEDIR}/kernel.${_kernel}/kernel.${_kernel}${flavor}.ucl ; \
awk -F\" ' \
@@ -2227,9 +2240,13 @@ ${_bt}-usr.bin/mandoc: ${_bt}-lib/libopenbsd
_basic_bootstrap_tools_multilink=usr.bin/grep grep,egrep,fgrep
_basic_bootstrap_tools_multilink+=bin/test test,[
# bootstrap tools needed by buildworld:
-_basic_bootstrap_tools=usr.bin/awk usr.bin/cut bin/expr usr.bin/gencat \
+_basic_bootstrap_tools=usr.bin/cut bin/expr usr.bin/gencat \
usr.bin/join usr.bin/mktemp bin/rmdir usr.bin/sed usr.bin/sort \
usr.bin/truncate usr.bin/tsort
+# Some build scripts use nawk instead of awk (this happens at least in
+# cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh) so we need both awk
+# and nawk in ${WORLDTMP}/legacy/bin.
+_basic_bootstrap_tools_multilink+=usr.bin/awk awk,nawk
# file2c is required for building usr.sbin/config:
_basic_bootstrap_tools+=usr.bin/file2c
# uuencode/uudecode required for share/tabset
diff --git a/UPDATING b/UPDATING
index 9e12bded35d5b..48c6a6bd3c4dc 100644
--- a/UPDATING
+++ b/UPDATING
@@ -32,6 +32,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
information about prerequisites and upgrading, if you are not already
using clang 3.5.0 or higher.
+20200810:
+ r364092 modified the internal ABI used between the kernel NFS
+ modules. As such, all of these modules need to be rebuilt
+ from sources, so a version bump was done.
+
20200807:
Makefile.inc has been updated to work around the issue documented in
20200729. It was a case where the optimization of using symbolic links
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh
index 50b7f1c1b9082..de4b86270efa4 100755
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh
@@ -24,15 +24,15 @@
# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
+set -e
-echo "\
-/*\n\
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.\n\
- * Use is subject to license terms.\n\
- */\n\
-\n\
-#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n"
+printf "%s" "
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+"
pattern='^#define[ ]\(E[A-Z0-9]*\)[ ]*\([A-Z0-9]*\).*$'
replace='inline int \1 = \2;@#pragma D binding "1.0" \1'
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh
index d5651ff727fce..11b327cbff17b 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh
@@ -24,36 +24,34 @@
# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
-
-BSDECHO=-e
-
-echo ${BSDECHO} "\
-/*\n\
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.\n\
- * Use is subject to license terms.\n\
- */\n\
-\n\
-#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n\
-\n\
+set -e
+
+printf "%s" "
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
#include <dt_errtags.h>
-\n\
-static const char *const _dt_errtags[] = {"
+
+static const char *const _dt_errtags[] = {
+"
pattern='^ \(D_[A-Z0-9_]*\),*'
replace=' "\1",'
sed -n "s/$pattern/$replace/p" || exit 1
-echo ${BSDECHO} "\
-};\n\
-\n\
-static const int _dt_ntag = sizeof (_dt_errtags) / sizeof (_dt_errtags[0]);\n\
-\n\
+printf "%s" "
+};
+
+static const int _dt_ntag = sizeof (_dt_errtags) / sizeof (_dt_errtags[0]);
+
const char *
dt_errtag(dt_errtag_t tag)
{
return (_dt_errtags[(tag > 0 && tag < _dt_ntag) ? tag : 0]);
-}"
+}
+"
exit 0
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh
index 2fdc2fa636d52..c7c28e75364e8 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh
@@ -24,32 +24,30 @@
# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
+set -e
-BSDECHO=-e
+printf "%s" "
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <dtrace.h>
-echo ${BSDECHO} "\
-/*\n\
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.\n\
- * Use is subject to license terms.\n\
- */\n\
-\n\
-#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n\
-\n\
-#include <dtrace.h>\n\
-\n\
/*ARGSUSED*/
-const char *\n\
-dtrace_subrstr(dtrace_hdl_t *dtp, int subr)\n\
-{\n\
- switch (subr) {"
+const char *
+dtrace_subrstr(dtrace_hdl_t *dtp, int subr)
+{
+ switch (subr) {
+"
nawk '
/^#define[ ]*DIF_SUBR_/ && $2 != "DIF_SUBR_MAX" {
printf("\tcase %s: return (\"%s\");\n", $2, tolower(substr($2, 10)));
}'
-echo ${BSDECHO} "\
- default: return (\"unknown\");\n\
- }\n\
-}"
+printf "%s" "
+ default: return (\"unknown\");
+ }
+}
+"
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh
index 1bffa6468c2bb..2bd5ec92b43e9 100755
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh
@@ -24,15 +24,15 @@
# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
+set -e
-echo "\
-/*\n\
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.\n\
- * Use is subject to license terms.\n\
- */\n\
-\n\
-#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n"
+printf "%s" "
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+"
pattern='^#define[ ]*_*\(SIG[A-Z0-9]*\)[ ]\{1,\}\([A-Z0-9]*\).*$'
replace='inline int \1 = \2;@#pragma D binding "1.0" \1'
diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist
index c8ea2f23ecac7..73a5fe6eca9c5 100644
--- a/etc/mtree/BSD.usr.dist
+++ b/etc/mtree/BSD.usr.dist
@@ -68,6 +68,8 @@
..
engines
..
+ flua
+ ..
i18n
..
libxo
@@ -370,6 +372,8 @@
..
firmware
..
+ flua
+ ..
games
fortune
..
diff --git a/lib/libbsnmp/Makefile b/lib/libbsnmp/Makefile
index 22821c7bcb5ab..453cba29ddf52 100644
--- a/lib/libbsnmp/Makefile
+++ b/lib/libbsnmp/Makefile
@@ -1,5 +1,6 @@
# $FreeBSD$
SUBDIR= libbsnmp
+SUBDIR.${MK_TESTS}+= tests
.include <bsd.subdir.mk>
diff --git a/lib/libbsnmp/tests/Makefile b/lib/libbsnmp/tests/Makefile
new file mode 100644
index 0000000000000..74fbec52ec130
--- /dev/null
+++ b/lib/libbsnmp/tests/Makefile
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+.include <bsd.own.mk>
+
+ATF_TESTS_C+= bsnmpd_test
+
+SRCS.bsmpd_test= bsnmpd_test.c
+
+LIBADD+= bsnmp
+
+.include <bsd.test.mk>
diff --git a/lib/libbsnmp/tests/bsnmpd_test.c b/lib/libbsnmp/tests/bsnmpd_test.c
new file mode 100644
index 0000000000000..c6e4bfd385b50
--- /dev/null
+++ b/lib/libbsnmp/tests/bsnmpd_test.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 2020 Dell EMC
+ * 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, 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$
+ */
+
+#include <bsnmp/asn1.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(sa_19_20_bsnmp_test);
+ATF_TC_BODY(sa_19_20_bsnmp_test, tc)
+{
+ struct asn_buf b = {};
+ char test_buf[] = { 0x25, 0x7f };
+ enum asn_err err;
+ asn_len_t len;
+ u_char type;
+
+ b.asn_cptr = test_buf;
+ b.asn_len = sizeof(test_buf);
+
+ err = asn_get_header(&b, &type, &len);
+ ATF_CHECK_EQ(ASN_ERR_EOBUF, err);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, sa_19_20_bsnmp_test);
+ return (atf_no_error());
+}
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index f86c7b04b92b4..779b418e93409 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -120,6 +120,7 @@ SRCS+= __getosreldate.c \
recvmmsg.c \
rewinddir.c \
scandir.c \
+ scandir_b.c \
scandir-compat11.c \
seed48.c \
seekdir.c \
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
index f9d4f158ed30d..e17d74d1a151f 100644
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -416,7 +416,6 @@ FBSD_1.5 {
readdir;
readdir_r;
scandir;
- scandir_b;
sem_clockwait_np;
setproctitle_fast;
timespec_get;
@@ -424,6 +423,7 @@ FBSD_1.5 {
FBSD_1.6 {
memalign;
+ scandir_b;
sigandset;
sigisemptyset;
sigorset;
diff --git a/lib/libc/gen/scandir-compat11.c b/lib/libc/gen/scandir-compat11.c
index 712d14ee9c04c..b1c0ecb836221 100644
--- a/lib/libc/gen/scandir-compat11.c
+++ b/lib/libc/gen/scandir-compat11.c
@@ -49,32 +49,25 @@ __FBSDID("$FreeBSD$");
#include "gen-compat.h"
-#ifdef I_AM_SCANDIR_B
-#include "block_abi.h"
-#define SELECT(x) CALL_BLOCK(select, x)
-#ifndef __BLOCKS__
-void
-qsort_b(void *, size_t, size_t, void*);
-#endif
-#else
+/*
+ * scandir_b@FBSD_1.4 was never exported from libc.so.7 due to a
+ * mistake, so there is no use of exporting it now with some earlier
+ * symbol version. As result, we do not need to implement compat
+ * function freebsd11_scandir_b().
+ */
+
#define SELECT(x) select(x)
-#endif
+
+void qsort_b(void *, size_t, size_t, void *);
static int freebsd11_alphasort_thunk(void *thunk, const void *p1,
const void *p2);
int
-#ifdef I_AM_SCANDIR_B
-freebsd11_scandir_b(const char *dirname, struct freebsd11_dirent ***namelist,
- DECLARE_BLOCK(int, select, const struct freebsd11_dirent *),
- DECLARE_BLOCK(int, dcomp, const struct freebsd11_dirent **,
- const struct freebsd11_dirent **))
-#else
freebsd11_scandir(const char *dirname, struct freebsd11_dirent ***namelist,
int (*select)(const struct freebsd11_dirent *),
int (*dcomp)(const struct freebsd11_dirent **,
const struct freebsd11_dirent **))
-#endif
{
struct freebsd11_dirent *d, *p, **names = NULL;
size_t arraysz, numitems;
@@ -124,13 +117,8 @@ freebsd11_scandir(const char *dirname, struct freebsd11_dirent ***namelist,
}
closedir(dirp);
if (numitems && dcomp != NULL)
-#ifdef I_AM_SCANDIR_B
- qsort_b(names, numitems, sizeof(struct freebsd11_dirent *),
- (void*)dcomp);
-#else
qsort_r(names, numitems, sizeof(struct freebsd11_dirent *),
&dcomp, freebsd11_alphasort_thunk);
-#endif
*namelist = names;
return (numitems);
@@ -168,4 +156,3 @@ freebsd11_alphasort_thunk(void *thunk, const void *p1, const void *p2)
__sym_compat(alphasort, freebsd11_alphasort, FBSD_1.0);
__sym_compat(scandir, freebsd11_scandir, FBSD_1.0);
-__sym_compat(scandir_b, freebsd11_scandir_b, FBSD_1.4);
diff --git a/lib/libc/gen/scandir.c b/lib/libc/gen/scandir.c
index 036a0166d48bc..7e5bcce905fb4 100644
--- a/lib/libc/gen/scandir.c
+++ b/lib/libc/gen/scandir.c
@@ -50,8 +50,7 @@ __FBSDID("$FreeBSD$");
#include "block_abi.h"
#define SELECT(x) CALL_BLOCK(select, x)
#ifndef __BLOCKS__
-void
-qsort_b(void *, size_t, size_t, void*);
+void qsort_b(void *, size_t, size_t, void *);
#endif
#else
#define SELECT(x) select(x)
@@ -134,6 +133,7 @@ fail:
return (-1);
}
+#ifndef I_AM_SCANDIR_B
/*
* Alphabetic order comparison routine for those who want it.
* POSIX 2008 requires that alphasort() uses strcoll().
@@ -153,3 +153,4 @@ alphasort_thunk(void *thunk, const void *p1, const void *p2)
dc = *(int (**)(const struct dirent **, const struct dirent **))thunk;
return (dc((const struct dirent **)p1, (const struct dirent **)p2));
}
+#endif
diff --git a/lib/libc/gen/syslog.c b/lib/libc/gen/syslog.c
index a0f1ddc975354..19d44db0075a7 100644
--- a/lib/libc/gen/syslog.c
+++ b/lib/libc/gen/syslog.c
@@ -75,6 +75,9 @@ static pthread_mutex_t syslog_mutex = PTHREAD_MUTEX_INITIALIZER;
if (__isthreaded) _pthread_mutex_unlock(&syslog_mutex); \
} while(0)
+/* RFC5424 defined value. */
+#define NILVALUE "-"
+
static void disconnectlog(void); /* disconnect from syslogd */
static void connectlog(void); /* (re)connect to syslogd */
static void openlog_unlocked(const char *, int, int);
@@ -190,25 +193,30 @@ vsyslog1(int pri, const char *fmt, va_list ap)
tm.tm_hour, tm.tm_min, tm.tm_sec, now.tv_usec,
tz_sign, tz_offset / 3600, (tz_offset % 3600) / 60);
} else
- (void)fprintf(fp, "- ");
+ (void)fputs(NILVALUE " ", fp);
/* Hostname. */
(void)gethostname(hostname, sizeof(hostname));
- (void)fprintf(fp, "%s ", hostname);
+ (void)fprintf(fp, "%s ",
+ hostname[0] == '\0' ? NILVALUE : hostname);
if (LogStat & LOG_PERROR) {
/* Transfer to string buffer */
(void)fflush(fp);
stdp = tbuf + (sizeof(tbuf) - tbuf_cookie.left);
}
+ /* Application name. */
+ if (LogTag == NULL)
+ LogTag = _getprogname();
+ (void)fprintf(fp, "%s ", LogTag == NULL ? NILVALUE : LogTag);
/*
- * Application name, process ID, message ID and structured data.
* Provide the process ID regardless of whether LOG_PID has been
* specified, as it provides valuable information. Many
* applications tend not to use this, even though they should.
*/
- if (LogTag == NULL)
- LogTag = _getprogname();
- (void)fprintf(fp, "%s %d - - ",
- LogTag == NULL ? "-" : LogTag, getpid());
+ (void)fprintf(fp, "%d ", getpid());
+ /* Message ID. */
+ (void)fputs(NILVALUE " ", fp);
+ /* Structured data. */
+ (void)fputs(NILVALUE " ", fp);
/* Check to see if we can skip expanding the %m */
if (strstr(fmt, "%m")) {
@@ -251,6 +259,7 @@ vsyslog1(int pri, const char *fmt, va_list ap)
fmt = fmt_cpy;
}
+ /* Message. */
(void)vfprintf(fp, fmt, ap);
(void)fclose(fp);
diff --git a/lib/liblua/Makefile b/lib/liblua/Makefile
index 28fc05a9aa712..e5f5e3c5960a3 100644
--- a/lib/liblua/Makefile
+++ b/lib/liblua/Makefile
@@ -29,6 +29,8 @@ CFLAGS+= -DLUA_PROGNAME="\"${PROG}\""
.if defined(BOOTSTRAPPING)
CFLAGS+= -DLUA_PATH_DEFAULT="\"/nonexistent/?.lua\""
CFLAGS+= -DLUA_CPATH_DEFAULT="\"/nonexistent/?.so\""
+# We don't support dynamic libs on bootstrap builds.
+CFLAGS+= -DBOOTSTRAPPING
.endif
.include <bsd.lib.mk>
diff --git a/lib/liblua/luaconf.h b/lib/liblua/luaconf.h
index b24645b8915f3..bc7f5bb6e1414 100644
--- a/lib/liblua/luaconf.h
+++ b/lib/liblua/luaconf.h
@@ -75,6 +75,9 @@
/* Local modifications: need io.popen */
#ifdef __FreeBSD__
#define LUA_USE_POSIX
+#ifndef BOOTSTRAPPING
+#define LUA_USE_DLOPEN
+#endif
#endif
/*
@@ -205,9 +208,9 @@
#else /* }{ */
-#define LUA_ROOT "/usr/local/"
-#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/"
-#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/"
+#define LUA_ROOT "/usr/"
+#define LUA_LDIR LUA_ROOT "share/flua/"
+#define LUA_CDIR LUA_ROOT "lib/flua/"
#if !defined(LUA_PATH_DEFAULT)
#define LUA_PATH_DEFAULT \
LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c
index 6e39373c1cb43..7d435cab0ff08 100644
--- a/lib/libpmc/libpmc.c
+++ b/lib/libpmc/libpmc.c
@@ -176,6 +176,11 @@ static const struct pmc_event_descr cortex_a57_event_table[] =
__PMC_EV_ALIAS_ARMV8_CORTEX_A57()
};
+static const struct pmc_event_descr cortex_a76_event_table[] =
+{
+ __PMC_EV_ALIAS_ARMV8_CORTEX_A76()
+};
+
/*
* PMC_MDEP_TABLE(NAME, PRIMARYCLASS, ADDITIONAL_CLASSES...)
*
@@ -193,6 +198,7 @@ PMC_MDEP_TABLE(cortex_a8, ARMV7, PMC_CLASS_SOFT, PMC_CLASS_ARMV7);
PMC_MDEP_TABLE(cortex_a9, ARMV7, PMC_CLASS_SOFT, PMC_CLASS_ARMV7);
PMC_MDEP_TABLE(cortex_a53, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8);
PMC_MDEP_TABLE(cortex_a57, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8);
+PMC_MDEP_TABLE(cortex_a76, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8);
PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K);
PMC_MDEP_TABLE(mips74k, MIPS74K, PMC_CLASS_SOFT, PMC_CLASS_MIPS74K);
PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON);
@@ -235,6 +241,7 @@ PMC_CLASS_TABLE_DESC(cortex_a9, ARMV7, cortex_a9, armv7);
#if defined(__aarch64__)
PMC_CLASS_TABLE_DESC(cortex_a53, ARMV8, cortex_a53, arm64);
PMC_CLASS_TABLE_DESC(cortex_a57, ARMV8, cortex_a57, arm64);
+PMC_CLASS_TABLE_DESC(cortex_a76, ARMV8, cortex_a76, arm64);
#endif
#if defined(__mips__)
PMC_CLASS_TABLE_DESC(beri, BERI, beri, mips);
@@ -817,6 +824,9 @@ static struct pmc_event_alias cortex_a53_aliases[] = {
static struct pmc_event_alias cortex_a57_aliases[] = {
EV_ALIAS(NULL, NULL)
};
+static struct pmc_event_alias cortex_a76_aliases[] = {
+ EV_ALIAS(NULL, NULL)
+};
static int
arm64_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
struct pmc_op_pmcallocate *pmc_config __unused)
@@ -1273,6 +1283,10 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames,
ev = cortex_a57_event_table;
count = PMC_EVENT_TABLE_SIZE(cortex_a57);
break;
+ case PMC_CPU_ARMV8_CORTEX_A76:
+ ev = cortex_a76_event_table;
+ count = PMC_EVENT_TABLE_SIZE(cortex_a76);
+ break;
}
break;
case PMC_CLASS_BERI:
@@ -1518,6 +1532,10 @@ pmc_init(void)
PMC_MDEP_INIT(cortex_a57);
pmc_class_table[n] = &cortex_a57_class_table_descr;
break;
+ case PMC_CPU_ARMV8_CORTEX_A76:
+ PMC_MDEP_INIT(cortex_a76);
+ pmc_class_table[n] = &cortex_a76_class_table_descr;
+ break;
#endif
#if defined(__mips__)
case PMC_CPU_MIPS_BERI:
@@ -1658,6 +1676,10 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu)
ev = cortex_a57_event_table;
evfence = cortex_a57_event_table + PMC_EVENT_TABLE_SIZE(cortex_a57);
break;
+ case PMC_CPU_ARMV8_CORTEX_A76:
+ ev = cortex_a76_event_table;
+ evfence = cortex_a76_event_table + PMC_EVENT_TABLE_SIZE(cortex_a76);
+ break;
default: /* Unknown CPU type. */
break;
}
diff --git a/libexec/flua/Makefile b/libexec/flua/Makefile
index a4dc916e7834a..cfa1f2460f5f6 100644
--- a/libexec/flua/Makefile
+++ b/libexec/flua/Makefile
@@ -30,6 +30,7 @@ CFLAGS+= -DLUA_PROGNAME="\"${PROG}\""
CFLAGS+= -DLUA_USE_READLINE
CFLAGS+= -I${SRCTOP}/lib/libedit -I${SRCTOP}/contrib/libedit
LIBADD+= edit
+LDFLAGS+= -Wl,-E
.endif
UCLSRC?= ${SRCTOP}/contrib/libucl
diff --git a/libexec/rc/rc.d/ipfilter b/libexec/rc/rc.d/ipfilter
index 6a430b55d897f..fe328308e6229 100755
--- a/libexec/rc/rc.d/ipfilter
+++ b/libexec/rc/rc.d/ipfilter
@@ -5,6 +5,7 @@
# PROVIDE: ipfilter
# REQUIRE: FILESYSTEMS
+# BEFORE: ipmon ipnat netif netwait securelevel
# KEYWORD: nojailvnet
. /etc/rc.subr
diff --git a/libexec/rc/rc.d/ipmon b/libexec/rc/rc.d/ipmon
index a742daa363d5a..56b64f8c8271d 100755
--- a/libexec/rc/rc.d/ipmon
+++ b/libexec/rc/rc.d/ipmon
@@ -4,7 +4,7 @@
#
# PROVIDE: ipmon
-# REQUIRE: FILESYSTEMS hostname sysctl ipfilter
+# REQUIRE: FILESYSTEMS hostname sysctl
# BEFORE: SERVERS
# KEYWORD: nojailvnet
diff --git a/libexec/rc/rc.d/ipnat b/libexec/rc/rc.d/ipnat
index bff94154dc65b..d4fa6b65dff4c 100755
--- a/libexec/rc/rc.d/ipnat
+++ b/libexec/rc/rc.d/ipnat
@@ -4,7 +4,6 @@
#
# PROVIDE: ipnat
-# REQUIRE: ipfilter
# KEYWORD: nojailvnet
. /etc/rc.subr
diff --git a/libexec/rc/rc.d/netif b/libexec/rc/rc.d/netif
index a1543e63e7049..eb1efc4d62749 100755
--- a/libexec/rc/rc.d/netif
+++ b/libexec/rc/rc.d/netif
@@ -27,7 +27,7 @@
# PROVIDE: netif
# REQUIRE: FILESYSTEMS iovctl serial sppp sysctl
-# REQUIRE: hostid ipfilter ipfs
+# REQUIRE: hostid ipfs
# KEYWORD: nojailvnet
. /etc/rc.subr
diff --git a/libexec/rc/rc.d/netwait b/libexec/rc/rc.d/netwait
index ab80cec50576d..92f124cd4f27e 100755
--- a/libexec/rc/rc.d/netwait
+++ b/libexec/rc/rc.d/netwait
@@ -3,7 +3,7 @@
# $FreeBSD$
#
# PROVIDE: netwait
-# REQUIRE: devd ipfilter ipfw pf routing
+# REQUIRE: devd ipfw pf routing
# KEYWORD: nojail
#
# The netwait script helps handle two situations:
diff --git a/libexec/rc/rc.d/securelevel b/libexec/rc/rc.d/securelevel
index c42a03534675c..24dbf269df3f1 100755
--- a/libexec/rc/rc.d/securelevel
+++ b/libexec/rc/rc.d/securelevel
@@ -4,7 +4,7 @@
#
# PROVIDE: securelevel
-# REQUIRE: adjkerntz ipfw ipfilter pf
+# REQUIRE: adjkerntz ipfw pf
. /etc/rc.subr
diff --git a/release/packages/binutils.ucl b/release/packages/binutils.ucl
index fcf05b313b388..ec246dfacd756 100644
--- a/release/packages/binutils.ucl
+++ b/release/packages/binutils.ucl
@@ -2,13 +2,13 @@
# $FreeBSD$
#
-name = "FreeBSD-%PKGNAME%"
+name = "%PKG_NAME_PREFIX%-%PKGNAME%"
origin = "base"
version = "%VERSION%"
comment = "%COMMENT%"
categories = [ base ]
-maintainer = "re@FreeBSD.org"
-www = "https://www.FreeBSD.org"
+maintainer = "%PKG_MAINTAINER%"
+www = "%PKG_WWW%"
prefix = "/"
licenselogic = "single"
licenses = [ GPLv2 ]
diff --git a/release/packages/caroot.ucl b/release/packages/caroot.ucl
index f0d1730f9976b..bc298efcabf4b 100644
--- a/release/packages/caroot.ucl
+++ b/release/packages/caroot.ucl
@@ -2,13 +2,13 @@
# $FreeBSD$
#
-name = "FreeBSD-%PKGNAME%"
+name = "%PKG_NAME_PREFIX%-%PKGNAME%"
origin = "base"
version = "%VERSION%"
comment = "%COMMENT%"
categories = [ base ]
-maintainer = "re@FreeBSD.org"
-www = "https://www.FreeBSD.org"
+maintainer = %PKG_MAINTAINER%
+www = "%PKG_WWW%"
prefix = "/"
licenselogic = "single"
licenses = [ BSD2CLAUSE ]
diff --git a/release/packages/clang.ucl b/release/packages/clang.ucl
index 3f8820abcbdf4..0642f21d1daa5 100644
--- a/release/packages/clang.ucl
+++ b/release/packages/clang.ucl
@@ -2,13 +2,13 @@
# $FreeBSD$
#
-name = "FreeBSD-%PKGNAME%"
+name = "%PKG_NAME_PREFIX%-%PKGNAME%"
origin = "base"
version = "%VERSION%"
comment = "%COMMENT%"
categories = [ base ]
-maintainer = "re@FreeBSD.org"
-www = "https://www.FreeBSD.org"
+maintainer = "%PKG_MAINTAINER%"
+www = "%PKG_WWW%"
prefix = "/"
licenselogic = "single"
licenses = [ NCSA ]
diff --git a/release/packages/gdb.ucl b/release/packages/gdb.ucl
index fcf05b313b388..ec246dfacd756 100644
--- a/release/packages/gdb.ucl
+++ b/release/packages/gdb.ucl
@@ -2,13 +2,13 @@
# $FreeBSD$
#
-name = "FreeBSD-%PKGNAME%"
+name = "%PKG_NAME_PREFIX%-%PKGNAME%"
origin = "base"
version = "%VERSION%"
comment = "%COMMENT%"
categories = [ base ]
-maintainer = "re@FreeBSD.org"
-www = "https://www.FreeBSD.org"
+maintainer = "%PKG_MAINTAINER%"
+www = "%PKG_WWW%"
prefix = "/"
licenselogic = "single"
licenses = [ GPLv2 ]
diff --git a/release/packages/generate-ucl.sh b/release/packages/generate-ucl.sh
index 38bbb992d454f..b3d76eb4019d2 100755
--- a/release/packages/generate-ucl.sh
+++ b/release/packages/generate-ucl.sh
@@ -146,6 +146,9 @@ EOF
-e "s/%COMMENT%/${comment}/" \
-e "s/%DESC%/${desc}/" \
-e "s/%CAP_MKDB_ENDIAN%/${cap_arg}/g" \
+ -e "s/%PKG_NAME_PREFIX%/${PKG_NAME_PREFIX}/" \
+ -e "s|%PKG_WWW%|${PKG_WWW}|" \
+ -e "s/%PKG_MAINTAINER%/${PKG_MAINTAINER}/" \
${uclfile}
return 0
}
diff --git a/release/packages/groff.ucl b/release/packages/groff.ucl
index fcf05b313b388..ec246dfacd756 100644
--- a/release/packages/groff.ucl
+++ b/release/packages/groff.ucl
@@ -2,13 +2,13 @@
# $FreeBSD$
#
-name = "FreeBSD-%PKGNAME%"
+name = "%PKG_NAME_PREFIX%-%PKGNAME%"
origin = "base"
version = "%VERSION%"
comment = "%COMMENT%"
categories = [ base ]
-maintainer = "re@FreeBSD.org"
-www = "https://www.FreeBSD.org"
+maintainer = "%PKG_MAINTAINER%"
+www = "%PKG_WWW%"
prefix = "/"
licenselogic = "single"
licenses = [ GPLv2 ]
diff --git a/release/packages/jail.ucl b/release/packages/jail.ucl
index fcb9a567125b8..8448a15ebf7b7 100644
--- a/release/packages/jail.ucl
+++ b/release/packages/jail.ucl
@@ -2,13 +2,13 @@
# $FreeBSD$
#
-name = "FreeBSD-%PKGNAME%"
+name = "%PKG_NAME_PREFIX%-%PKGNAME%"
origin = "base"
version = "%VERSION%"
comment = "%COMMENT%"
categories = [ base ]
-maintainer = "re@FreeBSD.org"
-www = "https://www.FreeBSD.org"
+maintainer = "%PKG_MAINTAINER%"
+www = "%PKG_WWW%"
prefix = "/"
vital = true
licenselogic = "single"
diff --git a/release/packages/kernel.ucl b/release/packages/kernel.ucl
index d7684a6d889d6..b7317cae507c7 100644
--- a/release/packages/kernel.ucl
+++ b/release/packages/kernel.ucl
@@ -2,13 +2,13 @@
# $FreeBSD$
#
-name = "FreeBSD-%PKGNAME%"
+name = "%PKG_NAME_PREFIX%-%PKGNAME%"
origin = "base"
version = "%VERSION%"
comment = "%COMMENT%"
categories = [ base ]
-maintainer = "re@FreeBSD.org"
-www = "https://www.FreeBSD.org"
+maintainer = "%PKG_MAINTAINER%"
+www = "%PKG_WWW%"
prefix = "/"
licenselogic = "single"
licenses = [ BSD2CLAUSE ]
diff --git a/release/packages/lld.ucl b/release/packages/lld.ucl
index 3f8820abcbdf4..0642f21d1daa5 100644
--- a/release/packages/lld.ucl
+++ b/release/packages/lld.ucl
@@ -2,13 +2,13 @@
# $FreeBSD$
#
-name = "FreeBSD-%PKGNAME%"
+name = "%PKG_NAME_PREFIX%-%PKGNAME%"
origin = "base"
version = "%VERSION%"
comment = "%COMMENT%"
categories = [ base ]
-maintainer = "re@FreeBSD.org"
-www = "https://www.FreeBSD.org"
+maintainer = "%PKG_MAINTAINER%"
+www = "%PKG_WWW%"
prefix = "/"
licenselogic = "single"
licenses = [ NCSA ]
diff --git a/release/packages/lldb.ucl b/release/packages/lldb.ucl
index 3f8820abcbdf4..0642f21d1daa5 100644
--- a/release/packages/lldb.ucl
+++ b/release/packages/lldb.ucl
@@ -2,13 +2,13 @@
# $FreeBSD$
#
-name = "FreeBSD-%PKGNAME%"
+name = "%PKG_NAME_PREFIX%-%PKGNAME%"
origin = "base"
version = "%VERSION%"
comment = "%COMMENT%"
categories = [ base ]
-maintainer = "re@FreeBSD.org"
-www = "https://www.FreeBSD.org"
+maintainer = "%PKG_MAINTAINER%"
+www = "%PKG_WWW%"
prefix = "/"
licenselogic = "single"
licenses = [ NCSA ]
diff --git a/release/packages/runtime.ucl b/release/packages/runtime.ucl
index b17971acb2eb5..6b51c830ab5cc 100644
--- a/release/packages/runtime.ucl
+++ b/release/packages/runtime.ucl
@@ -2,13 +2,13 @@
# $FreeBSD$
#
-name = "FreeBSD-%PKGNAME%"
+name = "%PKG_NAME_PREFIX%-%PKGNAME%"
origin = "base"
version = "%VERSION%"
comment = "%COMMENT%"
categories = [ base ]
-maintainer = "re@FreeBSD.org"
-www = "https://www.FreeBSD.org"
+maintainer = "%PKG_MAINTAINER%"
+www = "%PKG_WWW%"
prefix = "/"
vital = true
licenselogic = "single"
diff --git a/release/packages/ssh.ucl b/release/packages/ssh.ucl
index faf264e00f10a..415094e9d69f4 100644
--- a/release/packages/ssh.ucl
+++ b/release/packages/ssh.ucl
@@ -2,13 +2,13 @@
# $FreeBSD$
#
-name = "FreeBSD-%PKGNAME%"
+name = "%PKG_NAME_PREFIX%-%PKGNAME%"
origin = "base"
version = "%VERSION%"
comment = "%COMMENT%"
categories = [ base ]
-maintainer = "re@FreeBSD.org"
-www = "https://www.FreeBSD.org"
+maintainer = "%PKG_MAINTAINER%"
+www = "%PKG_WWW%"
prefix = "/"
licenselogic = "single"
licenses = [ ISCL ]
diff --git a/release/packages/svn.ucl b/release/packages/svn.ucl
index 5211101e9e8c4..f80da47be55b5 100644
--- a/release/packages/svn.ucl
+++ b/release/packages/svn.ucl
@@ -2,13 +2,13 @@
# $FreeBSD$
#
-name = "FreeBSD-%PKGNAME%"
+name = "%PKG_NAME_PREFIX%-%PKGNAME%"
origin = "base"
version = "%VERSION%"
comment = "%COMMENT%"
categories = [ base ]
-maintainer = "re@FreeBSD.org"
-www = "https://www.FreeBSD.org"
+maintainer = "%PKG_MAINTAINER%"
+www = "%PKG_WWW%"
prefix = "/"
licenselogic = "single"
licenses = [ APACHE20 ]
diff --git a/release/packages/template.ucl b/release/packages/template.ucl
index 38844f0f0898c..f7cea7af88931 100644
--- a/release/packages/template.ucl
+++ b/release/packages/template.ucl
@@ -2,13 +2,13 @@
# $FreeBSD$
#
-name = "FreeBSD-%PKGNAME%"
+name = "%PKG_NAME_PREFIX%-%PKGNAME%"
origin = "base"
version = "%VERSION%"
comment = "%COMMENT%"
categories = [ base ]
-maintainer = "re@FreeBSD.org"
-www = "https://www.FreeBSD.org"
+maintainer = "%PKG_MAINTAINER%"
+www = "%PKG_WWW%"
prefix = "/"
licenselogic = "single"
licenses = [ BSD2CLAUSE ]
diff --git a/release/packages/unbound.ucl b/release/packages/unbound.ucl
index 1ba9560abf12b..d250e76752f94 100644
--- a/release/packages/unbound.ucl
+++ b/release/packages/unbound.ucl
@@ -2,13 +2,13 @@
# $FreeBSD$
#
-name = "FreeBSD-%PKGNAME%"
+name = "%PKG_NAME_PREFIX%-%PKGNAME%"
origin = "base"
version = "%VERSION%"
comment = "%COMMENT%"
categories = [ base ]
-maintainer = "re@FreeBSD.org"
-www = "https://www.FreeBSD.org"
+maintainer = "%PKG_MAINTAINER%"
+www = "%PKG_WWW%"
prefix = "/"
licenselogic = "single"
licenses = [ BSD4CLAUSE ]
diff --git a/release/packages/utilities.ucl b/release/packages/utilities.ucl
index 936b46e4cb4c5..ab5725d1c1d86 100644
--- a/release/packages/utilities.ucl
+++ b/release/packages/utilities.ucl
@@ -2,13 +2,13 @@
# $FreeBSD$
#
-name = "FreeBSD-%PKGNAME%"
+name = "%PKG_NAME_PREFIX%-%PKGNAME%"
origin = "base"
version = "%VERSION%"
comment = "%COMMENT% %VCS_REVISION%"
categories = [ base ]
-maintainer = "re@FreeBSD.org"
-www = "https://www.FreeBSD.org"
+maintainer = "%PKG_MAINTAINER%"
+www = "%PKG_WWW%"
prefix = "/"
vital = true
licenselogic = "single"
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index 0aa73b095a57c..65847ad5954bb 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -748,6 +748,7 @@ group_member(const char *ifname, const char *match, const char *nomatch)
if (nomatch)
nomatched &= fnmatch(nomatch, ifg->ifgrq_group, 0);
}
+ free(ifgr.ifgr_groups);
if (match && !nomatch)
return (matched);
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index ea35a27678450..58bc3662fcc7c 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -1,7 +1,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 21, 2019
+.Dd August 10, 2020
.Dt IPFW 8
.Os
.Sh NAME
@@ -600,7 +600,7 @@ See Section
By name or address
.It Misc. IP header fields
Version, type of service, datagram length, identification,
-fragment flag (non-zero IP offset),
+fragmentation flags,
Time To Live
.It IP options
.It IPv6 Extension headers
@@ -1602,12 +1602,29 @@ Matches IPv6 packets containing any of the flow labels given in
.Ar labels .
.Ar labels
is a comma separated list of numeric flow labels.
-.It Cm frag
-Matches packets that are fragments and not the first
-fragment of an IP datagram.
-Note that these packets will not have
-the next protocol header (e.g.\& TCP, UDP) so options that look into
-these headers cannot match.
+.It Cm frag Ar spec
+Matches IPv4 packets whose
+.Cm ip_off
+field contains the comma separated list of IPv4 fragmentation
+options specified in
+.Ar spec .
+The recognized options are:
+.Cm df
+.Pq Dv don't fragment ,
+.Cm mf
+.Pq Dv more fragments ,
+.Cm rf
+.Pq Dv reserved fragment bit
+.Cm offset
+.Pq Dv non-zero fragment offset .
+The absence of a particular options may be denoted
+with a
+.Ql \&! .
+.Pp
+Empty list of options defaults to matching on non-zero fragment offset.
+Such rule would match all not the first fragment datagrams,
+both IPv4 and IPv6.
+This is a backward compatibility with older rulesets.
.It Cm gid Ar group
Matches all TCP or UDP packets sent by or received for a
.Ar group .
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index d4c81d5e4d664..830b35d2f7236 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -168,6 +168,14 @@ static struct _s_x f_iptos[] = {
{ NULL, 0 }
};
+static struct _s_x f_ipoff[] = {
+ { "rf", IP_RF >> 8 },
+ { "df", IP_DF >> 8 },
+ { "mf", IP_MF >> 8 },
+ { "offset", 0x1 },
+ { NULL, 0}
+};
+
struct _s_x f_ipdscp[] = {
{ "af11", IPTOS_DSCP_AF11 >> 2 }, /* 001010 */
{ "af12", IPTOS_DSCP_AF12 >> 2 }, /* 001100 */
@@ -1531,7 +1539,7 @@ print_instruction(struct buf_pr *bp, const struct format_opts *fo,
IPPROTO_ETHERTYPE, cmd->opcode);
break;
case O_FRAG:
- bprintf(bp, " frag");
+ print_flags(bp, "frag", cmd, f_ipoff);
break;
case O_FIB:
bprintf(bp, " fib %u", cmd->arg1);
@@ -4553,7 +4561,15 @@ read_options:
break;
case TOK_FRAG:
- fill_cmd(cmd, O_FRAG, 0, 0);
+ fill_flags_cmd(cmd, O_FRAG, f_ipoff, *av);
+ /*
+ * Compatibility: no argument after "frag"
+ * keyword equals to "frag offset".
+ */
+ if (cmd->arg1 == 0)
+ cmd->arg1 = 0x1;
+ else
+ av++;
break;
case TOK_LAYER2:
diff --git a/secure/lib/libssl/Makefile b/secure/lib/libssl/Makefile
index d97775b9afe4b..e201cfa36e315 100644
--- a/secure/lib/libssl/Makefile
+++ b/secure/lib/libssl/Makefile
@@ -31,7 +31,7 @@ CFLAGS+= -I${.OBJDIR:H}/libcrypto
.include <bsd.lib.mk>
-PICFLAG+= -DOPENSS_PIC
+PICFLAG+= -DOPENSSL_PIC
.PATH: ${LCRYPTO_SRC}/ssl \
${LCRYPTO_SRC}/ssl/record \
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 9049f3feb5e33..95ed799361f23 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -113,6 +113,7 @@ MAN= aac.4 \
cloudabi.4 \
cmx.4 \
${_coretemp.4} \
+ cp2112.4 \
${_cpuctl.4} \
cpufreq.4 \
crypto.4 \
@@ -171,6 +172,7 @@ MAN= aac.4 \
gif.4 \
gpio.4 \
gpioiic.4 \
+ gpiokeys.4 \
gpioled.4 \
gpioths.4 \
gre.4 \
diff --git a/share/man/man4/cp2112.4 b/share/man/man4/cp2112.4
new file mode 100644
index 0000000000000..39ac8dba114e2
--- /dev/null
+++ b/share/man/man4/cp2112.4
@@ -0,0 +1,87 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+.\"
+.\" Copyright (c) 2020 Andriy Gapon <avg@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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 12, 2020
+.Dt CP2112 4
+.Os
+.Sh NAME
+.Nm cp2112
+.Nd driver for a USB GPIO and I2C peripheral device
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following lines in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device cp2112"
+.Cd "device usb"
+.Cd "device gpio"
+.Cd "device iicbus"
+.Ed
+.Pp
+Alternatively, to load the driver as a
+module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+cp2112_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for Silicon Labs CP2112 device.
+The device has 8 general purpose I/O pins and an I2C controller that supports
+a subset of the I2C protocol.
+.Pp
+All pins support both input and output modes.
+An output pin can be configured either for open-drain or push-pull operation.
+Pins 0, 1 and 7 support special functions: I2C transmit indication,
+I2C receive indication and clock output respectively.
+At the moment the
+.Nm
+driver does not provide a way to enable and configure the special functions.
+.Pp
+The I2C controller supports read transactions with up to 512 bytes of data,
+write transactions with up to 61 bytes of data and a write followed by
+the repeated start followed by a read transactions where the write can be
+up to 16 bytes and the read can be up to 512 bytes.
+Zero length transfers are not supported.
+The
+.Nm
+driver creates a
+.Xr gpio 4
+and
+.Xr iicbus 4
+child buses to expose the respective functions.
+.Sh SEE ALSO
+.Xr gpio 4 ,
+.Xr iicbus 4 ,
+.Xr usb 4
+.Sh HISTORY
+The
+.Nm
+driver and this manual page was written by
+.An Andriy Gapon Aq Mt avg@FreeBSD.org .
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 33e162d5fae0b..993f65188543e 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -272,6 +272,7 @@ MAN= accept_filter.9 \
printf.9 \
prison_check.9 \
priv.9 \
+ prng.9 \
proc_rwmem.9 \
pseudofs.9 \
psignal.9 \
@@ -1745,6 +1746,10 @@ MLINKS+=printf.9 log.9 \
printf.9 uprintf.9
MLINKS+=priv.9 priv_check.9 \
priv.9 priv_check_cred.9
+MLINKS+=prng.9 prng32.9 \
+ prng.9 prng32_bounded.9 \
+ prng.9 prng64.9 \
+ prng.9 prng64_bounded.9
MLINKS+=proc_rwmem.9 proc_readmem.9 \
proc_rwmem.9 proc_writemem.9
MLINKS+=psignal.9 gsignal.9 \
diff --git a/share/man/man9/prng.9 b/share/man/man9/prng.9
new file mode 100644
index 0000000000000..63132c28c1986
--- /dev/null
+++ b/share/man/man9/prng.9
@@ -0,0 +1,99 @@
+.\"-
+.\" Copyright 2020 Conrad Meyer <cem@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, 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$
+.\"
+.Dd August 5, 2020
+.Dt PRNG 9
+.Os
+.Sh NAME
+.Nm prng
+.Nd "Kernel pseudo-random number generators"
+.Sh SYNOPSIS
+.In sys/prng.h
+.Ft uint32_t
+.Fn prng32 void
+.Ft uint32_t
+.Fn prng32_bounded "uint32_t bound"
+.Ft uint64_t
+.Fn prng64 void
+.Ft uint64_t
+.Fn prng64_bounded "uint64_t bound"
+.Sh DESCRIPTION
+.Ss GENERIC PRNG ROUTINES
+.Nm
+is a family of fast,
+.Em non-cryptographic
+pseudo-random number generators.
+Unlike
+.Xr random 9 ,
+.Fn prng32 ,
+.Fn prng32_bounded ,
+.Fn prng64 ,
+and
+.Fn prng64_bounded
+avoid shared global state, removing unnecessary contention on SMP
+systems.
+The routines are not explicitly tied to any specific implementation, and
+may produce different specific sequences on different hosts, reboots, or
+versions of
+.Fx .
+Different CPUs in SMP systems are guaranteed to produce different sequences of
+integers.
+.Pp
+For
+.Em cryptographically secure
+random numbers generated by the
+.Xr random 4
+kernel cryptographically secure random number generator subsystem, see
+.Xr arc4random 9 .
+.Pp
+.Bl -tag -width indent
+.It Fn prng32
+Generate a 32-bit integer uniformly distributed in [0, 2^32-1].
+.It Fn prng32_bounded bound
+Generate an integer uniformly in the range [0, bound-1].
+.It Fn prng64
+Generate a 64-bit integer uniformly distributed in [0, 2^64-1].
+.It Fn prng64_bounded bound
+Generate an integer uniformly in the range [0, bound-1].
+.El
+.Pp
+These routines are not reentrant; they are not safe to use in interrupt
+handlers ("interrupt filters" in
+.Xr bus_setup_intr 9
+terminology).
+They are safe to use in all other kernel contexts, including interrupt threads
+("ithreads").
+.Ss REPRODUCIBLE PRNG APIS
+In addition to these per-CPU helpers, the
+.In sys/prng.h
+header also exposes the entire API of the PCG family of PRNGs as inline
+functions.
+The PCG-C API is described in full at
+.Lk https://www.pcg-random.org/using-pcg-c.html .
+.Sh HISTORY
+.Nm
+was introduced in
+.Fx 13 .
diff --git a/share/mk/bsd.linker.mk b/share/mk/bsd.linker.mk
index 1a23393909905..ae867502c6f26 100644
--- a/share/mk/bsd.linker.mk
+++ b/share/mk/bsd.linker.mk
@@ -58,7 +58,7 @@ ${var}= ${${var}__${${X_}_ld_hash}}
.if ${ld} == "LD" || (${ld} == "XLD" && ${XLD} != ${LD})
.if !defined(${X_}LINKER_TYPE) || !defined(${X_}LINKER_VERSION)
-_ld_version!= (${${ld}} --version || echo none) | sed -n 1p
+_ld_version!= (${${ld}} -v 2>&1 || echo none) | sed -n 1p
.if ${_ld_version} == "none"
.warning Unable to determine linker type from ${ld}=${${ld}}
.endif
@@ -74,6 +74,17 @@ ${X_}LINKER_FREEBSD_VERSION:= ${_ld_version:[4]:C/.*-([^-]*)\)/\1/}
.else
${X_}LINKER_FREEBSD_VERSION= 0
.endif
+.elif ${_ld_version:[1]} == "@(\#)PROGRAM:ld"
+# bootstrap linker on MacOS
+${X_}LINKER_TYPE= mac
+_v= ${_ld_version:[2]:S/PROJECT:ld64-//}
+# Convert version 409.12 to 409.12.0 so that the echo + awk below works
+.if empty(_v:M[1-9]*.[0-9]*.[0-9]*) && !empty(_v:M[1-9]*.[0-9]*)
+_v:=${_v}.0
+.else
+# Some versions do not contain a minor version so we need to append .0.0 there
+_v:=${_v}.0.0
+.endif
.else
.warning Unknown linker from ${ld}=${${ld}}: ${_ld_version}, defaulting to bfd
${X_}LINKER_TYPE= bfd
@@ -94,6 +105,9 @@ ${X_}LINKER_FEATURES+= riscv-relaxations
.if ${${X_}LINKER_TYPE} == "lld" && ${${X_}LINKER_VERSION} >= 60000
${X_}LINKER_FEATURES+= retpoline
.endif
+.if ${${X_}LINKER_TYPE} == "lld" && ${${X_}LINKER_VERSION} >= 90000
+${X_}LINKER_FEATURES+= ifunc-noplt
+.endif
.endif
.else
# Use LD's values
diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk
index e596f216c2582..234b13205c67b 100644
--- a/share/mk/src.opts.mk
+++ b/share/mk/src.opts.mk
@@ -365,6 +365,14 @@ __DEFAULT_YES_OPTIONS+=OPENMP
__DEFAULT_NO_OPTIONS+=OPENMP
.endif
+.if ${.MAKE.OS} != "FreeBSD"
+# Building the target compiler requires building tablegen on the host
+# which is (currently) not possible on non-FreeBSD.
+BROKEN_OPTIONS+=CLANG LLD LLDB
+# The same also applies to the bootstrap LLVM.
+BROKEN_OPTIONS+=CLANG_BOOTSTRAP LLD_BOOTSTRAP
+.endif
+
.include <bsd.mkopt.mk>
#
diff --git a/share/mk/sys.mk b/share/mk/sys.mk
index 2248d64f65807..215b04563e233 100644
--- a/share/mk/sys.mk
+++ b/share/mk/sys.mk
@@ -275,6 +275,7 @@ SHELL ?= sh
.if !defined(%POSIX)
SIZE ?= size
+STRIPBIN ?= strip
.endif
YACC ?= yacc
diff --git a/stand/common/newvers.sh b/stand/common/newvers.sh
index 75efeceab26b8..714adba6c9cbb 100755
--- a/stand/common/newvers.sh
+++ b/stand/common/newvers.sh
@@ -55,6 +55,8 @@ if [ -n "${include_metadata}" ]; then
bootprog_info="$bootprog_info(${t} ${u}@${h})\\n"
fi
-echo "char bootprog_info[] = \"$bootprog_info\";" > $tempfile
-echo "unsigned bootprog_rev = ${r%%.*}${r##*.};" >> $tempfile
+cat > $tempfile <<EOF
+char bootprog_info[] = "$bootprog_info";
+unsigned bootprog_rev = ${r%%.*}${r##*.};
+EOF
mv $tempfile vers.c
diff --git a/stand/i386/loader/Makefile b/stand/i386/loader/Makefile
index b74ef9007d97c..3c0357b7b7a76 100644
--- a/stand/i386/loader/Makefile
+++ b/stand/i386/loader/Makefile
@@ -64,7 +64,7 @@ ${LOADER}: ${LOADER}.bin ${BTXLDR} ${BTXKERN}
-b ${BTXKERN} ${LOADER}.bin
${LOADER}.bin: ${LOADER}.sym
- strip -R .comment -R .note -o ${.TARGET} ${.ALLSRC}
+ ${STRIPBIN} -R .comment -R .note -o ${.TARGET} ${.ALLSRC}
.if ${MK_LOADER_ZFS} == "yes" && ${LOADER_INTERP} == ${LOADER_DEFAULT_INTERP}
LINKS+= ${BINDIR}/${LOADER} ${BINDIR}/zfsloader
diff --git a/sys/arm/allwinner/aw_cir.c b/sys/arm/allwinner/aw_cir.c
index 1531e2fe9d479..eabab4cba8f2b 100644
--- a/sys/arm/allwinner/aw_cir.c
+++ b/sys/arm/allwinner/aw_cir.c
@@ -126,16 +126,21 @@ __FBSDID("$FreeBSD$");
#define AW_IR_DMAX 53
/* Active Thresholds */
-#define AW_IR_ACTIVE_T ((0 & 0xff) << 16)
-#define AW_IR_ACTIVE_T_C ((1 & 0xff) << 23)
+#define AW_IR_ACTIVE_T_VAL AW_IR_L1_MIN
+#define AW_IR_ACTIVE_T (((AW_IR_ACTIVE_T_VAL - 1) & 0xff) << 16)
+#define AW_IR_ACTIVE_T_C_VAL 0
+#define AW_IR_ACTIVE_T_C ((AW_IR_ACTIVE_T_C_VAL & 0xff) << 23)
/* Code masks */
#define CODE_MASK 0x00ff00ff
#define INV_CODE_MASK 0xff00ff00
#define VALID_CODE_MASK 0x00ff0000
-#define A10_IR 1
-#define A13_IR 2
+enum {
+ A10_IR = 1,
+ A13_IR,
+ A31_IR,
+};
#define AW_IR_RAW_BUF_SIZE 128
@@ -158,6 +163,7 @@ static struct resource_spec aw_ir_spec[] = {
static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun4i-a10-ir", A10_IR },
{ "allwinner,sun5i-a13-ir", A13_IR },
+ { "allwinner,sun6i-a31-ir", A31_IR },
{ NULL, 0 }
};
@@ -196,24 +202,24 @@ aw_ir_read_data(struct aw_ir_softc *sc)
static unsigned long
aw_ir_decode_packets(struct aw_ir_softc *sc)
{
- unsigned long len, code;
- unsigned char val, last;
+ unsigned int len, code;
unsigned int active_delay;
+ unsigned char val, last;
int i, bitcount;
if (bootverbose)
device_printf(sc->dev, "sc->dcnt = %d\n", sc->dcnt);
/* Find Lead 1 (bit separator) */
- active_delay = (AW_IR_ACTIVE_T + 1) * (AW_IR_ACTIVE_T_C != 0 ? 128 : 1);
- len = 0;
- len += (active_delay >> 1);
+ active_delay = AW_IR_ACTIVE_T_VAL *
+ (AW_IR_ACTIVE_T_C_VAL != 0 ? 128 : 1);
+ len = active_delay;
if (bootverbose)
- device_printf(sc->dev, "Initial len: %ld\n", len);
+ device_printf(sc->dev, "Initial len: %d\n", len);
for (i = 0; i < sc->dcnt; i++) {
val = sc->buf[i];
if (val & VAL_MASK)
- len += val & PERIOD_MASK;
+ len += (val & PERIOD_MASK) + 1;
else {
if (len > AW_IR_L1_MIN)
break;
@@ -221,7 +227,7 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
}
}
if (bootverbose)
- device_printf(sc->dev, "len = %ld\n", len);
+ device_printf(sc->dev, "len = %d\n", len);
if ((val & VAL_MASK) || (len <= AW_IR_L1_MIN)) {
if (bootverbose)
device_printf(sc->dev, "Bit separator error\n");
@@ -237,7 +243,7 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
break;
len = 0;
} else
- len += val & PERIOD_MASK;
+ len += (val & PERIOD_MASK) + 1;
}
if ((!(val & VAL_MASK)) || (len <= AW_IR_L0_MIN)) {
if (bootverbose)
@@ -254,23 +260,25 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
val = sc->buf[i];
if (last) {
if (val & VAL_MASK)
- len += val & PERIOD_MASK;
+ len += (val & PERIOD_MASK) + 1;
else {
if (len > AW_IR_PMAX) {
if (bootverbose)
device_printf(sc->dev,
- "Pulse error\n");
+ "Pulse error, len=%d\n",
+ len);
goto error_code;
}
last = 0;
- len = val & PERIOD_MASK;
+ len = (val & PERIOD_MASK) + 1;
}
} else {
if (val & VAL_MASK) {
if (len > AW_IR_DMAX) {
if (bootverbose)
device_printf(sc->dev,
- "Distant error\n");
+ "Distance error, len=%d\n",
+ len);
goto error_code;
} else {
if (len > AW_IR_DMID) {
@@ -282,9 +290,9 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
break; /* Finish decoding */
}
last = 1;
- len = val & PERIOD_MASK;
+ len = (val & PERIOD_MASK) + 1;
} else
- len += val & PERIOD_MASK;
+ len += (val & PERIOD_MASK) + 1;
}
}
return (code);
@@ -364,7 +372,7 @@ aw_ir_intr(void *arg)
device_printf(sc->dev, "IR code status: %d\n",
stat);
}
- sc->dcnt = 0;
+ aw_ir_buf_reset(sc);
}
if (val & AW_IR_RXINT_ROI_EN) {
/* RX FIFO overflow */
@@ -414,6 +422,7 @@ aw_ir_attach(device_t dev)
sc->fifo_size = 16;
break;
case A13_IR:
+ case A31_IR:
sc->fifo_size = 64;
break;
}
@@ -464,7 +473,8 @@ aw_ir_attach(device_t dev)
&sc->intrhand)) {
bus_release_resources(dev, aw_ir_spec, sc->res);
device_printf(dev, "cannot setup interrupt handler\n");
- return (ENXIO);
+ err = ENXIO;
+ goto error;
}
/* Enable CIR Mode */
diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h
index c5091e93efe2a..9cac6fce439b9 100644
--- a/sys/arm64/include/armreg.h
+++ b/sys/arm64/include/armreg.h
@@ -857,11 +857,20 @@
#define PMCR_LC (1 << 6) /* Long cycle count enable */
#define PMCR_IMP_SHIFT 24 /* Implementer code */
#define PMCR_IMP_MASK (0xff << PMCR_IMP_SHIFT)
+#define PMCR_IMP_ARM 0x41
#define PMCR_IDCODE_SHIFT 16 /* Identification code */
#define PMCR_IDCODE_MASK (0xff << PMCR_IDCODE_SHIFT)
-#define PMCR_IDCODE_CORTEX_A57 0x01
-#define PMCR_IDCODE_CORTEX_A72 0x02
-#define PMCR_IDCODE_CORTEX_A53 0x03
+#define PMCR_IDCODE_CORTEX_A57 0x01
+#define PMCR_IDCODE_CORTEX_A72 0x02
+#define PMCR_IDCODE_CORTEX_A53 0x03
+#define PMCR_IDCODE_CORTEX_A73 0x04
+#define PMCR_IDCODE_CORTEX_A35 0x0a
+#define PMCR_IDCODE_CORTEX_A76 0x0b
+#define PMCR_IDCODE_NEOVERSE_N1 0x0c
+#define PMCR_IDCODE_CORTEX_A77 0x10
+#define PMCR_IDCODE_CORTEX_A55 0x45
+#define PMCR_IDCODE_NEOVERSE_E1 0x46
+#define PMCR_IDCODE_CORTEX_A75 0x4a
#define PMCR_N_SHIFT 11 /* Number of counters implemented */
#define PMCR_N_MASK (0x1f << PMCR_N_SHIFT)
diff --git a/sys/arm64/rockchip/if_dwc_rk.c b/sys/arm64/rockchip/if_dwc_rk.c
index 7ce13d01d3eb4..eafd9e00caf09 100644
--- a/sys/arm64/rockchip/if_dwc_rk.c
+++ b/sys/arm64/rockchip/if_dwc_rk.c
@@ -23,7 +23,7 @@
* 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.
- */
+*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -33,94 +33,347 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/socket.h>
#include <machine/bus.h>
+#include <net/if.h>
+#include <net/if_media.h>
+
#include <dev/dwc/if_dwc.h>
#include <dev/dwc/if_dwcvar.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/extres/clk/clk.h>
+#include <dev/extres/hwreset/hwreset.h>
#include <dev/extres/regulator/regulator.h>
-
#include <dev/extres/syscon/syscon.h>
-#include "syscon_if.h"
-
#include "if_dwc_if.h"
+#include "syscon_if.h"
#define RK3328_GRF_MAC_CON0 0x0900
-#define RK3328_GRF_MAC_CON0_TX_MASK 0x7F
-#define RK3328_GRF_MAC_CON0_TX_SHIFT 0
-#define RK3328_GRF_MAC_CON0_RX_MASK 0x7F
-#define RK3328_GRF_MAC_CON0_RX_SHIFT 7
+#define MAC_CON0_GMAC2IO_TX_DL_CFG_MASK 0x7F
+#define MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT 0
+#define MAC_CON0_GMAC2IO_RX_DL_CFG_MASK 0x7F
+#define MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT 7
#define RK3328_GRF_MAC_CON1 0x0904
-#define RK3328_GRF_MAC_CON1_RX_ENA (1 << 1)
-#define RK3328_GRF_MAC_CON1_TX_ENA (1 << 0)
+#define MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA (1 << 0)
+#define MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA (1 << 1)
+#define MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK (3 << 11)
+#define MAC_CON1_GMAC2IO_GMII_CLK_SEL_125 (0 << 11)
+#define MAC_CON1_GMAC2IO_GMII_CLK_SEL_25 (3 << 11)
+#define MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5 (2 << 11)
+#define MAC_CON1_GMAC2IO_RMII_MODE_MASK (1 << 9)
+#define MAC_CON1_GMAC2IO_RMII_MODE (1 << 9)
+#define MAC_CON1_GMAC2IO_INTF_SEL_MASK (7 << 4)
+#define MAC_CON1_GMAC2IO_INTF_RMII (4 << 4)
+#define MAC_CON1_GMAC2IO_INTF_RGMII (1 << 4)
+#define MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK (1 << 7)
+#define MAC_CON1_GMAC2IO_RMII_CLK_SEL_25 (1 << 7)
+#define MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5 (0 << 7)
+#define MAC_CON1_GMAC2IO_MAC_SPEED_MASK (1 << 2)
+#define MAC_CON1_GMAC2IO_MAC_SPEED_100 (1 << 2)
+#define MAC_CON1_GMAC2IO_MAC_SPEED_10 (0 << 2)
#define RK3328_GRF_MAC_CON2 0x0908
#define RK3328_GRF_MACPHY_CON0 0x0B00
+#define MACPHY_CON0_CLK_50M_MASK (1 << 14)
+#define MACPHY_CON0_CLK_50M (1 << 14)
+#define MACPHY_CON0_RMII_MODE_MASK (3 << 6)
+#define MACPHY_CON0_RMII_MODE (1 << 6)
#define RK3328_GRF_MACPHY_CON1 0x0B04
+#define MACPHY_CON1_RMII_MODE_MASK (1 << 9)
+#define MACPHY_CON1_RMII_MODE (1 << 9)
#define RK3328_GRF_MACPHY_CON2 0x0B08
#define RK3328_GRF_MACPHY_CON3 0x0B0C
#define RK3328_GRF_MACPHY_STATUS 0x0B10
+#define RK3399_GRF_SOC_CON5 0xc214
+#define SOC_CON5_GMAC_CLK_SEL_MASK (3 << 4)
+#define SOC_CON5_GMAC_CLK_SEL_125 (0 << 4)
+#define SOC_CON5_GMAC_CLK_SEL_25 (3 << 4)
+#define SOC_CON5_GMAC_CLK_SEL_2_5 (2 << 4)
+#define RK3399_GRF_SOC_CON6 0xc218
+#define SOC_CON6_GMAC_TXCLK_DLY_ENA (1 << 7)
+#define SOC_CON6_TX_DL_CFG_MASK 0x7F
+#define SOC_CON6_TX_DL_CFG_SHIFT 0
+#define SOC_CON6_RX_DL_CFG_MASK 0x7F
+#define SOC_CON6_GMAC_RXCLK_DLY_ENA (1 << 15)
+#define SOC_CON6_RX_DL_CFG_SHIFT 8
+
+struct if_dwc_rk_softc;
+
+typedef void (*if_dwc_rk_set_delaysfn_t)(struct if_dwc_rk_softc *);
+typedef int (*if_dwc_rk_set_speedfn_t)(struct if_dwc_rk_softc *, int);
+typedef void (*if_dwc_rk_set_phy_modefn_t)(struct if_dwc_rk_softc *);
+typedef void (*if_dwc_rk_phy_powerupfn_t)(struct if_dwc_rk_softc *);
+
+struct if_dwc_rk_ops {
+ if_dwc_rk_set_delaysfn_t set_delays;
+ if_dwc_rk_set_speedfn_t set_speed;
+ if_dwc_rk_set_phy_modefn_t set_phy_mode;
+ if_dwc_rk_phy_powerupfn_t phy_powerup;
+};
+
+struct if_dwc_rk_softc {
+ struct dwc_softc base;
+ uint32_t tx_delay;
+ uint32_t rx_delay;
+ bool integrated_phy;
+ bool clock_in;
+ phandle_t phy_node;
+ struct syscon *grf;
+ struct if_dwc_rk_ops *ops;
+ /* Common clocks */
+ clk_t mac_clk_rx;
+ clk_t mac_clk_tx;
+ clk_t aclk_mac;
+ clk_t pclk_mac;
+ clk_t clk_stmmaceth;
+ /* RMII clocks */
+ clk_t clk_mac_ref;
+ clk_t clk_mac_refout;
+ /* PHY clock */
+ clk_t clk_phy;
+};
+
+static void rk3328_set_delays(struct if_dwc_rk_softc *sc);
+static int rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed);
+static void rk3328_set_phy_mode(struct if_dwc_rk_softc *sc);
+static void rk3328_phy_powerup(struct if_dwc_rk_softc *sc);
+
+static void rk3399_set_delays(struct if_dwc_rk_softc *sc);
+static int rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed);
+
+static struct if_dwc_rk_ops rk3288_ops = {
+};
+
+static struct if_dwc_rk_ops rk3328_ops = {
+ .set_delays = rk3328_set_delays,
+ .set_speed = rk3328_set_speed,
+ .set_phy_mode = rk3328_set_phy_mode,
+ .phy_powerup = rk3328_phy_powerup,
+};
+
+static struct if_dwc_rk_ops rk3399_ops = {
+ .set_delays = rk3399_set_delays,
+ .set_speed = rk3399_set_speed,
+};
+
static struct ofw_compat_data compat_data[] = {
- {"rockchip,rk3288-gmac", 1},
- {"rockchip,rk3328-gmac", 1},
- {"rockchip,rk3399-gmac", 1},
+ {"rockchip,rk3288-gmac", (uintptr_t)&rk3288_ops},
+ {"rockchip,rk3328-gmac", (uintptr_t)&rk3328_ops},
+ {"rockchip,rk3399-gmac", (uintptr_t)&rk3399_ops},
{NULL, 0}
};
static void
-rk3328_set_delays(struct syscon *grf, phandle_t node)
+rk3328_set_delays(struct if_dwc_rk_softc *sc)
{
+ uint32_t reg;
uint32_t tx, rx;
- if (OF_getencprop(node, "tx_delay", &tx, sizeof(tx)) <= 0)
- tx = 0x30;
- if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0)
- rx = 0x10;
+ if (sc->base.phy_mode != PHY_MODE_RGMII)
+ return;
+
+ reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON0);
+ tx = ((reg >> MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK);
+ rx = ((reg >> MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_RX_DL_CFG_MASK);
+
+ reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON1);
+ if (bootverbose) {
+ device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n",
+ tx, ((reg & MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"),
+ rx, ((reg & MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled"));
- if (bootverbose)
- printf("setting RK3328 RX/TX delays: %d/%d\n", rx, tx);
- tx = ((tx & RK3328_GRF_MAC_CON0_TX_MASK) <<
- RK3328_GRF_MAC_CON0_TX_SHIFT);
- rx = ((rx & RK3328_GRF_MAC_CON0_TX_MASK) <<
- RK3328_GRF_MAC_CON0_RX_SHIFT);
+ device_printf(sc->base.dev, "setting new RK3328 RX/TX delays: %d/%d\n",
+ sc->tx_delay, sc->rx_delay);
+ }
+
+ reg = (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) << 16;
+ reg |= (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA);
+ SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1, reg);
- SYSCON_WRITE_4(grf, RK3328_GRF_MAC_CON0, tx | rx | 0xFFFF0000);
- SYSCON_WRITE_4(grf, RK3328_GRF_MAC_CON1, RK3328_GRF_MAC_CON1_TX_ENA | RK3328_GRF_MAC_CON1_RX_ENA |
- ((RK3328_GRF_MAC_CON1_TX_ENA | RK3328_GRF_MAC_CON1_RX_ENA) << 16));
+ reg = 0xffff << 16;
+ reg |= ((sc->tx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) <<
+ MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT);
+ reg |= ((sc->rx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) <<
+ MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT);
+ SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON0, reg);
}
-#define RK3399_GRF_SOC_CON6 0xc218
-#define RK3399_GRF_SOC_CON6_TX_ENA (1 << 7)
-#define RK3399_GRF_SOC_CON6_TX_MASK 0x7F
-#define RK3399_GRF_SOC_CON6_TX_SHIFT 0
-#define RK3399_GRF_SOC_CON6_RX_MASK 0x7F
-#define RK3399_GRF_SOC_CON6_RX_ENA (1 << 15)
-#define RK3399_GRF_SOC_CON6_RX_SHIFT 8
+static int
+rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed)
+{
+ uint32_t reg;
+
+ switch (sc->base.phy_mode) {
+ case PHY_MODE_RGMII:
+ switch (speed) {
+ case IFM_1000_T:
+ case IFM_1000_SX:
+ reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_125;
+ break;
+ case IFM_100_TX:
+ reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_25;
+ break;
+ case IFM_10_T:
+ reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5;
+ break;
+ default:
+ device_printf(sc->base.dev, "unsupported RGMII media %u\n", speed);
+ return (-1);
+ }
+
+ SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1,
+ ((MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK << 16) | reg));
+ break;
+ case PHY_MODE_RMII:
+ switch (speed) {
+ case IFM_100_TX:
+ reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_25 |
+ MAC_CON1_GMAC2IO_MAC_SPEED_100;
+ break;
+ case IFM_10_T:
+ reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5 |
+ MAC_CON1_GMAC2IO_MAC_SPEED_10;
+ break;
+ default:
+ device_printf(sc->base.dev, "unsupported RMII media %u\n", speed);
+ return (-1);
+ }
+
+ SYSCON_WRITE_4(sc->grf,
+ sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1,
+ reg |
+ ((MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK | MAC_CON1_GMAC2IO_MAC_SPEED_MASK) << 16));
+ break;
+ }
+
+ return (0);
+}
static void
-rk3399_set_delays(struct syscon *grf, phandle_t node)
+rk3328_set_phy_mode(struct if_dwc_rk_softc *sc)
{
- uint32_t tx, rx;
- if (OF_getencprop(node, "tx_delay", &tx, sizeof(tx)) <= 0)
- tx = 0x30;
- if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0)
- rx = 0x10;
+ switch (sc->base.phy_mode) {
+ case PHY_MODE_RGMII:
+ SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1,
+ ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) |
+ MAC_CON1_GMAC2IO_INTF_RGMII);
+ break;
+ case PHY_MODE_RMII:
+ SYSCON_WRITE_4(sc->grf, sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1,
+ ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) |
+ MAC_CON1_GMAC2IO_INTF_RMII | MAC_CON1_GMAC2IO_RMII_MODE);
+ break;
+ }
+}
+
+static void
+rk3328_phy_powerup(struct if_dwc_rk_softc *sc)
+{
+ SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON1,
+ (MACPHY_CON1_RMII_MODE_MASK << 16) |
+ MACPHY_CON1_RMII_MODE);
+}
+
+static void
+rk3399_set_delays(struct if_dwc_rk_softc *sc)
+{
+ uint32_t reg, tx, rx;
+
+ if (sc->base.phy_mode != PHY_MODE_RGMII)
+ return;
- if (bootverbose)
- printf("setting RK3399 RX/TX delays: %d/%d\n", rx, tx);
- tx = ((tx & RK3399_GRF_SOC_CON6_TX_MASK) <<
- RK3399_GRF_SOC_CON6_TX_SHIFT) | RK3399_GRF_SOC_CON6_TX_ENA;
- rx = ((rx & RK3399_GRF_SOC_CON6_TX_MASK) <<
- RK3399_GRF_SOC_CON6_RX_SHIFT) | RK3399_GRF_SOC_CON6_RX_ENA;
+ reg = SYSCON_READ_4(sc->grf, RK3399_GRF_SOC_CON6);
+ tx = ((reg >> SOC_CON6_TX_DL_CFG_SHIFT) & SOC_CON6_TX_DL_CFG_MASK);
+ rx = ((reg >> SOC_CON6_RX_DL_CFG_SHIFT) & SOC_CON6_RX_DL_CFG_MASK);
- SYSCON_WRITE_4(grf, RK3399_GRF_SOC_CON6, tx | rx | 0xFFFF0000);
+ if (bootverbose) {
+ device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n",
+ tx, ((reg & SOC_CON6_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"),
+ rx, ((reg & SOC_CON6_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled"));
+
+ device_printf(sc->base.dev, "setting new RK3399 RX/TX delays: %d/%d\n",
+ sc->rx_delay, sc->tx_delay);
+ }
+
+ reg = 0xFFFF << 16;
+ reg |= ((sc->tx_delay & SOC_CON6_TX_DL_CFG_MASK) <<
+ SOC_CON6_TX_DL_CFG_SHIFT);
+ reg |= ((sc->rx_delay & SOC_CON6_RX_DL_CFG_MASK) <<
+ SOC_CON6_RX_DL_CFG_SHIFT);
+ reg |= SOC_CON6_GMAC_TXCLK_DLY_ENA | SOC_CON6_GMAC_RXCLK_DLY_ENA;
+
+ SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON6, reg);
+}
+
+static int
+rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed)
+{
+ uint32_t reg;
+
+ switch (speed) {
+ case IFM_1000_T:
+ case IFM_1000_SX:
+ reg = SOC_CON5_GMAC_CLK_SEL_125;
+ break;
+ case IFM_100_TX:
+ reg = SOC_CON5_GMAC_CLK_SEL_25;
+ break;
+ case IFM_10_T:
+ reg = SOC_CON5_GMAC_CLK_SEL_2_5;
+ break;
+ default:
+ device_printf(sc->base.dev, "unsupported media %u\n", speed);
+ return (-1);
+ }
+
+ SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON5,
+ ((SOC_CON5_GMAC_CLK_SEL_MASK << 16) | reg));
+ return (0);
+}
+
+static int
+if_dwc_rk_sysctl_delays(SYSCTL_HANDLER_ARGS)
+{
+ struct if_dwc_rk_softc *sc;
+ int rv;
+ uint32_t rxtx;
+
+ sc = arg1;
+ rxtx = ((sc->rx_delay << 8) | sc->tx_delay);
+
+ rv = sysctl_handle_int(oidp, &rxtx, 0, req);
+ if (rv != 0 || req->newptr == NULL)
+ return (rv);
+ sc->tx_delay = rxtx & 0xff;
+ sc->rx_delay = (rxtx >> 8) & 0xff;
+
+ if (sc->ops->set_delays)
+ sc->ops->set_delays(sc);
+
+ return (0);
+}
+
+static int
+if_dwc_rk_init_sysctl(struct if_dwc_rk_softc *sc)
+{
+ struct sysctl_oid *child;
+ struct sysctl_ctx_list *ctx_list;
+
+ ctx_list = device_get_sysctl_ctx(sc->base.dev);
+ child = device_get_sysctl_tree(sc->base.dev);
+ SYSCTL_ADD_PROC(ctx_list,
+ SYSCTL_CHILDREN(child), OID_AUTO, "delays",
+ CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, sc, 0,
+ if_dwc_rk_sysctl_delays, "", "RGMII RX/TX delays: ((rx << 8) | tx)");
+
+ return (0);
}
static int
@@ -137,25 +390,188 @@ if_dwc_rk_probe(device_t dev)
}
static int
+if_dwc_rk_init_clocks(device_t dev)
+{
+ struct if_dwc_rk_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+ error = clk_set_assigned(dev, ofw_bus_get_node(dev));
+ if (error != 0) {
+ device_printf(dev, "clk_set_assigned failed\n");
+ return (error);
+ }
+
+ /* Enable clocks */
+ error = clk_get_by_ofw_name(dev, 0, "stmmaceth", &sc->clk_stmmaceth);
+ if (error != 0) {
+ device_printf(dev, "could not find clock stmmaceth\n");
+ return (error);
+ }
+
+ if (clk_get_by_ofw_name(dev, 0, "mac_clk_rx", &sc->mac_clk_rx) != 0) {
+ device_printf(sc->base.dev, "could not get mac_clk_rx clock\n");
+ sc->mac_clk_rx = NULL;
+ }
+
+ if (clk_get_by_ofw_name(dev, 0, "mac_clk_tx", &sc->mac_clk_tx) != 0) {
+ device_printf(sc->base.dev, "could not get mac_clk_tx clock\n");
+ sc->mac_clk_tx = NULL;
+ }
+
+ if (clk_get_by_ofw_name(dev, 0, "aclk_mac", &sc->aclk_mac) != 0) {
+ device_printf(sc->base.dev, "could not get aclk_mac clock\n");
+ sc->aclk_mac = NULL;
+ }
+
+ if (clk_get_by_ofw_name(dev, 0, "pclk_mac", &sc->pclk_mac) != 0) {
+ device_printf(sc->base.dev, "could not get pclk_mac clock\n");
+ sc->pclk_mac = NULL;
+ }
+
+ if (sc->base.phy_mode == PHY_MODE_RGMII) {
+ if (clk_get_by_ofw_name(dev, 0, "clk_mac_ref", &sc->clk_mac_ref) != 0) {
+ device_printf(sc->base.dev, "could not get clk_mac_ref clock\n");
+ sc->clk_mac_ref = NULL;
+ }
+
+ if (!sc->clock_in) {
+ if (clk_get_by_ofw_name(dev, 0, "clk_mac_refout", &sc->clk_mac_refout) != 0) {
+ device_printf(sc->base.dev, "could not get clk_mac_refout clock\n");
+ sc->clk_mac_refout = NULL;
+ }
+
+ clk_set_freq(sc->clk_stmmaceth, 50000000, 0);
+ }
+ }
+
+ if ((sc->phy_node != 0) && sc->integrated_phy) {
+ if (clk_get_by_ofw_index(dev, sc->phy_node, 0, &sc->clk_phy) != 0) {
+ device_printf(sc->base.dev, "could not get PHY clock\n");
+ sc->clk_phy = NULL;
+ }
+
+ if (sc->clk_phy) {
+ clk_set_freq(sc->clk_phy, 50000000, 0);
+ }
+ }
+
+ if (sc->base.phy_mode == PHY_MODE_RMII) {
+ if (sc->mac_clk_rx)
+ clk_enable(sc->mac_clk_rx);
+ if (sc->clk_mac_ref)
+ clk_enable(sc->clk_mac_ref);
+ if (sc->clk_mac_refout)
+ clk_enable(sc->clk_mac_refout);
+ }
+ if (sc->clk_phy)
+ clk_enable(sc->clk_phy);
+ if (sc->aclk_mac)
+ clk_enable(sc->aclk_mac);
+ if (sc->pclk_mac)
+ clk_enable(sc->pclk_mac);
+ if (sc->mac_clk_tx)
+ clk_enable(sc->mac_clk_tx);
+
+ DELAY(50);
+
+ return (0);
+}
+
+static int
if_dwc_rk_init(device_t dev)
{
+ struct if_dwc_rk_softc *sc;
phandle_t node;
- struct syscon *grf = NULL;
-
+ uint32_t rx, tx;
+ int err;
+ pcell_t phy_handle;
+ char *clock_in_out;
+ hwreset_t phy_reset;
+ regulator_t phy_supply;
+
+ sc = device_get_softc(dev);
node = ofw_bus_get_node(dev);
+ sc->ops = (struct if_dwc_rk_ops *)ofw_bus_search_compatible(dev, compat_data)->ocd_data;
if (OF_hasprop(node, "rockchip,grf") &&
syscon_get_by_ofw_property(dev, node,
- "rockchip,grf", &grf) != 0) {
+ "rockchip,grf", &sc->grf) != 0) {
device_printf(dev, "cannot get grf driver handle\n");
return (ENXIO);
}
- if (ofw_bus_is_compatible(dev, "rockchip,rk3399-gmac"))
- rk3399_set_delays(grf, node);
- else if (ofw_bus_is_compatible(dev, "rockchip,rk3328-gmac"))
- rk3328_set_delays(grf, node);
+ if (OF_getencprop(node, "tx_delay", &tx, sizeof(tx)) <= 0)
+ tx = 0x30;
+ if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0)
+ rx = 0x10;
+ sc->tx_delay = tx;
+ sc->rx_delay = rx;
+
+ sc->clock_in = true;
+ if (OF_getprop_alloc(node, "clock_in_out", (void **)&clock_in_out)) {
+ if (strcmp(clock_in_out, "input") == 0)
+ sc->clock_in = true;
+ else
+ sc->clock_in = false;
+ OF_prop_free(clock_in_out);
+ }
+
+ if (OF_getencprop(node, "phy-handle", (void *)&phy_handle,
+ sizeof(phy_handle)) > 0)
+ sc->phy_node = OF_node_from_xref(phy_handle);
+
+ if (sc->phy_node)
+ sc->integrated_phy = OF_hasprop(sc->phy_node, "phy-is-integrated");
- /* Mode should be set according to dtb property */
+ if (sc->integrated_phy)
+ device_printf(sc->base.dev, "PHY is integrated\n");
+
+ if_dwc_rk_init_clocks(dev);
+
+ if (sc->ops->set_phy_mode)
+ sc->ops->set_phy_mode(sc);
+
+ if (sc->ops->set_delays)
+ sc->ops->set_delays(sc);
+
+ /*
+ * this also sets delays if tunable is defined
+ */
+ err = if_dwc_rk_init_sysctl(sc);
+ if (err != 0)
+ return (err);
+
+ if (regulator_get_by_ofw_property(sc->base.dev, 0,
+ "phy-supply", &phy_supply) == 0) {
+ if (regulator_enable(phy_supply)) {
+ device_printf(sc->base.dev,
+ "cannot enable 'phy' regulator\n");
+ }
+ }
+ else
+ device_printf(sc->base.dev, "no phy-supply property\n");
+
+ /* Power up */
+ if (sc->integrated_phy) {
+ if (sc->ops->phy_powerup)
+ sc->ops->phy_powerup(sc);
+
+ SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0,
+ (MACPHY_CON0_CLK_50M_MASK << 16) |
+ MACPHY_CON0_CLK_50M);
+ SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0,
+ (MACPHY_CON0_RMII_MODE_MASK << 16) |
+ MACPHY_CON0_RMII_MODE);
+ SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON2, 0xffff1234);
+ SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON3, 0x003f0035);
+
+ if (hwreset_get_by_ofw_idx(dev, sc->phy_node, 0, &phy_reset) == 0) {
+ hwreset_assert(phy_reset);
+ DELAY(20);
+ hwreset_deassert(phy_reset);
+ DELAY(20);
+ }
+ }
return (0);
}
@@ -175,12 +591,26 @@ if_dwc_rk_mii_clk(device_t dev)
return (GMAC_MII_CLK_150_250M_DIV102);
}
+static int
+if_dwc_rk_set_speed(device_t dev, int speed)
+{
+ struct if_dwc_rk_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ if (sc->ops->set_speed)
+ return sc->ops->set_speed(sc, speed);
+
+ return (0);
+}
+
static device_method_t if_dwc_rk_methods[] = {
DEVMETHOD(device_probe, if_dwc_rk_probe),
DEVMETHOD(if_dwc_init, if_dwc_rk_init),
DEVMETHOD(if_dwc_mac_type, if_dwc_rk_mac_type),
DEVMETHOD(if_dwc_mii_clk, if_dwc_rk_mii_clk),
+ DEVMETHOD(if_dwc_set_speed, if_dwc_rk_set_speed),
DEVMETHOD_END
};
@@ -190,6 +620,6 @@ static devclass_t dwc_rk_devclass;
extern driver_t dwc_driver;
DEFINE_CLASS_1(dwc, dwc_rk_driver, if_dwc_rk_methods,
- sizeof(struct dwc_softc), dwc_driver);
+ sizeof(struct if_dwc_rk_softc), dwc_driver);
DRIVER_MODULE(dwc_rk, simplebus, dwc_rk_driver, dwc_rk_devclass, 0, 0);
MODULE_DEPEND(dwc_rk, dwc, 1, 1, 1);
diff --git a/sys/cam/nvme/nvme_da.c b/sys/cam/nvme/nvme_da.c
index 367c943f0dced..892dee5a9959d 100644
--- a/sys/cam/nvme/nvme_da.c
+++ b/sys/cam/nvme/nvme_da.c
@@ -943,7 +943,11 @@ ndaregister(struct cam_periph *periph, void *arg)
disk->d_hba_subdevice = cpi.hba_subdevice;
snprintf(disk->d_attachment, sizeof(disk->d_attachment),
"%s%d", cpi.dev_name, cpi.unit_number);
- disk->d_stripesize = disk->d_sectorsize;
+ if (((nsd->nsfeat >> NVME_NS_DATA_NSFEAT_NPVALID_SHIFT) &
+ NVME_NS_DATA_NSFEAT_NPVALID_MASK) != 0 && nsd->npwg != 0)
+ disk->d_stripesize = ((nsd->npwg + 1) * disk->d_sectorsize);
+ else
+ disk->d_stripesize = nsd->noiob * disk->d_sectorsize;
disk->d_stripeoffset = 0;
disk->d_devstat = devstat_new_entry(periph->periph_name,
periph->unit_number, disk->d_sectorsize,
diff --git a/sys/cam/nvme/nvme_xpt.c b/sys/cam/nvme/nvme_xpt.c
index 687da220325a8..fbb9cf19d8394 100644
--- a/sys/cam/nvme/nvme_xpt.c
+++ b/sys/cam/nvme/nvme_xpt.c
@@ -310,9 +310,11 @@ nvme_probe_done(struct cam_periph *periph, union ccb *done_ccb)
struct nvme_controller_data *nvme_cdata;
nvme_probe_softc *softc;
struct cam_path *path;
+ struct scsi_vpd_device_id *did;
+ struct scsi_vpd_id_descriptor *idd;
cam_status status;
u_int32_t priority;
- int found = 1;
+ int found = 1, e, g, len;
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("nvme_probe_done\n"));
@@ -369,6 +371,21 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
bcopy(&softc->cd, nvme_cdata, sizeof(*nvme_cdata));
path->device->nvme_cdata = nvme_cdata;
+ /* Save/update serial number. */
+ if (path->device->serial_num != NULL) {
+ free(path->device->serial_num, M_CAMXPT);
+ path->device->serial_num = NULL;
+ path->device->serial_num_len = 0;
+ }
+ path->device->serial_num = (u_int8_t *)
+ malloc(NVME_SERIAL_NUMBER_LENGTH + 1, M_CAMXPT, M_NOWAIT);
+ if (path->device->serial_num != NULL) {
+ cam_strvis(path->device->serial_num, nvme_cdata->sn,
+ NVME_SERIAL_NUMBER_LENGTH, NVME_SERIAL_NUMBER_LENGTH + 1);
+ path->device->serial_num_len =
+ strlen(path->device->serial_num);
+ }
+
// nvme_find_quirk(path->device);
nvme_device_transport(path);
NVME_PROBE_SET_ACTION(softc, NVME_PROBE_IDENTIFY_NS);
@@ -394,6 +411,53 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
bcopy(&softc->ns, nvme_data, sizeof(*nvme_data));
path->device->nvme_data = nvme_data;
+ /* Save/update device_id based on NGUID and/or EUI64. */
+ if (path->device->device_id != NULL) {
+ free(path->device->device_id, M_CAMXPT);
+ path->device->device_id = NULL;
+ path->device->device_id_len = 0;
+ }
+ len = 0;
+ for (g = 0; g < sizeof(nvme_data->nguid); g++) {
+ if (nvme_data->nguid[g] != 0)
+ break;
+ }
+ if (g < sizeof(nvme_data->nguid))
+ len += sizeof(struct scsi_vpd_id_descriptor) + 16;
+ for (e = 0; e < sizeof(nvme_data->eui64); e++) {
+ if (nvme_data->eui64[e] != 0)
+ break;
+ }
+ if (e < sizeof(nvme_data->eui64))
+ len += sizeof(struct scsi_vpd_id_descriptor) + 8;
+ if (len > 0) {
+ path->device->device_id = (u_int8_t *)
+ malloc(SVPD_DEVICE_ID_HDR_LEN + len,
+ M_CAMXPT, M_NOWAIT);
+ }
+ if (path->device->device_id != NULL) {
+ did = (struct scsi_vpd_device_id *)path->device->device_id;
+ did->device = SID_QUAL_LU_CONNECTED | T_DIRECT;
+ did->page_code = SVPD_DEVICE_ID;
+ scsi_ulto2b(len, did->length);
+ idd = (struct scsi_vpd_id_descriptor *)(did + 1);
+ if (g < sizeof(nvme_data->nguid)) {
+ idd->proto_codeset = SVPD_ID_CODESET_BINARY;
+ idd->id_type = SVPD_ID_ASSOC_LUN | SVPD_ID_TYPE_EUI64;
+ idd->length = 16;
+ bcopy(nvme_data->nguid, idd->identifier, 16);
+ idd = (struct scsi_vpd_id_descriptor *)
+ &idd->identifier[16];
+ }
+ if (e < sizeof(nvme_data->eui64)) {
+ idd->proto_codeset = SVPD_ID_CODESET_BINARY;
+ idd->id_type = SVPD_ID_ASSOC_LUN | SVPD_ID_TYPE_EUI64;
+ idd->length = 8;
+ bcopy(nvme_data->eui64, idd->identifier, 8);
+ }
+ path->device->device_id_len = SVPD_DEVICE_ID_HDR_LEN + len;
+ }
+
if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
path->device->flags &= ~CAM_DEV_UNCONFIGURED;
xpt_acquire_device(path->device);
@@ -546,9 +610,9 @@ nvme_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
device->maxtags = 0;
device->inq_flags = 0;
device->queue_flags = 0;
- device->device_id = NULL; /* XXX Need to set this somewhere */
+ device->device_id = NULL;
device->device_id_len = 0;
- device->serial_num = NULL; /* XXX Need to set this somewhere */
+ device->serial_num = NULL;
device->serial_num_len = 0;
return (device);
}
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index 2dd9b43ac0177..f2e5d2ba36e15 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -145,41 +145,35 @@ static int
linprocfs_domeminfo(PFS_FILL_ARGS)
{
unsigned long memtotal; /* total memory in bytes */
- unsigned long memused; /* used memory in bytes */
unsigned long memfree; /* free memory in bytes */
- unsigned long buffers, cached; /* buffer / cache memory ??? */
+ unsigned long cached; /* page cache */
+ unsigned long buffers; /* buffer cache */
unsigned long long swaptotal; /* total swap space in bytes */
unsigned long long swapused; /* used swap space in bytes */
unsigned long long swapfree; /* free swap space in bytes */
- int i, j;
+ size_t sz;
+ int error, i, j;
memtotal = physmem * PAGE_SIZE;
- /*
- * The correct thing here would be:
- *
- memfree = vm_free_count() * PAGE_SIZE;
- memused = memtotal - memfree;
- *
- * but it might mislead linux binaries into thinking there
- * is very little memory left, so we cheat and tell them that
- * all memory that isn't wired down is free.
- */
- memused = vm_wire_count() * PAGE_SIZE;
- memfree = memtotal - memused;
+ memfree = (unsigned long)vm_free_count() * PAGE_SIZE;
swap_pager_status(&i, &j);
swaptotal = (unsigned long long)i * PAGE_SIZE;
swapused = (unsigned long long)j * PAGE_SIZE;
swapfree = swaptotal - swapused;
+
/*
- * We'd love to be able to write:
- *
- buffers = bufspace;
- *
- * but bufspace is internal to vfs_bio.c and we don't feel
- * like unstaticizing it just for linprocfs's sake.
+ * This value may exclude wired pages, but we have no good way of
+ * accounting for that.
*/
- buffers = 0;
- cached = vm_inactive_count() * PAGE_SIZE;
+ cached =
+ (vm_active_count() + vm_inactive_count() + vm_laundry_count()) *
+ PAGE_SIZE;
+
+ sz = sizeof(buffers);
+ error = kernel_sysctlbyname(curthread, "vfs.bufspace", &buffers, &sz,
+ NULL, 0, 0, 0);
+ if (error != 0)
+ buffers = 0;
sbuf_printf(sb,
"MemTotal: %9lu kB\n"
diff --git a/sys/compat/linuxkpi/common/include/linux/bitops.h b/sys/compat/linuxkpi/common/include/linux/bitops.h
index 7e259760f7c3a..1bcbd681203cf 100644
--- a/sys/compat/linuxkpi/common/include/linux/bitops.h
+++ b/sys/compat/linuxkpi/common/include/linux/bitops.h
@@ -272,16 +272,12 @@ find_next_zero_bit(const unsigned long *addr, unsigned long size,
#define clear_bit(i, a) \
atomic_clear_long(&((volatile unsigned long *)(a))[BIT_WORD(i)], BIT_MASK(i))
+#define clear_bit_unlock(i, a) \
+ atomic_clear_rel_long(&((volatile unsigned long *)(a))[BIT_WORD(i)], BIT_MASK(i))
+
#define test_bit(i, a) \
!!(READ_ONCE(((volatile const unsigned long *)(a))[BIT_WORD(i)]) & BIT_MASK(i))
-static inline void
-clear_bit_unlock(long bit, volatile unsigned long *var)
-{
- clear_bit(bit, var);
- wmb();
-}
-
static inline int
test_and_clear_bit(long bit, volatile unsigned long *var)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/sched.h b/sys/compat/linuxkpi/common/include/linux/sched.h
index 0545710a61d7b..da38d89eb639c 100644
--- a/sys/compat/linuxkpi/common/include/linux/sched.h
+++ b/sys/compat/linuxkpi/common/include/linux/sched.h
@@ -76,8 +76,9 @@ struct task_struct {
unsigned bsd_ioctl_len;
struct completion parked;
struct completion exited;
- TAILQ_ENTRY(task_struct) rcu_entry;
- int rcu_recurse;
+#define TS_RCU_TYPE_MAX 2
+ TAILQ_ENTRY(task_struct) rcu_entry[TS_RCU_TYPE_MAX];
+ int rcu_recurse[TS_RCU_TYPE_MAX];
int bsd_interrupt_value;
struct work_struct *work; /* current work struct, if set */
struct task_struct *group_leader;
diff --git a/sys/compat/linuxkpi/common/include/linux/wait.h b/sys/compat/linuxkpi/common/include/linux/wait.h
index 7723910316aee..348464fb27df8 100644
--- a/sys/compat/linuxkpi/common/include/linux/wait.h
+++ b/sys/compat/linuxkpi/common/include/linux/wait.h
@@ -36,6 +36,7 @@
#include <linux/compiler.h>
#include <linux/list.h>
#include <linux/spinlock.h>
+#include <linux/sched.h>
#include <asm/atomic.h>
diff --git a/sys/compat/linuxkpi/common/include/linux/wait_bit.h b/sys/compat/linuxkpi/common/include/linux/wait_bit.h
new file mode 100644
index 0000000000000..e3dddaade498a
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/wait_bit.h
@@ -0,0 +1,64 @@
+/*-
+ * 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 __LINUX_WAITBIT_H__
+#define __LINUX_WAITBIT_H__
+
+#include <linux/wait.h>
+#include <linux/bitops.h>
+
+extern wait_queue_head_t linux_bit_waitq;
+extern wait_queue_head_t linux_var_waitq;
+
+#define wait_var_event_killable(var, cond) \
+ wait_event_killable(linux_var_waitq, cond)
+
+static inline void
+clear_and_wake_up_bit(int bit, void *word)
+{
+ clear_bit_unlock(bit, word);
+ wake_up_bit(word, bit);
+}
+
+static inline wait_queue_head_t *
+bit_waitqueue(void *word, int bit)
+{
+
+ return (&linux_bit_waitq);
+}
+
+static inline void
+wake_up_var(void *var)
+{
+
+ wake_up(&linux_var_waitq);
+}
+
+#endif /* __LINUX_WAITBIT_H__ */
diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c
index 0d5e14b9d0273..b3c2475b223fb 100644
--- a/sys/compat/linuxkpi/common/src/linux_compat.c
+++ b/sys/compat/linuxkpi/common/src/linux_compat.c
@@ -86,6 +86,7 @@ __FBSDID("$FreeBSD$");
#include <linux/compat.h>
#include <linux/poll.h>
#include <linux/smp.h>
+#include <linux/wait_bit.h>
#if defined(__i386__) || defined(__amd64__)
#include <asm/smp.h>
@@ -119,6 +120,9 @@ spinlock_t pci_lock;
unsigned long linux_timer_hz_mask;
+wait_queue_head_t linux_bit_waitq;
+wait_queue_head_t linux_var_waitq;
+
int
panic_cmp(struct rb_node *one, struct rb_node *two)
{
@@ -2523,6 +2527,8 @@ linux_compat_init(void *arg)
mtx_init(&vmmaplock, "IO Map lock", NULL, MTX_DEF);
for (i = 0; i < VMMAP_HASH_SIZE; i++)
LIST_INIT(&vmmaphead[i]);
+ init_waitqueue_head(&linux_bit_waitq);
+ init_waitqueue_head(&linux_var_waitq);
}
SYSINIT(linux_compat, SI_SUB_DRIVERS, SI_ORDER_SECOND, linux_compat_init, NULL);
diff --git a/sys/compat/linuxkpi/common/src/linux_rcu.c b/sys/compat/linuxkpi/common/src/linux_rcu.c
index 32ace5cf0c99f..5e698739ab09d 100644
--- a/sys/compat/linuxkpi/common/src/linux_rcu.c
+++ b/sys/compat/linuxkpi/common/src/linux_rcu.c
@@ -74,6 +74,7 @@ struct linux_epoch_record {
ck_epoch_record_t epoch_record;
TAILQ_HEAD(, task_struct) ts_head;
int cpuid;
+ int type;
} __aligned(CACHE_LINE_SIZE);
/*
@@ -90,6 +91,8 @@ CTASSERT(sizeof(struct rcu_head) == sizeof(struct callback_head));
*/
CTASSERT(offsetof(struct linux_epoch_record, epoch_record) == 0);
+CTASSERT(TS_RCU_TYPE_MAX == RCU_TYPE_MAX);
+
static ck_epoch_t linux_epoch[RCU_TYPE_MAX];
static struct linux_epoch_head linux_epoch_head[RCU_TYPE_MAX];
DPCPU_DEFINE_STATIC(struct linux_epoch_record, linux_epoch_record[RCU_TYPE_MAX]);
@@ -118,6 +121,7 @@ linux_rcu_runtime_init(void *arg __unused)
record = &DPCPU_ID_GET(i, linux_epoch_record[j]);
record->cpuid = i;
+ record->type = j;
ck_epoch_register(&linux_epoch[j],
&record->epoch_record, NULL);
TAILQ_INIT(&record->ts_head);
@@ -201,9 +205,9 @@ linux_rcu_read_lock(unsigned type)
*/
critical_enter();
ck_epoch_begin(&record->epoch_record, NULL);
- ts->rcu_recurse++;
- if (ts->rcu_recurse == 1)
- TAILQ_INSERT_TAIL(&record->ts_head, ts, rcu_entry);
+ ts->rcu_recurse[type]++;
+ if (ts->rcu_recurse[type] == 1)
+ TAILQ_INSERT_TAIL(&record->ts_head, ts, rcu_entry[type]);
critical_exit();
}
@@ -227,9 +231,9 @@ linux_rcu_read_unlock(unsigned type)
*/
critical_enter();
ck_epoch_end(&record->epoch_record, NULL);
- ts->rcu_recurse--;
- if (ts->rcu_recurse == 0)
- TAILQ_REMOVE(&record->ts_head, ts, rcu_entry);
+ ts->rcu_recurse[type]--;
+ if (ts->rcu_recurse[type] == 0)
+ TAILQ_REMOVE(&record->ts_head, ts, rcu_entry[type]);
critical_exit();
sched_unpin();
@@ -254,7 +258,7 @@ linux_synchronize_rcu_cb(ck_epoch_t *epoch __unused, ck_epoch_record_t *epoch_re
* the threads in the queue are CPU-pinned and cannot
* go anywhere while the current thread is locked.
*/
- TAILQ_FOREACH(ts, &record->ts_head, rcu_entry) {
+ TAILQ_FOREACH(ts, &record->ts_head, rcu_entry[record->type]) {
if (ts->task_thread->td_priority > prio)
prio = ts->task_thread->td_priority;
is_sleeping |= (ts->task_thread->td_inhibitors != 0);
diff --git a/sys/compat/netbsd/dvcfg.h b/sys/compat/netbsd/dvcfg.h
deleted file mode 100644
index 809c14a95aff2..0000000000000
--- a/sys/compat/netbsd/dvcfg.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD$ */
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * [NetBSD for NEC PC98 series]
- * Copyright (c) 1996 NetBSD/pc98 porting staff.
- * 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, 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.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * 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.
- */
-/*
- * Copyright (c) 1996 Naofumi HONDA. All rights reserved.
- */
-
-#ifndef _COMPAT_NETBSD_DVCFG_H_
-#define _COMPAT_NETBSD_DVCFG_H_
-
-typedef void *dvcfg_hw_t;
-
-struct dvcfg_hwsel {
- int cfg_max;
-
- dvcfg_hw_t *cfg_sel;
-};
-
-#define DVCFG_MAJOR(dvcfg) (((u_int)(dvcfg)) >> 16)
-#define DVCFG_MINOR(dvcfg) (((u_int)(dvcfg)) & 0xffff)
-
-#define DVCFG_MKCFG(major, minor) ((((u_int)(major)) << 16) | ((minor) & 0xffff))
-
-#define DVCFG_HWSEL_SZ(array) (sizeof(array) / sizeof(dvcfg_hw_t))
-
-static __inline dvcfg_hw_t dvcfg_hw(struct dvcfg_hwsel *, u_int);
-
-static __inline dvcfg_hw_t
-dvcfg_hw(selp, num)
- struct dvcfg_hwsel *selp;
- u_int num;
-{
-
- return ((num >= selp->cfg_max) ? 0 : selp->cfg_sel[num]);
-}
-
-#define DVCFG_HW(SELP, NUM) dvcfg_hw((SELP), (NUM))
-#endif /* _COMPAT_NETBSD_DVCFG_H_ */
diff --git a/sys/conf/files b/sys/conf/files
index 04e224437f93e..052e8c238f43b 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -3834,6 +3834,7 @@ kern/subr_pctrie.c standard
kern/subr_pidctrl.c standard
kern/subr_power.c standard
kern/subr_prf.c standard
+kern/subr_prng.c standard
kern/subr_prof.c standard
kern/subr_rangeset.c standard
kern/subr_rman.c standard
diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk
index 2436269c893c2..16910042af8ba 100644
--- a/sys/conf/kern.pre.mk
+++ b/sys/conf/kern.pre.mk
@@ -166,9 +166,13 @@ LDFLAGS+= -z max-page-size=2097152
.if ${LINKER_TYPE} != "lld"
LDFLAGS+= -z common-page-size=4096
.else
+.if defined(LINKER_FEATURES) && !${LINKER_FEATURES:Mifunc-noplt}
+.warning "Linker ${LD} does not support -z ifunc-noplt -> ifunc calls are unoptimized."
+.else
LDFLAGS+= -z notext -z ifunc-noplt
.endif
.endif
+.endif # ${MACHINE_CPUARCH} == "amd64"
.if ${MACHINE_CPUARCH} == "riscv"
# Hack: Work around undefined weak symbols being out of range when linking with
diff --git a/sys/contrib/pcg-c/include/pcg_variants.h b/sys/contrib/pcg-c/include/pcg_variants.h
index 768fb75ae93bc..14f8e7aa2cf8d 100644
--- a/sys/contrib/pcg-c/include/pcg_variants.h
+++ b/sys/contrib/pcg-c/include/pcg_variants.h
@@ -36,22 +36,16 @@
#ifndef PCG_VARIANTS_H_INCLUDED
#define PCG_VARIANTS_H_INCLUDED 1
-#include <inttypes.h>
-
-#if __SIZEOF_INT128__
+#if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__
typedef __uint128_t pcg128_t;
#define PCG_128BIT_CONSTANT(high,low) \
((((pcg128_t)high) << 64) + low)
#define PCG_HAS_128BIT_OPS 1
+#else
+ #define PCG_HAS_128BIT_OPS 0
#endif
-#if __GNUC_GNU_INLINE__ && !defined(__cplusplus)
- #error Nonstandard GNU inlining semantics. Compile with -std=c99 or better.
- /* We could instead use macros PCG_INLINE and PCG_EXTERN_INLINE
- but better to just reject ancient C code. */
-#endif
-
-#if __cplusplus
+#ifdef __cplusplus
extern "C" {
#endif
@@ -65,8 +59,8 @@ inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot)
* recognizing idiomatic rotate code, so for clang we actually provide
* assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss.
*/
-#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__)
- asm ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
+#if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
+ __asm__ ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
#else
return (value >> rot) | (value << ((- rot) & 7));
@@ -75,8 +69,8 @@ inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot)
inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot)
{
-#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__)
- asm ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
+#if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
+ __asm__ ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
#else
return (value >> rot) | (value << ((- rot) & 15));
@@ -85,8 +79,8 @@ inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot)
inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot)
{
-#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__)
- asm ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
+#if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
+ __asm__ ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
#else
return (value >> rot) | (value << ((- rot) & 31));
@@ -95,10 +89,10 @@ inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot)
inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot)
{
-#if 0 && PCG_USE_INLINE_ASM && __clang__ && __x86_64__
+#if 0 && PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
/* For whatever reason, clang actually *does* generate rotq by
itself, so we don't need this code. */
- asm ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
+ __asm__ ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
#else
return (value >> rot) | (value << ((- rot) & 63));
@@ -2491,18 +2485,6 @@ typedef struct pcg_state_setseq_128 pcg128i_random_t;
#define pcg128i_advance_r pcg_setseq_128_advance_r
#endif
-extern uint32_t pcg32_random(void);
-extern uint32_t pcg32_boundedrand(uint32_t bound);
-extern void pcg32_srandom(uint64_t seed, uint64_t seq);
-extern void pcg32_advance(uint64_t delta);
-
-#if PCG_HAS_128BIT_OPS
-extern uint64_t pcg64_random(void);
-extern uint64_t pcg64_boundedrand(uint64_t bound);
-extern void pcg64_srandom(pcg128_t seed, pcg128_t seq);
-extern void pcg64_advance(pcg128_t delta);
-#endif
-
/*
* Static initialization constants (if you can't call srandom for some
* bizarre reason).
@@ -2536,7 +2518,7 @@ extern void pcg64_advance(pcg128_t delta);
#define PCG128I_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER
#endif
-#if __cplusplus
+#ifdef __cplusplus
}
#endif
diff --git a/sys/dev/dwc/if_dwc.c b/sys/dev/dwc/if_dwc.c
index 44350ae087cc8..0b38439b3e129 100644
--- a/sys/dev/dwc/if_dwc.c
+++ b/sys/dev/dwc/if_dwc.c
@@ -1209,14 +1209,23 @@ dwc_clock_init(device_t dev)
hwreset_t rst;
clk_t clk;
int error;
+ int64_t freq;
- /* Enable clock */
+ /* Enable clocks */
if (clk_get_by_ofw_name(dev, 0, "stmmaceth", &clk) == 0) {
error = clk_enable(clk);
if (error != 0) {
device_printf(dev, "could not enable main clock\n");
return (error);
}
+ if (bootverbose) {
+ clk_get_freq(clk, &freq);
+ device_printf(dev, "MAC clock(%s) freq: %jd\n",
+ clk_get_name(clk), (intmax_t)freq);
+ }
+ }
+ else {
+ device_printf(dev, "could not find clock stmmaceth\n");
}
/* De-assert reset */
@@ -1254,6 +1263,8 @@ dwc_attach(device_t dev)
struct ifnet *ifp;
int error, i;
uint32_t reg;
+ char *phy_mode;
+ phandle_t node;
sc = device_get_softc(dev);
sc->dev = dev;
@@ -1262,6 +1273,15 @@ dwc_attach(device_t dev)
sc->mii_clk = IF_DWC_MII_CLK(dev);
sc->mactype = IF_DWC_MAC_TYPE(dev);
+ node = ofw_bus_get_node(dev);
+ if (OF_getprop_alloc(node, "phy-mode", (void **)&phy_mode)) {
+ if (strcmp(phy_mode, "rgmii") == 0)
+ sc->phy_mode = PHY_MODE_RGMII;
+ if (strcmp(phy_mode, "rmii") == 0)
+ sc->phy_mode = PHY_MODE_RMII;
+ OF_prop_free(phy_mode);
+ }
+
if (IF_DWC_INIT(dev) != 0)
return (ENXIO);
@@ -1475,6 +1495,9 @@ dwc_miibus_statchg(device_t dev)
else
reg &= ~(CONF_DM);
WRITE4(sc, MAC_CONFIGURATION, reg);
+
+ IF_DWC_SET_SPEED(dev, IFM_SUBTYPE(mii->mii_media_active));
+
}
static device_method_t dwc_methods[] = {
diff --git a/sys/dev/dwc/if_dwc.h b/sys/dev/dwc/if_dwc.h
index d20f35d74ce5a..045072abe6112 100644
--- a/sys/dev/dwc/if_dwc.h
+++ b/sys/dev/dwc/if_dwc.h
@@ -37,6 +37,10 @@
#ifndef __IF_DWC_H__
#define __IF_DWC_H__
+#define PHY_MODE_UNKNOWN 0x0
+#define PHY_MODE_RMII 0x1
+#define PHY_MODE_RGMII 0x2
+
#define MAC_CONFIGURATION 0x0
#define CONF_JD (1 << 22) /* jabber timer disable */
#define CONF_BE (1 << 21) /* Frame Burst Enable */
diff --git a/sys/dev/dwc/if_dwc_if.m b/sys/dev/dwc/if_dwc_if.m
index 733f83545cf4c..dae429c55e8a6 100644
--- a/sys/dev/dwc/if_dwc_if.m
+++ b/sys/dev/dwc/if_dwc_if.m
@@ -49,6 +49,12 @@ CODE {
{
return (GMAC_MII_CLK_25_35M_DIV16);
}
+
+ static int
+ if_dwc_default_set_speed(device_t dev, int speed)
+ {
+ return (0);
+ }
};
HEADER {
@@ -74,3 +80,11 @@ METHOD int mac_type {
METHOD int mii_clk {
device_t dev;
} DEFAULT if_dwc_default_mii_clk;
+
+#
+# Signal media change to a specific hardware
+#
+METHOD int set_speed {
+ device_t dev;
+ int speed;
+} DEFAULT if_dwc_default_set_speed;
diff --git a/sys/dev/dwc/if_dwcvar.h b/sys/dev/dwc/if_dwcvar.h
index 9db24c14f328d..0470b29cb0e1c 100644
--- a/sys/dev/dwc/if_dwcvar.h
+++ b/sys/dev/dwc/if_dwcvar.h
@@ -71,6 +71,7 @@ struct dwc_softc {
boolean_t is_detaching;
int tx_watchdog_count;
int stats_harvest_count;
+ int phy_mode;
/* RX */
bus_dma_tag_t rxdesc_tag;
diff --git a/sys/dev/gpio/gpiokeys.c b/sys/dev/gpio/gpiokeys.c
index 714bca6e61fbb..6fd1edddab44e 100644
--- a/sys/dev/gpio/gpiokeys.c
+++ b/sys/dev/gpio/gpiokeys.c
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#include "opt_platform.h"
#include "opt_kbd.h"
+#include "opt_evdev.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -56,6 +57,11 @@ __FBSDID("$FreeBSD$");
#include <dev/gpio/gpiobusvar.h>
#include <dev/gpio/gpiokeys.h>
+#ifdef EVDEV_SUPPORT
+#include <dev/evdev/evdev.h>
+#include <dev/evdev/input.h>
+#endif
+
#define KBD_DRIVER_NAME "gpiokeys"
#define GPIOKEYS_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
@@ -99,6 +105,9 @@ struct gpiokey
struct resource *irq_res;
void *intr_hl;
struct mtx mtx;
+#ifdef EVDEV_SUPPORT
+ uint32_t evcode;
+#endif
uint32_t keycode;
int autorepeat;
struct callout debounce_callout;
@@ -115,6 +124,9 @@ struct gpiokeys_softc
struct gpiokey *sc_keys;
int sc_total_keys;
+#ifdef EVDEV_SUPPORT
+ struct evdev_dev *sc_evdev;
+#endif
keyboard_t sc_kbd;
keymap_t sc_keymap;
accentmap_t sc_accmap;
@@ -171,26 +183,34 @@ gpiokeys_put_key(struct gpiokeys_softc *sc, uint32_t key)
}
static void
-gpiokeys_key_event(struct gpiokeys_softc *sc, uint16_t keycode, int pressed)
+gpiokeys_key_event(struct gpiokeys_softc *sc, struct gpiokey *key, int pressed)
{
- uint32_t key;
-
-
- key = keycode & SCAN_KEYCODE_MASK;
-
- if (!pressed)
- key |= KEY_RELEASE;
+ uint32_t code;
GPIOKEYS_LOCK(sc);
- if (keycode & SCAN_PREFIX_E0)
- gpiokeys_put_key(sc, 0xe0);
- else if (keycode & SCAN_PREFIX_E1)
- gpiokeys_put_key(sc, 0xe1);
+#ifdef EVDEV_SUPPORT
+ if (key->evcode != GPIOKEY_NONE &&
+ (evdev_rcpt_mask & EVDEV_RCPT_HW_KBD) != 0) {
+ evdev_push_key(sc->sc_evdev, key->evcode, pressed);
+ evdev_sync(sc->sc_evdev);
+ }
+#endif
+ if (key->keycode != GPIOKEY_NONE) {
+ code = key->keycode & SCAN_KEYCODE_MASK;
+ if (!pressed)
+ code |= KEY_RELEASE;
- gpiokeys_put_key(sc, key);
+ if (key->keycode & SCAN_PREFIX_E0)
+ gpiokeys_put_key(sc, 0xe0);
+ else if (key->keycode & SCAN_PREFIX_E1)
+ gpiokeys_put_key(sc, 0xe1);
+
+ gpiokeys_put_key(sc, code);
+ }
GPIOKEYS_UNLOCK(sc);
- gpiokeys_event_keyinput(sc);
+ if (key->keycode != GPIOKEY_NONE)
+ gpiokeys_event_keyinput(sc);
}
static void
@@ -200,10 +220,7 @@ gpiokey_autorepeat(void *arg)
key = arg;
- if (key->keycode == GPIOKEY_NONE)
- return;
-
- gpiokeys_key_event(key->parent_sc, key->keycode, 1);
+ gpiokeys_key_event(key->parent_sc, key, 1);
callout_reset(&key->repeat_callout, key->repeat,
gpiokey_autorepeat, key);
@@ -217,12 +234,9 @@ gpiokey_debounced_intr(void *arg)
key = arg;
- if (key->keycode == GPIOKEY_NONE)
- return;
-
gpio_pin_is_active(key->pin, &active);
if (active) {
- gpiokeys_key_event(key->parent_sc, key->keycode, 1);
+ gpiokeys_key_event(key->parent_sc, key, 1);
if (key->autorepeat) {
callout_reset(&key->repeat_callout, key->repeat_delay,
gpiokey_autorepeat, key);
@@ -232,7 +246,7 @@ gpiokey_debounced_intr(void *arg)
if (key->autorepeat &&
callout_pending(&key->repeat_callout))
callout_stop(&key->repeat_callout);
- gpiokeys_key_event(key->parent_sc, key->keycode, 0);
+ gpiokeys_key_event(key->parent_sc, key, 0);
}
}
@@ -301,6 +315,10 @@ gpiokeys_attach_key(struct gpiokeys_softc *sc, phandle_t node,
if (key->keycode == GPIOKEY_NONE)
device_printf(sc->sc_dev, "<%s> failed to map linux,code value 0x%x\n",
key_name, code);
+#ifdef EVDEV_SUPPORT
+ key->evcode = code;
+ evdev_support_key(sc->sc_evdev, code);
+#endif
}
else
device_printf(sc->sc_dev, "<%s> no linux,code or freebsd,code property\n",
@@ -365,7 +383,6 @@ gpiokeys_detach_key(struct gpiokeys_softc *sc, struct gpiokey *key)
if (key->pin)
gpio_pin_release(key->pin);
GPIOKEY_UNLOCK(key);
-
GPIOKEY_LOCK_DESTROY(key);
}
@@ -383,11 +400,14 @@ gpiokeys_probe(device_t dev)
static int
gpiokeys_attach(device_t dev)
{
- int unit;
struct gpiokeys_softc *sc;
keyboard_t *kbd;
+#ifdef EVDEV_SUPPORT
+ char *name;
+#endif
phandle_t keys, child;
int total_keys;
+ int unit;
if ((keys = ofw_bus_get_node(dev)) == -1)
return (ENXIO);
@@ -435,6 +455,19 @@ gpiokeys_attach(device_t dev)
kbdd_diag(kbd, 1);
}
+#ifdef EVDEV_SUPPORT
+ sc->sc_evdev = evdev_alloc();
+ evdev_set_name(sc->sc_evdev, device_get_desc(dev));
+
+ OF_getprop_alloc(keys, "name", (void **)&name);
+ evdev_set_phys(sc->sc_evdev, name != NULL ? name : "unknown");
+ OF_prop_free(name);
+
+ evdev_set_id(sc->sc_evdev, BUS_VIRTUAL, 0, 0, 0);
+ evdev_support_event(sc->sc_evdev, EV_SYN);
+ evdev_support_event(sc->sc_evdev, EV_KEY);
+#endif
+
total_keys = 0;
/* Traverse the 'gpio-keys' node and count keys */
@@ -458,6 +491,13 @@ gpiokeys_attach(device_t dev)
}
}
+#ifdef EVDEV_SUPPORT
+ if (evdev_register_mtx(sc->sc_evdev, &sc->sc_mtx) != 0) {
+ device_printf(dev, "failed to register evdev device\n");
+ goto detach;
+ }
+#endif
+
return (0);
detach:
@@ -485,6 +525,10 @@ gpiokeys_detach(device_t dev)
#endif
kbd_unregister(kbd);
+#ifdef EVDEV_SUPPORT
+ evdev_free(sc->sc_evdev);
+#endif
+
GPIOKEYS_LOCK_DESTROY(sc);
if (sc->sc_keys)
free(sc->sc_keys, M_DEVBUF);
diff --git a/sys/dev/hwpmc/hwpmc_arm64.c b/sys/dev/hwpmc/hwpmc_arm64.c
index 2618a889e86f8..4ae8645abaf6c 100644
--- a/sys/dev/hwpmc/hwpmc_arm64.c
+++ b/sys/dev/hwpmc/hwpmc_arm64.c
@@ -479,11 +479,12 @@ pmc_arm64_initialize()
{
struct pmc_mdep *pmc_mdep;
struct pmc_classdep *pcd;
- int idcode;
+ int idcode, impcode;
int reg;
reg = arm64_pmcr_read();
arm64_npmcs = (reg & PMCR_N_MASK) >> PMCR_N_SHIFT;
+ impcode = (reg & PMCR_IMP_MASK) >> PMCR_IMP_SHIFT;
idcode = (reg & PMCR_IDCODE_MASK) >> PMCR_IDCODE_SHIFT;
PMCDBG1(MDP, INI, 1, "arm64-init npmcs=%d", arm64_npmcs);
@@ -498,13 +499,24 @@ pmc_arm64_initialize()
/* Just one class */
pmc_mdep = pmc_mdep_alloc(1);
- switch (idcode) {
- case PMCR_IDCODE_CORTEX_A57:
- case PMCR_IDCODE_CORTEX_A72:
- pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A57;
+ switch(impcode) {
+ case PMCR_IMP_ARM:
+ switch (idcode) {
+ case PMCR_IDCODE_CORTEX_A76:
+ case PMCR_IDCODE_NEOVERSE_N1:
+ pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A76;
+ break;
+ case PMCR_IDCODE_CORTEX_A57:
+ case PMCR_IDCODE_CORTEX_A72:
+ pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A57;
+ break;
+ default:
+ case PMCR_IDCODE_CORTEX_A53:
+ pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A53;
+ break;
+ }
break;
default:
- case PMCR_IDCODE_CORTEX_A53:
pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A53;
break;
}
diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h
index 6f7282f8ea556..cb3c299b3aab4 100644
--- a/sys/dev/hwpmc/pmc_events.h
+++ b/sys/dev/hwpmc/pmc_events.h
@@ -955,7 +955,7 @@ __PMC_EV_ALIAS("unhalted-core-cycles", IAP_ARCH_UNH_COR_CYC)
__PMC_EV_ALIAS("BR_RETURN_RETIRED", ARMV8_EVENT_0EH) \
__PMC_EV_ALIAS("UNALIGNED_LDST_RETIRED",ARMV8_EVENT_0FH)
-#define __PMC_EV_ALIAS_ARMV8_CORTEX_A57() \
+#define __PMC_EV_ALIAS_ARMV8_CORTEX_A57_A76() \
__PMC_EV_ALIAS_ARMV8_COMMON() \
__PMC_EV_ALIAS("INST_SPEC", ARMV8_EVENT_1BH) \
__PMC_EV_ALIAS("TTBR_WRITE_RETIRED", ARMV8_EVENT_1CH) \
@@ -975,10 +975,6 @@ __PMC_EV_ALIAS("unhalted-core-cycles", IAP_ARCH_UNH_COR_CYC)
__PMC_EV_ALIAS("L2D_CACHE_WB_VICTIM", ARMV8_EVENT_56H) \
__PMC_EV_ALIAS("L2D_CACHE_WB_CLEAN", ARMV8_EVENT_57H) \
__PMC_EV_ALIAS("L2D_CACHE_INVAL", ARMV8_EVENT_58H) \
- __PMC_EV_ALIAS("BUS_ACCESS_SHARED", ARMV8_EVENT_62H) \
- __PMC_EV_ALIAS("BUS_ACCESS_NOT_SHARED", ARMV8_EVENT_63H) \
- __PMC_EV_ALIAS("BUS_ACCESS_NORMAL", ARMV8_EVENT_64H) \
- __PMC_EV_ALIAS("BUS_ACCESS_PERIPH", ARMV8_EVENT_65H) \
__PMC_EV_ALIAS("MEM_ACCESS_LD", ARMV8_EVENT_66H) \
__PMC_EV_ALIAS("MEM_ACCESS_ST", ARMV8_EVENT_67H) \
__PMC_EV_ALIAS("UNALIGNED_LD_SPEC", ARMV8_EVENT_68H) \
@@ -1014,6 +1010,43 @@ __PMC_EV_ALIAS("unhalted-core-cycles", IAP_ARCH_UNH_COR_CYC)
__PMC_EV_ALIAS("RC_LD_SPEC", ARMV8_EVENT_90H) \
__PMC_EV_ALIAS("RC_ST_SPEC", ARMV8_EVENT_91H)
+#define __PMC_EV_ALIAS_ARMV8_CORTEX_A57() \
+ __PMC_EV_ALIAS_ARMV8_CORTEX_A57_A76() \
+ __PMC_EV_ALIAS("BUS_ACCESS_SHARED", ARMV8_EVENT_62H) \
+ __PMC_EV_ALIAS("BUS_ACCESS_NOT_SHARED", ARMV8_EVENT_63H) \
+ __PMC_EV_ALIAS("BUS_ACCESS_NORMAL", ARMV8_EVENT_64H) \
+ __PMC_EV_ALIAS("BUS_ACCESS_PERIPH", ARMV8_EVENT_65H)
+
+#define __PMC_EV_ALIAS_ARMV8_CORTEX_A76() \
+ __PMC_EV_ALIAS_ARMV8_CORTEX_A57_A76() \
+ __PMC_EV_ALIAS("L2D_CACHE_ALLOCATE", ARMV8_EVENT_20H) \
+ __PMC_EV_ALIAS("BR_RETIRED", ARMV8_EVENT_21H) \
+ __PMC_EV_ALIAS("BR_MIS_PRED_RETIRED", ARMV8_EVENT_22H) \
+ __PMC_EV_ALIAS("STALL_FRONTEND", ARMV8_EVENT_23H) \
+ __PMC_EV_ALIAS("STALL_BACKEND", ARMV8_EVENT_24H) \
+ __PMC_EV_ALIAS("L1D_TLB", ARMV8_EVENT_25H) \
+ __PMC_EV_ALIAS("L1I_TLB", ARMV8_EVENT_26H) \
+ __PMC_EV_ALIAS("L3D_CACHE_ALLOCATE", ARMV8_EVENT_29H) \
+ __PMC_EV_ALIAS("L3D_CACHE_REFILL", ARMV8_EVENT_2AH) \
+ __PMC_EV_ALIAS("L3D_CACHE", ARMV8_EVENT_2BH) \
+ __PMC_EV_ALIAS("L2D_TLB_REFILL", ARMV8_EVENT_2DH) \
+ __PMC_EV_ALIAS("L2D_TLB", ARMV8_EVENT_2FH) \
+ __PMC_EV_ALIAS("REMOTE_ACCESS", ARMV8_EVENT_31H) \
+ __PMC_EV_ALIAS("DTLB_WALK", ARMV8_EVENT_34H) \
+ __PMC_EV_ALIAS("ITLB_WALK", ARMV8_EVENT_35H) \
+ __PMC_EV_ALIAS("LL_CACHE_RD", ARMV8_EVENT_36H) \
+ __PMC_EV_ALIAS("LL_CACHE_MISS_RD", ARMV8_EVENT_37H) \
+ __PMC_EV_ALIAS("L1D_CACHE_REFILL_INNER", ARMV8_EVENT_44H) \
+ __PMC_EV_ALIAS("L1D_CACHE_REFILL_OUTER", ARMV8_EVENT_45H) \
+ __PMC_EV_ALIAS("L1D_TLB_RD", ARMV8_EVENT_4EH) \
+ __PMC_EV_ALIAS("L1D_TLB_WR", ARMV8_EVENT_4FH) \
+ __PMC_EV_ALIAS("L2D_TLB_REFILL_RD", ARMV8_EVENT_5CH) \
+ __PMC_EV_ALIAS("L2D_TLB_REFILL_WR", ARMV8_EVENT_5DH) \
+ __PMC_EV_ALIAS("L2D_TLB_RD", ARMV8_EVENT_5EH) \
+ __PMC_EV_ALIAS("L2D_TLB_WR", ARMV8_EVENT_5FH) \
+ __PMC_EV_ALIAS("STREX_SPEC", ARMV8_EVENT_6FH) \
+ __PMC_EV_ALIAS("L3_CACHE_RD", ARMV8_EVENT_A0H)
+
/*
* MIPS Events from "Programming the MIPS32 24K Core Family",
* Document Number: MD00355 Revision 04.63 December 19, 2008
diff --git a/sys/dev/ice/ice_common.h b/sys/dev/ice/ice_common.h
index 1cff7efb8150f..bba7f2699b222 100644
--- a/sys/dev/ice/ice_common.h
+++ b/sys/dev/ice/ice_common.h
@@ -46,16 +46,6 @@ enum ice_fw_modes {
ICE_FW_MODE_ROLLBACK
};
-/* prototype for functions used for SW locks */
-void ice_free_list(struct LIST_HEAD_TYPE *list);
-void ice_init_lock(struct ice_lock *lock);
-void ice_acquire_lock(struct ice_lock *lock);
-void ice_release_lock(struct ice_lock *lock);
-void ice_destroy_lock(struct ice_lock *lock);
-
-void *ice_alloc_dma_mem(struct ice_hw *hw, struct ice_dma_mem *m, u64 size);
-void ice_free_dma_mem(struct ice_hw *hw, struct ice_dma_mem *m);
-
void ice_idle_aq(struct ice_hw *hw, struct ice_ctl_q_info *cq);
bool ice_sq_done(struct ice_hw *hw, struct ice_ctl_q_info *cq);
@@ -78,13 +68,6 @@ enum ice_status
ice_get_link_status(struct ice_port_info *pi, bool *link_up);
enum ice_status ice_update_link_info(struct ice_port_info *pi);
enum ice_status
-ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access);
-void ice_release_nvm(struct ice_hw *hw);
-enum ice_status
-ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length,
- void *data, bool last_command, bool read_shadow_ram,
- struct ice_sq_cd *cd);
-enum ice_status
ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res,
enum ice_aq_res_access_type access, u32 timeout);
void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res);
diff --git a/sys/dev/ixl/i40e_prototype.h b/sys/dev/ixl/i40e_prototype.h
index 51021ed28e6ad..6e86e68eb8db2 100644
--- a/sys/dev/ixl/i40e_prototype.h
+++ b/sys/dev/ixl/i40e_prototype.h
@@ -606,6 +606,4 @@ enum i40e_status_code i40e_read_phy_register(struct i40e_hw *hw,
enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
u8 page, u16 reg, u8 phy_addr, u16 value);
u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
-enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw,
- u32 time, u32 interval);
#endif /* _I40E_PROTOTYPE_H_ */
diff --git a/sys/dev/nvd/nvd.c b/sys/dev/nvd/nvd.c
index 8ac8c2bf9963d..1e8488867844e 100644
--- a/sys/dev/nvd/nvd.c
+++ b/sys/dev/nvd/nvd.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2012-2016 Intel Corporation
* All rights reserved.
- * Copyright (C) 2018 Alexander Motin <mav@FreeBSD.org>
+ * Copyright (C) 2018-2020 Alexander Motin <mav@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -45,6 +45,9 @@ __FBSDID("$FreeBSD$");
#include <geom/geom_disk.h>
#include <dev/nvme/nvme.h>
+#include <dev/nvme/nvme_private.h>
+
+#include <dev/pci/pcivar.h>
#define NVD_STR "nvd"
@@ -92,7 +95,7 @@ struct nvd_disk {
};
struct nvd_controller {
-
+ struct nvme_controller *ctrlr;
TAILQ_ENTRY(nvd_controller) tailq;
TAILQ_HEAD(, nvd_disk) disk_head;
};
@@ -401,6 +404,7 @@ nvd_new_controller(struct nvme_controller *ctrlr)
nvd_ctrlr = malloc(sizeof(struct nvd_controller), M_NVD,
M_ZERO | M_WAITOK);
+ nvd_ctrlr->ctrlr = ctrlr;
TAILQ_INIT(&nvd_ctrlr->disk_head);
mtx_lock(&nvd_lock);
TAILQ_INSERT_TAIL(&ctrlr_head, nvd_ctrlr, tailq);
@@ -416,6 +420,7 @@ nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg)
struct nvd_disk *ndisk, *tnd;
struct disk *disk;
struct nvd_controller *ctrlr = ctrlr_arg;
+ device_t dev = ctrlr->ctrlr->dev;
int unit;
ndisk = malloc(sizeof(struct nvd_disk), M_NVD, M_ZERO | M_WAITOK);
@@ -479,7 +484,13 @@ nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg)
NVME_MODEL_NUMBER_LENGTH);
strlcpy(disk->d_descr, descr, sizeof(descr));
+ disk->d_hba_vendor = pci_get_vendor(dev);
+ disk->d_hba_device = pci_get_device(dev);
+ disk->d_hba_subvendor = pci_get_subvendor(dev);
+ disk->d_hba_subdevice = pci_get_subdevice(dev);
disk->d_rotation_rate = DISK_RR_NON_ROTATING;
+ strlcpy(disk->d_attachment, device_get_nameunit(dev),
+ sizeof(disk->d_attachment));
disk_create(disk, DISK_VERSION);
diff --git a/sys/dev/nvme/nvme_sim.c b/sys/dev/nvme/nvme_sim.c
index c9d8d94543d7d..efec8d34868a4 100644
--- a/sys/dev/nvme/nvme_sim.c
+++ b/sys/dev/nvme/nvme_sim.c
@@ -197,8 +197,12 @@ nvme_sim_action(struct cam_sim *sim, union ccb *ccb)
cpi->xport_specific.nvme.slot = pci_get_slot(dev);
cpi->xport_specific.nvme.function = pci_get_function(dev);
cpi->xport_specific.nvme.extra = 0;
- strncpy(cpi->xport_specific.nvme.dev_name, device_get_nameunit(ctrlr->dev),
+ strncpy(cpi->xport_specific.nvme.dev_name, device_get_nameunit(dev),
sizeof(cpi->xport_specific.nvme.dev_name));
+ cpi->hba_vendor = pci_get_vendor(dev);
+ cpi->hba_device = pci_get_device(dev);
+ cpi->hba_subvendor = pci_get_subvendor(dev);
+ cpi->hba_subdevice = pci_get_subdevice(dev);
cpi->ccb_h.status = CAM_REQ_CMP;
break;
}
diff --git a/sys/dev/usb/misc/cp2112.c b/sys/dev/usb/misc/cp2112.c
index 0430fdbfe56f3..a2ead7d5371ed 100644
--- a/sys/dev/usb/misc/cp2112.c
+++ b/sys/dev/usb/misc/cp2112.c
@@ -66,6 +66,8 @@ __FBSDID("$FreeBSD$");
#define USB_DEBUG_VAR usb_debug
#include <dev/usb/usb_debug.h>
+#define SIZEOF_FIELD(_s, _f) sizeof(((struct _s *)NULL)->_f)
+
#define CP2112GPIO_LOCK(sc) sx_xlock(&sc->gpio_lock)
#define CP2112GPIO_UNLOCK(sc) sx_xunlock(&sc->gpio_lock)
#define CP2112GPIO_LOCKED(sc) sx_assert(&sc->gpio_lock, SX_XLOCKED)
@@ -93,8 +95,13 @@ __FBSDID("$FreeBSD$");
#define CP2112_REQ_LOCK 0x20
#define CP2112_REQ_USB_CFG 0x21
+#define CP2112_IIC_MAX_READ_LEN 512
#define CP2112_IIC_REPSTART_VER 2 /* Erratum CP2112_E10. */
+#define CP2112_GPIO_SPEC_CLK7 1 /* Pin 7 is clock output. */
+#define CP2112_GPIO_SPEC_TX0 2 /* Pin 0 pulses on USB TX. */
+#define CP2112_GPIO_SPEC_RX1 4 /* Pin 1 pulses on USB RX. */
+
#define CP2112_IIC_STATUS0_IDLE 0
#define CP2112_IIC_STATUS0_BUSY 1
#define CP2112_IIC_STATUS0_CMP 2
@@ -104,6 +111,111 @@ __FBSDID("$FreeBSD$");
#define CP2112_IIC_STATUS1_TIMEOUT_BUS 1
#define CP2112_IIC_STATUS1_ARB_LOST 2
+/* CP2112_REQ_VERSION */
+struct version_request {
+ uint8_t id;
+ uint8_t part_num;
+ uint8_t version;
+} __packed;
+
+/* CP2112_REQ_GPIO_GET */
+struct gpio_get_req {
+ uint8_t id;
+ uint8_t state;
+} __packed;
+
+/* CP2112_REQ_GPIO_SET */
+struct gpio_set_req {
+ uint8_t id;
+ uint8_t state;
+ uint8_t mask;
+} __packed;
+
+/* CP2112_REQ_GPIO_CFG */
+struct gpio_config_req {
+ uint8_t id;
+ uint8_t output;
+ uint8_t pushpull;
+ uint8_t special;
+ uint8_t divider;
+} __packed;
+
+/* CP2112_REQ_SMB_XFER_STATUS_REQ */
+struct i2c_xfer_status_req {
+ uint8_t id;
+ uint8_t request;
+} __packed;
+
+/* CP2112_REQ_SMB_XFER_STATUS_RESP */
+struct i2c_xfer_status_resp {
+ uint8_t id;
+ uint8_t status0;
+ uint8_t status1;
+ uint16_t status2;
+ uint16_t status3;
+} __packed;
+
+/* CP2112_REQ_SMB_READ_FORCE_SEND */
+struct i2c_data_read_force_send_req {
+ uint8_t id;
+ uint16_t len;
+} __packed;
+
+/* CP2112_REQ_SMB_READ_RESPONSE */
+struct i2c_data_read_resp {
+ uint8_t id;
+ uint8_t status;
+ uint8_t len;
+ uint8_t data[61];
+} __packed;
+
+/* CP2112_REQ_SMB_READ */
+struct i2c_write_read_req {
+ uint8_t id;
+ uint8_t slave;
+ uint16_t rlen;
+ uint8_t wlen;
+ uint8_t wdata[16];
+} __packed;
+
+/* CP2112_REQ_SMB_WRITE */
+struct i2c_read_req {
+ uint8_t id;
+ uint8_t slave;
+ uint16_t len;
+} __packed;
+
+/* CP2112_REQ_SMB_WRITE_READ */
+struct i2c_write_req {
+ uint8_t id;
+ uint8_t slave;
+ uint8_t len;
+ uint8_t data[61];
+} __packed;
+
+/* CP2112_REQ_SMB_CFG */
+struct i2c_cfg_req {
+ uint8_t id;
+ uint32_t speed; /* Hz */
+ uint8_t slave_addr; /* ACK only */
+ uint8_t auto_send_read; /* boolean */
+ uint16_t write_timeout; /* 0-1000 ms, 0 ~ no timeout */
+ uint16_t read_timeout; /* 0-1000 ms, 0 ~ no timeout */
+ uint8_t scl_low_timeout;/* boolean */
+ uint16_t retry_count; /* 1-1000, 0 ~ forever */
+} __packed;
+
+enum cp2112_out_mode {
+ OUT_OD,
+ OUT_PP,
+ OUT_KEEP
+};
+
+enum {
+ CP2112_INTR_OUT = 0,
+ CP2112_INTR_IN,
+ CP2112_N_TRANSFER,
+};
struct cp2112_softc {
device_t sc_gpio_dev;
@@ -120,10 +232,38 @@ struct cp2112gpio_softc {
struct gpio_pin pins[CP2112_GPIO_COUNT];
};
+struct cp2112iic_softc {
+ device_t dev;
+ device_t iicbus_dev;
+ struct usb_xfer *xfers[CP2112_N_TRANSFER];
+ u_char own_addr;
+ struct {
+ struct mtx lock;
+ struct cv cv;
+ struct {
+ uint8_t *data;
+ int len;
+ int done;
+ int error;
+ } in;
+ struct {
+ const uint8_t *data;
+ int len;
+ int done;
+ int error;
+ } out;
+ } io;
+};
+
static int cp2112_detach(device_t dev);
static int cp2112gpio_detach(device_t dev);
static int cp2112iic_detach(device_t dev);
+static const STRUCT_USB_HOST_ID cp2112_devs[] = {
+ { USB_VP(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2112) },
+ { USB_VP(0x1009, USB_PRODUCT_SILABS_CP2112) }, /* XXX */
+};
+
static int
cp2112_get_report(device_t dev, uint8_t id, void *data, uint16_t len)
{
@@ -143,25 +283,103 @@ cp2112_set_report(device_t dev, uint8_t id, void *data, uint16_t len)
int err;
sc = device_get_softc(dev);
+ *(uint8_t *)data = id;
err = usbd_req_set_report(sc->sc_udev, NULL, data,
len, sc->sc_iface_index, UHID_FEATURE_REPORT, id);
return (err);
}
static int
+cp2112_probe(device_t dev)
+{
+ struct usb_attach_arg *uaa;
+
+ uaa = device_get_ivars(dev);
+ if (uaa->usb_mode != USB_MODE_HOST)
+ return (ENXIO);
+ if (uaa->info.bInterfaceClass != UICLASS_HID)
+ return (ENXIO);
+
+ if (usbd_lookup_id_by_uaa(cp2112_devs, sizeof(cp2112_devs), uaa) == 0)
+ return (BUS_PROBE_DEFAULT);
+ return (ENXIO);
+}
+
+static int
+cp2112_attach(device_t dev)
+{
+ struct version_request vdata;
+ struct usb_attach_arg *uaa;
+ struct cp2112_softc *sc;
+ int err;
+
+ uaa = device_get_ivars(dev);
+ sc = device_get_softc(dev);
+
+ device_set_usb_desc(dev);
+
+ sc->sc_udev = uaa->device;
+ sc->sc_iface_index = uaa->info.bIfaceIndex;
+
+ err = cp2112_get_report(dev, CP2112_REQ_VERSION, &vdata, sizeof(vdata));
+ if (err != 0)
+ goto detach;
+ device_printf(dev, "part number 0x%02x, version 0x%02x\n",
+ vdata.part_num, vdata.version);
+ if (vdata.part_num != CP2112_PART_NUM) {
+ device_printf(dev, "unsupported part number\n");
+ goto detach;
+ }
+ sc->sc_version = vdata.version;
+ sc->sc_gpio_dev = device_add_child(dev, "gpio", -1);
+ if (sc->sc_gpio_dev != NULL) {
+ err = device_probe_and_attach(sc->sc_gpio_dev);
+ if (err != 0) {
+ device_printf(dev, "failed to attach gpio child\n");
+ }
+ } else {
+ device_printf(dev, "failed to create gpio child\n");
+ }
+
+ sc->sc_iic_dev = device_add_child(dev, "iichb", -1);
+ if (sc->sc_iic_dev != NULL) {
+ err = device_probe_and_attach(sc->sc_iic_dev);
+ if (err != 0) {
+ device_printf(dev, "failed to attach iic child\n");
+ }
+ } else {
+ device_printf(dev, "failed to create iic child\n");
+ }
+
+ return (0);
+
+detach:
+ cp2112_detach(dev);
+ return (ENXIO);
+}
+
+static int
+cp2112_detach(device_t dev)
+{
+ int err;
+
+ err = bus_generic_detach(dev);
+ if (err != 0)
+ return (err);
+ device_delete_children(dev);
+ return (0);
+}
+
+static int
cp2112_gpio_read_pin(device_t dev, uint32_t pin_num, bool *on)
{
- struct {
- uint8_t id;
- uint8_t state;
- } __packed data;
+ struct gpio_get_req data;
struct cp2112gpio_softc *sc;
int err;
sc = device_get_softc(dev);
CP2112GPIO_LOCKED(sc);
- data.id = CP2112_REQ_GPIO_GET;
err = cp2112_get_report(device_get_parent(dev),
CP2112_REQ_GPIO_GET, &data, sizeof(data));
if (err != 0)
@@ -174,11 +392,7 @@ cp2112_gpio_read_pin(device_t dev, uint32_t pin_num, bool *on)
static int
cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on)
{
- struct {
- uint8_t id;
- uint8_t state;
- uint8_t mask;
- } __packed data;
+ struct gpio_set_req data;
struct cp2112gpio_softc *sc;
int err;
bool actual;
@@ -186,10 +400,8 @@ cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on)
sc = device_get_softc(dev);
CP2112GPIO_LOCKED(sc);
- data.id = CP2112_REQ_GPIO_SET;
data.state = (uint8_t)on << pin_num;
data.mask = (uint8_t)1 << pin_num;
-
err = cp2112_set_report(device_get_parent(dev),
CP2112_REQ_GPIO_SET, &data, sizeof(data));
if (err != 0)
@@ -204,15 +416,9 @@ cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on)
static int
cp2112_gpio_configure_write_pin(device_t dev, uint32_t pin_num,
- bool output, bool pushpull)
+ bool output, enum cp2112_out_mode *mode)
{
- struct {
- uint8_t id;
- uint8_t output;
- uint8_t pushpull;
- uint8_t special;
- uint8_t divider;
- } __packed data;
+ struct gpio_config_req data;
struct cp2112gpio_softc *sc;
int err;
uint8_t mask;
@@ -220,21 +426,26 @@ cp2112_gpio_configure_write_pin(device_t dev, uint32_t pin_num,
sc = device_get_softc(dev);
CP2112GPIO_LOCKED(sc);
- mask = (uint8_t)1 << pin_num;
- data.id = CP2112_REQ_GPIO_CFG;
err = cp2112_get_report(device_get_parent(dev),
CP2112_REQ_GPIO_CFG, &data, sizeof(data));
if (err != 0)
return (err);
+
+ mask = (uint8_t)1 << pin_num;
if (output) {
data.output |= mask;
- if (pushpull)
+ switch (*mode) {
+ case OUT_PP:
data.pushpull |= mask;
- else
+ break;
+ case OUT_OD:
data.pushpull &= ~mask;
+ break;
+ default:
+ break;
+ }
} else {
data.output &= ~mask;
- data.pushpull &= ~mask;
}
err = cp2112_set_report(device_get_parent(dev),
@@ -247,10 +458,25 @@ cp2112_gpio_configure_write_pin(device_t dev, uint32_t pin_num,
CP2112_REQ_GPIO_CFG, &data, sizeof(data));
if (err != 0)
return (err);
+
if (((data.output & mask) != 0) != output)
return (EIO);
- if (((data.pushpull & mask) != 0) != pushpull)
- return (EIO);
+ if (output) {
+ switch (*mode) {
+ case OUT_PP:
+ if ((data.pushpull & mask) == 0)
+ return (EIO);
+ break;
+ case OUT_OD:
+ if ((data.pushpull & mask) != 0)
+ return (EIO);
+ break;
+ default:
+ *mode = (data.pushpull & mask) != 0 ?
+ OUT_PP : OUT_OD;
+ break;
+ }
+ }
return (0);
}
@@ -381,6 +607,7 @@ cp2112_gpio_pin_setflags(device_t dev, uint32_t pin_num, uint32_t flags)
{
struct cp2112gpio_softc *sc;
struct gpio_pin *pin;
+ enum cp2112_out_mode out_mode;
int err;
if (pin_num >= CP2112_GPIO_COUNT)
@@ -405,115 +632,42 @@ cp2112_gpio_pin_setflags(device_t dev, uint32_t pin_num, uint32_t flags)
return (EINVAL);
}
- CP2112GPIO_LOCK(sc);
- pin = &sc->pins[pin_num];
-
/*
- * If neither push-pull or opendrain is explcitely requested, then
+ * If neither push-pull or open-drain is explicitly requested, then
* preserve the current state.
*/
- if ((flags & GPIO_PIN_OUTPUT) != 0 &&
- (flags & (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)) == 0)
- flags |= pin->gp_flags & (GPIO_PIN_OPENDRAIN|GPIO_PIN_PUSHPULL);
- err = cp2112_gpio_configure_write_pin(dev, pin_num,
- (flags & GPIO_PIN_OUTPUT) != 0,
- (flags & GPIO_PIN_PUSHPULL) != 0);
- if (err == 0)
- pin->gp_flags = flags;
- CP2112GPIO_UNLOCK(sc);
-
- return (err);
-}
-
-static const STRUCT_USB_HOST_ID cp2112_devs[] = {
- { USB_VP(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2112) },
- { USB_VP(0x1009, USB_PRODUCT_SILABS_CP2112) }, /* XXX */
-};
-
-static int
-cp2112_probe(device_t dev)
-{
- struct usb_attach_arg *uaa;
-
- uaa = device_get_ivars(dev);
- if (uaa->usb_mode != USB_MODE_HOST)
- return (ENXIO);
- if (uaa->info.bInterfaceClass != UICLASS_HID)
- return (ENXIO);
-
- if (usbd_lookup_id_by_uaa(cp2112_devs, sizeof(cp2112_devs), uaa) == 0)
- return (BUS_PROBE_DEFAULT);
- return (ENXIO);
-}
-
-static int
-cp2112_attach(device_t dev)
-{
- struct {
- uint8_t id;
- uint8_t part_num;
- uint8_t version;
- } __packed vdata;
- struct usb_attach_arg *uaa;
- struct cp2112_softc *sc;
- int err;
-
- uaa = device_get_ivars(dev);
- sc = device_get_softc(dev);
-
- device_set_usb_desc(dev);
-
- sc->sc_udev = uaa->device;
- sc->sc_iface_index = uaa->info.bIfaceIndex;
-
- vdata.id = CP2112_REQ_VERSION;
- err = cp2112_get_report(dev, CP2112_REQ_VERSION, &vdata, sizeof(vdata));
- if (err != 0)
- goto detach;
- device_printf(dev, "part number 0x%02x, version 0x%02x\n",
- vdata.part_num, vdata.version);
- if (vdata.part_num != CP2112_PART_NUM) {
- device_printf(dev, "unsupported part number\n");
- goto detach;
- }
- sc->sc_version = vdata.version;
- sc->sc_gpio_dev = device_add_child(dev, "gpio", -1);
- if (sc->sc_gpio_dev != NULL) {
- err = device_probe_and_attach(sc->sc_gpio_dev);
- if (err != 0) {
- device_printf(dev, "failed to attach gpio child\n");
- }
- } else {
- device_printf(dev, "failed to create gpio child\n");
+ out_mode = OUT_KEEP;
+ if ((flags & GPIO_PIN_OUTPUT) != 0) {
+ if ((flags & GPIO_PIN_OPENDRAIN) != 0)
+ out_mode = OUT_OD;
+ if ((flags & GPIO_PIN_PUSHPULL) != 0)
+ out_mode = OUT_PP;
}
- sc->sc_iic_dev = device_add_child(dev, "iichb", -1);
- if (sc->sc_iic_dev != NULL) {
- err = device_probe_and_attach(sc->sc_iic_dev);
- if (err != 0) {
- device_printf(dev, "failed to attach iic child\n");
+ CP2112GPIO_LOCK(sc);
+ pin = &sc->pins[pin_num];
+ err = cp2112_gpio_configure_write_pin(dev, pin_num,
+ (flags & GPIO_PIN_OUTPUT) != 0, &out_mode);
+ if (err == 0) {
+ /*
+ * If neither open-drain or push-pull was requested, then see
+ * what hardware actually had. Otherwise, it has been
+ * reconfigured as requested.
+ */
+ if ((flags & GPIO_PIN_OUTPUT) != 0 &&
+ (flags & (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)) == 0) {
+ KASSERT(out_mode != OUT_KEEP,
+ ("impossible current output mode"));
+ if (out_mode == OUT_OD)
+ flags |= GPIO_PIN_OPENDRAIN;
+ else
+ flags |= GPIO_PIN_PUSHPULL;
}
- } else {
- device_printf(dev, "failed to create iic child\n");
+ pin->gp_flags = flags;
}
+ CP2112GPIO_UNLOCK(sc);
- return (0);
-
-detach:
- cp2112_detach(dev);
- return (ENXIO);
-}
-
-static int
-cp2112_detach(device_t dev)
-{
- int err;
-
- err = bus_generic_detach(dev);
- if (err != 0)
- return (err);
- device_delete_children(dev);
- return (0);
+ return (err);
}
static int
@@ -526,13 +680,7 @@ cp2112gpio_probe(device_t dev)
static int
cp2112gpio_attach(device_t dev)
{
- struct {
- uint8_t id;
- uint8_t output;
- uint8_t pushpull;
- uint8_t special;
- uint8_t divider;
- } __packed data;
+ struct gpio_config_req data;
struct cp2112gpio_softc *sc;
device_t cp2112;
int err;
@@ -546,7 +694,6 @@ cp2112gpio_attach(device_t dev)
sc->gpio_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN |
GPIO_PIN_PUSHPULL;
- data.id = CP2112_REQ_GPIO_CFG;
err = cp2112_get_report(cp2112, CP2112_REQ_GPIO_CFG,
&data, sizeof(data));
if (err != 0)
@@ -562,7 +709,11 @@ cp2112gpio_attach(device_t dev)
snprintf(pin->gp_name, GPIOMAXNAME, "GPIO%u", i);
pin->gp_name[GPIOMAXNAME - 1] = '\0';
- if ((data.output & mask) != 0) {
+ if ((i == 0 && (data.special & CP2112_GPIO_SPEC_TX0) != 0) ||
+ (i == 1 && (data.special & CP2112_GPIO_SPEC_RX1) != 0) ||
+ (i == 7 && (data.special & CP2112_GPIO_SPEC_CLK7) != 0)) {
+ /* Special mode means that a pin is not for GPIO. */
+ } else if ((data.output & mask) != 0) {
pin->gp_flags |= GPIO_PIN_OUTPUT;
if ((data.pushpull & mask) != 0)
pin->gp_flags |= GPIO_PIN_PUSHPULL;
@@ -597,94 +748,6 @@ cp2112gpio_detach(device_t dev)
return (0);
}
-static device_method_t cp2112hid_methods[] = {
- DEVMETHOD(device_probe, cp2112_probe),
- DEVMETHOD(device_attach, cp2112_attach),
- DEVMETHOD(device_detach, cp2112_detach),
-
- DEVMETHOD_END
-};
-
-static device_method_t cp2112gpio_methods[] = {
- /* Device */
- DEVMETHOD(device_probe, cp2112gpio_probe),
- DEVMETHOD(device_attach, cp2112gpio_attach),
- DEVMETHOD(device_detach, cp2112gpio_detach),
-
- /* GPIO */
- DEVMETHOD(gpio_get_bus, cp2112_gpio_get_bus),
- DEVMETHOD(gpio_pin_max, cp2112_gpio_pin_max),
- DEVMETHOD(gpio_pin_get, cp2112_gpio_pin_get),
- DEVMETHOD(gpio_pin_set, cp2112_gpio_pin_set),
- DEVMETHOD(gpio_pin_toggle, cp2112_gpio_pin_toggle),
- DEVMETHOD(gpio_pin_getname, cp2112_gpio_pin_getname),
- DEVMETHOD(gpio_pin_getcaps, cp2112_gpio_pin_getcaps),
- DEVMETHOD(gpio_pin_getflags, cp2112_gpio_pin_getflags),
- DEVMETHOD(gpio_pin_setflags, cp2112_gpio_pin_setflags),
-
- DEVMETHOD_END
-};
-
-static driver_t cp2112hid_driver = {
- .name = "cp2112hid",
- .methods = cp2112hid_methods,
- .size = sizeof(struct cp2112_softc),
-};
-
-static devclass_t cp2112hid_devclass;
-DRIVER_MODULE(cp2112hid, uhub, cp2112hid_driver, cp2112hid_devclass,
- NULL, NULL);
-MODULE_DEPEND(cp2112hid, usb, 1, 1, 1);
-MODULE_VERSION(cp2112hid, 1);
-USB_PNP_HOST_INFO(cp2112_devs);
-
-static driver_t cp2112gpio_driver = {
- .name = "gpio",
- .methods = cp2112gpio_methods,
- .size = sizeof(struct cp2112gpio_softc),
-};
-
-static devclass_t cp2112gpio_devclass;
-DRIVER_MODULE(cp2112gpio, cp2112hid, cp2112gpio_driver, cp2112gpio_devclass,
- NULL, NULL);
-MODULE_DEPEND(cp2112gpio, cp2112hid, 1, 1, 1);
-MODULE_DEPEND(cp2112gpio, gpiobus, 1, 1, 1);
-MODULE_VERSION(cp2112gpio, 1);
-
-
-
-/* CP2112 I2C driver code. */
-
-
-enum {
- CP2112_INTR_OUT = 0,
- CP2112_INTR_IN,
- CP2112_N_TRANSFER,
-};
-
-struct cp2112iic_softc {
- device_t dev;
- device_t iicbus_dev;
- struct usb_xfer *xfers[CP2112_N_TRANSFER];
- u_char own_addr;
- struct {
- struct mtx lock;
- struct cv cv;
- struct {
- uint8_t *data;
- int len;
- int done;
- int error;
- } in;
- struct {
- const uint8_t *data;
- int len;
- int done;
- int error;
- } out;
- } io;
-};
-
static void
cp2112iic_intr_write_callback(struct usb_xfer *xfer, usb_error_t error)
{
@@ -890,17 +953,8 @@ cp2112iic_req_resp(struct cp2112iic_softc *sc, const void *req_data,
static int
cp2112iic_check_req_status(struct cp2112iic_softc *sc)
{
- struct {
- uint8_t id;
- uint8_t request;
- } __packed xfer_status_req;
- struct {
- uint8_t id;
- uint8_t status0;
- uint8_t status1;
- uint16_t status2;
- uint16_t status3;
- } __packed xfer_status_resp;
+ struct i2c_xfer_status_req xfer_status_req;
+ struct i2c_xfer_status_resp xfer_status_resp;
int err;
mtx_assert(&sc->io.lock, MA_OWNED);
@@ -971,16 +1025,8 @@ static int
cp2112iic_read_data(struct cp2112iic_softc *sc, void *data, uint16_t in_len,
uint16_t *out_len)
{
- struct {
- uint8_t id;
- uint16_t length;
- } __packed data_read_force_send;
- struct {
- uint8_t id;
- uint8_t status;
- uint8_t length;
- uint8_t data[61];
- } __packed data_read_resp;
+ struct i2c_data_read_force_send_req data_read_force_send;
+ struct i2c_data_read_resp data_read_resp;
int err;
mtx_assert(&sc->io.lock, MA_OWNED);
@@ -993,7 +1039,7 @@ cp2112iic_read_data(struct cp2112iic_softc *sc, void *data, uint16_t in_len,
if (in_len > sizeof(data_read_resp.data))
in_len = sizeof(data_read_resp.data);
data_read_force_send.id = CP2112_REQ_SMB_READ_FORCE_SEND;
- data_read_force_send.length = htobe16(in_len);
+ data_read_force_send.len = htobe16(in_len);
err = cp2112iic_req_resp(sc,
&data_read_force_send, sizeof(data_read_force_send),
&data_read_resp, sizeof(data_read_resp));
@@ -1009,7 +1055,7 @@ cp2112iic_read_data(struct cp2112iic_softc *sc, void *data, uint16_t in_len,
}
DTRACE_PROBE2(read__response, uint8_t, data_read_resp.status,
- uint8_t, data_read_resp.length);
+ uint8_t, data_read_resp.len);
/*
* We expect either the request completed status or, more typical for
@@ -1021,13 +1067,13 @@ cp2112iic_read_data(struct cp2112iic_softc *sc, void *data, uint16_t in_len,
err = IIC_EBUSERR;
goto out;
}
- if (data_read_resp.length > in_len) {
+ if (data_read_resp.len > in_len) {
device_printf(sc->dev, "device returns more data than asked\n");
err = IIC_EOVERFLOW;
goto out;
}
- *out_len = data_read_resp.length;
+ *out_len = data_read_resp.len;
if (*out_len > 0)
memcpy(data, data_read_resp.data, *out_len);
out:
@@ -1070,11 +1116,13 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
reason = "message with no data";
break;
}
- if ((msgs[i].flags & IIC_M_RD) != 0 && msgs[i].len > 512) {
+ if ((msgs[i].flags & IIC_M_RD) != 0 &&
+ msgs[i].len > CP2112_IIC_MAX_READ_LEN) {
reason = "too long read";
break;
}
- if ((msgs[i].flags & IIC_M_RD) == 0 && msgs[i].len > 61) {
+ if ((msgs[i].flags & IIC_M_RD) == 0 &&
+ msgs[i].len > SIZEOF_FIELD(i2c_write_req, data)) {
reason = "too long write";
break;
}
@@ -1092,7 +1140,8 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
reason = "write without stop";
break;
}
- if ((msgs[i].flags & IIC_M_NOSTOP) != 0 && msgs[i].len > 16) {
+ if ((msgs[i].flags & IIC_M_NOSTOP) != 0 &&
+ msgs[i].len > SIZEOF_FIELD(i2c_write_read_req, wdata)) {
reason = "too long write without stop";
break;
}
@@ -1120,22 +1169,16 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
for (i = 0; i < nmsgs; i++) {
if (i + 1 < nmsgs && (msgs[i].flags & IIC_M_NOSTOP) != 0) {
- KASSERT((msgs[i].flags & IIC_M_RD) == 0,
- ("read without stop"));
- KASSERT((msgs[i + 1].flags & IIC_M_RD) != 0,
- ("write after write without stop"));
/*
* Combine <write><repeated start><read> into a single
* CP2112 operation.
*/
- struct {
- uint8_t id;
- uint8_t slave;
- uint16_t rlen;
- uint8_t wlen;
- uint8_t wdata[16];
- } __packed req;
+ struct i2c_write_read_req req;
+ KASSERT((msgs[i].flags & IIC_M_RD) == 0,
+ ("read without stop"));
+ KASSERT((msgs[i + 1].flags & IIC_M_RD) != 0,
+ ("write after write without stop"));
req.id = CP2112_REQ_SMB_WRITE_READ;
req.slave = msgs[i].slave & ~LSB;
to_read = msgs[i + 1].len;
@@ -1150,11 +1193,7 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
*/
i++;
} else if ((msgs[i].flags & IIC_M_RD) != 0) {
- struct {
- uint8_t id;
- uint8_t slave;
- uint16_t len;
- } __packed req;
+ struct i2c_read_req req;
req.id = CP2112_REQ_SMB_READ;
req.slave = msgs[i].slave & ~LSB;
@@ -1162,12 +1201,7 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
req.len = htobe16(to_read);
err = cp2112iic_send_req(sc, &req, sizeof(req));
} else {
- struct {
- uint8_t id;
- uint8_t slave;
- uint8_t len;
- uint8_t data[61];
- } __packed req;
+ struct i2c_write_req req;
req.id = CP2112_REQ_SMB_WRITE;
req.slave = msgs[i].slave & ~LSB;
@@ -1207,16 +1241,7 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
static int
cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
{
- struct {
- uint8_t id;
- uint32_t speed; /* Hz */
- uint8_t slave_addr; /* ACK only */
- uint8_t auto_send_read; /* boolean */
- uint16_t write_timeout; /* 0-1000 ms, 0 ~ no timeout */
- uint16_t read_timeout; /* 0-1000 ms, 0 ~ no timeout */
- uint8_t scl_low_timeout;/* boolean */
- uint16_t retry_count; /* 1-1000, 0 ~ forever */
- } __packed smb_cfg;
+ struct i2c_cfg_req i2c_cfg;
struct cp2112iic_softc *sc;
device_t cp2112;
u_int busfreq;
@@ -1229,16 +1254,15 @@ cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
else
busfreq = IICBUS_GET_FREQUENCY(sc->iicbus_dev, speed);
- smb_cfg.id = CP2112_REQ_SMB_CFG;
err = cp2112_get_report(cp2112, CP2112_REQ_SMB_CFG,
- &smb_cfg, sizeof(smb_cfg));
+ &i2c_cfg, sizeof(i2c_cfg));
if (err != 0) {
device_printf(dev, "failed to get CP2112_REQ_SMB_CFG report\n");
return (err);
}
if (oldaddr != NULL)
- *oldaddr = smb_cfg.slave_addr;
+ *oldaddr = i2c_cfg.slave_addr;
/*
* For simplicity we do not enable Auto Send Read
* because of erratum CP2112_E101 (fixed in version 3).
@@ -1251,28 +1275,28 @@ cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
* TODO: should the device reset request (0x01) be sent?
* If the device disconnects as a result, then no.
*/
- smb_cfg.speed = htobe32(busfreq);
+ i2c_cfg.speed = htobe32(busfreq);
if (addr != 0)
- smb_cfg.slave_addr = addr;
- smb_cfg.auto_send_read = 0;
- smb_cfg.retry_count = htobe16(1);
- smb_cfg.scl_low_timeout = 0;
+ i2c_cfg.slave_addr = addr;
+ i2c_cfg.auto_send_read = 0;
+ i2c_cfg.retry_count = htobe16(1);
+ i2c_cfg.scl_low_timeout = 0;
if (bootverbose) {
- device_printf(dev, "speed %d Hz\n", be32toh(smb_cfg.speed));
- device_printf(dev, "slave addr 0x%02x\n", smb_cfg.slave_addr);
+ device_printf(dev, "speed %d Hz\n", be32toh(i2c_cfg.speed));
+ device_printf(dev, "slave addr 0x%02x\n", i2c_cfg.slave_addr);
device_printf(dev, "auto send read %s\n",
- smb_cfg.auto_send_read ? "on" : "off");
+ i2c_cfg.auto_send_read ? "on" : "off");
device_printf(dev, "write timeout %d ms (0 - disabled)\n",
- be16toh(smb_cfg.write_timeout));
+ be16toh(i2c_cfg.write_timeout));
device_printf(dev, "read timeout %d ms (0 - disabled)\n",
- be16toh(smb_cfg.read_timeout));
+ be16toh(i2c_cfg.read_timeout));
device_printf(dev, "scl low timeout %s\n",
- smb_cfg.scl_low_timeout ? "on" : "off");
+ i2c_cfg.scl_low_timeout ? "on" : "off");
device_printf(dev, "retry count %d (0 - no limit)\n",
- be16toh(smb_cfg.retry_count));
+ be16toh(i2c_cfg.retry_count));
}
err = cp2112_set_report(cp2112, CP2112_REQ_SMB_CFG,
- &smb_cfg, sizeof(smb_cfg));
+ &i2c_cfg, sizeof(i2c_cfg));
if (err != 0) {
device_printf(dev, "failed to set CP2112_REQ_SMB_CFG report\n");
return (err);
@@ -1353,6 +1377,60 @@ cp2112iic_detach(device_t dev)
return (0);
}
+static device_method_t cp2112hid_methods[] = {
+ DEVMETHOD(device_probe, cp2112_probe),
+ DEVMETHOD(device_attach, cp2112_attach),
+ DEVMETHOD(device_detach, cp2112_detach),
+
+ DEVMETHOD_END
+};
+
+static driver_t cp2112hid_driver = {
+ .name = "cp2112hid",
+ .methods = cp2112hid_methods,
+ .size = sizeof(struct cp2112_softc),
+};
+
+static devclass_t cp2112hid_devclass;
+DRIVER_MODULE(cp2112hid, uhub, cp2112hid_driver, cp2112hid_devclass,
+ NULL, NULL);
+MODULE_DEPEND(cp2112hid, usb, 1, 1, 1);
+MODULE_VERSION(cp2112hid, 1);
+USB_PNP_HOST_INFO(cp2112_devs);
+
+static device_method_t cp2112gpio_methods[] = {
+ /* Device */
+ DEVMETHOD(device_probe, cp2112gpio_probe),
+ DEVMETHOD(device_attach, cp2112gpio_attach),
+ DEVMETHOD(device_detach, cp2112gpio_detach),
+
+ /* GPIO */
+ DEVMETHOD(gpio_get_bus, cp2112_gpio_get_bus),
+ DEVMETHOD(gpio_pin_max, cp2112_gpio_pin_max),
+ DEVMETHOD(gpio_pin_get, cp2112_gpio_pin_get),
+ DEVMETHOD(gpio_pin_set, cp2112_gpio_pin_set),
+ DEVMETHOD(gpio_pin_toggle, cp2112_gpio_pin_toggle),
+ DEVMETHOD(gpio_pin_getname, cp2112_gpio_pin_getname),
+ DEVMETHOD(gpio_pin_getcaps, cp2112_gpio_pin_getcaps),
+ DEVMETHOD(gpio_pin_getflags, cp2112_gpio_pin_getflags),
+ DEVMETHOD(gpio_pin_setflags, cp2112_gpio_pin_setflags),
+
+ DEVMETHOD_END
+};
+
+static driver_t cp2112gpio_driver = {
+ .name = "gpio",
+ .methods = cp2112gpio_methods,
+ .size = sizeof(struct cp2112gpio_softc),
+};
+
+static devclass_t cp2112gpio_devclass;
+DRIVER_MODULE(cp2112gpio, cp2112hid, cp2112gpio_driver, cp2112gpio_devclass,
+ NULL, NULL);
+MODULE_DEPEND(cp2112gpio, cp2112hid, 1, 1, 1);
+MODULE_DEPEND(cp2112gpio, gpiobus, 1, 1, 1);
+MODULE_VERSION(cp2112gpio, 1);
+
static device_method_t cp2112iic_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, cp2112iic_probe),
diff --git a/sys/fs/devfs/devfs.h b/sys/fs/devfs/devfs.h
index 673d949991697..aef2916012897 100644
--- a/sys/fs/devfs/devfs.h
+++ b/sys/fs/devfs/devfs.h
@@ -153,6 +153,7 @@ struct devfs_dirent {
struct timespec de_ctime;
struct vnode *de_vnode;
char *de_symlink;
+ int de_usecount;
};
struct devfs_mount {
@@ -203,6 +204,10 @@ struct devfs_dirent *devfs_vmkdir(struct devfs_mount *, char *, int,
struct devfs_dirent *devfs_find(struct devfs_dirent *, const char *, int,
int);
+void devfs_ctty_ref(struct vnode *);
+void devfs_ctty_unref(struct vnode *);
+int devfs_usecount(struct vnode *);
+
#endif /* _KERNEL */
#endif /* !_FS_DEVFS_DEVFS_H_ */
diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c
index 3929cc8b1e80f..e3d86cf902bf3 100644
--- a/sys/fs/devfs/devfs_devs.c
+++ b/sys/fs/devfs/devfs_devs.c
@@ -156,7 +156,7 @@ devfs_dev_exists(const char *name)
{
struct cdev_priv *cdp;
- mtx_assert(&devmtx, MA_OWNED);
+ dev_lock_assert_locked();
TAILQ_FOREACH(cdp, &cdevp_list, cdp_list) {
if ((cdp->cdp_flags & CDP_ACTIVE) == 0)
@@ -707,7 +707,7 @@ devfs_create(struct cdev *dev)
{
struct cdev_priv *cdp;
- mtx_assert(&devmtx, MA_OWNED);
+ dev_lock_assert_locked();
cdp = cdev2priv(dev);
cdp->cdp_flags |= CDP_ACTIVE;
cdp->cdp_inode = alloc_unrl(devfs_inos);
@@ -721,7 +721,7 @@ devfs_destroy(struct cdev *dev)
{
struct cdev_priv *cdp;
- mtx_assert(&devmtx, MA_OWNED);
+ dev_lock_assert_locked();
cdp = cdev2priv(dev);
cdp->cdp_flags &= ~CDP_ACTIVE;
devfs_generation++;
diff --git a/sys/fs/devfs/devfs_int.h b/sys/fs/devfs/devfs_int.h
index 4b23e4fce272f..5c3cb17eca612 100644
--- a/sys/fs/devfs/devfs_int.h
+++ b/sys/fs/devfs/devfs_int.h
@@ -95,6 +95,9 @@ extern struct sx clone_drain_lock;
extern struct mtx cdevpriv_mtx;
extern TAILQ_HEAD(cdev_priv_list, cdev_priv) cdevp_list;
+#define dev_lock_assert_locked() mtx_assert(&devmtx, MA_OWNED)
+#define dev_lock_assert_unlocked() mtx_assert(&devmtx, MA_NOTOWNED)
+
#endif /* _KERNEL */
#endif /* !_FS_DEVFS_DEVFS_INT_H_ */
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index f9e29e0b1c74a..983bfc8039998 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -222,6 +222,115 @@ devfs_clear_cdevpriv(void)
devfs_fpdrop(fp);
}
+static void
+devfs_usecount_add(struct vnode *vp)
+{
+ struct devfs_dirent *de;
+ struct cdev *dev;
+
+ mtx_lock(&devfs_de_interlock);
+ VI_LOCK(vp);
+ VNPASS(vp->v_type == VCHR || vp->v_type == VBAD, vp);
+ if (VN_IS_DOOMED(vp)) {
+ goto out_unlock;
+ }
+
+ de = vp->v_data;
+ dev = vp->v_rdev;
+ MPASS(de != NULL);
+ MPASS(dev != NULL);
+ dev->si_usecount++;
+ de->de_usecount++;
+out_unlock:
+ VI_UNLOCK(vp);
+ mtx_unlock(&devfs_de_interlock);
+}
+
+static void
+devfs_usecount_subl(struct vnode *vp)
+{
+ struct devfs_dirent *de;
+ struct cdev *dev;
+
+ mtx_assert(&devfs_de_interlock, MA_OWNED);
+ ASSERT_VI_LOCKED(vp, __func__);
+ VNPASS(vp->v_type == VCHR || vp->v_type == VBAD, vp);
+
+ de = vp->v_data;
+ dev = vp->v_rdev;
+ if (de == NULL)
+ return;
+ if (dev == NULL) {
+ MPASS(de->de_usecount == 0);
+ return;
+ }
+ if (dev->si_usecount < de->de_usecount)
+ panic("%s: si_usecount underflow for dev %p "
+ "(has %ld, dirent has %d)\n",
+ __func__, dev, dev->si_usecount, de->de_usecount);
+ if (VN_IS_DOOMED(vp)) {
+ dev->si_usecount -= de->de_usecount;
+ de->de_usecount = 0;
+ } else {
+ if (de->de_usecount == 0)
+ panic("%s: de_usecount underflow for dev %p\n",
+ __func__, dev);
+ dev->si_usecount--;
+ de->de_usecount--;
+ }
+}
+
+static void
+devfs_usecount_sub(struct vnode *vp)
+{
+
+ mtx_lock(&devfs_de_interlock);
+ VI_LOCK(vp);
+ devfs_usecount_subl(vp);
+ VI_UNLOCK(vp);
+ mtx_unlock(&devfs_de_interlock);
+}
+
+static int
+devfs_usecountl(struct vnode *vp)
+{
+
+ VNPASS(vp->v_type == VCHR, vp);
+ mtx_assert(&devfs_de_interlock, MA_OWNED);
+ ASSERT_VI_LOCKED(vp, __func__);
+ return (vp->v_rdev->si_usecount);
+}
+
+int
+devfs_usecount(struct vnode *vp)
+{
+ int count;
+
+ VNPASS(vp->v_type == VCHR, vp);
+ mtx_lock(&devfs_de_interlock);
+ VI_LOCK(vp);
+ count = devfs_usecountl(vp);
+ VI_UNLOCK(vp);
+ mtx_unlock(&devfs_de_interlock);
+ return (count);
+}
+
+void
+devfs_ctty_ref(struct vnode *vp)
+{
+
+ vrefact(vp);
+ devfs_usecount_add(vp);
+}
+
+void
+devfs_ctty_unref(struct vnode *vp)
+{
+
+ devfs_usecount_sub(vp);
+ vrele(vp);
+}
+
/*
* On success devfs_populate_vp() returns with dmp->dm_lock held.
*/
@@ -487,7 +596,6 @@ loop:
/* XXX: v_rdev should be protect by vnode lock */
vp->v_rdev = dev;
VNPASS(vp->v_usecount == 1, vp);
- dev->si_usecount++;
/* Special casing of ttys for deadfs. Probably redundant. */
dsw = dev->si_devsw;
if (dsw != NULL && (dsw->d_flags & D_TTY) != 0)
@@ -569,6 +677,7 @@ devfs_close(struct vop_close_args *ap)
struct proc *p;
struct cdev *dev = vp->v_rdev;
struct cdevsw *dsw;
+ struct devfs_dirent *de = vp->v_data;
int dflags, error, ref, vp_locked;
/*
@@ -587,7 +696,7 @@ devfs_close(struct vop_close_args *ap)
* if the reference count is 2 (this last descriptor
* plus the session), release the reference from the session.
*/
- if (vp->v_usecount == 2 && td != NULL) {
+ if (de->de_usecount == 2 && td != NULL) {
p = td->td_proc;
PROC_LOCK(p);
if (vp == p->p_session->s_ttyvp) {
@@ -596,19 +705,20 @@ devfs_close(struct vop_close_args *ap)
sx_xlock(&proctree_lock);
if (vp == p->p_session->s_ttyvp) {
SESS_LOCK(p->p_session);
+ mtx_lock(&devfs_de_interlock);
VI_LOCK(vp);
- if (vp->v_usecount == 2 && vcount(vp) == 1 &&
- !VN_IS_DOOMED(vp)) {
+ if (devfs_usecountl(vp) == 2 && !VN_IS_DOOMED(vp)) {
p->p_session->s_ttyvp = NULL;
p->p_session->s_ttydp = NULL;
oldvp = vp;
}
VI_UNLOCK(vp);
+ mtx_unlock(&devfs_de_interlock);
SESS_UNLOCK(p->p_session);
}
sx_xunlock(&proctree_lock);
if (oldvp != NULL)
- vrele(oldvp);
+ devfs_ctty_unref(oldvp);
} else
PROC_UNLOCK(p);
}
@@ -625,9 +735,12 @@ devfs_close(struct vop_close_args *ap)
if (dsw == NULL)
return (ENXIO);
dflags = 0;
+ mtx_lock(&devfs_de_interlock);
VI_LOCK(vp);
- if (vp->v_usecount == 1 && vcount(vp) == 1)
+ if (devfs_usecountl(vp) == 1)
dflags |= FLASTCLOSE;
+ devfs_usecount_subl(vp);
+ mtx_unlock(&devfs_de_interlock);
if (VN_IS_DOOMED(vp)) {
/* Forced close. */
dflags |= FREVOKE | FNONBLOCK;
@@ -850,7 +963,7 @@ devfs_ioctl(struct vop_ioctl_args *ap)
return (0);
}
- vrefact(vp);
+ devfs_ctty_ref(vp);
SESS_LOCK(sess);
vpold = sess->s_ttyvp;
sess->s_ttyvp = vp;
@@ -1159,6 +1272,9 @@ devfs_open(struct vop_open_args *ap)
return (ENXIO);
}
+ if (vp->v_type == VCHR)
+ devfs_usecount_add(vp);
+
vlocked = VOP_ISLOCKED(vp);
VOP_UNLOCK(vp);
@@ -1178,6 +1294,9 @@ devfs_open(struct vop_open_args *ap)
td->td_fpop = fpop;
vn_lock(vp, vlocked | LK_RETRY);
+ if (error != 0 && vp->v_type == VCHR)
+ devfs_usecount_sub(vp);
+
dev_relthread(dev, ref);
if (error != 0) {
if (error == ERESTART)
@@ -1406,19 +1525,28 @@ devfs_readlink(struct vop_readlink_args *ap)
return (uiomove(de->de_symlink, strlen(de->de_symlink), ap->a_uio));
}
-static int
-devfs_reclaim(struct vop_reclaim_args *ap)
+static void
+devfs_reclaiml(struct vnode *vp)
{
- struct vnode *vp;
struct devfs_dirent *de;
- vp = ap->a_vp;
- mtx_lock(&devfs_de_interlock);
+ mtx_assert(&devfs_de_interlock, MA_OWNED);
de = vp->v_data;
if (de != NULL) {
+ MPASS(de->de_usecount == 0);
de->de_vnode = NULL;
vp->v_data = NULL;
}
+}
+
+static int
+devfs_reclaim(struct vop_reclaim_args *ap)
+{
+ struct vnode *vp;
+
+ vp = ap->a_vp;
+ mtx_lock(&devfs_de_interlock);
+ devfs_reclaiml(vp);
mtx_unlock(&devfs_de_interlock);
return (0);
}
@@ -1432,14 +1560,14 @@ devfs_reclaim_vchr(struct vop_reclaim_args *ap)
vp = ap->a_vp;
MPASS(vp->v_type == VCHR);
- devfs_reclaim(ap);
-
+ mtx_lock(&devfs_de_interlock);
VI_LOCK(vp);
+ devfs_usecount_subl(vp);
+ devfs_reclaiml(vp);
+ mtx_unlock(&devfs_de_interlock);
dev_lock();
dev = vp->v_rdev;
vp->v_rdev = NULL;
- if (dev != NULL)
- dev->si_usecount -= (vp->v_usecount > 0);
dev_unlock();
VI_UNLOCK(vp);
if (dev != NULL)
diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h
index 29d5373b5966f..70b2536245ff9 100644
--- a/sys/fs/nfs/nfs.h
+++ b/sys/fs/nfs/nfs.h
@@ -336,6 +336,7 @@ struct nfsreferral {
#define LCL_DONEBINDCONN 0x00040000
#define LCL_RECLAIMONEFS 0x00080000
#define LCL_NFSV42 0x00100000
+#define LCL_TLSCB 0x00200000
#define LCL_GSS LCL_KERBV /* Or of all mechs */
diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c
index 334d46e05c231..79c6067c9866d 100644
--- a/sys/fs/nfs/nfs_commonkrpc.c
+++ b/sys/fs/nfs/nfs_commonkrpc.c
@@ -167,7 +167,7 @@ static int nfsv2_procid[NFS_V3NPROCS] = {
*/
int
newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp,
- struct ucred *cred, NFSPROC_T *p, int callback_retry_mult)
+ struct ucred *cred, NFSPROC_T *p, int callback_retry_mult, bool dotls)
{
int rcvreserve, sndreserve;
int pktscale, pktscalesav;
@@ -374,6 +374,8 @@ newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp,
} else {
retries = NFSV4_CALLBACKRETRY * callback_retry_mult;
}
+ if (dotls)
+ CLNT_CONTROL(client, CLSET_TLS, &one);
}
CLNT_CONTROL(client, CLSET_RETRIES, &retries);
@@ -586,7 +588,7 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp,
* and let clnt_reconnect_create handle reconnects.
*/
if (nrp->nr_client == NULL)
- newnfs_connect(nmp, nrp, cred, td, 0);
+ newnfs_connect(nmp, nrp, cred, td, 0, false);
/*
* For a client side mount, nmp is != NULL and clp == NULL. For
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index d9e03cf7b791c..1fc4e2a4d757f 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -1058,25 +1058,6 @@ nfsaddr2_match(NFSSOCKADDR_T nam1, NFSSOCKADDR_T nam2)
}
/*
- * Trim trailing data off the mbuf list being built.
- */
-void
-newnfs_trimtrailing(nd, mb, bpos)
- struct nfsrv_descript *nd;
- struct mbuf *mb;
- caddr_t bpos;
-{
-
- if (mb->m_next) {
- m_freem(mb->m_next);
- mb->m_next = NULL;
- }
- mb->m_len = bpos - mtod(mb, caddr_t);
- nd->nd_mb = mb;
- nd->nd_bpos = bpos;
-}
-
-/*
* Dissect a file handle on the client.
*/
int
@@ -3650,7 +3631,7 @@ nfsrv_nfsuserdport(struct nfsuserd_args *nargs, NFSPROC_T *p)
}
rp->nr_vers = RPCNFSUSERD_VERS;
if (error == 0)
- error = newnfs_connect(NULL, rp, NFSPROCCRED(p), p, 0);
+ error = newnfs_connect(NULL, rp, NFSPROCCRED(p), p, 0, false);
if (error == 0) {
NFSLOCKNAMEID();
nfsrv_nfsuserd = RUNNING;
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index 7bf89011d2fde..695c72f74ad37 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -324,8 +324,6 @@ int nfsm_mbufuio(struct nfsrv_descript *, struct uio *, int);
int nfsm_fhtom(struct nfsrv_descript *, u_int8_t *, int, int);
int nfsm_advance(struct nfsrv_descript *, int, int);
void *nfsm_dissct(struct nfsrv_descript *, int, int);
-void newnfs_trimtrailing(struct nfsrv_descript *, struct mbuf *,
- caddr_t);
void newnfs_copycred(struct nfscred *, struct ucred *);
void newnfs_copyincred(struct ucred *, struct nfscred *);
int nfsrv_dissectacl(struct nfsrv_descript *, NFSACL_T *, int *,
@@ -766,7 +764,7 @@ int newnfs_request(struct nfsrv_descript *, struct nfsmount *,
struct ucred *, u_int32_t, u_int32_t, u_char *, int, u_int64_t *,
struct nfsclsession *);
int newnfs_connect(struct nfsmount *, struct nfssockreq *,
- struct ucred *, NFSPROC_T *, int);
+ struct ucred *, NFSPROC_T *, int, bool);
void newnfs_disconnect(struct nfssockreq *);
int newnfs_sigintr(struct nfsmount *, NFSPROC_T *);
diff --git a/sys/fs/nfsclient/nfs_clcomsubs.c b/sys/fs/nfsclient/nfs_clcomsubs.c
index f4a6b8dfa90be..b93facfbe2648 100644
--- a/sys/fs/nfsclient/nfs_clcomsubs.c
+++ b/sys/fs/nfsclient/nfs_clcomsubs.c
@@ -92,7 +92,7 @@ nfsm_uiombuf(struct nfsrv_descript *nd, struct uio *uiop, int siz)
nd->nd_maxextsiz, &nd->nd_bextpg);
mcp = (char *)(void *)PHYS_TO_DMAP(
mp->m_epg_pa[nd->nd_bextpg]);
- nd->nd_bextpgsiz = PAGE_SIZE;
+ nd->nd_bextpgsiz = mlen = PAGE_SIZE;
} else {
if (clflg)
NFSMCLGET(mp, M_WAITOK);
diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index 33065249315f1..f64615df7f8f6 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -5617,7 +5617,7 @@ nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_in *sin,
* unmount, but I did it anyhow.
*/
nrp->nr_cred = crhold(nmp->nm_sockreq.nr_cred);
- error = newnfs_connect(nmp, nrp, NULL, p, 0);
+ error = newnfs_connect(nmp, nrp, NULL, p, 0, false);
NFSCL_DEBUG(3, "DS connect=%d\n", error);
dsp = NULL;
diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c
index 7124c10573fa5..e97d42f4a3811 100644
--- a/sys/fs/nfsclient/nfs_clvfsops.c
+++ b/sys/fs/nfsclient/nfs_clvfsops.c
@@ -718,7 +718,7 @@ nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
nmp->nm_soproto = argp->proto;
if (nmp->nm_sotype == SOCK_DGRAM)
while (newnfs_connect(nmp, &nmp->nm_sockreq,
- cred, td, 0)) {
+ cred, td, 0, false)) {
printf("newnfs_args: retrying connect\n");
(void) nfs_catnap(PSOCK, 0, "nfscon");
}
@@ -1527,7 +1527,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
nmp->nm_sockreq.nr_vers = NFS_VER2;
- if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0)))
+ if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0, false)))
goto bad;
/* For NFSv4.1, get the clientid now. */
if (nmp->nm_minorvers > 0) {
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 5d15c68c4eadb..68216a6f50f5c 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -4423,6 +4423,7 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp,
u_int32_t callback;
struct nfsdsession *sep = NULL;
uint64_t tval;
+ bool dotls;
nd = malloc(sizeof(*nd), M_TEMP, M_WAITOK | M_ZERO);
cred = newnfs_getcred();
@@ -4547,6 +4548,9 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp,
/*
* Call newnfs_connect(), as required, and then newnfs_request().
*/
+ dotls = false;
+ if ((clp->lc_flags & LCL_TLSCB) != 0)
+ dotls = true;
(void) newnfs_sndlock(&clp->lc_req.nr_lock);
if (clp->lc_req.nr_client == NULL) {
if ((clp->lc_flags & LCL_NFSV41) != 0) {
@@ -4554,10 +4558,10 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp,
nfsrv_freesession(sep, NULL);
} else if (nd->nd_procnum == NFSV4PROC_CBNULL)
error = newnfs_connect(NULL, &clp->lc_req, cred,
- NULL, 1);
+ NULL, 1, dotls);
else
error = newnfs_connect(NULL, &clp->lc_req, cred,
- NULL, 3);
+ NULL, 3, dotls);
}
newnfs_sndunlock(&clp->lc_req.nr_lock);
NFSD_DEBUG(4, "aft sndunlock=%d\n", error);
diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c
index cbaf992052a8f..2d14081c0e3c9 100644
--- a/sys/kern/kern_conf.c
+++ b/sys/kern/kern_conf.c
@@ -88,7 +88,7 @@ dev_unlock_and_free(void)
struct cdev_priv *cdp;
struct cdevsw *csw;
- mtx_assert(&devmtx, MA_OWNED);
+ dev_lock_assert_locked();
/*
* Make the local copy of the list heads while the dev_mtx is
@@ -116,7 +116,7 @@ dev_free_devlocked(struct cdev *cdev)
{
struct cdev_priv *cdp;
- mtx_assert(&devmtx, MA_OWNED);
+ dev_lock_assert_locked();
cdp = cdev2priv(cdev);
KASSERT((cdp->cdp_flags & CDP_UNREF_DTR) == 0,
("destroy_dev() was not called after delist_dev(%p)", cdev));
@@ -127,7 +127,7 @@ static void
cdevsw_free_devlocked(struct cdevsw *csw)
{
- mtx_assert(&devmtx, MA_OWNED);
+ dev_lock_assert_locked();
SLIST_INSERT_HEAD(&cdevsw_gt_post_list, csw, d_postfree_list);
}
@@ -142,7 +142,7 @@ void
dev_ref(struct cdev *dev)
{
- mtx_assert(&devmtx, MA_NOTOWNED);
+ dev_lock_assert_unlocked();
mtx_lock(&devmtx);
dev->si_refcount++;
mtx_unlock(&devmtx);
@@ -152,7 +152,7 @@ void
dev_refl(struct cdev *dev)
{
- mtx_assert(&devmtx, MA_OWNED);
+ dev_lock_assert_locked();
dev->si_refcount++;
}
@@ -161,7 +161,7 @@ dev_rel(struct cdev *dev)
{
int flag = 0;
- mtx_assert(&devmtx, MA_NOTOWNED);
+ dev_lock_assert_unlocked();
dev_lock();
dev->si_refcount--;
KASSERT(dev->si_refcount >= 0,
@@ -181,7 +181,7 @@ dev_refthread(struct cdev *dev, int *ref)
struct cdevsw *csw;
struct cdev_priv *cdp;
- mtx_assert(&devmtx, MA_NOTOWNED);
+ dev_lock_assert_unlocked();
if ((dev->si_flags & SI_ETERNAL) != 0) {
*ref = 0;
return (dev->si_devsw);
@@ -208,7 +208,7 @@ devvn_refthread(struct vnode *vp, struct cdev **devp, int *ref)
struct cdev_priv *cdp;
struct cdev *dev;
- mtx_assert(&devmtx, MA_NOTOWNED);
+ dev_lock_assert_unlocked();
if ((vp->v_vflag & VV_ETERNALDEV) != 0) {
dev = vp->v_rdev;
if (dev == NULL)
@@ -249,7 +249,7 @@ void
dev_relthread(struct cdev *dev, int ref)
{
- mtx_assert(&devmtx, MA_NOTOWNED);
+ dev_lock_assert_unlocked();
if (!ref)
return;
KASSERT(dev->si_threadcount > 0,
@@ -570,7 +570,7 @@ newdev(struct make_dev_args *args, struct cdev *si)
struct cdev *si2;
struct cdevsw *csw;
- mtx_assert(&devmtx, MA_OWNED);
+ dev_lock_assert_locked();
csw = args->mda_devsw;
si2 = NULL;
if (csw->d_flags & D_NEEDMINOR) {
@@ -629,7 +629,7 @@ prep_cdevsw(struct cdevsw *devsw, int flags)
{
struct cdevsw *dsw2;
- mtx_assert(&devmtx, MA_OWNED);
+ dev_lock_assert_locked();
if (devsw->d_flags & D_INIT)
return (0);
if (devsw->d_flags & D_NEEDGIANT) {
@@ -714,7 +714,7 @@ prep_devname(struct cdev *dev, const char *fmt, va_list ap)
int len;
char *from, *q, *s, *to;
- mtx_assert(&devmtx, MA_OWNED);
+ dev_lock_assert_locked();
len = vsnrprintf(dev->si_name, sizeof(dev->si_name), 32, fmt, ap);
if (len > sizeof(dev->si_name) - 1)
@@ -1098,7 +1098,7 @@ destroy_devl(struct cdev *dev)
struct cdev_privdata *p;
struct cdev_priv *cdp;
- mtx_assert(&devmtx, MA_OWNED);
+ dev_lock_assert_locked();
KASSERT(dev->si_flags & SI_NAMED,
("WARNING: Driver mistake: destroy_dev on %d\n", dev2unit(dev)));
KASSERT((dev->si_flags & SI_ETERNAL) == 0,
@@ -1200,7 +1200,7 @@ delist_dev_locked(struct cdev *dev)
struct cdev_priv *cdp;
struct cdev *child;
- mtx_assert(&devmtx, MA_OWNED);
+ dev_lock_assert_locked();
cdp = cdev2priv(dev);
if ((cdp->cdp_flags & CDP_UNREF_DTR) != 0)
return;
@@ -1464,7 +1464,7 @@ destroy_dev_sched_cbl(struct cdev *dev, void (*cb)(void *), void *arg)
{
struct cdev_priv *cp;
- mtx_assert(&devmtx, MA_OWNED);
+ dev_lock_assert_locked();
cp = cdev2priv(dev);
if (cp->cdp_flags & CDP_SCHED_DTR) {
dev_unlock();
diff --git a/sys/kern/kern_environment.c b/sys/kern/kern_environment.c
index 312440ab509ef..f906f3c6c8387 100644
--- a/sys/kern/kern_environment.c
+++ b/sys/kern/kern_environment.c
@@ -59,6 +59,9 @@ __FBSDID("$FreeBSD$");
static char *_getenv_dynamic_locked(const char *name, int *idx);
static char *_getenv_dynamic(const char *name, int *idx);
+static char *kenv_acquire(const char *name);
+static void kenv_release(const char *buf);
+
static MALLOC_DEFINE(M_KENV, "kenv", "kernel environment");
#define KENV_SIZE 512 /* Maximum number of environment strings */
@@ -88,8 +91,6 @@ bool dynamic_kenv;
#define KENV_CHECK if (!dynamic_kenv) \
panic("%s: called before SI_SUB_KMEM", __func__)
-static char *getenv_string_buffer(const char *);
-
int
sys_kenv(td, uap)
struct thread *td;
@@ -482,16 +483,24 @@ _getenv_static(const char *name)
char *
kern_getenv(const char *name)
{
- char *ret;
+ char *cp, *ret;
+ int len;
if (dynamic_kenv) {
- ret = getenv_string_buffer(name);
- if (ret == NULL) {
- WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
- "getenv");
+ len = KENV_MNAMELEN + 1 + kenv_mvallen + 1;
+ ret = uma_zalloc(kenv_zone, M_WAITOK | M_ZERO);
+ mtx_lock(&kenv_lock);
+ cp = _getenv_dynamic(name, NULL);
+ if (cp != NULL)
+ strlcpy(ret, cp, len);
+ mtx_unlock(&kenv_lock);
+ if (cp == NULL) {
+ uma_zfree(kenv_zone, ret);
+ ret = NULL;
}
} else
ret = _getenv_static(name);
+
return (ret);
}
@@ -503,12 +512,9 @@ testenv(const char *name)
{
char *cp;
- if (dynamic_kenv) {
- mtx_lock(&kenv_lock);
- cp = _getenv_dynamic(name, NULL);
- mtx_unlock(&kenv_lock);
- } else
- cp = _getenv_static(name);
+ cp = kenv_acquire(name);
+ kenv_release(cp);
+
if (cp != NULL)
return (1);
return (0);
@@ -615,30 +621,33 @@ kern_unsetenv(const char *name)
}
/*
- * Return a buffer containing the string value from an environment variable
+ * Return the internal kenv buffer for the variable name, if it exists.
+ * If the dynamic kenv is initialized and the name is present, return
+ * with kenv_lock held.
*/
static char *
-getenv_string_buffer(const char *name)
+kenv_acquire(const char *name)
{
- char *cp, *ret;
- int len;
+ char *value;
if (dynamic_kenv) {
- len = KENV_MNAMELEN + 1 + kenv_mvallen + 1;
- ret = uma_zalloc(kenv_zone, M_WAITOK | M_ZERO);
mtx_lock(&kenv_lock);
- cp = _getenv_dynamic(name, NULL);
- if (cp != NULL)
- strlcpy(ret, cp, len);
- mtx_unlock(&kenv_lock);
- if (cp == NULL) {
- uma_zfree(kenv_zone, ret);
- ret = NULL;
- }
+ value = _getenv_dynamic(name, NULL);
+ if (value == NULL)
+ mtx_unlock(&kenv_lock);
+ return (value);
} else
- ret = _getenv_static(name);
+ return (_getenv_static(name));
+}
- return (ret);
+/*
+ * Undo a previous kenv_acquire() operation
+ */
+static void
+kenv_release(const char *buf)
+{
+ if ((buf != NULL) && dynamic_kenv)
+ mtx_unlock(&kenv_lock);
}
/*
@@ -649,17 +658,13 @@ getenv_string(const char *name, char *data, int size)
{
char *cp;
- if (dynamic_kenv) {
- mtx_lock(&kenv_lock);
- cp = _getenv_dynamic(name, NULL);
- if (cp != NULL)
- strlcpy(data, cp, size);
- mtx_unlock(&kenv_lock);
- } else {
- cp = _getenv_static(name);
- if (cp != NULL)
- strlcpy(data, cp, size);
- }
+ cp = kenv_acquire(name);
+
+ if (cp != NULL)
+ strlcpy(data, cp, size);
+
+ kenv_release(cp);
+
return (cp != NULL);
}
@@ -673,16 +678,18 @@ getenv_array(const char *name, void *pdata, int size, int *psize,
uint8_t shift;
int64_t value;
int64_t old;
- char *buf;
+ const char *buf;
char *end;
- char *ptr;
+ const char *ptr;
int n;
int rc;
- if ((buf = getenv_string_buffer(name)) == NULL)
- return (0);
-
rc = 0; /* assume failure */
+
+ buf = kenv_acquire(name);
+ if (buf == NULL)
+ goto error;
+
/* get maximum number of elements */
size /= type_size;
@@ -797,8 +804,7 @@ getenv_array(const char *name, void *pdata, int size, int *psize,
if (n != 0)
rc = 1; /* success */
error:
- if (dynamic_kenv)
- uma_zfree(kenv_zone, buf);
+ kenv_release(buf);
return (rc);
}
@@ -898,18 +904,21 @@ getenv_ulong(const char *name, unsigned long *data)
int
getenv_quad(const char *name, quad_t *data)
{
- char *value, *vtp;
- quad_t iv;
+ const char *value;
+ char suffix, *vtp;
+ quad_t iv;
- value = getenv_string_buffer(name);
- if (value == NULL)
- return (0);
+ value = kenv_acquire(name);
+ if (value == NULL) {
+ goto error;
+ }
iv = strtoq(value, &vtp, 0);
if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) {
- freeenv(value);
- return (0);
+ goto error;
}
- switch (vtp[0]) {
+ suffix = vtp[0];
+ kenv_release(value);
+ switch (suffix) {
case 't': case 'T':
iv *= 1024;
/* FALLTHROUGH */
@@ -924,12 +933,13 @@ getenv_quad(const char *name, quad_t *data)
case '\0':
break;
default:
- freeenv(value);
return (0);
}
- freeenv(value);
*data = iv;
return (1);
+error:
+ kenv_release(value);
+ return (0);
}
/*
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index ce9554b6dfaa0..50449938c5c16 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -88,6 +88,8 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_page.h>
#include <vm/uma.h>
+#include <fs/devfs/devfs.h>
+
#ifdef COMPAT_FREEBSD32
#include <compat/freebsd32/freebsd32.h>
#include <compat/freebsd32/freebsd32_util.h>
@@ -858,7 +860,7 @@ killjobc(void)
VOP_REVOKE(ttyvp, REVOKEALL);
VOP_UNLOCK(ttyvp);
}
- vrele(ttyvp);
+ devfs_ctty_unref(ttyvp);
sx_xlock(&proctree_lock);
}
}
diff --git a/sys/kern/subr_prng.c b/sys/kern/subr_prng.c
new file mode 100644
index 0000000000000..124a56e0e4ea8
--- /dev/null
+++ b/sys/kern/subr_prng.c
@@ -0,0 +1,131 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright 2020 Conrad Meyer <cem@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, 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/pcpu.h>
+#include <sys/prng.h>
+#include <sys/smp.h>
+#include <sys/systm.h>
+
+#if !PCG_HAS_128BIT_OPS
+/* On 32-bit platforms, gang together two 32-bit generators. */
+typedef struct {
+ pcg32u_random_t states[2];
+} pcg64u_random_t;
+
+static inline void
+pcg64u_srandom_r(pcg64u_random_t *state64, uint64_t seed)
+{
+ pcg32u_srandom_r(&state64->states[0], seed);
+ pcg32u_srandom_r(&state64->states[1], seed);
+}
+
+static inline uint64_t
+pcg64u_random_r(pcg64u_random_t *state64)
+{
+ return ((((uint64_t)pcg32u_random_r(&state64->states[0])) << 32) |
+ pcg32u_random_r(&state64->states[1]));
+}
+
+static inline uint64_t
+pcg64u_boundedrand_r(pcg64u_random_t *state64, uint64_t bound)
+{
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg64u_random_r(state64);
+ if (r >= threshold)
+ return (r % bound);
+ }
+}
+#endif
+
+DPCPU_DEFINE_STATIC(pcg32u_random_t, pcpu_prng32_state);
+DPCPU_DEFINE_STATIC(pcg64u_random_t, pcpu_prng64_state);
+
+static void
+prng_init(void *dummy __unused)
+{
+ pcg32u_random_t *state;
+ pcg64u_random_t *state64;
+ int i;
+
+ CPU_FOREACH(i) {
+ state = DPCPU_ID_PTR(i, pcpu_prng32_state);
+ pcg32u_srandom_r(state, 1);
+ state64 = DPCPU_ID_PTR(i, pcpu_prng64_state);
+ pcg64u_srandom_r(state64, 1);
+ }
+}
+SYSINIT(prng_init, SI_SUB_CPU, SI_ORDER_ANY, prng_init, NULL);
+
+uint32_t
+prng32(void)
+{
+ uint32_t r;
+
+ critical_enter();
+ r = pcg32u_random_r(DPCPU_PTR(pcpu_prng32_state));
+ critical_exit();
+ return (r);
+}
+
+uint32_t
+prng32_bounded(uint32_t bound)
+{
+ uint32_t r;
+
+ critical_enter();
+ r = pcg32u_boundedrand_r(DPCPU_PTR(pcpu_prng32_state), bound);
+ critical_exit();
+ return (r);
+}
+
+uint64_t
+prng64(void)
+{
+ uint64_t r;
+
+ critical_enter();
+ r = pcg64u_random_r(DPCPU_PTR(pcpu_prng64_state));
+ critical_exit();
+ return (r);
+}
+
+uint64_t
+prng64_bounded(uint64_t bound)
+{
+ uint64_t r;
+
+ critical_enter();
+ r = pcg64u_boundedrand_r(DPCPU_PTR(pcpu_prng64_state), bound);
+ critical_exit();
+ return (r);
+}
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index a19b6efb02717..ad390e0a0c985 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -749,19 +749,19 @@ pipe_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
/*
* Direct copy, bypassing a kernel buffer.
*/
- } else if ((size = rpipe->pipe_map.cnt) != 0) {
+ } else if ((size = rpipe->pipe_pages.cnt) != 0) {
if (size > uio->uio_resid)
size = (u_int) uio->uio_resid;
PIPE_UNLOCK(rpipe);
- error = uiomove_fromphys(rpipe->pipe_map.ms,
- rpipe->pipe_map.pos, size, uio);
+ error = uiomove_fromphys(rpipe->pipe_pages.ms,
+ rpipe->pipe_pages.pos, size, uio);
PIPE_LOCK(rpipe);
if (error)
break;
nread += size;
- rpipe->pipe_map.pos += size;
- rpipe->pipe_map.cnt -= size;
- if (rpipe->pipe_map.cnt == 0) {
+ rpipe->pipe_pages.pos += size;
+ rpipe->pipe_pages.cnt -= size;
+ if (rpipe->pipe_pages.cnt == 0) {
rpipe->pipe_state &= ~PIPE_WANTW;
wakeup(rpipe);
}
@@ -865,7 +865,7 @@ pipe_build_write_buffer(struct pipe *wpipe, struct uio *uio)
PIPE_LOCK_ASSERT(wpipe, MA_OWNED);
KASSERT((wpipe->pipe_state & PIPE_DIRECTW) == 0,
("%s: PIPE_DIRECTW set on %p", __func__, wpipe));
- KASSERT(wpipe->pipe_map.cnt == 0,
+ KASSERT(wpipe->pipe_pages.cnt == 0,
("%s: pipe map for %p contains residual data", __func__, wpipe));
if (uio->uio_iov->iov_len > wpipe->pipe_buffer.size)
@@ -877,17 +877,17 @@ pipe_build_write_buffer(struct pipe *wpipe, struct uio *uio)
PIPE_UNLOCK(wpipe);
i = vm_fault_quick_hold_pages(&curproc->p_vmspace->vm_map,
(vm_offset_t)uio->uio_iov->iov_base, size, VM_PROT_READ,
- wpipe->pipe_map.ms, PIPENPAGES);
+ wpipe->pipe_pages.ms, PIPENPAGES);
PIPE_LOCK(wpipe);
if (i < 0) {
wpipe->pipe_state &= ~PIPE_DIRECTW;
return (EFAULT);
}
- wpipe->pipe_map.npages = i;
- wpipe->pipe_map.pos =
+ wpipe->pipe_pages.npages = i;
+ wpipe->pipe_pages.pos =
((vm_offset_t) uio->uio_iov->iov_base) & PAGE_MASK;
- wpipe->pipe_map.cnt = size;
+ wpipe->pipe_pages.cnt = size;
uio->uio_iov->iov_len -= size;
uio->uio_iov->iov_base = (char *)uio->uio_iov->iov_base + size;
@@ -908,12 +908,12 @@ pipe_destroy_write_buffer(struct pipe *wpipe)
PIPE_LOCK_ASSERT(wpipe, MA_OWNED);
KASSERT((wpipe->pipe_state & PIPE_DIRECTW) != 0,
("%s: PIPE_DIRECTW not set on %p", __func__, wpipe));
- KASSERT(wpipe->pipe_map.cnt == 0,
+ KASSERT(wpipe->pipe_pages.cnt == 0,
("%s: pipe map for %p contains residual data", __func__, wpipe));
wpipe->pipe_state &= ~PIPE_DIRECTW;
- vm_page_unhold_pages(wpipe->pipe_map.ms, wpipe->pipe_map.npages);
- wpipe->pipe_map.npages = 0;
+ vm_page_unhold_pages(wpipe->pipe_pages.ms, wpipe->pipe_pages.npages);
+ wpipe->pipe_pages.npages = 0;
}
/*
@@ -933,9 +933,9 @@ pipe_clone_write_buffer(struct pipe *wpipe)
KASSERT((wpipe->pipe_state & PIPE_DIRECTW) != 0,
("%s: PIPE_DIRECTW not set on %p", __func__, wpipe));
- size = wpipe->pipe_map.cnt;
- pos = wpipe->pipe_map.pos;
- wpipe->pipe_map.cnt = 0;
+ size = wpipe->pipe_pages.cnt;
+ pos = wpipe->pipe_pages.pos;
+ wpipe->pipe_pages.cnt = 0;
wpipe->pipe_buffer.in = size;
wpipe->pipe_buffer.out = 0;
@@ -951,7 +951,7 @@ pipe_clone_write_buffer(struct pipe *wpipe)
uio.uio_segflg = UIO_SYSSPACE;
uio.uio_rw = UIO_READ;
uio.uio_td = curthread;
- uiomove_fromphys(wpipe->pipe_map.ms, pos, size, &uio);
+ uiomove_fromphys(wpipe->pipe_pages.ms, pos, size, &uio);
PIPE_LOCK(wpipe);
pipe_destroy_write_buffer(wpipe);
}
@@ -1015,7 +1015,7 @@ retry:
goto error1;
}
- while (wpipe->pipe_map.cnt != 0 &&
+ while (wpipe->pipe_pages.cnt != 0 &&
(wpipe->pipe_state & PIPE_EOF) == 0) {
if (wpipe->pipe_state & PIPE_WANTR) {
wpipe->pipe_state &= ~PIPE_WANTR;
@@ -1032,7 +1032,7 @@ retry:
}
if ((wpipe->pipe_state & PIPE_EOF) != 0) {
- wpipe->pipe_map.cnt = 0;
+ wpipe->pipe_pages.cnt = 0;
pipe_destroy_write_buffer(wpipe);
pipeselwakeup(wpipe);
error = EPIPE;
@@ -1157,7 +1157,7 @@ pipe_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
* pipe buffer. We break out if a signal occurs or the
* reader goes away.
*/
- if (wpipe->pipe_map.cnt != 0) {
+ if (wpipe->pipe_pages.cnt != 0) {
if (wpipe->pipe_state & PIPE_WANTR) {
wpipe->pipe_state &= ~PIPE_WANTR;
wakeup(wpipe);
@@ -1375,8 +1375,8 @@ pipe_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *active_cred,
PIPE_UNLOCK(mpipe);
return (0);
}
- if (mpipe->pipe_map.cnt != 0)
- *(int *)data = mpipe->pipe_map.cnt;
+ if (mpipe->pipe_pages.cnt != 0)
+ *(int *)data = mpipe->pipe_pages.cnt;
else
*(int *)data = mpipe->pipe_buffer.cnt;
break;
@@ -1431,7 +1431,7 @@ pipe_poll(struct file *fp, int events, struct ucred *active_cred,
goto locked_error;
#endif
if (fp->f_flag & FREAD && events & (POLLIN | POLLRDNORM))
- if (rpipe->pipe_map.cnt > 0 || rpipe->pipe_buffer.cnt > 0)
+ if (rpipe->pipe_pages.cnt > 0 || rpipe->pipe_buffer.cnt > 0)
revents |= events & (POLLIN | POLLRDNORM);
if (fp->f_flag & FWRITE && events & (POLLOUT | POLLWRNORM))
@@ -1513,8 +1513,8 @@ pipe_stat(struct file *fp, struct stat *ub, struct ucred *active_cred,
bzero(ub, sizeof(*ub));
ub->st_mode = S_IFIFO;
ub->st_blksize = PAGE_SIZE;
- if (pipe->pipe_map.cnt != 0)
- ub->st_size = pipe->pipe_map.cnt;
+ if (pipe->pipe_pages.cnt != 0)
+ ub->st_size = pipe->pipe_pages.cnt;
else
ub->st_size = pipe->pipe_buffer.cnt;
ub->st_blocks = howmany(ub->st_size, ub->st_blksize);
@@ -1604,9 +1604,9 @@ pipe_free_kmem(struct pipe *cpipe)
}
#ifndef PIPE_NODIRECT
{
- cpipe->pipe_map.cnt = 0;
- cpipe->pipe_map.pos = 0;
- cpipe->pipe_map.npages = 0;
+ cpipe->pipe_pages.cnt = 0;
+ cpipe->pipe_pages.pos = 0;
+ cpipe->pipe_pages.npages = 0;
}
#endif
}
@@ -1752,7 +1752,7 @@ filt_piperead(struct knote *kn, long hint)
PIPE_LOCK_ASSERT(rpipe, MA_OWNED);
kn->kn_data = rpipe->pipe_buffer.cnt;
if (kn->kn_data == 0)
- kn->kn_data = rpipe->pipe_map.cnt;
+ kn->kn_data = rpipe->pipe_pages.cnt;
if ((rpipe->pipe_state & PIPE_EOF) != 0 &&
((rpipe->pipe_state & PIPE_NAMED) == 0 ||
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index 4c11ff56000b0..a6ed98f86297f 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -67,6 +67,8 @@ __FBSDID("$FreeBSD$");
#include <sys/ucred.h>
#include <sys/vnode.h>
+#include <fs/devfs/devfs.h>
+
#include <machine/stdarg.h>
static MALLOC_DEFINE(M_TTY, "tty", "tty device");
@@ -1256,7 +1258,7 @@ tty_drop_ctty(struct tty *tp, struct proc *p)
* is either changed or released.
*/
if (vp != NULL)
- vrele(vp);
+ devfs_ctty_unref(vp);
return (0);
}
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index e78fc25ec3431..43b36dccb028a 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -61,6 +61,9 @@ __FBSDID("$FreeBSD$");
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
+#ifdef INVARIANTS
+#include <machine/_inttypes.h>
+#endif
#include <security/audit/audit.h>
#include <security/mac/mac_framework.h>
@@ -70,7 +73,7 @@ __FBSDID("$FreeBSD$");
#define NAMEI_DIAGNOSTIC 1
#undef NAMEI_DIAGNOSTIC
-SDT_PROVIDER_DECLARE(vfs);
+SDT_PROVIDER_DEFINE(vfs);
SDT_PROBE_DEFINE4(vfs, namei, lookup, entry, "struct vnode *", "char *",
"unsigned long", "bool");
SDT_PROBE_DEFINE3(vfs, namei, lookup, return, "int", "struct vnode *", "bool");
@@ -428,6 +431,7 @@ namei_setup(struct nameidata *ndp, struct vnode **dpp, struct pwd **pwdp)
if (error != 0) {
if (*dpp != NULL)
vrele(*dpp);
+ pwd_drop(pwd);
return (error);
}
MPASS((ndp->ni_lcf & (NI_LCF_BENEATH_ABS | NI_LCF_LATCH)) !=
@@ -484,15 +488,15 @@ namei(struct nameidata *ndp)
("namei: nameiop contaminated with flags"));
KASSERT((cnp->cn_flags & OPMASK) == 0,
("namei: flags contaminated with nameiops"));
+ KASSERT((cnp->cn_flags & NAMEI_INTERNAL_FLAGS) == 0,
+ ("namei: unexpected flags: %" PRIx64 "\n",
+ cnp->cn_flags & NAMEI_INTERNAL_FLAGS));
if (cnp->cn_flags & NOCACHE)
KASSERT(cnp->cn_nameiop != LOOKUP,
("%s: NOCACHE passed with LOOKUP", __func__));
MPASS(ndp->ni_startdir == NULL || ndp->ni_startdir->v_type == VDIR ||
ndp->ni_startdir->v_type == VBAD);
- /* We will set this ourselves if we need it. */
- cnp->cn_flags &= ~TRAILINGSLASH;
-
ndp->ni_lcf = 0;
ndp->ni_vp = NULL;
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 4df6be9ace716..03bfa129b16c3 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -108,8 +108,6 @@ static int flushbuflist(struct bufv *bufv, int flags, struct bufobj *bo,
static void syncer_shutdown(void *arg, int howto);
static int vtryrecycle(struct vnode *vp);
static void v_init_counters(struct vnode *);
-static void v_incr_devcount(struct vnode *);
-static void v_decr_devcount(struct vnode *);
static void vgonel(struct vnode *);
static void vfs_knllock(void *arg);
static void vfs_knlunlock(void *arg);
@@ -2794,59 +2792,6 @@ v_init_counters(struct vnode *vp)
}
/*
- * Increment si_usecount of the associated device, if any.
- */
-static void
-v_incr_devcount(struct vnode *vp)
-{
-
- ASSERT_VI_LOCKED(vp, __FUNCTION__);
- if (vp->v_type == VCHR && vp->v_rdev != NULL) {
- dev_lock();
- vp->v_rdev->si_usecount++;
- dev_unlock();
- }
-}
-
-/*
- * Decrement si_usecount of the associated device, if any.
- *
- * The caller is required to hold the interlock when transitioning a VCHR use
- * count to zero. This prevents a race with devfs_reclaim_vchr() that would
- * leak a si_usecount reference. The vnode lock will also prevent this race
- * if it is held while dropping the last ref.
- *
- * The race is:
- *
- * CPU1 CPU2
- * devfs_reclaim_vchr
- * make v_usecount == 0
- * VI_LOCK
- * sees v_usecount == 0, no updates
- * vp->v_rdev = NULL;
- * ...
- * VI_UNLOCK
- * VI_LOCK
- * v_decr_devcount
- * sees v_rdev == NULL, no updates
- *
- * In this scenario si_devcount decrement is not performed.
- */
-static void
-v_decr_devcount(struct vnode *vp)
-{
-
- ASSERT_VOP_LOCKED(vp, __func__);
- ASSERT_VI_LOCKED(vp, __FUNCTION__);
- if (vp->v_type == VCHR && vp->v_rdev != NULL) {
- dev_lock();
- VNPASS(vp->v_rdev->si_usecount > 0, vp);
- vp->v_rdev->si_usecount--;
- dev_unlock();
- }
-}
-
-/*
* Grab a particular vnode from the free list, increment its
* reference count and lock it. VIRF_DOOMED is set if the vnode
* is being destroyed. Only callers who specify LK_RETRY will
@@ -2921,41 +2866,6 @@ vget(struct vnode *vp, int flags, struct thread *td)
return (vget_finish(vp, flags, vs));
}
-static void __noinline
-vget_finish_vchr(struct vnode *vp)
-{
-
- VNASSERT(vp->v_type == VCHR, vp, ("type != VCHR)"));
-
- /*
- * See the comment in vget_finish before usecount bump.
- */
- if (refcount_acquire_if_not_zero(&vp->v_usecount)) {
-#ifdef INVARIANTS
- int old = atomic_fetchadd_int(&vp->v_holdcnt, -1);
- VNASSERT(old > 0, vp, ("%s: wrong hold count %d", __func__, old));
-#else
- refcount_release(&vp->v_holdcnt);
-#endif
- return;
- }
-
- VI_LOCK(vp);
- if (refcount_acquire_if_not_zero(&vp->v_usecount)) {
-#ifdef INVARIANTS
- int old = atomic_fetchadd_int(&vp->v_holdcnt, -1);
- VNASSERT(old > 1, vp, ("%s: wrong hold count %d", __func__, old));
-#else
- refcount_release(&vp->v_holdcnt);
-#endif
- VI_UNLOCK(vp);
- return;
- }
- v_incr_devcount(vp);
- refcount_acquire(&vp->v_usecount);
- VI_UNLOCK(vp);
-}
-
int
vget_finish(struct vnode *vp, int flags, enum vgetstate vs)
{
@@ -2993,11 +2903,6 @@ vget_finish_ref(struct vnode *vp, enum vgetstate vs)
if (vs == VGET_USECOUNT)
return;
- if (__predict_false(vp->v_type == VCHR)) {
- vget_finish_vchr(vp);
- return;
- }
-
/*
* We hold the vnode. If the usecount is 0 it will be utilized to keep
* the vnode around. Otherwise someone else lended their hold count and
@@ -3015,85 +2920,14 @@ vget_finish_ref(struct vnode *vp, enum vgetstate vs)
}
}
-/*
- * Increase the reference (use) and hold count of a vnode.
- * This will also remove the vnode from the free list if it is presently free.
- */
-static void __noinline
-vref_vchr(struct vnode *vp, bool interlock)
-{
-
- /*
- * See the comment in vget_finish before usecount bump.
- */
- if (!interlock) {
- if (refcount_acquire_if_not_zero(&vp->v_usecount)) {
- VNODE_REFCOUNT_FENCE_ACQ();
- VNASSERT(vp->v_holdcnt > 0, vp,
- ("%s: active vnode not held", __func__));
- return;
- }
- VI_LOCK(vp);
- /*
- * By the time we get here the vnode might have been doomed, at
- * which point the 0->1 use count transition is no longer
- * protected by the interlock. Since it can't bounce back to
- * VCHR and requires vref semantics, punt it back
- */
- if (__predict_false(vp->v_type == VBAD)) {
- VI_UNLOCK(vp);
- vref(vp);
- return;
- }
- }
- VNASSERT(vp->v_type == VCHR, vp, ("type != VCHR)"));
- if (refcount_acquire_if_not_zero(&vp->v_usecount)) {
- VNODE_REFCOUNT_FENCE_ACQ();
- VNASSERT(vp->v_holdcnt > 0, vp,
- ("%s: active vnode not held", __func__));
- if (!interlock)
- VI_UNLOCK(vp);
- return;
- }
- vhold(vp);
- v_incr_devcount(vp);
- refcount_acquire(&vp->v_usecount);
- if (!interlock)
- VI_UNLOCK(vp);
- return;
-}
-
void
vref(struct vnode *vp)
{
- int old;
+ enum vgetstate vs;
CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
- if (__predict_false(vp->v_type == VCHR)) {
- vref_vchr(vp, false);
- return;
- }
-
- if (refcount_acquire_if_not_zero(&vp->v_usecount)) {
- VNODE_REFCOUNT_FENCE_ACQ();
- VNASSERT(vp->v_holdcnt > 0, vp,
- ("%s: active vnode not held", __func__));
- return;
- }
- vhold(vp);
- /*
- * See the comment in vget_finish.
- */
- old = atomic_fetchadd_int(&vp->v_usecount, 1);
- VNASSERT(old >= 0, vp, ("%s: wrong use count %d", __func__, old));
- if (old != 0) {
-#ifdef INVARIANTS
- old = atomic_fetchadd_int(&vp->v_holdcnt, -1);
- VNASSERT(old > 1, vp, ("%s: wrong hold count %d", __func__, old));
-#else
- refcount_release(&vp->v_holdcnt);
-#endif
- }
+ vs = vget_prep(vp);
+ vget_finish_ref(vp, vs);
}
void
@@ -3102,10 +2936,6 @@ vrefl(struct vnode *vp)
ASSERT_VI_LOCKED(vp, __func__);
CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
- if (__predict_false(vp->v_type == VCHR)) {
- vref_vchr(vp, true);
- return;
- }
vref(vp);
}
@@ -3123,35 +2953,6 @@ vrefact(struct vnode *vp)
}
void
-vrefactn(struct vnode *vp, u_int n)
-{
-
- CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
-#ifdef INVARIANTS
- int old = atomic_fetchadd_int(&vp->v_usecount, n);
- VNASSERT(old > 0, vp, ("%s: wrong use count %d", __func__, old));
-#else
- atomic_add_int(&vp->v_usecount, n);
-#endif
-}
-
-/*
- * Return reference count of a vnode.
- *
- * The results of this call are only guaranteed when some mechanism is used to
- * stop other processes from gaining references to the vnode. This may be the
- * case if the caller holds the only reference. This is also useful when stale
- * data is acceptable as race conditions may be accounted for by some other
- * means.
- */
-int
-vrefcnt(struct vnode *vp)
-{
-
- return (vp->v_usecount);
-}
-
-void
vlazy(struct vnode *vp)
{
struct mount *mp;
@@ -3246,9 +3047,6 @@ enum vput_op { VRELE, VPUT, VUNREF };
* By releasing the last usecount we take ownership of the hold count which
* provides liveness of the vnode, meaning we have to vdrop.
*
- * If the vnode is of type VCHR we may need to decrement si_usecount, see
- * v_decr_devcount for details.
- *
* For all vnodes we may need to perform inactive processing. It requires an
* exclusive lock on the vnode, while it is legal to call here with only a
* shared lock (or no locks). If locking the vnode in an expected manner fails,
@@ -3269,8 +3067,6 @@ vput_final(struct vnode *vp, enum vput_op func)
VNPASS(vp->v_holdcnt > 0, vp);
VI_LOCK(vp);
- if (__predict_false(vp->v_type == VCHR && func != VRELE))
- v_decr_devcount(vp);
/*
* By the time we got here someone else might have transitioned
@@ -3358,28 +3154,9 @@ out:
* Releasing the last use count requires additional processing, see vput_final
* above for details.
*
- * Note that releasing use count without the vnode lock requires special casing
- * for VCHR, see v_decr_devcount for details.
- *
* Comment above each variant denotes lock state on entry and exit.
*/
-static void __noinline
-vrele_vchr(struct vnode *vp)
-{
-
- if (refcount_release_if_not_last(&vp->v_usecount))
- return;
- VI_LOCK(vp);
- if (!refcount_release(&vp->v_usecount)) {
- VI_UNLOCK(vp);
- return;
- }
- v_decr_devcount(vp);
- VI_UNLOCK(vp);
- vput_final(vp, VRELE);
-}
-
/*
* in: any
* out: same as passed in
@@ -3389,10 +3166,6 @@ vrele(struct vnode *vp)
{
ASSERT_VI_UNLOCKED(vp, __func__);
- if (__predict_false(vp->v_type == VCHR)) {
- vrele_vchr(vp);
- return;
- }
if (!refcount_release(&vp->v_usecount))
return;
vput_final(vp, VRELE);
@@ -4144,20 +3917,6 @@ vgonel(struct vnode *vp)
}
/*
- * Calculate the total number of references to a special device.
- */
-int
-vcount(struct vnode *vp)
-{
- int count;
-
- dev_lock();
- count = vp->v_rdev->si_usecount;
- dev_unlock();
- return (count);
-}
-
-/*
* Print out a description of a vnode.
*/
static const char * const typename[] =
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 69a6be798208d..f44b440be6611 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -87,14 +87,12 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_page.h>
#include <vm/uma.h>
+#include <fs/devfs/devfs.h>
+
#include <ufs/ufs/quota.h>
MALLOC_DEFINE(M_FADVISE, "fadvise", "posix_fadvise(2) information");
-SDT_PROVIDER_DEFINE(vfs);
-SDT_PROBE_DEFINE2(vfs, , stat, mode, "char *", "int");
-SDT_PROBE_DEFINE2(vfs, , stat, reg, "char *", "int");
-
static int kern_chflagsat(struct thread *td, int fd, const char *path,
enum uio_seg pathseg, u_long flags, int atflag);
static int setfflags(struct thread *td, struct vnode *, u_long);
@@ -2383,9 +2381,6 @@ kern_statat(struct thread *td, int flag, int fd, const char *path,
return (error);
error = VOP_STAT(nd.ni_vp, sbp, td->td_ucred, NOCRED, td);
if (error == 0) {
- SDT_PROBE2(vfs, , stat, mode, path, sbp->st_mode);
- if (S_ISREG(sbp->st_mode))
- SDT_PROBE2(vfs, , stat, reg, path, pathseg);
if (__predict_false(hook != NULL))
hook(nd.ni_vp, sbp);
}
@@ -4220,7 +4215,7 @@ sys_revoke(struct thread *td, struct revoke_args *uap)
if (error != 0)
goto out;
}
- if (vp->v_usecount > 1 || vcount(vp) > 1)
+ if (devfs_usecount(vp) > 0)
VOP_REVOKE(vp, REVOKEALL);
out:
vput(vp);
diff --git a/sys/libkern/random.c b/sys/libkern/random.c
index e5e9de6108e1e..23a8887fa49b4 100644
--- a/sys/libkern/random.c
+++ b/sys/libkern/random.c
@@ -36,43 +36,14 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/libkern.h>
+#include <sys/prng.h>
#include <sys/systm.h>
-static u_long randseed = 937186357; /* after srandom(1), NSHUFF counted */
-
/*
- * Pseudo-random number generator for perturbing the profiling clock,
- * and whatever else we might use it for. The result is uniform on
- * [0, 2^31 - 1].
+ * Pseudo-random number generator. The result is uniform in [0, 2^31 - 1].
*/
u_long
random(void)
{
- static bool warned = false;
-
- long x, hi, lo, t;
-
- /* Warn only once, or it gets very spammy. */
- if (!warned) {
- gone_in(13,
- "random(9) is the obsolete Park-Miller LCG from 1988");
- warned = true;
- }
-
- /*
- * Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1).
- * From "Random number generators: good ones are hard to find",
- * Park and Miller, Communications of the ACM, vol. 31, no. 10,
- * October 1988, p. 1195.
- */
- /* Can't be initialized with 0, so use another value. */
- if ((x = randseed) == 0)
- x = 123459876;
- hi = x / 127773;
- lo = x % 127773;
- t = 16807 * lo - 2836 * hi;
- if (t < 0)
- t += 0x7fffffff;
- randseed = t;
- return (t);
+ return (prng32());
}
diff --git a/sys/modules/linux/Makefile b/sys/modules/linux/Makefile
index 7065c1f0f6cd0..c91dfbdaf3803 100644
--- a/sys/modules/linux/Makefile
+++ b/sys/modules/linux/Makefile
@@ -69,12 +69,12 @@ linux${SFX}_support.o: linux${SFX}_assym.h assym.inc
${VDSO}.so: linux${SFX}_locore.o
${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd \
--binary-architecture i386 linux${SFX}_locore.o ${.TARGET}
- strip -N _binary_linux${SFX}_locore_o_size ${.TARGET}
+ ${STRIPBIN} -N _binary_linux${SFX}_locore_o_size ${.TARGET}
.else
${VDSO}.so: linux${SFX}_locore.o
${OBJCOPY} --input-target binary --output-target elf32-i386-freebsd \
--binary-architecture i386 linux${SFX}_locore.o ${.TARGET}
- strip -N _binary_linux_locore_o_size ${.TARGET}
+ ${STRIPBIN} -N _binary_linux_locore_o_size ${.TARGET}
.endif
linux${SFX}_genassym.o: offset.inc
diff --git a/sys/modules/linux64/Makefile b/sys/modules/linux64/Makefile
index 046eeeda30f20..33dccc9077095 100644
--- a/sys/modules/linux64/Makefile
+++ b/sys/modules/linux64/Makefile
@@ -46,7 +46,7 @@ OBJCOPY_TARGET=--output-target elf64-x86-64 --binary-architecture i386:x86-64
${VDSO}.so: linux_locore.o
${OBJCOPY} --input-target binary ${OBJCOPY_TARGET} -S -g \
linux_locore.o ${.TARGET}
- strip -N _binary_linux_locore_o_size ${.TARGET}
+ ${STRIPBIN} -N _binary_linux_locore_o_size ${.TARGET}
linux_support.o: assym.inc linux_assym.h
${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \
diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c
index 814a5b5b14c7b..4930e1820f3bc 100644
--- a/sys/net/if_lagg.c
+++ b/sys/net/if_lagg.c
@@ -679,6 +679,9 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp)
return (EINVAL);
}
+ if (sc->sc_destroying == 1)
+ return (ENXIO);
+
/* Limit the maximal number of lagg ports */
if (sc->sc_count >= LAGG_MAX_PORTS)
return (ENOSPC);
@@ -1191,6 +1194,8 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
bzero(&rpbuf, sizeof(rpbuf));
+ /* XXX: This can race with lagg_clone_destroy. */
+
switch (cmd) {
case SIOCGLAGG:
LAGG_XLOCK(sc);
diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index b7cc308d22f20..fd3384a5175da 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -424,7 +424,7 @@ struct iflib_rxq {
struct pfil_head *pfil;
/*
* If there is a separate completion queue (IFLIB_HAS_RXCQ), this is
- * the command queue consumer index. Otherwise it's unused.
+ * the completion queue consumer index. Otherwise it's unused.
*/
qidx_t ifr_cq_cidx;
uint16_t ifr_id;
@@ -838,39 +838,41 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, uint32_t nm_i, boo
struct if_rxd_update iru;
if_ctx_t ctx = rxq->ifr_ctx;
iflib_fl_t fl = &rxq->ifr_fl[0];
- uint32_t refill_pidx, nic_i;
+ uint32_t nic_i_first, nic_i;
+ int i;
#if IFLIB_DEBUG_COUNTERS
int rf_count = 0;
#endif
if (nm_i == head && __predict_true(!init))
- return 0;
+ return (0);
+
iru_init(&iru, rxq, 0 /* flid */);
map = fl->ifl_sds.ifsd_map;
- refill_pidx = netmap_idx_k2n(kring, nm_i);
+ nic_i = netmap_idx_k2n(kring, nm_i);
/*
* IMPORTANT: we must leave one free slot in the ring,
* so move head back by one unit
*/
head = nm_prev(head, lim);
- nic_i = UINT_MAX;
DBG_COUNTER_INC(fl_refills);
while (nm_i != head) {
#if IFLIB_DEBUG_COUNTERS
if (++rf_count == 9)
DBG_COUNTER_INC(fl_refills_large);
#endif
- for (int tmp_pidx = 0; tmp_pidx < IFLIB_MAX_RX_REFRESH && nm_i != head; tmp_pidx++) {
+ nic_i_first = nic_i;
+ for (i = 0; i < IFLIB_MAX_RX_REFRESH && nm_i != head; i++) {
struct netmap_slot *slot = &ring->slot[nm_i];
- void *addr = PNMB(na, slot, &fl->ifl_bus_addrs[tmp_pidx]);
- uint32_t nic_i_dma = refill_pidx;
- nic_i = netmap_idx_k2n(kring, nm_i);
+ void *addr = PNMB(na, slot, &fl->ifl_bus_addrs[i]);
- MPASS(tmp_pidx < IFLIB_MAX_RX_REFRESH);
+ MPASS(i < IFLIB_MAX_RX_REFRESH);
if (addr == NETMAP_BUF_BASE(na)) /* bad buf */
return netmap_ring_reinit(kring);
+ fl->ifl_rxd_idxs[i] = nic_i;
+
if (__predict_false(init)) {
netmap_load_map(na, fl->ifl_buf_tag,
map[nic_i], addr);
@@ -879,33 +881,25 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, uint32_t nm_i, boo
netmap_reload_map(na, fl->ifl_buf_tag,
map[nic_i], addr);
}
+ bus_dmamap_sync(fl->ifl_buf_tag, map[nic_i],
+ BUS_DMASYNC_PREREAD);
slot->flags &= ~NS_BUF_CHANGED;
nm_i = nm_next(nm_i, lim);
- fl->ifl_rxd_idxs[tmp_pidx] = nic_i = nm_next(nic_i, lim);
- if (nm_i != head && tmp_pidx < IFLIB_MAX_RX_REFRESH-1)
- continue;
-
- iru.iru_pidx = refill_pidx;
- iru.iru_count = tmp_pidx+1;
- ctx->isc_rxd_refill(ctx->ifc_softc, &iru);
- refill_pidx = nic_i;
- for (int n = 0; n < iru.iru_count; n++) {
- bus_dmamap_sync(fl->ifl_buf_tag, map[nic_i_dma],
- BUS_DMASYNC_PREREAD);
- /* XXX - change this to not use the netmap func*/
- nic_i_dma = nm_next(nic_i_dma, lim);
- }
+ nic_i = nm_next(nic_i, lim);
}
+
+ iru.iru_pidx = nic_i_first;
+ iru.iru_count = i;
+ ctx->isc_rxd_refill(ctx->ifc_softc, &iru);
}
kring->nr_hwcur = head;
bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- if (__predict_true(nic_i != UINT_MAX)) {
- ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id, nic_i);
- DBG_COUNTER_INC(rxd_flush);
- }
+ ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id, nic_i);
+ DBG_COUNTER_INC(rxd_flush);
+
return (0);
}
@@ -1083,9 +1077,12 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags)
int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR;
if_ctx_t ctx = ifp->if_softc;
+ if_shared_ctx_t sctx = ctx->ifc_sctx;
+ if_softc_ctx_t scctx = &ctx->ifc_softc_ctx;
iflib_rxq_t rxq = &ctx->ifc_rxqs[kring->ring_id];
iflib_fl_t fl = &rxq->ifr_fl[0];
struct if_rxd_info ri;
+ qidx_t *cidxp;
/*
* netmap only uses free list 0, to avoid out of order consumption
@@ -1099,40 +1096,56 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags)
* First part: import newly received packets.
*
* nm_i is the index of the next free slot in the netmap ring,
- * nic_i is the index of the next received packet in the NIC ring,
- * and they may differ in case if_init() has been called while
+ * nic_i is the index of the next received packet in the NIC ring
+ * (or in the free list 0 if IFLIB_HAS_RXCQ is set), and they may
+ * differ in case if_init() has been called while
* in netmap mode. For the receive ring we have
*
- * nic_i = rxr->next_check;
+ * nic_i = fl->ifl_cidx;
* nm_i = kring->nr_hwtail (previous)
* and
* nm_i == (nic_i + kring->nkr_hwofs) % ring_size
*
- * rxr->next_check is set to 0 on a ring reinit
+ * fl->ifl_cidx is set to 0 on a ring reinit
*/
if (netmap_no_pendintr || force_update) {
uint32_t hwtail_lim = nm_prev(kring->nr_hwcur, lim);
+ bool have_rxcq = sctx->isc_flags & IFLIB_HAS_RXCQ;
int crclen = iflib_crcstrip ? 0 : 4;
int error, avail;
+ /*
+ * For the free list consumer index, we use the same
+ * logic as in iflib_rxeof().
+ */
+ if (have_rxcq)
+ cidxp = &rxq->ifr_cq_cidx;
+ else
+ cidxp = &fl->ifl_cidx;
+ avail = ctx->isc_rxd_available(ctx->ifc_softc,
+ rxq->ifr_id, *cidxp, USHRT_MAX);
+
nic_i = fl->ifl_cidx;
nm_i = netmap_idx_n2k(kring, nic_i);
- avail = ctx->isc_rxd_available(ctx->ifc_softc,
- rxq->ifr_id, nic_i, USHRT_MAX);
for (n = 0; avail > 0 && nm_i != hwtail_lim; n++, avail--) {
rxd_info_zero(&ri);
ri.iri_frags = rxq->ifr_frags;
ri.iri_qsidx = kring->ring_id;
ri.iri_ifp = ctx->ifc_ifp;
- ri.iri_cidx = nic_i;
+ ri.iri_cidx = *cidxp;
error = ctx->isc_rxd_pkt_get(ctx->ifc_softc, &ri);
ring->slot[nm_i].len = error ? 0 : ri.iri_len - crclen;
ring->slot[nm_i].flags = 0;
+ if (have_rxcq) {
+ *cidxp = ri.iri_cidx;
+ while (*cidxp >= scctx->isc_nrxd[0])
+ *cidxp -= scctx->isc_nrxd[0];
+ }
bus_dmamap_sync(fl->ifl_buf_tag,
fl->ifl_sds.ifsd_map[nic_i], BUS_DMASYNC_POSTREAD);
nm_i = nm_next(nm_i, lim);
- nic_i = nm_next(nic_i, lim);
+ fl->ifl_cidx = nic_i = nm_next(nic_i, lim);
}
if (n) { /* update the state variables */
if (netmap_no_pendintr && !force_update) {
@@ -1140,7 +1153,6 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags)
iflib_rx_miss ++;
iflib_rx_miss_bufs += n;
}
- fl->ifl_cidx = nic_i;
kring->nr_hwtail = nm_i;
}
kring->nr_kflags &= ~NKR_PENDINTR;
diff --git a/sys/net/iflib.h b/sys/net/iflib.h
index 99f13438f8007..e2d32c5635137 100644
--- a/sys/net/iflib.h
+++ b/sys/net/iflib.h
@@ -297,7 +297,7 @@ typedef enum {
} iflib_intr_type_t;
/*
- * Interface has a separate command queue for RX
+ * Interface has a separate completion queue for RX
*/
#define IFLIB_HAS_RXCQ 0x01
/*
@@ -309,7 +309,7 @@ typedef enum {
*/
#define IFLIB_IS_VF 0x04
/*
- * Interface has a separate command queue for TX
+ * Interface has a separate completion queue for TX
*/
#define IFLIB_HAS_TXCQ 0x08
/*
diff --git a/sys/net/route.c b/sys/net/route.c
index f24200a88e400..4167df8d0cce5 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -122,14 +122,10 @@ VNET_DEFINE(struct rib_head *, rt_tables);
#define V_rt_tables VNET(rt_tables)
-VNET_DEFINE(uma_zone_t, rtzone); /* Routing table UMA zone. */
-#define V_rtzone VNET(rtzone)
-
EVENTHANDLER_LIST_DEFINE(rt_addrmsg);
static int rt_ifdelroute(const struct rtentry *rt, const struct nhop_object *,
void *arg);
-static void destroy_rtentry_epoch(epoch_context_t ctx);
static int rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info,
int flags);
@@ -207,43 +203,6 @@ route_init(void)
}
SYSINIT(route_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, NULL);
-static int
-rtentry_zinit(void *mem, int size, int how)
-{
- struct rtentry *rt = mem;
-
- RT_LOCK_INIT(rt);
-
- return (0);
-}
-
-static void
-rtentry_zfini(void *mem, int size)
-{
- struct rtentry *rt = mem;
-
- RT_LOCK_DESTROY(rt);
-}
-
-static int
-rtentry_ctor(void *mem, int size, void *arg, int how)
-{
- struct rtentry *rt = mem;
-
- bzero(rt, offsetof(struct rtentry, rt_endzero));
- rt->rt_chain = NULL;
-
- return (0);
-}
-
-static void
-rtentry_dtor(void *mem, int size, void *arg)
-{
- struct rtentry *rt = mem;
-
- RT_UNLOCK_COND(rt);
-}
-
static void
vnet_route_init(const void *unused __unused)
{
@@ -255,9 +214,7 @@ vnet_route_init(const void *unused __unused)
V_rt_tables = malloc(rt_numfibs * (AF_MAX+1) *
sizeof(struct rib_head *), M_RTABLE, M_WAITOK|M_ZERO);
- V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry),
- rtentry_ctor, rtentry_dtor,
- rtentry_zinit, rtentry_zfini, UMA_ALIGN_PTR, 0);
+ vnet_rtzone_init();
for (dom = domains; dom; dom = dom->dom_next) {
if (dom->dom_rtattach == NULL)
continue;
@@ -270,7 +227,7 @@ vnet_route_init(const void *unused __unused)
rnh = rt_tables_get_rnh_ptr(table, fam);
if (rnh == NULL)
panic("%s: rnh NULL", __func__);
- dom->dom_rtattach((void **)rnh, 0, table);
+ *rnh = dom->dom_rtattach(table);
}
}
}
@@ -299,7 +256,7 @@ vnet_route_uninit(const void *unused __unused)
rnh = rt_tables_get_rnh_ptr(table, fam);
if (rnh == NULL)
panic("%s: rnh NULL", __func__);
- dom->dom_rtdetach((void **)rnh, 0);
+ dom->dom_rtdetach(*rnh);
}
}
@@ -314,7 +271,7 @@ vnet_route_uninit(const void *unused __unused)
epoch_drain_callbacks(net_epoch_preempt);
free(V_rt_tables, M_RTABLE);
- uma_zdestroy(V_rtzone);
+ vnet_rtzone_destroy();
}
VNET_SYSUNINIT(vnet_route_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST,
vnet_route_uninit, 0);
@@ -406,55 +363,6 @@ sys_setfib(struct thread *td, struct setfib_args *uap)
}
/*
- * Remove a reference count from an rtentry.
- * If the count gets low enough, take it out of the routing table
- */
-void
-rtfree(struct rtentry *rt)
-{
-
- KASSERT(rt != NULL,("%s: NULL rt", __func__));
-
- RT_LOCK_ASSERT(rt);
-
- RT_UNLOCK(rt);
- epoch_call(net_epoch_preempt, destroy_rtentry_epoch,
- &rt->rt_epoch_ctx);
-}
-
-static void
-destroy_rtentry(struct rtentry *rt)
-{
-
- /*
- * At this moment rnh, nh_control may be already freed.
- * nhop interface may have been migrated to a different vnet.
- * Use vnet stored in the nexthop to delete the entry.
- */
- CURVNET_SET(nhop_get_vnet(rt->rt_nhop));
-
- /* Unreference nexthop */
- nhop_free(rt->rt_nhop);
-
- uma_zfree(V_rtzone, rt);
-
- CURVNET_RESTORE();
-}
-
-/*
- * Epoch callback indicating rtentry is safe to destroy
- */
-static void
-destroy_rtentry_epoch(epoch_context_t ctx)
-{
- struct rtentry *rt;
-
- rt = __containerof(ctx, struct rtentry, rt_epoch_ctx);
-
- destroy_rtentry(rt);
-}
-
-/*
* Adds a temporal redirect entry to the routing table.
* @fibnum: fib number
* @dst: destination to install redirect to
@@ -1107,7 +1015,11 @@ rt_mpath_unlink(struct rib_head *rnh, struct rt_addrinfo *info,
rn = rnh->rnh_deladdr(info->rti_info[RTAX_DST],
info->rti_info[RTAX_NETMASK],
&rnh->head);
- *perror = 0;
+ if (rn != NULL) {
+ *perror = 0;
+ } else {
+ *perror = ESRCH;
+ }
return (rn);
}
diff --git a/sys/net/route.h b/sys/net/route.h
index 1ffabcbc86df7..b8a98007a41ed 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -387,16 +387,7 @@ int rtsock_routemsg_info(int, struct rt_addrinfo *, int);
struct sockaddr *rtsock_fix_netmask(const struct sockaddr *dst,
const struct sockaddr *smask, struct sockaddr_storage *dmask);
-/*
- * Note the following locking behavior:
- *
- * rtfree() and RTFREE_LOCKED() require a locked rtentry
- *
- * RTFREE() uses an unlocked entry.
- */
-void rtfree(struct rtentry *);
-void rtfree_func(struct rtentry *);
void rt_updatemtu(struct ifnet *);
void rt_flushifroutes_af(struct ifnet *, int);
diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c
index ade0b2a96b245..f448bcef1b8d0 100644
--- a/sys/net/route/route_ctl.c
+++ b/sys/net/route/route_ctl.c
@@ -76,11 +76,88 @@ struct rib_subscription {
struct epoch_context epoch_ctx;
};
+static int add_route(struct rib_head *rnh, struct rt_addrinfo *info,
+ struct rib_cmd_info *rc);
+static int del_route(struct rib_head *rnh, struct rt_addrinfo *info,
+ struct rib_cmd_info *rc);
+static int change_route(struct rib_head *, struct rt_addrinfo *,
+ struct rib_cmd_info *rc);
static void rib_notify(struct rib_head *rnh, enum rib_subscription_type type,
struct rib_cmd_info *rc);
static void destroy_subscription_epoch(epoch_context_t ctx);
+/* Routing table UMA zone */
+VNET_DEFINE_STATIC(uma_zone_t, rtzone);
+#define V_rtzone VNET(rtzone)
+
+void
+vnet_rtzone_init()
+{
+
+ V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry),
+ NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
+}
+
+#ifdef VIMAGE
+void
+vnet_rtzone_destroy()
+{
+
+ uma_zdestroy(V_rtzone);
+}
+#endif
+
+static void
+destroy_rtentry(struct rtentry *rt)
+{
+
+ /*
+ * At this moment rnh, nh_control may be already freed.
+ * nhop interface may have been migrated to a different vnet.
+ * Use vnet stored in the nexthop to delete the entry.
+ */
+ CURVNET_SET(nhop_get_vnet(rt->rt_nhop));
+
+ /* Unreference nexthop */
+ nhop_free(rt->rt_nhop);
+
+ uma_zfree(V_rtzone, rt);
+
+ CURVNET_RESTORE();
+}
+
+/*
+ * Epoch callback indicating rtentry is safe to destroy
+ */
+static void
+destroy_rtentry_epoch(epoch_context_t ctx)
+{
+ struct rtentry *rt;
+
+ rt = __containerof(ctx, struct rtentry, rt_epoch_ctx);
+
+ destroy_rtentry(rt);
+}
+
+/*
+ * Schedule rtentry deletion
+ */
+static void
+rtfree(struct rtentry *rt)
+{
+
+ KASSERT(rt != NULL, ("%s: NULL rt", __func__));
+
+ RT_LOCK_ASSERT(rt);
+
+ RT_UNLOCK(rt);
+ epoch_call(net_epoch_preempt, destroy_rtentry_epoch,
+ &rt->rt_epoch_ctx);
+}
+
+
+
static struct rib_head *
get_rnh(uint32_t fibnum, const struct rt_addrinfo *info)
{
@@ -128,7 +205,7 @@ rib_add_route(uint32_t fibnum, struct rt_addrinfo *info,
return (add_route(rnh, info, rc));
}
-int
+static int
add_route(struct rib_head *rnh, struct rt_addrinfo *info,
struct rib_cmd_info *rc)
{
@@ -138,7 +215,6 @@ add_route(struct rib_head *rnh, struct rt_addrinfo *info,
struct radix_node *rn;
struct ifaddr *ifa;
int error, flags;
- struct epoch_tracker et;
dst = info->rti_info[RTAX_DST];
gateway = info->rti_info[RTAX_GATEWAY];
@@ -162,20 +238,19 @@ add_route(struct rib_head *rnh, struct rt_addrinfo *info,
ifa_ref(info->rti_ifa);
}
- NET_EPOCH_ENTER(et);
error = nhop_create_from_info(rnh, info, &nh);
- NET_EPOCH_EXIT(et);
if (error != 0) {
ifa_free(info->rti_ifa);
return (error);
}
- rt = uma_zalloc(V_rtzone, M_NOWAIT);
+ rt = uma_zalloc(V_rtzone, M_NOWAIT | M_ZERO);
if (rt == NULL) {
ifa_free(info->rti_ifa);
nhop_free(nh);
return (ENOBUFS);
}
+ RT_LOCK_INIT(rt);
rt->rt_flags = RTF_UP | flags;
rt->rt_nhop = nh;
@@ -216,6 +291,7 @@ add_route(struct rib_head *rnh, struct rt_addrinfo *info,
RIB_WUNLOCK(rnh);
nhop_free(nh);
+ RT_LOCK_DESTROY(rt);
uma_zfree(V_rtzone, rt);
return (EEXIST);
}
@@ -283,6 +359,7 @@ add_route(struct rib_head *rnh, struct rt_addrinfo *info,
*/
if (rn == NULL) {
nhop_free(nh);
+ RT_LOCK_DESTROY(rt);
uma_zfree(V_rtzone, rt);
return (EEXIST);
}
@@ -389,7 +466,7 @@ rt_unlinkrte(struct rib_head *rnh, struct rt_addrinfo *info, int *perror)
return (rt);
}
-int
+static int
del_route(struct rib_head *rnh, struct rt_addrinfo *info,
struct rib_cmd_info *rc)
{
@@ -566,7 +643,7 @@ change_route_one(struct rib_head *rnh, struct rt_addrinfo *info,
return (0);
}
-int
+static int
change_route(struct rib_head *rnh, struct rt_addrinfo *info,
struct rib_cmd_info *rc)
{
@@ -740,36 +817,69 @@ rib_notify(struct rib_head *rnh, enum rib_subscription_type type,
}
}
+static struct rib_subscription *
+allocate_subscription(rib_subscription_cb_t *f, void *arg,
+ enum rib_subscription_type type, bool waitok)
+{
+ struct rib_subscription *rs;
+ int flags = M_ZERO | (waitok ? M_WAITOK : 0);
+
+ rs = malloc(sizeof(struct rib_subscription), M_RTABLE, flags);
+ if (rs == NULL)
+ return (NULL);
+
+ rs->func = f;
+ rs->arg = arg;
+ rs->type = type;
+
+ return (rs);
+}
+
+
/*
* Subscribe for the changes in the routing table specified by @fibnum and
* @family.
- * Needs to be run in network epoch.
*
* Returns pointer to the subscription structure on success.
*/
struct rib_subscription *
rib_subscribe(uint32_t fibnum, int family, rib_subscription_cb_t *f, void *arg,
- enum rib_subscription_type type, int waitok)
+ enum rib_subscription_type type, bool waitok)
{
struct rib_head *rnh;
struct rib_subscription *rs;
- int flags = M_ZERO | (waitok ? M_WAITOK : 0);
+ struct epoch_tracker et;
- NET_EPOCH_ASSERT();
+ if ((rs = allocate_subscription(f, arg, type, waitok)) == NULL)
+ return (NULL);
+
+ NET_EPOCH_ENTER(et);
KASSERT((fibnum < rt_numfibs), ("%s: bad fibnum", __func__));
rnh = rt_tables_get_rnh(fibnum, family);
- rs = malloc(sizeof(struct rib_subscription), M_RTABLE, flags);
- if (rs == NULL)
- return (NULL);
+ RIB_WLOCK(rnh);
+ CK_STAILQ_INSERT_TAIL(&rnh->rnh_subscribers, rs, next);
+ RIB_WUNLOCK(rnh);
+ NET_EPOCH_EXIT(et);
- rs->func = f;
- rs->arg = arg;
- rs->type = type;
+ return (rs);
+}
+
+struct rib_subscription *
+rib_subscribe_internal(struct rib_head *rnh, rib_subscription_cb_t *f, void *arg,
+ enum rib_subscription_type type, bool waitok)
+{
+ struct rib_subscription *rs;
+ struct epoch_tracker et;
+
+ if ((rs = allocate_subscription(f, arg, type, waitok)) == NULL)
+ return (NULL);
+ NET_EPOCH_ENTER(et);
RIB_WLOCK(rnh);
CK_STAILQ_INSERT_TAIL(&rnh->rnh_subscribers, rs, next);
RIB_WUNLOCK(rnh);
+ NET_EPOCH_EXIT(et);
return (rs);
}
diff --git a/sys/net/route/route_ctl.h b/sys/net/route/route_ctl.h
index b06eb2c30e5d8..62208609cd4d3 100644
--- a/sys/net/route/route_ctl.h
+++ b/sys/net/route/route_ctl.h
@@ -78,7 +78,10 @@ typedef void rib_subscription_cb_t(struct rib_head *rnh, struct rib_cmd_info *rc
struct rib_subscription *rib_subscribe(uint32_t fibnum, int family,
rib_subscription_cb_t *f, void *arg, enum rib_subscription_type type,
- int waitok);
+ bool waitok);
+struct rib_subscription *rib_subscribe_internal(struct rib_head *rnh,
+ rib_subscription_cb_t *f, void *arg, enum rib_subscription_type type,
+ bool waitok);
int rib_unsibscribe(uint32_t fibnum, int family, struct rib_subscription *rs);
#endif
diff --git a/sys/net/route/route_var.h b/sys/net/route/route_var.h
index 4427ac046ee86..a55835ffa9d60 100644
--- a/sys/net/route/route_var.h
+++ b/sys/net/route/route_var.h
@@ -113,12 +113,6 @@ struct radix_node *rt_mpath_unlink(struct rib_head *rnh,
struct rt_addrinfo *info, struct rtentry *rto, int *perror);
#endif
struct rib_cmd_info;
-int add_route(struct rib_head *rnh, struct rt_addrinfo *info,
- struct rib_cmd_info *rc);
-int del_route(struct rib_head *rnh, struct rt_addrinfo *info,
- struct rib_cmd_info *rc);
-int change_route(struct rib_head *, struct rt_addrinfo *,
- struct rib_cmd_info *rc);
VNET_PCPUSTAT_DECLARE(struct rtstat, rtstat);
#define RTSTAT_ADD(name, val) \
@@ -243,4 +237,8 @@ void tmproutes_update(struct rib_head *rnh, struct rtentry *rt);
void tmproutes_init(struct rib_head *rh);
void tmproutes_destroy(struct rib_head *rh);
+/* route_ctl.c */
+void vnet_rtzone_init(void);
+void vnet_rtzone_destroy(void);
+
#endif
diff --git a/sys/net/route/shared.h b/sys/net/route/shared.h
index 4ea20c5e011e8..3d68f5db0c8e3 100644
--- a/sys/net/route/shared.h
+++ b/sys/net/route/shared.h
@@ -72,9 +72,6 @@ void rib_init_subscriptions(struct rib_head *rnh);
void rib_destroy_subscriptions(struct rib_head *rnh);
/* route */
-VNET_DECLARE(uma_zone_t, rtzone); /* Routing table UMA zone. */
-#define V_rtzone VNET(rtzone)
-
struct rtentry *rt_unlinkrte(struct rib_head *rnh, struct rt_addrinfo *info,
int *perror);
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 8e00c95942acc..0b8edf452c23d 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -900,7 +900,7 @@ route_output(struct mbuf *m, struct socket *so, ...)
error = lla_rt_output(rtm, &info);
#ifdef INET6
if (error == 0)
- rti_need_deembed = (V_deembed_scopeid) ? 1 : 0;
+ rti_need_deembed = 1;
#endif
goto flush;
}
@@ -915,7 +915,7 @@ route_output(struct mbuf *m, struct socket *so, ...)
error = rib_action(fibnum, rtm->rtm_type, &info, &rc);
if (error == 0) {
#ifdef INET6
- rti_need_deembed = (V_deembed_scopeid) ? 1 : 0;
+ rti_need_deembed = 1;
#endif
rtm->rtm_index = rc.rc_nh_new->nh_ifp->if_index;
nh = rc.rc_nh_new;
@@ -930,7 +930,7 @@ route_output(struct mbuf *m, struct socket *so, ...)
}
#ifdef INET6
/* rt_msg2() will not be used when RTM_DELETE fails. */
- rti_need_deembed = (V_deembed_scopeid) ? 1 : 0;
+ rti_need_deembed = 1;
#endif
break;
@@ -1192,7 +1192,7 @@ rtsock_msg_mbuf(int type, struct rt_addrinfo *rtinfo)
rtinfo->rti_addrs |= (1 << i);
dlen = SA_SIZE(sa);
#ifdef INET6
- if (V_deembed_scopeid && sa->sa_family == AF_INET6) {
+ if (sa->sa_family == AF_INET6) {
sin6 = (struct sockaddr_in6 *)&ss;
bcopy(sa, sin6, sizeof(*sin6));
if (sa6_recoverscope(sin6) == 0)
@@ -1298,7 +1298,7 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int *
dlen = SA_SIZE(sa);
if (cp != NULL && buflen >= dlen) {
#ifdef INET6
- if (V_deembed_scopeid && sa->sa_family == AF_INET6) {
+ if (sa->sa_family == AF_INET6) {
sin6 = (struct sockaddr_in6 *)&ss;
bcopy(sa, sin6, sizeof(*sin6));
if (sa6_recoverscope(sin6) == 0)
diff --git a/sys/netinet/cc/cc_cubic.c b/sys/netinet/cc/cc_cubic.c
index cbd2e71893265..a905033c458d6 100644
--- a/sys/netinet/cc/cc_cubic.c
+++ b/sys/netinet/cc/cc_cubic.c
@@ -132,19 +132,29 @@ cubic_ack_received(struct cc_var *ccv, uint16_t type)
/*
* Regular ACK and we're not in cong/fast recovery and we're cwnd
- * limited and we're either not doing ABC or are slow starting or are
- * doing ABC and we've sent a cwnd's worth of bytes.
+ * limited and we're either not doing ABC or are just coming out
+ * from slow-start or were application limited or are slow starting
+ * or are doing ABC and we've sent a cwnd's worth of bytes.
*/
if (type == CC_ACK && !IN_RECOVERY(CCV(ccv, t_flags)) &&
(ccv->flags & CCF_CWND_LIMITED) && (!V_tcp_do_rfc3465 ||
+ (cubic_data->flags & (CUBICFLAG_IN_SLOWSTART | CUBICFLAG_IN_APPLIMIT)) ||
CCV(ccv, snd_cwnd) <= CCV(ccv, snd_ssthresh) ||
- (V_tcp_do_rfc3465 && ccv->flags & CCF_ABC_SENTAWND))) {
+ (V_tcp_do_rfc3465 && (ccv->flags & CCF_ABC_SENTAWND)))) {
/* Use the logic in NewReno ack_received() for slow start. */
if (CCV(ccv, snd_cwnd) <= CCV(ccv, snd_ssthresh) ||
cubic_data->min_rtt_ticks == TCPTV_SRTTBASE) {
cubic_data->flags |= CUBICFLAG_IN_SLOWSTART;
newreno_cc_algo.ack_received(ccv, type);
} else {
+ if (cubic_data->flags & (CUBICFLAG_IN_SLOWSTART |
+ CUBICFLAG_IN_APPLIMIT)) {
+ cubic_data->flags &= ~(CUBICFLAG_IN_SLOWSTART |
+ CUBICFLAG_IN_APPLIMIT);
+ cubic_data->t_last_cong = ticks;
+ cubic_data->K = cubic_k(cubic_data->max_cwnd /
+ CCV(ccv, t_maxseg));
+ }
if ((ticks_since_cong =
ticks - cubic_data->t_last_cong) < 0) {
/*
@@ -153,14 +163,6 @@ cubic_ack_received(struct cc_var *ccv, uint16_t type)
ticks_since_cong = INT_MAX;
cubic_data->t_last_cong = ticks - INT_MAX;
}
-
- if (cubic_data->flags & (CUBICFLAG_IN_SLOWSTART |
- CUBICFLAG_IN_APPLIMIT)) {
- cubic_data->flags &= ~(CUBICFLAG_IN_SLOWSTART |
- CUBICFLAG_IN_APPLIMIT);
- cubic_data->t_last_cong = ticks;
- cubic_data->K = 0;
- }
/*
* The mean RTT is used to best reflect the equations in
* the I-D. Using min_rtt in the tf_cwnd calculation
@@ -284,8 +286,7 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type)
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
cubic_ssthresh_update(ccv);
cubic_data->flags |= CUBICFLAG_CONG_EVENT;
- cubic_data->prev_max_cwnd = cubic_data->max_cwnd;
- cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
+ cubic_data->t_last_cong = ticks;
cubic_data->K = cubic_k(cubic_data->max_cwnd / CCV(ccv, t_maxseg));
}
ENTER_RECOVERY(CCV(ccv, t_flags));
@@ -296,8 +297,6 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type)
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
cubic_ssthresh_update(ccv);
cubic_data->flags |= CUBICFLAG_CONG_EVENT;
- cubic_data->prev_max_cwnd = cubic_data->max_cwnd;
- cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
cubic_data->t_last_cong = ticks;
cubic_data->K = cubic_k(cubic_data->max_cwnd / CCV(ccv, t_maxseg));
CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
@@ -359,11 +358,6 @@ cubic_post_recovery(struct cc_var *ccv)
cubic_data = ccv->cc_data;
pipe = 0;
- /* Fast convergence heuristic. */
- if (cubic_data->max_cwnd < cubic_data->prev_max_cwnd)
- cubic_data->max_cwnd = (cubic_data->max_cwnd * CUBIC_FC_FACTOR)
- >> CUBIC_SHIFT;
-
if (IN_FASTRECOVERY(CCV(ccv, t_flags))) {
/*
* If inflight data is less than ssthresh, set cwnd
@@ -390,7 +384,6 @@ cubic_post_recovery(struct cc_var *ccv)
CUBIC_BETA) >> CUBIC_SHIFT,
2 * CCV(ccv, t_maxseg));
}
- cubic_data->t_last_cong = ticks;
/* Calculate the average RTT between congestion epochs. */
if (cubic_data->epoch_ack_count > 0 &&
@@ -401,7 +394,6 @@ cubic_post_recovery(struct cc_var *ccv)
cubic_data->epoch_ack_count = 0;
cubic_data->sum_rtt_ticks = 0;
- cubic_data->K = cubic_k(cubic_data->max_cwnd / CCV(ccv, t_maxseg));
}
/*
@@ -455,18 +447,32 @@ cubic_ssthresh_update(struct cc_var *ccv)
{
struct cubic *cubic_data;
uint32_t ssthresh;
+ uint32_t cwnd;
cubic_data = ccv->cc_data;
+ cwnd = CCV(ccv, snd_cwnd);
+
+ /* Fast convergence heuristic. */
+ if (cwnd < cubic_data->max_cwnd) {
+ cwnd = ((uint64_t)cwnd * CUBIC_FC_FACTOR) >> CUBIC_SHIFT;
+ }
+ cubic_data->prev_max_cwnd = cubic_data->max_cwnd;
+ cubic_data->max_cwnd = cwnd;
/*
- * On the first congestion event, set ssthresh to cwnd * 0.5, on
- * subsequent congestion events, set it to cwnd * beta.
+ * On the first congestion event, set ssthresh to cwnd * 0.5
+ * and reduce max_cwnd to cwnd * beta. This aligns the cubic concave
+ * region appropriately. On subsequent congestion events, set
+ * ssthresh to cwnd * beta.
*/
- if ((cubic_data->flags & CUBICFLAG_CONG_EVENT) == 0)
- ssthresh = CCV(ccv, snd_cwnd) >> 1;
- else
- ssthresh = ((uint64_t)CCV(ccv, snd_cwnd) *
+ if ((cubic_data->flags & CUBICFLAG_CONG_EVENT) == 0) {
+ ssthresh = cwnd >> 1;
+ cubic_data->max_cwnd = ((uint64_t)cwnd *
+ CUBIC_BETA) >> CUBIC_SHIFT;
+ } else {
+ ssthresh = ((uint64_t)cwnd *
CUBIC_BETA) >> CUBIC_SHIFT;
+ }
CCV(ccv, snd_ssthresh) = max(ssthresh, 2 * CCV(ccv, t_maxseg));
}
diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c
index cf624e8a3157b..99efb4bdb3e44 100644
--- a/sys/netinet/in_mcast.c
+++ b/sys/netinet/in_mcast.c
@@ -229,16 +229,9 @@ inm_is_ifp_detached(const struct in_multi *inm)
* dedicated thread to avoid deadlocks when draining inm_release tasks.
*/
TASKQUEUE_DEFINE_THREAD(inm_free);
-static struct task inm_free_task;
static struct in_multi_head inm_free_list = SLIST_HEAD_INITIALIZER();
static void inm_release_task(void *arg __unused, int pending __unused);
-
-static void
-inm_init(void *arg __unused)
-{
- TASK_INIT(&inm_free_task, 0, inm_release_task, NULL);
-}
-SYSINIT(inm_init, SI_SUB_TASKQ, SI_ORDER_ANY, inm_init, NULL);
+static struct task inm_free_task = TASK_INITIALIZER(0, inm_release_task, NULL);
void
inm_release_wait(void *arg __unused)
diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c
index 2288a4c36abe6..4133ded92a821 100644
--- a/sys/netinet/in_proto.c
+++ b/sys/netinet/in_proto.c
@@ -294,9 +294,6 @@ IPPROTOSPACER,
},
};
-extern int in_inithead(void **, int, u_int);
-extern int in_detachhead(void **, int);
-
struct domain inetdomain = {
.dom_family = AF_INET,
.dom_name = "internet",
diff --git a/sys/netinet/in_rmx.c b/sys/netinet/in_rmx.c
index 38a9d9232a8ae..21f2e67b15bdd 100644
--- a/sys/netinet/in_rmx.c
+++ b/sys/netinet/in_rmx.c
@@ -54,10 +54,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_icmp.h>
#include <netinet/ip_var.h>
-extern int in_inithead(void **head, int off, u_int fibnum);
-#ifdef VIMAGE
-extern int in_detachhead(void **head, int off);
-#endif
static int
rib4_preadd(u_int fibnum, const struct sockaddr *addr, const struct sockaddr *mask,
@@ -121,38 +117,32 @@ rib4_preadd(u_int fibnum, const struct sockaddr *addr, const struct sockaddr *ma
return (0);
}
-static int _in_rt_was_here;
/*
* Initialize our routing tree.
*/
-int
-in_inithead(void **head, int off, u_int fibnum)
+struct rib_head *
+in_inithead(uint32_t fibnum)
{
struct rib_head *rh;
rh = rt_table_init(32, AF_INET, fibnum);
if (rh == NULL)
- return (0);
+ return (NULL);
rh->rnh_preadd = rib4_preadd;
#ifdef RADIX_MPATH
rt_mpath_init_rnh(rh);
#endif
- *head = (void *)rh;
- if (_in_rt_was_here == 0 ) {
- _in_rt_was_here = 1;
- }
- return 1;
+ return (rh);
}
#ifdef VIMAGE
-int
-in_detachhead(void **head, int off)
+void
+in_detachhead(struct rib_head *rh)
{
- rt_table_destroy((struct rib_head *)(*head));
- return (1);
+ rt_table_destroy(rh);
}
#endif
diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h
index 9babe5d053d9f..fabd8e1ab50c5 100644
--- a/sys/netinet/in_var.h
+++ b/sys/netinet/in_var.h
@@ -436,8 +436,7 @@ inm_rele_locked(struct in_multi_head *inmh, struct in_multi *inm)
#define MCAST_NOTSMEMBER 2 /* This host excluded source */
#define MCAST_MUTED 3 /* [deprecated] */
-struct rtentry;
-struct route;
+struct rib_head;
struct ip_moptions;
struct in_multi *inm_lookup_locked(struct ifnet *, const struct in_addr);
@@ -471,6 +470,10 @@ void in_ifadown(struct ifaddr *ifa, int);
struct mbuf *ip_tryforward(struct mbuf *);
void *in_domifattach(struct ifnet *);
void in_domifdetach(struct ifnet *, void *);
+struct rib_head *in_inithead(uint32_t fibnum);
+#ifdef VIMAGE
+void in_detachhead(struct rib_head *rh);
+#endif
#endif /* _KERNEL */
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 41c202c0d62f2..74e6456600967 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -1727,6 +1727,7 @@ sctp_timeout_handler(void *t)
stcb = (struct sctp_tcb *)tmr->tcb;
net = (struct sctp_nets *)tmr->net;
CURVNET_SET((struct vnet *)tmr->vnet);
+ NET_EPOCH_ENTER(et);
did_output = 1;
released_asoc_reference = false;
@@ -1786,7 +1787,6 @@ sctp_timeout_handler(void *t)
/* Record in stopped_from which timeout occurred. */
tmr->stopped_from = type;
- NET_EPOCH_ENTER(et);
/* mark as being serviced now */
if (SCTP_OS_TIMER_PENDING(&tmr->timer)) {
/*
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 337871e8fdc20..9bf6f52855a77 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -2673,9 +2673,16 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
tp->t_dupacks = 0;
/*
* If this ack also has new SACK info, increment the
- * counter as per rfc6675.
+ * counter as per rfc6675. The variable
+ * sack_changed tracks all changes to the SACK
+ * scoreboard, including when partial ACKs without
+ * SACK options are received, and clear the scoreboard
+ * from the left side. Such partial ACKs should not be
+ * counted as dupacks here.
*/
- if ((tp->t_flags & TF_SACK_PERMIT) && sack_changed)
+ if ((tp->t_flags & TF_SACK_PERMIT) &&
+ (to.to_flags & TOF_SACK) &&
+ sack_changed)
tp->t_dupacks++;
}
diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c
index 423836afb6210..b7879269966df 100644
--- a/sys/netinet/tcp_sack.c
+++ b/sys/netinet/tcp_sack.c
@@ -535,9 +535,7 @@ tcp_sackhole_remove(struct tcpcb *tp, struct sackhole *hole)
* tp->snd_holes is an ordered list of holes (oldest to newest, in terms of
* the sequence space).
* Returns 1 if incoming ACK has previously unknown SACK information,
- * 0 otherwise. Note: We treat (snd_una, th_ack) as a sack block so any changes
- * to that (i.e. left edge moving) would also be considered a change in SACK
- * information which is slightly different than rfc6675.
+ * 0 otherwise.
*/
int
tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
@@ -545,16 +543,21 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
struct sackhole *cur, *temp;
struct sackblk sack, sack_blocks[TCP_MAX_SACK + 1], *sblkp;
int i, j, num_sack_blks, sack_changed;
+ int delivered_data, left_edge_delta;
INP_WLOCK_ASSERT(tp->t_inpcb);
num_sack_blks = 0;
sack_changed = 0;
+ delivered_data = 0;
+ left_edge_delta = 0;
/*
* If SND.UNA will be advanced by SEG.ACK, and if SACK holes exist,
* treat [SND.UNA, SEG.ACK) as if it is a SACK block.
+ * Account changes to SND.UNA always in delivered data.
*/
if (SEQ_LT(tp->snd_una, th_ack) && !TAILQ_EMPTY(&tp->snd_holes)) {
+ left_edge_delta = th_ack - tp->snd_una;
sack_blocks[num_sack_blks].start = tp->snd_una;
sack_blocks[num_sack_blks++].end = th_ack;
}
@@ -563,7 +566,6 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
* received new blocks from the other side.
*/
if (to->to_flags & TOF_SACK) {
- tp->sackhint.sacked_bytes = 0; /* reset */
for (i = 0; i < to->to_nsacks; i++) {
bcopy((to->to_sacks + i * TCPOLEN_SACK),
&sack, sizeof(sack));
@@ -576,8 +578,6 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
SEQ_GT(sack.end, tp->snd_una) &&
SEQ_LEQ(sack.end, tp->snd_max)) {
sack_blocks[num_sack_blks++] = sack;
- tp->sackhint.sacked_bytes +=
- (sack.end-sack.start);
}
}
}
@@ -602,7 +602,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
}
}
}
- if (TAILQ_EMPTY(&tp->snd_holes))
+ if (TAILQ_EMPTY(&tp->snd_holes)) {
/*
* Empty scoreboard. Need to initialize snd_fack (it may be
* uninitialized or have a bogus value). Scoreboard holes
@@ -611,6 +611,8 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
* scoreboard).
*/
tp->snd_fack = SEQ_MAX(tp->snd_una, th_ack);
+ tp->sackhint.sacked_bytes = 0; /* reset */
+ }
/*
* In the while-loop below, incoming SACK blocks (sack_blocks[]) and
* SACK holes (snd_holes) are traversed from their tails with just
@@ -634,6 +636,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
*/
temp = tcp_sackhole_insert(tp, tp->snd_fack,sblkp->start,NULL);
if (temp != NULL) {
+ delivered_data += sblkp->end - sblkp->start;
tp->snd_fack = sblkp->end;
/* Go to the previous sack block. */
sblkp--;
@@ -651,11 +654,15 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
SEQ_LT(tp->snd_fack, sblkp->start))
sblkp--;
if (sblkp >= sack_blocks &&
- SEQ_LT(tp->snd_fack, sblkp->end))
+ SEQ_LT(tp->snd_fack, sblkp->end)) {
+ delivered_data += sblkp->end - tp->snd_fack;
tp->snd_fack = sblkp->end;
+ sack_changed = 1;
+ }
}
} else if (SEQ_LT(tp->snd_fack, sblkp->end)) {
/* fack is advanced. */
+ delivered_data += sblkp->end - tp->snd_fack;
tp->snd_fack = sblkp->end;
sack_changed = 1;
}
@@ -689,6 +696,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
/* Data acks at least the beginning of hole. */
if (SEQ_GEQ(sblkp->end, cur->end)) {
/* Acks entire hole, so delete hole. */
+ delivered_data += (cur->end - cur->start);
temp = cur;
cur = TAILQ_PREV(cur, sackhole_head, scblink);
tcp_sackhole_remove(tp, temp);
@@ -700,6 +708,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
continue;
} else {
/* Move start of hole forward. */
+ delivered_data += (sblkp->end - cur->start);
cur->start = sblkp->end;
cur->rxmit = SEQ_MAX(cur->rxmit, cur->start);
}
@@ -707,6 +716,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
/* Data acks at least the end of hole. */
if (SEQ_GEQ(sblkp->end, cur->end)) {
/* Move end of hole backward. */
+ delivered_data += (cur->end - sblkp->start);
cur->end = sblkp->start;
cur->rxmit = SEQ_MIN(cur->rxmit, cur->end);
} else {
@@ -726,6 +736,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
cur->end = sblkp->start;
cur->rxmit = SEQ_MIN(cur->rxmit,
cur->end);
+ delivered_data += (sblkp->end - sblkp->start);
}
}
}
@@ -740,6 +751,10 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
else
sblkp--;
}
+ tp->sackhint.delivered_data = delivered_data;
+ tp->sackhint.sacked_bytes += delivered_data - left_edge_delta;
+ KASSERT((delivered_data >= 0), ("delivered_data < 0"));
+ KASSERT((tp->sackhint.sacked_bytes >= 0), ("sacked_bytes < 0"));
return (sack_changed);
}
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index e564540b007d8..a9c7dea399543 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -831,6 +831,8 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
inp->inp_vflag &= ~INP_IPV6;
inp->inp_vflag |= INP_IPV4;
#endif
+ inp->inp_ip_ttl = sc->sc_ip_ttl;
+ inp->inp_ip_tos = sc->sc_ip_tos;
inp->inp_laddr = sc->sc_inc.inc_laddr;
#ifdef INET6
}
@@ -866,6 +868,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
if (oinp->in6p_outputopts)
inp->in6p_outputopts =
ip6_copypktopts(oinp->in6p_outputopts, M_NOWAIT);
+ inp->in6p_hops = oinp->in6p_hops;
}
if (sc->sc_inc.inc_flags & INC_ISIPV6) {
@@ -1389,12 +1392,28 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
cred = crhold(so->so_cred);
#ifdef INET6
- if ((inc->inc_flags & INC_ISIPV6) &&
- (inp->inp_flags & IN6P_AUTOFLOWLABEL))
- autoflowlabel = 1;
+ if (inc->inc_flags & INC_ISIPV6) {
+ if (inp->inp_flags & IN6P_AUTOFLOWLABEL) {
+ autoflowlabel = 1;
+ }
+ ip_ttl = in6_selecthlim(inp, NULL);
+ if ((inp->in6p_outputopts == NULL) ||
+ (inp->in6p_outputopts->ip6po_tclass == -1)) {
+ ip_tos = 0;
+ } else {
+ ip_tos = inp->in6p_outputopts->ip6po_tclass;
+ }
+ }
+#endif
+#if defined(INET6) && defined(INET)
+ else
+#endif
+#ifdef INET
+ {
+ ip_ttl = inp->inp_ip_ttl;
+ ip_tos = inp->inp_ip_tos;
+ }
#endif
- ip_ttl = inp->inp_ip_ttl;
- ip_tos = inp->inp_ip_tos;
win = so->sol_sbrcv_hiwat;
ltflags = (tp->t_flags & (TF_NOOPT | TF_SIGNATURE));
@@ -1599,13 +1618,8 @@ skip_alloc:
cred = NULL;
sc->sc_ipopts = ipopts;
bcopy(inc, &sc->sc_inc, sizeof(struct in_conninfo));
-#ifdef INET6
- if (!(inc->inc_flags & INC_ISIPV6))
-#endif
- {
- sc->sc_ip_tos = ip_tos;
- sc->sc_ip_ttl = ip_ttl;
- }
+ sc->sc_ip_tos = ip_tos;
+ sc->sc_ip_ttl = ip_ttl;
#ifdef TCP_OFFLOAD
sc->sc_tod = tod;
sc->sc_todctx = todctx;
@@ -1807,6 +1821,7 @@ syncache_respond(struct syncache *sc, const struct mbuf *m0, int flags)
/* Zero out traffic class and flow label. */
ip6->ip6_flow &= ~IPV6_FLOWINFO_MASK;
ip6->ip6_flow |= sc->sc_flowlabel;
+ ip6->ip6_flow |= htonl(sc->sc_ip_tos << 20);
th = (struct tcphdr *)(ip6 + 1);
}
@@ -1935,7 +1950,7 @@ syncache_respond(struct syncache *sc, const struct mbuf *m0, int flags)
m->m_pkthdr.csum_flags = CSUM_TCP_IPV6;
th->th_sum = in6_cksum_pseudo(ip6, tlen + optlen - hlen,
IPPROTO_TCP, 0);
- ip6->ip6_hlim = in6_selecthlim(NULL, NULL);
+ ip6->ip6_hlim = sc->sc_ip_ttl;
#ifdef TCP_OFFLOAD
if (ADDED_BY_TOE(sc)) {
struct toedev *tod = sc->sc_tod;
diff --git a/sys/netinet/tcp_syncache.h b/sys/netinet/tcp_syncache.h
index 27cbad42f9aec..37575a14467c4 100644
--- a/sys/netinet/tcp_syncache.h
+++ b/sys/netinet/tcp_syncache.h
@@ -63,8 +63,8 @@ struct syncache {
struct mbuf *sc_ipopts; /* source route */
u_int16_t sc_peer_mss; /* peer's MSS */
u_int16_t sc_wnd; /* advertised window */
- u_int8_t sc_ip_ttl; /* IPv4 TTL */
- u_int8_t sc_ip_tos; /* IPv4 TOS */
+ u_int8_t sc_ip_ttl; /* TTL / Hop Limit */
+ u_int8_t sc_ip_tos; /* TOS / Traffic Class */
u_int8_t sc_requested_s_scale:4,
sc_requested_r_scale:4;
u_int16_t sc_flags;
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index c1fb25853836d..d79ac73525d97 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -105,12 +105,12 @@ struct sackhole {
struct sackhint {
struct sackhole *nexthole;
- int sack_bytes_rexmit;
+ int32_t sack_bytes_rexmit;
tcp_seq last_sack_ack; /* Most recent/largest sacked ack */
- int ispare; /* explicit pad for 64bit alignment */
- int sacked_bytes; /*
- * Total sacked bytes reported by the
+ int32_t delivered_data; /* Newly acked data from last SACK */
+
+ int32_t sacked_bytes; /* Total sacked bytes reported by the
* receiver via sack option
*/
uint32_t _pad1[1]; /* TBD */
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index fb53adb86e821..31cb54aef6a00 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -2374,8 +2374,7 @@ in6_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
ndpc.rtm.rtm_type = RTM_GET;
ndpc.rtm.rtm_flags = RTF_UP;
ndpc.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY;
- if (V_deembed_scopeid)
- sa6_recoverscope(&ndpc.sin6);
+ sa6_recoverscope(&ndpc.sin6);
/* publish */
if (lle->la_flags & LLE_PUB)
diff --git a/sys/netinet6/in6_mcast.c b/sys/netinet6/in6_mcast.c
index 2433dc2ee1947..fde7e5dad165c 100644
--- a/sys/netinet6/in6_mcast.c
+++ b/sys/netinet6/in6_mcast.c
@@ -516,16 +516,9 @@ in6m_release(struct in6_multi *inm)
* dedicated thread to avoid deadlocks when draining in6m_release tasks.
*/
TASKQUEUE_DEFINE_THREAD(in6m_free);
-static struct task in6m_free_task;
static struct in6_multi_head in6m_free_list = SLIST_HEAD_INITIALIZER();
static void in6m_release_task(void *arg __unused, int pending __unused);
-
-static void
-in6m_init(void *arg __unused)
-{
- TASK_INIT(&in6m_free_task, 0, in6m_release_task, NULL);
-}
-SYSINIT(in6m_init, SI_SUB_TASKQ, SI_ORDER_ANY, in6m_init, NULL);
+static struct task in6m_free_task = TASK_INITIALIZER(0, in6m_release_task, NULL);
void
in6m_release_list_deferred(struct in6_multi_head *inmh)
diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c
index ea7a468ac72be..9f9c9b9dbbf8b 100644
--- a/sys/netinet6/in6_proto.c
+++ b/sys/netinet6/in6_proto.c
@@ -333,11 +333,6 @@ IP6PROTOSPACER,
},
};
-extern int in6_inithead(void **, int, u_int);
-#ifdef VIMAGE
-extern int in6_detachhead(void **, int);
-#endif
-
struct domain inet6domain = {
.dom_family = AF_INET6,
.dom_name = "internet6",
diff --git a/sys/netinet6/in6_rmx.c b/sys/netinet6/in6_rmx.c
index 357292c5c59d7..c026bf4a057c0 100644
--- a/sys/netinet6/in6_rmx.c
+++ b/sys/netinet6/in6_rmx.c
@@ -101,11 +101,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
-extern int in6_inithead(void **head, int off, u_int fibnum);
-#ifdef VIMAGE
-extern int in6_detachhead(void **head, int off);
-#endif
-
static int
rib6_preadd(u_int fibnum, const struct sockaddr *addr, const struct sockaddr *mask,
struct nhop_object *nh)
@@ -147,41 +142,35 @@ rib6_preadd(u_int fibnum, const struct sockaddr *addr, const struct sockaddr *ma
* Initialize our routing tree.
*/
-int
-in6_inithead(void **head, int off, u_int fibnum)
+struct rib_head *
+in6_inithead(uint32_t fibnum)
{
- struct epoch_tracker et;
struct rib_head *rh;
+ struct rib_subscription *rs;
rh = rt_table_init(offsetof(struct sockaddr_in6, sin6_addr) << 3,
AF_INET6, fibnum);
if (rh == NULL)
- return (0);
+ return (NULL);
rh->rnh_preadd = rib6_preadd;
#ifdef RADIX_MPATH
rt_mpath_init_rnh(rh);
#endif
- *head = (void *)rh;
- NET_EPOCH_ENTER(et);
- if (rib_subscribe(fibnum, AF_INET6, nd6_subscription_cb, NULL,
- RIB_NOTIFY_IMMEDIATE, M_NOWAIT) == NULL)
- log(LOG_ERR, "in6_inithead(): unable to subscribe to fib %u\n",
- fibnum);
- NET_EPOCH_EXIT(et);
+ rs = rib_subscribe_internal(rh, nd6_subscription_cb, NULL,
+ RIB_NOTIFY_IMMEDIATE, true);
+ KASSERT(rs != NULL, ("Unable to subscribe to fib %u\n", fibnum));
- return (1);
+ return (rh);
}
#ifdef VIMAGE
-int
-in6_detachhead(void **head, int off)
+void
+in6_detachhead(struct rib_head *rh)
{
- rt_table_destroy((struct rib_head *)(*head));
-
- return (1);
+ rt_table_destroy(rh);
}
#endif
diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h
index 7381ff68064a6..f5e6a931ae64e 100644
--- a/sys/netinet6/in6_var.h
+++ b/sys/netinet6/in6_var.h
@@ -857,6 +857,7 @@ in6m_rele_locked(struct in6_multi_head *inmh, struct in6_multi *inm)
struct ip6_moptions;
struct sockopt;
struct inpcbinfo;
+struct rib_head;
/* Multicast KPIs. */
int im6o_mc_filter(const struct ip6_moptions *, const struct ifnet *,
@@ -891,6 +892,8 @@ void in6_savemkludge(struct in6_ifaddr *);
void *in6_domifattach(struct ifnet *);
void in6_domifdetach(struct ifnet *, void *);
int in6_domifmtu(struct ifnet *);
+struct rib_head *in6_inithead(uint32_t fibnum);
+void in6_detachhead(struct rib_head *rh);
void in6_setmaxmtu(void);
int in6_if2idlen(struct ifnet *);
struct in6_ifaddr *in6ifa_ifpforlinklocal(struct ifnet *, int);
diff --git a/sys/netinet6/scope6.c b/sys/netinet6/scope6.c
index 42d999be6a8de..f99585dc17893 100644
--- a/sys/netinet6/scope6.c
+++ b/sys/netinet6/scope6.c
@@ -60,11 +60,7 @@ VNET_DEFINE(int, ip6_use_defzone) = 1;
#else
VNET_DEFINE(int, ip6_use_defzone) = 0;
#endif
-VNET_DEFINE(int, deembed_scopeid) = 1;
SYSCTL_DECL(_net_inet6_ip6);
-SYSCTL_INT(_net_inet6_ip6, OID_AUTO, deembed_scopeid, CTLFLAG_VNET | CTLFLAG_RW,
- &VNET_NAME(deembed_scopeid), 0,
- "Extract embedded zone ID and set it to sin6_scope_id in sockaddr_in6.");
/*
* The scope6_lock protects the global sid default stored in
diff --git a/sys/netinet6/scope6_var.h b/sys/netinet6/scope6_var.h
index cdb2b9572bc24..181e30afe6f8d 100644
--- a/sys/netinet6/scope6_var.h
+++ b/sys/netinet6/scope6_var.h
@@ -47,9 +47,6 @@ struct scope6_id {
uint32_t s6id_list[IPV6_ADDR_SCOPES_COUNT];
};
-VNET_DECLARE(int, deembed_scopeid);
-#define V_deembed_scopeid VNET(deembed_scopeid)
-
void scope6_init(void);
struct scope6_id *scope6_ifattach(struct ifnet *);
void scope6_ifdetach(struct scope6_id *);
diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c
index bbdbcc88a038c..bfce77f40c3fe 100644
--- a/sys/netpfil/ipfw/ip_fw2.c
+++ b/sys/netpfil/ipfw/ip_fw2.c
@@ -1944,7 +1944,23 @@ do { \
break;
case O_FRAG:
- match = (offset != 0);
+ if (is_ipv4) {
+ /*
+ * Since flags_match() works with
+ * uint8_t we pack ip_off into 8 bits.
+ * For this match offset is a boolean.
+ */
+ match = flags_match(cmd,
+ ((ntohs(ip->ip_off) & ~IP_OFFMASK)
+ >> 8) | (offset != 0));
+ } else {
+ /*
+ * Compatiblity: historically bare
+ * "frag" would match IPv6 fragments.
+ */
+ match = (cmd->arg1 == 0x1 &&
+ (offset != 0));
+ }
break;
case O_IN: /* "out" is "not in" */
diff --git a/sys/riscv/include/pcpu.h b/sys/riscv/include/pcpu.h
index 46b258380a105..5068596462fc3 100644
--- a/sys/riscv/include/pcpu.h
+++ b/sys/riscv/include/pcpu.h
@@ -48,7 +48,7 @@
struct pmap *pc_curpmap; /* Currently active pmap */ \
uint32_t pc_pending_ipis; /* IPIs pending to this CPU */ \
uint32_t pc_hart; /* Hart ID */ \
- char __pad[49]
+ char __pad[56] /* Pad to factor of PAGE_SIZE */
#ifdef _KERNEL
diff --git a/sys/riscv/include/pcpu_aux.h b/sys/riscv/include/pcpu_aux.h
index 3d4c70c491d62..9fecd25c67cbc 100644
--- a/sys/riscv/include/pcpu_aux.h
+++ b/sys/riscv/include/pcpu_aux.h
@@ -46,6 +46,9 @@
* be a multiple of the size of struct pcpu.
*/
_Static_assert(PAGE_SIZE % sizeof(struct pcpu) == 0, "fix pcpu size");
+_Static_assert(offsetof(struct pcpu, __pad) +
+ sizeof(((struct pcpu *)0)->__pad) == sizeof(struct pcpu),
+ "fix pcpu padding");
extern struct pcpu __pcpu[];
diff --git a/sys/riscv/include/stack.h b/sys/riscv/include/stack.h
index 7f4be068ec273..40183afb9f4d6 100644
--- a/sys/riscv/include/stack.h
+++ b/sys/riscv/include/stack.h
@@ -41,9 +41,9 @@
(va) <= VM_MAX_KERNEL_ADDRESS)
struct unwind_state {
- uint64_t fp;
- uint64_t sp;
- uint64_t pc;
+ uintptr_t fp;
+ uintptr_t sp;
+ uintptr_t pc;
};
int unwind_frame(struct unwind_state *);
diff --git a/sys/riscv/riscv/db_trace.c b/sys/riscv/riscv/db_trace.c
index 2a783b2ed0f02..6d7b6b934d43e 100644
--- a/sys/riscv/riscv/db_trace.c
+++ b/sys/riscv/riscv/db_trace.c
@@ -108,9 +108,9 @@ db_stack_trace_cmd(struct unwind_state *frame)
db_printf("--- exception %ld, tval = %#lx\n",
tf->tf_scause & EXCP_MASK,
tf->tf_stval);
- frame->sp = (uint64_t)tf->tf_sp;
- frame->fp = (uint64_t)tf->tf_s[0];
- frame->pc = (uint64_t)tf->tf_sepc;
+ frame->sp = tf->tf_sp;
+ frame->fp = tf->tf_s[0];
+ frame->pc = tf->tf_sepc;
if (!INKERNEL(frame->fp))
break;
continue;
@@ -132,9 +132,9 @@ db_trace_thread(struct thread *thr, int count)
ctx = kdb_thr_ctx(thr);
- frame.sp = (uint64_t)ctx->pcb_sp;
- frame.fp = (uint64_t)ctx->pcb_s[0];
- frame.pc = (uint64_t)ctx->pcb_ra;
+ frame.sp = ctx->pcb_sp;
+ frame.fp = ctx->pcb_s[0];
+ frame.pc = ctx->pcb_ra;
db_stack_trace_cmd(&frame);
return (0);
}
@@ -143,12 +143,12 @@ void
db_trace_self(void)
{
struct unwind_state frame;
- uint64_t sp;
+ uintptr_t sp;
__asm __volatile("mv %0, sp" : "=&r" (sp));
frame.sp = sp;
- frame.fp = (uint64_t)__builtin_frame_address(0);
- frame.pc = (uint64_t)db_trace_self;
+ frame.fp = (uintptr_t)__builtin_frame_address(0);
+ frame.pc = (uintptr_t)db_trace_self;
db_stack_trace_cmd(&frame);
}
diff --git a/sys/riscv/riscv/locore.S b/sys/riscv/riscv/locore.S
index 4a5b01df85b76..86eaab6d533b6 100644
--- a/sys/riscv/riscv/locore.S
+++ b/sys/riscv/riscv/locore.S
@@ -223,19 +223,21 @@ va:
csrw sscratch, t0
/* Initialize stack pointer */
- la s3, initstack_end
- mv sp, s3
+ la sp, initstack_end
+
+ /* Clear frame pointer */
+ mv s0, zero
/* Allocate space for thread0 PCB and riscv_bootparams */
addi sp, sp, -(PCB_SIZE + RISCV_BOOTPARAMS_SIZE) & ~STACKALIGNBYTES
/* Clear BSS */
- la s0, _C_LABEL(__bss_start)
- la s1, _C_LABEL(_end)
+ la t0, _C_LABEL(__bss_start)
+ la t1, _C_LABEL(_end)
1:
- sd zero, 0(s0)
- addi s0, s0, 8
- bltu s0, s1, 1b
+ sd zero, 0(t0)
+ addi t0, t0, 8
+ bltu t0, t1, 1b
/* Fill riscv_bootparams */
la t0, pagetable_l1
@@ -259,6 +261,11 @@ va:
call _C_LABEL(initriscv) /* Off we go */
call _C_LABEL(mi_startup)
+ /* We should never reach here, but if so just hang. */
+2:
+ wfi
+ j 2b
+
/*
* Get the physical address the kernel is loaded to. Returned in s9.
*/
@@ -350,7 +357,7 @@ ENTRY(mpentry)
ld sp, 0(t0)
/* Get the kernel's load address */
- jal get_physmem
+ jal get_physmem
/* Setup supervisor trap vector */
lla t0, mpva
diff --git a/sys/riscv/riscv/stack_machdep.c b/sys/riscv/riscv/stack_machdep.c
index 2e016f537f91c..d4939dbda0418 100644
--- a/sys/riscv/riscv/stack_machdep.c
+++ b/sys/riscv/riscv/stack_machdep.c
@@ -47,15 +47,18 @@ __FBSDID("$FreeBSD$");
#include <machine/stack.h>
static void
-stack_capture(struct stack *st, struct unwind_state *frame)
+stack_capture(struct thread *td, struct stack *st, struct unwind_state *frame)
{
stack_zero(st);
while (1) {
+ if ((vm_offset_t)frame->fp < td->td_kstack ||
+ (vm_offset_t)frame->fp >= td->td_kstack +
+ td->td_kstack_pages * PAGE_SIZE)
+ break;
unwind_frame(frame);
- if (!INKERNEL((vm_offset_t)frame->fp) ||
- !INKERNEL((vm_offset_t)frame->pc))
+ if (!INKERNEL((vm_offset_t)frame->pc))
break;
if (stack_put(st, frame->pc) == -1)
break;
@@ -78,7 +81,7 @@ stack_save_td(struct stack *st, struct thread *td)
frame.fp = td->td_pcb->pcb_s[0];
frame.pc = td->td_pcb->pcb_ra;
- stack_capture(st, &frame);
+ stack_capture(td, st, &frame);
return (0);
}
@@ -86,13 +89,13 @@ void
stack_save(struct stack *st)
{
struct unwind_state frame;
- uint64_t sp;
+ uintptr_t sp;
__asm __volatile("mv %0, sp" : "=&r" (sp));
frame.sp = sp;
- frame.fp = (uint64_t)__builtin_frame_address(0);
- frame.pc = (uint64_t)stack_save;
+ frame.fp = (uintptr_t)__builtin_frame_address(0);
+ frame.pc = (uintptr_t)stack_save;
- stack_capture(st, &frame);
+ stack_capture(curthread, st, &frame);
}
diff --git a/sys/riscv/riscv/trap.c b/sys/riscv/riscv/trap.c
index aa9ec534669d3..dabd84e822e94 100644
--- a/sys/riscv/riscv/trap.c
+++ b/sys/riscv/riscv/trap.c
@@ -198,14 +198,22 @@ data_abort(struct trapframe *frame, int usermode)
"Kernel page fault") != 0)
goto fatal;
- if (usermode)
- map = &td->td_proc->p_vmspace->vm_map;
- else if (stval >= VM_MAX_USER_ADDRESS)
- map = kernel_map;
- else {
- if (pcb->pcb_onfault == 0)
- goto fatal;
+ if (usermode) {
map = &td->td_proc->p_vmspace->vm_map;
+ } else {
+ /*
+ * Enable interrupts for the duration of the page fault. For
+ * user faults this was done already in do_trap_user().
+ */
+ intr_enable();
+
+ if (stval >= VM_MAX_USER_ADDRESS) {
+ map = kernel_map;
+ } else {
+ if (pcb->pcb_onfault == 0)
+ goto fatal;
+ map = &td->td_proc->p_vmspace->vm_map;
+ }
}
va = trunc_page(stval);
@@ -324,6 +332,7 @@ do_trap_user(struct trapframe *frame)
riscv_cpu_intr(frame);
return;
}
+ intr_enable();
CTR3(KTR_TRAP, "do_trap_user: curthread: %p, sepc: %lx, frame: %p",
curthread, frame->tf_sepc, frame);
diff --git a/sys/riscv/riscv/unwind.c b/sys/riscv/riscv/unwind.c
index 18fc1e250c9b5..8b0cdeca29034 100644
--- a/sys/riscv/riscv/unwind.c
+++ b/sys/riscv/riscv/unwind.c
@@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$");
int
unwind_frame(struct unwind_state *frame)
{
- uint64_t fp;
+ uintptr_t fp;
fp = frame->fp;
@@ -50,8 +50,8 @@ unwind_frame(struct unwind_state *frame)
return (-1);
frame->sp = fp;
- frame->fp = *(uint64_t *)(fp - 16);
- frame->pc = *(uint64_t *)(fp - 8) - 4;
+ frame->fp = ((uintptr_t *)fp)[-2];
+ frame->pc = ((uintptr_t *)fp)[-1] - 4;
return (0);
}
diff --git a/sys/rpc/clnt.h b/sys/rpc/clnt.h
index 26a21cf13187d..23c92103edff2 100644
--- a/sys/rpc/clnt.h
+++ b/sys/rpc/clnt.h
@@ -357,6 +357,8 @@ enum clnt_stat clnt_call_private(CLIENT *, struct rpc_callextra *, rpcproc_t,
#define CLSET_PRIVPORT 27 /* set privileged source port flag */
#define CLGET_PRIVPORT 28 /* get privileged source port flag */
#define CLSET_BACKCHANNEL 29 /* set backchannel for socket */
+#define CLSET_TLS 30 /* set TLS for socket */
+#define CLSET_BLOCKRCV 31 /* Temporarily block reception */
#endif
diff --git a/sys/sys/domain.h b/sys/sys/domain.h
index e83dd0f4afc54..3d17879f1ccd9 100644
--- a/sys/sys/domain.h
+++ b/sys/sys/domain.h
@@ -45,6 +45,7 @@
struct mbuf;
struct ifnet;
struct socket;
+struct rib_head;
struct domain {
int dom_family; /* AF_xxx */
@@ -59,10 +60,10 @@ struct domain {
(struct socket *);
struct protosw *dom_protosw, *dom_protoswNPROTOSW;
struct domain *dom_next;
- int (*dom_rtattach) /* initialize routing table */
- (void **, int, u_int);
- int (*dom_rtdetach) /* clean up routing table */
- (void **, int);
+ struct rib_head *(*dom_rtattach) /* initialize routing table */
+ (uint32_t);
+ void (*dom_rtdetach) /* clean up routing table */
+ (struct rib_head *);
void *(*dom_ifattach)(struct ifnet *);
void (*dom_ifdetach)(struct ifnet *, void *);
int (*dom_ifmtu)(struct ifnet *);
diff --git a/sys/sys/namei.h b/sys/sys/namei.h
index 784eb79311c06..42d39e7330abb 100644
--- a/sys/sys/namei.h
+++ b/sys/sys/namei.h
@@ -152,24 +152,33 @@ int cache_fplookup(struct nameidata *ndp, enum cache_fpl_status *status,
#define HASBUF 0x00000400 /* has allocated pathname buffer */
#define SAVENAME 0x00000800 /* save pathname buffer */
#define SAVESTART 0x00001000 /* save starting directory */
-#define ISDOTDOT 0x00002000 /* current component name is .. */
-#define MAKEENTRY 0x00004000 /* entry is to be added to name cache */
-#define ISLASTCN 0x00008000 /* this is last component of pathname */
-#define ISSYMLINK 0x00010000 /* symlink needs interpretation */
-#define ISWHITEOUT 0x00020000 /* found whiteout */
-#define DOWHITEOUT 0x00040000 /* do whiteouts */
-#define WILLBEDIR 0x00080000 /* new files will be dirs; allow trailing / */
-#define ISOPEN 0x00200000 /* caller is opening; return a real vnode. */
-#define NOCROSSMOUNT 0x00400000 /* do not cross mount points */
-#define NOMACCHECK 0x00800000 /* do not perform MAC checks */
-#define AUDITVNODE1 0x04000000 /* audit the looked up vnode information */
-#define AUDITVNODE2 0x08000000 /* audit the looked up vnode information */
-#define TRAILINGSLASH 0x10000000 /* path ended in a slash */
-#define NOCAPCHECK 0x20000000 /* do not perform capability checks */
-#define NOEXECCHECK 0x40000000 /* do not perform exec check on dir */
+#define ISWHITEOUT 0x00002000 /* found whiteout */
+#define DOWHITEOUT 0x00004000 /* do whiteouts */
+#define WILLBEDIR 0x00008000 /* new files will be dirs; allow trailing / */
+#define ISOPEN 0x00010000 /* caller is opening; return a real vnode. */
+#define NOCROSSMOUNT 0x00020000 /* do not cross mount points */
+#define NOMACCHECK 0x00040000 /* do not perform MAC checks */
+#define AUDITVNODE1 0x00080000 /* audit the looked up vnode information */
+#define AUDITVNODE2 0x00100000 /* audit the looked up vnode information */
+#define NOCAPCHECK 0x00200000 /* do not perform capability checks */
+/* UNUSED 0x00400000 */
+/* UNUSED 0x00800000 */
+/* UNUSED 0x01000000 */
+#define NOEXECCHECK 0x02000000 /* do not perform exec check on dir */
+#define MAKEENTRY 0x04000000 /* entry is to be added to name cache */
+#define ISSYMLINK 0x08000000 /* symlink needs interpretation */
+#define ISLASTCN 0x10000000 /* this is last component of pathname */
+#define ISDOTDOT 0x20000000 /* current component name is .. */
+#define TRAILINGSLASH 0x40000000 /* path ended in a slash */
#define PARAMASK 0x7ffffe00 /* mask of parameter descriptors */
/*
+ * Flags which must not be passed in by callers.
+ */
+#define NAMEI_INTERNAL_FLAGS \
+ (NOEXECCHECK | MAKEENTRY | ISSYMLINK | ISLASTCN | ISDOTDOT | TRAILINGSLASH)
+
+/*
* Namei results flags
*/
#define NIRES_ABS 0x00000001 /* Path was absolute */
diff --git a/sys/sys/param.h b/sys/sys/param.h
index cdb5495ed3358..1713003199916 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -60,7 +60,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1300105 /* Master, propagated to newvers */
+#define __FreeBSD_version 1300108 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/sys/sys/pipe.h b/sys/sys/pipe.h
index 4e633262191d1..2f1568ab6637c 100644
--- a/sys/sys/pipe.h
+++ b/sys/sys/pipe.h
@@ -103,7 +103,7 @@ struct pipemapping {
*/
struct pipe {
struct pipebuf pipe_buffer; /* data storage */
- struct pipemapping pipe_map; /* pipe mapping for direct I/O */
+ struct pipemapping pipe_pages; /* wired pages for direct I/O */
struct selinfo pipe_sel; /* for compat with select */
struct timespec pipe_atime; /* time of last access */
struct timespec pipe_mtime; /* time of last modify */
diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h
index 7e14df30bff83..224d84c484f44 100644
--- a/sys/sys/pmc.h
+++ b/sys/sys/pmc.h
@@ -127,7 +127,8 @@ extern char pmc_cpuid[PMC_CPUID_LEN];
__PMC_CPU(ARMV7_CORTEX_A15, 0x504, "ARMv7 Cortex A15") \
__PMC_CPU(ARMV7_CORTEX_A17, 0x505, "ARMv7 Cortex A17") \
__PMC_CPU(ARMV8_CORTEX_A53, 0x600, "ARMv8 Cortex A53") \
- __PMC_CPU(ARMV8_CORTEX_A57, 0x601, "ARMv8 Cortex A57")
+ __PMC_CPU(ARMV8_CORTEX_A57, 0x601, "ARMv8 Cortex A57") \
+ __PMC_CPU(ARMV8_CORTEX_A76, 0x602, "ARMv8 Cortex A76")
enum pmc_cputype {
#undef __PMC_CPU
diff --git a/sys/sys/prng.h b/sys/sys/prng.h
new file mode 100644
index 0000000000000..a1abe6ad1a11d
--- /dev/null
+++ b/sys/sys/prng.h
@@ -0,0 +1,20 @@
+/*-
+ * This file is in the public domain.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_PRNG_H_
+#define _SYS_PRNG_H_
+
+#define PCG_USE_INLINE_ASM 1
+#include <contrib/pcg-c/include/pcg_variants.h>
+
+#ifdef _KERNEL
+__uint32_t prng32(void);
+__uint32_t prng32_bounded(__uint32_t bound);
+__uint64_t prng64(void);
+__uint64_t prng64_bounded(__uint64_t bound);
+#endif
+
+#endif
diff --git a/sys/sys/smp.h b/sys/sys/smp.h
index a7ca84e92bc77..a971ffbbd91b0 100644
--- a/sys/sys/smp.h
+++ b/sys/sys/smp.h
@@ -154,7 +154,6 @@ struct cpu_group *smp_topo_2level(int l2share, int l2count, int l1share,
struct cpu_group *smp_topo_find(struct cpu_group *top, int cpu);
extern void (*cpustop_restartfunc)(void);
-extern int smp_cpus;
/* The suspend/resume cpusets are x86 only, but minimize ifdefs. */
extern volatile cpuset_t resuming_cpus; /* woken up cpus in suspend pen */
extern volatile cpuset_t started_cpus; /* cpus to let out of stop pen */
@@ -169,6 +168,7 @@ extern u_int mp_maxid;
extern int mp_maxcpus;
extern int mp_ncores;
extern int mp_ncpus;
+extern int smp_cpus;
extern volatile int smp_started;
extern int smp_threads_per_core;
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 87c01a9620645..9d736483d0087 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -676,7 +676,6 @@ int vaccess_acl_posix1e(enum vtype type, uid_t file_uid,
gid_t file_gid, struct acl *acl, accmode_t accmode,
struct ucred *cred);
void vattr_null(struct vattr *vap);
-int vcount(struct vnode *vp);
void vlazy(struct vnode *);
void vdrop(struct vnode *);
void vdropl(struct vnode *);
@@ -968,9 +967,13 @@ void vrele(struct vnode *vp);
void vref(struct vnode *vp);
void vrefl(struct vnode *vp);
void vrefact(struct vnode *vp);
-void vrefactn(struct vnode *vp, u_int n);
-int vrefcnt(struct vnode *vp);
void v_addpollinfo(struct vnode *vp);
+static __inline int
+vrefcnt(struct vnode *vp)
+{
+
+ return (vp->v_usecount);
+}
int vnode_create_vobject(struct vnode *vp, off_t size, struct thread *td);
void vnode_destroy_vobject(struct vnode *vp);
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index d90423bd9c5f2..9d0786c1d754a 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -3429,12 +3429,6 @@ cache_alloc(uma_zone_t zone, uma_cache_t cache, void *udata, int flags)
bucket_free(zone, bucket, udata);
}
- /* Short-circuit for zones without buckets and low memory. */
- if (zone->uz_bucket_size == 0 || bucketdisable) {
- critical_enter();
- return (false);
- }
-
/*
* Attempt to retrieve the item from the per-CPU cache has failed, so
* we must go back to the zone. This requires the zdom lock, so we
@@ -3449,11 +3443,12 @@ cache_alloc(uma_zone_t zone, uma_cache_t cache, void *udata, int flags)
VM_DOMAIN_EMPTY(domain))
domain = zone_domain_highest(zone, domain);
bucket = cache_fetch_bucket(zone, cache, domain);
- if (bucket == NULL) {
+ if (bucket == NULL && zone->uz_bucket_size != 0 && !bucketdisable) {
bucket = zone_alloc_bucket(zone, udata, domain, flags);
new = true;
- } else
+ } else {
new = false;
+ }
CTR3(KTR_UMA, "uma_zalloc: zone %s(%p) bucket zone returned %p",
zone->uz_name, zone, bucket);
diff --git a/sys/vm/vm_meter.c b/sys/vm/vm_meter.c
index e316dd5cae0d5..d7d4d8986f152 100644
--- a/sys/vm/vm_meter.c
+++ b/sys/vm/vm_meter.c
@@ -552,6 +552,9 @@ vm_domain_stats_init(struct vm_domain *vmd, struct sysctl_oid *parent)
SYSCTL_ADD_UINT(NULL, SYSCTL_CHILDREN(oid), OID_AUTO,
"free_severe", CTLFLAG_RD, &vmd->vmd_free_severe, 0,
"Severe free pages");
+ SYSCTL_ADD_UINT(NULL, SYSCTL_CHILDREN(oid), OID_AUTO,
+ "inactive_pps", CTLFLAG_RD, &vmd->vmd_inactive_pps, 0,
+ "inactive pages freed/second");
}
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 593af4b5a2e4d..1e6a392d862ca 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -421,7 +421,7 @@ sysctl_vm_page_blacklist(SYSCTL_HANDLER_ARGS)
* In principle, this function only needs to set the flag PG_MARKER.
* Nonetheless, it write busies the page as a safety precaution.
*/
-static void
+void
vm_page_init_marker(vm_page_t marker, int queue, uint16_t aflags)
{
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
index 039e467491d06..a44e31f506d05 100644
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -630,6 +630,7 @@ vm_page_t vm_page_find_least(vm_object_t, vm_pindex_t);
void vm_page_free_invalid(vm_page_t);
vm_page_t vm_page_getfake(vm_paddr_t paddr, vm_memattr_t memattr);
void vm_page_initfake(vm_page_t m, vm_paddr_t paddr, vm_memattr_t memattr);
+void vm_page_init_marker(vm_page_t marker, int queue, uint16_t aflags);
int vm_page_insert (vm_page_t, vm_object_t, vm_pindex_t);
void vm_page_invalid(vm_page_t m);
void vm_page_launder(vm_page_t m);
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index db2aa5f1c1cf9..a882a17f3f398 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/blockcount.h>
#include <sys/eventhandler.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -163,6 +164,12 @@ SYSCTL_INT(_vm, OID_AUTO, panic_on_oom,
SYSCTL_INT(_vm, OID_AUTO, pageout_update_period,
CTLFLAG_RWTUN, &vm_pageout_update_period, 0,
"Maximum active LRU update period");
+
+/* Access with get_pageout_threads_per_domain(). */
+static int pageout_threads_per_domain = 1;
+SYSCTL_INT(_vm, OID_AUTO, pageout_threads_per_domain, CTLFLAG_RDTUN,
+ &pageout_threads_per_domain, 0,
+ "Number of worker threads comprising each per-domain pagedaemon");
SYSCTL_INT(_vm, OID_AUTO, lowmem_period, CTLFLAG_RWTUN, &lowmem_period, 0,
"Low memory callback period");
@@ -1414,22 +1421,22 @@ vm_pageout_reinsert_inactive(struct scan_state *ss, struct vm_batchqueue *bq,
vm_batchqueue_init(bq);
}
-/*
- * Attempt to reclaim the requested number of pages from the inactive queue.
- * Returns true if the shortage was addressed.
- */
-static int
-vm_pageout_scan_inactive(struct vm_domain *vmd, int shortage,
- int *addl_shortage)
+static void
+vm_pageout_scan_inactive(struct vm_domain *vmd, int page_shortage)
{
+ struct timeval start, end;
struct scan_state ss;
struct vm_batchqueue rq;
+ struct vm_page marker_page;
vm_page_t m, marker;
struct vm_pagequeue *pq;
vm_object_t object;
vm_page_astate_t old, new;
- int act_delta, addl_page_shortage, deficit, page_shortage, refs;
- int starting_page_shortage;
+ int act_delta, addl_page_shortage, starting_page_shortage, refs;
+
+ object = NULL;
+ vm_batchqueue_init(&rq);
+ getmicrouptime(&start);
/*
* The addl_page_shortage is an estimate of the number of temporarily
@@ -1440,24 +1447,14 @@ vm_pageout_scan_inactive(struct vm_domain *vmd, int shortage,
addl_page_shortage = 0;
/*
- * vmd_pageout_deficit counts the number of pages requested in
- * allocations that failed because of a free page shortage. We assume
- * that the allocations will be reattempted and thus include the deficit
- * in our scan target.
- */
- deficit = atomic_readandclear_int(&vmd->vmd_pageout_deficit);
- starting_page_shortage = page_shortage = shortage + deficit;
-
- object = NULL;
- vm_batchqueue_init(&rq);
-
- /*
* Start scanning the inactive queue for pages that we can free. The
* scan will stop when we reach the target or we have scanned the
* entire queue. (Note that m->a.act_count is not used to make
* decisions for the inactive queue, only for the active queue.)
*/
- marker = &vmd->vmd_markers[PQ_INACTIVE];
+ starting_page_shortage = page_shortage;
+ marker = &marker_page;
+ vm_page_init_marker(marker, PQ_INACTIVE, 0);
pq = &vmd->vmd_pagequeues[PQ_INACTIVE];
vm_pagequeue_lock(pq);
vm_pageout_init_scan(&ss, pq, marker, NULL, pq->pq_cnt);
@@ -1637,7 +1634,97 @@ reinsert:
vm_pageout_end_scan(&ss);
vm_pagequeue_unlock(pq);
- VM_CNT_ADD(v_dfree, starting_page_shortage - page_shortage);
+ /*
+ * Record the remaining shortage and the progress and rate it was made.
+ */
+ atomic_add_int(&vmd->vmd_addl_shortage, addl_page_shortage);
+ getmicrouptime(&end);
+ timevalsub(&end, &start);
+ atomic_add_int(&vmd->vmd_inactive_us,
+ end.tv_sec * 1000000 + end.tv_usec);
+ atomic_add_int(&vmd->vmd_inactive_freed,
+ starting_page_shortage - page_shortage);
+}
+
+/*
+ * Dispatch a number of inactive threads according to load and collect the
+ * results to prevent a coherent (CEM: incoherent?) view of paging activity on
+ * this domain.
+ */
+static int
+vm_pageout_inactive_dispatch(struct vm_domain *vmd, int shortage)
+{
+ u_int freed, pps, threads, us;
+
+ vmd->vmd_inactive_shortage = shortage;
+
+ /*
+ * If we have more work than we can do in a quarter of our interval, we
+ * fire off multiple threads to process it.
+ */
+ if (vmd->vmd_inactive_threads > 1 && vmd->vmd_inactive_pps != 0 &&
+ shortage > vmd->vmd_inactive_pps / VM_INACT_SCAN_RATE / 4) {
+ threads = vmd->vmd_inactive_threads;
+ vm_domain_pageout_lock(vmd);
+ vmd->vmd_inactive_shortage /= threads;
+ blockcount_acquire(&vmd->vmd_inactive_starting, threads - 1);
+ blockcount_acquire(&vmd->vmd_inactive_running, threads - 1);
+ wakeup(&vmd->vmd_inactive_shortage);
+ vm_domain_pageout_unlock(vmd);
+ }
+
+ /* Run the local thread scan. */
+ vm_pageout_scan_inactive(vmd, vmd->vmd_inactive_shortage);
+
+ /*
+ * Block until helper threads report results and then accumulate
+ * totals.
+ */
+ blockcount_wait(&vmd->vmd_inactive_running, NULL, "vmpoid", PVM);
+ freed = atomic_readandclear_int(&vmd->vmd_inactive_freed);
+ VM_CNT_ADD(v_dfree, freed);
+
+ /*
+ * Calculate the per-thread paging rate with an exponential decay of
+ * prior results. Careful to avoid integer rounding errors with large
+ * us values.
+ */
+ us = max(atomic_readandclear_int(&vmd->vmd_inactive_us), 1);
+ if (us > 1000000)
+ /* Keep rounding to tenths */
+ pps = (freed * 10) / ((us * 10) / 1000000);
+ else
+ pps = (1000000 / us) * freed;
+ vmd->vmd_inactive_pps = (vmd->vmd_inactive_pps / 2) + (pps / 2);
+
+ return (shortage - freed);
+}
+
+/*
+ * Attempt to reclaim the requested number of pages from the inactive queue.
+ * Returns true if the shortage was addressed.
+ */
+static int
+vm_pageout_inactive(struct vm_domain *vmd, int shortage, int *addl_shortage)
+{
+ struct vm_pagequeue *pq;
+ u_int addl_page_shortage, deficit, page_shortage;
+ u_int starting_page_shortage;
+
+ /*
+ * vmd_pageout_deficit counts the number of pages requested in
+ * allocations that failed because of a free page shortage. We assume
+ * that the allocations will be reattempted and thus include the deficit
+ * in our scan target.
+ */
+ deficit = atomic_readandclear_int(&vmd->vmd_pageout_deficit);
+ starting_page_shortage = shortage + deficit;
+
+ /*
+ * Run the inactive scan on as many threads as is necessary.
+ */
+ page_shortage = vm_pageout_inactive_dispatch(vmd, starting_page_shortage);
+ addl_page_shortage = atomic_readandclear_int(&vmd->vmd_addl_shortage);
/*
* Wake up the laundry thread so that it can perform any needed
@@ -2066,7 +2153,7 @@ vm_pageout_worker(void *arg)
if (vm_pageout_lowmem() && vmd->vmd_free_count > ofree)
shortage -= min(vmd->vmd_free_count - ofree,
(u_int)shortage);
- target_met = vm_pageout_scan_inactive(vmd, shortage,
+ target_met = vm_pageout_inactive(vmd, shortage,
&addl_shortage);
} else
addl_shortage = 0;
@@ -2082,6 +2169,72 @@ vm_pageout_worker(void *arg)
}
/*
+ * vm_pageout_helper runs additional pageout daemons in times of high paging
+ * activity.
+ */
+static void
+vm_pageout_helper(void *arg)
+{
+ struct vm_domain *vmd;
+ int domain;
+
+ domain = (uintptr_t)arg;
+ vmd = VM_DOMAIN(domain);
+
+ vm_domain_pageout_lock(vmd);
+ for (;;) {
+ msleep(&vmd->vmd_inactive_shortage,
+ vm_domain_pageout_lockptr(vmd), PVM, "psleep", 0);
+ blockcount_release(&vmd->vmd_inactive_starting, 1);
+
+ vm_domain_pageout_unlock(vmd);
+ vm_pageout_scan_inactive(vmd, vmd->vmd_inactive_shortage);
+ vm_domain_pageout_lock(vmd);
+
+ /*
+ * Release the running count while the pageout lock is held to
+ * prevent wakeup races.
+ */
+ blockcount_release(&vmd->vmd_inactive_running, 1);
+ }
+}
+
+static int
+get_pageout_threads_per_domain(void)
+{
+ static bool resolved = false;
+ int half_cpus_per_dom;
+
+ /*
+ * This is serialized externally by the sorted autoconfig portion of
+ * boot.
+ */
+ if (__predict_true(resolved))
+ return (pageout_threads_per_domain);
+
+ /*
+ * Semi-arbitrarily constrain pagedaemon threads to less than half the
+ * total number of threads in the system as an insane upper limit.
+ */
+ half_cpus_per_dom = howmany(mp_ncpus / vm_ndomains, 2);
+
+ if (pageout_threads_per_domain < 1) {
+ printf("Invalid tuneable vm.pageout_threads_per_domain value: "
+ "%d out of valid range: [1-%d]; clamping to 1\n",
+ pageout_threads_per_domain, half_cpus_per_dom);
+ pageout_threads_per_domain = 1;
+ } else if (pageout_threads_per_domain > half_cpus_per_dom) {
+ printf("Invalid tuneable vm.pageout_threads_per_domain value: "
+ "%d out of valid range: [1-%d]; clamping to %d\n",
+ pageout_threads_per_domain, half_cpus_per_dom,
+ half_cpus_per_dom);
+ pageout_threads_per_domain = half_cpus_per_dom;
+ }
+ resolved = true;
+ return (pageout_threads_per_domain);
+}
+
+/*
* Initialize basic pageout daemon settings. See the comment above the
* definition of vm_domain for some explanation of how these thresholds are
* used.
@@ -2134,6 +2287,8 @@ vm_pageout_init_domain(int domain)
oid = SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(vmd->vmd_oid), OID_AUTO,
"pidctrl", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "");
pidctrl_init_sysctl(&vmd->vmd_pid, SYSCTL_CHILDREN(oid));
+
+ vmd->vmd_inactive_threads = get_pageout_threads_per_domain();
}
static void
@@ -2184,10 +2339,11 @@ vm_pageout(void)
{
struct proc *p;
struct thread *td;
- int error, first, i;
+ int error, first, i, j, pageout_threads;
p = curproc;
td = curthread;
+ pageout_threads = get_pageout_threads_per_domain();
mtx_init(&vm_oom_ratelim_mtx, "vmoomr", NULL, MTX_DEF);
swap_pager_swap_init();
@@ -2207,6 +2363,14 @@ vm_pageout(void)
panic("starting pageout for domain %d: %d\n",
i, error);
}
+ for (j = 0; j < pageout_threads - 1; j++) {
+ error = kthread_add(vm_pageout_helper,
+ (void *)(uintptr_t)i, p, NULL, 0, 0,
+ "dom%d helper%d", i, j);
+ if (error != 0)
+ panic("starting pageout helper %d for domain "
+ "%d: %d\n", j, i, error);
+ }
error = kthread_add(vm_pageout_laundry_worker,
(void *)(uintptr_t)i, p, NULL, 0, 0, "laundry: dom%d", i);
if (error != 0)
diff --git a/sys/vm/vm_pagequeue.h b/sys/vm/vm_pagequeue.h
index 0573457db675b..0e5d1c911b8dc 100644
--- a/sys/vm/vm_pagequeue.h
+++ b/sys/vm/vm_pagequeue.h
@@ -84,6 +84,7 @@ struct vm_batchqueue {
} __aligned(CACHE_LINE_SIZE);
#include <vm/uma.h>
+#include <sys/_blockcount.h>
#include <sys/pidctrl.h>
struct sysctl_oid;
@@ -254,6 +255,14 @@ struct vm_domain {
/* Paging control variables, used within single threaded page daemon. */
struct pidctrl vmd_pid; /* Pageout controller. */
boolean_t vmd_oom;
+ u_int vmd_inactive_threads;
+ u_int vmd_inactive_shortage; /* Per-thread shortage. */
+ blockcount_t vmd_inactive_running; /* Number of inactive threads. */
+ blockcount_t vmd_inactive_starting; /* Number of threads started. */
+ volatile u_int vmd_addl_shortage; /* Shortage accumulator. */
+ volatile u_int vmd_inactive_freed; /* Successful inactive frees. */
+ volatile u_int vmd_inactive_us; /* Microseconds for above. */
+ u_int vmd_inactive_pps; /* Exponential decay frees/second. */
int vmd_oom_seq;
int vmd_last_active_scan;
struct vm_page vmd_markers[PQ_COUNT]; /* (q) markers for queue scans */
diff --git a/tests/sys/fs/fusefs/forget.cc b/tests/sys/fs/fusefs/forget.cc
index 8a53ac0ecaa69..c138b7acc4aa5 100644
--- a/tests/sys/fs/fusefs/forget.cc
+++ b/tests/sys/fs/fusefs/forget.cc
@@ -116,6 +116,7 @@ TEST_F(Forget, invalidate_names)
int err;
EXPECT_LOOKUP(FUSE_ROOT_ID, DNAME)
+ .Times(2)
.WillRepeatedly(Invoke(
ReturnImmediate([=](auto in __unused, auto& out) {
SET_OUT_HEADER_LEN(out, entry);
@@ -142,7 +143,7 @@ TEST_F(Forget, invalidate_names)
out.body.entry.attr_valid = UINT64_MAX;
out.body.entry.entry_valid = UINT64_MAX;
})));
- expect_forget(dir_ino, 2);
+ expect_forget(dir_ino, 1);
/* Access the file to cache its name */
ASSERT_EQ(0, access(FULLFPATH, F_OK)) << strerror(errno);
diff --git a/tools/build/Makefile b/tools/build/Makefile
index 73eeac3ee09a4..23bd6cc1896f4 100644
--- a/tools/build/Makefile
+++ b/tools/build/Makefile
@@ -92,6 +92,12 @@ DISKINCS+= ${SRCTOP}/sys/sys/disk/bsd.h
SYSINCS+= ${SRCTOP}/sys/sys/nv.h ${SRCTOP}/sys/sys/cnv.h \
${SRCTOP}/sys/sys/dnv.h
+# Needed when bootstrapping ldd (since it uses DF_1_PIE)
+SYSINCS+= ${SRCTOP}/sys/sys/elf32.h
+SYSINCS+= ${SRCTOP}/sys/sys/elf64.h
+SYSINCS+= ${SRCTOP}/sys/sys/elf_common.h
+SYSINCS+= ${SRCTOP}/sys/sys/elf_generic.h
+
# vtfontcvt is using sys/font.h
SYSINCS+= ${SRCTOP}/sys/sys/font.h
@@ -107,8 +113,8 @@ SYSINCS+= ${SRCTOP}/sys/sys/font.h
# Linux/MacOS since we only use flags that are supported by all of them.
_host_tools_to_symlink= basename bzip2 bunzip2 chmod chown cmp comm cp date dd \
dirname echo env false find fmt gzip gunzip head hostname id ln ls \
- mkdir mv nice patch rm realpath sh sleep stat tee touch tr true uname \
- uniq wc which
+ mkdir mv nice patch rm realpath sh sleep stat tee touch tr true \
+ uname uniq wc which
# We also need a symlink to the absolute path to the make binary used for
# the toplevel makefile. This is not necessarily the same as `which make`
diff --git a/tools/debugscripts/kgdb b/tools/debugscripts/kgdb
deleted file mode 100644
index ae580b301d417..0000000000000
--- a/tools/debugscripts/kgdb
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/bin/sh -
-#
-# Copyright 2004 John-Mark Gurney
-# 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, 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$
-
-crashpath="/var/crash"
-kld_debpy="kld_deb.py"
-
-if [ x"$1" = x"-?" -o x"$1" = x"-h" ]; then
- echo "Usage: $0 <corenum> [ <gdbcmdfile> [ <modulepaths> ] ]"
- echo ""
- echo "Path for crash dumps: $crashpath"
- exit 1
-fi
-
-if [ x"$1" = x"" ]; then
- echo "Need core number."
- exit 1
-fi
-corenum="$1"
-shift
-
-cmd_file=""
-if [ x"$2" != x"" ]; then
- cmd_file="-x $2"
- shift
-fi
-
-core="$crashpath/vmcore.$corenum"
-info="$crashpath/info.$corenum"
-
-#Get the kernel source compile dir from the info file
-kernsrc="`awk 'i == 1 { split($0, a, ":"); print a[2]; i = 0 } $1 == "Versionstring:" { i = 1 }' < "$info"`"
-
-tmpfile="/tmp/kgdb.asf.$$"
-# -mapped (broken?)
-# -x command_file
-echo "Kernel Source: $kernsrc"
-echo "Getting KLD information and locations..."
-python $kld_debpy "$kernsrc" "$core" $@ > "$tmpfile" &&
-echo "Please run the following command to load module symbols:"
-echo "source $tmpfile"
-(cd "$kernsrc"; kgdb "$kernsrc/kernel.debug" "$core")
-rm "$tmpfile"
diff --git a/tools/tools/locale/Makefile b/tools/tools/locale/Makefile
index 508034d196950..aad2c2160bb5d 100644
--- a/tools/tools/locale/Makefile
+++ b/tools/tools/locale/Makefile
@@ -7,19 +7,30 @@
#
# Modified by John Marino to suit DragonFly needs
#
+.if ${.CURDIR} == ${.OBJDIR}
+.error Do make obj first.
+.endif
-.OBJDIR: .
+LOCALESRCDIR?= ${DESTDIR}/usr/src/share
+TMPDIR?= /tmp
-.if !defined(UNIDIR)
-.error UNIDIR is not set
-.endif
-PASSON= UNIDIR="${UNIDIR}"
+BASEDIR= ${.CURDIR}
+ETCDIR= ${BASEDIR}/etc
+TOOLSDIR= ${BASEDIR}/tools
+PATCHDIR= ${BASEDIR}/patch
+UNIDIR= ${.OBJDIR:tA}/unicode
-ETCDIR= ${.CURDIR}/etc
+PKGS= openjdk8 \
+ apache-ant \
+ p5-XML-Parser \
+ p5-Tie-IxHash \
+ p5-Text-Iconv
+tools-test:
+ pkg info -e ${PKGS}
+ @echo tools ok.
KNOWN= monetdef numericdef msgdef colldef ctypedef # timedef
TYPES?= ${KNOWN}
-LOCALE_DESTDIR?= /tmp/generated-locales/
COLLATION_SPECIAL?= \
cs_CZ ISO8859-2 \
@@ -44,65 +55,79 @@ COLLATION_SPECIAL?= \
.for area enc in ${COLLATION_SPECIAL}
COLLATIONS_SPECIAL_ENV+= ${area}.${enc}
.endfor
-PASSON+= COLLATIONS_SPECIAL="${COLLATIONS_SPECIAL_ENV}"
+SETENV= env -i \
+ PATH="${PATH}" \
+ TMPDIR="${TMPDIR}" \
+ COLLATIONS_SPECIAL="${COLLATIONS_SPECIAL_ENV}" \
+ UNIDIR="${UNIDIR}" \
+ BASEDIR="${BASEDIR}" \
+ TOOLSDIR="${TOOLSDIR}" \
+ ETCDIR="${ETCDIR}"
+
+all: posix build afterbuild
+.ORDER: posix build afterbuild
+
+afterbuild: build
+ @echo ""
+ @find . -name *failed
-all:
.for t in ${TYPES}
. if ${KNOWN:M${t}}
- test -d ${t} || mkdir ${t}
- make build-${t}
+build: build-${t}
+.ORDER: build-${t} afterbuild
. endif
.endfor
- @echo ""
- @find . -name *failed
+diff:
.for t in ${TYPES}
+. if ${KNOWN:M${t}}
+diff: diff-${t}
+diff-${t}:
+ -/usr/bin/diff -ruN -x Makefile -x Makefile.depend \
+ ${LOCALESRCDIR}/${t} ${t}
+. endif
+.endfor
+
+install:
+.for t in ${TYPES}
+. if ${KNOWN:M${t}}
install: install-${t}
install-${t}:
-. if ${KNOWN:M${t}}
- rm -rf ${.CURDIR}/${t}.draft
- rm -f ${.CURDIR}/../../../share/${t}/Makefile
- rm -f ${.CURDIR}/../../../share/${t}/*.src
- mv ${.CURDIR}/${t}/* ${.CURDIR}/../../../share/${t}/
+ cd ${LOCALESRCDIR}/${t} && \
+ rm -f Makefile *.src && \
+ install -c ${t}/* ${LOCALESRCDIR}/${t}
. endif
.endfor
post-install:
.for t in ${TYPES}
. if ${KNOWN:M${t}}
- (cd ${.CURDIR}/../../../share/${t} && \
- make && make install && make clean)
+ cd ${LOCALSRCDIR}/${t} && \
+ make && make install && make clean
. endif
.endfor
.for t in ${TYPES}
-gen-${t}:
- mkdir -p ${t} ${t}.draft
- perl -I tools tools/cldr2def.pl \
- --unidir=$$(realpath ${UNIDIR}) \
- --etc=$$(realpath ${ETCDIR}) \
+CLEANDIRS+= ${t} ${t}.draft
+${t}:
+ mkdir -p ${t} ${t}.draft && \
+ perl -I ${TOOLSDIR} ${TOOLSDIR}/cldr2def.pl \
+ --unidir=${UNIDIR:tA} \
+ --etc=${ETCDIR:tA} \
--type=${t}
-build-${t}: gen-${t}
- env ${PASSON} tools/finalize ${t}
+build-${t}: ${t}
+ ${SETENV} OUTBASEDIR="${.OBJDIR}/${t}" ${TOOLSDIR}/finalize ${t}
.endfor
-gen-ctypedef: ctype-rollup
-static-colldef: gen-colldef
+static-colldef: colldef
build-colldef: static-colldef
static-colldef:
.for area enc in ${COLLATION_SPECIAL}
- awk -f tools/extract-colldef.awk ${UNIDIR}/posix/${area}.${enc}.src > \
- colldef.draft/${area}.${enc}.src
-.endfor
-
-ctype-rollup:
- perl -I tools tools/utf8-rollup.pl --unidir=$$(realpath ${UNIDIR})
-
-clean:
-.for t in ${TYPES}
- rm -rf ${t} ${t}.draft
+colldef.draft/${area}.${enc}.src: posix/${area}.${enc}.src
+ awk -f ${TOOLSDIR}/extract-colldef.awk \
+ ${.ALLSRC} > ${.TARGET} || (rm -f ${.TARGET} && false)
.endfor
BASE_LOCALES_OF_INTEREST?= \
@@ -145,31 +170,71 @@ ENCODINGS= Big5 \
US-ASCII \
UTF-8
-POSIX: posixsrc posixcol posixcm
+# CLDR files
+CLDRFILES_CORE= https://unicode.org/Public/cldr/35/core.zip
+CLDRFILES_KEY= https://unicode.org/Public/cldr/35/keyboards.zip
+CLDRFILES_TOOLS=https://unicode.org/Public/cldr/35/tools.zip
+CLDRFILES_UCD= http://www.unicode.org/Public/zipped/latest/UCD.zip
+
+# fetch and extract targets
+${UNIDIR}:
+ mkdir -p ${UNIDIR}
+.for N in CORE KEY TOOLS UCD
+${CLDRFILES_${N}:T}:
+ fetch ${CLDRFILES_${N}}
+fetch: ${CLDRFILES_${N}:T}
+extract-${CLDRFILES_${N}:T}:: ${CLDRFILES_${N}:T} ${UNIDIR}
+ cd ${UNIDIR} && unzip -o ../${CLDRFILES_${N}:T}
+extract: extract-${CLDRFILES_${N}:T}
+.endfor
+patch::
+.if exists(${PATCHDIR})
+ cd ${UNIDIR} && cat ${PATCHDIR}/patch-* | patch
+.endif
+
.if !exists(${UNIDIR}/tools/java/cldr.jar)
-.error check README about building cldr.jar
+.ORDER: extract patch
+build-tools: extract patch tools-test ${UNIDIR}
+ cd ${UNIDIR}/tools/java && ${SETENV} ant all jar
+.else
+build-tools:
+ @echo cldr.jar is ready.
.endif
+
+JAVA_CLDR= java -DCLDR_DIR=${UNIDIR:Q} -jar ${UNIDIR}/tools/java/cldr.jar
+
+posix: posixcm post-posixcm posixsrc posixcol
+.ORDER: posixcm post-posixcm posixsrc posixcol
+${UNIDIR}/posix:
+ ln -s -f ../posix ${.TARGET}
+clean-posix:
+ rm -rf posix ${UNIDIR}/posix
+post-posixcm: ${UNIDIR}/posix
+ perl -I ${TOOLSDIR} ${TOOLSDIR}/utf8-rollup.pl \
+ --unidir=${UNIDIR}
+.for enc in ${ENCODINGS}
+posixcm: build-tools posix/${enc}.cm
+.ORDER: build-tools posix/${enc}.cm
+posix/${enc}.cm:
+ mkdir -p posix && \
+ ${JAVA_CLDR} org.unicode.cldr.posix.GenerateCharmap \
+ -d posix -c ${enc}
+.endfor
.for area in ${BASE_LOCALES_OF_INTEREST}
-posixsrc: ${UNIDIR}/posix/${area}.UTF-8.src
-${UNIDIR}/posix/${area}.UTF-8.src:
- java -DCLDR_DIR=${UNIDIR:Q} -jar ${UNIDIR}/tools/java/cldr.jar \
- org.unicode.cldr.posix.GeneratePOSIX \
- -d ${UNIDIR}/posix -m ${area} -c UTF-8
+posixsrc: build-tools posix/${area}.UTF-8.src
+.ORDER: build-tools posix/${area}.UTF-8.src
+posix/${area}.UTF-8.src:
+ mkdir -p posix && \
+ ${JAVA_CLDR} org.unicode.cldr.posix.GeneratePOSIX \
+ -d posix -m ${area} -c UTF-8
.endfor
.for area encoding in ${COLLATION_SPECIAL}
-posixcol: ${UNIDIR}/posix/${area}.${encoding}.src
-${UNIDIR}/posix/${area}.${encoding}.src:
- java -DCLDR_DIR=${UNIDIR:Q} -jar ${UNIDIR}/tools/java/cldr.jar \
- org.unicode.cldr.posix.GeneratePOSIX \
- -d ${UNIDIR}/posix -m ${area} -c ${encoding}
-.endfor
-.for enc in ${ENCODINGS}
-posixcm: ${UNIDIR}/posix/${enc}.cm
-${UNIDIR}/posix/${enc}.cm:
- java -DCLDR_DIR=${UNIDIR:Q} -jar ${UNIDIR}/tools/java/cldr.jar \
- org.unicode.cldr.posix.GenerateCharmap \
- -d ${UNIDIR}/posix -c ${enc}
+posixcol: build-tools posix/${area}.${encoding}.src
+.ORDER: build-tools posix/${area}.${encoding}.src
+posix/${area}.${encoding}.src:
+ mkdir -p posix && \
+ ${JAVA_CLDR} org.unicode.cldr.posix.GeneratePOSIX \
+ -d posix -m ${area} -c ${encoding}
.endfor
-clean-POSIX:
- rm -f ${UNIDIR}/posix/*
+.include <bsd.obj.mk>
diff --git a/tools/tools/locale/README b/tools/tools/locale/README
index 60357d4d8dfee..8dc8c2a25fc12 100644
--- a/tools/tools/locale/README
+++ b/tools/tools/locale/README
@@ -1,32 +1,58 @@
# $FreeBSD$
-To generate the locales:
-
-Tools needed:
- java (openjdk >= 8)
- perl
- converters/p5-Text-Iconv
- devel/apache-ant
- devel/p5-Tie-IxHash
- textproc/p5-XML-Parser
-
-1. Fetch CLDR data from: http://unicode.org/Public/cldr/. You need all of the
-core.zip, keyboards.zip, and tools.zip.
-2. Fetch unidata (UCD.zip) from http://www.unicode.org/Public/zipped/latest.
-3. Extract:
- mkdir -p ~/unicode
- cd ~/unicode
- unzip ~/core.zip
- unzip ~/keyboards.zip
- unzip ~/tools.zip
- unzip ~/UCD.zip
-4. Export variable:
- UNIDIR=~/unicode; export UNIDIR
-5. Build the CLDR tools:
- cd $UNIDIR/tools/java
- ant jar
-6. Build POSIX data files from CLDR data:
- make POSIX
-7. Build and install new locale data:
- make
+Files in this directory are used to generate locale source files
+from files in CLDR (Unicode Common Locale Data Repository).
+
+To generate the files, do the following:
+
+ cd /usr/src/tools/tools/locale
+ make obj (mandatory)
+ make -j16 (-jN recommended)
+ make diff (check if the changes are reasonable)
+ make install
+
+"make" downloads the necessary files, build them, and install the
+results into /usr/src/share/* as source files for locales.
+
+More details are as follows:
+
+Variables:
+ LOCALESRCDIR
+ Destination path for the generated locale files.
+ Default: $DESTDIR/usr/src/share.
+ TMPDIR
+ Temporary directory.
+ Default: /tmp
+
+Targets:
+ make obj
+ Create a temporary directory for building.
+
+ make clean
+ Clean up the obj directories.
+
+ make cleandir
+ Remove the obj directories completely.
+
+ make tools-test
+ Check if necessary tools are installed or not.
+ If something is missing, install them.
+
+ make fetch
+ Download necessary files from CLDR.
+
+ make build-tools
+ Build a tool to generate locale source files.
+
+ make posix
+ Build POSIX locale source files.
+
+ make build
+ Build locale files.
+
+ make diff
+ Run diff(1) the build results against $LOCALESRCDIR.
+
make install
+ Install the build results into $LOCALESRCDIR.
+[EOF]
diff --git a/tools/tools/locale/etc/final-maps/map.UTF-8 b/tools/tools/locale/etc/final-maps/map.UTF-8
index 031b8545982de..ad0dfd2c7de68 100644
--- a/tools/tools/locale/etc/final-maps/map.UTF-8
+++ b/tools/tools/locale/etc/final-maps/map.UTF-8
@@ -2969,6 +2969,7 @@ CHARMAP
<TELUGU_DIGIT_SEVEN> \xE0\xB1\xAD
<TELUGU_DIGIT_EIGHT> \xE0\xB1\xAE
<TELUGU_DIGIT_NINE> \xE0\xB1\xAF
+<TELUGU_SIGN_SIDDHAM> \xE0\xB1\xB7
<TELUGU_FRACTION_DIGIT_ZERO_FOR_ODD_POWERS_OF_FOUR> \xE0\xB1\xB8
<TELUGU_FRACTION_DIGIT_ONE_FOR_ODD_POWERS_OF_FOUR> \xE0\xB1\xB9
<TELUGU_FRACTION_DIGIT_TWO_FOR_ODD_POWERS_OF_FOUR> \xE0\xB1\xBA
@@ -3363,14 +3364,24 @@ CHARMAP
<LAO_LETTER_KO> \xE0\xBA\x81
<LAO_LETTER_KHO_SUNG> \xE0\xBA\x82
<LAO_LETTER_KHO_TAM> \xE0\xBA\x84
+<LAO_LETTER_PALI_GHA> \xE0\xBA\x86
<LAO_LETTER_NGO> \xE0\xBA\x87
<LAO_LETTER_CO> \xE0\xBA\x88
+<LAO_LETTER_PALI_CHA> \xE0\xBA\x89
<LAO_LETTER_SO_TAM> \xE0\xBA\x8A
+<LAO_LETTER_PALI_JHA> \xE0\xBA\x8C
<LAO_LETTER_NYO> \xE0\xBA\x8D
+<LAO_LETTER_PALI_NYA> \xE0\xBA\x8E
+<LAO_LETTER_PALI_TTA> \xE0\xBA\x8F
+<LAO_LETTER_PALI_TTHA> \xE0\xBA\x90
+<LAO_LETTER_PALI_DDA> \xE0\xBA\x91
+<LAO_LETTER_PALI_DDHA> \xE0\xBA\x92
+<LAO_LETTER_PALI_NNA> \xE0\xBA\x93
<LAO_LETTER_DO> \xE0\xBA\x94
<LAO_LETTER_TO> \xE0\xBA\x95
<LAO_LETTER_THO_SUNG> \xE0\xBA\x96
<LAO_LETTER_THO_TAM> \xE0\xBA\x97
+<LAO_LETTER_PALI_DHA> \xE0\xBA\x98
<LAO_LETTER_NO> \xE0\xBA\x99
<LAO_LETTER_BO> \xE0\xBA\x9A
<LAO_LETTER_PO> \xE0\xBA\x9B
@@ -3378,13 +3389,17 @@ CHARMAP
<LAO_LETTER_FO_TAM> \xE0\xBA\x9D
<LAO_LETTER_PHO_TAM> \xE0\xBA\x9E
<LAO_LETTER_FO_SUNG> \xE0\xBA\x9F
+<LAO_LETTER_PALI_BHA> \xE0\xBA\xA0
<LAO_LETTER_MO> \xE0\xBA\xA1
<LAO_LETTER_YO> \xE0\xBA\xA2
<LAO_LETTER_LO_LING> \xE0\xBA\xA3
<LAO_LETTER_LO_LOOT> \xE0\xBA\xA5
<LAO_LETTER_WO> \xE0\xBA\xA7
+<LAO_LETTER_SANSKRIT_SHA> \xE0\xBA\xA8
+<LAO_LETTER_SANSKRIT_SSA> \xE0\xBA\xA9
<LAO_LETTER_SO_SUNG> \xE0\xBA\xAA
<LAO_LETTER_HO_SUNG> \xE0\xBA\xAB
+<LAO_LETTER_PALI_LLA> \xE0\xBA\xAC
<LAO_LETTER_O> \xE0\xBA\xAD
<LAO_LETTER_HO_TAM> \xE0\xBA\xAE
<LAO_ELLIPSIS> \xE0\xBA\xAF
@@ -3398,6 +3413,7 @@ CHARMAP
<LAO_VOWEL_SIGN_YY> \xE0\xBA\xB7
<LAO_VOWEL_SIGN_U> \xE0\xBA\xB8
<LAO_VOWEL_SIGN_UU> \xE0\xBA\xB9
+<LAO_SIGN_PALI_VIRAMA> \xE0\xBA\xBA
<LAO_VOWEL_SIGN_MAI_KON> \xE0\xBA\xBB
<LAO_SEMIVOWEL_SIGN_LO> \xE0\xBA\xBC
<LAO_SEMIVOWEL_SIGN_NYO> \xE0\xBA\xBD
@@ -6656,6 +6672,7 @@ CHARMAP
<VEDIC_SIGN_ATIKRAMA> \xE1\xB3\xB7
<VEDIC_TONE_RING_ABOVE> \xE1\xB3\xB8
<VEDIC_TONE_DOUBLE_RING_ABOVE> \xE1\xB3\xB9
+<VEDIC_SIGN_DOUBLE_ANUSVARA_ANTARGOMUKHA> \xE1\xB3\xBA
<LATIN_LETTER_SMALL_CAPITAL_A> \xE1\xB4\x80
<LATIN_LETTER_SMALL_CAPITAL_AE> \xE1\xB4\x81
<LATIN_SMALL_LETTER_TURNED_AE> \xE1\xB4\x82
@@ -10325,6 +10342,7 @@ CHARMAP
<BLACK_MEDIUM_DOWN-POINTING_TRIANGLE_CENTRED> \xE2\xAF\x86
<BLACK_MEDIUM_LEFT-POINTING_TRIANGLE_CENTRED> \xE2\xAF\x87
<BLACK_MEDIUM_RIGHT-POINTING_TRIANGLE_CENTRED> \xE2\xAF\x88
+<NEPTUNE_FORM_TWO> \xE2\xAF\x89
<TOP_HALF_BLACK_CIRCLE> \xE2\xAF\x8A
<BOTTOM_HALF_BLACK_CIRCLE> \xE2\xAF\x8B
<LIGHT_FOUR_POINTED_BLACK_CUSP> \xE2\xAF\x8C
@@ -10378,6 +10396,7 @@ CHARMAP
<DOUBLED_SYMBOL> \xE2\xAF\xBC
<PASSED_SYMBOL> \xE2\xAF\xBD
<REVERSED_RIGHT_ANGLE> \xE2\xAF\xBE
+<HELLSCHREIBER_PAUSE_SYMBOL> \xE2\xAF\xBF
<GLAGOLITIC_CAPITAL_LETTER_AZU> \xE2\xB0\x80
<GLAGOLITIC_CAPITAL_LETTER_BUKY> \xE2\xB0\x81
<GLAGOLITIC_CAPITAL_LETTER_VEDE> \xE2\xB0\x82
@@ -10916,6 +10935,7 @@ CHARMAP
<MEDIEVAL_COMMA> \xE2\xB9\x8C
<PARAGRAPHUS_MARK> \xE2\xB9\x8D
<PUNCTUS_ELEVATUS_MARK> \xE2\xB9\x8E
+<CORNISH_VERSE_DIVIDER> \xE2\xB9\x8F
<CJK_RADICAL_REPEAT> \xE2\xBA\x80
<CJK_RADICAL_CLIFF> \xE2\xBA\x81
<CJK_RADICAL_SECOND_ONE> \xE2\xBA\x82
@@ -41812,6 +41832,17 @@ CHARMAP
<LATIN_SMALL_LETTER_OMEGA> \xEA\x9E\xB7
<LATIN_CAPITAL_LETTER_U_WITH_STROKE> \xEA\x9E\xB8
<LATIN_SMALL_LETTER_U_WITH_STROKE> \xEA\x9E\xB9
+<LATIN_CAPITAL_LETTER_GLOTTAL_A> \xEA\x9E\xBA
+<LATIN_SMALL_LETTER_GLOTTAL_A> \xEA\x9E\xBB
+<LATIN_CAPITAL_LETTER_GLOTTAL_I> \xEA\x9E\xBC
+<LATIN_SMALL_LETTER_GLOTTAL_I> \xEA\x9E\xBD
+<LATIN_CAPITAL_LETTER_GLOTTAL_U> \xEA\x9E\xBE
+<LATIN_SMALL_LETTER_GLOTTAL_U> \xEA\x9E\xBF
+<LATIN_CAPITAL_LETTER_ANGLICANA_W> \xEA\x9F\x82
+<LATIN_SMALL_LETTER_ANGLICANA_W> \xEA\x9F\x83
+<LATIN_CAPITAL_LETTER_C_WITH_PALATAL_HOOK> \xEA\x9F\x84
+<LATIN_CAPITAL_LETTER_S_WITH_HOOK> \xEA\x9F\x85
+<LATIN_CAPITAL_LETTER_Z_WITH_PALATAL_HOOK> \xEA\x9F\x86
<LATIN_EPIGRAPHIC_LETTER_SIDEWAYS_I> \xEA\x9F\xB7
<MODIFIER_LETTER_CAPITAL_H_WITH_STROKE> \xEA\x9F\xB8
<MODIFIER_LETTER_SMALL_LIGATURE_OE> \xEA\x9F\xB9
@@ -42577,6 +42608,8 @@ CHARMAP
<LATIN_SMALL_LETTER_UO> \xEA\xAD\xA3
<LATIN_SMALL_LETTER_INVERTED_ALPHA> \xEA\xAD\xA4
<GREEK_LETTER_SMALL_CAPITAL_OMEGA> \xEA\xAD\xA5
+<LATIN_SMALL_LETTER_DZ_DIGRAPH_WITH_RETROFLEX_HOOK> \xEA\xAD\xA6
+<LATIN_SMALL_LETTER_TS_DIGRAPH_WITH_RETROFLEX_HOOK> \xEA\xAD\xA7
<CHEROKEE_SMALL_LETTER_A> \xEA\xAD\xB0
<CHEROKEE_SMALL_LETTER_E> \xEA\xAD\xB1
<CHEROKEE_SMALL_LETTER_I> \xEA\xAD\xB2
@@ -64381,6 +64414,29 @@ CHARMAP
<SOGDIAN_PUNCTUATION_CIRCLE_WITH_DOT> \xF0\x90\xBD\x97
<SOGDIAN_PUNCTUATION_TWO_CIRCLES_WITH_DOTS> \xF0\x90\xBD\x98
<SOGDIAN_PUNCTUATION_HALF_CIRCLE_WITH_DOT> \xF0\x90\xBD\x99
+<ELYMAIC_LETTER_ALEPH> \xF0\x90\xBF\xA0
+<ELYMAIC_LETTER_BETH> \xF0\x90\xBF\xA1
+<ELYMAIC_LETTER_GIMEL> \xF0\x90\xBF\xA2
+<ELYMAIC_LETTER_DALETH> \xF0\x90\xBF\xA3
+<ELYMAIC_LETTER_HE> \xF0\x90\xBF\xA4
+<ELYMAIC_LETTER_WAW> \xF0\x90\xBF\xA5
+<ELYMAIC_LETTER_ZAYIN> \xF0\x90\xBF\xA6
+<ELYMAIC_LETTER_HETH> \xF0\x90\xBF\xA7
+<ELYMAIC_LETTER_TETH> \xF0\x90\xBF\xA8
+<ELYMAIC_LETTER_YODH> \xF0\x90\xBF\xA9
+<ELYMAIC_LETTER_KAPH> \xF0\x90\xBF\xAA
+<ELYMAIC_LETTER_LAMEDH> \xF0\x90\xBF\xAB
+<ELYMAIC_LETTER_MEM> \xF0\x90\xBF\xAC
+<ELYMAIC_LETTER_NUN> \xF0\x90\xBF\xAD
+<ELYMAIC_LETTER_SAMEKH> \xF0\x90\xBF\xAE
+<ELYMAIC_LETTER_AYIN> \xF0\x90\xBF\xAF
+<ELYMAIC_LETTER_PE> \xF0\x90\xBF\xB0
+<ELYMAIC_LETTER_SADHE> \xF0\x90\xBF\xB1
+<ELYMAIC_LETTER_QOPH> \xF0\x90\xBF\xB2
+<ELYMAIC_LETTER_RESH> \xF0\x90\xBF\xB3
+<ELYMAIC_LETTER_SHIN> \xF0\x90\xBF\xB4
+<ELYMAIC_LETTER_TAW> \xF0\x90\xBF\xB5
+<ELYMAIC_LIGATURE_ZAYIN-YODH> \xF0\x90\xBF\xB6
<BRAHMI_SIGN_CANDRABINDU> \xF0\x91\x80\x80
<BRAHMI_SIGN_ANUSVARA> \xF0\x91\x80\x81
<BRAHMI_SIGN_VISARGA> \xF0\x91\x80\x82
@@ -65163,6 +65219,7 @@ CHARMAP
<NEWA_PLACEHOLDER_MARK> \xF0\x91\x91\x9B
<NEWA_INSERTION_SIGN> \xF0\x91\x91\x9D
<NEWA_SANDHI_MARK> \xF0\x91\x91\x9E
+<NEWA_LETTER_VEDIC_ANUSVARA> \xF0\x91\x91\x9F
<TIRHUTA_ANJI> \xF0\x91\x92\x80
<TIRHUTA_LETTER_A> \xF0\x91\x92\x81
<TIRHUTA_LETTER_AA> \xF0\x91\x92\x82
@@ -65485,6 +65542,7 @@ CHARMAP
<TAKRI_VOWEL_SIGN_AU> \xF0\x91\x9A\xB5
<TAKRI_SIGN_VIRAMA> \xF0\x91\x9A\xB6
<TAKRI_SIGN_NUKTA> \xF0\x91\x9A\xB7
+<TAKRI_LETTER_ARCHAIC_KHA> \xF0\x91\x9A\xB8
<TAKRI_DIGIT_ZERO> \xF0\x91\x9B\x80
<TAKRI_DIGIT_ONE> \xF0\x91\x9B\x81
<TAKRI_DIGIT_TWO> \xF0\x91\x9B\x82
@@ -65697,6 +65755,71 @@ CHARMAP
<WARANG_CITI_NUMBER_EIGHTY> \xF0\x91\xA3\xB1
<WARANG_CITI_NUMBER_NINETY> \xF0\x91\xA3\xB2
<WARANG_CITI_OM> \xF0\x91\xA3\xBF
+<NANDINAGARI_LETTER_A> \xF0\x91\xA6\xA0
+<NANDINAGARI_LETTER_AA> \xF0\x91\xA6\xA1
+<NANDINAGARI_LETTER_I> \xF0\x91\xA6\xA2
+<NANDINAGARI_LETTER_II> \xF0\x91\xA6\xA3
+<NANDINAGARI_LETTER_U> \xF0\x91\xA6\xA4
+<NANDINAGARI_LETTER_UU> \xF0\x91\xA6\xA5
+<NANDINAGARI_LETTER_VOCALIC_R> \xF0\x91\xA6\xA6
+<NANDINAGARI_LETTER_VOCALIC_RR> \xF0\x91\xA6\xA7
+<NANDINAGARI_LETTER_E> \xF0\x91\xA6\xAA
+<NANDINAGARI_LETTER_AI> \xF0\x91\xA6\xAB
+<NANDINAGARI_LETTER_O> \xF0\x91\xA6\xAC
+<NANDINAGARI_LETTER_AU> \xF0\x91\xA6\xAD
+<NANDINAGARI_LETTER_KA> \xF0\x91\xA6\xAE
+<NANDINAGARI_LETTER_KHA> \xF0\x91\xA6\xAF
+<NANDINAGARI_LETTER_GA> \xF0\x91\xA6\xB0
+<NANDINAGARI_LETTER_GHA> \xF0\x91\xA6\xB1
+<NANDINAGARI_LETTER_NGA> \xF0\x91\xA6\xB2
+<NANDINAGARI_LETTER_CA> \xF0\x91\xA6\xB3
+<NANDINAGARI_LETTER_CHA> \xF0\x91\xA6\xB4
+<NANDINAGARI_LETTER_JA> \xF0\x91\xA6\xB5
+<NANDINAGARI_LETTER_JHA> \xF0\x91\xA6\xB6
+<NANDINAGARI_LETTER_NYA> \xF0\x91\xA6\xB7
+<NANDINAGARI_LETTER_TTA> \xF0\x91\xA6\xB8
+<NANDINAGARI_LETTER_TTHA> \xF0\x91\xA6\xB9
+<NANDINAGARI_LETTER_DDA> \xF0\x91\xA6\xBA
+<NANDINAGARI_LETTER_DDHA> \xF0\x91\xA6\xBB
+<NANDINAGARI_LETTER_NNA> \xF0\x91\xA6\xBC
+<NANDINAGARI_LETTER_TA> \xF0\x91\xA6\xBD
+<NANDINAGARI_LETTER_THA> \xF0\x91\xA6\xBE
+<NANDINAGARI_LETTER_DA> \xF0\x91\xA6\xBF
+<NANDINAGARI_LETTER_DHA> \xF0\x91\xA7\x80
+<NANDINAGARI_LETTER_NA> \xF0\x91\xA7\x81
+<NANDINAGARI_LETTER_PA> \xF0\x91\xA7\x82
+<NANDINAGARI_LETTER_PHA> \xF0\x91\xA7\x83
+<NANDINAGARI_LETTER_BA> \xF0\x91\xA7\x84
+<NANDINAGARI_LETTER_BHA> \xF0\x91\xA7\x85
+<NANDINAGARI_LETTER_MA> \xF0\x91\xA7\x86
+<NANDINAGARI_LETTER_YA> \xF0\x91\xA7\x87
+<NANDINAGARI_LETTER_RA> \xF0\x91\xA7\x88
+<NANDINAGARI_LETTER_LA> \xF0\x91\xA7\x89
+<NANDINAGARI_LETTER_VA> \xF0\x91\xA7\x8A
+<NANDINAGARI_LETTER_SHA> \xF0\x91\xA7\x8B
+<NANDINAGARI_LETTER_SSA> \xF0\x91\xA7\x8C
+<NANDINAGARI_LETTER_SA> \xF0\x91\xA7\x8D
+<NANDINAGARI_LETTER_HA> \xF0\x91\xA7\x8E
+<NANDINAGARI_LETTER_LLA> \xF0\x91\xA7\x8F
+<NANDINAGARI_LETTER_RRA> \xF0\x91\xA7\x90
+<NANDINAGARI_VOWEL_SIGN_AA> \xF0\x91\xA7\x91
+<NANDINAGARI_VOWEL_SIGN_I> \xF0\x91\xA7\x92
+<NANDINAGARI_VOWEL_SIGN_II> \xF0\x91\xA7\x93
+<NANDINAGARI_VOWEL_SIGN_U> \xF0\x91\xA7\x94
+<NANDINAGARI_VOWEL_SIGN_UU> \xF0\x91\xA7\x95
+<NANDINAGARI_VOWEL_SIGN_VOCALIC_R> \xF0\x91\xA7\x96
+<NANDINAGARI_VOWEL_SIGN_VOCALIC_RR> \xF0\x91\xA7\x97
+<NANDINAGARI_VOWEL_SIGN_E> \xF0\x91\xA7\x9A
+<NANDINAGARI_VOWEL_SIGN_AI> \xF0\x91\xA7\x9B
+<NANDINAGARI_VOWEL_SIGN_O> \xF0\x91\xA7\x9C
+<NANDINAGARI_VOWEL_SIGN_AU> \xF0\x91\xA7\x9D
+<NANDINAGARI_SIGN_ANUSVARA> \xF0\x91\xA7\x9E
+<NANDINAGARI_SIGN_VISARGA> \xF0\x91\xA7\x9F
+<NANDINAGARI_SIGN_VIRAMA> \xF0\x91\xA7\xA0
+<NANDINAGARI_SIGN_AVAGRAHA> \xF0\x91\xA7\xA1
+<NANDINAGARI_SIGN_SIDDHAM> \xF0\x91\xA7\xA2
+<NANDINAGARI_HEADSTROKE> \xF0\x91\xA7\xA3
+<NANDINAGARI_VOWEL_SIGN_PRISHTHAMATRA_E> \xF0\x91\xA7\xA4
<ZANABAZAR_SQUARE_LETTER_A> \xF0\x91\xA8\x80
<ZANABAZAR_SQUARE_VOWEL_SIGN_I> \xF0\x91\xA8\x81
<ZANABAZAR_SQUARE_VOWEL_SIGN_UE> \xF0\x91\xA8\x82
@@ -65821,6 +65944,8 @@ CHARMAP
<SOYOMBO_LETTER_SA> \xF0\x91\xAA\x81
<SOYOMBO_LETTER_HA> \xF0\x91\xAA\x82
<SOYOMBO_LETTER_KSSA> \xF0\x91\xAA\x83
+<SOYOMBO_SIGN_JIHVAMULIYA> \xF0\x91\xAA\x84
+<SOYOMBO_SIGN_UPADHMANIYA> \xF0\x91\xAA\x85
<SOYOMBO_CLUSTER-INITIAL_LETTER_RA> \xF0\x91\xAA\x86
<SOYOMBO_CLUSTER-INITIAL_LETTER_LA> \xF0\x91\xAA\x87
<SOYOMBO_CLUSTER-INITIAL_LETTER_SHA> \xF0\x91\xAA\x88
@@ -66235,6 +66360,57 @@ CHARMAP
<MAKASAR_VOWEL_SIGN_O> \xF0\x91\xBB\xB6
<MAKASAR_PASSIMBANG> \xF0\x91\xBB\xB7
<MAKASAR_END_OF_SECTION> \xF0\x91\xBB\xB8
+<TAMIL_FRACTION_ONE_THREE-HUNDRED-AND-TWENTIETH> \xF0\x91\xBF\x80
+<TAMIL_FRACTION_ONE_ONE-HUNDRED-AND-SIXTIETH> \xF0\x91\xBF\x81
+<TAMIL_FRACTION_ONE_EIGHTIETH> \xF0\x91\xBF\x82
+<TAMIL_FRACTION_ONE_SIXTY-FOURTH> \xF0\x91\xBF\x83
+<TAMIL_FRACTION_ONE_FORTIETH> \xF0\x91\xBF\x84
+<TAMIL_FRACTION_ONE_THIRTY-SECOND> \xF0\x91\xBF\x85
+<TAMIL_FRACTION_THREE_EIGHTIETHS> \xF0\x91\xBF\x86
+<TAMIL_FRACTION_THREE_SIXTY-FOURTHS> \xF0\x91\xBF\x87
+<TAMIL_FRACTION_ONE_TWENTIETH> \xF0\x91\xBF\x88
+<TAMIL_FRACTION_ONE_SIXTEENTH-1> \xF0\x91\xBF\x89
+<TAMIL_FRACTION_ONE_SIXTEENTH-2> \xF0\x91\xBF\x8A
+<TAMIL_FRACTION_ONE_TENTH> \xF0\x91\xBF\x8B
+<TAMIL_FRACTION_ONE_EIGHTH> \xF0\x91\xBF\x8C
+<TAMIL_FRACTION_THREE_TWENTIETHS> \xF0\x91\xBF\x8D
+<TAMIL_FRACTION_THREE_SIXTEENTHS> \xF0\x91\xBF\x8E
+<TAMIL_FRACTION_ONE_FIFTH> \xF0\x91\xBF\x8F
+<TAMIL_FRACTION_ONE_QUARTER> \xF0\x91\xBF\x90
+<TAMIL_FRACTION_ONE_HALF-1> \xF0\x91\xBF\x91
+<TAMIL_FRACTION_ONE_HALF-2> \xF0\x91\xBF\x92
+<TAMIL_FRACTION_THREE_QUARTERS> \xF0\x91\xBF\x93
+<TAMIL_FRACTION_DOWNSCALING_FACTOR_KIIZH> \xF0\x91\xBF\x94
+<TAMIL_SIGN_NEL> \xF0\x91\xBF\x95
+<TAMIL_SIGN_CEVITU> \xF0\x91\xBF\x96
+<TAMIL_SIGN_AAZHAAKKU> \xF0\x91\xBF\x97
+<TAMIL_SIGN_UZHAKKU> \xF0\x91\xBF\x98
+<TAMIL_SIGN_MUUVUZHAKKU> \xF0\x91\xBF\x99
+<TAMIL_SIGN_KURUNI> \xF0\x91\xBF\x9A
+<TAMIL_SIGN_PATHAKKU> \xF0\x91\xBF\x9B
+<TAMIL_SIGN_MUKKURUNI> \xF0\x91\xBF\x9C
+<TAMIL_SIGN_KAACU> \xF0\x91\xBF\x9D
+<TAMIL_SIGN_PANAM> \xF0\x91\xBF\x9E
+<TAMIL_SIGN_PON> \xF0\x91\xBF\x9F
+<TAMIL_SIGN_VARAAKAN> \xF0\x91\xBF\xA0
+<TAMIL_SIGN_PAARAM> \xF0\x91\xBF\xA1
+<TAMIL_SIGN_KUZHI> \xF0\x91\xBF\xA2
+<TAMIL_SIGN_VELI> \xF0\x91\xBF\xA3
+<TAMIL_WET_CULTIVATION_SIGN> \xF0\x91\xBF\xA4
+<TAMIL_DRY_CULTIVATION_SIGN> \xF0\x91\xBF\xA5
+<TAMIL_LAND_SIGN> \xF0\x91\xBF\xA6
+<TAMIL_SALT_PAN_SIGN> \xF0\x91\xBF\xA7
+<TAMIL_TRADITIONAL_CREDIT_SIGN> \xF0\x91\xBF\xA8
+<TAMIL_TRADITIONAL_NUMBER_SIGN> \xF0\x91\xBF\xA9
+<TAMIL_CURRENT_SIGN> \xF0\x91\xBF\xAA
+<TAMIL_AND_ODD_SIGN> \xF0\x91\xBF\xAB
+<TAMIL_SPENT_SIGN> \xF0\x91\xBF\xAC
+<TAMIL_TOTAL_SIGN> \xF0\x91\xBF\xAD
+<TAMIL_IN_POSSESSION_SIGN> \xF0\x91\xBF\xAE
+<TAMIL_STARTING_FROM_SIGN> \xF0\x91\xBF\xAF
+<TAMIL_SIGN_MUTHALIYA> \xF0\x91\xBF\xB0
+<TAMIL_SIGN_VAKAIYARAA> \xF0\x91\xBF\xB1
+<TAMIL_PUNCTUATION_END_OF_TEXT> \xF0\x91\xBF\xBF
<CUNEIFORM_SIGN_A> \xF0\x92\x80\x80
<CUNEIFORM_SIGN_A_TIMES_A> \xF0\x92\x80\x81
<CUNEIFORM_SIGN_A_TIMES_BAD> \xF0\x92\x80\x82
@@ -68540,6 +68716,15 @@ CHARMAP
<EGYPTIAN_HIEROGLYPH_AA030> \xF0\x93\x90\xAC
<EGYPTIAN_HIEROGLYPH_AA031> \xF0\x93\x90\xAD
<EGYPTIAN_HIEROGLYPH_AA032> \xF0\x93\x90\xAE
+<EGYPTIAN_HIEROGLYPH_VERTICAL_JOINER> \xF0\x93\x90\xB0
+<EGYPTIAN_HIEROGLYPH_HORIZONTAL_JOINER> \xF0\x93\x90\xB1
+<EGYPTIAN_HIEROGLYPH_INSERT_AT_TOP_START> \xF0\x93\x90\xB2
+<EGYPTIAN_HIEROGLYPH_INSERT_AT_BOTTOM_START> \xF0\x93\x90\xB3
+<EGYPTIAN_HIEROGLYPH_INSERT_AT_TOP_END> \xF0\x93\x90\xB4
+<EGYPTIAN_HIEROGLYPH_INSERT_AT_BOTTOM_END> \xF0\x93\x90\xB5
+<EGYPTIAN_HIEROGLYPH_OVERLAY_MIDDLE> \xF0\x93\x90\xB6
+<EGYPTIAN_HIEROGLYPH_BEGIN_SEGMENT> \xF0\x93\x90\xB7
+<EGYPTIAN_HIEROGLYPH_END_SEGMENT> \xF0\x93\x90\xB8
<ANATOLIAN_HIEROGLYPH_A001> \xF0\x94\x90\x80
<ANATOLIAN_HIEROGLYPH_A002> \xF0\x94\x90\x81
<ANATOLIAN_HIEROGLYPH_A003> \xF0\x94\x90\x82
@@ -70058,6 +70243,13 @@ CHARMAP
<MIAO_LETTER_WA> \xF0\x96\xBD\x82
<MIAO_LETTER_AH> \xF0\x96\xBD\x83
<MIAO_LETTER_HHA> \xF0\x96\xBD\x84
+<MIAO_LETTER_BRI> \xF0\x96\xBD\x85
+<MIAO_LETTER_SYI> \xF0\x96\xBD\x86
+<MIAO_LETTER_DZYI> \xF0\x96\xBD\x87
+<MIAO_LETTER_TE> \xF0\x96\xBD\x88
+<MIAO_LETTER_TSE> \xF0\x96\xBD\x89
+<MIAO_LETTER_RTE> \xF0\x96\xBD\x8A
+<MIAO_SIGN_CONSONANT_MODIFIER_BAR> \xF0\x96\xBD\x8F
<MIAO_LETTER_NASALIZATION> \xF0\x96\xBD\x90
<MIAO_SIGN_ASPIRATION> \xF0\x96\xBD\x91
<MIAO_SIGN_REFORMED_VOICING> \xF0\x96\xBD\x92
@@ -70105,6 +70297,15 @@ CHARMAP
<MIAO_VOWEL_SIGN_OU> \xF0\x96\xBD\xBC
<MIAO_VOWEL_SIGN_N> \xF0\x96\xBD\xBD
<MIAO_VOWEL_SIGN_NG> \xF0\x96\xBD\xBE
+<MIAO_VOWEL_SIGN_UOG> \xF0\x96\xBD\xBF
+<MIAO_VOWEL_SIGN_YUI> \xF0\x96\xBE\x80
+<MIAO_VOWEL_SIGN_OG> \xF0\x96\xBE\x81
+<MIAO_VOWEL_SIGN_OER> \xF0\x96\xBE\x82
+<MIAO_VOWEL_SIGN_VW> \xF0\x96\xBE\x83
+<MIAO_VOWEL_SIGN_IG> \xF0\x96\xBE\x84
+<MIAO_VOWEL_SIGN_EA> \xF0\x96\xBE\x85
+<MIAO_VOWEL_SIGN_IONG> \xF0\x96\xBE\x86
+<MIAO_VOWEL_SIGN_UI> \xF0\x96\xBE\x87
<MIAO_TONE_RIGHT> \xF0\x96\xBE\x8F
<MIAO_TONE_TOP_RIGHT> \xF0\x96\xBE\x90
<MIAO_TONE_ABOVE> \xF0\x96\xBE\x91
@@ -70124,6 +70325,8 @@ CHARMAP
<MIAO_LETTER_REFORMED_TONE-8> \xF0\x96\xBE\x9F
<TANGUT_ITERATION_MARK> \xF0\x96\xBF\xA0
<NUSHU_ITERATION_MARK> \xF0\x96\xBF\xA1
+<OLD_CHINESE_HOOK_MARK> \xF0\x96\xBF\xA2
+<OLD_CHINESE_ITERATION_MARK> \xF0\x96\xBF\xA3
<TANGUT_IDEOGRAPH-17000> \xF0\x97\x80\x80
<TANGUT_IDEOGRAPH-17001> \xF0\x97\x80\x81
<TANGUT_IDEOGRAPH-17002> \xF0\x97\x80\x82
@@ -76254,6 +76457,12 @@ CHARMAP
<TANGUT_IDEOGRAPH-187EF> \xF0\x98\x9F\xAF
<TANGUT_IDEOGRAPH-187F0> \xF0\x98\x9F\xB0
<TANGUT_IDEOGRAPH-187F1> \xF0\x98\x9F\xB1
+<TANGUT_IDEOGRAPH-187F2> \xF0\x98\x9F\xB2
+<TANGUT_IDEOGRAPH-187F3> \xF0\x98\x9F\xB3
+<TANGUT_IDEOGRAPH-187F4> \xF0\x98\x9F\xB4
+<TANGUT_IDEOGRAPH-187F5> \xF0\x98\x9F\xB5
+<TANGUT_IDEOGRAPH-187F6> \xF0\x98\x9F\xB6
+<TANGUT_IDEOGRAPH-187F7> \xF0\x98\x9F\xB7
<TANGUT_COMPONENT-001> \xF0\x98\xA0\x80
<TANGUT_COMPONENT-002> \xF0\x98\xA0\x81
<TANGUT_COMPONENT-003> \xF0\x98\xA0\x82
@@ -77296,6 +77505,13 @@ CHARMAP
<HENTAIGANA_LETTER_WO-7> \xF0\x9B\x84\x9C
<HENTAIGANA_LETTER_N-MU-MO-1> \xF0\x9B\x84\x9D
<HENTAIGANA_LETTER_N-MU-MO-2> \xF0\x9B\x84\x9E
+<HIRAGANA_LETTER_SMALL_WI> \xF0\x9B\x85\x90
+<HIRAGANA_LETTER_SMALL_WE> \xF0\x9B\x85\x91
+<HIRAGANA_LETTER_SMALL_WO> \xF0\x9B\x85\x92
+<KATAKANA_LETTER_SMALL_WI> \xF0\x9B\x85\xA4
+<KATAKANA_LETTER_SMALL_WE> \xF0\x9B\x85\xA5
+<KATAKANA_LETTER_SMALL_WO> \xF0\x9B\x85\xA6
+<KATAKANA_LETTER_SMALL_N> \xF0\x9B\x85\xA7
<NUSHU_CHARACTER-1B170> \xF0\x9B\x85\xB0
<NUSHU_CHARACTER-1B171> \xF0\x9B\x85\xB1
<NUSHU_CHARACTER-1B172> \xF0\x9B\x85\xB2
@@ -80224,6 +80440,136 @@ CHARMAP
<COMBINING_GLAGOLITIC_LETTER_BIG_YUS> \xF0\x9E\x80\xA8
<COMBINING_GLAGOLITIC_LETTER_IOTATED_BIG_YUS> \xF0\x9E\x80\xA9
<COMBINING_GLAGOLITIC_LETTER_FITA> \xF0\x9E\x80\xAA
+<NYIAKENG_PUACHUE_HMONG_LETTER_MA> \xF0\x9E\x84\x80
+<NYIAKENG_PUACHUE_HMONG_LETTER_TSA> \xF0\x9E\x84\x81
+<NYIAKENG_PUACHUE_HMONG_LETTER_NTA> \xF0\x9E\x84\x82
+<NYIAKENG_PUACHUE_HMONG_LETTER_TA> \xF0\x9E\x84\x83
+<NYIAKENG_PUACHUE_HMONG_LETTER_HA> \xF0\x9E\x84\x84
+<NYIAKENG_PUACHUE_HMONG_LETTER_NA> \xF0\x9E\x84\x85
+<NYIAKENG_PUACHUE_HMONG_LETTER_XA> \xF0\x9E\x84\x86
+<NYIAKENG_PUACHUE_HMONG_LETTER_NKA> \xF0\x9E\x84\x87
+<NYIAKENG_PUACHUE_HMONG_LETTER_CA> \xF0\x9E\x84\x88
+<NYIAKENG_PUACHUE_HMONG_LETTER_LA> \xF0\x9E\x84\x89
+<NYIAKENG_PUACHUE_HMONG_LETTER_SA> \xF0\x9E\x84\x8A
+<NYIAKENG_PUACHUE_HMONG_LETTER_ZA> \xF0\x9E\x84\x8B
+<NYIAKENG_PUACHUE_HMONG_LETTER_NCA> \xF0\x9E\x84\x8C
+<NYIAKENG_PUACHUE_HMONG_LETTER_NTSA> \xF0\x9E\x84\x8D
+<NYIAKENG_PUACHUE_HMONG_LETTER_KA> \xF0\x9E\x84\x8E
+<NYIAKENG_PUACHUE_HMONG_LETTER_DA> \xF0\x9E\x84\x8F
+<NYIAKENG_PUACHUE_HMONG_LETTER_NYA> \xF0\x9E\x84\x90
+<NYIAKENG_PUACHUE_HMONG_LETTER_NRA> \xF0\x9E\x84\x91
+<NYIAKENG_PUACHUE_HMONG_LETTER_VA> \xF0\x9E\x84\x92
+<NYIAKENG_PUACHUE_HMONG_LETTER_NTXA> \xF0\x9E\x84\x93
+<NYIAKENG_PUACHUE_HMONG_LETTER_TXA> \xF0\x9E\x84\x94
+<NYIAKENG_PUACHUE_HMONG_LETTER_FA> \xF0\x9E\x84\x95
+<NYIAKENG_PUACHUE_HMONG_LETTER_RA> \xF0\x9E\x84\x96
+<NYIAKENG_PUACHUE_HMONG_LETTER_QA> \xF0\x9E\x84\x97
+<NYIAKENG_PUACHUE_HMONG_LETTER_YA> \xF0\x9E\x84\x98
+<NYIAKENG_PUACHUE_HMONG_LETTER_NQA> \xF0\x9E\x84\x99
+<NYIAKENG_PUACHUE_HMONG_LETTER_PA> \xF0\x9E\x84\x9A
+<NYIAKENG_PUACHUE_HMONG_LETTER_XYA> \xF0\x9E\x84\x9B
+<NYIAKENG_PUACHUE_HMONG_LETTER_NPA> \xF0\x9E\x84\x9C
+<NYIAKENG_PUACHUE_HMONG_LETTER_DLA> \xF0\x9E\x84\x9D
+<NYIAKENG_PUACHUE_HMONG_LETTER_NPLA> \xF0\x9E\x84\x9E
+<NYIAKENG_PUACHUE_HMONG_LETTER_HAH> \xF0\x9E\x84\x9F
+<NYIAKENG_PUACHUE_HMONG_LETTER_MLA> \xF0\x9E\x84\xA0
+<NYIAKENG_PUACHUE_HMONG_LETTER_PLA> \xF0\x9E\x84\xA1
+<NYIAKENG_PUACHUE_HMONG_LETTER_GA> \xF0\x9E\x84\xA2
+<NYIAKENG_PUACHUE_HMONG_LETTER_RRA> \xF0\x9E\x84\xA3
+<NYIAKENG_PUACHUE_HMONG_LETTER_A> \xF0\x9E\x84\xA4
+<NYIAKENG_PUACHUE_HMONG_LETTER_AA> \xF0\x9E\x84\xA5
+<NYIAKENG_PUACHUE_HMONG_LETTER_I> \xF0\x9E\x84\xA6
+<NYIAKENG_PUACHUE_HMONG_LETTER_U> \xF0\x9E\x84\xA7
+<NYIAKENG_PUACHUE_HMONG_LETTER_O> \xF0\x9E\x84\xA8
+<NYIAKENG_PUACHUE_HMONG_LETTER_OO> \xF0\x9E\x84\xA9
+<NYIAKENG_PUACHUE_HMONG_LETTER_E> \xF0\x9E\x84\xAA
+<NYIAKENG_PUACHUE_HMONG_LETTER_EE> \xF0\x9E\x84\xAB
+<NYIAKENG_PUACHUE_HMONG_LETTER_W> \xF0\x9E\x84\xAC
+<NYIAKENG_PUACHUE_HMONG_TONE-B> \xF0\x9E\x84\xB0
+<NYIAKENG_PUACHUE_HMONG_TONE-M> \xF0\x9E\x84\xB1
+<NYIAKENG_PUACHUE_HMONG_TONE-J> \xF0\x9E\x84\xB2
+<NYIAKENG_PUACHUE_HMONG_TONE-V> \xF0\x9E\x84\xB3
+<NYIAKENG_PUACHUE_HMONG_TONE-S> \xF0\x9E\x84\xB4
+<NYIAKENG_PUACHUE_HMONG_TONE-G> \xF0\x9E\x84\xB5
+<NYIAKENG_PUACHUE_HMONG_TONE-D> \xF0\x9E\x84\xB6
+<NYIAKENG_PUACHUE_HMONG_SIGN_FOR_PERSON> \xF0\x9E\x84\xB7
+<NYIAKENG_PUACHUE_HMONG_SIGN_FOR_THING> \xF0\x9E\x84\xB8
+<NYIAKENG_PUACHUE_HMONG_SIGN_FOR_LOCATION> \xF0\x9E\x84\xB9
+<NYIAKENG_PUACHUE_HMONG_SIGN_FOR_ANIMAL> \xF0\x9E\x84\xBA
+<NYIAKENG_PUACHUE_HMONG_SIGN_FOR_INVERTEBRATE> \xF0\x9E\x84\xBB
+<NYIAKENG_PUACHUE_HMONG_SIGN_XW_XW> \xF0\x9E\x84\xBC
+<NYIAKENG_PUACHUE_HMONG_SYLLABLE_LENGTHENER> \xF0\x9E\x84\xBD
+<NYIAKENG_PUACHUE_HMONG_DIGIT_ZERO> \xF0\x9E\x85\x80
+<NYIAKENG_PUACHUE_HMONG_DIGIT_ONE> \xF0\x9E\x85\x81
+<NYIAKENG_PUACHUE_HMONG_DIGIT_TWO> \xF0\x9E\x85\x82
+<NYIAKENG_PUACHUE_HMONG_DIGIT_THREE> \xF0\x9E\x85\x83
+<NYIAKENG_PUACHUE_HMONG_DIGIT_FOUR> \xF0\x9E\x85\x84
+<NYIAKENG_PUACHUE_HMONG_DIGIT_FIVE> \xF0\x9E\x85\x85
+<NYIAKENG_PUACHUE_HMONG_DIGIT_SIX> \xF0\x9E\x85\x86
+<NYIAKENG_PUACHUE_HMONG_DIGIT_SEVEN> \xF0\x9E\x85\x87
+<NYIAKENG_PUACHUE_HMONG_DIGIT_EIGHT> \xF0\x9E\x85\x88
+<NYIAKENG_PUACHUE_HMONG_DIGIT_NINE> \xF0\x9E\x85\x89
+<NYIAKENG_PUACHUE_HMONG_LOGOGRAM_NYAJ> \xF0\x9E\x85\x8E
+<NYIAKENG_PUACHUE_HMONG_CIRCLED_CA> \xF0\x9E\x85\x8F
+<WANCHO_LETTER_AA> \xF0\x9E\x8B\x80
+<WANCHO_LETTER_A> \xF0\x9E\x8B\x81
+<WANCHO_LETTER_BA> \xF0\x9E\x8B\x82
+<WANCHO_LETTER_CA> \xF0\x9E\x8B\x83
+<WANCHO_LETTER_DA> \xF0\x9E\x8B\x84
+<WANCHO_LETTER_GA> \xF0\x9E\x8B\x85
+<WANCHO_LETTER_YA> \xF0\x9E\x8B\x86
+<WANCHO_LETTER_PHA> \xF0\x9E\x8B\x87
+<WANCHO_LETTER_LA> \xF0\x9E\x8B\x88
+<WANCHO_LETTER_NA> \xF0\x9E\x8B\x89
+<WANCHO_LETTER_PA> \xF0\x9E\x8B\x8A
+<WANCHO_LETTER_TA> \xF0\x9E\x8B\x8B
+<WANCHO_LETTER_THA> \xF0\x9E\x8B\x8C
+<WANCHO_LETTER_FA> \xF0\x9E\x8B\x8D
+<WANCHO_LETTER_SA> \xF0\x9E\x8B\x8E
+<WANCHO_LETTER_SHA> \xF0\x9E\x8B\x8F
+<WANCHO_LETTER_JA> \xF0\x9E\x8B\x90
+<WANCHO_LETTER_ZA> \xF0\x9E\x8B\x91
+<WANCHO_LETTER_WA> \xF0\x9E\x8B\x92
+<WANCHO_LETTER_VA> \xF0\x9E\x8B\x93
+<WANCHO_LETTER_KA> \xF0\x9E\x8B\x94
+<WANCHO_LETTER_O> \xF0\x9E\x8B\x95
+<WANCHO_LETTER_AU> \xF0\x9E\x8B\x96
+<WANCHO_LETTER_RA> \xF0\x9E\x8B\x97
+<WANCHO_LETTER_MA> \xF0\x9E\x8B\x98
+<WANCHO_LETTER_KHA> \xF0\x9E\x8B\x99
+<WANCHO_LETTER_HA> \xF0\x9E\x8B\x9A
+<WANCHO_LETTER_E> \xF0\x9E\x8B\x9B
+<WANCHO_LETTER_I> \xF0\x9E\x8B\x9C
+<WANCHO_LETTER_NGA> \xF0\x9E\x8B\x9D
+<WANCHO_LETTER_U> \xF0\x9E\x8B\x9E
+<WANCHO_LETTER_LLHA> \xF0\x9E\x8B\x9F
+<WANCHO_LETTER_TSA> \xF0\x9E\x8B\xA0
+<WANCHO_LETTER_TRA> \xF0\x9E\x8B\xA1
+<WANCHO_LETTER_ONG> \xF0\x9E\x8B\xA2
+<WANCHO_LETTER_AANG> \xF0\x9E\x8B\xA3
+<WANCHO_LETTER_ANG> \xF0\x9E\x8B\xA4
+<WANCHO_LETTER_ING> \xF0\x9E\x8B\xA5
+<WANCHO_LETTER_ON> \xF0\x9E\x8B\xA6
+<WANCHO_LETTER_EN> \xF0\x9E\x8B\xA7
+<WANCHO_LETTER_AAN> \xF0\x9E\x8B\xA8
+<WANCHO_LETTER_NYA> \xF0\x9E\x8B\xA9
+<WANCHO_LETTER_UEN> \xF0\x9E\x8B\xAA
+<WANCHO_LETTER_YIH> \xF0\x9E\x8B\xAB
+<WANCHO_TONE_TUP> \xF0\x9E\x8B\xAC
+<WANCHO_TONE_TUPNI> \xF0\x9E\x8B\xAD
+<WANCHO_TONE_KOI> \xF0\x9E\x8B\xAE
+<WANCHO_TONE_KOINI> \xF0\x9E\x8B\xAF
+<WANCHO_DIGIT_ZERO> \xF0\x9E\x8B\xB0
+<WANCHO_DIGIT_ONE> \xF0\x9E\x8B\xB1
+<WANCHO_DIGIT_TWO> \xF0\x9E\x8B\xB2
+<WANCHO_DIGIT_THREE> \xF0\x9E\x8B\xB3
+<WANCHO_DIGIT_FOUR> \xF0\x9E\x8B\xB4
+<WANCHO_DIGIT_FIVE> \xF0\x9E\x8B\xB5
+<WANCHO_DIGIT_SIX> \xF0\x9E\x8B\xB6
+<WANCHO_DIGIT_SEVEN> \xF0\x9E\x8B\xB7
+<WANCHO_DIGIT_EIGHT> \xF0\x9E\x8B\xB8
+<WANCHO_DIGIT_NINE> \xF0\x9E\x8B\xB9
+<WANCHO_NGUN_SIGN> \xF0\x9E\x8B\xBF
<MENDE_KIKAKUI_SYLLABLE_M001_KI> \xF0\x9E\xA0\x80
<MENDE_KIKAKUI_SYLLABLE_M002_KA> \xF0\x9E\xA0\x81
<MENDE_KIKAKUI_SYLLABLE_M003_KU> \xF0\x9E\xA0\x82
@@ -80512,6 +80858,7 @@ CHARMAP
<ADLAM_CONSONANT_MODIFIER> \xF0\x9E\xA5\x88
<ADLAM_GEMINATE_CONSONANT_MODIFIER> \xF0\x9E\xA5\x89
<ADLAM_NUKTA> \xF0\x9E\xA5\x8A
+<ADLAM_NASALIZATION_MARK> \xF0\x9E\xA5\x8B
<ADLAM_DIGIT_ZERO> \xF0\x9E\xA5\x90
<ADLAM_DIGIT_ONE> \xF0\x9E\xA5\x91
<ADLAM_DIGIT_TWO> \xF0\x9E\xA5\x92
@@ -80592,6 +80939,67 @@ CHARMAP
<INDIC_SIYAQ_NUMBER_ALTERNATE_TWO> \xF0\x9E\xB2\xB2
<INDIC_SIYAQ_NUMBER_ALTERNATE_TEN_THOUSAND> \xF0\x9E\xB2\xB3
<INDIC_SIYAQ_ALTERNATE_LAKH_MARK> \xF0\x9E\xB2\xB4
+<OTTOMAN_SIYAQ_NUMBER_ONE> \xF0\x9E\xB4\x81
+<OTTOMAN_SIYAQ_NUMBER_TWO> \xF0\x9E\xB4\x82
+<OTTOMAN_SIYAQ_NUMBER_THREE> \xF0\x9E\xB4\x83
+<OTTOMAN_SIYAQ_NUMBER_FOUR> \xF0\x9E\xB4\x84
+<OTTOMAN_SIYAQ_NUMBER_FIVE> \xF0\x9E\xB4\x85
+<OTTOMAN_SIYAQ_NUMBER_SIX> \xF0\x9E\xB4\x86
+<OTTOMAN_SIYAQ_NUMBER_SEVEN> \xF0\x9E\xB4\x87
+<OTTOMAN_SIYAQ_NUMBER_EIGHT> \xF0\x9E\xB4\x88
+<OTTOMAN_SIYAQ_NUMBER_NINE> \xF0\x9E\xB4\x89
+<OTTOMAN_SIYAQ_NUMBER_TEN> \xF0\x9E\xB4\x8A
+<OTTOMAN_SIYAQ_NUMBER_TWENTY> \xF0\x9E\xB4\x8B
+<OTTOMAN_SIYAQ_NUMBER_THIRTY> \xF0\x9E\xB4\x8C
+<OTTOMAN_SIYAQ_NUMBER_FORTY> \xF0\x9E\xB4\x8D
+<OTTOMAN_SIYAQ_NUMBER_FIFTY> \xF0\x9E\xB4\x8E
+<OTTOMAN_SIYAQ_NUMBER_SIXTY> \xF0\x9E\xB4\x8F
+<OTTOMAN_SIYAQ_NUMBER_SEVENTY> \xF0\x9E\xB4\x90
+<OTTOMAN_SIYAQ_NUMBER_EIGHTY> \xF0\x9E\xB4\x91
+<OTTOMAN_SIYAQ_NUMBER_NINETY> \xF0\x9E\xB4\x92
+<OTTOMAN_SIYAQ_NUMBER_ONE_HUNDRED> \xF0\x9E\xB4\x93
+<OTTOMAN_SIYAQ_NUMBER_TWO_HUNDRED> \xF0\x9E\xB4\x94
+<OTTOMAN_SIYAQ_NUMBER_THREE_HUNDRED> \xF0\x9E\xB4\x95
+<OTTOMAN_SIYAQ_NUMBER_FOUR_HUNDRED> \xF0\x9E\xB4\x96
+<OTTOMAN_SIYAQ_NUMBER_FIVE_HUNDRED> \xF0\x9E\xB4\x97
+<OTTOMAN_SIYAQ_NUMBER_SIX_HUNDRED> \xF0\x9E\xB4\x98
+<OTTOMAN_SIYAQ_NUMBER_SEVEN_HUNDRED> \xF0\x9E\xB4\x99
+<OTTOMAN_SIYAQ_NUMBER_EIGHT_HUNDRED> \xF0\x9E\xB4\x9A
+<OTTOMAN_SIYAQ_NUMBER_NINE_HUNDRED> \xF0\x9E\xB4\x9B
+<OTTOMAN_SIYAQ_NUMBER_ONE_THOUSAND> \xF0\x9E\xB4\x9C
+<OTTOMAN_SIYAQ_NUMBER_TWO_THOUSAND> \xF0\x9E\xB4\x9D
+<OTTOMAN_SIYAQ_NUMBER_THREE_THOUSAND> \xF0\x9E\xB4\x9E
+<OTTOMAN_SIYAQ_NUMBER_FOUR_THOUSAND> \xF0\x9E\xB4\x9F
+<OTTOMAN_SIYAQ_NUMBER_FIVE_THOUSAND> \xF0\x9E\xB4\xA0
+<OTTOMAN_SIYAQ_NUMBER_SIX_THOUSAND> \xF0\x9E\xB4\xA1
+<OTTOMAN_SIYAQ_NUMBER_SEVEN_THOUSAND> \xF0\x9E\xB4\xA2
+<OTTOMAN_SIYAQ_NUMBER_EIGHT_THOUSAND> \xF0\x9E\xB4\xA3
+<OTTOMAN_SIYAQ_NUMBER_NINE_THOUSAND> \xF0\x9E\xB4\xA4
+<OTTOMAN_SIYAQ_NUMBER_TEN_THOUSAND> \xF0\x9E\xB4\xA5
+<OTTOMAN_SIYAQ_NUMBER_TWENTY_THOUSAND> \xF0\x9E\xB4\xA6
+<OTTOMAN_SIYAQ_NUMBER_THIRTY_THOUSAND> \xF0\x9E\xB4\xA7
+<OTTOMAN_SIYAQ_NUMBER_FORTY_THOUSAND> \xF0\x9E\xB4\xA8
+<OTTOMAN_SIYAQ_NUMBER_FIFTY_THOUSAND> \xF0\x9E\xB4\xA9
+<OTTOMAN_SIYAQ_NUMBER_SIXTY_THOUSAND> \xF0\x9E\xB4\xAA
+<OTTOMAN_SIYAQ_NUMBER_SEVENTY_THOUSAND> \xF0\x9E\xB4\xAB
+<OTTOMAN_SIYAQ_NUMBER_EIGHTY_THOUSAND> \xF0\x9E\xB4\xAC
+<OTTOMAN_SIYAQ_NUMBER_NINETY_THOUSAND> \xF0\x9E\xB4\xAD
+<OTTOMAN_SIYAQ_MARRATAN> \xF0\x9E\xB4\xAE
+<OTTOMAN_SIYAQ_ALTERNATE_NUMBER_TWO> \xF0\x9E\xB4\xAF
+<OTTOMAN_SIYAQ_ALTERNATE_NUMBER_THREE> \xF0\x9E\xB4\xB0
+<OTTOMAN_SIYAQ_ALTERNATE_NUMBER_FOUR> \xF0\x9E\xB4\xB1
+<OTTOMAN_SIYAQ_ALTERNATE_NUMBER_FIVE> \xF0\x9E\xB4\xB2
+<OTTOMAN_SIYAQ_ALTERNATE_NUMBER_SIX> \xF0\x9E\xB4\xB3
+<OTTOMAN_SIYAQ_ALTERNATE_NUMBER_SEVEN> \xF0\x9E\xB4\xB4
+<OTTOMAN_SIYAQ_ALTERNATE_NUMBER_EIGHT> \xF0\x9E\xB4\xB5
+<OTTOMAN_SIYAQ_ALTERNATE_NUMBER_NINE> \xF0\x9E\xB4\xB6
+<OTTOMAN_SIYAQ_ALTERNATE_NUMBER_TEN> \xF0\x9E\xB4\xB7
+<OTTOMAN_SIYAQ_ALTERNATE_NUMBER_FOUR_HUNDRED> \xF0\x9E\xB4\xB8
+<OTTOMAN_SIYAQ_ALTERNATE_NUMBER_SIX_HUNDRED> \xF0\x9E\xB4\xB9
+<OTTOMAN_SIYAQ_ALTERNATE_NUMBER_TWO_THOUSAND> \xF0\x9E\xB4\xBA
+<OTTOMAN_SIYAQ_ALTERNATE_NUMBER_TEN_THOUSAND> \xF0\x9E\xB4\xBB
+<OTTOMAN_SIYAQ_FRACTION_ONE_HALF> \xF0\x9E\xB4\xBC
+<OTTOMAN_SIYAQ_FRACTION_ONE_SIXTH> \xF0\x9E\xB4\xBD
<ARABIC_MATHEMATICAL_ALEF> \xF0\x9E\xB8\x80
<ARABIC_MATHEMATICAL_BEH> \xF0\x9E\xB8\x81
<ARABIC_MATHEMATICAL_JEEM> \xF0\x9E\xB8\x82
@@ -81066,6 +81474,7 @@ CHARMAP
<NEGATIVE_CIRCLED_LATIN_CAPITAL_LETTER_Z> \xF0\x9F\x85\xA9
<RAISED_MC_SIGN> \xF0\x9F\x85\xAA
<RAISED_MD_SIGN> \xF0\x9F\x85\xAB
+<RAISED_MR_SIGN> \xF0\x9F\x85\xAC
<NEGATIVE_SQUARED_LATIN_CAPITAL_LETTER_A> \xF0\x9F\x85\xB0
<NEGATIVE_SQUARED_LATIN_CAPITAL_LETTER_B> \xF0\x9F\x85\xB1
<NEGATIVE_SQUARED_LATIN_CAPITAL_LETTER_C> \xF0\x9F\x85\xB2
@@ -82198,6 +82607,7 @@ CHARMAP
<SHOPPING_TROLLEY> \xF0\x9F\x9B\x92
<STUPA> \xF0\x9F\x9B\x93
<PAGODA> \xF0\x9F\x9B\x94
+<HINDU_TEMPLE> \xF0\x9F\x9B\x95
<HAMMER_AND_WRENCH> \xF0\x9F\x9B\xA0
<SHIELD> \xF0\x9F\x9B\xA1
<OIL_DRUM> \xF0\x9F\x9B\xA2
@@ -82221,6 +82631,7 @@ CHARMAP
<SLED> \xF0\x9F\x9B\xB7
<FLYING_SAUCER> \xF0\x9F\x9B\xB8
<SKATEBOARD> \xF0\x9F\x9B\xB9
+<AUTO_RICKSHAW> \xF0\x9F\x9B\xBA
<ALCHEMICAL_SYMBOL_FOR_QUINTESSENCE> \xF0\x9F\x9C\x80
<ALCHEMICAL_SYMBOL_FOR_AIR> \xF0\x9F\x9C\x81
<ALCHEMICAL_SYMBOL_FOR_FIRE> \xF0\x9F\x9C\x82
@@ -82426,6 +82837,18 @@ CHARMAP
<NEGATIVE_CIRCLED_TRIANGLE> \xF0\x9F\x9F\x96
<CIRCLED_SQUARE> \xF0\x9F\x9F\x97
<NEGATIVE_CIRCLED_SQUARE> \xF0\x9F\x9F\x98
+<LARGE_ORANGE_CIRCLE> \xF0\x9F\x9F\xA0
+<LARGE_YELLOW_CIRCLE> \xF0\x9F\x9F\xA1
+<LARGE_GREEN_CIRCLE> \xF0\x9F\x9F\xA2
+<LARGE_PURPLE_CIRCLE> \xF0\x9F\x9F\xA3
+<LARGE_BROWN_CIRCLE> \xF0\x9F\x9F\xA4
+<LARGE_RED_SQUARE> \xF0\x9F\x9F\xA5
+<LARGE_BLUE_SQUARE> \xF0\x9F\x9F\xA6
+<LARGE_ORANGE_SQUARE> \xF0\x9F\x9F\xA7
+<LARGE_YELLOW_SQUARE> \xF0\x9F\x9F\xA8
+<LARGE_GREEN_SQUARE> \xF0\x9F\x9F\xA9
+<LARGE_PURPLE_SQUARE> \xF0\x9F\x9F\xAA
+<LARGE_BROWN_SQUARE> \xF0\x9F\x9F\xAB
<LEFTWARDS_ARROW_WITH_SMALL_TRIANGLE_ARROWHEAD> \xF0\x9F\xA0\x80
<UPWARDS_ARROW_WITH_SMALL_TRIANGLE_ARROWHEAD> \xF0\x9F\xA0\x81
<RIGHTWARDS_ARROW_WITH_SMALL_TRIANGLE_ARROWHEAD> \xF0\x9F\xA0\x82
@@ -82586,6 +83009,9 @@ CHARMAP
<DOWNWARD_FACING_NOTCHED_HOOK> \xF0\x9F\xA4\x89
<DOWNWARD_FACING_HOOK_WITH_DOT> \xF0\x9F\xA4\x8A
<DOWNWARD_FACING_NOTCHED_HOOK_WITH_DOT> \xF0\x9F\xA4\x8B
+<WHITE_HEART> \xF0\x9F\xA4\x8D
+<BROWN_HEART> \xF0\x9F\xA4\x8E
+<PINCHING_HAND> \xF0\x9F\xA4\x8F
<ZIPPER-MOUTH_FACE> \xF0\x9F\xA4\x90
<MONEY-MOUTH_FACE> \xF0\x9F\xA4\x91
<FACE_WITH_THERMOMETER> \xF0\x9F\xA4\x92
@@ -82633,6 +83059,7 @@ CHARMAP
<WRESTLERS> \xF0\x9F\xA4\xBC
<WATER_POLO> \xF0\x9F\xA4\xBD
<HANDBALL> \xF0\x9F\xA4\xBE
+<DIVING_MASK> \xF0\x9F\xA4\xBF
<WILTED_FLOWER> \xF0\x9F\xA5\x80
<DRUM_WITH_DRUMSTICKS> \xF0\x9F\xA5\x81
<CLINKING_GLASSES> \xF0\x9F\xA5\x82
@@ -82682,11 +83109,13 @@ CHARMAP
<MOON_CAKE> \xF0\x9F\xA5\xAE
<BAGEL> \xF0\x9F\xA5\xAF
<SMILING_FACE_WITH_SMILING_EYES_AND_THREE_HEARTS> \xF0\x9F\xA5\xB0
+<YAWNING_FACE> \xF0\x9F\xA5\xB1
<FACE_WITH_PARTY_HORN_AND_PARTY_HAT> \xF0\x9F\xA5\xB3
<FACE_WITH_UNEVEN_EYES_AND_WAVY_MOUTH> \xF0\x9F\xA5\xB4
<OVERHEATED_FACE> \xF0\x9F\xA5\xB5
<FREEZING_FACE> \xF0\x9F\xA5\xB6
<FACE_WITH_PLEADING_EYES> \xF0\x9F\xA5\xBA
+<SARI> \xF0\x9F\xA5\xBB
<LAB_COAT> \xF0\x9F\xA5\xBC
<GOGGLES> \xF0\x9F\xA5\xBD
<HIKING_BOOT> \xF0\x9F\xA5\xBE
@@ -82726,6 +83155,14 @@ CHARMAP
<MICROBE> \xF0\x9F\xA6\xA0
<BADGER> \xF0\x9F\xA6\xA1
<SWAN> \xF0\x9F\xA6\xA2
+<SLOTH> \xF0\x9F\xA6\xA5
+<OTTER> \xF0\x9F\xA6\xA6
+<ORANGUTAN> \xF0\x9F\xA6\xA7
+<SKUNK> \xF0\x9F\xA6\xA8
+<FLAMINGO> \xF0\x9F\xA6\xA9
+<OYSTER> \xF0\x9F\xA6\xAA
+<GUIDE_DOG> \xF0\x9F\xA6\xAE
+<PROBING_CANE> \xF0\x9F\xA6\xAF
<EMOJI_COMPONENT_RED_HAIR> \xF0\x9F\xA6\xB0
<EMOJI_COMPONENT_CURLY_HAIR> \xF0\x9F\xA6\xB1
<EMOJI_COMPONENT_BALD> \xF0\x9F\xA6\xB2
@@ -82736,9 +83173,26 @@ CHARMAP
<TOOTH> \xF0\x9F\xA6\xB7
<SUPERHERO> \xF0\x9F\xA6\xB8
<SUPERVILLAIN> \xF0\x9F\xA6\xB9
+<SAFETY_VEST> \xF0\x9F\xA6\xBA
+<EAR_WITH_HEARING_AID> \xF0\x9F\xA6\xBB
+<MOTORIZED_WHEELCHAIR> \xF0\x9F\xA6\xBC
+<MANUAL_WHEELCHAIR> \xF0\x9F\xA6\xBD
+<MECHANICAL_ARM> \xF0\x9F\xA6\xBE
+<MECHANICAL_LEG> \xF0\x9F\xA6\xBF
<CHEESE_WEDGE> \xF0\x9F\xA7\x80
<CUPCAKE> \xF0\x9F\xA7\x81
<SALT_SHAKER> \xF0\x9F\xA7\x82
+<BEVERAGE_BOX> \xF0\x9F\xA7\x83
+<GARLIC> \xF0\x9F\xA7\x84
+<ONION> \xF0\x9F\xA7\x85
+<FALAFEL> \xF0\x9F\xA7\x86
+<WAFFLE> \xF0\x9F\xA7\x87
+<BUTTER> \xF0\x9F\xA7\x88
+<MATE_DRINK> \xF0\x9F\xA7\x89
+<ICE_CUBE> \xF0\x9F\xA7\x8A
+<STANDING_PERSON> \xF0\x9F\xA7\x8D
+<KNEELING_PERSON> \xF0\x9F\xA7\x8E
+<DEAF_PERSON> \xF0\x9F\xA7\x8F
<FACE_WITH_MONOCLE> \xF0\x9F\xA7\x90
<ADULT> \xF0\x9F\xA7\x91
<CHILD> \xF0\x9F\xA7\x92
@@ -82787,6 +83241,90 @@ CHARMAP
<SPONGE> \xF0\x9F\xA7\xBD
<RECEIPT> \xF0\x9F\xA7\xBE
<NAZAR_AMULET> \xF0\x9F\xA7\xBF
+<NEUTRAL_CHESS_KING> \xF0\x9F\xA8\x80
+<NEUTRAL_CHESS_QUEEN> \xF0\x9F\xA8\x81
+<NEUTRAL_CHESS_ROOK> \xF0\x9F\xA8\x82
+<NEUTRAL_CHESS_BISHOP> \xF0\x9F\xA8\x83
+<NEUTRAL_CHESS_KNIGHT> \xF0\x9F\xA8\x84
+<NEUTRAL_CHESS_PAWN> \xF0\x9F\xA8\x85
+<WHITE_CHESS_KNIGHT_ROTATED_FORTY-FIVE_DEGREES> \xF0\x9F\xA8\x86
+<BLACK_CHESS_KNIGHT_ROTATED_FORTY-FIVE_DEGREES> \xF0\x9F\xA8\x87
+<NEUTRAL_CHESS_KNIGHT_ROTATED_FORTY-FIVE_DEGREES> \xF0\x9F\xA8\x88
+<WHITE_CHESS_KING_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x89
+<WHITE_CHESS_QUEEN_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x8A
+<WHITE_CHESS_ROOK_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x8B
+<WHITE_CHESS_BISHOP_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x8C
+<WHITE_CHESS_KNIGHT_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x8D
+<WHITE_CHESS_PAWN_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x8E
+<BLACK_CHESS_KING_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x8F
+<BLACK_CHESS_QUEEN_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x90
+<BLACK_CHESS_ROOK_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x91
+<BLACK_CHESS_BISHOP_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x92
+<BLACK_CHESS_KNIGHT_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x93
+<BLACK_CHESS_PAWN_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x94
+<NEUTRAL_CHESS_KING_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x95
+<NEUTRAL_CHESS_QUEEN_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x96
+<NEUTRAL_CHESS_ROOK_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x97
+<NEUTRAL_CHESS_BISHOP_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x98
+<NEUTRAL_CHESS_KNIGHT_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x99
+<NEUTRAL_CHESS_PAWN_ROTATED_NINETY_DEGREES> \xF0\x9F\xA8\x9A
+<WHITE_CHESS_KNIGHT_ROTATED_ONE_HUNDRED_THIRTY-FIVE_DEGREES> \xF0\x9F\xA8\x9B
+<BLACK_CHESS_KNIGHT_ROTATED_ONE_HUNDRED_THIRTY-FIVE_DEGREES> \xF0\x9F\xA8\x9C
+<NEUTRAL_CHESS_KNIGHT_ROTATED_ONE_HUNDRED_THIRTY-FIVE_DEGREES> \xF0\x9F\xA8\x9D
+<WHITE_CHESS_TURNED_KING> \xF0\x9F\xA8\x9E
+<WHITE_CHESS_TURNED_QUEEN> \xF0\x9F\xA8\x9F
+<WHITE_CHESS_TURNED_ROOK> \xF0\x9F\xA8\xA0
+<WHITE_CHESS_TURNED_BISHOP> \xF0\x9F\xA8\xA1
+<WHITE_CHESS_TURNED_KNIGHT> \xF0\x9F\xA8\xA2
+<WHITE_CHESS_TURNED_PAWN> \xF0\x9F\xA8\xA3
+<BLACK_CHESS_TURNED_KING> \xF0\x9F\xA8\xA4
+<BLACK_CHESS_TURNED_QUEEN> \xF0\x9F\xA8\xA5
+<BLACK_CHESS_TURNED_ROOK> \xF0\x9F\xA8\xA6
+<BLACK_CHESS_TURNED_BISHOP> \xF0\x9F\xA8\xA7
+<BLACK_CHESS_TURNED_KNIGHT> \xF0\x9F\xA8\xA8
+<BLACK_CHESS_TURNED_PAWN> \xF0\x9F\xA8\xA9
+<NEUTRAL_CHESS_TURNED_KING> \xF0\x9F\xA8\xAA
+<NEUTRAL_CHESS_TURNED_QUEEN> \xF0\x9F\xA8\xAB
+<NEUTRAL_CHESS_TURNED_ROOK> \xF0\x9F\xA8\xAC
+<NEUTRAL_CHESS_TURNED_BISHOP> \xF0\x9F\xA8\xAD
+<NEUTRAL_CHESS_TURNED_KNIGHT> \xF0\x9F\xA8\xAE
+<NEUTRAL_CHESS_TURNED_PAWN> \xF0\x9F\xA8\xAF
+<WHITE_CHESS_KNIGHT_ROTATED_TWO_HUNDRED_TWENTY-FIVE_DEGREES> \xF0\x9F\xA8\xB0
+<BLACK_CHESS_KNIGHT_ROTATED_TWO_HUNDRED_TWENTY-FIVE_DEGREES> \xF0\x9F\xA8\xB1
+<NEUTRAL_CHESS_KNIGHT_ROTATED_TWO_HUNDRED_TWENTY-FIVE_DEGREES> \xF0\x9F\xA8\xB2
+<WHITE_CHESS_KING_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA8\xB3
+<WHITE_CHESS_QUEEN_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA8\xB4
+<WHITE_CHESS_ROOK_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA8\xB5
+<WHITE_CHESS_BISHOP_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA8\xB6
+<WHITE_CHESS_KNIGHT_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA8\xB7
+<WHITE_CHESS_PAWN_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA8\xB8
+<BLACK_CHESS_KING_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA8\xB9
+<BLACK_CHESS_QUEEN_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA8\xBA
+<BLACK_CHESS_ROOK_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA8\xBB
+<BLACK_CHESS_BISHOP_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA8\xBC
+<BLACK_CHESS_KNIGHT_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA8\xBD
+<BLACK_CHESS_PAWN_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA8\xBE
+<NEUTRAL_CHESS_KING_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA8\xBF
+<NEUTRAL_CHESS_QUEEN_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA9\x80
+<NEUTRAL_CHESS_ROOK_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA9\x81
+<NEUTRAL_CHESS_BISHOP_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA9\x82
+<NEUTRAL_CHESS_KNIGHT_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA9\x83
+<NEUTRAL_CHESS_PAWN_ROTATED_TWO_HUNDRED_SEVENTY_DEGREES> \xF0\x9F\xA9\x84
+<WHITE_CHESS_KNIGHT_ROTATED_THREE_HUNDRED_FIFTEEN_DEGREES> \xF0\x9F\xA9\x85
+<BLACK_CHESS_KNIGHT_ROTATED_THREE_HUNDRED_FIFTEEN_DEGREES> \xF0\x9F\xA9\x86
+<NEUTRAL_CHESS_KNIGHT_ROTATED_THREE_HUNDRED_FIFTEEN_DEGREES> \xF0\x9F\xA9\x87
+<WHITE_CHESS_EQUIHOPPER> \xF0\x9F\xA9\x88
+<BLACK_CHESS_EQUIHOPPER> \xF0\x9F\xA9\x89
+<NEUTRAL_CHESS_EQUIHOPPER> \xF0\x9F\xA9\x8A
+<WHITE_CHESS_EQUIHOPPER_ROTATED_NINETY_DEGREES> \xF0\x9F\xA9\x8B
+<BLACK_CHESS_EQUIHOPPER_ROTATED_NINETY_DEGREES> \xF0\x9F\xA9\x8C
+<NEUTRAL_CHESS_EQUIHOPPER_ROTATED_NINETY_DEGREES> \xF0\x9F\xA9\x8D
+<WHITE_CHESS_KNIGHT-QUEEN> \xF0\x9F\xA9\x8E
+<WHITE_CHESS_KNIGHT-ROOK> \xF0\x9F\xA9\x8F
+<WHITE_CHESS_KNIGHT-BISHOP> \xF0\x9F\xA9\x90
+<BLACK_CHESS_KNIGHT-QUEEN> \xF0\x9F\xA9\x91
+<BLACK_CHESS_KNIGHT-ROOK> \xF0\x9F\xA9\x92
+<BLACK_CHESS_KNIGHT-BISHOP> \xF0\x9F\xA9\x93
<XIANGQI_RED_GENERAL> \xF0\x9F\xA9\xA0
<XIANGQI_RED_MANDARIN> \xF0\x9F\xA9\xA1
<XIANGQI_RED_ELEPHANT> \xF0\x9F\xA9\xA2
@@ -82801,6 +83339,22 @@ CHARMAP
<XIANGQI_BLACK_CHARIOT> \xF0\x9F\xA9\xAB
<XIANGQI_BLACK_CANNON> \xF0\x9F\xA9\xAC
<XIANGQI_BLACK_SOLDIER> \xF0\x9F\xA9\xAD
+<BALLET_SHOES> \xF0\x9F\xA9\xB0
+<ONE-PIECE_SWIMSUIT> \xF0\x9F\xA9\xB1
+<BRIEFS> \xF0\x9F\xA9\xB2
+<SHORTS> \xF0\x9F\xA9\xB3
+<DROP_OF_BLOOD> \xF0\x9F\xA9\xB8
+<ADHESIVE_BANDAGE> \xF0\x9F\xA9\xB9
+<STETHOSCOPE> \xF0\x9F\xA9\xBA
+<YO-YO> \xF0\x9F\xAA\x80
+<KITE> \xF0\x9F\xAA\x81
+<PARACHUTE> \xF0\x9F\xAA\x82
+<RINGED_PLANET> \xF0\x9F\xAA\x90
+<CHAIR> \xF0\x9F\xAA\x91
+<RAZOR> \xF0\x9F\xAA\x92
+<AXE> \xF0\x9F\xAA\x93
+<DIYA_LAMP> \xF0\x9F\xAA\x94
+<BANJO> \xF0\x9F\xAA\x95
<CJK_UNIFIED_IDEOGRAPH-20000> \xF0\xA0\x80\x80
<CJK_UNIFIED_IDEOGRAPH-20001> \xF0\xA0\x80\x81
<CJK_UNIFIED_IDEOGRAPH-20002> \xF0\xA0\x80\x82
diff --git a/tools/tools/locale/patch/patch-UnicodeData.txt b/tools/tools/locale/patch/patch-UnicodeData.txt
new file mode 100644
index 0000000000000..fe65ebacd16ae
--- /dev/null
+++ b/tools/tools/locale/patch/patch-UnicodeData.txt
@@ -0,0 +1,29 @@
+--- UnicodeData.txt.orig 2020-06-29 14:05:49.483379000 +0900
++++ UnicodeData.txt 2020-06-29 14:12:09.808622000 +0900
+@@ -12138,7 +12138,7 @@
+ 33FE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE;So;0;L;<compat> 0033 0031 65E5;;;;N;;;;;
+ 33FF;SQUARE GAL;So;0;ON;<square> 0067 0061 006C;;;;N;;;;;
+ 3400;<CJK Ideograph Extension A, First>;Lo;0;L;;;;;N;;;;;
+-4DBF;<CJK Ideograph Extension A, Last>;Lo;0;L;;;;;N;;;;;
++4DB5;<CJK Ideograph Extension A, Last>;Lo;0;L;;;;;N;;;;;
+ 4DC0;HEXAGRAM FOR THE CREATIVE HEAVEN;So;0;ON;;;;;N;;;;;
+ 4DC1;HEXAGRAM FOR THE RECEPTIVE EARTH;So;0;ON;;;;;N;;;;;
+ 4DC2;HEXAGRAM FOR DIFFICULTY AT THE BEGINNING;So;0;ON;;;;;N;;;;;
+@@ -12204,7 +12204,7 @@
+ 4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;;
+ 4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;;
+ 4E00;<CJK Ideograph, First>;Lo;0;L;;;;;N;;;;;
+-9FFC;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
++9FEF;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
+ A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;;
+ A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;;
+ A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;;
+@@ -32901,7 +32901,7 @@
+ 1FBF8;SEGMENTED DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
+ 1FBF9;SEGMENTED DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
+ 20000;<CJK Ideograph Extension B, First>;Lo;0;L;;;;;N;;;;;
+-2A6DD;<CJK Ideograph Extension B, Last>;Lo;0;L;;;;;N;;;;;
++2A6D6;<CJK Ideograph Extension B, Last>;Lo;0;L;;;;;N;;;;;
+ 2A700;<CJK Ideograph Extension C, First>;Lo;0;L;;;;;N;;;;;
+ 2B734;<CJK Ideograph Extension C, Last>;Lo;0;L;;;;;N;;;;;
+ 2B740;<CJK Ideograph Extension D, First>;Lo;0;L;;;;;N;;;;;
diff --git a/tools/tools/locale/tools/cldr2def.pl b/tools/tools/locale/tools/cldr2def.pl
index 3a6f8ac79d183..5f756cc3895a1 100755
--- a/tools/tools/locale/tools/cldr2def.pl
+++ b/tools/tools/locale/tools/cldr2def.pl
@@ -460,6 +460,11 @@ sub transform_ctypes {
foreach my $enc (sort keys(%{$languages{$l}{$f}{data}{$c}})) {
next if ($enc eq $DEFENCODING);
$filename = "$UNIDIR/posix/$file.$DEFENCODING.src";
+ if ($file eq 'ja_JP') {
+ # Override $filename for ja_JP because
+ # its CTYPE is not compatible with UTF-8.
+ $filename = "$UNIDIR/posix/$file.eucJP.src";
+ }
if (! -f $filename) {
print STDERR "Cannot open $filename\n";
next;
diff --git a/tools/tools/locale/tools/convert_map.pl b/tools/tools/locale/tools/convert_map.pl
index 88222531d0649..8b54ff33381b6 100755
--- a/tools/tools/locale/tools/convert_map.pl
+++ b/tools/tools/locale/tools/convert_map.pl
@@ -87,7 +87,7 @@ sub load_utf8_cm
{
my $file = shift;
- open(UTF8, "$file") || die "open";
+ open(UTF8, "$file") || die "$!: open: $file";
while (<UTF8>) {
next if (/^#/);
@@ -158,7 +158,8 @@ $mf = shift(@ARGV);
$codeset = shift(@ARGV);
my $max_mb;
-load_utf8_cm("etc/final-maps/map.UTF-8");
+my $etcdir = (exists $ENV{'ETCDIR'}) ? $ENV{'ETCDIR'} : "etc";
+load_utf8_cm("${etcdir}/final-maps/map.UTF-8");
load_map($mf);
diff --git a/tools/tools/locale/tools/finalize b/tools/tools/locale/tools/finalize
index f4dfd7d0892f9..88dfcad0cb243 100755
--- a/tools/tools/locale/tools/finalize
+++ b/tools/tools/locale/tools/finalize
@@ -47,15 +47,21 @@ usage ()
$1 = "numericdef" -o $1 = "timedef" -o $1 = "ctypedef" ] || usage
self=$(realpath $0)
-base=$(dirname ${self})
-old=${base}/../${1}.draft
-new=${base}/../${1}
-TEMP=/tmp/${1}.locales
-TEMP2=/tmp/${1}.hashes
-TEMP3=/tmp/${1}.symlinks
-TEMP4=/tmp/${1}.mapped
-FULLMAP=/tmp/utf8-map
-FULLEXTRACT=/tmp/extracted-names
+base=${BASEDIR:-$(dirname ${self})}
+: ${ETCDIR:=${base}/../etc}
+: ${TOOLSDIR:=${base}}
+: ${OUTBASEDIR:=${base}/../${1}}
+: ${OLD_DIR:=${OUTBASEDIR}.draft}
+: ${NEW_DIR:=${OUTBASEDIR}}
+old=${OLD_DIR}
+new=${NEW_DIR}
+: ${TMPDIR:=/tmp}
+TEMP=${TMPDIR}/${1}.locales
+TEMP2=${TMPDIR}/${1}.hashes
+TEMP3=${TMPDIR}/${1}.symlinks
+TEMP4=${TMPDIR}/${1}.mapped
+FULLMAP=${TMPDIR}/utf8-map
+FULLEXTRACT=${TMPDIR}/extracted-names
AWKCMD="/## PLACEHOLDER/ { \
while ( getline line < \"${TEMP}\" ) {print line} } \
/## SYMPAIRS/ { \
@@ -65,6 +71,7 @@ AWKCMD="/## PLACEHOLDER/ { \
!/## / { print \$0 }"
# Rename the sources with 3 components name into the POSIX version of the name using @modifier
+mkdir -p $old $new
cd $old
pwd
for i in *_*_*.*.src; do
@@ -142,13 +149,13 @@ then
rm -f ${TEMP2}
/usr/bin/sed -E -e 's/[ ]+/ /g' \
${UNIDIR}/posix/UTF-8.cm \
- > ${base}/../etc/final-maps/map.UTF-8
+ > ${ETCDIR}/final-maps/map.UTF-8
/usr/bin/sed -E -e 's/[ ]+/ /g' \
${UNIDIR}/posix/eucCN.cm \
- > ${base}/../etc/final-maps/map.eucCN
+ > ${ETCDIR}/final-maps/map.eucCN
/usr/bin/sed -E -e 's/[ ]+/ /g' \
${UNIDIR}/posix/eucCN.cm \
- > ${base}/../etc/final-maps/map.GB2312
+ > ${ETCDIR}/final-maps/map.GB2312
# GB18030 and Big5 are pre-generated from CLDR data
CHARMAPS="ARMSCII-8 CP1131 CP1251 \
@@ -160,10 +167,11 @@ then
for map in ${CHARMAPS}
do
encoding=${map}
- /usr/local/bin/perl ${base}/convert_map.pl \
- ${base}/../etc/charmaps/${map}.TXT ${encoding} \
+ env ETCDIR="${ETCDIR}" \
+ /usr/local/bin/perl ${TOOLSDIR}/convert_map.pl \
+ ${ETCDIR}/charmaps/${map}.TXT ${encoding} \
| /usr/bin/sed -E -e 's/ +/ /g' \
- > ${base}/../etc/final-maps/map.${map}
+ > ${ETCDIR}/final-maps/map.${map}
echo map ${map} converted.
done
diff --git a/tools/tools/locale/tools/utf8-rollup.pl b/tools/tools/locale/tools/utf8-rollup.pl
index da93d2f4398ae..b275828d52c90 100755
--- a/tools/tools/locale/tools/utf8-rollup.pl
+++ b/tools/tools/locale/tools/utf8-rollup.pl
@@ -30,6 +30,7 @@
use strict;
use Getopt::Long;
+use Encode qw(encode decode);
if ($#ARGV != 0) {
print "Usage: $0 --unidir=<unidir>\n";
@@ -52,6 +53,23 @@ generate_footer ();
############################
+sub utf8to32 {
+ my @kl = split /\\x/, $_[0];
+
+ shift @kl if ($kl[0] eq '');
+ my $k = pack('H2' x scalar @kl, @kl);
+ my $ux = encode('UTF-32BE', decode('UTF-8', $k));
+ my $u = uc(unpack('H*', $ux));
+ # Remove BOM
+ $u =~ s/^0000FEFF//;
+ # Remove heading bytes of 0
+ while ($u =~ m/^0/ and length($u) > 4) {
+ $u =~ s/^0//;
+ }
+
+ return $u;
+}
+
sub get_utf8map {
my $file = shift;
@@ -75,9 +93,10 @@ sub get_utf8map {
last if ($l eq "END CHARMAP");
$l =~ /^(<[^\s]+>)\s+(.*)/;
- my $k = $2;
+ my $k = utf8to32($2); # UTF-8 char code
my $v = $1;
- $k =~ s/\\x//g; # UTF-8 char code
+
+# print STDERR "register: $k - $v\n";
$utf8map{$k} = $v;
}
}
@@ -143,7 +162,7 @@ sub parse_unidata {
foreach my $l (@lines) {
my @d = split(/;/, $l, -1);
- my $mb = wctomb($d[0]);
+ my $mb = $d[0];
my $cat;
# XXX There are code points present in UnicodeData.txt
@@ -180,9 +199,9 @@ sub parse_unidata {
# Check if there's upper/lower mapping
if ($d[12] ne "") {
- $data{'toupper'}{$mb} = wctomb($d[12]);
+ $data{'toupper'}{$mb} = $d[12];
} elsif ($d[13] ne "") {
- $data{'tolower'}{$mb} = wctomb($d[13]);
+ $data{'tolower'}{$mb} = $d[13];
}
}
@@ -193,7 +212,7 @@ sub parse_unidata {
foreach my $cat (sort keys (%data)) {
print FOUT "$cat\t";
$first = 1;
- foreach my $mb (sort keys (%{$data{$cat}})) {
+ foreach my $mb (sort {hex($a) <=> hex($b)} keys (%{$data{$cat}})) {
if ($first == 1) {
$first = 0;
} elsif ($inrange == 1) {
diff --git a/usr.bin/fortune/fortune/fortune.c b/usr.bin/fortune/fortune/fortune.c
index af408d6dff1d2..724fb4a2372eb 100644
--- a/usr.bin/fortune/fortune/fortune.c
+++ b/usr.bin/fortune/fortune/fortune.c
@@ -400,11 +400,12 @@ form_file_list(char **files, int file_cnt)
sp = files[i];
else {
percent = 0;
- for (sp = files[i]; isdigit((unsigned char)*sp); sp++)
+ for (sp = files[i]; isdigit((unsigned char)*sp); sp++) {
percent = percent * 10 + *sp - '0';
- if (percent > 100) {
- fprintf(stderr, "percentages must be <= 100\n");
- return (FALSE);
+ if (percent > 100) {
+ fprintf(stderr, "percentages must be <= 100\n");
+ return (FALSE);
+ }
}
if (*sp == '.') {
fprintf(stderr, "percentages must be integers\n");
diff --git a/usr.bin/fortune/strfile/strfile.c b/usr.bin/fortune/strfile/strfile.c
index ce28e274fd553..f6cda6cd39008 100644
--- a/usr.bin/fortune/strfile/strfile.c
+++ b/usr.bin/fortune/strfile/strfile.c
@@ -295,16 +295,26 @@ getargs(int argc, char **argv)
if (*argv) {
Infile = *argv;
- if (*++argv)
- strcpy(Outfile, *argv);
+ if (*++argv) {
+ if (strlcpy(Outfile, *argv, sizeof(Outfile)) >=
+ sizeof(Outfile)) {
+ fprintf(stderr,
+ "output_file path is too long\n");
+ exit(1);
+ }
+ }
}
if (!Infile) {
puts("No input file name");
usage();
}
if (*Outfile == '\0') {
- strlcpy(Outfile, Infile, sizeof(Outfile));
- strlcat(Outfile, ".dat", sizeof(Outfile));
+ if ((size_t)snprintf(Outfile, sizeof(Outfile), "%s.dat",
+ Infile) >= sizeof(Outfile)) {
+ fprintf(stderr,
+ "generated output_file path is too long\n");
+ exit(1);
+ }
}
}
diff --git a/usr.bin/script/script.c b/usr.bin/script/script.c
index 8d22ea4251e75..149458baa331d 100644
--- a/usr.bin/script/script.c
+++ b/usr.bin/script/script.c
@@ -176,16 +176,16 @@ main(int argc, char *argv[])
if (pflg)
playback(fscript);
- if ((ttyflg = isatty(STDIN_FILENO)) != 0) {
- if (tcgetattr(STDIN_FILENO, &tt) == -1)
- err(1, "tcgetattr");
- if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win) == -1)
- err(1, "ioctl");
- if (openpty(&master, &slave, NULL, &tt, &win) == -1)
+ if (tcgetattr(STDIN_FILENO, &tt) == -1 ||
+ ioctl(STDIN_FILENO, TIOCGWINSZ, &win) == -1) {
+ if (errno != ENOTTY) /* For debugger. */
+ err(1, "tcgetattr/ioctl");
+ if (openpty(&master, &slave, NULL, NULL, NULL) == -1)
err(1, "openpty");
} else {
- if (openpty(&master, &slave, NULL, NULL, NULL) == -1)
+ if (openpty(&master, &slave, NULL, &tt, &win) == -1)
err(1, "openpty");
+ ttyflg = 1;
}
if (rawout)
@@ -433,9 +433,8 @@ termset(void)
struct termios traw;
if (tcgetattr(STDOUT_FILENO, &tt) == -1) {
- if (errno == EBADF)
- err(1, "%d not valid fd", STDOUT_FILENO);
- /* errno == ENOTTY */
+ if (errno != ENOTTY) /* For debugger. */
+ err(1, "tcgetattr");
return;
}
ttyflg = 1;
diff --git a/usr.bin/tput/tput.1 b/usr.bin/tput/tput.1
index ad91f7d381062..996575bb622e5 100644
--- a/usr.bin/tput/tput.1
+++ b/usr.bin/tput/tput.1
@@ -38,22 +38,24 @@
.Sh SYNOPSIS
.Nm
.Op Fl T Ar term
-.Ar attribute ...
+.Op Ar attribute ...
.Nm clear
.Sh DESCRIPTION
The
.Nm
utility makes terminal-dependent information available to users or shell
applications.
-When invoked as the
+.Pp
+The
.Nm clear
-utility, the screen will be cleared as if
+utility executes the
.Dl tput clear
-had been executed.
-The options to
+command, ignoring any arguments.
+.Pp
+The only option to
.Nm
-are as follows:
-.Bl -tag -width Ds
+is:
+.Bl -tag -width 2n
.It Fl T
The terminal name as specified in the
.Xr termcap 5
@@ -65,7 +67,9 @@ If not specified,
.Nm
retrieves the
.Dq Ev TERM
-variable from the environment.
+variable from the environment unless that too is not specified,
+in which case an error message will be sent to standard error and
+the error status will be 2.
.El
.Pp
The
@@ -83,28 +87,37 @@ If an
is of type string, and takes arguments (e.g.\& cursor movement,
the termcap
.Dq cm
-sequence) the arguments are taken from the command line immediately
+capability) the arguments are taken from the command line immediately
following the attribute.
.Pp
-The following special attributes are available:
+The following special attributes are available.
+The first three use the capabilities of the specified terminal,
+and only work if compatible with the utility's terminal.
.Bl -tag -width Ar
.It Cm clear
Clear the screen (the
.Xr termcap 5
.Dq cl
-sequence).
+capability).
.It Cm init
Initialize the terminal (the
.Xr termcap 5
.Dq is
-sequence).
-.It Cm longname
-Print the descriptive name of the user's terminal type.
+capability).
.It Cm reset
Reset the terminal (the
.Xr termcap 5
.Dq rs
-sequence).
+capability).
+.It Cm longname
+Print the descriptive name of the user's terminal type.
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width ".Ev TERM"
+.It Ev TERM
+The terminal name, if set and
+.Fl T
+is not used.
.El
.Sh EXIT STATUS
The exit status of
@@ -112,16 +125,28 @@ The exit status of
is as follows:
.Bl -tag -width indent
.It 0
-If the last attribute
+If the last
.Ar attribute
-argument is of type string or integer, its value was successfully written
+is of type string or integer, its value was successfully written
to standard output.
-If the argument is of type boolean, the terminal has this attribute.
+If the
+.Ar attribute
+is of type boolean, the terminal does have the
+.Ar attribute .
+Otherwise, no
+.Ar attribute
+was specified.
.It 1
-This terminal does not have the specified boolean
+If the last
+.Ar attribute
+is of type boolean,
+this terminal does not have the
.Ar attribute .
.It 2
Usage error.
+For example, see
+.Fl T
+description.
.It 3
No information is available about the specified terminal type.
.El
diff --git a/usr.sbin/crunch/crunchgen/crunchgen.c b/usr.sbin/crunch/crunchgen/crunchgen.c
index dc0510e24e6a1..5a3200ed7fac8 100644
--- a/usr.sbin/crunch/crunchgen/crunchgen.c
+++ b/usr.sbin/crunch/crunchgen/crunchgen.c
@@ -39,10 +39,13 @@ __FBSDID("$FreeBSD$");
#include <ctype.h>
#include <err.h>
+#include <fcntl.h>
#include <paths.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sysexits.h>
#include <unistd.h>
#define CRUNCH_VERSION "0.2"
@@ -91,6 +94,7 @@ prog_t *progs = NULL;
char confname[MAXPATHLEN], infilename[MAXPATHLEN];
char outmkname[MAXPATHLEN], outcfname[MAXPATHLEN], execfname[MAXPATHLEN];
char tempfname[MAXPATHLEN], cachename[MAXPATHLEN], curfilename[MAXPATHLEN];
+bool tempfname_initialized = false;
char outhdrname[MAXPATHLEN] ; /* user-supplied header for *.mk */
char *objprefix; /* where are the objects ? */
char *path_make;
@@ -216,6 +220,7 @@ main(int argc, char **argv)
snprintf(cachename, sizeof(cachename), "%s.cache", confname);
snprintf(tempfname, sizeof(tempfname), "%s/crunchgen_%sXXXXXX",
getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP, confname);
+ tempfname_initialized = false;
parse_conf_file();
if (list_mode)
@@ -648,8 +653,7 @@ fillin_program(prog_t *p)
/* Determine the actual srcdir (maybe symlinked). */
if (p->srcdir) {
- snprintf(line, MAXLINELEN, "cd %s && echo -n `/bin/pwd`",
- p->srcdir);
+ snprintf(line, MAXLINELEN, "cd %s && pwd -P", p->srcdir);
f = popen(line,"r");
if (!f)
errx(1, "Can't execute: %s\n", line);
@@ -721,14 +725,26 @@ fillin_program_objs(prog_t *p, char *path)
/* discover the objs from the srcdir Makefile */
- if ((fd = mkstemp(tempfname)) == -1) {
- perror(tempfname);
- exit(1);
+ /*
+ * We reuse the same temporary file name for multiple objects. However,
+ * some libc implementations (such as glibc) return EINVAL if there
+ * are no XXXXX characters in the template. This happens after the
+ * first call to mkstemp since the argument is modified in-place.
+ * To avoid this error we use open() instead of mkstemp() after the
+ * call to mkstemp().
+ */
+ if (tempfname_initialized) {
+ if ((fd = open(tempfname, O_CREAT | O_EXCL | O_RDWR, 0600)) == -1) {
+ err(EX_OSERR, "open(%s)", tempfname);
+ }
+ } else if ((fd = mkstemp(tempfname)) == -1) {
+ err(EX_OSERR, "mkstemp(%s)", tempfname);
}
+ tempfname_initialized = true;
if ((f = fdopen(fd, "w")) == NULL) {
- warn("%s", tempfname);
+ warn("fdopen(%s)", tempfname);
goterror = 1;
- return;
+ goto out;
}
if (p->objvar)
objvar = p->objvar;
@@ -763,14 +779,14 @@ fillin_program_objs(prog_t *p, char *path)
if ((f = popen(line, "r")) == NULL) {
warn("submake pipe");
goterror = 1;
- return;
+ goto out;
}
while(fgets(line, MAXLINELEN, f)) {
if (strncmp(line, "OBJS= ", 6)) {
warnx("make error: %s", line);
goterror = 1;
- continue;
+ goto out;
}
cp = line + 6;
@@ -793,7 +809,7 @@ fillin_program_objs(prog_t *p, char *path)
warnx("make error: make returned %d", rc);
goterror = 1;
}
-
+out:
unlink(tempfname);
}
diff --git a/usr.sbin/pwd_mkdb/bootstrap/pwd.h b/usr.sbin/pwd_mkdb/bootstrap/pwd.h
index a3b595881e217..bc196e2c0fd03 100644
--- a/usr.sbin/pwd_mkdb/bootstrap/pwd.h
+++ b/usr.sbin/pwd_mkdb/bootstrap/pwd.h
@@ -60,7 +60,7 @@ typedef uint64_t _bootstrap_time_t;
#define uid_t _bootstrap_uid_t
#define time_t _bootstrap_time_t
#define passwd _bootstrap_passwd
-#include "../../include/pwd.h"
+#include "../../../include/pwd.h"
#undef gid_t
#undef uid_t
#undef time_t