Merge ^/head r364082 through r364250.

This commit is contained in:
Dimitry Andric 2020-08-15 11:49:31 +00:00
commit de6fc2e39b
175 changed files with 3872 additions and 1830 deletions

View File

@ -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

View File

@ -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

View File

@ -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'

View File

@ -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 <dt_errtags.h>
\n\
static const char *const _dt_errtags[] = {"
static const char *const _dt_errtags[] = {
"
pattern='^ \(D_[A-Z0-9_]*\),*'
replace=' "\1",'
sed -n "s/$pattern/$replace/p" || exit 1
echo ${BSDECHO} "\
};\n\
\n\
static const int _dt_ntag = sizeof (_dt_errtags) / sizeof (_dt_errtags[0]);\n\
\n\
printf "%s" "
};
static const int _dt_ntag = sizeof (_dt_errtags) / sizeof (_dt_errtags[0]);
const char *
dt_errtag(dt_errtag_t tag)
{
return (_dt_errtags[(tag > 0 && tag < _dt_ntag) ? tag : 0]);
}"
}
"
exit 0

View File

@ -24,32 +24,30 @@
# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
set -e
BSDECHO=-e
printf "%s" "
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <dtrace.h>
echo ${BSDECHO} "\
/*\n\
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.\n\
* Use is subject to license terms.\n\
*/\n\
\n\
#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n\
\n\
#include <dtrace.h>\n\
\n\
/*ARGSUSED*/
const char *\n\
dtrace_subrstr(dtrace_hdl_t *dtp, int subr)\n\
{\n\
switch (subr) {"
const char *
dtrace_subrstr(dtrace_hdl_t *dtp, int subr)
{
switch (subr) {
"
nawk '
/^#define[ ]*DIF_SUBR_/ && $2 != "DIF_SUBR_MAX" {
printf("\tcase %s: return (\"%s\");\n", $2, tolower(substr($2, 10)));
}'
echo ${BSDECHO} "\
default: return (\"unknown\");\n\
}\n\
}"
printf "%s" "
default: return (\"unknown\");
}
}
"

View File

@ -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'

View File

@ -68,6 +68,8 @@
..
engines
..
flua
..
i18n
..
libxo
@ -370,6 +372,8 @@
..
firmware
..
flua
..
games
fortune
..

View File

@ -1,5 +1,6 @@
# $FreeBSD$
SUBDIR= libbsnmp
SUBDIR.${MK_TESTS}+= tests
.include <bsd.subdir.mk>

View File

@ -0,0 +1,11 @@
# $FreeBSD$
.include <bsd.own.mk>
ATF_TESTS_C+= bsnmpd_test
SRCS.bsmpd_test= bsnmpd_test.c
LIBADD+= bsnmp
.include <bsd.test.mk>

View File

@ -0,0 +1,53 @@
/*-
* Copyright (c) 2020 Dell EMC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <bsnmp/asn1.h>
#include <atf-c.h>
ATF_TC_WITHOUT_HEAD(sa_19_20_bsnmp_test);
ATF_TC_BODY(sa_19_20_bsnmp_test, tc)
{
struct asn_buf b = {};
char test_buf[] = { 0x25, 0x7f };
enum asn_err err;
asn_len_t len;
u_char type;
b.asn_cptr = test_buf;
b.asn_len = sizeof(test_buf);
err = asn_get_header(&b, &type, &len);
ATF_CHECK_EQ(ASN_ERR_EOBUF, err);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, sa_19_20_bsnmp_test);
return (atf_no_error());
}

View File

@ -120,6 +120,7 @@ SRCS+= __getosreldate.c \
recvmmsg.c \
rewinddir.c \
scandir.c \
scandir_b.c \
scandir-compat11.c \
seed48.c \
seekdir.c \

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -29,6 +29,8 @@ CFLAGS+= -DLUA_PROGNAME="\"${PROG}\""
.if defined(BOOTSTRAPPING)
CFLAGS+= -DLUA_PATH_DEFAULT="\"/nonexistent/?.lua\""
CFLAGS+= -DLUA_CPATH_DEFAULT="\"/nonexistent/?.so\""
# We don't support dynamic libs on bootstrap builds.
CFLAGS+= -DBOOTSTRAPPING
.endif
.include <bsd.lib.mk>

View File

@ -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;" \

View File

@ -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;
}

View File

@ -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

View File

@ -5,6 +5,7 @@
# PROVIDE: ipfilter
# REQUIRE: FILESYSTEMS
# BEFORE: ipmon ipnat netif netwait securelevel
# KEYWORD: nojailvnet
. /etc/rc.subr

View File

@ -4,7 +4,7 @@
#
# PROVIDE: ipmon
# REQUIRE: FILESYSTEMS hostname sysctl ipfilter
# REQUIRE: FILESYSTEMS hostname sysctl
# BEFORE: SERVERS
# KEYWORD: nojailvnet

View File

@ -4,7 +4,6 @@
#
# PROVIDE: ipnat
# REQUIRE: ipfilter
# KEYWORD: nojailvnet
. /etc/rc.subr

View File

@ -27,7 +27,7 @@
# PROVIDE: netif
# REQUIRE: FILESYSTEMS iovctl serial sppp sysctl
# REQUIRE: hostid ipfilter ipfs
# REQUIRE: hostid ipfs
# KEYWORD: nojailvnet
. /etc/rc.subr

View File

@ -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:

View File

@ -4,7 +4,7 @@
#
# PROVIDE: securelevel
# REQUIRE: adjkerntz ipfw ipfilter pf
# REQUIRE: adjkerntz ipfw pf
. /etc/rc.subr

View File

@ -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 ]

View File

@ -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 ]

View File

@ -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 ]

View File

@ -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 ]

View File

@ -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
}

View File

@ -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 ]

View File

@ -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"

View File

@ -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 ]

View File

@ -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 ]

View File

@ -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 ]

View File

@ -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"

View File

@ -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 ]

View File

@ -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 ]

View File

@ -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 ]

View File

@ -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 ]

View File

@ -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"

View File

@ -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);

View File

@ -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 .

View File

@ -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:

View File

@ -31,7 +31,7 @@ CFLAGS+= -I${.OBJDIR:H}/libcrypto
.include <bsd.lib.mk>
PICFLAG+= -DOPENSS_PIC
PICFLAG+= -DOPENSSL_PIC
.PATH: ${LCRYPTO_SRC}/ssl \
${LCRYPTO_SRC}/ssl/record \

View File

@ -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 \

87
share/man/man4/cp2112.4 Normal file
View File

@ -0,0 +1,87 @@
.\"
.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD
.\"
.\" Copyright (c) 2020 Andriy Gapon <avg@FreeBSD.org>
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd August 12, 2020
.Dt CP2112 4
.Os
.Sh NAME
.Nm cp2112
.Nd driver for a USB GPIO and I2C peripheral device
.Sh SYNOPSIS
To compile this driver into the kernel,
place the following lines in your
kernel configuration file:
.Bd -ragged -offset indent
.Cd "device cp2112"
.Cd "device usb"
.Cd "device gpio"
.Cd "device iicbus"
.Ed
.Pp
Alternatively, to load the driver as a
module at boot time, place the following line in
.Xr loader.conf 5 :
.Bd -literal -offset indent
cp2112_load="YES"
.Ed
.Sh DESCRIPTION
The
.Nm
driver provides support for Silicon Labs CP2112 device.
The device has 8 general purpose I/O pins and an I2C controller that supports
a subset of the I2C protocol.
.Pp
All pins support both input and output modes.
An output pin can be configured either for open-drain or push-pull operation.
Pins 0, 1 and 7 support special functions: I2C transmit indication,
I2C receive indication and clock output respectively.
At the moment the
.Nm
driver does not provide a way to enable and configure the special functions.
.Pp
The I2C controller supports read transactions with up to 512 bytes of data,
write transactions with up to 61 bytes of data and a write followed by
the repeated start followed by a read transactions where the write can be
up to 16 bytes and the read can be up to 512 bytes.
Zero length transfers are not supported.
The
.Nm
driver creates a
.Xr gpio 4
and
.Xr iicbus 4
child buses to expose the respective functions.
.Sh SEE ALSO
.Xr gpio 4 ,
.Xr iicbus 4 ,
.Xr usb 4
.Sh HISTORY
The
.Nm
driver and this manual page was written by
.An Andriy Gapon Aq Mt avg@FreeBSD.org .

View File

@ -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 \

99
share/man/man9/prng.9 Normal file
View File

@ -0,0 +1,99 @@
.\"-
.\" Copyright 2020 Conrad Meyer <cem@FreeBSD.org>. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd August 5, 2020
.Dt PRNG 9
.Os
.Sh NAME
.Nm prng
.Nd "Kernel pseudo-random number generators"
.Sh SYNOPSIS
.In sys/prng.h
.Ft uint32_t
.Fn prng32 void
.Ft uint32_t
.Fn prng32_bounded "uint32_t bound"
.Ft uint64_t
.Fn prng64 void
.Ft uint64_t
.Fn prng64_bounded "uint64_t bound"
.Sh DESCRIPTION
.Ss GENERIC PRNG ROUTINES
.Nm
is a family of fast,
.Em non-cryptographic
pseudo-random number generators.
Unlike
.Xr random 9 ,
.Fn prng32 ,
.Fn prng32_bounded ,
.Fn prng64 ,
and
.Fn prng64_bounded
avoid shared global state, removing unnecessary contention on SMP
systems.
The routines are not explicitly tied to any specific implementation, and
may produce different specific sequences on different hosts, reboots, or
versions of
.Fx .
Different CPUs in SMP systems are guaranteed to produce different sequences of
integers.
.Pp
For
.Em cryptographically secure
random numbers generated by the
.Xr random 4
kernel cryptographically secure random number generator subsystem, see
.Xr arc4random 9 .
.Pp
.Bl -tag -width indent
.It Fn prng32
Generate a 32-bit integer uniformly distributed in [0, 2^32-1].
.It Fn prng32_bounded bound
Generate an integer uniformly in the range [0, bound-1].
.It Fn prng64
Generate a 64-bit integer uniformly distributed in [0, 2^64-1].
.It Fn prng64_bounded bound
Generate an integer uniformly in the range [0, bound-1].
.El
.Pp
These routines are not reentrant; they are not safe to use in interrupt
handlers ("interrupt filters" in
.Xr bus_setup_intr 9
terminology).
They are safe to use in all other kernel contexts, including interrupt threads
("ithreads").
.Ss REPRODUCIBLE PRNG APIS
In addition to these per-CPU helpers, the
.In sys/prng.h
header also exposes the entire API of the PCG family of PRNGs as inline
functions.
The PCG-C API is described in full at
.Lk https://www.pcg-random.org/using-pcg-c.html .
.Sh HISTORY
.Nm
was introduced in
.Fx 13 .

View File

@ -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

View File

@ -365,6 +365,14 @@ __DEFAULT_YES_OPTIONS+=OPENMP
__DEFAULT_NO_OPTIONS+=OPENMP
.endif
.if ${.MAKE.OS} != "FreeBSD"
# Building the target compiler requires building tablegen on the host
# which is (currently) not possible on non-FreeBSD.
BROKEN_OPTIONS+=CLANG LLD LLDB
# The same also applies to the bootstrap LLVM.
BROKEN_OPTIONS+=CLANG_BOOTSTRAP LLD_BOOTSTRAP
.endif
.include <bsd.mkopt.mk>
#

View File

@ -275,6 +275,7 @@ SHELL ?= sh
.if !defined(%POSIX)
SIZE ?= size
STRIPBIN ?= strip
.endif
YACC ?= yacc

View File

@ -55,6 +55,8 @@ if [ -n "${include_metadata}" ]; then
bootprog_info="$bootprog_info(${t} ${u}@${h})\\n"
fi
echo "char bootprog_info[] = \"$bootprog_info\";" > $tempfile
echo "unsigned bootprog_rev = ${r%%.*}${r##*.};" >> $tempfile
cat > $tempfile <<EOF
char bootprog_info[] = "$bootprog_info";
unsigned bootprog_rev = ${r%%.*}${r##*.};
EOF
mv $tempfile vers.c

View File

@ -64,7 +64,7 @@ ${LOADER}: ${LOADER}.bin ${BTXLDR} ${BTXKERN}
-b ${BTXKERN} ${LOADER}.bin
${LOADER}.bin: ${LOADER}.sym
strip -R .comment -R .note -o ${.TARGET} ${.ALLSRC}
${STRIPBIN} -R .comment -R .note -o ${.TARGET} ${.ALLSRC}
.if ${MK_LOADER_ZFS} == "yes" && ${LOADER_INTERP} == ${LOADER_DEFAULT_INTERP}
LINKS+= ${BINDIR}/${LOADER} ${BINDIR}/zfsloader

View File

@ -126,16 +126,21 @@ __FBSDID("$FreeBSD$");
#define AW_IR_DMAX 53
/* Active Thresholds */
#define AW_IR_ACTIVE_T ((0 & 0xff) << 16)
#define AW_IR_ACTIVE_T_C ((1 & 0xff) << 23)
#define AW_IR_ACTIVE_T_VAL AW_IR_L1_MIN
#define AW_IR_ACTIVE_T (((AW_IR_ACTIVE_T_VAL - 1) & 0xff) << 16)
#define AW_IR_ACTIVE_T_C_VAL 0
#define AW_IR_ACTIVE_T_C ((AW_IR_ACTIVE_T_C_VAL & 0xff) << 23)
/* Code masks */
#define CODE_MASK 0x00ff00ff
#define INV_CODE_MASK 0xff00ff00
#define VALID_CODE_MASK 0x00ff0000
#define A10_IR 1
#define A13_IR 2
enum {
A10_IR = 1,
A13_IR,
A31_IR,
};
#define AW_IR_RAW_BUF_SIZE 128
@ -158,6 +163,7 @@ static struct resource_spec aw_ir_spec[] = {
static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun4i-a10-ir", A10_IR },
{ "allwinner,sun5i-a13-ir", A13_IR },
{ "allwinner,sun6i-a31-ir", A31_IR },
{ NULL, 0 }
};
@ -196,24 +202,24 @@ aw_ir_read_data(struct aw_ir_softc *sc)
static unsigned long
aw_ir_decode_packets(struct aw_ir_softc *sc)
{
unsigned long len, code;
unsigned char val, last;
unsigned int len, code;
unsigned int active_delay;
unsigned char val, last;
int i, bitcount;
if (bootverbose)
device_printf(sc->dev, "sc->dcnt = %d\n", sc->dcnt);
/* Find Lead 1 (bit separator) */
active_delay = (AW_IR_ACTIVE_T + 1) * (AW_IR_ACTIVE_T_C != 0 ? 128 : 1);
len = 0;
len += (active_delay >> 1);
active_delay = AW_IR_ACTIVE_T_VAL *
(AW_IR_ACTIVE_T_C_VAL != 0 ? 128 : 1);
len = active_delay;
if (bootverbose)
device_printf(sc->dev, "Initial len: %ld\n", len);
device_printf(sc->dev, "Initial len: %d\n", len);
for (i = 0; i < sc->dcnt; i++) {
val = sc->buf[i];
if (val & VAL_MASK)
len += val & PERIOD_MASK;
len += (val & PERIOD_MASK) + 1;
else {
if (len > AW_IR_L1_MIN)
break;
@ -221,7 +227,7 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
}
}
if (bootverbose)
device_printf(sc->dev, "len = %ld\n", len);
device_printf(sc->dev, "len = %d\n", len);
if ((val & VAL_MASK) || (len <= AW_IR_L1_MIN)) {
if (bootverbose)
device_printf(sc->dev, "Bit separator error\n");
@ -237,7 +243,7 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
break;
len = 0;
} else
len += val & PERIOD_MASK;
len += (val & PERIOD_MASK) + 1;
}
if ((!(val & VAL_MASK)) || (len <= AW_IR_L0_MIN)) {
if (bootverbose)
@ -254,23 +260,25 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
val = sc->buf[i];
if (last) {
if (val & VAL_MASK)
len += val & PERIOD_MASK;
len += (val & PERIOD_MASK) + 1;
else {
if (len > AW_IR_PMAX) {
if (bootverbose)
device_printf(sc->dev,
"Pulse error\n");
"Pulse error, len=%d\n",
len);
goto error_code;
}
last = 0;
len = val & PERIOD_MASK;
len = (val & PERIOD_MASK) + 1;
}
} else {
if (val & VAL_MASK) {
if (len > AW_IR_DMAX) {
if (bootverbose)
device_printf(sc->dev,
"Distant error\n");
"Distance error, len=%d\n",
len);
goto error_code;
} else {
if (len > AW_IR_DMID) {
@ -282,9 +290,9 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
break; /* Finish decoding */
}
last = 1;
len = val & PERIOD_MASK;
len = (val & PERIOD_MASK) + 1;
} else
len += val & PERIOD_MASK;
len += (val & PERIOD_MASK) + 1;
}
}
return (code);
@ -364,7 +372,7 @@ aw_ir_intr(void *arg)
device_printf(sc->dev, "IR code status: %d\n",
stat);
}
sc->dcnt = 0;
aw_ir_buf_reset(sc);
}
if (val & AW_IR_RXINT_ROI_EN) {
/* RX FIFO overflow */
@ -414,6 +422,7 @@ aw_ir_attach(device_t dev)
sc->fifo_size = 16;
break;
case A13_IR:
case A31_IR:
sc->fifo_size = 64;
break;
}
@ -464,7 +473,8 @@ aw_ir_attach(device_t dev)
&sc->intrhand)) {
bus_release_resources(dev, aw_ir_spec, sc->res);
device_printf(dev, "cannot setup interrupt handler\n");
return (ENXIO);
err = ENXIO;
goto error;
}
/* Enable CIR Mode */

