diff --git a/Makefile.inc1 b/Makefile.inc1 index 00abab63d24b..9223123b1e1b 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 9e12bded35d5..48c6a6bd3c4d 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 50b7f1c1b908..de4b86270efa 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 d5651ff727fc..11b327cbff17 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" +set -e -BSDECHO=-e +printf "%s" " +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ -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\ #include -\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 2fdc2fa636d5..c7c28e75364e 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 -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 \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 1bffa6468c2b..2bd5ec92b43e 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 c8ea2f23ecac..73a5fe6eca9c 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 22821c7bcb5a..453cba29ddf5 100644 --- a/lib/libbsnmp/Makefile +++ b/lib/libbsnmp/Makefile @@ -1,5 +1,6 @@ # $FreeBSD$ SUBDIR= libbsnmp +SUBDIR.${MK_TESTS}+= tests .include diff --git a/lib/libbsnmp/tests/Makefile b/lib/libbsnmp/tests/Makefile new file mode 100644 index 000000000000..74fbec52ec13 --- /dev/null +++ b/lib/libbsnmp/tests/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ + +.include + +ATF_TESTS_C+= bsnmpd_test + +SRCS.bsmpd_test= bsnmpd_test.c + +LIBADD+= bsnmp + +.include diff --git a/lib/libbsnmp/tests/bsnmpd_test.c b/lib/libbsnmp/tests/bsnmpd_test.c new file mode 100644 index 000000000000..c6e4bfd385b5 --- /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 + +#include + +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 f86c7b04b92b..779b418e9340 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 f9d4f158ed30..e17d74d1a151 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 712d14ee9c04..b1c0ecb83622 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 036a0166d48b..7e5bcce905fb 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 @@ scandir(const char *dirname, struct dirent ***namelist, 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 a0f1ddc97535..19d44db0075a 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 28fc05a9aa71..e5f5e3c5960a 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 diff --git a/lib/liblua/luaconf.h b/lib/liblua/luaconf.h index b24645b8915f..bc7f5bb6e141 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 6e39373c1cb4..7d435cab0ff0 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 a4dc916e7834..cfa1f2460f5f 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 6a430b55d897..fe328308e622 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 a742daa363d5..56b64f8c8271 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 bff94154dc65..d4fa6b65dff4 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 a1543e63e704..eb1efc4d6274 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 ab80cec50576..92f124cd4f27 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 c42a03534675..24dbf269df3f 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 fcf05b313b38..ec246dfacd75 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 f0d1730f9976..bc298efcabf4 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 3f8820abcbdf..0642f21d1daa 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 fcf05b313b38..ec246dfacd75 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 38bbb992d454..b3d76eb4019d 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 fcf05b313b38..ec246dfacd75 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 fcb9a567125b..8448a15ebf7b 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 d7684a6d889d..b7317cae507c 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 3f8820abcbdf..0642f21d1daa 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 3f8820abcbdf..0642f21d1daa 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 b17971acb2eb..6b51c830ab5c 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 faf264e00f10..415094e9d69f 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 5211101e9e8c..f80da47be55b 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 38844f0f0898..f7cea7af8893 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 1ba9560abf12..d250e76752f9 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 936b46e4cb4c..ab5725d1c1d8 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 0aa73b095a57..65847ad5954b 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 ea35a2767845..58bc3662fcc7 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 d4c81d5e4d66..830b35d2f723 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 @@ compile_rule(char *av[], uint32_t *rbuf, int *rbufsize, struct tidx *tstate) 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 d97775b9afe4..e201cfa36e31 100644 --- a/secure/lib/libssl/Makefile +++ b/secure/lib/libssl/Makefile @@ -31,7 +31,7 @@ CFLAGS+= -I${.OBJDIR:H}/libcrypto .include -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 9049f3feb5e3..95ed799361f2 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 000000000000..39ac8dba114e --- /dev/null +++ b/share/man/man4/cp2112.4 @@ -0,0 +1,87 @@ +.\" +.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" +.\" Copyright (c) 2020 Andriy Gapon +.\" +.\" 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 33e162d5fae0..993f65188543 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 000000000000..63132c28c198 --- /dev/null +++ b/share/man/man9/prng.9 @@ -0,0 +1,99 @@ +.\"- +.\" Copyright 2020 Conrad Meyer . 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 1a2339390990..ae867502c6f2 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 e596f216c258..234b13205c67 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 # diff --git a/share/mk/sys.mk b/share/mk/sys.mk index 2248d64f6580..215b04563e23 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 75efeceab26b..714adba6c9cb 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 <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 c5091e93efe2..9cac6fce439b 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 7ce13d01d3eb..eafd9e00caf0 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 __FBSDID("$FreeBSD$"); @@ -33,94 +33,347 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include +#include + #include #include #include #include #include +#include #include - #include +#include "if_dwc_if.h" #include "syscon_if.h" -#include "if_dwc_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; - 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); + 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); - 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 = 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")); + + 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); + + 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; + } +} - 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; +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); +} - SYSCON_WRITE_4(grf, RK3399_GRF_SOC_CON6, tx | rx | 0xFFFF0000); +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; + + 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); + + 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 @@ -136,26 +389,189 @@ if_dwc_rk_probe(device_t dev) return (BUS_PROBE_DEFAULT); } +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; - /* Mode should be set according to dtb property */ + 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"); + + 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 367c943f0dce..892dee5a9959 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 687da220325a..fbb9cf19d839 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 2dd9b43ac017..f2e5d2ba36e1 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 7e259760f7c3..1bcbd681203c 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 0545710a61d7..da38d89eb639 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 7723910316ae..348464fb27df 100644 --- a/sys/compat/linuxkpi/common/include/linux/wait.h +++ b/sys/compat/linuxkpi/common/include/linux/wait.h @@ -36,6 +36,7 @@ #include #include #include +#include #include 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 000000000000..e3dddaade498 --- /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 +#include + +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 0d5e14b9d027..b3c2475b223f 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 #include #include +#include #if defined(__i386__) || defined(__amd64__) #include @@ -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 32ace5cf0c99..5e698739ab09 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 809c14a95aff..000000000000 --- 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 04e224437f93..052e8c238f43 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 2436269c893c..16910042af8b 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 768fb75ae93b..14f8e7aa2cf8 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 - -#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 44350ae087cc..0b38439b3e12 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 d20f35d74ce5..045072abe611 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 733f83545cf4..dae429c55e8a 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 9db24c14f328..0470b29cb0e1 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 714bca6e61fb..6fd1edddab44 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 #include @@ -56,6 +57,11 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef EVDEV_SUPPORT +#include +#include +#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 2618a889e86f..4ae8645abaf6 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 6f7282f8ea55..cb3c299b3aab 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 1cff7efb8150..bba7f2699b22 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 51021ed28e6a..6e86e68eb8db 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 8ac8c2bf9963..1e8488867844 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 + * Copyright (C) 2018-2020 Alexander Motin * * 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 #include +#include + +#include #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 c9d8d94543d7..efec8d34868a 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 0430fdbfe56f..a2ead7d5371e 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 +#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,117 +632,44 @@ 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); + 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; + } + + CP2112GPIO_LOCK(sc); + pin = &sc->pins[pin_num]; err = cp2112_gpio_configure_write_pin(dev, pin_num, - (flags & GPIO_PIN_OUTPUT) != 0, - (flags & GPIO_PIN_PUSHPULL) != 0); - if (err == 0) + (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; + } 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"); - } - - 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 cp2112gpio_probe(device_t dev) { @@ -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 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 673d94999169..aef291601289 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 3929cc8b1e80..e3d86cf902bf 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 4b23e4fce272..5c3cb17eca61 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 f9e29e0b1c74..983bfc803999 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 @@ devfs_allocv(struct devfs_dirent *de, struct mount *mp, int lockmode, /* 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 void +devfs_reclaiml(struct vnode *vp) +{ + struct devfs_dirent *de; + + 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; - struct devfs_dirent *de; vp = ap->a_vp; mtx_lock(&devfs_de_interlock); - de = vp->v_data; - if (de != NULL) { - de->de_vnode = NULL; - vp->v_data = NULL; - } + 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 29d5373b5966..70b2536245ff 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 334d46e05c23..79c6067c9866 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 d9e03cf7b791..1fc4e2a4d757 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -1057,25 +1057,6 @@ nfsaddr2_match(NFSSOCKADDR_T nam1, NFSSOCKADDR_T nam2) return (0); } -/* - * 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. */ @@ -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 7bf89011d2fd..695c72f74ad3 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 f4a6b8dfa90b..b93facfbe264 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 33065249315f..f64615df7f8f 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 7124c10573fa..e97d42f4a381 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 5d15c68c4ead..68216a6f50f5 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 cbaf992052a8..2d14081c0e3c 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 312440ab509e..f906f3c6c838 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 ce9554b6dfaa..50449938c5c1 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -88,6 +88,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #ifdef COMPAT_FREEBSD32 #include #include @@ -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 000000000000..124a56e0e4ea --- /dev/null +++ b/sys/kern/subr_prng.c @@ -0,0 +1,131 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright 2020 Conrad Meyer . 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#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 a19b6efb0271..ad390e0a0c98 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 @@ pipe_direct_write(struct pipe *wpipe, struct uio *uio) 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 @@ pipe_direct_write(struct pipe *wpipe, struct uio *uio) } 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 4c11ff56000b..a6ed98f86297 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -67,6 +67,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include 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 e78fc25ec343..43b36dccb028 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -61,6 +61,9 @@ __FBSDID("$FreeBSD$"); #ifdef KTRACE #include #endif +#ifdef INVARIANTS +#include +#endif #include #include @@ -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 4df6be9ace71..03bfa129b16c 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); @@ -2793,59 +2791,6 @@ v_init_counters(struct vnode *vp) refcount_init(&vp->v_usecount, 1); } -/* - * 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 @@ -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); } @@ -3122,35 +2952,6 @@ vrefact(struct vnode *vp) #endif } -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) { @@ -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 @@ vput_final(struct vnode *vp, enum vput_op func) * 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); @@ -4143,20 +3916,6 @@ vgonel(struct vnode *vp) vp->v_type = VBAD; } -/* - * 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. */ diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 69a6be798208..f44b440be661 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -87,14 +87,12 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include 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 e5e9de6108e1..23a8887fa49b 100644 --- a/sys/libkern/random.c +++ b/sys/libkern/random.c @@ -36,43 +36,14 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include -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 7065c1f0f6cd..c91dfbdaf380 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 046eeeda30f2..33dccc907709 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 814a5b5b14c7..4930e1820f3b 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 b7cc308d22f2..fd3384a5175d 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 99f13438f800..e2d32c563513 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 f24200a88e40..4167df8d0cce 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); @@ -405,55 +362,6 @@ sys_setfib(struct thread *td, struct setfib_args *uap) return (0); } -/* - * 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 @@ -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 1ffabcbc86df..b8a98007a41e 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 ade0b2a96b24..f448bcef1b8d 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,25 +817,13 @@ rib_notify(struct rib_head *rnh, enum rib_subscription_type type, } } -/* - * 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) +static struct rib_subscription * +allocate_subscription(rib_subscription_cb_t *f, void *arg, + enum rib_subscription_type type, bool waitok) { - struct rib_head *rnh; struct rib_subscription *rs; int flags = M_ZERO | (waitok ? M_WAITOK : 0); - NET_EPOCH_ASSERT(); - 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); @@ -767,9 +832,54 @@ rib_subscribe(uint32_t fibnum, int family, rib_subscription_cb_t *f, void *arg, rs->arg = arg; rs->type = type; + return (rs); +} + + +/* + * Subscribe for the changes in the routing table specified by @fibnum and + * @family. + * + * 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, bool waitok) +{ + struct rib_head *rnh; + struct rib_subscription *rs; + struct epoch_tracker et; + + 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); + RIB_WLOCK(rnh); CK_STAILQ_INSERT_TAIL(&rnh->rnh_subscribers, rs, next); RIB_WUNLOCK(rnh); + NET_EPOCH_EXIT(et); + + 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 b06eb2c30e5d..62208609cd4d 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 4427ac046ee8..a55835ffa9d6 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 4ea20c5e011e..3d68f5db0c8e 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 8e00c95942ac..0b8edf452c23 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 cbd2e7189326..a905033c458d 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 cf624e8a3157..99efb4bdb3e4 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 2288a4c36abe..4133ded92a82 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 38a9d9232a8a..21f2e67b15bd 100644 --- a/sys/netinet/in_rmx.c +++ b/sys/netinet/in_rmx.c @@ -54,10 +54,6 @@ __FBSDID("$FreeBSD$"); #include #include -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 9babe5d053d9..fabd8e1ab50c 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 41c202c0d62f..74e645660096 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 337871e8fdc2..9bf6f52855a7 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 423836afb621..b7879269966d 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 e564540b007d..a9c7dea39954 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 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, 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 27cbad42f9ae..37575a14467c 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 c1fb25853836..d79ac73525d9 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 fb53adb86e82..31cb54aef6a0 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 2433dc2ee194..fde7e5dad165 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 ea7a468ac72b..9f9c9b9dbbf8 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 357292c5c59d..c026bf4a057c 100644 --- a/sys/netinet6/in6_rmx.c +++ b/sys/netinet6/in6_rmx.c @@ -101,11 +101,6 @@ __FBSDID("$FreeBSD$"); #include #include -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 7381ff68064a..f5e6a931ae64 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 42d999be6a8d..f99585dc1789 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 cdb2b9572bc2..181e30afe6f8 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 bbdbcc88a038..bfce77f40c3f 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 46b258380a10..5068596462fc 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 3d4c70c491d6..9fecd25c67cb 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 7f4be068ec27..40183afb9f4d 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 2a783b2ed0f0..6d7b6b934d43 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 4a5b01df85b7..86eaab6d533b 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 2e016f537f91..d4939dbda041 100644 --- a/sys/riscv/riscv/stack_machdep.c +++ b/sys/riscv/riscv/stack_machdep.c @@ -47,15 +47,18 @@ __FBSDID("$FreeBSD$"); #include 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 aa9ec534669d..dabd84e822e9 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 18fc1e250c9b..8b0cdeca2903 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 26a21cf13187..23c92103edff 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 e83dd0f4afc5..3d17879f1ccd 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 784eb79311c0..42d39e7330ab 100644 --- a/sys/sys/namei.h +++ b/sys/sys/namei.h @@ -152,23 +152,32 @@ 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 */ diff --git a/sys/sys/param.h b/sys/sys/param.h index cdb5495ed335..171300319991 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 4e633262191d..2f1568ab6637 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 7e14df30bff8..224d84c484f4 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 000000000000..a1abe6ad1a11 --- /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 + +#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 a7ca84e92bc7..a971ffbbd91b 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 87c01a962064..9d736483d008 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 d90423bd9c5f..9d0786c1d754 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 e316dd5cae0d..d7d4d8986f15 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 593af4b5a2e4..1e6a392d862c 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 039e467491d0..a44e31f506d0 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 db2aa5f1c1cf..a882a17f3f39 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -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 @@ -1439,25 +1446,15 @@ 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 @@ vm_pageout_scan_inactive(struct vm_domain *vmd, int shortage, 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; @@ -2081,6 +2168,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 @@ -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 0573457db675..0e5d1c911b8d 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 +#include #include 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 8a53ac0ecaa6..c138b7acc4aa 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 73eeac3ee09a..23bd6cc1896f 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 ae580b301d41..000000000000 --- 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 [ [ ] ]" - 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 508034d19695..aad2c2160bb5 100644 --- a/tools/tools/locale/Makefile +++ b/tools/tools/locale/Makefile @@ -7,19 +7,30 @@ # # Modified by John Marino to suit DragonFly needs # - -.OBJDIR: . - -.if !defined(UNIDIR) -.error UNIDIR is not set +.if ${.CURDIR} == ${.OBJDIR} +.error Do make obj first. .endif -PASSON= UNIDIR="${UNIDIR}" -ETCDIR= ${.CURDIR}/etc +LOCALESRCDIR?= ${DESTDIR}/usr/src/share +TMPDIR?= /tmp + +BASEDIR= ${.CURDIR} +ETCDIR= ${BASEDIR}/etc +TOOLSDIR= ${BASEDIR}/tools +PATCHDIR= ${BASEDIR}/patch +UNIDIR= ${.OBJDIR:tA}/unicode + +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: -.for t in ${TYPES} -. if ${KNOWN:M${t}} - test -d ${t} || mkdir ${t} - make build-${t} -. endif -.endfor +all: posix build afterbuild +.ORDER: posix build afterbuild + +afterbuild: build @echo "" @find . -name *failed .for t in ${TYPES} +. if ${KNOWN:M${t}} +build: build-${t} +.ORDER: build-${t} afterbuild +. endif +.endfor + +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 -.if !exists(${UNIDIR}/tools/java/cldr.jar) -.error check README about building cldr.jar +# 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) +.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 diff --git a/tools/tools/locale/README b/tools/tools/locale/README index 60357d4d8dfe..8dc8c2a25fc1 100644 --- a/tools/tools/locale/README +++ b/tools/tools/locale/README @@ -1,32 +1,58 @@ # $FreeBSD$ -To generate the locales: +Files in this directory are used to generate locale source files +from files in CLDR (Unicode Common Locale Data Repository). -Tools needed: - java (openjdk >= 8) - perl - converters/p5-Text-Iconv - devel/apache-ant - devel/p5-Tie-IxHash - textproc/p5-XML-Parser +To generate the files, do the following: -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 + 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 031b8545982d..ad0dfd2c7de6 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 \xE0\xB1\xAD \xE0\xB1\xAE \xE0\xB1\xAF + \xE0\xB1\xB7 \xE0\xB1\xB8 \xE0\xB1\xB9 \xE0\xB1\xBA @@ -3363,14 +3364,24 @@ CHARMAP \xE0\xBA\x81 \xE0\xBA\x82 \xE0\xBA\x84 + \xE0\xBA\x86 \xE0\xBA\x87 \xE0\xBA\x88 + \xE0\xBA\x89 \xE0\xBA\x8A + \xE0\xBA\x8C \xE0\xBA\x8D + \xE0\xBA\x8E + \xE0\xBA\x8F + \xE0\xBA\x90 + \xE0\xBA\x91 + \xE0\xBA\x92 + \xE0\xBA\x93 \xE0\xBA\x94 \xE0\xBA\x95 \xE0\xBA\x96 \xE0\xBA\x97 + \xE0\xBA\x98 \xE0\xBA\x99 \xE0\xBA\x9A \xE0\xBA\x9B @@ -3378,13 +3389,17 @@ CHARMAP \xE0\xBA\x9D \xE0\xBA\x9E \xE0\xBA\x9F + \xE0\xBA\xA0 \xE0\xBA\xA1 \xE0\xBA\xA2 \xE0\xBA\xA3 \xE0\xBA\xA5 \xE0\xBA\xA7 + \xE0\xBA\xA8 + \xE0\xBA\xA9 \xE0\xBA\xAA \xE0\xBA\xAB + \xE0\xBA\xAC \xE0\xBA\xAD \xE0\xBA\xAE \xE0\xBA\xAF @@ -3398,6 +3413,7 @@ CHARMAP \xE0\xBA\xB7 \xE0\xBA\xB8 \xE0\xBA\xB9 + \xE0\xBA\xBA \xE0\xBA\xBB \xE0\xBA\xBC \xE0\xBA\xBD @@ -6656,6 +6672,7 @@ CHARMAP \xE1\xB3\xB7 \xE1\xB3\xB8 \xE1\xB3\xB9 + \xE1\xB3\xBA \xE1\xB4\x80 \xE1\xB4\x81 \xE1\xB4\x82 @@ -10325,6 +10342,7 @@ CHARMAP \xE2\xAF\x86 \xE2\xAF\x87 \xE2\xAF\x88 + \xE2\xAF\x89 \xE2\xAF\x8A \xE2\xAF\x8B \xE2\xAF\x8C @@ -10378,6 +10396,7 @@ CHARMAP \xE2\xAF\xBC \xE2\xAF\xBD \xE2\xAF\xBE + \xE2\xAF\xBF \xE2\xB0\x80 \xE2\xB0\x81 \xE2\xB0\x82 @@ -10916,6 +10935,7 @@ CHARMAP \xE2\xB9\x8C \xE2\xB9\x8D \xE2\xB9\x8E + \xE2\xB9\x8F \xE2\xBA\x80 \xE2\xBA\x81 \xE2\xBA\x82 @@ -41812,6 +41832,17 @@ CHARMAP \xEA\x9E\xB7 \xEA\x9E\xB8 \xEA\x9E\xB9 + \xEA\x9E\xBA + \xEA\x9E\xBB + \xEA\x9E\xBC + \xEA\x9E\xBD + \xEA\x9E\xBE + \xEA\x9E\xBF + \xEA\x9F\x82 + \xEA\x9F\x83 + \xEA\x9F\x84 + \xEA\x9F\x85 + \xEA\x9F\x86 \xEA\x9F\xB7 \xEA\x9F\xB8 \xEA\x9F\xB9 @@ -42577,6 +42608,8 @@ CHARMAP \xEA\xAD\xA3 \xEA\xAD\xA4 \xEA\xAD\xA5 + \xEA\xAD\xA6 + \xEA\xAD\xA7 \xEA\xAD\xB0 \xEA\xAD\xB1 \xEA\xAD\xB2 @@ -64381,6 +64414,29 @@ CHARMAP \xF0\x90\xBD\x97 \xF0\x90\xBD\x98 \xF0\x90\xBD\x99 + \xF0\x90\xBF\xA0 + \xF0\x90\xBF\xA1 + \xF0\x90\xBF\xA2 + \xF0\x90\xBF\xA3 + \xF0\x90\xBF\xA4 + \xF0\x90\xBF\xA5 + \xF0\x90\xBF\xA6 + \xF0\x90\xBF\xA7 + \xF0\x90\xBF\xA8 + \xF0\x90\xBF\xA9 + \xF0\x90\xBF\xAA + \xF0\x90\xBF\xAB + \xF0\x90\xBF\xAC + \xF0\x90\xBF\xAD + \xF0\x90\xBF\xAE + \xF0\x90\xBF\xAF + \xF0\x90\xBF\xB0 + \xF0\x90\xBF\xB1 + \xF0\x90\xBF\xB2 + \xF0\x90\xBF\xB3 + \xF0\x90\xBF\xB4 + \xF0\x90\xBF\xB5 + \xF0\x90\xBF\xB6 \xF0\x91\x80\x80 \xF0\x91\x80\x81 \xF0\x91\x80\x82 @@ -65163,6 +65219,7 @@ CHARMAP \xF0\x91\x91\x9B \xF0\x91\x91\x9D \xF0\x91\x91\x9E + \xF0\x91\x91\x9F \xF0\x91\x92\x80 \xF0\x91\x92\x81 \xF0\x91\x92\x82 @@ -65485,6 +65542,7 @@ CHARMAP \xF0\x91\x9A\xB5 \xF0\x91\x9A\xB6 \xF0\x91\x9A\xB7 + \xF0\x91\x9A\xB8 \xF0\x91\x9B\x80 \xF0\x91\x9B\x81 \xF0\x91\x9B\x82 @@ -65697,6 +65755,71 @@ CHARMAP \xF0\x91\xA3\xB1 \xF0\x91\xA3\xB2 \xF0\x91\xA3\xBF + \xF0\x91\xA6\xA0 + \xF0\x91\xA6\xA1 + \xF0\x91\xA6\xA2 + \xF0\x91\xA6\xA3 + \xF0\x91\xA6\xA4 + \xF0\x91\xA6\xA5 + \xF0\x91\xA6\xA6 + \xF0\x91\xA6\xA7 + \xF0\x91\xA6\xAA + \xF0\x91\xA6\xAB + \xF0\x91\xA6\xAC + \xF0\x91\xA6\xAD + \xF0\x91\xA6\xAE + \xF0\x91\xA6\xAF + \xF0\x91\xA6\xB0 + \xF0\x91\xA6\xB1 + \xF0\x91\xA6\xB2 + \xF0\x91\xA6\xB3 + \xF0\x91\xA6\xB4 + \xF0\x91\xA6\xB5 + \xF0\x91\xA6\xB6 + \xF0\x91\xA6\xB7 + \xF0\x91\xA6\xB8 + \xF0\x91\xA6\xB9 + \xF0\x91\xA6\xBA + \xF0\x91\xA6\xBB + \xF0\x91\xA6\xBC + \xF0\x91\xA6\xBD + \xF0\x91\xA6\xBE + \xF0\x91\xA6\xBF + \xF0\x91\xA7\x80 + \xF0\x91\xA7\x81 + \xF0\x91\xA7\x82 + \xF0\x91\xA7\x83 + \xF0\x91\xA7\x84 + \xF0\x91\xA7\x85 + \xF0\x91\xA7\x86 + \xF0\x91\xA7\x87 + \xF0\x91\xA7\x88 + \xF0\x91\xA7\x89 + \xF0\x91\xA7\x8A + \xF0\x91\xA7\x8B + \xF0\x91\xA7\x8C + \xF0\x91\xA7\x8D + \xF0\x91\xA7\x8E + \xF0\x91\xA7\x8F + \xF0\x91\xA7\x90 + \xF0\x91\xA7\x91 + \xF0\x91\xA7\x92 + \xF0\x91\xA7\x93 + \xF0\x91\xA7\x94 + \xF0\x91\xA7\x95 + \xF0\x91\xA7\x96 + \xF0\x91\xA7\x97 + \xF0\x91\xA7\x9A + \xF0\x91\xA7\x9B + \xF0\x91\xA7\x9C + \xF0\x91\xA7\x9D + \xF0\x91\xA7\x9E + \xF0\x91\xA7\x9F + \xF0\x91\xA7\xA0 + \xF0\x91\xA7\xA1 + \xF0\x91\xA7\xA2 + \xF0\x91\xA7\xA3 + \xF0\x91\xA7\xA4 \xF0\x91\xA8\x80 \xF0\x91\xA8\x81 \xF0\x91\xA8\x82 @@ -65821,6 +65944,8 @@ CHARMAP \xF0\x91\xAA\x81 \xF0\x91\xAA\x82 \xF0\x91\xAA\x83 + \xF0\x91\xAA\x84 + \xF0\x91\xAA\x85 \xF0\x91\xAA\x86 \xF0\x91\xAA\x87 \xF0\x91\xAA\x88 @@ -66235,6 +66360,57 @@ CHARMAP \xF0\x91\xBB\xB6 \xF0\x91\xBB\xB7 \xF0\x91\xBB\xB8 + \xF0\x91\xBF\x80 + \xF0\x91\xBF\x81 + \xF0\x91\xBF\x82 + \xF0\x91\xBF\x83 + \xF0\x91\xBF\x84 + \xF0\x91\xBF\x85 + \xF0\x91\xBF\x86 + \xF0\x91\xBF\x87 + \xF0\x91\xBF\x88 + \xF0\x91\xBF\x89 + \xF0\x91\xBF\x8A + \xF0\x91\xBF\x8B + \xF0\x91\xBF\x8C + \xF0\x91\xBF\x8D + \xF0\x91\xBF\x8E + \xF0\x91\xBF\x8F + \xF0\x91\xBF\x90 + \xF0\x91\xBF\x91 + \xF0\x91\xBF\x92 + \xF0\x91\xBF\x93 + \xF0\x91\xBF\x94 + \xF0\x91\xBF\x95 + \xF0\x91\xBF\x96 + \xF0\x91\xBF\x97 + \xF0\x91\xBF\x98 + \xF0\x91\xBF\x99 + \xF0\x91\xBF\x9A + \xF0\x91\xBF\x9B + \xF0\x91\xBF\x9C + \xF0\x91\xBF\x9D + \xF0\x91\xBF\x9E + \xF0\x91\xBF\x9F + \xF0\x91\xBF\xA0 + \xF0\x91\xBF\xA1 + \xF0\x91\xBF\xA2 + \xF0\x91\xBF\xA3 + \xF0\x91\xBF\xA4 + \xF0\x91\xBF\xA5 + \xF0\x91\xBF\xA6 + \xF0\x91\xBF\xA7 + \xF0\x91\xBF\xA8 + \xF0\x91\xBF\xA9 + \xF0\x91\xBF\xAA + \xF0\x91\xBF\xAB + \xF0\x91\xBF\xAC + \xF0\x91\xBF\xAD + \xF0\x91\xBF\xAE + \xF0\x91\xBF\xAF + \xF0\x91\xBF\xB0 + \xF0\x91\xBF\xB1 + \xF0\x91\xBF\xBF \xF0\x92\x80\x80 \xF0\x92\x80\x81 \xF0\x92\x80\x82 @@ -68540,6 +68716,15 @@ CHARMAP \xF0\x93\x90\xAC \xF0\x93\x90\xAD \xF0\x93\x90\xAE + \xF0\x93\x90\xB0 + \xF0\x93\x90\xB1 + \xF0\x93\x90\xB2 + \xF0\x93\x90\xB3 + \xF0\x93\x90\xB4 + \xF0\x93\x90\xB5 + \xF0\x93\x90\xB6 + \xF0\x93\x90\xB7 + \xF0\x93\x90\xB8 \xF0\x94\x90\x80 \xF0\x94\x90\x81 \xF0\x94\x90\x82 @@ -70058,6 +70243,13 @@ CHARMAP \xF0\x96\xBD\x82 \xF0\x96\xBD\x83 \xF0\x96\xBD\x84 + \xF0\x96\xBD\x85 + \xF0\x96\xBD\x86 + \xF0\x96\xBD\x87 + \xF0\x96\xBD\x88 + \xF0\x96\xBD\x89 + \xF0\x96\xBD\x8A + \xF0\x96\xBD\x8F \xF0\x96\xBD\x90 \xF0\x96\xBD\x91 \xF0\x96\xBD\x92 @@ -70105,6 +70297,15 @@ CHARMAP \xF0\x96\xBD\xBC \xF0\x96\xBD\xBD \xF0\x96\xBD\xBE + \xF0\x96\xBD\xBF + \xF0\x96\xBE\x80 + \xF0\x96\xBE\x81 + \xF0\x96\xBE\x82 + \xF0\x96\xBE\x83 + \xF0\x96\xBE\x84 + \xF0\x96\xBE\x85 + \xF0\x96\xBE\x86 + \xF0\x96\xBE\x87 \xF0\x96\xBE\x8F \xF0\x96\xBE\x90 \xF0\x96\xBE\x91 @@ -70124,6 +70325,8 @@ CHARMAP \xF0\x96\xBE\x9F \xF0\x96\xBF\xA0 \xF0\x96\xBF\xA1 + \xF0\x96\xBF\xA2 + \xF0\x96\xBF\xA3 \xF0\x97\x80\x80 \xF0\x97\x80\x81 \xF0\x97\x80\x82 @@ -76254,6 +76457,12 @@ CHARMAP \xF0\x98\x9F\xAF \xF0\x98\x9F\xB0 \xF0\x98\x9F\xB1 + \xF0\x98\x9F\xB2 + \xF0\x98\x9F\xB3 + \xF0\x98\x9F\xB4 + \xF0\x98\x9F\xB5 + \xF0\x98\x9F\xB6 + \xF0\x98\x9F\xB7 \xF0\x98\xA0\x80 \xF0\x98\xA0\x81 \xF0\x98\xA0\x82 @@ -77296,6 +77505,13 @@ CHARMAP \xF0\x9B\x84\x9C \xF0\x9B\x84\x9D \xF0\x9B\x84\x9E + \xF0\x9B\x85\x90 + \xF0\x9B\x85\x91 + \xF0\x9B\x85\x92 + \xF0\x9B\x85\xA4 + \xF0\x9B\x85\xA5 + \xF0\x9B\x85\xA6 + \xF0\x9B\x85\xA7 \xF0\x9B\x85\xB0 \xF0\x9B\x85\xB1 \xF0\x9B\x85\xB2 @@ -80224,6 +80440,136 @@ CHARMAP \xF0\x9E\x80\xA8 \xF0\x9E\x80\xA9 \xF0\x9E\x80\xAA + \xF0\x9E\x84\x80 + \xF0\x9E\x84\x81 + \xF0\x9E\x84\x82 + \xF0\x9E\x84\x83 + \xF0\x9E\x84\x84 + \xF0\x9E\x84\x85 + \xF0\x9E\x84\x86 + \xF0\x9E\x84\x87 + \xF0\x9E\x84\x88 + \xF0\x9E\x84\x89 + \xF0\x9E\x84\x8A + \xF0\x9E\x84\x8B + \xF0\x9E\x84\x8C + \xF0\x9E\x84\x8D + \xF0\x9E\x84\x8E + \xF0\x9E\x84\x8F + \xF0\x9E\x84\x90 + \xF0\x9E\x84\x91 + \xF0\x9E\x84\x92 + \xF0\x9E\x84\x93 + \xF0\x9E\x84\x94 + \xF0\x9E\x84\x95 + \xF0\x9E\x84\x96 + \xF0\x9E\x84\x97 + \xF0\x9E\x84\x98 + \xF0\x9E\x84\x99 + \xF0\x9E\x84\x9A + \xF0\x9E\x84\x9B + \xF0\x9E\x84\x9C + \xF0\x9E\x84\x9D + \xF0\x9E\x84\x9E + \xF0\x9E\x84\x9F + \xF0\x9E\x84\xA0 + \xF0\x9E\x84\xA1 + \xF0\x9E\x84\xA2 + \xF0\x9E\x84\xA3 + \xF0\x9E\x84\xA4 + \xF0\x9E\x84\xA5 + \xF0\x9E\x84\xA6 + \xF0\x9E\x84\xA7 + \xF0\x9E\x84\xA8 + \xF0\x9E\x84\xA9 + \xF0\x9E\x84\xAA + \xF0\x9E\x84\xAB + \xF0\x9E\x84\xAC + \xF0\x9E\x84\xB0 + \xF0\x9E\x84\xB1 + \xF0\x9E\x84\xB2 + \xF0\x9E\x84\xB3 + \xF0\x9E\x84\xB4 + \xF0\x9E\x84\xB5 + \xF0\x9E\x84\xB6 + \xF0\x9E\x84\xB7 + \xF0\x9E\x84\xB8 + \xF0\x9E\x84\xB9 + \xF0\x9E\x84\xBA + \xF0\x9E\x84\xBB + \xF0\x9E\x84\xBC + \xF0\x9E\x84\xBD + \xF0\x9E\x85\x80 + \xF0\x9E\x85\x81 + \xF0\x9E\x85\x82 + \xF0\x9E\x85\x83 + \xF0\x9E\x85\x84 + \xF0\x9E\x85\x85 + \xF0\x9E\x85\x86 + \xF0\x9E\x85\x87 + \xF0\x9E\x85\x88 + \xF0\x9E\x85\x89 + \xF0\x9E\x85\x8E + \xF0\x9E\x85\x8F + \xF0\x9E\x8B\x80 + \xF0\x9E\x8B\x81 + \xF0\x9E\x8B\x82 + \xF0\x9E\x8B\x83 + \xF0\x9E\x8B\x84 + \xF0\x9E\x8B\x85 + \xF0\x9E\x8B\x86 + \xF0\x9E\x8B\x87 + \xF0\x9E\x8B\x88 + \xF0\x9E\x8B\x89 + \xF0\x9E\x8B\x8A + \xF0\x9E\x8B\x8B + \xF0\x9E\x8B\x8C + \xF0\x9E\x8B\x8D + \xF0\x9E\x8B\x8E + \xF0\x9E\x8B\x8F + \xF0\x9E\x8B\x90 + \xF0\x9E\x8B\x91 + \xF0\x9E\x8B\x92 + \xF0\x9E\x8B\x93 + \xF0\x9E\x8B\x94 + \xF0\x9E\x8B\x95 + \xF0\x9E\x8B\x96 + \xF0\x9E\x8B\x97 + \xF0\x9E\x8B\x98 + \xF0\x9E\x8B\x99 + \xF0\x9E\x8B\x9A + \xF0\x9E\x8B\x9B + \xF0\x9E\x8B\x9C + \xF0\x9E\x8B\x9D + \xF0\x9E\x8B\x9E + \xF0\x9E\x8B\x9F + \xF0\x9E\x8B\xA0 + \xF0\x9E\x8B\xA1 + \xF0\x9E\x8B\xA2 + \xF0\x9E\x8B\xA3 + \xF0\x9E\x8B\xA4 + \xF0\x9E\x8B\xA5 + \xF0\x9E\x8B\xA6 + \xF0\x9E\x8B\xA7 + \xF0\x9E\x8B\xA8 + \xF0\x9E\x8B\xA9 + \xF0\x9E\x8B\xAA + \xF0\x9E\x8B\xAB + \xF0\x9E\x8B\xAC + \xF0\x9E\x8B\xAD + \xF0\x9E\x8B\xAE + \xF0\x9E\x8B\xAF + \xF0\x9E\x8B\xB0 + \xF0\x9E\x8B\xB1 + \xF0\x9E\x8B\xB2 + \xF0\x9E\x8B\xB3 + \xF0\x9E\x8B\xB4 + \xF0\x9E\x8B\xB5 + \xF0\x9E\x8B\xB6 + \xF0\x9E\x8B\xB7 + \xF0\x9E\x8B\xB8 + \xF0\x9E\x8B\xB9 + \xF0\x9E\x8B\xBF \xF0\x9E\xA0\x80 \xF0\x9E\xA0\x81 \xF0\x9E\xA0\x82 @@ -80512,6 +80858,7 @@ CHARMAP \xF0\x9E\xA5\x88 \xF0\x9E\xA5\x89 \xF0\x9E\xA5\x8A + \xF0\x9E\xA5\x8B \xF0\x9E\xA5\x90 \xF0\x9E\xA5\x91 \xF0\x9E\xA5\x92 @@ -80592,6 +80939,67 @@ CHARMAP \xF0\x9E\xB2\xB2 \xF0\x9E\xB2\xB3 \xF0\x9E\xB2\xB4 + \xF0\x9E\xB4\x81 + \xF0\x9E\xB4\x82 + \xF0\x9E\xB4\x83 + \xF0\x9E\xB4\x84 + \xF0\x9E\xB4\x85 + \xF0\x9E\xB4\x86 + \xF0\x9E\xB4\x87 + \xF0\x9E\xB4\x88 + \xF0\x9E\xB4\x89 + \xF0\x9E\xB4\x8A + \xF0\x9E\xB4\x8B + \xF0\x9E\xB4\x8C + \xF0\x9E\xB4\x8D + \xF0\x9E\xB4\x8E + \xF0\x9E\xB4\x8F + \xF0\x9E\xB4\x90 + \xF0\x9E\xB4\x91 + \xF0\x9E\xB4\x92 + \xF0\x9E\xB4\x93 + \xF0\x9E\xB4\x94 + \xF0\x9E\xB4\x95 + \xF0\x9E\xB4\x96 + \xF0\x9E\xB4\x97 + \xF0\x9E\xB4\x98 + \xF0\x9E\xB4\x99 + \xF0\x9E\xB4\x9A + \xF0\x9E\xB4\x9B + \xF0\x9E\xB4\x9C + \xF0\x9E\xB4\x9D + \xF0\x9E\xB4\x9E + \xF0\x9E\xB4\x9F + \xF0\x9E\xB4\xA0 + \xF0\x9E\xB4\xA1 + \xF0\x9E\xB4\xA2 + \xF0\x9E\xB4\xA3 + \xF0\x9E\xB4\xA4 + \xF0\x9E\xB4\xA5 + \xF0\x9E\xB4\xA6 + \xF0\x9E\xB4\xA7 + \xF0\x9E\xB4\xA8 + \xF0\x9E\xB4\xA9 + \xF0\x9E\xB4\xAA + \xF0\x9E\xB4\xAB + \xF0\x9E\xB4\xAC + \xF0\x9E\xB4\xAD + \xF0\x9E\xB4\xAE + \xF0\x9E\xB4\xAF + \xF0\x9E\xB4\xB0 + \xF0\x9E\xB4\xB1 + \xF0\x9E\xB4\xB2 + \xF0\x9E\xB4\xB3 + \xF0\x9E\xB4\xB4 + \xF0\x9E\xB4\xB5 + \xF0\x9E\xB4\xB6 + \xF0\x9E\xB4\xB7 + \xF0\x9E\xB4\xB8 + \xF0\x9E\xB4\xB9 + \xF0\x9E\xB4\xBA + \xF0\x9E\xB4\xBB + \xF0\x9E\xB4\xBC + \xF0\x9E\xB4\xBD \xF0\x9E\xB8\x80 \xF0\x9E\xB8\x81 \xF0\x9E\xB8\x82 @@ -81066,6 +81474,7 @@ CHARMAP \xF0\x9F\x85\xA9 \xF0\x9F\x85\xAA \xF0\x9F\x85\xAB + \xF0\x9F\x85\xAC \xF0\x9F\x85\xB0 \xF0\x9F\x85\xB1 \xF0\x9F\x85\xB2 @@ -82198,6 +82607,7 @@ CHARMAP \xF0\x9F\x9B\x92 \xF0\x9F\x9B\x93 \xF0\x9F\x9B\x94 + \xF0\x9F\x9B\x95 \xF0\x9F\x9B\xA0 \xF0\x9F\x9B\xA1 \xF0\x9F\x9B\xA2 @@ -82221,6 +82631,7 @@ CHARMAP \xF0\x9F\x9B\xB7 \xF0\x9F\x9B\xB8 \xF0\x9F\x9B\xB9 + \xF0\x9F\x9B\xBA \xF0\x9F\x9C\x80 \xF0\x9F\x9C\x81 \xF0\x9F\x9C\x82 @@ -82426,6 +82837,18 @@ CHARMAP \xF0\x9F\x9F\x96 \xF0\x9F\x9F\x97 \xF0\x9F\x9F\x98 + \xF0\x9F\x9F\xA0 + \xF0\x9F\x9F\xA1 + \xF0\x9F\x9F\xA2 + \xF0\x9F\x9F\xA3 + \xF0\x9F\x9F\xA4 + \xF0\x9F\x9F\xA5 + \xF0\x9F\x9F\xA6 + \xF0\x9F\x9F\xA7 + \xF0\x9F\x9F\xA8 + \xF0\x9F\x9F\xA9 + \xF0\x9F\x9F\xAA + \xF0\x9F\x9F\xAB \xF0\x9F\xA0\x80 \xF0\x9F\xA0\x81 \xF0\x9F\xA0\x82 @@ -82586,6 +83009,9 @@ CHARMAP \xF0\x9F\xA4\x89 \xF0\x9F\xA4\x8A \xF0\x9F\xA4\x8B + \xF0\x9F\xA4\x8D + \xF0\x9F\xA4\x8E + \xF0\x9F\xA4\x8F \xF0\x9F\xA4\x90 \xF0\x9F\xA4\x91 \xF0\x9F\xA4\x92 @@ -82633,6 +83059,7 @@ CHARMAP \xF0\x9F\xA4\xBC \xF0\x9F\xA4\xBD \xF0\x9F\xA4\xBE + \xF0\x9F\xA4\xBF \xF0\x9F\xA5\x80 \xF0\x9F\xA5\x81 \xF0\x9F\xA5\x82 @@ -82682,11 +83109,13 @@ CHARMAP \xF0\x9F\xA5\xAE \xF0\x9F\xA5\xAF \xF0\x9F\xA5\xB0 + \xF0\x9F\xA5\xB1 \xF0\x9F\xA5\xB3 \xF0\x9F\xA5\xB4 \xF0\x9F\xA5\xB5 \xF0\x9F\xA5\xB6 \xF0\x9F\xA5\xBA + \xF0\x9F\xA5\xBB \xF0\x9F\xA5\xBC \xF0\x9F\xA5\xBD \xF0\x9F\xA5\xBE @@ -82726,6 +83155,14 @@ CHARMAP \xF0\x9F\xA6\xA0 \xF0\x9F\xA6\xA1 \xF0\x9F\xA6\xA2 + \xF0\x9F\xA6\xA5 + \xF0\x9F\xA6\xA6 + \xF0\x9F\xA6\xA7 + \xF0\x9F\xA6\xA8 + \xF0\x9F\xA6\xA9 + \xF0\x9F\xA6\xAA + \xF0\x9F\xA6\xAE + \xF0\x9F\xA6\xAF \xF0\x9F\xA6\xB0 \xF0\x9F\xA6\xB1 \xF0\x9F\xA6\xB2 @@ -82736,9 +83173,26 @@ CHARMAP \xF0\x9F\xA6\xB7 \xF0\x9F\xA6\xB8 \xF0\x9F\xA6\xB9 + \xF0\x9F\xA6\xBA + \xF0\x9F\xA6\xBB + \xF0\x9F\xA6\xBC + \xF0\x9F\xA6\xBD + \xF0\x9F\xA6\xBE + \xF0\x9F\xA6\xBF \xF0\x9F\xA7\x80 \xF0\x9F\xA7\x81 \xF0\x9F\xA7\x82 + \xF0\x9F\xA7\x83 + \xF0\x9F\xA7\x84 + \xF0\x9F\xA7\x85 + \xF0\x9F\xA7\x86 + \xF0\x9F\xA7\x87 + \xF0\x9F\xA7\x88 + \xF0\x9F\xA7\x89 + \xF0\x9F\xA7\x8A + \xF0\x9F\xA7\x8D + \xF0\x9F\xA7\x8E + \xF0\x9F\xA7\x8F \xF0\x9F\xA7\x90 \xF0\x9F\xA7\x91 \xF0\x9F\xA7\x92 @@ -82787,6 +83241,90 @@ CHARMAP \xF0\x9F\xA7\xBD \xF0\x9F\xA7\xBE \xF0\x9F\xA7\xBF + \xF0\x9F\xA8\x80 + \xF0\x9F\xA8\x81 + \xF0\x9F\xA8\x82 + \xF0\x9F\xA8\x83 + \xF0\x9F\xA8\x84 + \xF0\x9F\xA8\x85 + \xF0\x9F\xA8\x86 + \xF0\x9F\xA8\x87 + \xF0\x9F\xA8\x88 + \xF0\x9F\xA8\x89 + \xF0\x9F\xA8\x8A + \xF0\x9F\xA8\x8B + \xF0\x9F\xA8\x8C + \xF0\x9F\xA8\x8D + \xF0\x9F\xA8\x8E + \xF0\x9F\xA8\x8F + \xF0\x9F\xA8\x90 + \xF0\x9F\xA8\x91 + \xF0\x9F\xA8\x92 + \xF0\x9F\xA8\x93 + \xF0\x9F\xA8\x94 + \xF0\x9F\xA8\x95 + \xF0\x9F\xA8\x96 + \xF0\x9F\xA8\x97 + \xF0\x9F\xA8\x98 + \xF0\x9F\xA8\x99 + \xF0\x9F\xA8\x9A + \xF0\x9F\xA8\x9B + \xF0\x9F\xA8\x9C + \xF0\x9F\xA8\x9D + \xF0\x9F\xA8\x9E + \xF0\x9F\xA8\x9F + \xF0\x9F\xA8\xA0 + \xF0\x9F\xA8\xA1 + \xF0\x9F\xA8\xA2 + \xF0\x9F\xA8\xA3 + \xF0\x9F\xA8\xA4 + \xF0\x9F\xA8\xA5 + \xF0\x9F\xA8\xA6 + \xF0\x9F\xA8\xA7 + \xF0\x9F\xA8\xA8 + \xF0\x9F\xA8\xA9 + \xF0\x9F\xA8\xAA + \xF0\x9F\xA8\xAB + \xF0\x9F\xA8\xAC + \xF0\x9F\xA8\xAD + \xF0\x9F\xA8\xAE + \xF0\x9F\xA8\xAF + \xF0\x9F\xA8\xB0 + \xF0\x9F\xA8\xB1 + \xF0\x9F\xA8\xB2 + \xF0\x9F\xA8\xB3 + \xF0\x9F\xA8\xB4 + \xF0\x9F\xA8\xB5 + \xF0\x9F\xA8\xB6 + \xF0\x9F\xA8\xB7 + \xF0\x9F\xA8\xB8 + \xF0\x9F\xA8\xB9 + \xF0\x9F\xA8\xBA + \xF0\x9F\xA8\xBB + \xF0\x9F\xA8\xBC + \xF0\x9F\xA8\xBD + \xF0\x9F\xA8\xBE + \xF0\x9F\xA8\xBF + \xF0\x9F\xA9\x80 + \xF0\x9F\xA9\x81 + \xF0\x9F\xA9\x82 + \xF0\x9F\xA9\x83 + \xF0\x9F\xA9\x84 + \xF0\x9F\xA9\x85 + \xF0\x9F\xA9\x86 + \xF0\x9F\xA9\x87 + \xF0\x9F\xA9\x88 + \xF0\x9F\xA9\x89 + \xF0\x9F\xA9\x8A + \xF0\x9F\xA9\x8B + \xF0\x9F\xA9\x8C + \xF0\x9F\xA9\x8D + \xF0\x9F\xA9\x8E + \xF0\x9F\xA9\x8F + \xF0\x9F\xA9\x90 + \xF0\x9F\xA9\x91 + \xF0\x9F\xA9\x92 + \xF0\x9F\xA9\x93 \xF0\x9F\xA9\xA0 \xF0\x9F\xA9\xA1 \xF0\x9F\xA9\xA2 @@ -82801,6 +83339,22 @@ CHARMAP \xF0\x9F\xA9\xAB \xF0\x9F\xA9\xAC \xF0\x9F\xA9\xAD + \xF0\x9F\xA9\xB0 + \xF0\x9F\xA9\xB1 + \xF0\x9F\xA9\xB2 + \xF0\x9F\xA9\xB3 + \xF0\x9F\xA9\xB8 + \xF0\x9F\xA9\xB9 + \xF0\x9F\xA9\xBA + \xF0\x9F\xAA\x80 + \xF0\x9F\xAA\x81 + \xF0\x9F\xAA\x82 + \xF0\x9F\xAA\x90 + \xF0\x9F\xAA\x91 + \xF0\x9F\xAA\x92 + \xF0\x9F\xAA\x93 + \xF0\x9F\xAA\x94 + \xF0\x9F\xAA\x95 \xF0\xA0\x80\x80 \xF0\xA0\x80\x81 \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 000000000000..fe65ebacd16a --- /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; 0033 0031 65E5;;;;N;;;;; + 33FF;SQUARE GAL;So;0;ON; 0067 0061 006C;;;;N;;;;; + 3400;;Lo;0;L;;;;;N;;;;; +-4DBF;;Lo;0;L;;;;;N;;;;; ++4DB5;;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;;Lo;0;L;;;;;N;;;;; +-9FFC;;Lo;0;L;;;;;N;;;;; ++9FEF;;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; 0038;8;8;8;N;;;;; + 1FBF9;SEGMENTED DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; + 20000;;Lo;0;L;;;;;N;;;;; +-2A6DD;;Lo;0;L;;;;;N;;;;; ++2A6D6;;Lo;0;L;;;;;N;;;;; + 2A700;;Lo;0;L;;;;;N;;;;; + 2B734;;Lo;0;L;;;;;N;;;;; + 2B740;;Lo;0;L;;;;;N;;;;; diff --git a/tools/tools/locale/tools/cldr2def.pl b/tools/tools/locale/tools/cldr2def.pl index 3a6f8ac79d18..5f756cc3895a 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 88222531d064..8b54ff33381b 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 () { 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 f4dfd7d0892f..88dfcad0cb24 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 da93d2f4398a..b275828d52c9 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=\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 af408d6dff1d..724fb4a2372e 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 ce28e274fd55..f6cda6cd3900 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 8d22ea4251e7..149458baa331 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) - err(1, "openpty"); - } else { + 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, &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 ad91f7d38106..996575bb622e 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 dc0510e24e6a..5a3200ed7fac 100644 --- a/usr.sbin/crunch/crunchgen/crunchgen.c +++ b/usr.sbin/crunch/crunchgen/crunchgen.c @@ -39,10 +39,13 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include +#include #include #include #include +#include #include #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 a3b595881e21..bc196e2c0fd0 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