Merge ^/head r364082 through r364250.
This commit is contained in:
commit
de6fc2e39b
@ -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
|
||||
|
5
UPDATING
5
UPDATING
@ -32,6 +32,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
|
||||
information about prerequisites and upgrading, if you are not already
|
||||
using clang 3.5.0 or higher.
|
||||
|
||||
20200810:
|
||||
r364092 modified the internal ABI used between the kernel NFS
|
||||
modules. As such, all of these modules need to be rebuilt
|
||||
from sources, so a version bump was done.
|
||||
|
||||
20200807:
|
||||
Makefile.inc has been updated to work around the issue documented in
|
||||
20200729. It was a case where the optimization of using symbolic links
|
||||
|
@ -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'
|
||||
|
@ -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
|
||||
|
@ -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\");
|
||||
}
|
||||
}
|
||||
"
|
||||
|
@ -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'
|
||||
|
@ -68,6 +68,8 @@
|
||||
..
|
||||
engines
|
||||
..
|
||||
flua
|
||||
..
|
||||
i18n
|
||||
..
|
||||
libxo
|
||||
@ -370,6 +372,8 @@
|
||||
..
|
||||
firmware
|
||||
..
|
||||
flua
|
||||
..
|
||||
games
|
||||
fortune
|
||||
..
|
||||
|
@ -1,5 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SUBDIR= libbsnmp
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
11
lib/libbsnmp/tests/Makefile
Normal file
11
lib/libbsnmp/tests/Makefile
Normal 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>
|
53
lib/libbsnmp/tests/bsnmpd_test.c
Normal file
53
lib/libbsnmp/tests/bsnmpd_test.c
Normal 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());
|
||||
}
|
@ -120,6 +120,7 @@ SRCS+= __getosreldate.c \
|
||||
recvmmsg.c \
|
||||
rewinddir.c \
|
||||
scandir.c \
|
||||
scandir_b.c \
|
||||
scandir-compat11.c \
|
||||
seed48.c \
|
||||
seekdir.c \
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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;" \
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
# PROVIDE: ipfilter
|
||||
# REQUIRE: FILESYSTEMS
|
||||
# BEFORE: ipmon ipnat netif netwait securelevel
|
||||
# KEYWORD: nojailvnet
|
||||
|
||||
. /etc/rc.subr
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
|
||||
# PROVIDE: ipmon
|
||||
# REQUIRE: FILESYSTEMS hostname sysctl ipfilter
|
||||
# REQUIRE: FILESYSTEMS hostname sysctl
|
||||
# BEFORE: SERVERS
|
||||
# KEYWORD: nojailvnet
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
#
|
||||
|
||||
# PROVIDE: ipnat
|
||||
# REQUIRE: ipfilter
|
||||
# KEYWORD: nojailvnet
|
||||
|
||||
. /etc/rc.subr
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
# PROVIDE: netif
|
||||
# REQUIRE: FILESYSTEMS iovctl serial sppp sysctl
|
||||
# REQUIRE: hostid ipfilter ipfs
|
||||
# REQUIRE: hostid ipfs
|
||||
# KEYWORD: nojailvnet
|
||||
|
||||
. /etc/rc.subr
|
||||
|
@ -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:
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
|
||||
# PROVIDE: securelevel
|
||||
# REQUIRE: adjkerntz ipfw ipfilter pf
|
||||
# REQUIRE: adjkerntz ipfw pf
|
||||
|
||||
. /etc/rc.subr
|
||||
|
||||
|
@ -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 ]
|
||||
|
@ -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 ]
|
||||
|
@ -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 ]
|
||||
|
@ -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 ]
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 ]
|
||||
|
@ -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"
|
||||
|
@ -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 ]
|
||||
|
@ -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 ]
|
||||
|
@ -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 ]
|
||||
|
@ -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"
|
||||
|
@ -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 ]
|
||||
|
@ -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 ]
|
||||
|
@ -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 ]
|
||||
|
@ -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 ]
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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 .
|
||||
|
@ -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:
|
||||
|
@ -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 \
|
||||
|
@ -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
87
share/man/man4/cp2112.4
Normal 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 .
|
@ -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
99
share/man/man9/prng.9
Normal 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 .
|
@ -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
|
||||
|
@ -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>
|
||||
|
||||
#
|
||||
|
@ -275,6 +275,7 @@ SHELL ?= sh
|
||||
|
||||
.if !defined(%POSIX)
|
||||
SIZE ?= size
|
||||
STRIPBIN ?= strip
|
||||
.endif
|
||||
|
||||
YACC ?= yacc
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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_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)
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
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;
|
||||
cached = vm_inactive_count() * PAGE_SIZE;
|
||||
|
||||
sbuf_printf(sb,
|
||||
"MemTotal: %9lu kB\n"
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include <asm/atomic.h>
|
||||
|
||||
|
64
sys/compat/linuxkpi/common/include/linux/wait_bit.h
Normal file
64
sys/compat/linuxkpi/common/include/linux/wait_bit.h
Normal 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__ */
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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_ */
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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[] = {
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,25 +183,33 @@ 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)
|
||||
#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;
|
||||
|
||||
if (key->keycode & SCAN_PREFIX_E0)
|
||||
gpiokeys_put_key(sc, 0xe0);
|
||||
else if (keycode & SCAN_PREFIX_E1)
|
||||
else if (key->keycode & SCAN_PREFIX_E1)
|
||||
gpiokeys_put_key(sc, 0xe1);
|
||||
|
||||
gpiokeys_put_key(sc, key);
|
||||
gpiokeys_put_key(sc, code);
|
||||
}
|
||||
GPIOKEYS_UNLOCK(sc);
|
||||
|
||||
if (key->keycode != GPIOKEY_NONE)
|
||||
gpiokeys_event_keyinput(sc);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
@ -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,7 +499,13 @@ pmc_arm64_initialize()
|
||||
/* Just one class */
|
||||
pmc_mdep = pmc_mdep_alloc(1);
|
||||
|
||||
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;
|
||||
@ -508,6 +515,11 @@ pmc_arm64_initialize()
|
||||
pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A53;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A53;
|
||||
break;
|
||||
}
|
||||
|
||||
pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_ARMV8];
|
||||
pcd->pcd_caps = ARMV8_PMC_CAPS;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
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),
|
||||
|
@ -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_ */
|
||||
|
@ -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++;
|
||||
|
@ -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_ */
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 *);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
value = _getenv_dynamic(name, NULL);
|
||||
if (value == NULL)
|
||||
mtx_unlock(&kenv_lock);
|
||||
if (cp == NULL) {
|
||||
uma_zfree(kenv_zone, ret);
|
||||
ret = NULL;
|
||||
}
|
||||
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);
|
||||
cp = kenv_acquire(name);
|
||||
|
||||
if (cp != NULL)
|
||||
strlcpy(data, cp, size);
|
||||
mtx_unlock(&kenv_lock);
|
||||
} else {
|
||||
cp = _getenv_static(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;
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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
131
sys/kern/subr_prng.c
Normal 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);
|
||||
}
|
@ -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 ||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user