View File

@ -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)

View File

@ -23,7 +23,7 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -33,94 +33,347 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/socket.h>
#include <machine/bus.h>
#include <net/if.h>
#include <net/if_media.h>
#include <dev/dwc/if_dwc.h>
#include <dev/dwc/if_dwcvar.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/extres/clk/clk.h>
#include <dev/extres/hwreset/hwreset.h>
#include <dev/extres/regulator/regulator.h>
#include <dev/extres/syscon/syscon.h>
#include "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);

View File

@ -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,

View File

@ -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);
}

View File

@ -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"

View File

@ -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)
{

View File

@ -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;

View File

@ -36,6 +36,7 @@
#include <linux/compiler.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <asm/atomic.h>

View File

@ -0,0 +1,64 @@
/*-
* Copyright (c) 2020 The FreeBSD Foundation
*
* This software was developed by Emmanuel Vadot under sponsorship
* from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef __LINUX_WAITBIT_H__
#define __LINUX_WAITBIT_H__
#include <linux/wait.h>
#include <linux/bitops.h>
extern wait_queue_head_t linux_bit_waitq;
extern wait_queue_head_t linux_var_waitq;
#define wait_var_event_killable(var, cond) \
wait_event_killable(linux_var_waitq, cond)
static inline void
clear_and_wake_up_bit(int bit, void *word)
{
clear_bit_unlock(bit, word);
wake_up_bit(word, bit);
}
static inline wait_queue_head_t *
bit_waitqueue(void *word, int bit)
{
return (&linux_bit_waitq);
}
static inline void
wake_up_var(void *var)
{
wake_up(&linux_var_waitq);
}
#endif /* __LINUX_WAITBIT_H__ */

View File

@ -86,6 +86,7 @@ __FBSDID("$FreeBSD$");
#include <linux/compat.h>
#include <linux/poll.h>
#include <linux/smp.h>
#include <linux/wait_bit.h>
#if defined(__i386__) || defined(__amd64__)
#include <asm/smp.h>
@ -119,6 +120,9 @@ spinlock_t pci_lock;
unsigned long linux_timer_hz_mask;
wait_queue_head_t linux_bit_waitq;
wait_queue_head_t linux_var_waitq;
int
panic_cmp(struct rb_node *one, struct rb_node *two)
{
@ -2523,6 +2527,8 @@ linux_compat_init(void *arg)
mtx_init(&vmmaplock, "IO Map lock", NULL, MTX_DEF);
for (i = 0; i < VMMAP_HASH_SIZE; i++)
LIST_INIT(&vmmaphead[i]);
init_waitqueue_head(&linux_bit_waitq);
init_waitqueue_head(&linux_var_waitq);
}
SYSINIT(linux_compat, SI_SUB_DRIVERS, SI_ORDER_SECOND, linux_compat_init, NULL);

View File

@ -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);

