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)
|
.if defined(CROSS_TOOLCHAIN_PREFIX)
|
||||||
CROSS_BINUTILS_PREFIX?=${CROSS_TOOLCHAIN_PREFIX}
|
CROSS_BINUTILS_PREFIX?=${CROSS_TOOLCHAIN_PREFIX}
|
||||||
.endif
|
.endif
|
||||||
XBINUTILS= AS AR LD NM OBJCOPY RANLIB SIZE STRINGS
|
XBINUTILS= AS AR LD NM OBJCOPY RANLIB SIZE STRINGS STRIPBIN
|
||||||
.for BINUTIL in ${XBINUTILS}
|
.for BINUTIL in ${XBINUTILS}
|
||||||
.if defined(CROSS_BINUTILS_PREFIX) && \
|
.if defined(CROSS_BINUTILS_PREFIX) && \
|
||||||
exists(${CROSS_BINUTILS_PREFIX}/${${BINUTIL}})
|
exists(${CROSS_BINUTILS_PREFIX}/${${BINUTIL}})
|
||||||
@ -552,6 +552,13 @@ SOURCE_DATE_EPOCH= ${TIMEEPOCHNOW:gmtime}
|
|||||||
SOURCE_DATE_EPOCH= ${PKG_TIMESTAMP}
|
SOURCE_DATE_EPOCH= ${PKG_TIMESTAMP}
|
||||||
.endif
|
.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)
|
.if !defined(_MKSHOWCONFIG)
|
||||||
_CPUTYPE!= MAKEFLAGS= CPUTYPE=${_TARGET_CPUTYPE} ${MAKE} -f /dev/null \
|
_CPUTYPE!= MAKEFLAGS= CPUTYPE=${_TARGET_CPUTYPE} ${MAKE} -f /dev/null \
|
||||||
-m ${.CURDIR}/share/mk MK_AUTO_OBJ=no -V CPUTYPE
|
-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}" \
|
AS="${XAS}" AR="${XAR}" LD="${XLD}" LLVM_LINK="${XLLVM_LINK}" \
|
||||||
NM=${XNM} OBJCOPY="${XOBJCOPY}" \
|
NM=${XNM} OBJCOPY="${XOBJCOPY}" \
|
||||||
RANLIB=${XRANLIB} STRINGS=${XSTRINGS} \
|
RANLIB=${XRANLIB} STRINGS=${XSTRINGS} \
|
||||||
SIZE="${XSIZE}"
|
SIZE="${XSIZE}" STRIPBIN="${XSTRIPBIN}"
|
||||||
|
|
||||||
.if defined(CROSS_BINUTILS_PREFIX) && exists(${CROSS_BINUTILS_PREFIX})
|
.if defined(CROSS_BINUTILS_PREFIX) && exists(${CROSS_BINUTILS_PREFIX})
|
||||||
# In the case of xdev-build tools, CROSS_BINUTILS_PREFIX won't be a
|
# 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/%COMMENT%/FreeBSD ${INSTALLKERNEL} kernel ${flavor}/" \
|
||||||
-e "s/%DESC%/FreeBSD ${INSTALLKERNEL} kernel ${flavor}/" \
|
-e "s/%DESC%/FreeBSD ${INSTALLKERNEL} kernel ${flavor}/" \
|
||||||
-e "s/ %VCS_REVISION%/${VCS_REVISION}/" \
|
-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 \
|
${SRCDIR}/release/packages/kernel.ucl \
|
||||||
> ${KSTAGEDIR}/${DISTDIR}/kernel.${INSTALLKERNEL}${flavor}.ucl ; \
|
> ${KSTAGEDIR}/${DISTDIR}/kernel.${INSTALLKERNEL}${flavor}.ucl ; \
|
||||||
awk -F\" ' \
|
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/%COMMENT%/FreeBSD ${_kernel} kernel ${flavor}/" \
|
||||||
-e "s/%DESC%/FreeBSD ${_kernel} kernel ${flavor}/" \
|
-e "s/%DESC%/FreeBSD ${_kernel} kernel ${flavor}/" \
|
||||||
-e "s/ %VCS_REVISION%/${VCS_REVISION}/" \
|
-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 \
|
${SRCDIR}/release/packages/kernel.ucl \
|
||||||
> ${KSTAGEDIR}/kernel.${_kernel}/kernel.${_kernel}${flavor}.ucl ; \
|
> ${KSTAGEDIR}/kernel.${_kernel}/kernel.${_kernel}${flavor}.ucl ; \
|
||||||
awk -F\" ' \
|
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=usr.bin/grep grep,egrep,fgrep
|
||||||
_basic_bootstrap_tools_multilink+=bin/test test,[
|
_basic_bootstrap_tools_multilink+=bin/test test,[
|
||||||
# bootstrap tools needed by buildworld:
|
# 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/join usr.bin/mktemp bin/rmdir usr.bin/sed usr.bin/sort \
|
||||||
usr.bin/truncate usr.bin/tsort
|
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:
|
# file2c is required for building usr.sbin/config:
|
||||||
_basic_bootstrap_tools+=usr.bin/file2c
|
_basic_bootstrap_tools+=usr.bin/file2c
|
||||||
# uuencode/uudecode required for share/tabset
|
# 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
|
information about prerequisites and upgrading, if you are not already
|
||||||
using clang 3.5.0 or higher.
|
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:
|
20200807:
|
||||||
Makefile.inc has been updated to work around the issue documented in
|
Makefile.inc has been updated to work around the issue documented in
|
||||||
20200729. It was a case where the optimization of using symbolic links
|
20200729. It was a case where the optimization of using symbolic links
|
||||||
|
@ -24,15 +24,15 @@
|
|||||||
# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
||||||
# Use is subject to license terms.
|
# Use is subject to license terms.
|
||||||
#
|
#
|
||||||
#ident "%Z%%M% %I% %E% SMI"
|
set -e
|
||||||
|
|
||||||
echo "\
|
printf "%s" "
|
||||||
/*\n\
|
/*
|
||||||
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.\n\
|
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
||||||
* Use is subject to license terms.\n\
|
* Use is subject to license terms.
|
||||||
*/\n\
|
*/
|
||||||
\n\
|
|
||||||
#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n"
|
"
|
||||||
|
|
||||||
pattern='^#define[ ]\(E[A-Z0-9]*\)[ ]*\([A-Z0-9]*\).*$'
|
pattern='^#define[ ]\(E[A-Z0-9]*\)[ ]*\([A-Z0-9]*\).*$'
|
||||||
replace='inline int \1 = \2;@#pragma D binding "1.0" \1'
|
replace='inline int \1 = \2;@#pragma D binding "1.0" \1'
|
||||||
|
@ -24,36 +24,34 @@
|
|||||||
# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
||||||
# Use is subject to license terms.
|
# 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>
|
#include <dt_errtags.h>
|
||||||
\n\
|
|
||||||
static const char *const _dt_errtags[] = {"
|
static const char *const _dt_errtags[] = {
|
||||||
|
"
|
||||||
|
|
||||||
pattern='^ \(D_[A-Z0-9_]*\),*'
|
pattern='^ \(D_[A-Z0-9_]*\),*'
|
||||||
replace=' "\1",'
|
replace=' "\1",'
|
||||||
|
|
||||||
sed -n "s/$pattern/$replace/p" || exit 1
|
sed -n "s/$pattern/$replace/p" || exit 1
|
||||||
|
|
||||||
echo ${BSDECHO} "\
|
printf "%s" "
|
||||||
};\n\
|
};
|
||||||
\n\
|
|
||||||
static const int _dt_ntag = sizeof (_dt_errtags) / sizeof (_dt_errtags[0]);\n\
|
static const int _dt_ntag = sizeof (_dt_errtags) / sizeof (_dt_errtags[0]);
|
||||||
\n\
|
|
||||||
const char *
|
const char *
|
||||||
dt_errtag(dt_errtag_t tag)
|
dt_errtag(dt_errtag_t tag)
|
||||||
{
|
{
|
||||||
return (_dt_errtags[(tag > 0 && tag < _dt_ntag) ? tag : 0]);
|
return (_dt_errtags[(tag > 0 && tag < _dt_ntag) ? tag : 0]);
|
||||||
}"
|
}
|
||||||
|
"
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -24,32 +24,30 @@
|
|||||||
# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
||||||
# Use is subject to license terms.
|
# 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*/
|
/*ARGSUSED*/
|
||||||
const char *\n\
|
const char *
|
||||||
dtrace_subrstr(dtrace_hdl_t *dtp, int subr)\n\
|
dtrace_subrstr(dtrace_hdl_t *dtp, int subr)
|
||||||
{\n\
|
{
|
||||||
switch (subr) {"
|
switch (subr) {
|
||||||
|
"
|
||||||
|
|
||||||
nawk '
|
nawk '
|
||||||
/^#define[ ]*DIF_SUBR_/ && $2 != "DIF_SUBR_MAX" {
|
/^#define[ ]*DIF_SUBR_/ && $2 != "DIF_SUBR_MAX" {
|
||||||
printf("\tcase %s: return (\"%s\");\n", $2, tolower(substr($2, 10)));
|
printf("\tcase %s: return (\"%s\");\n", $2, tolower(substr($2, 10)));
|
||||||
}'
|
}'
|
||||||
|
|
||||||
echo ${BSDECHO} "\
|
printf "%s" "
|
||||||
default: return (\"unknown\");\n\
|
default: return (\"unknown\");
|
||||||
}\n\
|
}
|
||||||
}"
|
}
|
||||||
|
"
|
||||||
|
@ -24,15 +24,15 @@
|
|||||||
# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
||||||
# Use is subject to license terms.
|
# Use is subject to license terms.
|
||||||
#
|
#
|
||||||
#ident "%Z%%M% %I% %E% SMI"
|
set -e
|
||||||
|
|
||||||
echo "\
|
printf "%s" "
|
||||||
/*\n\
|
/*
|
||||||
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.\n\
|
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
||||||
* Use is subject to license terms.\n\
|
* Use is subject to license terms.
|
||||||
*/\n\
|
*/
|
||||||
\n\
|
|
||||||
#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n"
|
"
|
||||||
|
|
||||||
pattern='^#define[ ]*_*\(SIG[A-Z0-9]*\)[ ]\{1,\}\([A-Z0-9]*\).*$'
|
pattern='^#define[ ]*_*\(SIG[A-Z0-9]*\)[ ]\{1,\}\([A-Z0-9]*\).*$'
|
||||||
replace='inline int \1 = \2;@#pragma D binding "1.0" \1'
|
replace='inline int \1 = \2;@#pragma D binding "1.0" \1'
|
||||||
|
@ -68,6 +68,8 @@
|
|||||||
..
|
..
|
||||||
engines
|
engines
|
||||||
..
|
..
|
||||||
|
flua
|
||||||
|
..
|
||||||
i18n
|
i18n
|
||||||
..
|
..
|
||||||
libxo
|
libxo
|
||||||
@ -370,6 +372,8 @@
|
|||||||
..
|
..
|
||||||
firmware
|
firmware
|
||||||
..
|
..
|
||||||
|
flua
|
||||||
|
..
|
||||||
games
|
games
|
||||||
fortune
|
fortune
|
||||||
..
|
..
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
|
|
||||||
SUBDIR= libbsnmp
|
SUBDIR= libbsnmp
|
||||||
|
SUBDIR.${MK_TESTS}+= tests
|
||||||
|
|
||||||
.include <bsd.subdir.mk>
|
.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 \
|
recvmmsg.c \
|
||||||
rewinddir.c \
|
rewinddir.c \
|
||||||
scandir.c \
|
scandir.c \
|
||||||
|
scandir_b.c \
|
||||||
scandir-compat11.c \
|
scandir-compat11.c \
|
||||||
seed48.c \
|
seed48.c \
|
||||||
seekdir.c \
|
seekdir.c \
|
||||||
|
@ -416,7 +416,6 @@ FBSD_1.5 {
|
|||||||
readdir;
|
readdir;
|
||||||
readdir_r;
|
readdir_r;
|
||||||
scandir;
|
scandir;
|
||||||
scandir_b;
|
|
||||||
sem_clockwait_np;
|
sem_clockwait_np;
|
||||||
setproctitle_fast;
|
setproctitle_fast;
|
||||||
timespec_get;
|
timespec_get;
|
||||||
@ -424,6 +423,7 @@ FBSD_1.5 {
|
|||||||
|
|
||||||
FBSD_1.6 {
|
FBSD_1.6 {
|
||||||
memalign;
|
memalign;
|
||||||
|
scandir_b;
|
||||||
sigandset;
|
sigandset;
|
||||||
sigisemptyset;
|
sigisemptyset;
|
||||||
sigorset;
|
sigorset;
|
||||||
|
@ -49,32 +49,25 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include "gen-compat.h"
|
#include "gen-compat.h"
|
||||||
|
|
||||||
#ifdef I_AM_SCANDIR_B
|
/*
|
||||||
#include "block_abi.h"
|
* scandir_b@FBSD_1.4 was never exported from libc.so.7 due to a
|
||||||
#define SELECT(x) CALL_BLOCK(select, x)
|
* mistake, so there is no use of exporting it now with some earlier
|
||||||
#ifndef __BLOCKS__
|
* symbol version. As result, we do not need to implement compat
|
||||||
void
|
* function freebsd11_scandir_b().
|
||||||
qsort_b(void *, size_t, size_t, void*);
|
*/
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define SELECT(x) select(x)
|
#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,
|
static int freebsd11_alphasort_thunk(void *thunk, const void *p1,
|
||||||
const void *p2);
|
const void *p2);
|
||||||
|
|
||||||
int
|
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,
|
freebsd11_scandir(const char *dirname, struct freebsd11_dirent ***namelist,
|
||||||
int (*select)(const struct freebsd11_dirent *),
|
int (*select)(const struct freebsd11_dirent *),
|
||||||
int (*dcomp)(const struct freebsd11_dirent **,
|
int (*dcomp)(const struct freebsd11_dirent **,
|
||||||
const struct freebsd11_dirent **))
|
const struct freebsd11_dirent **))
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
struct freebsd11_dirent *d, *p, **names = NULL;
|
struct freebsd11_dirent *d, *p, **names = NULL;
|
||||||
size_t arraysz, numitems;
|
size_t arraysz, numitems;
|
||||||
@ -124,13 +117,8 @@ freebsd11_scandir(const char *dirname, struct freebsd11_dirent ***namelist,
|
|||||||
}
|
}
|
||||||
closedir(dirp);
|
closedir(dirp);
|
||||||
if (numitems && dcomp != NULL)
|
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 *),
|
qsort_r(names, numitems, sizeof(struct freebsd11_dirent *),
|
||||||
&dcomp, freebsd11_alphasort_thunk);
|
&dcomp, freebsd11_alphasort_thunk);
|
||||||
#endif
|
|
||||||
*namelist = names;
|
*namelist = names;
|
||||||
return (numitems);
|
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(alphasort, freebsd11_alphasort, FBSD_1.0);
|
||||||
__sym_compat(scandir, freebsd11_scandir, 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"
|
#include "block_abi.h"
|
||||||
#define SELECT(x) CALL_BLOCK(select, x)
|
#define SELECT(x) CALL_BLOCK(select, x)
|
||||||
#ifndef __BLOCKS__
|
#ifndef __BLOCKS__
|
||||||
void
|
void qsort_b(void *, size_t, size_t, void *);
|
||||||
qsort_b(void *, size_t, size_t, void*);
|
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define SELECT(x) select(x)
|
#define SELECT(x) select(x)
|
||||||
@ -134,6 +133,7 @@ scandir(const char *dirname, struct dirent ***namelist,
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef I_AM_SCANDIR_B
|
||||||
/*
|
/*
|
||||||
* Alphabetic order comparison routine for those who want it.
|
* Alphabetic order comparison routine for those who want it.
|
||||||
* POSIX 2008 requires that alphasort() uses strcoll().
|
* 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;
|
dc = *(int (**)(const struct dirent **, const struct dirent **))thunk;
|
||||||
return (dc((const struct dirent **)p1, (const struct dirent **)p2));
|
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); \
|
if (__isthreaded) _pthread_mutex_unlock(&syslog_mutex); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
/* RFC5424 defined value. */
|
||||||
|
#define NILVALUE "-"
|
||||||
|
|
||||||
static void disconnectlog(void); /* disconnect from syslogd */
|
static void disconnectlog(void); /* disconnect from syslogd */
|
||||||
static void connectlog(void); /* (re)connect to syslogd */
|
static void connectlog(void); /* (re)connect to syslogd */
|
||||||
static void openlog_unlocked(const char *, int, int);
|
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,
|
tm.tm_hour, tm.tm_min, tm.tm_sec, now.tv_usec,
|
||||||
tz_sign, tz_offset / 3600, (tz_offset % 3600) / 60);
|
tz_sign, tz_offset / 3600, (tz_offset % 3600) / 60);
|
||||||
} else
|
} else
|
||||||
(void)fprintf(fp, "- ");
|
(void)fputs(NILVALUE " ", fp);
|
||||||
/* Hostname. */
|
/* Hostname. */
|
||||||
(void)gethostname(hostname, sizeof(hostname));
|
(void)gethostname(hostname, sizeof(hostname));
|
||||||
(void)fprintf(fp, "%s ", hostname);
|
(void)fprintf(fp, "%s ",
|
||||||
|
hostname[0] == '\0' ? NILVALUE : hostname);
|
||||||
if (LogStat & LOG_PERROR) {
|
if (LogStat & LOG_PERROR) {
|
||||||
/* Transfer to string buffer */
|
/* Transfer to string buffer */
|
||||||
(void)fflush(fp);
|
(void)fflush(fp);
|
||||||
stdp = tbuf + (sizeof(tbuf) - tbuf_cookie.left);
|
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
|
* Provide the process ID regardless of whether LOG_PID has been
|
||||||
* specified, as it provides valuable information. Many
|
* specified, as it provides valuable information. Many
|
||||||
* applications tend not to use this, even though they should.
|
* applications tend not to use this, even though they should.
|
||||||
*/
|
*/
|
||||||
if (LogTag == NULL)
|
(void)fprintf(fp, "%d ", getpid());
|
||||||
LogTag = _getprogname();
|
/* Message ID. */
|
||||||
(void)fprintf(fp, "%s %d - - ",
|
(void)fputs(NILVALUE " ", fp);
|
||||||
LogTag == NULL ? "-" : LogTag, getpid());
|
/* Structured data. */
|
||||||
|
(void)fputs(NILVALUE " ", fp);
|
||||||
|
|
||||||
/* Check to see if we can skip expanding the %m */
|
/* Check to see if we can skip expanding the %m */
|
||||||
if (strstr(fmt, "%m")) {
|
if (strstr(fmt, "%m")) {
|
||||||
@ -251,6 +259,7 @@ vsyslog1(int pri, const char *fmt, va_list ap)
|
|||||||
fmt = fmt_cpy;
|
fmt = fmt_cpy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Message. */
|
||||||
(void)vfprintf(fp, fmt, ap);
|
(void)vfprintf(fp, fmt, ap);
|
||||||
(void)fclose(fp);
|
(void)fclose(fp);
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ CFLAGS+= -DLUA_PROGNAME="\"${PROG}\""
|
|||||||
.if defined(BOOTSTRAPPING)
|
.if defined(BOOTSTRAPPING)
|
||||||
CFLAGS+= -DLUA_PATH_DEFAULT="\"/nonexistent/?.lua\""
|
CFLAGS+= -DLUA_PATH_DEFAULT="\"/nonexistent/?.lua\""
|
||||||
CFLAGS+= -DLUA_CPATH_DEFAULT="\"/nonexistent/?.so\""
|
CFLAGS+= -DLUA_CPATH_DEFAULT="\"/nonexistent/?.so\""
|
||||||
|
# We don't support dynamic libs on bootstrap builds.
|
||||||
|
CFLAGS+= -DBOOTSTRAPPING
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.include <bsd.lib.mk>
|
.include <bsd.lib.mk>
|
||||||
|
@ -75,6 +75,9 @@
|
|||||||
/* Local modifications: need io.popen */
|
/* Local modifications: need io.popen */
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
#define LUA_USE_POSIX
|
#define LUA_USE_POSIX
|
||||||
|
#ifndef BOOTSTRAPPING
|
||||||
|
#define LUA_USE_DLOPEN
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -205,9 +208,9 @@
|
|||||||
|
|
||||||
#else /* }{ */
|
#else /* }{ */
|
||||||
|
|
||||||
#define LUA_ROOT "/usr/local/"
|
#define LUA_ROOT "/usr/"
|
||||||
#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/"
|
#define LUA_LDIR LUA_ROOT "share/flua/"
|
||||||
#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/"
|
#define LUA_CDIR LUA_ROOT "lib/flua/"
|
||||||
#if !defined(LUA_PATH_DEFAULT)
|
#if !defined(LUA_PATH_DEFAULT)
|
||||||
#define LUA_PATH_DEFAULT \
|
#define LUA_PATH_DEFAULT \
|
||||||
LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
|
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()
|
__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...)
|
* 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_a9, ARMV7, PMC_CLASS_SOFT, PMC_CLASS_ARMV7);
|
||||||
PMC_MDEP_TABLE(cortex_a53, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8);
|
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_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(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K);
|
||||||
PMC_MDEP_TABLE(mips74k, MIPS74K, PMC_CLASS_SOFT, PMC_CLASS_MIPS74K);
|
PMC_MDEP_TABLE(mips74k, MIPS74K, PMC_CLASS_SOFT, PMC_CLASS_MIPS74K);
|
||||||
PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON);
|
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__)
|
#if defined(__aarch64__)
|
||||||
PMC_CLASS_TABLE_DESC(cortex_a53, ARMV8, cortex_a53, arm64);
|
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_a57, ARMV8, cortex_a57, arm64);
|
||||||
|
PMC_CLASS_TABLE_DESC(cortex_a76, ARMV8, cortex_a76, arm64);
|
||||||
#endif
|
#endif
|
||||||
#if defined(__mips__)
|
#if defined(__mips__)
|
||||||
PMC_CLASS_TABLE_DESC(beri, BERI, beri, 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[] = {
|
static struct pmc_event_alias cortex_a57_aliases[] = {
|
||||||
EV_ALIAS(NULL, NULL)
|
EV_ALIAS(NULL, NULL)
|
||||||
};
|
};
|
||||||
|
static struct pmc_event_alias cortex_a76_aliases[] = {
|
||||||
|
EV_ALIAS(NULL, NULL)
|
||||||
|
};
|
||||||
static int
|
static int
|
||||||
arm64_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
|
arm64_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
|
||||||
struct pmc_op_pmcallocate *pmc_config __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;
|
ev = cortex_a57_event_table;
|
||||||
count = PMC_EVENT_TABLE_SIZE(cortex_a57);
|
count = PMC_EVENT_TABLE_SIZE(cortex_a57);
|
||||||
break;
|
break;
|
||||||
|
case PMC_CPU_ARMV8_CORTEX_A76:
|
||||||
|
ev = cortex_a76_event_table;
|
||||||
|
count = PMC_EVENT_TABLE_SIZE(cortex_a76);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PMC_CLASS_BERI:
|
case PMC_CLASS_BERI:
|
||||||
@ -1518,6 +1532,10 @@ pmc_init(void)
|
|||||||
PMC_MDEP_INIT(cortex_a57);
|
PMC_MDEP_INIT(cortex_a57);
|
||||||
pmc_class_table[n] = &cortex_a57_class_table_descr;
|
pmc_class_table[n] = &cortex_a57_class_table_descr;
|
||||||
break;
|
break;
|
||||||
|
case PMC_CPU_ARMV8_CORTEX_A76:
|
||||||
|
PMC_MDEP_INIT(cortex_a76);
|
||||||
|
pmc_class_table[n] = &cortex_a76_class_table_descr;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if defined(__mips__)
|
#if defined(__mips__)
|
||||||
case PMC_CPU_MIPS_BERI:
|
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;
|
ev = cortex_a57_event_table;
|
||||||
evfence = cortex_a57_event_table + PMC_EVENT_TABLE_SIZE(cortex_a57);
|
evfence = cortex_a57_event_table + PMC_EVENT_TABLE_SIZE(cortex_a57);
|
||||||
break;
|
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. */
|
default: /* Unknown CPU type. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ CFLAGS+= -DLUA_PROGNAME="\"${PROG}\""
|
|||||||
CFLAGS+= -DLUA_USE_READLINE
|
CFLAGS+= -DLUA_USE_READLINE
|
||||||
CFLAGS+= -I${SRCTOP}/lib/libedit -I${SRCTOP}/contrib/libedit
|
CFLAGS+= -I${SRCTOP}/lib/libedit -I${SRCTOP}/contrib/libedit
|
||||||
LIBADD+= edit
|
LIBADD+= edit
|
||||||
|
LDFLAGS+= -Wl,-E
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
UCLSRC?= ${SRCTOP}/contrib/libucl
|
UCLSRC?= ${SRCTOP}/contrib/libucl
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
# PROVIDE: ipfilter
|
# PROVIDE: ipfilter
|
||||||
# REQUIRE: FILESYSTEMS
|
# REQUIRE: FILESYSTEMS
|
||||||
|
# BEFORE: ipmon ipnat netif netwait securelevel
|
||||||
# KEYWORD: nojailvnet
|
# KEYWORD: nojailvnet
|
||||||
|
|
||||||
. /etc/rc.subr
|
. /etc/rc.subr
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
# PROVIDE: ipmon
|
# PROVIDE: ipmon
|
||||||
# REQUIRE: FILESYSTEMS hostname sysctl ipfilter
|
# REQUIRE: FILESYSTEMS hostname sysctl
|
||||||
# BEFORE: SERVERS
|
# BEFORE: SERVERS
|
||||||
# KEYWORD: nojailvnet
|
# KEYWORD: nojailvnet
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
# PROVIDE: ipnat
|
# PROVIDE: ipnat
|
||||||
# REQUIRE: ipfilter
|
|
||||||
# KEYWORD: nojailvnet
|
# KEYWORD: nojailvnet
|
||||||
|
|
||||||
. /etc/rc.subr
|
. /etc/rc.subr
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
# PROVIDE: netif
|
# PROVIDE: netif
|
||||||
# REQUIRE: FILESYSTEMS iovctl serial sppp sysctl
|
# REQUIRE: FILESYSTEMS iovctl serial sppp sysctl
|
||||||
# REQUIRE: hostid ipfilter ipfs
|
# REQUIRE: hostid ipfs
|
||||||
# KEYWORD: nojailvnet
|
# KEYWORD: nojailvnet
|
||||||
|
|
||||||
. /etc/rc.subr
|
. /etc/rc.subr
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
# PROVIDE: netwait
|
# PROVIDE: netwait
|
||||||
# REQUIRE: devd ipfilter ipfw pf routing
|
# REQUIRE: devd ipfw pf routing
|
||||||
# KEYWORD: nojail
|
# KEYWORD: nojail
|
||||||
#
|
#
|
||||||
# The netwait script helps handle two situations:
|
# The netwait script helps handle two situations:
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
# PROVIDE: securelevel
|
# PROVIDE: securelevel
|
||||||
# REQUIRE: adjkerntz ipfw ipfilter pf
|
# REQUIRE: adjkerntz ipfw pf
|
||||||
|
|
||||||
. /etc/rc.subr
|
. /etc/rc.subr
|
||||||
|
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
name = "FreeBSD-%PKGNAME%"
|
name = "%PKG_NAME_PREFIX%-%PKGNAME%"
|
||||||
origin = "base"
|
origin = "base"
|
||||||
version = "%VERSION%"
|
version = "%VERSION%"
|
||||||
comment = "%COMMENT%"
|
comment = "%COMMENT%"
|
||||||
categories = [ base ]
|
categories = [ base ]
|
||||||
maintainer = "re@FreeBSD.org"
|
maintainer = "%PKG_MAINTAINER%"
|
||||||
www = "https://www.FreeBSD.org"
|
www = "%PKG_WWW%"
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
licenselogic = "single"
|
licenselogic = "single"
|
||||||
licenses = [ GPLv2 ]
|
licenses = [ GPLv2 ]
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
name = "FreeBSD-%PKGNAME%"
|
name = "%PKG_NAME_PREFIX%-%PKGNAME%"
|
||||||
origin = "base"
|
origin = "base"
|
||||||
version = "%VERSION%"
|
version = "%VERSION%"
|
||||||
comment = "%COMMENT%"
|
comment = "%COMMENT%"
|
||||||
categories = [ base ]
|
categories = [ base ]
|
||||||
maintainer = "re@FreeBSD.org"
|
maintainer = %PKG_MAINTAINER%
|
||||||
www = "https://www.FreeBSD.org"
|
www = "%PKG_WWW%"
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
licenselogic = "single"
|
licenselogic = "single"
|
||||||
licenses = [ BSD2CLAUSE ]
|
licenses = [ BSD2CLAUSE ]
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
name = "FreeBSD-%PKGNAME%"
|
name = "%PKG_NAME_PREFIX%-%PKGNAME%"
|
||||||
origin = "base"
|
origin = "base"
|
||||||
version = "%VERSION%"
|
version = "%VERSION%"
|
||||||
comment = "%COMMENT%"
|
comment = "%COMMENT%"
|
||||||
categories = [ base ]
|
categories = [ base ]
|
||||||
maintainer = "re@FreeBSD.org"
|
maintainer = "%PKG_MAINTAINER%"
|
||||||
www = "https://www.FreeBSD.org"
|
www = "%PKG_WWW%"
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
licenselogic = "single"
|
licenselogic = "single"
|
||||||
licenses = [ NCSA ]
|
licenses = [ NCSA ]
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
name = "FreeBSD-%PKGNAME%"
|
name = "%PKG_NAME_PREFIX%-%PKGNAME%"
|
||||||
origin = "base"
|
origin = "base"
|
||||||
version = "%VERSION%"
|
version = "%VERSION%"
|
||||||
comment = "%COMMENT%"
|
comment = "%COMMENT%"
|
||||||
categories = [ base ]
|
categories = [ base ]
|
||||||
maintainer = "re@FreeBSD.org"
|
maintainer = "%PKG_MAINTAINER%"
|
||||||
www = "https://www.FreeBSD.org"
|
www = "%PKG_WWW%"
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
licenselogic = "single"
|
licenselogic = "single"
|
||||||
licenses = [ GPLv2 ]
|
licenses = [ GPLv2 ]
|
||||||
|
@ -146,6 +146,9 @@ EOF
|
|||||||
-e "s/%COMMENT%/${comment}/" \
|
-e "s/%COMMENT%/${comment}/" \
|
||||||
-e "s/%DESC%/${desc}/" \
|
-e "s/%DESC%/${desc}/" \
|
||||||
-e "s/%CAP_MKDB_ENDIAN%/${cap_arg}/g" \
|
-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}
|
${uclfile}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
name = "FreeBSD-%PKGNAME%"
|
name = "%PKG_NAME_PREFIX%-%PKGNAME%"
|
||||||
origin = "base"
|
origin = "base"
|
||||||
version = "%VERSION%"
|
version = "%VERSION%"
|
||||||
comment = "%COMMENT%"
|
comment = "%COMMENT%"
|
||||||
categories = [ base ]
|
categories = [ base ]
|
||||||
maintainer = "re@FreeBSD.org"
|
maintainer = "%PKG_MAINTAINER%"
|
||||||
www = "https://www.FreeBSD.org"
|
www = "%PKG_WWW%"
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
licenselogic = "single"
|
licenselogic = "single"
|
||||||
licenses = [ GPLv2 ]
|
licenses = [ GPLv2 ]
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
name = "FreeBSD-%PKGNAME%"
|
name = "%PKG_NAME_PREFIX%-%PKGNAME%"
|
||||||
origin = "base"
|
origin = "base"
|
||||||
version = "%VERSION%"
|
version = "%VERSION%"
|
||||||
comment = "%COMMENT%"
|
comment = "%COMMENT%"
|
||||||
categories = [ base ]
|
categories = [ base ]
|
||||||
maintainer = "re@FreeBSD.org"
|
maintainer = "%PKG_MAINTAINER%"
|
||||||
www = "https://www.FreeBSD.org"
|
www = "%PKG_WWW%"
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
vital = true
|
vital = true
|
||||||
licenselogic = "single"
|
licenselogic = "single"
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
name = "FreeBSD-%PKGNAME%"
|
name = "%PKG_NAME_PREFIX%-%PKGNAME%"
|
||||||
origin = "base"
|
origin = "base"
|
||||||
version = "%VERSION%"
|
version = "%VERSION%"
|
||||||
comment = "%COMMENT%"
|
comment = "%COMMENT%"
|
||||||
categories = [ base ]
|
categories = [ base ]
|
||||||
maintainer = "re@FreeBSD.org"
|
maintainer = "%PKG_MAINTAINER%"
|
||||||
www = "https://www.FreeBSD.org"
|
www = "%PKG_WWW%"
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
licenselogic = "single"
|
licenselogic = "single"
|
||||||
licenses = [ BSD2CLAUSE ]
|
licenses = [ BSD2CLAUSE ]
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
name = "FreeBSD-%PKGNAME%"
|
name = "%PKG_NAME_PREFIX%-%PKGNAME%"
|
||||||
origin = "base"
|
origin = "base"
|
||||||
version = "%VERSION%"
|
version = "%VERSION%"
|
||||||
comment = "%COMMENT%"
|
comment = "%COMMENT%"
|
||||||
categories = [ base ]
|
categories = [ base ]
|
||||||
maintainer = "re@FreeBSD.org"
|
maintainer = "%PKG_MAINTAINER%"
|
||||||
www = "https://www.FreeBSD.org"
|
www = "%PKG_WWW%"
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
licenselogic = "single"
|
licenselogic = "single"
|
||||||
licenses = [ NCSA ]
|
licenses = [ NCSA ]
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
name = "FreeBSD-%PKGNAME%"
|
name = "%PKG_NAME_PREFIX%-%PKGNAME%"
|
||||||
origin = "base"
|
origin = "base"
|
||||||
version = "%VERSION%"
|
version = "%VERSION%"
|
||||||
comment = "%COMMENT%"
|
comment = "%COMMENT%"
|
||||||
categories = [ base ]
|
categories = [ base ]
|
||||||
maintainer = "re@FreeBSD.org"
|
maintainer = "%PKG_MAINTAINER%"
|
||||||
www = "https://www.FreeBSD.org"
|
www = "%PKG_WWW%"
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
licenselogic = "single"
|
licenselogic = "single"
|
||||||
licenses = [ NCSA ]
|
licenses = [ NCSA ]
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
name = "FreeBSD-%PKGNAME%"
|
name = "%PKG_NAME_PREFIX%-%PKGNAME%"
|
||||||
origin = "base"
|
origin = "base"
|
||||||
version = "%VERSION%"
|
version = "%VERSION%"
|
||||||
comment = "%COMMENT%"
|
comment = "%COMMENT%"
|
||||||
categories = [ base ]
|
categories = [ base ]
|
||||||
maintainer = "re@FreeBSD.org"
|
maintainer = "%PKG_MAINTAINER%"
|
||||||
www = "https://www.FreeBSD.org"
|
www = "%PKG_WWW%"
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
vital = true
|
vital = true
|
||||||
licenselogic = "single"
|
licenselogic = "single"
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
name = "FreeBSD-%PKGNAME%"
|
name = "%PKG_NAME_PREFIX%-%PKGNAME%"
|
||||||
origin = "base"
|
origin = "base"
|
||||||
version = "%VERSION%"
|
version = "%VERSION%"
|
||||||
comment = "%COMMENT%"
|
comment = "%COMMENT%"
|
||||||
categories = [ base ]
|
categories = [ base ]
|
||||||
maintainer = "re@FreeBSD.org"
|
maintainer = "%PKG_MAINTAINER%"
|
||||||
www = "https://www.FreeBSD.org"
|
www = "%PKG_WWW%"
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
licenselogic = "single"
|
licenselogic = "single"
|
||||||
licenses = [ ISCL ]
|
licenses = [ ISCL ]
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
name = "FreeBSD-%PKGNAME%"
|
name = "%PKG_NAME_PREFIX%-%PKGNAME%"
|
||||||
origin = "base"
|
origin = "base"
|
||||||
version = "%VERSION%"
|
version = "%VERSION%"
|
||||||
comment = "%COMMENT%"
|
comment = "%COMMENT%"
|
||||||
categories = [ base ]
|
categories = [ base ]
|
||||||
maintainer = "re@FreeBSD.org"
|
maintainer = "%PKG_MAINTAINER%"
|
||||||
www = "https://www.FreeBSD.org"
|
www = "%PKG_WWW%"
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
licenselogic = "single"
|
licenselogic = "single"
|
||||||
licenses = [ APACHE20 ]
|
licenses = [ APACHE20 ]
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
name = "FreeBSD-%PKGNAME%"
|
name = "%PKG_NAME_PREFIX%-%PKGNAME%"
|
||||||
origin = "base"
|
origin = "base"
|
||||||
version = "%VERSION%"
|
version = "%VERSION%"
|
||||||
comment = "%COMMENT%"
|
comment = "%COMMENT%"
|
||||||
categories = [ base ]
|
categories = [ base ]
|
||||||
maintainer = "re@FreeBSD.org"
|
maintainer = "%PKG_MAINTAINER%"
|
||||||
www = "https://www.FreeBSD.org"
|
www = "%PKG_WWW%"
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
licenselogic = "single"
|
licenselogic = "single"
|
||||||
licenses = [ BSD2CLAUSE ]
|
licenses = [ BSD2CLAUSE ]
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
name = "FreeBSD-%PKGNAME%"
|
name = "%PKG_NAME_PREFIX%-%PKGNAME%"
|
||||||
origin = "base"
|
origin = "base"
|
||||||
version = "%VERSION%"
|
version = "%VERSION%"
|
||||||
comment = "%COMMENT%"
|
comment = "%COMMENT%"
|
||||||
categories = [ base ]
|
categories = [ base ]
|
||||||
maintainer = "re@FreeBSD.org"
|
maintainer = "%PKG_MAINTAINER%"
|
||||||
www = "https://www.FreeBSD.org"
|
www = "%PKG_WWW%"
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
licenselogic = "single"
|
licenselogic = "single"
|
||||||
licenses = [ BSD4CLAUSE ]
|
licenses = [ BSD4CLAUSE ]
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
name = "FreeBSD-%PKGNAME%"
|
name = "%PKG_NAME_PREFIX%-%PKGNAME%"
|
||||||
origin = "base"
|
origin = "base"
|
||||||
version = "%VERSION%"
|
version = "%VERSION%"
|
||||||
comment = "%COMMENT% %VCS_REVISION%"
|
comment = "%COMMENT% %VCS_REVISION%"
|
||||||
categories = [ base ]
|
categories = [ base ]
|
||||||
maintainer = "re@FreeBSD.org"
|
maintainer = "%PKG_MAINTAINER%"
|
||||||
www = "https://www.FreeBSD.org"
|
www = "%PKG_WWW%"
|
||||||
prefix = "/"
|
prefix = "/"
|
||||||
vital = true
|
vital = true
|
||||||
licenselogic = "single"
|
licenselogic = "single"
|
||||||
|
@ -748,6 +748,7 @@ group_member(const char *ifname, const char *match, const char *nomatch)
|
|||||||
if (nomatch)
|
if (nomatch)
|
||||||
nomatched &= fnmatch(nomatch, ifg->ifgrq_group, 0);
|
nomatched &= fnmatch(nomatch, ifg->ifgrq_group, 0);
|
||||||
}
|
}
|
||||||
|
free(ifgr.ifgr_groups);
|
||||||
|
|
||||||
if (match && !nomatch)
|
if (match && !nomatch)
|
||||||
return (matched);
|
return (matched);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd June 21, 2019
|
.Dd August 10, 2020
|
||||||
.Dt IPFW 8
|
.Dt IPFW 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -600,7 +600,7 @@ See Section
|
|||||||
By name or address
|
By name or address
|
||||||
.It Misc. IP header fields
|
.It Misc. IP header fields
|
||||||
Version, type of service, datagram length, identification,
|
Version, type of service, datagram length, identification,
|
||||||
fragment flag (non-zero IP offset),
|
fragmentation flags,
|
||||||
Time To Live
|
Time To Live
|
||||||
.It IP options
|
.It IP options
|
||||||
.It IPv6 Extension headers
|
.It IPv6 Extension headers
|
||||||
@ -1602,12 +1602,29 @@ Matches IPv6 packets containing any of the flow labels given in
|
|||||||
.Ar labels .
|
.Ar labels .
|
||||||
.Ar labels
|
.Ar labels
|
||||||
is a comma separated list of numeric flow labels.
|
is a comma separated list of numeric flow labels.
|
||||||
.It Cm frag
|
.It Cm frag Ar spec
|
||||||
Matches packets that are fragments and not the first
|
Matches IPv4 packets whose
|
||||||
fragment of an IP datagram.
|
.Cm ip_off
|
||||||
Note that these packets will not have
|
field contains the comma separated list of IPv4 fragmentation
|
||||||
the next protocol header (e.g.\& TCP, UDP) so options that look into
|
options specified in
|
||||||
these headers cannot match.
|
.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
|
.It Cm gid Ar group
|
||||||
Matches all TCP or UDP packets sent by or received for a
|
Matches all TCP or UDP packets sent by or received for a
|
||||||
.Ar group .
|
.Ar group .
|
||||||
|
@ -168,6 +168,14 @@ static struct _s_x f_iptos[] = {
|
|||||||
{ NULL, 0 }
|
{ 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[] = {
|
struct _s_x f_ipdscp[] = {
|
||||||
{ "af11", IPTOS_DSCP_AF11 >> 2 }, /* 001010 */
|
{ "af11", IPTOS_DSCP_AF11 >> 2 }, /* 001010 */
|
||||||
{ "af12", IPTOS_DSCP_AF12 >> 2 }, /* 001100 */
|
{ "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);
|
IPPROTO_ETHERTYPE, cmd->opcode);
|
||||||
break;
|
break;
|
||||||
case O_FRAG:
|
case O_FRAG:
|
||||||
bprintf(bp, " frag");
|
print_flags(bp, "frag", cmd, f_ipoff);
|
||||||
break;
|
break;
|
||||||
case O_FIB:
|
case O_FIB:
|
||||||
bprintf(bp, " fib %u", cmd->arg1);
|
bprintf(bp, " fib %u", cmd->arg1);
|
||||||
@ -4553,7 +4561,15 @@ compile_rule(char *av[], uint32_t *rbuf, int *rbufsize, struct tidx *tstate)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_FRAG:
|
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;
|
break;
|
||||||
|
|
||||||
case TOK_LAYER2:
|
case TOK_LAYER2:
|
||||||
|
@ -31,7 +31,7 @@ CFLAGS+= -I${.OBJDIR:H}/libcrypto
|
|||||||
|
|
||||||
.include <bsd.lib.mk>
|
.include <bsd.lib.mk>
|
||||||
|
|
||||||
PICFLAG+= -DOPENSS_PIC
|
PICFLAG+= -DOPENSSL_PIC
|
||||||
|
|
||||||
.PATH: ${LCRYPTO_SRC}/ssl \
|
.PATH: ${LCRYPTO_SRC}/ssl \
|
||||||
${LCRYPTO_SRC}/ssl/record \
|
${LCRYPTO_SRC}/ssl/record \
|
||||||
|
@ -113,6 +113,7 @@ MAN= aac.4 \
|
|||||||
cloudabi.4 \
|
cloudabi.4 \
|
||||||
cmx.4 \
|
cmx.4 \
|
||||||
${_coretemp.4} \
|
${_coretemp.4} \
|
||||||
|
cp2112.4 \
|
||||||
${_cpuctl.4} \
|
${_cpuctl.4} \
|
||||||
cpufreq.4 \
|
cpufreq.4 \
|
||||||
crypto.4 \
|
crypto.4 \
|
||||||
@ -171,6 +172,7 @@ MAN= aac.4 \
|
|||||||
gif.4 \
|
gif.4 \
|
||||||
gpio.4 \
|
gpio.4 \
|
||||||
gpioiic.4 \
|
gpioiic.4 \
|
||||||
|
gpiokeys.4 \
|
||||||
gpioled.4 \
|
gpioled.4 \
|
||||||
gpioths.4 \
|
gpioths.4 \
|
||||||
gre.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 \
|
printf.9 \
|
||||||
prison_check.9 \
|
prison_check.9 \
|
||||||
priv.9 \
|
priv.9 \
|
||||||
|
prng.9 \
|
||||||
proc_rwmem.9 \
|
proc_rwmem.9 \
|
||||||
pseudofs.9 \
|
pseudofs.9 \
|
||||||
psignal.9 \
|
psignal.9 \
|
||||||
@ -1745,6 +1746,10 @@ MLINKS+=printf.9 log.9 \
|
|||||||
printf.9 uprintf.9
|
printf.9 uprintf.9
|
||||||
MLINKS+=priv.9 priv_check.9 \
|
MLINKS+=priv.9 priv_check.9 \
|
||||||
priv.9 priv_check_cred.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 \
|
MLINKS+=proc_rwmem.9 proc_readmem.9 \
|
||||||
proc_rwmem.9 proc_writemem.9
|
proc_rwmem.9 proc_writemem.9
|
||||||
MLINKS+=psignal.9 gsignal.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 ${ld} == "LD" || (${ld} == "XLD" && ${XLD} != ${LD})
|
||||||
.if !defined(${X_}LINKER_TYPE) || !defined(${X_}LINKER_VERSION)
|
.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"
|
.if ${_ld_version} == "none"
|
||||||
.warning Unable to determine linker type from ${ld}=${${ld}}
|
.warning Unable to determine linker type from ${ld}=${${ld}}
|
||||||
.endif
|
.endif
|
||||||
@ -74,6 +74,17 @@ ${X_}LINKER_FREEBSD_VERSION:= ${_ld_version:[4]:C/.*-([^-]*)\)/\1/}
|
|||||||
.else
|
.else
|
||||||
${X_}LINKER_FREEBSD_VERSION= 0
|
${X_}LINKER_FREEBSD_VERSION= 0
|
||||||
.endif
|
.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
|
.else
|
||||||
.warning Unknown linker from ${ld}=${${ld}}: ${_ld_version}, defaulting to bfd
|
.warning Unknown linker from ${ld}=${${ld}}: ${_ld_version}, defaulting to bfd
|
||||||
${X_}LINKER_TYPE= bfd
|
${X_}LINKER_TYPE= bfd
|
||||||
@ -94,6 +105,9 @@ ${X_}LINKER_FEATURES+= riscv-relaxations
|
|||||||
.if ${${X_}LINKER_TYPE} == "lld" && ${${X_}LINKER_VERSION} >= 60000
|
.if ${${X_}LINKER_TYPE} == "lld" && ${${X_}LINKER_VERSION} >= 60000
|
||||||
${X_}LINKER_FEATURES+= retpoline
|
${X_}LINKER_FEATURES+= retpoline
|
||||||
.endif
|
.endif
|
||||||
|
.if ${${X_}LINKER_TYPE} == "lld" && ${${X_}LINKER_VERSION} >= 90000
|
||||||
|
${X_}LINKER_FEATURES+= ifunc-noplt
|
||||||
|
.endif
|
||||||
.endif
|
.endif
|
||||||
.else
|
.else
|
||||||
# Use LD's values
|
# Use LD's values
|
||||||
|
@ -365,6 +365,14 @@ __DEFAULT_YES_OPTIONS+=OPENMP
|
|||||||
__DEFAULT_NO_OPTIONS+=OPENMP
|
__DEFAULT_NO_OPTIONS+=OPENMP
|
||||||
.endif
|
.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>
|
.include <bsd.mkopt.mk>
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -275,6 +275,7 @@ SHELL ?= sh
|
|||||||
|
|
||||||
.if !defined(%POSIX)
|
.if !defined(%POSIX)
|
||||||
SIZE ?= size
|
SIZE ?= size
|
||||||
|
STRIPBIN ?= strip
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
YACC ?= yacc
|
YACC ?= yacc
|
||||||
|
@ -55,6 +55,8 @@ if [ -n "${include_metadata}" ]; then
|
|||||||
bootprog_info="$bootprog_info(${t} ${u}@${h})\\n"
|
bootprog_info="$bootprog_info(${t} ${u}@${h})\\n"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "char bootprog_info[] = \"$bootprog_info\";" > $tempfile
|
cat > $tempfile <<EOF
|
||||||
echo "unsigned bootprog_rev = ${r%%.*}${r##*.};" >> $tempfile
|
char bootprog_info[] = "$bootprog_info";
|
||||||
|
unsigned bootprog_rev = ${r%%.*}${r##*.};
|
||||||
|
EOF
|
||||||
mv $tempfile vers.c
|
mv $tempfile vers.c
|
||||||
|
@ -64,7 +64,7 @@ ${LOADER}: ${LOADER}.bin ${BTXLDR} ${BTXKERN}
|
|||||||
-b ${BTXKERN} ${LOADER}.bin
|
-b ${BTXKERN} ${LOADER}.bin
|
||||||
|
|
||||||
${LOADER}.bin: ${LOADER}.sym
|
${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}
|
.if ${MK_LOADER_ZFS} == "yes" && ${LOADER_INTERP} == ${LOADER_DEFAULT_INTERP}
|
||||||
LINKS+= ${BINDIR}/${LOADER} ${BINDIR}/zfsloader
|
LINKS+= ${BINDIR}/${LOADER} ${BINDIR}/zfsloader
|
||||||
|
@ -126,16 +126,21 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define AW_IR_DMAX 53
|
#define AW_IR_DMAX 53
|
||||||
|
|
||||||
/* Active Thresholds */
|
/* Active Thresholds */
|
||||||
#define AW_IR_ACTIVE_T ((0 & 0xff) << 16)
|
#define AW_IR_ACTIVE_T_VAL AW_IR_L1_MIN
|
||||||
#define AW_IR_ACTIVE_T_C ((1 & 0xff) << 23)
|
#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 */
|
/* Code masks */
|
||||||
#define CODE_MASK 0x00ff00ff
|
#define CODE_MASK 0x00ff00ff
|
||||||
#define INV_CODE_MASK 0xff00ff00
|
#define INV_CODE_MASK 0xff00ff00
|
||||||
#define VALID_CODE_MASK 0x00ff0000
|
#define VALID_CODE_MASK 0x00ff0000
|
||||||
|
|
||||||
#define A10_IR 1
|
enum {
|
||||||
#define A13_IR 2
|
A10_IR = 1,
|
||||||
|
A13_IR,
|
||||||
|
A31_IR,
|
||||||
|
};
|
||||||
|
|
||||||
#define AW_IR_RAW_BUF_SIZE 128
|
#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[] = {
|
static struct ofw_compat_data compat_data[] = {
|
||||||
{ "allwinner,sun4i-a10-ir", A10_IR },
|
{ "allwinner,sun4i-a10-ir", A10_IR },
|
||||||
{ "allwinner,sun5i-a13-ir", A13_IR },
|
{ "allwinner,sun5i-a13-ir", A13_IR },
|
||||||
|
{ "allwinner,sun6i-a31-ir", A31_IR },
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -196,24 +202,24 @@ aw_ir_read_data(struct aw_ir_softc *sc)
|
|||||||
static unsigned long
|
static unsigned long
|
||||||
aw_ir_decode_packets(struct aw_ir_softc *sc)
|
aw_ir_decode_packets(struct aw_ir_softc *sc)
|
||||||
{
|
{
|
||||||
unsigned long len, code;
|
unsigned int len, code;
|
||||||
unsigned char val, last;
|
|
||||||
unsigned int active_delay;
|
unsigned int active_delay;
|
||||||
|
unsigned char val, last;
|
||||||
int i, bitcount;
|
int i, bitcount;
|
||||||
|
|
||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
device_printf(sc->dev, "sc->dcnt = %d\n", sc->dcnt);
|
device_printf(sc->dev, "sc->dcnt = %d\n", sc->dcnt);
|
||||||
|
|
||||||
/* Find Lead 1 (bit separator) */
|
/* Find Lead 1 (bit separator) */
|
||||||
active_delay = (AW_IR_ACTIVE_T + 1) * (AW_IR_ACTIVE_T_C != 0 ? 128 : 1);
|
active_delay = AW_IR_ACTIVE_T_VAL *
|
||||||
len = 0;
|
(AW_IR_ACTIVE_T_C_VAL != 0 ? 128 : 1);
|
||||||
len += (active_delay >> 1);
|
len = active_delay;
|
||||||
if (bootverbose)
|
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++) {
|
for (i = 0; i < sc->dcnt; i++) {
|
||||||
val = sc->buf[i];
|
val = sc->buf[i];
|
||||||
if (val & VAL_MASK)
|
if (val & VAL_MASK)
|
||||||
len += val & PERIOD_MASK;
|
len += (val & PERIOD_MASK) + 1;
|
||||||
else {
|
else {
|
||||||
if (len > AW_IR_L1_MIN)
|
if (len > AW_IR_L1_MIN)
|
||||||
break;
|
break;
|
||||||
@ -221,7 +227,7 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bootverbose)
|
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 ((val & VAL_MASK) || (len <= AW_IR_L1_MIN)) {
|
||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
device_printf(sc->dev, "Bit separator error\n");
|
device_printf(sc->dev, "Bit separator error\n");
|
||||||
@ -237,7 +243,7 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
|
|||||||
break;
|
break;
|
||||||
len = 0;
|
len = 0;
|
||||||
} else
|
} else
|
||||||
len += val & PERIOD_MASK;
|
len += (val & PERIOD_MASK) + 1;
|
||||||
}
|
}
|
||||||
if ((!(val & VAL_MASK)) || (len <= AW_IR_L0_MIN)) {
|
if ((!(val & VAL_MASK)) || (len <= AW_IR_L0_MIN)) {
|
||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
@ -254,23 +260,25 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
|
|||||||
val = sc->buf[i];
|
val = sc->buf[i];
|
||||||
if (last) {
|
if (last) {
|
||||||
if (val & VAL_MASK)
|
if (val & VAL_MASK)
|
||||||
len += val & PERIOD_MASK;
|
len += (val & PERIOD_MASK) + 1;
|
||||||
else {
|
else {
|
||||||
if (len > AW_IR_PMAX) {
|
if (len > AW_IR_PMAX) {
|
||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
device_printf(sc->dev,
|
device_printf(sc->dev,
|
||||||
"Pulse error\n");
|
"Pulse error, len=%d\n",
|
||||||
|
len);
|
||||||
goto error_code;
|
goto error_code;
|
||||||
}
|
}
|
||||||
last = 0;
|
last = 0;
|
||||||
len = val & PERIOD_MASK;
|
len = (val & PERIOD_MASK) + 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (val & VAL_MASK) {
|
if (val & VAL_MASK) {
|
||||||
if (len > AW_IR_DMAX) {
|
if (len > AW_IR_DMAX) {
|
||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
device_printf(sc->dev,
|
device_printf(sc->dev,
|
||||||
"Distant error\n");
|
"Distance error, len=%d\n",
|
||||||
|
len);
|
||||||
goto error_code;
|
goto error_code;
|
||||||
} else {
|
} else {
|
||||||
if (len > AW_IR_DMID) {
|
if (len > AW_IR_DMID) {
|
||||||
@ -282,9 +290,9 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
|
|||||||
break; /* Finish decoding */
|
break; /* Finish decoding */
|
||||||
}
|
}
|
||||||
last = 1;
|
last = 1;
|
||||||
len = val & PERIOD_MASK;
|
len = (val & PERIOD_MASK) + 1;
|
||||||
} else
|
} else
|
||||||
len += val & PERIOD_MASK;
|
len += (val & PERIOD_MASK) + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (code);
|
return (code);
|
||||||
@ -364,7 +372,7 @@ aw_ir_intr(void *arg)
|
|||||||
device_printf(sc->dev, "IR code status: %d\n",
|
device_printf(sc->dev, "IR code status: %d\n",
|
||||||
stat);
|
stat);
|
||||||
}
|
}
|
||||||
sc->dcnt = 0;
|
aw_ir_buf_reset(sc);
|
||||||
}
|
}
|
||||||
if (val & AW_IR_RXINT_ROI_EN) {
|
if (val & AW_IR_RXINT_ROI_EN) {
|
||||||
/* RX FIFO overflow */
|
/* RX FIFO overflow */
|
||||||
@ -414,6 +422,7 @@ aw_ir_attach(device_t dev)
|
|||||||
sc->fifo_size = 16;
|
sc->fifo_size = 16;
|
||||||
break;
|
break;
|
||||||
case A13_IR:
|
case A13_IR:
|
||||||
|
case A31_IR:
|
||||||
sc->fifo_size = 64;
|
sc->fifo_size = 64;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -464,7 +473,8 @@ aw_ir_attach(device_t dev)
|
|||||||
&sc->intrhand)) {
|
&sc->intrhand)) {
|
||||||
bus_release_resources(dev, aw_ir_spec, sc->res);
|
bus_release_resources(dev, aw_ir_spec, sc->res);
|
||||||
device_printf(dev, "cannot setup interrupt handler\n");
|
device_printf(dev, "cannot setup interrupt handler\n");
|
||||||
return (ENXIO);
|
err = ENXIO;
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable CIR Mode */
|
/* Enable CIR Mode */
|
||||||
|
@ -857,11 +857,20 @@
|
|||||||
#define PMCR_LC (1 << 6) /* Long cycle count enable */
|
#define PMCR_LC (1 << 6) /* Long cycle count enable */
|
||||||
#define PMCR_IMP_SHIFT 24 /* Implementer code */
|
#define PMCR_IMP_SHIFT 24 /* Implementer code */
|
||||||
#define PMCR_IMP_MASK (0xff << PMCR_IMP_SHIFT)
|
#define PMCR_IMP_MASK (0xff << PMCR_IMP_SHIFT)
|
||||||
|
#define PMCR_IMP_ARM 0x41
|
||||||
#define PMCR_IDCODE_SHIFT 16 /* Identification code */
|
#define PMCR_IDCODE_SHIFT 16 /* Identification code */
|
||||||
#define PMCR_IDCODE_MASK (0xff << PMCR_IDCODE_SHIFT)
|
#define PMCR_IDCODE_MASK (0xff << PMCR_IDCODE_SHIFT)
|
||||||
#define PMCR_IDCODE_CORTEX_A57 0x01
|
#define PMCR_IDCODE_CORTEX_A57 0x01
|
||||||
#define PMCR_IDCODE_CORTEX_A72 0x02
|
#define PMCR_IDCODE_CORTEX_A72 0x02
|
||||||
#define PMCR_IDCODE_CORTEX_A53 0x03
|
#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_SHIFT 11 /* Number of counters implemented */
|
||||||
#define PMCR_N_MASK (0x1f << PMCR_N_SHIFT)
|
#define PMCR_N_MASK (0x1f << PMCR_N_SHIFT)
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
* 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
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
@ -33,94 +33,347 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/bus.h>
|
#include <sys/bus.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/module.h>
|
#include <sys/module.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#include <machine/bus.h>
|
#include <machine/bus.h>
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <net/if_media.h>
|
||||||
|
|
||||||
#include <dev/dwc/if_dwc.h>
|
#include <dev/dwc/if_dwc.h>
|
||||||
#include <dev/dwc/if_dwcvar.h>
|
#include <dev/dwc/if_dwcvar.h>
|
||||||
#include <dev/ofw/ofw_bus.h>
|
#include <dev/ofw/ofw_bus.h>
|
||||||
#include <dev/ofw/ofw_bus_subr.h>
|
#include <dev/ofw/ofw_bus_subr.h>
|
||||||
|
|
||||||
#include <dev/extres/clk/clk.h>
|
#include <dev/extres/clk/clk.h>
|
||||||
|
#include <dev/extres/hwreset/hwreset.h>
|
||||||
#include <dev/extres/regulator/regulator.h>
|
#include <dev/extres/regulator/regulator.h>
|
||||||
|
|
||||||
#include <dev/extres/syscon/syscon.h>
|
#include <dev/extres/syscon/syscon.h>
|
||||||
|
|
||||||
|
#include "if_dwc_if.h"
|
||||||
#include "syscon_if.h"
|
#include "syscon_if.h"
|
||||||
|
|
||||||
#include "if_dwc_if.h"
|
|
||||||
|
|
||||||
#define RK3328_GRF_MAC_CON0 0x0900
|
#define RK3328_GRF_MAC_CON0 0x0900
|
||||||
#define RK3328_GRF_MAC_CON0_TX_MASK 0x7F
|
#define MAC_CON0_GMAC2IO_TX_DL_CFG_MASK 0x7F
|
||||||
#define RK3328_GRF_MAC_CON0_TX_SHIFT 0
|
#define MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT 0
|
||||||
#define RK3328_GRF_MAC_CON0_RX_MASK 0x7F
|
#define MAC_CON0_GMAC2IO_RX_DL_CFG_MASK 0x7F
|
||||||
#define RK3328_GRF_MAC_CON0_RX_SHIFT 7
|
#define MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT 7
|
||||||
|
|
||||||
#define RK3328_GRF_MAC_CON1 0x0904
|
#define RK3328_GRF_MAC_CON1 0x0904
|
||||||
#define RK3328_GRF_MAC_CON1_RX_ENA (1 << 1)
|
#define MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA (1 << 0)
|
||||||
#define RK3328_GRF_MAC_CON1_TX_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_MAC_CON2 0x0908
|
||||||
#define RK3328_GRF_MACPHY_CON0 0x0B00
|
#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 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_CON2 0x0B08
|
||||||
#define RK3328_GRF_MACPHY_CON3 0x0B0C
|
#define RK3328_GRF_MACPHY_CON3 0x0B0C
|
||||||
#define RK3328_GRF_MACPHY_STATUS 0x0B10
|
#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[] = {
|
static struct ofw_compat_data compat_data[] = {
|
||||||
{"rockchip,rk3288-gmac", 1},
|
{"rockchip,rk3288-gmac", (uintptr_t)&rk3288_ops},
|
||||||
{"rockchip,rk3328-gmac", 1},
|
{"rockchip,rk3328-gmac", (uintptr_t)&rk3328_ops},
|
||||||
{"rockchip,rk3399-gmac", 1},
|
{"rockchip,rk3399-gmac", (uintptr_t)&rk3399_ops},
|
||||||
{NULL, 0}
|
{NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
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;
|
uint32_t tx, rx;
|
||||||
|
|
||||||
if (OF_getencprop(node, "tx_delay", &tx, sizeof(tx)) <= 0)
|
if (sc->base.phy_mode != PHY_MODE_RGMII)
|
||||||
tx = 0x30;
|
return;
|
||||||
if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0)
|
|
||||||
rx = 0x10;
|
|
||||||
|
|
||||||
if (bootverbose)
|
reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON0);
|
||||||
printf("setting RK3328 RX/TX delays: %d/%d\n", rx, tx);
|
tx = ((reg >> MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK);
|
||||||
tx = ((tx & RK3328_GRF_MAC_CON0_TX_MASK) <<
|
rx = ((reg >> MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_RX_DL_CFG_MASK);
|
||||||
RK3328_GRF_MAC_CON0_TX_SHIFT);
|
|
||||||
rx = ((rx & RK3328_GRF_MAC_CON0_TX_MASK) <<
|
|
||||||
RK3328_GRF_MAC_CON0_RX_SHIFT);
|
|
||||||
|
|
||||||
SYSCON_WRITE_4(grf, RK3328_GRF_MAC_CON0, tx | rx | 0xFFFF0000);
|
reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON1);
|
||||||
SYSCON_WRITE_4(grf, RK3328_GRF_MAC_CON1, RK3328_GRF_MAC_CON1_TX_ENA | RK3328_GRF_MAC_CON1_RX_ENA |
|
if (bootverbose) {
|
||||||
((RK3328_GRF_MAC_CON1_TX_ENA | RK3328_GRF_MAC_CON1_RX_ENA) << 16));
|
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
|
static int
|
||||||
#define RK3399_GRF_SOC_CON6_TX_ENA (1 << 7)
|
rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed)
|
||||||
#define RK3399_GRF_SOC_CON6_TX_MASK 0x7F
|
{
|
||||||
#define RK3399_GRF_SOC_CON6_TX_SHIFT 0
|
uint32_t reg;
|
||||||
#define RK3399_GRF_SOC_CON6_RX_MASK 0x7F
|
|
||||||
#define RK3399_GRF_SOC_CON6_RX_ENA (1 << 15)
|
switch (sc->base.phy_mode) {
|
||||||
#define RK3399_GRF_SOC_CON6_RX_SHIFT 8
|
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
|
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)
|
switch (sc->base.phy_mode) {
|
||||||
tx = 0x30;
|
case PHY_MODE_RGMII:
|
||||||
if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0)
|
SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1,
|
||||||
rx = 0x10;
|
((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)
|
static void
|
||||||
printf("setting RK3399 RX/TX delays: %d/%d\n", rx, tx);
|
rk3328_phy_powerup(struct if_dwc_rk_softc *sc)
|
||||||
tx = ((tx & RK3399_GRF_SOC_CON6_TX_MASK) <<
|
{
|
||||||
RK3399_GRF_SOC_CON6_TX_SHIFT) | RK3399_GRF_SOC_CON6_TX_ENA;
|
SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON1,
|
||||||
rx = ((rx & RK3399_GRF_SOC_CON6_TX_MASK) <<
|
(MACPHY_CON1_RMII_MODE_MASK << 16) |
|
||||||
RK3399_GRF_SOC_CON6_RX_SHIFT) | RK3399_GRF_SOC_CON6_RX_ENA;
|
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
|
static int
|
||||||
@ -136,26 +389,189 @@ if_dwc_rk_probe(device_t dev)
|
|||||||
return (BUS_PROBE_DEFAULT);
|
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
|
static int
|
||||||
if_dwc_rk_init(device_t dev)
|
if_dwc_rk_init(device_t dev)
|
||||||
{
|
{
|
||||||
|
struct if_dwc_rk_softc *sc;
|
||||||
phandle_t node;
|
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);
|
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") &&
|
if (OF_hasprop(node, "rockchip,grf") &&
|
||||||
syscon_get_by_ofw_property(dev, node,
|
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");
|
device_printf(dev, "cannot get grf driver handle\n");
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ofw_bus_is_compatible(dev, "rockchip,rk3399-gmac"))
|
if (OF_getencprop(node, "tx_delay", &tx, sizeof(tx)) <= 0)
|
||||||
rk3399_set_delays(grf, node);
|
tx = 0x30;
|
||||||
else if (ofw_bus_is_compatible(dev, "rockchip,rk3328-gmac"))
|
if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0)
|
||||||
rk3328_set_delays(grf, node);
|
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);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -175,12 +591,26 @@ if_dwc_rk_mii_clk(device_t dev)
|
|||||||
return (GMAC_MII_CLK_150_250M_DIV102);
|
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[] = {
|
static device_method_t if_dwc_rk_methods[] = {
|
||||||
DEVMETHOD(device_probe, if_dwc_rk_probe),
|
DEVMETHOD(device_probe, if_dwc_rk_probe),
|
||||||
|
|
||||||
DEVMETHOD(if_dwc_init, if_dwc_rk_init),
|
DEVMETHOD(if_dwc_init, if_dwc_rk_init),
|
||||||
DEVMETHOD(if_dwc_mac_type, if_dwc_rk_mac_type),
|
DEVMETHOD(if_dwc_mac_type, if_dwc_rk_mac_type),
|
||||||
DEVMETHOD(if_dwc_mii_clk, if_dwc_rk_mii_clk),
|
DEVMETHOD(if_dwc_mii_clk, if_dwc_rk_mii_clk),
|
||||||
|
DEVMETHOD(if_dwc_set_speed, if_dwc_rk_set_speed),
|
||||||
|
|
||||||
DEVMETHOD_END
|
DEVMETHOD_END
|
||||||
};
|
};
|
||||||
@ -190,6 +620,6 @@ static devclass_t dwc_rk_devclass;
|
|||||||
extern driver_t dwc_driver;
|
extern driver_t dwc_driver;
|
||||||
|
|
||||||
DEFINE_CLASS_1(dwc, dwc_rk_driver, if_dwc_rk_methods,
|
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);
|
DRIVER_MODULE(dwc_rk, simplebus, dwc_rk_driver, dwc_rk_devclass, 0, 0);
|
||||||
MODULE_DEPEND(dwc_rk, dwc, 1, 1, 1);
|
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;
|
disk->d_hba_subdevice = cpi.hba_subdevice;
|
||||||
snprintf(disk->d_attachment, sizeof(disk->d_attachment),
|
snprintf(disk->d_attachment, sizeof(disk->d_attachment),
|
||||||
"%s%d", cpi.dev_name, cpi.unit_number);
|
"%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_stripeoffset = 0;
|
||||||
disk->d_devstat = devstat_new_entry(periph->periph_name,
|
disk->d_devstat = devstat_new_entry(periph->periph_name,
|
||||||
periph->unit_number, disk->d_sectorsize,
|
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;
|
struct nvme_controller_data *nvme_cdata;
|
||||||
nvme_probe_softc *softc;
|
nvme_probe_softc *softc;
|
||||||
struct cam_path *path;
|
struct cam_path *path;
|
||||||
|
struct scsi_vpd_device_id *did;
|
||||||
|
struct scsi_vpd_id_descriptor *idd;
|
||||||
cam_status status;
|
cam_status status;
|
||||||
u_int32_t priority;
|
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"));
|
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));
|
bcopy(&softc->cd, nvme_cdata, sizeof(*nvme_cdata));
|
||||||
path->device->nvme_cdata = 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_find_quirk(path->device);
|
||||||
nvme_device_transport(path);
|
nvme_device_transport(path);
|
||||||
NVME_PROBE_SET_ACTION(softc, NVME_PROBE_IDENTIFY_NS);
|
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));
|
bcopy(&softc->ns, nvme_data, sizeof(*nvme_data));
|
||||||
path->device->nvme_data = 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) {
|
if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
|
||||||
path->device->flags &= ~CAM_DEV_UNCONFIGURED;
|
path->device->flags &= ~CAM_DEV_UNCONFIGURED;
|
||||||
xpt_acquire_device(path->device);
|
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->maxtags = 0;
|
||||||
device->inq_flags = 0;
|
device->inq_flags = 0;
|
||||||
device->queue_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->device_id_len = 0;
|
||||||
device->serial_num = NULL; /* XXX Need to set this somewhere */
|
device->serial_num = NULL;
|
||||||
device->serial_num_len = 0;
|
device->serial_num_len = 0;
|
||||||
return (device);
|
return (device);
|
||||||
}
|
}
|
||||||
|
@ -145,41 +145,35 @@ static int
|
|||||||
linprocfs_domeminfo(PFS_FILL_ARGS)
|
linprocfs_domeminfo(PFS_FILL_ARGS)
|
||||||
{
|
{
|
||||||
unsigned long memtotal; /* total memory in bytes */
|
unsigned long memtotal; /* total memory in bytes */
|
||||||
unsigned long memused; /* used memory in bytes */
|
|
||||||
unsigned long memfree; /* free 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 swaptotal; /* total swap space in bytes */
|
||||||
unsigned long long swapused; /* used swap space in bytes */
|
unsigned long long swapused; /* used swap space in bytes */
|
||||||
unsigned long long swapfree; /* free 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;
|
memtotal = physmem * PAGE_SIZE;
|
||||||
/*
|
memfree = (unsigned long)vm_free_count() * 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;
|
|
||||||
swap_pager_status(&i, &j);
|
swap_pager_status(&i, &j);
|
||||||
swaptotal = (unsigned long long)i * PAGE_SIZE;
|
swaptotal = (unsigned long long)i * PAGE_SIZE;
|
||||||
swapused = (unsigned long long)j * PAGE_SIZE;
|
swapused = (unsigned long long)j * PAGE_SIZE;
|
||||||
swapfree = swaptotal - swapused;
|
swapfree = swaptotal - swapused;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We'd love to be able to write:
|
* This value may exclude wired pages, but we have no good way of
|
||||||
*
|
* accounting for that.
|
||||||
buffers = bufspace;
|
|
||||||
*
|
|
||||||
* but bufspace is internal to vfs_bio.c and we don't feel
|
|
||||||
* like unstaticizing it just for linprocfs's sake.
|
|
||||||
*/
|
*/
|
||||||
buffers = 0;
|
cached =
|
||||||
cached = vm_inactive_count() * PAGE_SIZE;
|
(vm_active_count() + vm_inactive_count() + vm_laundry_count()) *
|
||||||
|
PAGE_SIZE;
|
||||||
|
|
||||||
|
sz = sizeof(buffers);
|
||||||
|
error = kernel_sysctlbyname(curthread, "vfs.bufspace", &buffers, &sz,
|
||||||
|
NULL, 0, 0, 0);
|
||||||
|
if (error != 0)
|
||||||
|
buffers = 0;
|
||||||
|
|
||||||
sbuf_printf(sb,
|
sbuf_printf(sb,
|
||||||
"MemTotal: %9lu kB\n"
|
"MemTotal: %9lu kB\n"
|
||||||
|
@ -272,16 +272,12 @@ find_next_zero_bit(const unsigned long *addr, unsigned long size,
|
|||||||
#define clear_bit(i, a) \
|
#define clear_bit(i, a) \
|
||||||
atomic_clear_long(&((volatile unsigned long *)(a))[BIT_WORD(i)], BIT_MASK(i))
|
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) \
|
#define test_bit(i, a) \
|
||||||
!!(READ_ONCE(((volatile const unsigned long *)(a))[BIT_WORD(i)]) & BIT_MASK(i))
|
!!(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
|
static inline int
|
||||||
test_and_clear_bit(long bit, volatile unsigned long *var)
|
test_and_clear_bit(long bit, volatile unsigned long *var)
|
||||||
{
|
{
|
||||||
|
@ -76,8 +76,9 @@ struct task_struct {
|
|||||||
unsigned bsd_ioctl_len;
|
unsigned bsd_ioctl_len;
|
||||||
struct completion parked;
|
struct completion parked;
|
||||||
struct completion exited;
|
struct completion exited;
|
||||||
TAILQ_ENTRY(task_struct) rcu_entry;
|
#define TS_RCU_TYPE_MAX 2
|
||||||
int rcu_recurse;
|
TAILQ_ENTRY(task_struct) rcu_entry[TS_RCU_TYPE_MAX];
|
||||||
|
int rcu_recurse[TS_RCU_TYPE_MAX];
|
||||||
int bsd_interrupt_value;
|
int bsd_interrupt_value;
|
||||||
struct work_struct *work; /* current work struct, if set */
|
struct work_struct *work; /* current work struct, if set */
|
||||||
struct task_struct *group_leader;
|
struct task_struct *group_leader;
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
|
||||||
#include <asm/atomic.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/compat.h>
|
||||||
#include <linux/poll.h>
|
#include <linux/poll.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
|
#include <linux/wait_bit.h>
|
||||||
|
|
||||||
#if defined(__i386__) || defined(__amd64__)
|
#if defined(__i386__) || defined(__amd64__)
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
@ -119,6 +120,9 @@ spinlock_t pci_lock;
|
|||||||
|
|
||||||
unsigned long linux_timer_hz_mask;
|
unsigned long linux_timer_hz_mask;
|
||||||
|
|
||||||
|
wait_queue_head_t linux_bit_waitq;
|
||||||
|
wait_queue_head_t linux_var_waitq;
|
||||||
|
|
||||||
int
|
int
|
||||||
panic_cmp(struct rb_node *one, struct rb_node *two)
|
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);
|
mtx_init(&vmmaplock, "IO Map lock", NULL, MTX_DEF);
|
||||||
for (i = 0; i < VMMAP_HASH_SIZE; i++)
|
for (i = 0; i < VMMAP_HASH_SIZE; i++)
|
||||||
LIST_INIT(&vmmaphead[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);
|
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;
|
ck_epoch_record_t epoch_record;
|
||||||
TAILQ_HEAD(, task_struct) ts_head;
|
TAILQ_HEAD(, task_struct) ts_head;
|
||||||
int cpuid;
|
int cpuid;
|
||||||
|
int type;
|
||||||
} __aligned(CACHE_LINE_SIZE);
|
} __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(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 ck_epoch_t linux_epoch[RCU_TYPE_MAX];
|
||||||
static struct linux_epoch_head linux_epoch_head[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]);
|
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 = &DPCPU_ID_GET(i, linux_epoch_record[j]);
|
||||||
|
|
||||||
record->cpuid = i;
|
record->cpuid = i;
|
||||||
|
record->type = j;
|
||||||
ck_epoch_register(&linux_epoch[j],
|
ck_epoch_register(&linux_epoch[j],
|
||||||
&record->epoch_record, NULL);
|
&record->epoch_record, NULL);
|
||||||
TAILQ_INIT(&record->ts_head);
|
TAILQ_INIT(&record->ts_head);
|
||||||
@ -201,9 +205,9 @@ linux_rcu_read_lock(unsigned type)
|
|||||||
*/
|
*/
|
||||||
critical_enter();
|
critical_enter();
|
||||||
ck_epoch_begin(&record->epoch_record, NULL);
|
ck_epoch_begin(&record->epoch_record, NULL);
|
||||||
ts->rcu_recurse++;
|
ts->rcu_recurse[type]++;
|
||||||
if (ts->rcu_recurse == 1)
|
if (ts->rcu_recurse[type] == 1)
|
||||||
TAILQ_INSERT_TAIL(&record->ts_head, ts, rcu_entry);
|
TAILQ_INSERT_TAIL(&record->ts_head, ts, rcu_entry[type]);
|
||||||
critical_exit();
|
critical_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,9 +231,9 @@ linux_rcu_read_unlock(unsigned type)
|
|||||||
*/
|
*/
|
||||||
critical_enter();
|
critical_enter();
|
||||||
ck_epoch_end(&record->epoch_record, NULL);
|
ck_epoch_end(&record->epoch_record, NULL);
|
||||||
ts->rcu_recurse--;
|
ts->rcu_recurse[type]--;
|
||||||
if (ts->rcu_recurse == 0)
|
if (ts->rcu_recurse[type] == 0)
|
||||||
TAILQ_REMOVE(&record->ts_head, ts, rcu_entry);
|
TAILQ_REMOVE(&record->ts_head, ts, rcu_entry[type]);
|
||||||
critical_exit();
|
critical_exit();
|
||||||
|
|
||||||
sched_unpin();
|
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
|
* the threads in the queue are CPU-pinned and cannot
|
||||||
* go anywhere while the current thread is locked.
|
* 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)
|
if (ts->task_thread->td_priority > prio)
|
||||||
prio = ts->task_thread->td_priority;
|
prio = ts->task_thread->td_priority;
|
||||||
is_sleeping |= (ts->task_thread->td_inhibitors != 0);
|
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_pidctrl.c standard
|
||||||
kern/subr_power.c standard
|
kern/subr_power.c standard
|
||||||
kern/subr_prf.c standard
|
kern/subr_prf.c standard
|
||||||
|
kern/subr_prng.c standard
|
||||||
kern/subr_prof.c standard
|
kern/subr_prof.c standard
|
||||||
kern/subr_rangeset.c standard
|
kern/subr_rangeset.c standard
|
||||||
kern/subr_rman.c standard
|
kern/subr_rman.c standard
|
||||||
|
@ -166,9 +166,13 @@ LDFLAGS+= -z max-page-size=2097152
|
|||||||
.if ${LINKER_TYPE} != "lld"
|
.if ${LINKER_TYPE} != "lld"
|
||||||
LDFLAGS+= -z common-page-size=4096
|
LDFLAGS+= -z common-page-size=4096
|
||||||
.else
|
.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
|
LDFLAGS+= -z notext -z ifunc-noplt
|
||||||
.endif
|
.endif
|
||||||
.endif
|
.endif
|
||||||
|
.endif # ${MACHINE_CPUARCH} == "amd64"
|
||||||
|
|
||||||
.if ${MACHINE_CPUARCH} == "riscv"
|
.if ${MACHINE_CPUARCH} == "riscv"
|
||||||
# Hack: Work around undefined weak symbols being out of range when linking with
|
# Hack: Work around undefined weak symbols being out of range when linking with
|
||||||
|
@ -36,22 +36,16 @@
|
|||||||
#ifndef PCG_VARIANTS_H_INCLUDED
|
#ifndef PCG_VARIANTS_H_INCLUDED
|
||||||
#define PCG_VARIANTS_H_INCLUDED 1
|
#define PCG_VARIANTS_H_INCLUDED 1
|
||||||
|
|
||||||
#include <inttypes.h>
|
#if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__
|
||||||
|
|
||||||
#if __SIZEOF_INT128__
|
|
||||||
typedef __uint128_t pcg128_t;
|
typedef __uint128_t pcg128_t;
|
||||||
#define PCG_128BIT_CONSTANT(high,low) \
|
#define PCG_128BIT_CONSTANT(high,low) \
|
||||||
((((pcg128_t)high) << 64) + low)
|
((((pcg128_t)high) << 64) + low)
|
||||||
#define PCG_HAS_128BIT_OPS 1
|
#define PCG_HAS_128BIT_OPS 1
|
||||||
|
#else
|
||||||
|
#define PCG_HAS_128BIT_OPS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __GNUC_GNU_INLINE__ && !defined(__cplusplus)
|
#ifdef __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
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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
|
* recognizing idiomatic rotate code, so for clang we actually provide
|
||||||
* assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss.
|
* assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss.
|
||||||
*/
|
*/
|
||||||
#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__)
|
#if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
|
||||||
asm ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
|
__asm__ ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
|
||||||
return value;
|
return value;
|
||||||
#else
|
#else
|
||||||
return (value >> rot) | (value << ((- rot) & 7));
|
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)
|
inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot)
|
||||||
{
|
{
|
||||||
#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__)
|
#if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
|
||||||
asm ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
|
__asm__ ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
|
||||||
return value;
|
return value;
|
||||||
#else
|
#else
|
||||||
return (value >> rot) | (value << ((- rot) & 15));
|
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)
|
inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot)
|
||||||
{
|
{
|
||||||
#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__)
|
#if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
|
||||||
asm ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
|
__asm__ ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
|
||||||
return value;
|
return value;
|
||||||
#else
|
#else
|
||||||
return (value >> rot) | (value << ((- rot) & 31));
|
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)
|
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
|
/* For whatever reason, clang actually *does* generate rotq by
|
||||||
itself, so we don't need this code. */
|
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;
|
return value;
|
||||||
#else
|
#else
|
||||||
return (value >> rot) | (value << ((- rot) & 63));
|
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
|
#define pcg128i_advance_r pcg_setseq_128_advance_r
|
||||||
#endif
|
#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
|
* Static initialization constants (if you can't call srandom for some
|
||||||
* bizarre reason).
|
* bizarre reason).
|
||||||
@ -2536,7 +2518,7 @@ extern void pcg64_advance(pcg128_t delta);
|
|||||||
#define PCG128I_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER
|
#define PCG128I_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1209,14 +1209,23 @@ dwc_clock_init(device_t dev)
|
|||||||
hwreset_t rst;
|
hwreset_t rst;
|
||||||
clk_t clk;
|
clk_t clk;
|
||||||
int error;
|
int error;
|
||||||
|
int64_t freq;
|
||||||
|
|
||||||
/* Enable clock */
|
/* Enable clocks */
|
||||||
if (clk_get_by_ofw_name(dev, 0, "stmmaceth", &clk) == 0) {
|
if (clk_get_by_ofw_name(dev, 0, "stmmaceth", &clk) == 0) {
|
||||||
error = clk_enable(clk);
|
error = clk_enable(clk);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
device_printf(dev, "could not enable main clock\n");
|
device_printf(dev, "could not enable main clock\n");
|
||||||
return (error);
|
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 */
|
/* De-assert reset */
|
||||||
@ -1254,6 +1263,8 @@ dwc_attach(device_t dev)
|
|||||||
struct ifnet *ifp;
|
struct ifnet *ifp;
|
||||||
int error, i;
|
int error, i;
|
||||||
uint32_t reg;
|
uint32_t reg;
|
||||||
|
char *phy_mode;
|
||||||
|
phandle_t node;
|
||||||
|
|
||||||
sc = device_get_softc(dev);
|
sc = device_get_softc(dev);
|
||||||
sc->dev = dev;
|
sc->dev = dev;
|
||||||
@ -1262,6 +1273,15 @@ dwc_attach(device_t dev)
|
|||||||
sc->mii_clk = IF_DWC_MII_CLK(dev);
|
sc->mii_clk = IF_DWC_MII_CLK(dev);
|
||||||
sc->mactype = IF_DWC_MAC_TYPE(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)
|
if (IF_DWC_INIT(dev) != 0)
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
|
|
||||||
@ -1475,6 +1495,9 @@ dwc_miibus_statchg(device_t dev)
|
|||||||
else
|
else
|
||||||
reg &= ~(CONF_DM);
|
reg &= ~(CONF_DM);
|
||||||
WRITE4(sc, MAC_CONFIGURATION, reg);
|
WRITE4(sc, MAC_CONFIGURATION, reg);
|
||||||
|
|
||||||
|
IF_DWC_SET_SPEED(dev, IFM_SUBTYPE(mii->mii_media_active));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static device_method_t dwc_methods[] = {
|
static device_method_t dwc_methods[] = {
|
||||||
|
@ -37,6 +37,10 @@
|
|||||||
#ifndef __IF_DWC_H__
|
#ifndef __IF_DWC_H__
|
||||||
#define __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 MAC_CONFIGURATION 0x0
|
||||||
#define CONF_JD (1 << 22) /* jabber timer disable */
|
#define CONF_JD (1 << 22) /* jabber timer disable */
|
||||||
#define CONF_BE (1 << 21) /* Frame Burst Enable */
|
#define CONF_BE (1 << 21) /* Frame Burst Enable */
|
||||||
|
@ -49,6 +49,12 @@ CODE {
|
|||||||
{
|
{
|
||||||
return (GMAC_MII_CLK_25_35M_DIV16);
|
return (GMAC_MII_CLK_25_35M_DIV16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
if_dwc_default_set_speed(device_t dev, int speed)
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
HEADER {
|
HEADER {
|
||||||
@ -74,3 +80,11 @@ METHOD int mac_type {
|
|||||||
METHOD int mii_clk {
|
METHOD int mii_clk {
|
||||||
device_t dev;
|
device_t dev;
|
||||||
} DEFAULT if_dwc_default_mii_clk;
|
} 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;
|
boolean_t is_detaching;
|
||||||
int tx_watchdog_count;
|
int tx_watchdog_count;
|
||||||
int stats_harvest_count;
|
int stats_harvest_count;
|
||||||
|
int phy_mode;
|
||||||
|
|
||||||
/* RX */
|
/* RX */
|
||||||
bus_dma_tag_t rxdesc_tag;
|
bus_dma_tag_t rxdesc_tag;
|
||||||
|
@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include "opt_platform.h"
|
#include "opt_platform.h"
|
||||||
#include "opt_kbd.h"
|
#include "opt_kbd.h"
|
||||||
|
#include "opt_evdev.h"
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
@ -56,6 +57,11 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <dev/gpio/gpiobusvar.h>
|
#include <dev/gpio/gpiobusvar.h>
|
||||||
#include <dev/gpio/gpiokeys.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 KBD_DRIVER_NAME "gpiokeys"
|
||||||
|
|
||||||
#define GPIOKEYS_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
|
#define GPIOKEYS_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
|
||||||
@ -99,6 +105,9 @@ struct gpiokey
|
|||||||
struct resource *irq_res;
|
struct resource *irq_res;
|
||||||
void *intr_hl;
|
void *intr_hl;
|
||||||
struct mtx mtx;
|
struct mtx mtx;
|
||||||
|
#ifdef EVDEV_SUPPORT
|
||||||
|
uint32_t evcode;
|
||||||
|
#endif
|
||||||
uint32_t keycode;
|
uint32_t keycode;
|
||||||
int autorepeat;
|
int autorepeat;
|
||||||
struct callout debounce_callout;
|
struct callout debounce_callout;
|
||||||
@ -115,6 +124,9 @@ struct gpiokeys_softc
|
|||||||
struct gpiokey *sc_keys;
|
struct gpiokey *sc_keys;
|
||||||
int sc_total_keys;
|
int sc_total_keys;
|
||||||
|
|
||||||
|
#ifdef EVDEV_SUPPORT
|
||||||
|
struct evdev_dev *sc_evdev;
|
||||||
|
#endif
|
||||||
keyboard_t sc_kbd;
|
keyboard_t sc_kbd;
|
||||||
keymap_t sc_keymap;
|
keymap_t sc_keymap;
|
||||||
accentmap_t sc_accmap;
|
accentmap_t sc_accmap;
|
||||||
@ -171,26 +183,34 @@ gpiokeys_put_key(struct gpiokeys_softc *sc, uint32_t key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
uint32_t code;
|
||||||
|
|
||||||
|
|
||||||
key = keycode & SCAN_KEYCODE_MASK;
|
|
||||||
|
|
||||||
if (!pressed)
|
|
||||||
key |= KEY_RELEASE;
|
|
||||||
|
|
||||||
GPIOKEYS_LOCK(sc);
|
GPIOKEYS_LOCK(sc);
|
||||||
if (keycode & SCAN_PREFIX_E0)
|
#ifdef EVDEV_SUPPORT
|
||||||
gpiokeys_put_key(sc, 0xe0);
|
if (key->evcode != GPIOKEY_NONE &&
|
||||||
else if (keycode & SCAN_PREFIX_E1)
|
(evdev_rcpt_mask & EVDEV_RCPT_HW_KBD) != 0) {
|
||||||
gpiokeys_put_key(sc, 0xe1);
|
evdev_push_key(sc->sc_evdev, key->evcode, pressed);
|
||||||
|
evdev_sync(sc->sc_evdev);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (key->keycode != GPIOKEY_NONE) {
|
||||||
|
code = key->keycode & SCAN_KEYCODE_MASK;
|
||||||
|
if (!pressed)
|
||||||
|
code |= KEY_RELEASE;
|
||||||
|
|
||||||
gpiokeys_put_key(sc, key);
|
if (key->keycode & SCAN_PREFIX_E0)
|
||||||
|
gpiokeys_put_key(sc, 0xe0);
|
||||||
|
else if (key->keycode & SCAN_PREFIX_E1)
|
||||||
|
gpiokeys_put_key(sc, 0xe1);
|
||||||
|
|
||||||
|
gpiokeys_put_key(sc, code);
|
||||||
|
}
|
||||||
GPIOKEYS_UNLOCK(sc);
|
GPIOKEYS_UNLOCK(sc);
|
||||||
|
|
||||||
gpiokeys_event_keyinput(sc);
|
if (key->keycode != GPIOKEY_NONE)
|
||||||
|
gpiokeys_event_keyinput(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -200,10 +220,7 @@ gpiokey_autorepeat(void *arg)
|
|||||||
|
|
||||||
key = arg;
|
key = arg;
|
||||||
|
|
||||||
if (key->keycode == GPIOKEY_NONE)
|
gpiokeys_key_event(key->parent_sc, key, 1);
|
||||||
return;
|
|
||||||
|
|
||||||
gpiokeys_key_event(key->parent_sc, key->keycode, 1);
|
|
||||||
|
|
||||||
callout_reset(&key->repeat_callout, key->repeat,
|
callout_reset(&key->repeat_callout, key->repeat,
|
||||||
gpiokey_autorepeat, key);
|
gpiokey_autorepeat, key);
|
||||||
@ -217,12 +234,9 @@ gpiokey_debounced_intr(void *arg)
|
|||||||
|
|
||||||
key = arg;
|
key = arg;
|
||||||
|
|
||||||
if (key->keycode == GPIOKEY_NONE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
gpio_pin_is_active(key->pin, &active);
|
gpio_pin_is_active(key->pin, &active);
|
||||||
if (active) {
|
if (active) {
|
||||||
gpiokeys_key_event(key->parent_sc, key->keycode, 1);
|
gpiokeys_key_event(key->parent_sc, key, 1);
|
||||||
if (key->autorepeat) {
|
if (key->autorepeat) {
|
||||||
callout_reset(&key->repeat_callout, key->repeat_delay,
|
callout_reset(&key->repeat_callout, key->repeat_delay,
|
||||||
gpiokey_autorepeat, key);
|
gpiokey_autorepeat, key);
|
||||||
@ -232,7 +246,7 @@ gpiokey_debounced_intr(void *arg)
|
|||||||
if (key->autorepeat &&
|
if (key->autorepeat &&
|
||||||
callout_pending(&key->repeat_callout))
|
callout_pending(&key->repeat_callout))
|
||||||
callout_stop(&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)
|
if (key->keycode == GPIOKEY_NONE)
|
||||||
device_printf(sc->sc_dev, "<%s> failed to map linux,code value 0x%x\n",
|
device_printf(sc->sc_dev, "<%s> failed to map linux,code value 0x%x\n",
|
||||||
key_name, code);
|
key_name, code);
|
||||||
|
#ifdef EVDEV_SUPPORT
|
||||||
|
key->evcode = code;
|
||||||
|
evdev_support_key(sc->sc_evdev, code);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
device_printf(sc->sc_dev, "<%s> no linux,code or freebsd,code property\n",
|
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)
|
if (key->pin)
|
||||||
gpio_pin_release(key->pin);
|
gpio_pin_release(key->pin);
|
||||||
GPIOKEY_UNLOCK(key);
|
GPIOKEY_UNLOCK(key);
|
||||||
|
|
||||||
GPIOKEY_LOCK_DESTROY(key);
|
GPIOKEY_LOCK_DESTROY(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,11 +400,14 @@ gpiokeys_probe(device_t dev)
|
|||||||
static int
|
static int
|
||||||
gpiokeys_attach(device_t dev)
|
gpiokeys_attach(device_t dev)
|
||||||
{
|
{
|
||||||
int unit;
|
|
||||||
struct gpiokeys_softc *sc;
|
struct gpiokeys_softc *sc;
|
||||||
keyboard_t *kbd;
|
keyboard_t *kbd;
|
||||||
|
#ifdef EVDEV_SUPPORT
|
||||||
|
char *name;
|
||||||
|
#endif
|
||||||
phandle_t keys, child;
|
phandle_t keys, child;
|
||||||
int total_keys;
|
int total_keys;
|
||||||
|
int unit;
|
||||||
|
|
||||||
if ((keys = ofw_bus_get_node(dev)) == -1)
|
if ((keys = ofw_bus_get_node(dev)) == -1)
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
@ -435,6 +455,19 @@ gpiokeys_attach(device_t dev)
|
|||||||
kbdd_diag(kbd, 1);
|
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;
|
total_keys = 0;
|
||||||
|
|
||||||
/* Traverse the 'gpio-keys' node and count keys */
|
/* 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);
|
return (0);
|
||||||
|
|
||||||
detach:
|
detach:
|
||||||
@ -485,6 +525,10 @@ gpiokeys_detach(device_t dev)
|
|||||||
#endif
|
#endif
|
||||||
kbd_unregister(kbd);
|
kbd_unregister(kbd);
|
||||||
|
|
||||||
|
#ifdef EVDEV_SUPPORT
|
||||||
|
evdev_free(sc->sc_evdev);
|
||||||
|
#endif
|
||||||
|
|
||||||
GPIOKEYS_LOCK_DESTROY(sc);
|
GPIOKEYS_LOCK_DESTROY(sc);
|
||||||
if (sc->sc_keys)
|
if (sc->sc_keys)
|
||||||
free(sc->sc_keys, M_DEVBUF);
|
free(sc->sc_keys, M_DEVBUF);
|
||||||
|
@ -479,11 +479,12 @@ pmc_arm64_initialize()
|
|||||||
{
|
{
|
||||||
struct pmc_mdep *pmc_mdep;
|
struct pmc_mdep *pmc_mdep;
|
||||||
struct pmc_classdep *pcd;
|
struct pmc_classdep *pcd;
|
||||||
int idcode;
|
int idcode, impcode;
|
||||||
int reg;
|
int reg;
|
||||||
|
|
||||||
reg = arm64_pmcr_read();
|
reg = arm64_pmcr_read();
|
||||||
arm64_npmcs = (reg & PMCR_N_MASK) >> PMCR_N_SHIFT;
|
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;
|
idcode = (reg & PMCR_IDCODE_MASK) >> PMCR_IDCODE_SHIFT;
|
||||||
|
|
||||||
PMCDBG1(MDP, INI, 1, "arm64-init npmcs=%d", arm64_npmcs);
|
PMCDBG1(MDP, INI, 1, "arm64-init npmcs=%d", arm64_npmcs);
|
||||||
@ -498,13 +499,24 @@ pmc_arm64_initialize()
|
|||||||
/* Just one class */
|
/* Just one class */
|
||||||
pmc_mdep = pmc_mdep_alloc(1);
|
pmc_mdep = pmc_mdep_alloc(1);
|
||||||
|
|
||||||
switch (idcode) {
|
switch(impcode) {
|
||||||
case PMCR_IDCODE_CORTEX_A57:
|
case PMCR_IMP_ARM:
|
||||||
case PMCR_IDCODE_CORTEX_A72:
|
switch (idcode) {
|
||||||
pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A57;
|
case PMCR_IDCODE_CORTEX_A76:
|
||||||
|
case PMCR_IDCODE_NEOVERSE_N1:
|
||||||
|
pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A76;
|
||||||
|
break;
|
||||||
|
case PMCR_IDCODE_CORTEX_A57:
|
||||||
|
case PMCR_IDCODE_CORTEX_A72:
|
||||||
|
pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A57;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case PMCR_IDCODE_CORTEX_A53:
|
||||||
|
pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A53;
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case PMCR_IDCODE_CORTEX_A53:
|
|
||||||
pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A53;
|
pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A53;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -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("BR_RETURN_RETIRED", ARMV8_EVENT_0EH) \
|
||||||
__PMC_EV_ALIAS("UNALIGNED_LDST_RETIRED",ARMV8_EVENT_0FH)
|
__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_ARMV8_COMMON() \
|
||||||
__PMC_EV_ALIAS("INST_SPEC", ARMV8_EVENT_1BH) \
|
__PMC_EV_ALIAS("INST_SPEC", ARMV8_EVENT_1BH) \
|
||||||
__PMC_EV_ALIAS("TTBR_WRITE_RETIRED", ARMV8_EVENT_1CH) \
|
__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_VICTIM", ARMV8_EVENT_56H) \
|
||||||
__PMC_EV_ALIAS("L2D_CACHE_WB_CLEAN", ARMV8_EVENT_57H) \
|
__PMC_EV_ALIAS("L2D_CACHE_WB_CLEAN", ARMV8_EVENT_57H) \
|
||||||
__PMC_EV_ALIAS("L2D_CACHE_INVAL", ARMV8_EVENT_58H) \
|
__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_LD", ARMV8_EVENT_66H) \
|
||||||
__PMC_EV_ALIAS("MEM_ACCESS_ST", ARMV8_EVENT_67H) \
|
__PMC_EV_ALIAS("MEM_ACCESS_ST", ARMV8_EVENT_67H) \
|
||||||
__PMC_EV_ALIAS("UNALIGNED_LD_SPEC", ARMV8_EVENT_68H) \
|
__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_LD_SPEC", ARMV8_EVENT_90H) \
|
||||||
__PMC_EV_ALIAS("RC_ST_SPEC", ARMV8_EVENT_91H)
|
__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",
|
* MIPS Events from "Programming the MIPS32 24K Core Family",
|
||||||
* Document Number: MD00355 Revision 04.63 December 19, 2008
|
* Document Number: MD00355 Revision 04.63 December 19, 2008
|
||||||
|
@ -46,16 +46,6 @@ enum ice_fw_modes {
|
|||||||
ICE_FW_MODE_ROLLBACK
|
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);
|
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);
|
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);
|
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_update_link_info(struct ice_port_info *pi);
|
||||||
enum ice_status
|
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,
|
ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res,
|
||||||
enum ice_aq_res_access_type access, u32 timeout);
|
enum ice_aq_res_access_type access, u32 timeout);
|
||||||
void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res);
|
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,
|
enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
|
||||||
u8 page, u16 reg, u8 phy_addr, u16 value);
|
u8 page, u16 reg, u8 phy_addr, u16 value);
|
||||||
u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
|
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_ */
|
#endif /* _I40E_PROTOTYPE_H_ */
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2012-2016 Intel Corporation
|
* Copyright (C) 2012-2016 Intel Corporation
|
||||||
* All rights reserved.
|
* 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
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@ -45,6 +45,9 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <geom/geom_disk.h>
|
#include <geom/geom_disk.h>
|
||||||
|
|
||||||
#include <dev/nvme/nvme.h>
|
#include <dev/nvme/nvme.h>
|
||||||
|
#include <dev/nvme/nvme_private.h>
|
||||||
|
|
||||||
|
#include <dev/pci/pcivar.h>
|
||||||
|
|
||||||
#define NVD_STR "nvd"
|
#define NVD_STR "nvd"
|
||||||
|
|
||||||
@ -92,7 +95,7 @@ struct nvd_disk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct nvd_controller {
|
struct nvd_controller {
|
||||||
|
struct nvme_controller *ctrlr;
|
||||||
TAILQ_ENTRY(nvd_controller) tailq;
|
TAILQ_ENTRY(nvd_controller) tailq;
|
||||||
TAILQ_HEAD(, nvd_disk) disk_head;
|
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,
|
nvd_ctrlr = malloc(sizeof(struct nvd_controller), M_NVD,
|
||||||
M_ZERO | M_WAITOK);
|
M_ZERO | M_WAITOK);
|
||||||
|
|
||||||
|
nvd_ctrlr->ctrlr = ctrlr;
|
||||||
TAILQ_INIT(&nvd_ctrlr->disk_head);
|
TAILQ_INIT(&nvd_ctrlr->disk_head);
|
||||||
mtx_lock(&nvd_lock);
|
mtx_lock(&nvd_lock);
|
||||||
TAILQ_INSERT_TAIL(&ctrlr_head, nvd_ctrlr, tailq);
|
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 nvd_disk *ndisk, *tnd;
|
||||||
struct disk *disk;
|
struct disk *disk;
|
||||||
struct nvd_controller *ctrlr = ctrlr_arg;
|
struct nvd_controller *ctrlr = ctrlr_arg;
|
||||||
|
device_t dev = ctrlr->ctrlr->dev;
|
||||||
int unit;
|
int unit;
|
||||||
|
|
||||||
ndisk = malloc(sizeof(struct nvd_disk), M_NVD, M_ZERO | M_WAITOK);
|
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);
|
NVME_MODEL_NUMBER_LENGTH);
|
||||||
strlcpy(disk->d_descr, descr, sizeof(descr));
|
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;
|
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);
|
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.slot = pci_get_slot(dev);
|
||||||
cpi->xport_specific.nvme.function = pci_get_function(dev);
|
cpi->xport_specific.nvme.function = pci_get_function(dev);
|
||||||
cpi->xport_specific.nvme.extra = 0;
|
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));
|
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;
|
cpi->ccb_h.status = CAM_REQ_CMP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define USB_DEBUG_VAR usb_debug
|
#define USB_DEBUG_VAR usb_debug
|
||||||
#include <dev/usb/usb_debug.h>
|
#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_LOCK(sc) sx_xlock(&sc->gpio_lock)
|
||||||
#define CP2112GPIO_UNLOCK(sc) sx_xunlock(&sc->gpio_lock)
|
#define CP2112GPIO_UNLOCK(sc) sx_xunlock(&sc->gpio_lock)
|
||||||
#define CP2112GPIO_LOCKED(sc) sx_assert(&sc->gpio_lock, SX_XLOCKED)
|
#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_LOCK 0x20
|
||||||
#define CP2112_REQ_USB_CFG 0x21
|
#define CP2112_REQ_USB_CFG 0x21
|
||||||
|
|
||||||
|
#define CP2112_IIC_MAX_READ_LEN 512
|
||||||
#define CP2112_IIC_REPSTART_VER 2 /* Erratum CP2112_E10. */
|
#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_IDLE 0
|
||||||
#define CP2112_IIC_STATUS0_BUSY 1
|
#define CP2112_IIC_STATUS0_BUSY 1
|
||||||
#define CP2112_IIC_STATUS0_CMP 2
|
#define CP2112_IIC_STATUS0_CMP 2
|
||||||
@ -104,6 +111,111 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define CP2112_IIC_STATUS1_TIMEOUT_BUS 1
|
#define CP2112_IIC_STATUS1_TIMEOUT_BUS 1
|
||||||
#define CP2112_IIC_STATUS1_ARB_LOST 2
|
#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 {
|
struct cp2112_softc {
|
||||||
device_t sc_gpio_dev;
|
device_t sc_gpio_dev;
|
||||||
@ -120,10 +232,38 @@ struct cp2112gpio_softc {
|
|||||||
struct gpio_pin pins[CP2112_GPIO_COUNT];
|
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 cp2112_detach(device_t dev);
|
||||||
static int cp2112gpio_detach(device_t dev);
|
static int cp2112gpio_detach(device_t dev);
|
||||||
static int cp2112iic_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
|
static int
|
||||||
cp2112_get_report(device_t dev, uint8_t id, void *data, uint16_t len)
|
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;
|
int err;
|
||||||
|
|
||||||
sc = device_get_softc(dev);
|
sc = device_get_softc(dev);
|
||||||
|
*(uint8_t *)data = id;
|
||||||
err = usbd_req_set_report(sc->sc_udev, NULL, data,
|
err = usbd_req_set_report(sc->sc_udev, NULL, data,
|
||||||
len, sc->sc_iface_index, UHID_FEATURE_REPORT, id);
|
len, sc->sc_iface_index, UHID_FEATURE_REPORT, id);
|
||||||
return (err);
|
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
|
static int
|
||||||
cp2112_gpio_read_pin(device_t dev, uint32_t pin_num, bool *on)
|
cp2112_gpio_read_pin(device_t dev, uint32_t pin_num, bool *on)
|
||||||
{
|
{
|
||||||
struct {
|
struct gpio_get_req data;
|
||||||
uint8_t id;
|
|
||||||
uint8_t state;
|
|
||||||
} __packed data;
|
|
||||||
struct cp2112gpio_softc *sc;
|
struct cp2112gpio_softc *sc;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
sc = device_get_softc(dev);
|
sc = device_get_softc(dev);
|
||||||
CP2112GPIO_LOCKED(sc);
|
CP2112GPIO_LOCKED(sc);
|
||||||
|
|
||||||
data.id = CP2112_REQ_GPIO_GET;
|
|
||||||
err = cp2112_get_report(device_get_parent(dev),
|
err = cp2112_get_report(device_get_parent(dev),
|
||||||
CP2112_REQ_GPIO_GET, &data, sizeof(data));
|
CP2112_REQ_GPIO_GET, &data, sizeof(data));
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
@ -174,11 +392,7 @@ cp2112_gpio_read_pin(device_t dev, uint32_t pin_num, bool *on)
|
|||||||
static int
|
static int
|
||||||
cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on)
|
cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on)
|
||||||
{
|
{
|
||||||
struct {
|
struct gpio_set_req data;
|
||||||
uint8_t id;
|
|
||||||
uint8_t state;
|
|
||||||
uint8_t mask;
|
|
||||||
} __packed data;
|
|
||||||
struct cp2112gpio_softc *sc;
|
struct cp2112gpio_softc *sc;
|
||||||
int err;
|
int err;
|
||||||
bool actual;
|
bool actual;
|
||||||
@ -186,10 +400,8 @@ cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on)
|
|||||||
sc = device_get_softc(dev);
|
sc = device_get_softc(dev);
|
||||||
CP2112GPIO_LOCKED(sc);
|
CP2112GPIO_LOCKED(sc);
|
||||||
|
|
||||||
data.id = CP2112_REQ_GPIO_SET;
|
|
||||||
data.state = (uint8_t)on << pin_num;
|
data.state = (uint8_t)on << pin_num;
|
||||||
data.mask = (uint8_t)1 << pin_num;
|
data.mask = (uint8_t)1 << pin_num;
|
||||||
|
|
||||||
err = cp2112_set_report(device_get_parent(dev),
|
err = cp2112_set_report(device_get_parent(dev),
|
||||||
CP2112_REQ_GPIO_SET, &data, sizeof(data));
|
CP2112_REQ_GPIO_SET, &data, sizeof(data));
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
@ -204,15 +416,9 @@ cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
cp2112_gpio_configure_write_pin(device_t dev, uint32_t pin_num,
|
cp2112_gpio_configure_write_pin(device_t dev, uint32_t pin_num,
|
||||||
bool output, bool pushpull)
|
bool output, enum cp2112_out_mode *mode)
|
||||||
{
|
{
|
||||||
struct {
|
struct gpio_config_req data;
|
||||||
uint8_t id;
|
|
||||||
uint8_t output;
|
|
||||||
uint8_t pushpull;
|
|
||||||
uint8_t special;
|
|
||||||
uint8_t divider;
|
|
||||||
} __packed data;
|
|
||||||
struct cp2112gpio_softc *sc;
|
struct cp2112gpio_softc *sc;
|
||||||
int err;
|
int err;
|
||||||
uint8_t mask;
|
uint8_t mask;
|
||||||
@ -220,21 +426,26 @@ cp2112_gpio_configure_write_pin(device_t dev, uint32_t pin_num,
|
|||||||
sc = device_get_softc(dev);
|
sc = device_get_softc(dev);
|
||||||
CP2112GPIO_LOCKED(sc);
|
CP2112GPIO_LOCKED(sc);
|
||||||
|
|
||||||
mask = (uint8_t)1 << pin_num;
|
|
||||||
data.id = CP2112_REQ_GPIO_CFG;
|
|
||||||
err = cp2112_get_report(device_get_parent(dev),
|
err = cp2112_get_report(device_get_parent(dev),
|
||||||
CP2112_REQ_GPIO_CFG, &data, sizeof(data));
|
CP2112_REQ_GPIO_CFG, &data, sizeof(data));
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
return (err);
|
return (err);
|
||||||
|
|
||||||
|
mask = (uint8_t)1 << pin_num;
|
||||||
if (output) {
|
if (output) {
|
||||||
data.output |= mask;
|
data.output |= mask;
|
||||||
if (pushpull)
|
switch (*mode) {
|
||||||
|
case OUT_PP:
|
||||||
data.pushpull |= mask;
|
data.pushpull |= mask;
|
||||||
else
|
break;
|
||||||
|
case OUT_OD:
|
||||||
data.pushpull &= ~mask;
|
data.pushpull &= ~mask;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
data.output &= ~mask;
|
data.output &= ~mask;
|
||||||
data.pushpull &= ~mask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = cp2112_set_report(device_get_parent(dev),
|
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));
|
CP2112_REQ_GPIO_CFG, &data, sizeof(data));
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
return (err);
|
return (err);
|
||||||
|
|
||||||
if (((data.output & mask) != 0) != output)
|
if (((data.output & mask) != 0) != output)
|
||||||
return (EIO);
|
return (EIO);
|
||||||
if (((data.pushpull & mask) != 0) != pushpull)
|
if (output) {
|
||||||
return (EIO);
|
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);
|
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 cp2112gpio_softc *sc;
|
||||||
struct gpio_pin *pin;
|
struct gpio_pin *pin;
|
||||||
|
enum cp2112_out_mode out_mode;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (pin_num >= CP2112_GPIO_COUNT)
|
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);
|
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.
|
* preserve the current state.
|
||||||
*/
|
*/
|
||||||
if ((flags & GPIO_PIN_OUTPUT) != 0 &&
|
out_mode = OUT_KEEP;
|
||||||
(flags & (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)) == 0)
|
if ((flags & GPIO_PIN_OUTPUT) != 0) {
|
||||||
flags |= pin->gp_flags & (GPIO_PIN_OPENDRAIN|GPIO_PIN_PUSHPULL);
|
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,
|
err = cp2112_gpio_configure_write_pin(dev, pin_num,
|
||||||
(flags & GPIO_PIN_OUTPUT) != 0,
|
(flags & GPIO_PIN_OUTPUT) != 0, &out_mode);
|
||||||
(flags & GPIO_PIN_PUSHPULL) != 0);
|
if (err == 0) {
|
||||||
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;
|
pin->gp_flags = flags;
|
||||||
|
}
|
||||||
CP2112GPIO_UNLOCK(sc);
|
CP2112GPIO_UNLOCK(sc);
|
||||||
|
|
||||||
return (err);
|
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
|
static int
|
||||||
cp2112gpio_probe(device_t dev)
|
cp2112gpio_probe(device_t dev)
|
||||||
{
|
{
|
||||||
@ -526,13 +680,7 @@ cp2112gpio_probe(device_t dev)
|
|||||||
static int
|
static int
|
||||||
cp2112gpio_attach(device_t dev)
|
cp2112gpio_attach(device_t dev)
|
||||||
{
|
{
|
||||||
struct {
|
struct gpio_config_req data;
|
||||||
uint8_t id;
|
|
||||||
uint8_t output;
|
|
||||||
uint8_t pushpull;
|
|
||||||
uint8_t special;
|
|
||||||
uint8_t divider;
|
|
||||||
} __packed data;
|
|
||||||
struct cp2112gpio_softc *sc;
|
struct cp2112gpio_softc *sc;
|
||||||
device_t cp2112;
|
device_t cp2112;
|
||||||
int err;
|
int err;
|
||||||
@ -546,7 +694,6 @@ cp2112gpio_attach(device_t dev)
|
|||||||
sc->gpio_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN |
|
sc->gpio_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN |
|
||||||
GPIO_PIN_PUSHPULL;
|
GPIO_PIN_PUSHPULL;
|
||||||
|
|
||||||
data.id = CP2112_REQ_GPIO_CFG;
|
|
||||||
err = cp2112_get_report(cp2112, CP2112_REQ_GPIO_CFG,
|
err = cp2112_get_report(cp2112, CP2112_REQ_GPIO_CFG,
|
||||||
&data, sizeof(data));
|
&data, sizeof(data));
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
@ -562,7 +709,11 @@ cp2112gpio_attach(device_t dev)
|
|||||||
snprintf(pin->gp_name, GPIOMAXNAME, "GPIO%u", i);
|
snprintf(pin->gp_name, GPIOMAXNAME, "GPIO%u", i);
|
||||||
pin->gp_name[GPIOMAXNAME - 1] = '\0';
|
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;
|
pin->gp_flags |= GPIO_PIN_OUTPUT;
|
||||||
if ((data.pushpull & mask) != 0)
|
if ((data.pushpull & mask) != 0)
|
||||||
pin->gp_flags |= GPIO_PIN_PUSHPULL;
|
pin->gp_flags |= GPIO_PIN_PUSHPULL;
|
||||||
@ -597,94 +748,6 @@ cp2112gpio_detach(device_t dev)
|
|||||||
return (0);
|
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
|
static void
|
||||||
cp2112iic_intr_write_callback(struct usb_xfer *xfer, usb_error_t error)
|
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
|
static int
|
||||||
cp2112iic_check_req_status(struct cp2112iic_softc *sc)
|
cp2112iic_check_req_status(struct cp2112iic_softc *sc)
|
||||||
{
|
{
|
||||||
struct {
|
struct i2c_xfer_status_req xfer_status_req;
|
||||||
uint8_t id;
|
struct i2c_xfer_status_resp xfer_status_resp;
|
||||||
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;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
mtx_assert(&sc->io.lock, MA_OWNED);
|
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,
|
cp2112iic_read_data(struct cp2112iic_softc *sc, void *data, uint16_t in_len,
|
||||||
uint16_t *out_len)
|
uint16_t *out_len)
|
||||||
{
|
{
|
||||||
struct {
|
struct i2c_data_read_force_send_req data_read_force_send;
|
||||||
uint8_t id;
|
struct i2c_data_read_resp data_read_resp;
|
||||||
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;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
mtx_assert(&sc->io.lock, MA_OWNED);
|
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))
|
if (in_len > sizeof(data_read_resp.data))
|
||||||
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.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,
|
err = cp2112iic_req_resp(sc,
|
||||||
&data_read_force_send, sizeof(data_read_force_send),
|
&data_read_force_send, sizeof(data_read_force_send),
|
||||||
&data_read_resp, sizeof(data_read_resp));
|
&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,
|
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
|
* 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;
|
err = IIC_EBUSERR;
|
||||||
goto out;
|
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");
|
device_printf(sc->dev, "device returns more data than asked\n");
|
||||||
err = IIC_EOVERFLOW;
|
err = IIC_EOVERFLOW;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_len = data_read_resp.length;
|
*out_len = data_read_resp.len;
|
||||||
if (*out_len > 0)
|
if (*out_len > 0)
|
||||||
memcpy(data, data_read_resp.data, *out_len);
|
memcpy(data, data_read_resp.data, *out_len);
|
||||||
out:
|
out:
|
||||||
@ -1070,11 +1116,13 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
|
|||||||
reason = "message with no data";
|
reason = "message with no data";
|
||||||
break;
|
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";
|
reason = "too long read";
|
||||||
break;
|
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";
|
reason = "too long write";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1092,7 +1140,8 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
|
|||||||
reason = "write without stop";
|
reason = "write without stop";
|
||||||
break;
|
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";
|
reason = "too long write without stop";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1120,22 +1169,16 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
|
|||||||
|
|
||||||
for (i = 0; i < nmsgs; i++) {
|
for (i = 0; i < nmsgs; i++) {
|
||||||
if (i + 1 < nmsgs && (msgs[i].flags & IIC_M_NOSTOP) != 0) {
|
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
|
* Combine <write><repeated start><read> into a single
|
||||||
* CP2112 operation.
|
* CP2112 operation.
|
||||||
*/
|
*/
|
||||||
struct {
|
struct i2c_write_read_req req;
|
||||||
uint8_t id;
|
|
||||||
uint8_t slave;
|
|
||||||
uint16_t rlen;
|
|
||||||
uint8_t wlen;
|
|
||||||
uint8_t wdata[16];
|
|
||||||
} __packed 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.id = CP2112_REQ_SMB_WRITE_READ;
|
||||||
req.slave = msgs[i].slave & ~LSB;
|
req.slave = msgs[i].slave & ~LSB;
|
||||||
to_read = msgs[i + 1].len;
|
to_read = msgs[i + 1].len;
|
||||||
@ -1150,11 +1193,7 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
|
|||||||
*/
|
*/
|
||||||
i++;
|
i++;
|
||||||
} else if ((msgs[i].flags & IIC_M_RD) != 0) {
|
} else if ((msgs[i].flags & IIC_M_RD) != 0) {
|
||||||
struct {
|
struct i2c_read_req req;
|
||||||
uint8_t id;
|
|
||||||
uint8_t slave;
|
|
||||||
uint16_t len;
|
|
||||||
} __packed req;
|
|
||||||
|
|
||||||
req.id = CP2112_REQ_SMB_READ;
|
req.id = CP2112_REQ_SMB_READ;
|
||||||
req.slave = msgs[i].slave & ~LSB;
|
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);
|
req.len = htobe16(to_read);
|
||||||
err = cp2112iic_send_req(sc, &req, sizeof(req));
|
err = cp2112iic_send_req(sc, &req, sizeof(req));
|
||||||
} else {
|
} else {
|
||||||
struct {
|
struct i2c_write_req req;
|
||||||
uint8_t id;
|
|
||||||
uint8_t slave;
|
|
||||||
uint8_t len;
|
|
||||||
uint8_t data[61];
|
|
||||||
} __packed req;
|
|
||||||
|
|
||||||
req.id = CP2112_REQ_SMB_WRITE;
|
req.id = CP2112_REQ_SMB_WRITE;
|
||||||
req.slave = msgs[i].slave & ~LSB;
|
req.slave = msgs[i].slave & ~LSB;
|
||||||
@ -1207,16 +1241,7 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
|
|||||||
static int
|
static int
|
||||||
cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
|
cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
|
||||||
{
|
{
|
||||||
struct {
|
struct i2c_cfg_req i2c_cfg;
|
||||||
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 cp2112iic_softc *sc;
|
struct cp2112iic_softc *sc;
|
||||||
device_t cp2112;
|
device_t cp2112;
|
||||||
u_int busfreq;
|
u_int busfreq;
|
||||||
@ -1229,16 +1254,15 @@ cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
|
|||||||
else
|
else
|
||||||
busfreq = IICBUS_GET_FREQUENCY(sc->iicbus_dev, speed);
|
busfreq = IICBUS_GET_FREQUENCY(sc->iicbus_dev, speed);
|
||||||
|
|
||||||
smb_cfg.id = CP2112_REQ_SMB_CFG;
|
|
||||||
err = cp2112_get_report(cp2112, 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) {
|
if (err != 0) {
|
||||||
device_printf(dev, "failed to get CP2112_REQ_SMB_CFG report\n");
|
device_printf(dev, "failed to get CP2112_REQ_SMB_CFG report\n");
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldaddr != NULL)
|
if (oldaddr != NULL)
|
||||||
*oldaddr = smb_cfg.slave_addr;
|
*oldaddr = i2c_cfg.slave_addr;
|
||||||
/*
|
/*
|
||||||
* For simplicity we do not enable Auto Send Read
|
* For simplicity we do not enable Auto Send Read
|
||||||
* because of erratum CP2112_E101 (fixed in version 3).
|
* 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?
|
* TODO: should the device reset request (0x01) be sent?
|
||||||
* If the device disconnects as a result, then no.
|
* If the device disconnects as a result, then no.
|
||||||
*/
|
*/
|
||||||
smb_cfg.speed = htobe32(busfreq);
|
i2c_cfg.speed = htobe32(busfreq);
|
||||||
if (addr != 0)
|
if (addr != 0)
|
||||||
smb_cfg.slave_addr = addr;
|
i2c_cfg.slave_addr = addr;
|
||||||
smb_cfg.auto_send_read = 0;
|
i2c_cfg.auto_send_read = 0;
|
||||||
smb_cfg.retry_count = htobe16(1);
|
i2c_cfg.retry_count = htobe16(1);
|
||||||
smb_cfg.scl_low_timeout = 0;
|
i2c_cfg.scl_low_timeout = 0;
|
||||||
if (bootverbose) {
|
if (bootverbose) {
|
||||||
device_printf(dev, "speed %d Hz\n", be32toh(smb_cfg.speed));
|
device_printf(dev, "speed %d Hz\n", be32toh(i2c_cfg.speed));
|
||||||
device_printf(dev, "slave addr 0x%02x\n", smb_cfg.slave_addr);
|
device_printf(dev, "slave addr 0x%02x\n", i2c_cfg.slave_addr);
|
||||||
device_printf(dev, "auto send read %s\n",
|
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",
|
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",
|
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",
|
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",
|
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,
|
err = cp2112_set_report(cp2112, CP2112_REQ_SMB_CFG,
|
||||||
&smb_cfg, sizeof(smb_cfg));
|
&i2c_cfg, sizeof(i2c_cfg));
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
device_printf(dev, "failed to set CP2112_REQ_SMB_CFG report\n");
|
device_printf(dev, "failed to set CP2112_REQ_SMB_CFG report\n");
|
||||||
return (err);
|
return (err);
|
||||||
@ -1353,6 +1377,60 @@ cp2112iic_detach(device_t dev)
|
|||||||
return (0);
|
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[] = {
|
static device_method_t cp2112iic_methods[] = {
|
||||||
/* Device interface */
|
/* Device interface */
|
||||||
DEVMETHOD(device_probe, cp2112iic_probe),
|
DEVMETHOD(device_probe, cp2112iic_probe),
|
||||||
|
@ -153,6 +153,7 @@ struct devfs_dirent {
|
|||||||
struct timespec de_ctime;
|
struct timespec de_ctime;
|
||||||
struct vnode *de_vnode;
|
struct vnode *de_vnode;
|
||||||
char *de_symlink;
|
char *de_symlink;
|
||||||
|
int de_usecount;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct devfs_mount {
|
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,
|
struct devfs_dirent *devfs_find(struct devfs_dirent *, const char *, int,
|
||||||
int);
|
int);
|
||||||
|
|
||||||
|
void devfs_ctty_ref(struct vnode *);
|
||||||
|
void devfs_ctty_unref(struct vnode *);
|
||||||
|
int devfs_usecount(struct vnode *);
|
||||||
|
|
||||||
#endif /* _KERNEL */
|
#endif /* _KERNEL */
|
||||||
|
|
||||||
#endif /* !_FS_DEVFS_DEVFS_H_ */
|
#endif /* !_FS_DEVFS_DEVFS_H_ */
|
||||||
|
@ -156,7 +156,7 @@ devfs_dev_exists(const char *name)
|
|||||||
{
|
{
|
||||||
struct cdev_priv *cdp;
|
struct cdev_priv *cdp;
|
||||||
|
|
||||||
mtx_assert(&devmtx, MA_OWNED);
|
dev_lock_assert_locked();
|
||||||
|
|
||||||
TAILQ_FOREACH(cdp, &cdevp_list, cdp_list) {
|
TAILQ_FOREACH(cdp, &cdevp_list, cdp_list) {
|
||||||
if ((cdp->cdp_flags & CDP_ACTIVE) == 0)
|
if ((cdp->cdp_flags & CDP_ACTIVE) == 0)
|
||||||
@ -707,7 +707,7 @@ devfs_create(struct cdev *dev)
|
|||||||
{
|
{
|
||||||
struct cdev_priv *cdp;
|
struct cdev_priv *cdp;
|
||||||
|
|
||||||
mtx_assert(&devmtx, MA_OWNED);
|
dev_lock_assert_locked();
|
||||||
cdp = cdev2priv(dev);
|
cdp = cdev2priv(dev);
|
||||||
cdp->cdp_flags |= CDP_ACTIVE;
|
cdp->cdp_flags |= CDP_ACTIVE;
|
||||||
cdp->cdp_inode = alloc_unrl(devfs_inos);
|
cdp->cdp_inode = alloc_unrl(devfs_inos);
|
||||||
@ -721,7 +721,7 @@ devfs_destroy(struct cdev *dev)
|
|||||||
{
|
{
|
||||||
struct cdev_priv *cdp;
|
struct cdev_priv *cdp;
|
||||||
|
|
||||||
mtx_assert(&devmtx, MA_OWNED);
|
dev_lock_assert_locked();
|
||||||
cdp = cdev2priv(dev);
|
cdp = cdev2priv(dev);
|
||||||
cdp->cdp_flags &= ~CDP_ACTIVE;
|
cdp->cdp_flags &= ~CDP_ACTIVE;
|
||||||
devfs_generation++;
|
devfs_generation++;
|
||||||
|
@ -95,6 +95,9 @@ extern struct sx clone_drain_lock;
|
|||||||
extern struct mtx cdevpriv_mtx;
|
extern struct mtx cdevpriv_mtx;
|
||||||
extern TAILQ_HEAD(cdev_priv_list, cdev_priv) cdevp_list;
|
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 /* _KERNEL */
|
||||||
|
|
||||||
#endif /* !_FS_DEVFS_DEVFS_INT_H_ */
|
#endif /* !_FS_DEVFS_DEVFS_INT_H_ */
|
||||||
|
@ -222,6 +222,115 @@ devfs_clear_cdevpriv(void)
|
|||||||
devfs_fpdrop(fp);
|
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.
|
* 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 */
|
/* XXX: v_rdev should be protect by vnode lock */
|
||||||
vp->v_rdev = dev;
|
vp->v_rdev = dev;
|
||||||
VNPASS(vp->v_usecount == 1, vp);
|
VNPASS(vp->v_usecount == 1, vp);
|
||||||
dev->si_usecount++;
|
|
||||||
/* Special casing of ttys for deadfs. Probably redundant. */
|
/* Special casing of ttys for deadfs. Probably redundant. */
|
||||||
dsw = dev->si_devsw;
|
dsw = dev->si_devsw;
|
||||||
if (dsw != NULL && (dsw->d_flags & D_TTY) != 0)
|
if (dsw != NULL && (dsw->d_flags & D_TTY) != 0)
|
||||||
@ -569,6 +677,7 @@ devfs_close(struct vop_close_args *ap)
|
|||||||
struct proc *p;
|
struct proc *p;
|
||||||
struct cdev *dev = vp->v_rdev;
|
struct cdev *dev = vp->v_rdev;
|
||||||
struct cdevsw *dsw;
|
struct cdevsw *dsw;
|
||||||
|
struct devfs_dirent *de = vp->v_data;
|
||||||
int dflags, error, ref, vp_locked;
|
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
|
* if the reference count is 2 (this last descriptor
|
||||||
* plus the session), release the reference from the session.
|
* 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;
|
p = td->td_proc;
|
||||||
PROC_LOCK(p);
|
PROC_LOCK(p);
|
||||||
if (vp == p->p_session->s_ttyvp) {
|
if (vp == p->p_session->s_ttyvp) {
|
||||||
@ -596,19 +705,20 @@ devfs_close(struct vop_close_args *ap)
|
|||||||
sx_xlock(&proctree_lock);
|
sx_xlock(&proctree_lock);
|
||||||
if (vp == p->p_session->s_ttyvp) {
|
if (vp == p->p_session->s_ttyvp) {
|
||||||
SESS_LOCK(p->p_session);
|
SESS_LOCK(p->p_session);
|
||||||
|
mtx_lock(&devfs_de_interlock);
|
||||||
VI_LOCK(vp);
|
VI_LOCK(vp);
|
||||||
if (vp->v_usecount == 2 && vcount(vp) == 1 &&
|
if (devfs_usecountl(vp) == 2 && !VN_IS_DOOMED(vp)) {
|
||||||
!VN_IS_DOOMED(vp)) {
|
|
||||||
p->p_session->s_ttyvp = NULL;
|
p->p_session->s_ttyvp = NULL;
|
||||||
p->p_session->s_ttydp = NULL;
|
p->p_session->s_ttydp = NULL;
|
||||||
oldvp = vp;
|
oldvp = vp;
|
||||||
}
|
}
|
||||||
VI_UNLOCK(vp);
|
VI_UNLOCK(vp);
|
||||||
|
mtx_unlock(&devfs_de_interlock);
|
||||||
SESS_UNLOCK(p->p_session);
|
SESS_UNLOCK(p->p_session);
|
||||||
}
|
}
|
||||||
sx_xunlock(&proctree_lock);
|
sx_xunlock(&proctree_lock);
|
||||||
if (oldvp != NULL)
|
if (oldvp != NULL)
|
||||||
vrele(oldvp);
|
devfs_ctty_unref(oldvp);
|
||||||
} else
|
} else
|
||||||
PROC_UNLOCK(p);
|
PROC_UNLOCK(p);
|
||||||
}
|
}
|
||||||
@ -625,9 +735,12 @@ devfs_close(struct vop_close_args *ap)
|
|||||||
if (dsw == NULL)
|
if (dsw == NULL)
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
dflags = 0;
|
dflags = 0;
|
||||||
|
mtx_lock(&devfs_de_interlock);
|
||||||
VI_LOCK(vp);
|
VI_LOCK(vp);
|
||||||
if (vp->v_usecount == 1 && vcount(vp) == 1)
|
if (devfs_usecountl(vp) == 1)
|
||||||
dflags |= FLASTCLOSE;
|
dflags |= FLASTCLOSE;
|
||||||
|
devfs_usecount_subl(vp);
|
||||||
|
mtx_unlock(&devfs_de_interlock);
|
||||||
if (VN_IS_DOOMED(vp)) {
|
if (VN_IS_DOOMED(vp)) {
|
||||||
/* Forced close. */
|
/* Forced close. */
|
||||||
dflags |= FREVOKE | FNONBLOCK;
|
dflags |= FREVOKE | FNONBLOCK;
|
||||||
@ -850,7 +963,7 @@ devfs_ioctl(struct vop_ioctl_args *ap)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vrefact(vp);
|
devfs_ctty_ref(vp);
|
||||||
SESS_LOCK(sess);
|
SESS_LOCK(sess);
|
||||||
vpold = sess->s_ttyvp;
|
vpold = sess->s_ttyvp;
|
||||||
sess->s_ttyvp = vp;
|
sess->s_ttyvp = vp;
|
||||||
@ -1159,6 +1272,9 @@ devfs_open(struct vop_open_args *ap)
|
|||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vp->v_type == VCHR)
|
||||||
|
devfs_usecount_add(vp);
|
||||||
|
|
||||||
vlocked = VOP_ISLOCKED(vp);
|
vlocked = VOP_ISLOCKED(vp);
|
||||||
VOP_UNLOCK(vp);
|
VOP_UNLOCK(vp);
|
||||||
|
|
||||||
@ -1178,6 +1294,9 @@ devfs_open(struct vop_open_args *ap)
|
|||||||
td->td_fpop = fpop;
|
td->td_fpop = fpop;
|
||||||
|
|
||||||
vn_lock(vp, vlocked | LK_RETRY);
|
vn_lock(vp, vlocked | LK_RETRY);
|
||||||
|
if (error != 0 && vp->v_type == VCHR)
|
||||||
|
devfs_usecount_sub(vp);
|
||||||
|
|
||||||
dev_relthread(dev, ref);
|
dev_relthread(dev, ref);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
if (error == ERESTART)
|
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));
|
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
|
static int
|
||||||
devfs_reclaim(struct vop_reclaim_args *ap)
|
devfs_reclaim(struct vop_reclaim_args *ap)
|
||||||
{
|
{
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
struct devfs_dirent *de;
|
|
||||||
|
|
||||||
vp = ap->a_vp;
|
vp = ap->a_vp;
|
||||||
mtx_lock(&devfs_de_interlock);
|
mtx_lock(&devfs_de_interlock);
|
||||||
de = vp->v_data;
|
devfs_reclaiml(vp);
|
||||||
if (de != NULL) {
|
|
||||||
de->de_vnode = NULL;
|
|
||||||
vp->v_data = NULL;
|
|
||||||
}
|
|
||||||
mtx_unlock(&devfs_de_interlock);
|
mtx_unlock(&devfs_de_interlock);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -1432,14 +1560,14 @@ devfs_reclaim_vchr(struct vop_reclaim_args *ap)
|
|||||||
vp = ap->a_vp;
|
vp = ap->a_vp;
|
||||||
MPASS(vp->v_type == VCHR);
|
MPASS(vp->v_type == VCHR);
|
||||||
|
|
||||||
devfs_reclaim(ap);
|
mtx_lock(&devfs_de_interlock);
|
||||||
|
|
||||||
VI_LOCK(vp);
|
VI_LOCK(vp);
|
||||||
|
devfs_usecount_subl(vp);
|
||||||
|
devfs_reclaiml(vp);
|
||||||
|
mtx_unlock(&devfs_de_interlock);
|
||||||
dev_lock();
|
dev_lock();
|
||||||
dev = vp->v_rdev;
|
dev = vp->v_rdev;
|
||||||
vp->v_rdev = NULL;
|
vp->v_rdev = NULL;
|
||||||
if (dev != NULL)
|
|
||||||
dev->si_usecount -= (vp->v_usecount > 0);
|
|
||||||
dev_unlock();
|
dev_unlock();
|
||||||
VI_UNLOCK(vp);
|
VI_UNLOCK(vp);
|
||||||
if (dev != NULL)
|
if (dev != NULL)
|
||||||
|
@ -336,6 +336,7 @@ struct nfsreferral {
|
|||||||
#define LCL_DONEBINDCONN 0x00040000
|
#define LCL_DONEBINDCONN 0x00040000
|
||||||
#define LCL_RECLAIMONEFS 0x00080000
|
#define LCL_RECLAIMONEFS 0x00080000
|
||||||
#define LCL_NFSV42 0x00100000
|
#define LCL_NFSV42 0x00100000
|
||||||
|
#define LCL_TLSCB 0x00200000
|
||||||
|
|
||||||
#define LCL_GSS LCL_KERBV /* Or of all mechs */
|
#define LCL_GSS LCL_KERBV /* Or of all mechs */
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ static int nfsv2_procid[NFS_V3NPROCS] = {
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp,
|
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 rcvreserve, sndreserve;
|
||||||
int pktscale, pktscalesav;
|
int pktscale, pktscalesav;
|
||||||
@ -374,6 +374,8 @@ newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp,
|
|||||||
} else {
|
} else {
|
||||||
retries = NFSV4_CALLBACKRETRY * callback_retry_mult;
|
retries = NFSV4_CALLBACKRETRY * callback_retry_mult;
|
||||||
}
|
}
|
||||||
|
if (dotls)
|
||||||
|
CLNT_CONTROL(client, CLSET_TLS, &one);
|
||||||
}
|
}
|
||||||
CLNT_CONTROL(client, CLSET_RETRIES, &retries);
|
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.
|
* and let clnt_reconnect_create handle reconnects.
|
||||||
*/
|
*/
|
||||||
if (nrp->nr_client == NULL)
|
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
|
* 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);
|
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.
|
* 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;
|
rp->nr_vers = RPCNFSUSERD_VERS;
|
||||||
if (error == 0)
|
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) {
|
if (error == 0) {
|
||||||
NFSLOCKNAMEID();
|
NFSLOCKNAMEID();
|
||||||
nfsrv_nfsuserd = RUNNING;
|
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_fhtom(struct nfsrv_descript *, u_int8_t *, int, int);
|
||||||
int nfsm_advance(struct nfsrv_descript *, int, int);
|
int nfsm_advance(struct nfsrv_descript *, int, int);
|
||||||
void *nfsm_dissct(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_copycred(struct nfscred *, struct ucred *);
|
||||||
void newnfs_copyincred(struct ucred *, struct nfscred *);
|
void newnfs_copyincred(struct ucred *, struct nfscred *);
|
||||||
int nfsrv_dissectacl(struct nfsrv_descript *, NFSACL_T *, int *,
|
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 ucred *, u_int32_t, u_int32_t, u_char *, int, u_int64_t *,
|
||||||
struct nfsclsession *);
|
struct nfsclsession *);
|
||||||
int newnfs_connect(struct nfsmount *, struct nfssockreq *,
|
int newnfs_connect(struct nfsmount *, struct nfssockreq *,
|
||||||
struct ucred *, NFSPROC_T *, int);
|
struct ucred *, NFSPROC_T *, int, bool);
|
||||||
void newnfs_disconnect(struct nfssockreq *);
|
void newnfs_disconnect(struct nfssockreq *);
|
||||||
int newnfs_sigintr(struct nfsmount *, NFSPROC_T *);
|
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);
|
nd->nd_maxextsiz, &nd->nd_bextpg);
|
||||||
mcp = (char *)(void *)PHYS_TO_DMAP(
|
mcp = (char *)(void *)PHYS_TO_DMAP(
|
||||||
mp->m_epg_pa[nd->nd_bextpg]);
|
mp->m_epg_pa[nd->nd_bextpg]);
|
||||||
nd->nd_bextpgsiz = PAGE_SIZE;
|
nd->nd_bextpgsiz = mlen = PAGE_SIZE;
|
||||||
} else {
|
} else {
|
||||||
if (clflg)
|
if (clflg)
|
||||||
NFSMCLGET(mp, M_WAITOK);
|
NFSMCLGET(mp, M_WAITOK);
|
||||||
|
@ -5617,7 +5617,7 @@ nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_in *sin,
|
|||||||
* unmount, but I did it anyhow.
|
* unmount, but I did it anyhow.
|
||||||
*/
|
*/
|
||||||
nrp->nr_cred = crhold(nmp->nm_sockreq.nr_cred);
|
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);
|
NFSCL_DEBUG(3, "DS connect=%d\n", error);
|
||||||
|
|
||||||
dsp = NULL;
|
dsp = NULL;
|
||||||
|
@ -718,7 +718,7 @@ nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
|
|||||||
nmp->nm_soproto = argp->proto;
|
nmp->nm_soproto = argp->proto;
|
||||||
if (nmp->nm_sotype == SOCK_DGRAM)
|
if (nmp->nm_sotype == SOCK_DGRAM)
|
||||||
while (newnfs_connect(nmp, &nmp->nm_sockreq,
|
while (newnfs_connect(nmp, &nmp->nm_sockreq,
|
||||||
cred, td, 0)) {
|
cred, td, 0, false)) {
|
||||||
printf("newnfs_args: retrying connect\n");
|
printf("newnfs_args: retrying connect\n");
|
||||||
(void) nfs_catnap(PSOCK, 0, "nfscon");
|
(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;
|
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;
|
goto bad;
|
||||||
/* For NFSv4.1, get the clientid now. */
|
/* For NFSv4.1, get the clientid now. */
|
||||||
if (nmp->nm_minorvers > 0) {
|
if (nmp->nm_minorvers > 0) {
|
||||||
|
@ -4423,6 +4423,7 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp,
|
|||||||
u_int32_t callback;
|
u_int32_t callback;
|
||||||
struct nfsdsession *sep = NULL;
|
struct nfsdsession *sep = NULL;
|
||||||
uint64_t tval;
|
uint64_t tval;
|
||||||
|
bool dotls;
|
||||||
|
|
||||||
nd = malloc(sizeof(*nd), M_TEMP, M_WAITOK | M_ZERO);
|
nd = malloc(sizeof(*nd), M_TEMP, M_WAITOK | M_ZERO);
|
||||||
cred = newnfs_getcred();
|
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().
|
* 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);
|
(void) newnfs_sndlock(&clp->lc_req.nr_lock);
|
||||||
if (clp->lc_req.nr_client == NULL) {
|
if (clp->lc_req.nr_client == NULL) {
|
||||||
if ((clp->lc_flags & LCL_NFSV41) != 0) {
|
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);
|
nfsrv_freesession(sep, NULL);
|
||||||
} else if (nd->nd_procnum == NFSV4PROC_CBNULL)
|
} else if (nd->nd_procnum == NFSV4PROC_CBNULL)
|
||||||
error = newnfs_connect(NULL, &clp->lc_req, cred,
|
error = newnfs_connect(NULL, &clp->lc_req, cred,
|
||||||
NULL, 1);
|
NULL, 1, dotls);
|
||||||
else
|
else
|
||||||
error = newnfs_connect(NULL, &clp->lc_req, cred,
|
error = newnfs_connect(NULL, &clp->lc_req, cred,
|
||||||
NULL, 3);
|
NULL, 3, dotls);
|
||||||
}
|
}
|
||||||
newnfs_sndunlock(&clp->lc_req.nr_lock);
|
newnfs_sndunlock(&clp->lc_req.nr_lock);
|
||||||
NFSD_DEBUG(4, "aft sndunlock=%d\n", error);
|
NFSD_DEBUG(4, "aft sndunlock=%d\n", error);
|
||||||
|
@ -88,7 +88,7 @@ dev_unlock_and_free(void)
|
|||||||
struct cdev_priv *cdp;
|
struct cdev_priv *cdp;
|
||||||
struct cdevsw *csw;
|
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
|
* 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;
|
struct cdev_priv *cdp;
|
||||||
|
|
||||||
mtx_assert(&devmtx, MA_OWNED);
|
dev_lock_assert_locked();
|
||||||
cdp = cdev2priv(cdev);
|
cdp = cdev2priv(cdev);
|
||||||
KASSERT((cdp->cdp_flags & CDP_UNREF_DTR) == 0,
|
KASSERT((cdp->cdp_flags & CDP_UNREF_DTR) == 0,
|
||||||
("destroy_dev() was not called after delist_dev(%p)", cdev));
|
("destroy_dev() was not called after delist_dev(%p)", cdev));
|
||||||
@ -127,7 +127,7 @@ static void
|
|||||||
cdevsw_free_devlocked(struct cdevsw *csw)
|
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);
|
SLIST_INSERT_HEAD(&cdevsw_gt_post_list, csw, d_postfree_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ void
|
|||||||
dev_ref(struct cdev *dev)
|
dev_ref(struct cdev *dev)
|
||||||
{
|
{
|
||||||
|
|
||||||
mtx_assert(&devmtx, MA_NOTOWNED);
|
dev_lock_assert_unlocked();
|
||||||
mtx_lock(&devmtx);
|
mtx_lock(&devmtx);
|
||||||
dev->si_refcount++;
|
dev->si_refcount++;
|
||||||
mtx_unlock(&devmtx);
|
mtx_unlock(&devmtx);
|
||||||
@ -152,7 +152,7 @@ void
|
|||||||
dev_refl(struct cdev *dev)
|
dev_refl(struct cdev *dev)
|
||||||
{
|
{
|
||||||
|
|
||||||
mtx_assert(&devmtx, MA_OWNED);
|
dev_lock_assert_locked();
|
||||||
dev->si_refcount++;
|
dev->si_refcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ dev_rel(struct cdev *dev)
|
|||||||
{
|
{
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
|
|
||||||
mtx_assert(&devmtx, MA_NOTOWNED);
|
dev_lock_assert_unlocked();
|
||||||
dev_lock();
|
dev_lock();
|
||||||
dev->si_refcount--;
|
dev->si_refcount--;
|
||||||
KASSERT(dev->si_refcount >= 0,
|
KASSERT(dev->si_refcount >= 0,
|
||||||
@ -181,7 +181,7 @@ dev_refthread(struct cdev *dev, int *ref)
|
|||||||
struct cdevsw *csw;
|
struct cdevsw *csw;
|
||||||
struct cdev_priv *cdp;
|
struct cdev_priv *cdp;
|
||||||
|
|
||||||
mtx_assert(&devmtx, MA_NOTOWNED);
|
dev_lock_assert_unlocked();
|
||||||
if ((dev->si_flags & SI_ETERNAL) != 0) {
|
if ((dev->si_flags & SI_ETERNAL) != 0) {
|
||||||
*ref = 0;
|
*ref = 0;
|
||||||
return (dev->si_devsw);
|
return (dev->si_devsw);
|
||||||
@ -208,7 +208,7 @@ devvn_refthread(struct vnode *vp, struct cdev **devp, int *ref)
|
|||||||
struct cdev_priv *cdp;
|
struct cdev_priv *cdp;
|
||||||
struct cdev *dev;
|
struct cdev *dev;
|
||||||
|
|
||||||
mtx_assert(&devmtx, MA_NOTOWNED);
|
dev_lock_assert_unlocked();
|
||||||
if ((vp->v_vflag & VV_ETERNALDEV) != 0) {
|
if ((vp->v_vflag & VV_ETERNALDEV) != 0) {
|
||||||
dev = vp->v_rdev;
|
dev = vp->v_rdev;
|
||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
@ -249,7 +249,7 @@ void
|
|||||||
dev_relthread(struct cdev *dev, int ref)
|
dev_relthread(struct cdev *dev, int ref)
|
||||||
{
|
{
|
||||||
|
|
||||||
mtx_assert(&devmtx, MA_NOTOWNED);
|
dev_lock_assert_unlocked();
|
||||||
if (!ref)
|
if (!ref)
|
||||||
return;
|
return;
|
||||||
KASSERT(dev->si_threadcount > 0,
|
KASSERT(dev->si_threadcount > 0,
|
||||||
@ -570,7 +570,7 @@ newdev(struct make_dev_args *args, struct cdev *si)
|
|||||||
struct cdev *si2;
|
struct cdev *si2;
|
||||||
struct cdevsw *csw;
|
struct cdevsw *csw;
|
||||||
|
|
||||||
mtx_assert(&devmtx, MA_OWNED);
|
dev_lock_assert_locked();
|
||||||
csw = args->mda_devsw;
|
csw = args->mda_devsw;
|
||||||
si2 = NULL;
|
si2 = NULL;
|
||||||
if (csw->d_flags & D_NEEDMINOR) {
|
if (csw->d_flags & D_NEEDMINOR) {
|
||||||
@ -629,7 +629,7 @@ prep_cdevsw(struct cdevsw *devsw, int flags)
|
|||||||
{
|
{
|
||||||
struct cdevsw *dsw2;
|
struct cdevsw *dsw2;
|
||||||
|
|
||||||
mtx_assert(&devmtx, MA_OWNED);
|
dev_lock_assert_locked();
|
||||||
if (devsw->d_flags & D_INIT)
|
if (devsw->d_flags & D_INIT)
|
||||||
return (0);
|
return (0);
|
||||||
if (devsw->d_flags & D_NEEDGIANT) {
|
if (devsw->d_flags & D_NEEDGIANT) {
|
||||||
@ -714,7 +714,7 @@ prep_devname(struct cdev *dev, const char *fmt, va_list ap)
|
|||||||
int len;
|
int len;
|
||||||
char *from, *q, *s, *to;
|
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);
|
len = vsnrprintf(dev->si_name, sizeof(dev->si_name), 32, fmt, ap);
|
||||||
if (len > sizeof(dev->si_name) - 1)
|
if (len > sizeof(dev->si_name) - 1)
|
||||||
@ -1098,7 +1098,7 @@ destroy_devl(struct cdev *dev)
|
|||||||
struct cdev_privdata *p;
|
struct cdev_privdata *p;
|
||||||
struct cdev_priv *cdp;
|
struct cdev_priv *cdp;
|
||||||
|
|
||||||
mtx_assert(&devmtx, MA_OWNED);
|
dev_lock_assert_locked();
|
||||||
KASSERT(dev->si_flags & SI_NAMED,
|
KASSERT(dev->si_flags & SI_NAMED,
|
||||||
("WARNING: Driver mistake: destroy_dev on %d\n", dev2unit(dev)));
|
("WARNING: Driver mistake: destroy_dev on %d\n", dev2unit(dev)));
|
||||||
KASSERT((dev->si_flags & SI_ETERNAL) == 0,
|
KASSERT((dev->si_flags & SI_ETERNAL) == 0,
|
||||||
@ -1200,7 +1200,7 @@ delist_dev_locked(struct cdev *dev)
|
|||||||
struct cdev_priv *cdp;
|
struct cdev_priv *cdp;
|
||||||
struct cdev *child;
|
struct cdev *child;
|
||||||
|
|
||||||
mtx_assert(&devmtx, MA_OWNED);
|
dev_lock_assert_locked();
|
||||||
cdp = cdev2priv(dev);
|
cdp = cdev2priv(dev);
|
||||||
if ((cdp->cdp_flags & CDP_UNREF_DTR) != 0)
|
if ((cdp->cdp_flags & CDP_UNREF_DTR) != 0)
|
||||||
return;
|
return;
|
||||||
@ -1464,7 +1464,7 @@ destroy_dev_sched_cbl(struct cdev *dev, void (*cb)(void *), void *arg)
|
|||||||
{
|
{
|
||||||
struct cdev_priv *cp;
|
struct cdev_priv *cp;
|
||||||
|
|
||||||
mtx_assert(&devmtx, MA_OWNED);
|
dev_lock_assert_locked();
|
||||||
cp = cdev2priv(dev);
|
cp = cdev2priv(dev);
|
||||||
if (cp->cdp_flags & CDP_SCHED_DTR) {
|
if (cp->cdp_flags & CDP_SCHED_DTR) {
|
||||||
dev_unlock();
|
dev_unlock();
|
||||||
|
@ -59,6 +59,9 @@ __FBSDID("$FreeBSD$");
|
|||||||
static char *_getenv_dynamic_locked(const char *name, int *idx);
|
static char *_getenv_dynamic_locked(const char *name, int *idx);
|
||||||
static char *_getenv_dynamic(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");
|
static MALLOC_DEFINE(M_KENV, "kenv", "kernel environment");
|
||||||
|
|
||||||
#define KENV_SIZE 512 /* Maximum number of environment strings */
|
#define KENV_SIZE 512 /* Maximum number of environment strings */
|
||||||
@ -88,8 +91,6 @@ bool dynamic_kenv;
|
|||||||
#define KENV_CHECK if (!dynamic_kenv) \
|
#define KENV_CHECK if (!dynamic_kenv) \
|
||||||
panic("%s: called before SI_SUB_KMEM", __func__)
|
panic("%s: called before SI_SUB_KMEM", __func__)
|
||||||
|
|
||||||
static char *getenv_string_buffer(const char *);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
sys_kenv(td, uap)
|
sys_kenv(td, uap)
|
||||||
struct thread *td;
|
struct thread *td;
|
||||||
@ -482,16 +483,24 @@ _getenv_static(const char *name)
|
|||||||
char *
|
char *
|
||||||
kern_getenv(const char *name)
|
kern_getenv(const char *name)
|
||||||
{
|
{
|
||||||
char *ret;
|
char *cp, *ret;
|
||||||
|
int len;
|
||||||
|
|
||||||
if (dynamic_kenv) {
|
if (dynamic_kenv) {
|
||||||
ret = getenv_string_buffer(name);
|
len = KENV_MNAMELEN + 1 + kenv_mvallen + 1;
|
||||||
if (ret == NULL) {
|
ret = uma_zalloc(kenv_zone, M_WAITOK | M_ZERO);
|
||||||
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
|
mtx_lock(&kenv_lock);
|
||||||
"getenv");
|
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
|
} else
|
||||||
ret = _getenv_static(name);
|
ret = _getenv_static(name);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,12 +512,9 @@ testenv(const char *name)
|
|||||||
{
|
{
|
||||||
char *cp;
|
char *cp;
|
||||||
|
|
||||||
if (dynamic_kenv) {
|
cp = kenv_acquire(name);
|
||||||
mtx_lock(&kenv_lock);
|
kenv_release(cp);
|
||||||
cp = _getenv_dynamic(name, NULL);
|
|
||||||
mtx_unlock(&kenv_lock);
|
|
||||||
} else
|
|
||||||
cp = _getenv_static(name);
|
|
||||||
if (cp != NULL)
|
if (cp != NULL)
|
||||||
return (1);
|
return (1);
|
||||||
return (0);
|
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 *
|
static char *
|
||||||
getenv_string_buffer(const char *name)
|
kenv_acquire(const char *name)
|
||||||
{
|
{
|
||||||
char *cp, *ret;
|
char *value;
|
||||||
int len;
|
|
||||||
|
|
||||||
if (dynamic_kenv) {
|
if (dynamic_kenv) {
|
||||||
len = KENV_MNAMELEN + 1 + kenv_mvallen + 1;
|
|
||||||
ret = uma_zalloc(kenv_zone, M_WAITOK | M_ZERO);
|
|
||||||
mtx_lock(&kenv_lock);
|
mtx_lock(&kenv_lock);
|
||||||
cp = _getenv_dynamic(name, NULL);
|
value = _getenv_dynamic(name, NULL);
|
||||||
if (cp != NULL)
|
if (value == NULL)
|
||||||
strlcpy(ret, cp, len);
|
mtx_unlock(&kenv_lock);
|
||||||
mtx_unlock(&kenv_lock);
|
return (value);
|
||||||
if (cp == NULL) {
|
|
||||||
uma_zfree(kenv_zone, ret);
|
|
||||||
ret = NULL;
|
|
||||||
}
|
|
||||||
} else
|
} 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;
|
char *cp;
|
||||||
|
|
||||||
if (dynamic_kenv) {
|
cp = kenv_acquire(name);
|
||||||
mtx_lock(&kenv_lock);
|
|
||||||
cp = _getenv_dynamic(name, NULL);
|
if (cp != NULL)
|
||||||
if (cp != NULL)
|
strlcpy(data, cp, size);
|
||||||
strlcpy(data, cp, size);
|
|
||||||
mtx_unlock(&kenv_lock);
|
kenv_release(cp);
|
||||||
} else {
|
|
||||||
cp = _getenv_static(name);
|
|
||||||
if (cp != NULL)
|
|
||||||
strlcpy(data, cp, size);
|
|
||||||
}
|
|
||||||
return (cp != NULL);
|
return (cp != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,16 +678,18 @@ getenv_array(const char *name, void *pdata, int size, int *psize,
|
|||||||
uint8_t shift;
|
uint8_t shift;
|
||||||
int64_t value;
|
int64_t value;
|
||||||
int64_t old;
|
int64_t old;
|
||||||
char *buf;
|
const char *buf;
|
||||||
char *end;
|
char *end;
|
||||||
char *ptr;
|
const char *ptr;
|
||||||
int n;
|
int n;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if ((buf = getenv_string_buffer(name)) == NULL)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
rc = 0; /* assume failure */
|
rc = 0; /* assume failure */
|
||||||
|
|
||||||
|
buf = kenv_acquire(name);
|
||||||
|
if (buf == NULL)
|
||||||
|
goto error;
|
||||||
|
|
||||||
/* get maximum number of elements */
|
/* get maximum number of elements */
|
||||||
size /= type_size;
|
size /= type_size;
|
||||||
|
|
||||||
@ -797,8 +804,7 @@ getenv_array(const char *name, void *pdata, int size, int *psize,
|
|||||||
if (n != 0)
|
if (n != 0)
|
||||||
rc = 1; /* success */
|
rc = 1; /* success */
|
||||||
error:
|
error:
|
||||||
if (dynamic_kenv)
|
kenv_release(buf);
|
||||||
uma_zfree(kenv_zone, buf);
|
|
||||||
return (rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -898,18 +904,21 @@ getenv_ulong(const char *name, unsigned long *data)
|
|||||||
int
|
int
|
||||||
getenv_quad(const char *name, quad_t *data)
|
getenv_quad(const char *name, quad_t *data)
|
||||||
{
|
{
|
||||||
char *value, *vtp;
|
const char *value;
|
||||||
quad_t iv;
|
char suffix, *vtp;
|
||||||
|
quad_t iv;
|
||||||
|
|
||||||
value = getenv_string_buffer(name);
|
value = kenv_acquire(name);
|
||||||
if (value == NULL)
|
if (value == NULL) {
|
||||||
return (0);
|
goto error;
|
||||||
|
}
|
||||||
iv = strtoq(value, &vtp, 0);
|
iv = strtoq(value, &vtp, 0);
|
||||||
if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) {
|
if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) {
|
||||||
freeenv(value);
|
goto error;
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
switch (vtp[0]) {
|
suffix = vtp[0];
|
||||||
|
kenv_release(value);
|
||||||
|
switch (suffix) {
|
||||||
case 't': case 'T':
|
case 't': case 'T':
|
||||||
iv *= 1024;
|
iv *= 1024;
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
@ -924,12 +933,13 @@ getenv_quad(const char *name, quad_t *data)
|
|||||||
case '\0':
|
case '\0':
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
freeenv(value);
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
freeenv(value);
|
|
||||||
*data = iv;
|
*data = iv;
|
||||||
return (1);
|
return (1);
|
||||||
|
error:
|
||||||
|
kenv_release(value);
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -88,6 +88,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <vm/vm_page.h>
|
#include <vm/vm_page.h>
|
||||||
#include <vm/uma.h>
|
#include <vm/uma.h>
|
||||||
|
|
||||||
|
#include <fs/devfs/devfs.h>
|
||||||
|
|
||||||
#ifdef COMPAT_FREEBSD32
|
#ifdef COMPAT_FREEBSD32
|
||||||
#include <compat/freebsd32/freebsd32.h>
|
#include <compat/freebsd32/freebsd32.h>
|
||||||
#include <compat/freebsd32/freebsd32_util.h>
|
#include <compat/freebsd32/freebsd32_util.h>
|
||||||
@ -858,7 +860,7 @@ killjobc(void)
|
|||||||
VOP_REVOKE(ttyvp, REVOKEALL);
|
VOP_REVOKE(ttyvp, REVOKEALL);
|
||||||
VOP_UNLOCK(ttyvp);
|
VOP_UNLOCK(ttyvp);
|
||||||
}
|
}
|
||||||
vrele(ttyvp);
|
devfs_ctty_unref(ttyvp);
|
||||||
sx_xlock(&proctree_lock);
|
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.
|
* 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)
|
if (size > uio->uio_resid)
|
||||||
size = (u_int) uio->uio_resid;
|
size = (u_int) uio->uio_resid;
|
||||||
PIPE_UNLOCK(rpipe);
|
PIPE_UNLOCK(rpipe);
|
||||||
error = uiomove_fromphys(rpipe->pipe_map.ms,
|
error = uiomove_fromphys(rpipe->pipe_pages.ms,
|
||||||
rpipe->pipe_map.pos, size, uio);
|
rpipe->pipe_pages.pos, size, uio);
|
||||||
PIPE_LOCK(rpipe);
|
PIPE_LOCK(rpipe);
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
nread += size;
|
nread += size;
|
||||||
rpipe->pipe_map.pos += size;
|
rpipe->pipe_pages.pos += size;
|
||||||
rpipe->pipe_map.cnt -= size;
|
rpipe->pipe_pages.cnt -= size;
|
||||||
if (rpipe->pipe_map.cnt == 0) {
|
if (rpipe->pipe_pages.cnt == 0) {
|
||||||
rpipe->pipe_state &= ~PIPE_WANTW;
|
rpipe->pipe_state &= ~PIPE_WANTW;
|
||||||
wakeup(rpipe);
|
wakeup(rpipe);
|
||||||
}
|
}
|
||||||
@ -865,7 +865,7 @@ pipe_build_write_buffer(struct pipe *wpipe, struct uio *uio)
|
|||||||
PIPE_LOCK_ASSERT(wpipe, MA_OWNED);
|
PIPE_LOCK_ASSERT(wpipe, MA_OWNED);
|
||||||
KASSERT((wpipe->pipe_state & PIPE_DIRECTW) == 0,
|
KASSERT((wpipe->pipe_state & PIPE_DIRECTW) == 0,
|
||||||
("%s: PIPE_DIRECTW set on %p", __func__, wpipe));
|
("%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));
|
("%s: pipe map for %p contains residual data", __func__, wpipe));
|
||||||
|
|
||||||
if (uio->uio_iov->iov_len > wpipe->pipe_buffer.size)
|
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);
|
PIPE_UNLOCK(wpipe);
|
||||||
i = vm_fault_quick_hold_pages(&curproc->p_vmspace->vm_map,
|
i = vm_fault_quick_hold_pages(&curproc->p_vmspace->vm_map,
|
||||||
(vm_offset_t)uio->uio_iov->iov_base, size, VM_PROT_READ,
|
(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);
|
PIPE_LOCK(wpipe);
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
wpipe->pipe_state &= ~PIPE_DIRECTW;
|
wpipe->pipe_state &= ~PIPE_DIRECTW;
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
wpipe->pipe_map.npages = i;
|
wpipe->pipe_pages.npages = i;
|
||||||
wpipe->pipe_map.pos =
|
wpipe->pipe_pages.pos =
|
||||||
((vm_offset_t) uio->uio_iov->iov_base) & PAGE_MASK;
|
((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_len -= size;
|
||||||
uio->uio_iov->iov_base = (char *)uio->uio_iov->iov_base + 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);
|
PIPE_LOCK_ASSERT(wpipe, MA_OWNED);
|
||||||
KASSERT((wpipe->pipe_state & PIPE_DIRECTW) != 0,
|
KASSERT((wpipe->pipe_state & PIPE_DIRECTW) != 0,
|
||||||
("%s: PIPE_DIRECTW not set on %p", __func__, wpipe));
|
("%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));
|
("%s: pipe map for %p contains residual data", __func__, wpipe));
|
||||||
|
|
||||||
wpipe->pipe_state &= ~PIPE_DIRECTW;
|
wpipe->pipe_state &= ~PIPE_DIRECTW;
|
||||||
vm_page_unhold_pages(wpipe->pipe_map.ms, wpipe->pipe_map.npages);
|
vm_page_unhold_pages(wpipe->pipe_pages.ms, wpipe->pipe_pages.npages);
|
||||||
wpipe->pipe_map.npages = 0;
|
wpipe->pipe_pages.npages = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -933,9 +933,9 @@ pipe_clone_write_buffer(struct pipe *wpipe)
|
|||||||
KASSERT((wpipe->pipe_state & PIPE_DIRECTW) != 0,
|
KASSERT((wpipe->pipe_state & PIPE_DIRECTW) != 0,
|
||||||
("%s: PIPE_DIRECTW not set on %p", __func__, wpipe));
|
("%s: PIPE_DIRECTW not set on %p", __func__, wpipe));
|
||||||
|
|
||||||
size = wpipe->pipe_map.cnt;
|
size = wpipe->pipe_pages.cnt;
|
||||||
pos = wpipe->pipe_map.pos;
|
pos = wpipe->pipe_pages.pos;
|
||||||
wpipe->pipe_map.cnt = 0;
|
wpipe->pipe_pages.cnt = 0;
|
||||||
|
|
||||||
wpipe->pipe_buffer.in = size;
|
wpipe->pipe_buffer.in = size;
|
||||||
wpipe->pipe_buffer.out = 0;
|
wpipe->pipe_buffer.out = 0;
|
||||||
@ -951,7 +951,7 @@ pipe_clone_write_buffer(struct pipe *wpipe)
|
|||||||
uio.uio_segflg = UIO_SYSSPACE;
|
uio.uio_segflg = UIO_SYSSPACE;
|
||||||
uio.uio_rw = UIO_READ;
|
uio.uio_rw = UIO_READ;
|
||||||
uio.uio_td = curthread;
|
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_LOCK(wpipe);
|
||||||
pipe_destroy_write_buffer(wpipe);
|
pipe_destroy_write_buffer(wpipe);
|
||||||
}
|
}
|
||||||
@ -1015,7 +1015,7 @@ pipe_direct_write(struct pipe *wpipe, struct uio *uio)
|
|||||||
goto error1;
|
goto error1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (wpipe->pipe_map.cnt != 0 &&
|
while (wpipe->pipe_pages.cnt != 0 &&
|
||||||
(wpipe->pipe_state & PIPE_EOF) == 0) {
|
(wpipe->pipe_state & PIPE_EOF) == 0) {
|
||||||
if (wpipe->pipe_state & PIPE_WANTR) {
|
if (wpipe->pipe_state & PIPE_WANTR) {
|
||||||
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) {
|
if ((wpipe->pipe_state & PIPE_EOF) != 0) {
|
||||||
wpipe->pipe_map.cnt = 0;
|
wpipe->pipe_pages.cnt = 0;
|
||||||
pipe_destroy_write_buffer(wpipe);
|
pipe_destroy_write_buffer(wpipe);
|
||||||
pipeselwakeup(wpipe);
|
pipeselwakeup(wpipe);
|
||||||
error = EPIPE;
|
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
|
* pipe buffer. We break out if a signal occurs or the
|
||||||
* reader goes away.
|
* reader goes away.
|
||||||
*/
|
*/
|
||||||
if (wpipe->pipe_map.cnt != 0) {
|
if (wpipe->pipe_pages.cnt != 0) {
|
||||||
if (wpipe->pipe_state & PIPE_WANTR) {
|
if (wpipe->pipe_state & PIPE_WANTR) {
|
||||||
wpipe->pipe_state &= ~PIPE_WANTR;
|
wpipe->pipe_state &= ~PIPE_WANTR;
|
||||||
wakeup(wpipe);
|
wakeup(wpipe);
|
||||||
@ -1375,8 +1375,8 @@ pipe_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *active_cred,
|
|||||||
PIPE_UNLOCK(mpipe);
|
PIPE_UNLOCK(mpipe);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
if (mpipe->pipe_map.cnt != 0)
|
if (mpipe->pipe_pages.cnt != 0)
|
||||||
*(int *)data = mpipe->pipe_map.cnt;
|
*(int *)data = mpipe->pipe_pages.cnt;
|
||||||
else
|
else
|
||||||
*(int *)data = mpipe->pipe_buffer.cnt;
|
*(int *)data = mpipe->pipe_buffer.cnt;
|
||||||
break;
|
break;
|
||||||
@ -1431,7 +1431,7 @@ pipe_poll(struct file *fp, int events, struct ucred *active_cred,
|
|||||||
goto locked_error;
|
goto locked_error;
|
||||||
#endif
|
#endif
|
||||||
if (fp->f_flag & FREAD && events & (POLLIN | POLLRDNORM))
|
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);
|
revents |= events & (POLLIN | POLLRDNORM);
|
||||||
|
|
||||||
if (fp->f_flag & FWRITE && events & (POLLOUT | POLLWRNORM))
|
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));
|
bzero(ub, sizeof(*ub));
|
||||||
ub->st_mode = S_IFIFO;
|
ub->st_mode = S_IFIFO;
|
||||||
ub->st_blksize = PAGE_SIZE;
|
ub->st_blksize = PAGE_SIZE;
|
||||||
if (pipe->pipe_map.cnt != 0)
|
if (pipe->pipe_pages.cnt != 0)
|
||||||
ub->st_size = pipe->pipe_map.cnt;
|
ub->st_size = pipe->pipe_pages.cnt;
|
||||||
else
|
else
|
||||||
ub->st_size = pipe->pipe_buffer.cnt;
|
ub->st_size = pipe->pipe_buffer.cnt;
|
||||||
ub->st_blocks = howmany(ub->st_size, ub->st_blksize);
|
ub->st_blocks = howmany(ub->st_size, ub->st_blksize);
|
||||||
@ -1604,9 +1604,9 @@ pipe_free_kmem(struct pipe *cpipe)
|
|||||||
}
|
}
|
||||||
#ifndef PIPE_NODIRECT
|
#ifndef PIPE_NODIRECT
|
||||||
{
|
{
|
||||||
cpipe->pipe_map.cnt = 0;
|
cpipe->pipe_pages.cnt = 0;
|
||||||
cpipe->pipe_map.pos = 0;
|
cpipe->pipe_pages.pos = 0;
|
||||||
cpipe->pipe_map.npages = 0;
|
cpipe->pipe_pages.npages = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -1752,7 +1752,7 @@ filt_piperead(struct knote *kn, long hint)
|
|||||||
PIPE_LOCK_ASSERT(rpipe, MA_OWNED);
|
PIPE_LOCK_ASSERT(rpipe, MA_OWNED);
|
||||||
kn->kn_data = rpipe->pipe_buffer.cnt;
|
kn->kn_data = rpipe->pipe_buffer.cnt;
|
||||||
if (kn->kn_data == 0)
|
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 &&
|
if ((rpipe->pipe_state & PIPE_EOF) != 0 &&
|
||||||
((rpipe->pipe_state & PIPE_NAMED) == 0 ||
|
((rpipe->pipe_state & PIPE_NAMED) == 0 ||
|
||||||
|
@ -67,6 +67,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/ucred.h>
|
#include <sys/ucred.h>
|
||||||
#include <sys/vnode.h>
|
#include <sys/vnode.h>
|
||||||
|
|
||||||
|
#include <fs/devfs/devfs.h>
|
||||||
|
|
||||||
#include <machine/stdarg.h>
|
#include <machine/stdarg.h>
|
||||||
|
|
||||||
static MALLOC_DEFINE(M_TTY, "tty", "tty device");
|
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.
|
* is either changed or released.
|
||||||
*/
|
*/
|
||||||
if (vp != NULL)
|
if (vp != NULL)
|
||||||
vrele(vp);
|
devfs_ctty_unref(vp);
|
||||||
return (0);
|
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