View File

@ -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_ */

View File

@ -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

View File

@ -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

View File

@ -36,22 +36,16 @@
#ifndef PCG_VARIANTS_H_INCLUDED
#define PCG_VARIANTS_H_INCLUDED 1
#include <inttypes.h>
#if __SIZEOF_INT128__
#if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__
typedef __uint128_t pcg128_t;
#define PCG_128BIT_CONSTANT(high,low) \
((((pcg128_t)high) << 64) + low)
#define PCG_HAS_128BIT_OPS 1
#else
#define PCG_HAS_128BIT_OPS 0
#endif
#if __GNUC_GNU_INLINE__ && !defined(__cplusplus)
#error Nonstandard GNU inlining semantics. Compile with -std=c99 or better.
/* We could instead use macros PCG_INLINE and PCG_EXTERN_INLINE
but better to just reject ancient C code. */
#endif
#if __cplusplus
#ifdef __cplusplus
extern "C" {
#endif
@ -65,8 +59,8 @@ inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot)
* recognizing idiomatic rotate code, so for clang we actually provide
* assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss.
*/
#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__)
asm ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
#if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
__asm__ ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
#else
return (value >> rot) | (value << ((- rot) & 7));
@ -75,8 +69,8 @@ inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot)
inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot)
{
#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__)
asm ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
#if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
__asm__ ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
#else
return (value >> rot) | (value << ((- rot) & 15));
@ -85,8 +79,8 @@ inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot)
inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot)
{
#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__)
asm ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
#if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
__asm__ ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
#else
return (value >> rot) | (value << ((- rot) & 31));
@ -95,10 +89,10 @@ inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot)
inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot)
{
#if 0 && PCG_USE_INLINE_ASM && __clang__ && __x86_64__
#if 0 && PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
/* For whatever reason, clang actually *does* generate rotq by
itself, so we don't need this code. */
asm ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
__asm__ ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
#else
return (value >> rot) | (value << ((- rot) & 63));
@ -2491,18 +2485,6 @@ typedef struct pcg_state_setseq_128 pcg128i_random_t;
#define pcg128i_advance_r pcg_setseq_128_advance_r
#endif
extern uint32_t pcg32_random(void);
extern uint32_t pcg32_boundedrand(uint32_t bound);
extern void pcg32_srandom(uint64_t seed, uint64_t seq);
extern void pcg32_advance(uint64_t delta);
#if PCG_HAS_128BIT_OPS
extern uint64_t pcg64_random(void);
extern uint64_t pcg64_boundedrand(uint64_t bound);
extern void pcg64_srandom(pcg128_t seed, pcg128_t seq);
extern void pcg64_advance(pcg128_t delta);
#endif
/*
* Static initialization constants (if you can't call srandom for some
* bizarre reason).
@ -2536,7 +2518,7 @@ extern void pcg64_advance(pcg128_t delta);
#define PCG128I_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER
#endif
#if __cplusplus
#ifdef __cplusplus
}
#endif

View File

@ -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[] = {

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#include "opt_platform.h"
#include "opt_kbd.h"
#include "opt_evdev.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -56,6 +57,11 @@ __FBSDID("$FreeBSD$");
#include <dev/gpio/gpiobusvar.h>
#include <dev/gpio/gpiokeys.h>
#ifdef EVDEV_SUPPORT
#include <dev/evdev/evdev.h>
#include <dev/evdev/input.h>
#endif
#define KBD_DRIVER_NAME "gpiokeys"
#define GPIOKEYS_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
@ -99,6 +105,9 @@ struct gpiokey
struct resource *irq_res;
void *intr_hl;
struct mtx mtx;
#ifdef EVDEV_SUPPORT
uint32_t evcode;
#endif
uint32_t keycode;
int autorepeat;
struct callout debounce_callout;
@ -115,6 +124,9 @@ struct gpiokeys_softc
struct gpiokey *sc_keys;
int sc_total_keys;
#ifdef EVDEV_SUPPORT
struct evdev_dev *sc_evdev;
#endif
keyboard_t sc_kbd;
keymap_t sc_keymap;
accentmap_t sc_accmap;
@ -171,26 +183,34 @@ gpiokeys_put_key(struct gpiokeys_softc *sc, uint32_t key)
}
static void
gpiokeys_key_event(struct gpiokeys_softc *sc, uint16_t keycode, int pressed)
gpiokeys_key_event(struct gpiokeys_softc *sc, struct gpiokey *key, int pressed)
{
uint32_t key;
key = keycode & SCAN_KEYCODE_MASK;
if (!pressed)
key |= KEY_RELEASE;
uint32_t code;
GPIOKEYS_LOCK(sc);
if (keycode & SCAN_PREFIX_E0)
gpiokeys_put_key(sc, 0xe0);
else if (keycode & SCAN_PREFIX_E1)
gpiokeys_put_key(sc, 0xe1);
#ifdef EVDEV_SUPPORT
if (key->evcode != GPIOKEY_NONE &&
(evdev_rcpt_mask & EVDEV_RCPT_HW_KBD) != 0) {
evdev_push_key(sc->sc_evdev, key->evcode, pressed);
evdev_sync(sc->sc_evdev);
}
#endif
if (key->keycode != GPIOKEY_NONE) {
code = key->keycode & SCAN_KEYCODE_MASK;
if (!pressed)
code |= KEY_RELEASE;
gpiokeys_put_key(sc, key);
if (key->keycode & SCAN_PREFIX_E0)
gpiokeys_put_key(sc, 0xe0);
else if (key->keycode & SCAN_PREFIX_E1)
gpiokeys_put_key(sc, 0xe1);
gpiokeys_put_key(sc, code);
}
GPIOKEYS_UNLOCK(sc);
gpiokeys_event_keyinput(sc);
if (key->keycode != GPIOKEY_NONE)
gpiokeys_event_keyinput(sc);
}
static void
@ -200,10 +220,7 @@ gpiokey_autorepeat(void *arg)
key = arg;
if (key->keycode == GPIOKEY_NONE)
return;
gpiokeys_key_event(key->parent_sc, key->keycode, 1);
gpiokeys_key_event(key->parent_sc, key, 1);
callout_reset(&key->repeat_callout, key->repeat,
gpiokey_autorepeat, key);
@ -217,12 +234,9 @@ gpiokey_debounced_intr(void *arg)
key = arg;
if (key->keycode == GPIOKEY_NONE)
return;
gpio_pin_is_active(key->pin, &active);
if (active) {
gpiokeys_key_event(key->parent_sc, key->keycode, 1);
gpiokeys_key_event(key->parent_sc, key, 1);
if (key->autorepeat) {
callout_reset(&key->repeat_callout, key->repeat_delay,
gpiokey_autorepeat, key);
@ -232,7 +246,7 @@ gpiokey_debounced_intr(void *arg)
if (key->autorepeat &&
callout_pending(&key->repeat_callout))
callout_stop(&key->repeat_callout);
gpiokeys_key_event(key->parent_sc, key->keycode, 0);
gpiokeys_key_event(key->parent_sc, key, 0);
}
}
@ -301,6 +315,10 @@ gpiokeys_attach_key(struct gpiokeys_softc *sc, phandle_t node,
if (key->keycode == GPIOKEY_NONE)
device_printf(sc->sc_dev, "<%s> failed to map linux,code value 0x%x\n",
key_name, code);
#ifdef EVDEV_SUPPORT
key->evcode = code;
evdev_support_key(sc->sc_evdev, code);
#endif
}
else
device_printf(sc->sc_dev, "<%s> no linux,code or freebsd,code property\n",
@ -365,7 +383,6 @@ gpiokeys_detach_key(struct gpiokeys_softc *sc, struct gpiokey *key)
if (key->pin)
gpio_pin_release(key->pin);
GPIOKEY_UNLOCK(key);
GPIOKEY_LOCK_DESTROY(key);
}
@ -383,11 +400,14 @@ gpiokeys_probe(device_t dev)
static int
gpiokeys_attach(device_t dev)
{
int unit;
struct gpiokeys_softc *sc;
keyboard_t *kbd;
#ifdef EVDEV_SUPPORT
char *name;
#endif
phandle_t keys, child;
int total_keys;
int unit;
if ((keys = ofw_bus_get_node(dev)) == -1)
return (ENXIO);
@ -435,6 +455,19 @@ gpiokeys_attach(device_t dev)
kbdd_diag(kbd, 1);
}
#ifdef EVDEV_SUPPORT
sc->sc_evdev = evdev_alloc();
evdev_set_name(sc->sc_evdev, device_get_desc(dev));
OF_getprop_alloc(keys, "name", (void **)&name);
evdev_set_phys(sc->sc_evdev, name != NULL ? name : "unknown");
OF_prop_free(name);
evdev_set_id(sc->sc_evdev, BUS_VIRTUAL, 0, 0, 0);
evdev_support_event(sc->sc_evdev, EV_SYN);
evdev_support_event(sc->sc_evdev, EV_KEY);
#endif
total_keys = 0;
/* Traverse the 'gpio-keys' node and count keys */
@ -458,6 +491,13 @@ gpiokeys_attach(device_t dev)
}
}
#ifdef EVDEV_SUPPORT
if (evdev_register_mtx(sc->sc_evdev, &sc->sc_mtx) != 0) {
device_printf(dev, "failed to register evdev device\n");
goto detach;
}
#endif
return (0);
detach:
@ -485,6 +525,10 @@ gpiokeys_detach(device_t dev)
#endif
kbd_unregister(kbd);
#ifdef EVDEV_SUPPORT
evdev_free(sc->sc_evdev);
#endif
GPIOKEYS_LOCK_DESTROY(sc);
if (sc->sc_keys)
free(sc->sc_keys, M_DEVBUF);

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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_ */

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2012-2016 Intel Corporation
* All rights reserved.
* Copyright (C) 2018 Alexander Motin <mav@FreeBSD.org>
* Copyright (C) 2018-2020 Alexander Motin <mav@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -45,6 +45,9 @@ __FBSDID("$FreeBSD$");
#include <geom/geom_disk.h>
#include <dev/nvme/nvme.h>
#include <dev/nvme/nvme_private.h>
#include <dev/pci/pcivar.h>
#define NVD_STR "nvd"
@ -92,7 +95,7 @@ struct nvd_disk {
};
struct nvd_controller {
struct nvme_controller *ctrlr;
TAILQ_ENTRY(nvd_controller) tailq;
TAILQ_HEAD(, nvd_disk) disk_head;
};
@ -401,6 +404,7 @@ nvd_new_controller(struct nvme_controller *ctrlr)
nvd_ctrlr = malloc(sizeof(struct nvd_controller), M_NVD,
M_ZERO | M_WAITOK);
nvd_ctrlr->ctrlr = ctrlr;
TAILQ_INIT(&nvd_ctrlr->disk_head);
mtx_lock(&nvd_lock);
TAILQ_INSERT_TAIL(&ctrlr_head, nvd_ctrlr, tailq);
@ -416,6 +420,7 @@ nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg)
struct nvd_disk *ndisk, *tnd;
struct disk *disk;
struct nvd_controller *ctrlr = ctrlr_arg;
device_t dev = ctrlr->ctrlr->dev;
int unit;
ndisk = malloc(sizeof(struct nvd_disk), M_NVD, M_ZERO | M_WAITOK);
@ -479,7 +484,13 @@ nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg)
NVME_MODEL_NUMBER_LENGTH);
strlcpy(disk->d_descr, descr, sizeof(descr));
disk->d_hba_vendor = pci_get_vendor(dev);
disk->d_hba_device = pci_get_device(dev);
disk->d_hba_subvendor = pci_get_subvendor(dev);
disk->d_hba_subdevice = pci_get_subdevice(dev);
disk->d_rotation_rate = DISK_RR_NON_ROTATING;
strlcpy(disk->d_attachment, device_get_nameunit(dev),
sizeof(disk->d_attachment));
disk_create(disk, DISK_VERSION);

View File

@ -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;
}

View File

@ -66,6 +66,8 @@ __FBSDID("$FreeBSD$");
#define USB_DEBUG_VAR usb_debug
#include <dev/usb/usb_debug.h>
#define SIZEOF_FIELD(_s, _f) sizeof(((struct _s *)NULL)->_f)
#define CP2112GPIO_LOCK(sc) sx_xlock(&sc->gpio_lock)
#define CP2112GPIO_UNLOCK(sc) sx_xunlock(&sc->gpio_lock)
#define CP2112GPIO_LOCKED(sc) sx_assert(&sc->gpio_lock, SX_XLOCKED)
@ -93,8 +95,13 @@ __FBSDID("$FreeBSD$");
#define CP2112_REQ_LOCK 0x20
#define CP2112_REQ_USB_CFG 0x21
#define CP2112_IIC_MAX_READ_LEN 512
#define CP2112_IIC_REPSTART_VER 2 /* Erratum CP2112_E10. */
#define CP2112_GPIO_SPEC_CLK7 1 /* Pin 7 is clock output. */
#define CP2112_GPIO_SPEC_TX0 2 /* Pin 0 pulses on USB TX. */
#define CP2112_GPIO_SPEC_RX1 4 /* Pin 1 pulses on USB RX. */
#define CP2112_IIC_STATUS0_IDLE 0
#define CP2112_IIC_STATUS0_BUSY 1
#define CP2112_IIC_STATUS0_CMP 2
@ -104,6 +111,111 @@ __FBSDID("$FreeBSD$");
#define CP2112_IIC_STATUS1_TIMEOUT_BUS 1
#define CP2112_IIC_STATUS1_ARB_LOST 2
/* CP2112_REQ_VERSION */
struct version_request {
uint8_t id;
uint8_t part_num;
uint8_t version;
} __packed;
/* CP2112_REQ_GPIO_GET */
struct gpio_get_req {
uint8_t id;
uint8_t state;
} __packed;
/* CP2112_REQ_GPIO_SET */
struct gpio_set_req {
uint8_t id;
uint8_t state;
uint8_t mask;
} __packed;
/* CP2112_REQ_GPIO_CFG */
struct gpio_config_req {
uint8_t id;
uint8_t output;
uint8_t pushpull;
uint8_t special;
uint8_t divider;
} __packed;
/* CP2112_REQ_SMB_XFER_STATUS_REQ */
struct i2c_xfer_status_req {
uint8_t id;
uint8_t request;
} __packed;
/* CP2112_REQ_SMB_XFER_STATUS_RESP */
struct i2c_xfer_status_resp {
uint8_t id;
uint8_t status0;
uint8_t status1;
uint16_t status2;
uint16_t status3;
} __packed;
/* CP2112_REQ_SMB_READ_FORCE_SEND */
struct i2c_data_read_force_send_req {
uint8_t id;
uint16_t len;
} __packed;
/* CP2112_REQ_SMB_READ_RESPONSE */
struct i2c_data_read_resp {
uint8_t id;
uint8_t status;
uint8_t len;
uint8_t data[61];
} __packed;
/* CP2112_REQ_SMB_READ */
struct i2c_write_read_req {
uint8_t id;
uint8_t slave;
uint16_t rlen;
uint8_t wlen;
uint8_t wdata[16];
} __packed;
/* CP2112_REQ_SMB_WRITE */
struct i2c_read_req {
uint8_t id;
uint8_t slave;
uint16_t len;
} __packed;
/* CP2112_REQ_SMB_WRITE_READ */
struct i2c_write_req {
uint8_t id;
uint8_t slave;
uint8_t len;
uint8_t data[61];
} __packed;
/* CP2112_REQ_SMB_CFG */
struct i2c_cfg_req {
uint8_t id;
uint32_t speed; /* Hz */
uint8_t slave_addr; /* ACK only */
uint8_t auto_send_read; /* boolean */
uint16_t write_timeout; /* 0-1000 ms, 0 ~ no timeout */
uint16_t read_timeout; /* 0-1000 ms, 0 ~ no timeout */
uint8_t scl_low_timeout;/* boolean */
uint16_t retry_count; /* 1-1000, 0 ~ forever */
} __packed;
enum cp2112_out_mode {
OUT_OD,
OUT_PP,
OUT_KEEP
};
enum {
CP2112_INTR_OUT = 0,
CP2112_INTR_IN,
CP2112_N_TRANSFER,
};
struct cp2112_softc {
device_t sc_gpio_dev;
@ -120,10 +232,38 @@ struct cp2112gpio_softc {
struct gpio_pin pins[CP2112_GPIO_COUNT];
};
struct cp2112iic_softc {
device_t dev;
device_t iicbus_dev;
struct usb_xfer *xfers[CP2112_N_TRANSFER];
u_char own_addr;
struct {
struct mtx lock;
struct cv cv;
struct {
uint8_t *data;
int len;
int done;
int error;
} in;
struct {
const uint8_t *data;
int len;
int done;
int error;
} out;
} io;
};
static int cp2112_detach(device_t dev);
static int cp2112gpio_detach(device_t dev);
static int cp2112iic_detach(device_t dev);
static const STRUCT_USB_HOST_ID cp2112_devs[] = {
{ USB_VP(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2112) },
{ USB_VP(0x1009, USB_PRODUCT_SILABS_CP2112) }, /* XXX */
};
static int
cp2112_get_report(device_t dev, uint8_t id, void *data, uint16_t len)
{
@ -143,25 +283,103 @@ cp2112_set_report(device_t dev, uint8_t id, void *data, uint16_t len)
int err;
sc = device_get_softc(dev);
*(uint8_t *)data = id;
err = usbd_req_set_report(sc->sc_udev, NULL, data,
len, sc->sc_iface_index, UHID_FEATURE_REPORT, id);
return (err);
}
static int
cp2112_probe(device_t dev)
{
struct usb_attach_arg *uaa;
uaa = device_get_ivars(dev);
if (uaa->usb_mode != USB_MODE_HOST)
return (ENXIO);
if (uaa->info.bInterfaceClass != UICLASS_HID)
return (ENXIO);
if (usbd_lookup_id_by_uaa(cp2112_devs, sizeof(cp2112_devs), uaa) == 0)
return (BUS_PROBE_DEFAULT);
return (ENXIO);
}
static int
cp2112_attach(device_t dev)
{
struct version_request vdata;
struct usb_attach_arg *uaa;
struct cp2112_softc *sc;
int err;
uaa = device_get_ivars(dev);
sc = device_get_softc(dev);
device_set_usb_desc(dev);
sc->sc_udev = uaa->device;
sc->sc_iface_index = uaa->info.bIfaceIndex;
err = cp2112_get_report(dev, CP2112_REQ_VERSION, &vdata, sizeof(vdata));
if (err != 0)
goto detach;
device_printf(dev, "part number 0x%02x, version 0x%02x\n",
vdata.part_num, vdata.version);
if (vdata.part_num != CP2112_PART_NUM) {
device_printf(dev, "unsupported part number\n");
goto detach;
}
sc->sc_version = vdata.version;
sc->sc_gpio_dev = device_add_child(dev, "gpio", -1);
if (sc->sc_gpio_dev != NULL) {
err = device_probe_and_attach(sc->sc_gpio_dev);
if (err != 0) {
device_printf(dev, "failed to attach gpio child\n");
}
} else {
device_printf(dev, "failed to create gpio child\n");
}
sc->sc_iic_dev = device_add_child(dev, "iichb", -1);
if (sc->sc_iic_dev != NULL) {
err = device_probe_and_attach(sc->sc_iic_dev);
if (err != 0) {
device_printf(dev, "failed to attach iic child\n");
}
} else {
device_printf(dev, "failed to create iic child\n");
}
return (0);
detach:
cp2112_detach(dev);
return (ENXIO);
}
static int
cp2112_detach(device_t dev)
{
int err;
err = bus_generic_detach(dev);
if (err != 0)
return (err);
device_delete_children(dev);
return (0);
}
static int
cp2112_gpio_read_pin(device_t dev, uint32_t pin_num, bool *on)
{
struct {
uint8_t id;
uint8_t state;
} __packed data;
struct gpio_get_req data;
struct cp2112gpio_softc *sc;
int err;
sc = device_get_softc(dev);
CP2112GPIO_LOCKED(sc);
data.id = CP2112_REQ_GPIO_GET;
err = cp2112_get_report(device_get_parent(dev),
CP2112_REQ_GPIO_GET, &data, sizeof(data));
if (err != 0)
@ -174,11 +392,7 @@ cp2112_gpio_read_pin(device_t dev, uint32_t pin_num, bool *on)
static int
cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on)
{
struct {
uint8_t id;
uint8_t state;
uint8_t mask;
} __packed data;
struct gpio_set_req data;
struct cp2112gpio_softc *sc;
int err;
bool actual;
@ -186,10 +400,8 @@ cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on)
sc = device_get_softc(dev);
CP2112GPIO_LOCKED(sc);
data.id = CP2112_REQ_GPIO_SET;
data.state = (uint8_t)on << pin_num;
data.mask = (uint8_t)1 << pin_num;
err = cp2112_set_report(device_get_parent(dev),
CP2112_REQ_GPIO_SET, &data, sizeof(data));
if (err != 0)
@ -204,15 +416,9 @@ cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on)
static int
cp2112_gpio_configure_write_pin(device_t dev, uint32_t pin_num,
bool output, bool pushpull)
bool output, enum cp2112_out_mode *mode)
{
struct {
uint8_t id;
uint8_t output;
uint8_t pushpull;
uint8_t special;
uint8_t divider;
} __packed data;
struct gpio_config_req data;
struct cp2112gpio_softc *sc;
int err;
uint8_t mask;
@ -220,21 +426,26 @@ cp2112_gpio_configure_write_pin(device_t dev, uint32_t pin_num,
sc = device_get_softc(dev);
CP2112GPIO_LOCKED(sc);
mask = (uint8_t)1 << pin_num;
data.id = CP2112_REQ_GPIO_CFG;
err = cp2112_get_report(device_get_parent(dev),
CP2112_REQ_GPIO_CFG, &data, sizeof(data));
if (err != 0)
return (err);
mask = (uint8_t)1 << pin_num;
if (output) {
data.output |= mask;
if (pushpull)
switch (*mode) {
case OUT_PP:
data.pushpull |= mask;
else
break;
case OUT_OD:
data.pushpull &= ~mask;
break;
default:
break;
}
} else {
data.output &= ~mask;
data.pushpull &= ~mask;
}
err = cp2112_set_report(device_get_parent(dev),
@ -247,10 +458,25 @@ cp2112_gpio_configure_write_pin(device_t dev, uint32_t pin_num,
CP2112_REQ_GPIO_CFG, &data, sizeof(data));
if (err != 0)
return (err);
if (((data.output & mask) != 0) != output)
return (EIO);
if (((data.pushpull & mask) != 0) != pushpull)
return (EIO);
if (output) {
switch (*mode) {
case OUT_PP:
if ((data.pushpull & mask) == 0)
return (EIO);
break;
case OUT_OD:
if ((data.pushpull & mask) != 0)
return (EIO);
break;
default:
*mode = (data.pushpull & mask) != 0 ?
OUT_PP : OUT_OD;
break;
}
}
return (0);
}
@ -381,6 +607,7 @@ cp2112_gpio_pin_setflags(device_t dev, uint32_t pin_num, uint32_t flags)
{
struct cp2112gpio_softc *sc;
struct gpio_pin *pin;
enum cp2112_out_mode out_mode;
int err;
if (pin_num >= CP2112_GPIO_COUNT)
@ -405,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 <write><repeated start><read> into a single
* CP2112 operation.
*/
struct {
uint8_t id;
uint8_t slave;
uint16_t rlen;
uint8_t wlen;
uint8_t wdata[16];
} __packed req;
struct i2c_write_read_req req;
KASSERT((msgs[i].flags & IIC_M_RD) == 0,
("read without stop"));
KASSERT((msgs[i + 1].flags & IIC_M_RD) != 0,
("write after write without stop"));
req.id = CP2112_REQ_SMB_WRITE_READ;
req.slave = msgs[i].slave & ~LSB;
to_read = msgs[i + 1].len;
@ -1150,11 +1193,7 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
*/
i++;
} else if ((msgs[i].flags & IIC_M_RD) != 0) {
struct {
uint8_t id;
uint8_t slave;
uint16_t len;
} __packed req;
struct i2c_read_req req;
req.id = CP2112_REQ_SMB_READ;
req.slave = msgs[i].slave & ~LSB;
@ -1162,12 +1201,7 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
req.len = htobe16(to_read);
err = cp2112iic_send_req(sc, &req, sizeof(req));
} else {
struct {
uint8_t id;
uint8_t slave;
uint8_t len;
uint8_t data[61];
} __packed req;
struct i2c_write_req req;
req.id = CP2112_REQ_SMB_WRITE;
req.slave = msgs[i].slave & ~LSB;
@ -1207,16 +1241,7 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
static int
cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
{
struct {
uint8_t id;
uint32_t speed; /* Hz */
uint8_t slave_addr; /* ACK only */
uint8_t auto_send_read; /* boolean */
uint16_t write_timeout; /* 0-1000 ms, 0 ~ no timeout */
uint16_t read_timeout; /* 0-1000 ms, 0 ~ no timeout */
uint8_t scl_low_timeout;/* boolean */
uint16_t retry_count; /* 1-1000, 0 ~ forever */
} __packed smb_cfg;
struct i2c_cfg_req i2c_cfg;
struct cp2112iic_softc *sc;
device_t cp2112;
u_int busfreq;
@ -1229,16 +1254,15 @@ cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
else
busfreq = IICBUS_GET_FREQUENCY(sc->iicbus_dev, speed);
smb_cfg.id = CP2112_REQ_SMB_CFG;
err = cp2112_get_report(cp2112, CP2112_REQ_SMB_CFG,
&smb_cfg, sizeof(smb_cfg));
&i2c_cfg, sizeof(i2c_cfg));
if (err != 0) {
device_printf(dev, "failed to get CP2112_REQ_SMB_CFG report\n");
return (err);
}
if (oldaddr != NULL)
*oldaddr = smb_cfg.slave_addr;
*oldaddr = i2c_cfg.slave_addr;
/*
* For simplicity we do not enable Auto Send Read
* because of erratum CP2112_E101 (fixed in version 3).
@ -1251,28 +1275,28 @@ cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
* TODO: should the device reset request (0x01) be sent?
* If the device disconnects as a result, then no.
*/
smb_cfg.speed = htobe32(busfreq);
i2c_cfg.speed = htobe32(busfreq);
if (addr != 0)
smb_cfg.slave_addr = addr;
smb_cfg.auto_send_read = 0;
smb_cfg.retry_count = htobe16(1);
smb_cfg.scl_low_timeout = 0;
i2c_cfg.slave_addr = addr;
i2c_cfg.auto_send_read = 0;
i2c_cfg.retry_count = htobe16(1);
i2c_cfg.scl_low_timeout = 0;
if (bootverbose) {
device_printf(dev, "speed %d Hz\n", be32toh(smb_cfg.speed));
device_printf(dev, "slave addr 0x%02x\n", smb_cfg.slave_addr);
device_printf(dev, "speed %d Hz\n", be32toh(i2c_cfg.speed));
device_printf(dev, "slave addr 0x%02x\n", i2c_cfg.slave_addr);
device_printf(dev, "auto send read %s\n",
smb_cfg.auto_send_read ? "on" : "off");
i2c_cfg.auto_send_read ? "on" : "off");
device_printf(dev, "write timeout %d ms (0 - disabled)\n",
be16toh(smb_cfg.write_timeout));
be16toh(i2c_cfg.write_timeout));
device_printf(dev, "read timeout %d ms (0 - disabled)\n",
be16toh(smb_cfg.read_timeout));
be16toh(i2c_cfg.read_timeout));
device_printf(dev, "scl low timeout %s\n",
smb_cfg.scl_low_timeout ? "on" : "off");
i2c_cfg.scl_low_timeout ? "on" : "off");
device_printf(dev, "retry count %d (0 - no limit)\n",
be16toh(smb_cfg.retry_count));
be16toh(i2c_cfg.retry_count));
}
err = cp2112_set_report(cp2112, CP2112_REQ_SMB_CFG,
&smb_cfg, sizeof(smb_cfg));
&i2c_cfg, sizeof(i2c_cfg));
if (err != 0) {
device_printf(dev, "failed to set CP2112_REQ_SMB_CFG report\n");
return (err);
@ -1353,6 +1377,60 @@ cp2112iic_detach(device_t dev)
return (0);
}
static device_method_t cp2112hid_methods[] = {
DEVMETHOD(device_probe, cp2112_probe),
DEVMETHOD(device_attach, cp2112_attach),
DEVMETHOD(device_detach, cp2112_detach),
DEVMETHOD_END
};
static driver_t cp2112hid_driver = {
.name = "cp2112hid",
.methods = cp2112hid_methods,
.size = sizeof(struct cp2112_softc),
};
static devclass_t cp2112hid_devclass;
DRIVER_MODULE(cp2112hid, uhub, cp2112hid_driver, cp2112hid_devclass,
NULL, NULL);
MODULE_DEPEND(cp2112hid, usb, 1, 1, 1);
MODULE_VERSION(cp2112hid, 1);
USB_PNP_HOST_INFO(cp2112_devs);
static device_method_t cp2112gpio_methods[] = {
/* Device */
DEVMETHOD(device_probe, cp2112gpio_probe),
DEVMETHOD(device_attach, cp2112gpio_attach),
DEVMETHOD(device_detach, cp2112gpio_detach),
/* GPIO */
DEVMETHOD(gpio_get_bus, cp2112_gpio_get_bus),
DEVMETHOD(gpio_pin_max, cp2112_gpio_pin_max),
DEVMETHOD(gpio_pin_get, cp2112_gpio_pin_get),
DEVMETHOD(gpio_pin_set, cp2112_gpio_pin_set),
DEVMETHOD(gpio_pin_toggle, cp2112_gpio_pin_toggle),
DEVMETHOD(gpio_pin_getname, cp2112_gpio_pin_getname),
DEVMETHOD(gpio_pin_getcaps, cp2112_gpio_pin_getcaps),
DEVMETHOD(gpio_pin_getflags, cp2112_gpio_pin_getflags),
DEVMETHOD(gpio_pin_setflags, cp2112_gpio_pin_setflags),
DEVMETHOD_END
};
static driver_t cp2112gpio_driver = {
.name = "gpio",
.methods = cp2112gpio_methods,
.size = sizeof(struct cp2112gpio_softc),
};
static devclass_t cp2112gpio_devclass;
DRIVER_MODULE(cp2112gpio, cp2112hid, cp2112gpio_driver, cp2112gpio_devclass,
NULL, NULL);
MODULE_DEPEND(cp2112gpio, cp2112hid, 1, 1, 1);
MODULE_DEPEND(cp2112gpio, gpiobus, 1, 1, 1);
MODULE_VERSION(cp2112gpio, 1);
static device_method_t cp2112iic_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, cp2112iic_probe),

View File

@ -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_ */

View File

@ -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++;

View File

@ -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_ */

View File

@ -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)

View File

@ -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 */

View File

@ -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

View File

@ -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;

View File

@ -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 *);

View File

@ -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);

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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();

View File

@ -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);
}
/*

View File

@ -88,6 +88,8 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_page.h>
#include <vm/uma.h>
#include <fs/devfs/devfs.h>
#ifdef COMPAT_FREEBSD32
#include <compat/freebsd32/freebsd32.h>
#include <compat/freebsd32/freebsd32_util.h>
@ -858,7 +860,7 @@ killjobc(void)
VOP_REVOKE(ttyvp, REVOKEALL);
VOP_UNLOCK(ttyvp);
}
vrele(ttyvp);
devfs_ctty_unref(ttyvp);
sx_xlock(&proctree_lock);
}
}

131
sys/kern/subr_prng.c Normal file
View File

@ -0,0 +1,131 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright 2020 Conrad Meyer <cem@FreeBSD.org>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/pcpu.h>
#include <sys/prng.h>
#include <sys/smp.h>
#include <sys/systm.h>
#if !PCG_HAS_128BIT_OPS
/* On 32-bit platforms, gang together two 32-bit generators. */
typedef struct {
pcg32u_random_t states[2];
} pcg64u_random_t;
static inline void
pcg64u_srandom_r(pcg64u_random_t *state64, uint64_t seed)
{
pcg32u_srandom_r(&state64->states[0], seed);
pcg32u_srandom_r(&state64->states[1], seed);
}
static inline uint64_t
pcg64u_random_r(pcg64u_random_t *state64)
{
return ((((uint64_t)pcg32u_random_r(&state64->states[0])) << 32) |
pcg32u_random_r(&state64->states[1]));
}
static inline uint64_t
pcg64u_boundedrand_r(pcg64u_random_t *state64, uint64_t bound)
{
uint64_t threshold = -bound % bound;
for (;;) {
uint64_t r = pcg64u_random_r(state64);
if (r >= threshold)
return (r % bound);
}
}
#endif
DPCPU_DEFINE_STATIC(pcg32u_random_t, pcpu_prng32_state);
DPCPU_DEFINE_STATIC(pcg64u_random_t, pcpu_prng64_state);
static void
prng_init(void *dummy __unused)
{
pcg32u_random_t *state;
pcg64u_random_t *state64;
int i;
CPU_FOREACH(i) {
state = DPCPU_ID_PTR(i, pcpu_prng32_state);
pcg32u_srandom_r(state, 1);
state64 = DPCPU_ID_PTR(i, pcpu_prng64_state);
pcg64u_srandom_r(state64, 1);
}
}
SYSINIT(prng_init, SI_SUB_CPU, SI_ORDER_ANY, prng_init, NULL);
uint32_t
prng32(void)
{
uint32_t r;
critical_enter();
r = pcg32u_random_r(DPCPU_PTR(pcpu_prng32_state));
critical_exit();
return (r);
}
uint32_t
prng32_bounded(uint32_t bound)
{
uint32_t r;
critical_enter();
r = pcg32u_boundedrand_r(DPCPU_PTR(pcpu_prng32_state), bound);
critical_exit();
return (r);
}
uint64_t
prng64(void)
{
uint64_t r;
critical_enter();
r = pcg64u_random_r(DPCPU_PTR(pcpu_prng64_state));
critical_exit();
return (r);
}
uint64_t
prng64_bounded(uint64_t bound)
{
uint64_t r;
critical_enter();
r = pcg64u_boundedrand_r(DPCPU_PTR(pcpu_prng64_state), bound);
critical_exit();
return (r);
}

View File

@ -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 ||

View File

@ -67,6 +67,8 @@ __FBSDID("$FreeBSD$");
#include <sys/ucred.h>
#include <sys/vnode.h>
#include <fs/devfs/devfs.h>
#include <machine/stdarg.h>
static MALLOC_DEFINE(M_TTY, "tty", "tty device");
@ -1256,7 +1258,7 @@ tty_drop_ctty(struct tty *tp, struct proc *p)
* is either changed or released.
*/
if (vp != NULL)
vrele(vp);
devfs_ctty_unref(vp);
return (0);
}

Some files were not shown because too many files have changed in this diff Show More