mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-20 00:33:57 +00:00
MFhead@r322515
This commit is contained in:
commit
82baa8db5e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/runtime-coverage/; revision=322517
21
UPDATING
21
UPDATING
|
@ -51,6 +51,27 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
|
|||
|
||||
****************************** SPECIAL WARNING: ******************************
|
||||
|
||||
20170814:
|
||||
"make check" behavior (made in ^/head@r295380) has been changed to
|
||||
execute from a limited sandbox, as opposed to executing from
|
||||
${TESTSDIR}.
|
||||
|
||||
Behavioral changes:
|
||||
- The "beforecheck" and "aftercheck" targets are now specified.
|
||||
- ${CHECKDIR} (added in commit noted above) has been removed.
|
||||
- Legacy behavior can be enabled by setting
|
||||
WITHOUT_MAKE_CHECK_USE_SANDBOX in src.conf(5) or the environment.
|
||||
|
||||
If the limited sandbox mode is enabled, "make check" will execute
|
||||
"make distribution", then install, execute the tests, and clean up the
|
||||
sandbox if successful.
|
||||
|
||||
The "make distribution" and "make install" targets are typically run as
|
||||
root to set appropriate permissions and ownership at installation time.
|
||||
The end-user should set "WITH_INSTALL_AS_USER" in src.conf(5) or the
|
||||
environment if executing "make check" with limited sandbox mode using
|
||||
an unprivileged user.
|
||||
|
||||
20170808:
|
||||
Since the switch to GPT disk labels, fsck for UFS/FFS has been
|
||||
unable to automatically find alternate superblocks. As of r322297,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
PACKAGE=runtime
|
||||
PROG= cat
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
PACKAGE=runtime
|
||||
PROG= chmod
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -7,6 +7,7 @@ PACKAGE=runtime
|
|||
PROG= date
|
||||
SRCS= date.c netdate.c vary.c
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -38,6 +38,7 @@ test: ${PROG} gen
|
|||
|
||||
@rm -f gen 1M_zeroes* obs_zeroes
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
PACKAGE=runtime
|
||||
PROG= echo
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -12,6 +12,7 @@ CFLAGS+= -fwrapv
|
|||
|
||||
NO_WMISSING_VARIABLE_DECLARATIONS=
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -10,6 +10,7 @@ MAN= ln.1 symlink.7
|
|||
LINKS= ${BINDIR}/ln ${BINDIR}/link
|
||||
MLINKS= ln.1 link.1
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -14,6 +14,7 @@ CFLAGS+= -DCOLORLS
|
|||
LIBADD+= termcapw
|
||||
.endif
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
PACKAGE=runtime
|
||||
PROG= mv
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -33,6 +33,7 @@ SRCS= ar_io.c ar_subs.c buf_subs.c cache.c cpio.c file_subs.c ftree.c \
|
|||
gen_subs.c getoldopt.c options.c pat_rep.c pax.c sel_subs.c \
|
||||
tables.c tar.c tty_subs.c
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -19,6 +19,7 @@ MLINKS= pkill.1 pgrep.1
|
|||
SYMLINKS= ../..${BINDIR}/pkill /usr/bin/pkill
|
||||
SYMLINKS+= ../..${BINDIR}/pgrep /usr/bin/pgrep
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
PACKAGE=runtime
|
||||
PROG= pwait
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -64,6 +64,7 @@ syntax.c syntax.h: mksyntax
|
|||
token.h: mktokens
|
||||
sh ${.CURDIR}/mktokens
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -8,6 +8,7 @@ TESTSDIR= ${TESTSBASE}/bin/sh/${.CURDIR:T}
|
|||
ATF_TESTS_SH= functional_test
|
||||
|
||||
${PACKAGE}FILES+= sh-ac1.0
|
||||
${PACKAGE}FILES+= sh-c-missing1.0
|
||||
${PACKAGE}FILES+= sh-c1.0
|
||||
${PACKAGE}FILES+= sh-ca1.0
|
||||
${PACKAGE}FILES+= sh-fca1.0
|
||||
|
|
3
bin/sh/tests/invocation/sh-c-missing1.0
Normal file
3
bin/sh/tests/invocation/sh-c-missing1.0
Normal file
|
@ -0,0 +1,3 @@
|
|||
# $FreeBSD$
|
||||
|
||||
! echo echo bad | ${SH} -c 2>/dev/null
|
|
@ -6,6 +6,7 @@
|
|||
PACKAGE=runtime
|
||||
PROG= sleep
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -8,6 +8,7 @@ PROG= test
|
|||
LINKS= ${BINDIR}/test ${BINDIR}/[
|
||||
MLINKS= test.1 [.1
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -615,7 +615,8 @@ static bool getCompressDebugSections(opt::InputArgList &Args) {
|
|||
|
||||
// Initializes Config members by the command line options.
|
||||
void LinkerDriver::readConfigs(opt::InputArgList &Args) {
|
||||
Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition);
|
||||
Config->AllowMultipleDefinition =
|
||||
Args.hasArg(OPT_allow_multiple_definition) || hasZOption(Args, "muldefs");
|
||||
Config->AuxiliaryList = getArgs(Args, OPT_auxiliary);
|
||||
Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
|
||||
Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);
|
||||
|
|
|
@ -72,6 +72,7 @@ INCSDIR_atf-c++.hpp= ${INCLUDEDIR}
|
|||
MAN= atf-c++.3
|
||||
MLINKS+= atf-c++.3 atf-c-api++.3 # Backwards compatibility.
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include "../common.mk"
|
||||
|
|
|
@ -97,6 +97,7 @@ INCSDIR_atf-c.h= ${INCLUDEDIR}
|
|||
MAN= atf-c.3
|
||||
MLINKS+= atf-c.3 atf-c-api.3 # Backwards compatibility.
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include "../common.mk"
|
||||
|
|
|
@ -413,6 +413,7 @@ MLINKS+= archive_write_set_options.3 archive_write_set_format_option.3
|
|||
MLINKS+= archive_write_set_options.3 archive_write_set_option.3
|
||||
MLINKS+= libarchive.3 archive.3
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -173,6 +173,7 @@ libkern.${LIBC_ARCH}:: ${KMSRCS}
|
|||
${CP} ${.ALLSRC} ${DESTDIR}/sys/libkern/${LIBC_ARCH}
|
||||
.endif
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -188,7 +188,7 @@ The following options are recognized in
|
|||
.It Dv SO_LISTENINCQLEN Ta "get incomplete queue length of the socket (get only)"
|
||||
.It Dv SO_USER_COOKIE Ta "set the 'so_user_cookie' value for the socket (uint32_t, set only)"
|
||||
.It Dv SO_TS_CLOCK Ta "set specific format of timestamp returned by SO_TIMESTAMP"
|
||||
.It Dv SO_MAX_PACING_RATE "set the maximum transmit rate in bytes per second for the socket"
|
||||
.It Dv SO_MAX_PACING_RATE Ta "set the maximum transmit rate in bytes per second for the socket"
|
||||
.El
|
||||
.Pp
|
||||
.Dv SO_DEBUG
|
||||
|
|
|
@ -101,6 +101,7 @@ init_fence(void)
|
|||
#if defined(__i386__)
|
||||
u_int cpuid_supported, p[4];
|
||||
|
||||
lfence_works = LMB_NONE;
|
||||
__asm __volatile(
|
||||
" pushfl\n"
|
||||
" popl %%eax\n"
|
||||
|
@ -121,8 +122,7 @@ init_fence(void)
|
|||
cpuidp(0x1, p);
|
||||
if ((p[3] & CPUID_SSE2) != 0)
|
||||
lfence_works = select_lmb();
|
||||
} else
|
||||
lfence_works = LMB_NONE;
|
||||
}
|
||||
#elif defined(__amd64__)
|
||||
lfence_works = select_lmb();
|
||||
#else
|
||||
|
|
|
@ -47,6 +47,7 @@ SHLIB_MAJOR= 7
|
|||
|
||||
.include <src.opts.mk>
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -18,6 +18,7 @@ LIBADD= nv
|
|||
|
||||
CFLAGS+=-I${.CURDIR}
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -18,6 +18,7 @@ LIBADD= nv
|
|||
|
||||
CFLAGS+=-I${.CURDIR}
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -18,6 +18,7 @@ LIBADD= nv
|
|||
|
||||
CFLAGS+=-I${.CURDIR}
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -18,6 +18,7 @@ LIBADD= nv
|
|||
|
||||
CFLAGS+=-I${.CURDIR}
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -43,6 +43,7 @@ WARNS?= 2
|
|||
|
||||
PRECIOUSLIB=
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -38,6 +38,7 @@ MLINKS+=kvm_read.3 kvm_read2.3 kvm_read.3 kvm_write.3
|
|||
|
||||
.include <src.opts.mk>
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -15,6 +15,7 @@ CFLAGS+= -I${SRCTOP}/crypto
|
|||
VERSION_DEF= ${SRCTOP}/lib/libc/Versions.def
|
||||
SYMBOL_MAPS= ${.CURDIR}/Symbol.map
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -17,6 +17,7 @@ SRCS+= msgio.c
|
|||
SRCS+= nvlist.c
|
||||
SRCS+= nvpair.c
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -13,6 +13,7 @@ SRCS= abs2rel.c rel2abs.c
|
|||
#VERSION_DEF= ${SRCTOP/lib/libc/Versions.def
|
||||
#SYMBOL_MAPS= ${.CURDIR}/Symbol.map
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -41,6 +41,7 @@ SHLIB_MAJOR= 4
|
|||
|
||||
MAN=
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -21,6 +21,7 @@ PRECIOUSLIB=
|
|||
VERSION_DEF=${SRCTOP}/lib/libc/Versions.def
|
||||
SYMBOL_MAPS=${.CURDIR}/Symbol.map
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -14,6 +14,7 @@ VERSION_DEF= ${.CURDIR}/Version.def
|
|||
|
||||
.PATH: ${SRCTOP}/sys/kern
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -69,6 +69,7 @@ SYMLINKS+=lib${LIB}.so ${LIBDIR}/libpthread.so
|
|||
SYMLINKS+=lib${LIB}_p.a ${LIBDIR}/libpthread_p.a
|
||||
.endif
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -85,6 +85,7 @@ MLINKS+=pw_util.3 pw_copy.3 \
|
|||
pw_util.3 pw_tempname.3 \
|
||||
pw_util.3 pw_tmp.3
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -110,6 +110,7 @@ MLINKS= xo_attr.3 xo_attr_h.3 \
|
|||
xo_syslog.3 xo_set_logmask.3 \
|
||||
xo_syslog.3 xo_vsyslog.3
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -228,6 +228,7 @@ MLINKS+=trunc.3 truncf.3 trunc.3 truncl.3
|
|||
|
||||
.include <src.opts.mk>
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
|
|
@ -40,6 +40,7 @@ CFLAGS+= -DATF_SHELL='"/bin/sh"'
|
|||
|
||||
LIBADD= atf_cxx
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -72,6 +72,7 @@ FILESGROUPS= SUBR
|
|||
SUBRDIR= ${SHAREDIR}/atf
|
||||
SUBR= libatf-sh.subr
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include "../../../lib/atf/common.mk"
|
||||
|
|
|
@ -85,6 +85,7 @@ beforeinstall:
|
|||
|
||||
.PATH: ${.CURDIR}/${RTLD_ARCH}
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -18,6 +18,7 @@ CFLAGS+=-I. -I${.CURDIR}
|
|||
|
||||
CLEANFILES= y.output
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -46,6 +46,7 @@ LIBADD= util
|
|||
|
||||
WARNS?= 2
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -22,6 +22,7 @@ NO_WCAST_ALIGN= yes
|
|||
|
||||
LIBADD= util
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -67,6 +67,7 @@ MAN= ifconfig.8
|
|||
CFLAGS+= -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings -Wnested-externs
|
||||
WARNS?= 2
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -8,6 +8,7 @@ MAN= mdconfig.8
|
|||
|
||||
LIBADD= util geom
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -31,6 +31,7 @@ YFLAGS=
|
|||
|
||||
LIBADD= m md
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -266,6 +266,7 @@ SUBDIR+=pf
|
|||
.endif
|
||||
.endif
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
SUBDIR_PARALLEL=
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.\" DO NOT EDIT-- this file is generated by tools/build/options/makeman.
|
||||
.\" $FreeBSD$
|
||||
.Dd August 2, 2017
|
||||
.Dd August 14, 2017
|
||||
.Dt SRC.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -967,12 +967,12 @@ amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64 and i386/i386.
|
|||
Set to not build the LLDB debugger.
|
||||
.Pp
|
||||
This is a default setting on
|
||||
arm/arm, arm/armeb, arm/armv6, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe, riscv/riscv64, riscv/riscv64sf and sparc64/sparc64.
|
||||
arm/arm, arm/armeb, arm/armv6, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe, riscv/riscv64, riscv/riscv64sf and sparc64/sparc64.
|
||||
.It Va WITH_LLDB
|
||||
Set to build the LLDB debugger.
|
||||
.Pp
|
||||
This is a default setting on
|
||||
amd64/amd64 and arm64/aarch64.
|
||||
amd64/amd64, arm64/aarch64 and i386/i386.
|
||||
.It Va WITHOUT_LLD_BOOTSTRAP
|
||||
Set to not build the LLD linker during the bootstrap phase of
|
||||
the build.
|
||||
|
@ -1043,6 +1043,16 @@ MTA selector.
|
|||
Set to not install
|
||||
.Xr make 1
|
||||
and related support files.
|
||||
.It Va WITHOUT_MAKE_CHECK_USE_SANDBOX
|
||||
Set to not execute
|
||||
.Dq Li "make check"
|
||||
in limited sandbox mode.
|
||||
This option should be paired with
|
||||
.Va WITH_INSTALL_AS_USER
|
||||
if executed as an unprivileged user.
|
||||
See
|
||||
.Xr tests 7
|
||||
for more details.
|
||||
.It Va WITHOUT_MAN
|
||||
Set to not build manual pages.
|
||||
When set, these options are also in effect:
|
||||
|
@ -1254,13 +1264,13 @@ Set to not build profiled libraries for use with
|
|||
.Xr gprof 8 .
|
||||
.Pp
|
||||
This is a default setting on
|
||||
riscv/riscv64 and riscv/riscv64sf.
|
||||
mips/mips64el, mips/mips64, mips/mips64elhf, mips/mips64hf, riscv/riscv64 and riscv/riscv64sf.
|
||||
.It Va WITH_PROFILE
|
||||
Set to build profiled libraries for use with
|
||||
.Xr gprof 8 .
|
||||
.Pp
|
||||
This is a default setting on
|
||||
amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe and sparc64/sparc64.
|
||||
amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64, i386/i386, mips/mipsel, mips/mips, mips/mipsn32, mips/mipselhf, mips/mipshf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe and sparc64/sparc64.
|
||||
.It Va WITHOUT_QUOTAS
|
||||
Set to not build
|
||||
.Xr quota 1
|
||||
|
|
|
@ -669,7 +669,8 @@ MLINKS+=condvar.9 cv_broadcast.9 \
|
|||
condvar.9 cv_wait_unlock.9 \
|
||||
condvar.9 cv_wmesg.9
|
||||
MLINKS+=config_intrhook.9 config_intrhook_disestablish.9 \
|
||||
config_intrhook.9 config_intrhook_establish.9
|
||||
config_intrhook.9 config_intrhook_establish.9 \
|
||||
config_intrhook.9 config_intrhook_oneshot.9
|
||||
MLINKS+=contigmalloc.9 contigfree.9
|
||||
MLINKS+=casuword.9 casueword.9 \
|
||||
casuword.9 casueword32.9 \
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 24, 2006
|
||||
.Dd August 10, 2017
|
||||
.Dt CONFIG_INTRHOOK 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -35,10 +35,13 @@
|
|||
but before root is mounted
|
||||
.Sh SYNOPSIS
|
||||
.In sys/kernel.h
|
||||
.Vt typedef void (*ich_func_t)(void *arg);
|
||||
.Ft int
|
||||
.Fn config_intrhook_establish "struct intr_config_hook *hook"
|
||||
.Ft void
|
||||
.Fn config_intrhook_disestablish "struct intr_config_hook *hook"
|
||||
.Ft void
|
||||
.Fn config_intrhook_oneshot "ich_func_t func" "void *arg"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn config_intrhook_establish
|
||||
|
@ -51,6 +54,18 @@ The
|
|||
.Fn config_intrhook_disestablish
|
||||
function removes the entry from the hook queue.
|
||||
.Pp
|
||||
The
|
||||
.Fn config_intrhook_oneshot
|
||||
function schedules a function to be run as described for
|
||||
.Fn config_intrhook_establish ;
|
||||
the entry is automatically removed from the hook queue
|
||||
after that function runs.
|
||||
This is appropriate when additional device configuration must be done
|
||||
after interrupts are enabled, but there is no need to stall the
|
||||
boot process after that.
|
||||
This function allocates memory using M_WAITOK; do not call this while
|
||||
holding any non-sleepable locks.
|
||||
.Pp
|
||||
Before root is mounted, all the previously established hooks are
|
||||
run.
|
||||
The boot process is then stalled until all handlers remove their hook
|
||||
|
@ -71,8 +86,8 @@ This structure is defined as follows:
|
|||
.Bd -literal
|
||||
struct intr_config_hook {
|
||||
TAILQ_ENTRY(intr_config_hook) ich_links;/* Private */
|
||||
void (*ich_func)(void *arg); /* function to call */
|
||||
void *ich_arg; /* Argument to call */
|
||||
ich_func_t ich_func; /* function to call */
|
||||
void *ich_arg; /* Argument to call */
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
|
|
|
@ -566,7 +566,7 @@ It has seven targets:
|
|||
all:
|
||||
build the test programs.
|
||||
check:
|
||||
runs the test programs from CHECKDIR with kyua test.
|
||||
runs the test programs with kyua test.
|
||||
|
||||
The beforecheck and aftercheck targets will be invoked, if
|
||||
defined, to execute commands before and after the realcheck
|
||||
|
@ -574,8 +574,6 @@ It has seven targets:
|
|||
|
||||
The devel/kyua package must be installed before invoking this
|
||||
target.
|
||||
|
||||
See CHECKDIR for more details.
|
||||
clean:
|
||||
remove the test programs and any object files.
|
||||
cleandir:
|
||||
|
@ -603,10 +601,6 @@ ATF_TESTS_CXX The names of the ATF C++ test programs to build.
|
|||
|
||||
ATF_TESTS_SH The names of the ATF sh test programs to build.
|
||||
|
||||
CHECKDIR The directory that 'make check' executes tests from.
|
||||
|
||||
The value of CHECKDIR defaults to .OBJDIR.
|
||||
|
||||
KYUAFILE If 'auto' (the default), generate a Kyuafile out of the
|
||||
test programs defined in the Makefile. If 'yes', then a
|
||||
manually-crafted Kyuafile must be supplied with the
|
||||
|
|
|
@ -111,10 +111,9 @@ _CPUCFLAGS = -march=armv5te -D__XSCALE__
|
|||
. elif ${CPUTYPE:M*soft*} != ""
|
||||
_CPUCFLAGS = -mfloat-abi=softfp
|
||||
. elif ${CPUTYPE} == "armv6"
|
||||
# Not sure we still need ARM_ARCH_6=1 here.
|
||||
_CPUCFLAGS = -march=${CPUTYPE} -DARM_ARCH_6=1
|
||||
_CPUCFLAGS = -march=${CPUTYPE}
|
||||
. elif ${CPUTYPE} == "cortexa"
|
||||
_CPUCFLAGS = -march=armv7 -DARM_ARCH_6=1 -mfpu=vfp
|
||||
_CPUCFLAGS = -march=armv7 -mfpu=vfp
|
||||
. elif ${CPUTYPE:Marmv[4567]*} != ""
|
||||
# Handle all the armvX types that FreeBSD runs:
|
||||
# armv4, armv4t, armv5, armv5te, armv6, armv6t2, armv7, armv7-a, armv7ve
|
||||
|
|
|
@ -469,6 +469,12 @@ OBJS_DEPEND_GUESS.${_S:R}.pico+= ${_S}
|
|||
.endfor
|
||||
.endif
|
||||
|
||||
.if defined(HAS_TESTS)
|
||||
MAKE+= MK_MAKE_CHECK_USE_SANDBOX=yes
|
||||
SUBDIR_TARGETS+= check
|
||||
TESTS_LD_LIBRARY_PATH+= ${.OBJDIR}
|
||||
.endif
|
||||
|
||||
.include <bsd.dep.mk>
|
||||
.include <bsd.clang-analyze.mk>
|
||||
.include <bsd.obj.mk>
|
||||
|
|
|
@ -55,6 +55,7 @@ __DEFAULT_YES_OPTIONS = \
|
|||
INCLUDES \
|
||||
INSTALLLIB \
|
||||
KERBEROS \
|
||||
MAKE_CHECK_USE_SANDBOX \
|
||||
MAN \
|
||||
MANCOMPRESS \
|
||||
NIS \
|
||||
|
@ -63,6 +64,7 @@ __DEFAULT_YES_OPTIONS = \
|
|||
PROFILE \
|
||||
SSP \
|
||||
SYMVER \
|
||||
TESTS \
|
||||
TOOLCHAIN \
|
||||
WARNS
|
||||
|
||||
|
@ -75,6 +77,7 @@ __DEFAULT_NO_OPTIONS = \
|
|||
|
||||
__DEFAULT_DEPENDENT_OPTIONS = \
|
||||
COVERAGE/DEBUG_FILES \
|
||||
MAKE_CHECK_USE_SANDBOX/TESTS \
|
||||
STAGING_MAN/STAGING \
|
||||
STAGING_PROG/STAGING \
|
||||
STALE_STAGED/STAGING \
|
||||
|
|
|
@ -324,6 +324,13 @@ lint: ${SRCS:M*.c}
|
|||
.include <bsd.man.mk>
|
||||
.endif
|
||||
|
||||
.if defined(HAS_TESTS)
|
||||
MAKE+= MK_MAKE_CHECK_USE_SANDBOX=yes
|
||||
SUBDIR_TARGETS+= check
|
||||
TESTS_LD_LIBRARY_PATH+= ${.OBJDIR}
|
||||
TESTS_PATH+= ${.OBJDIR}
|
||||
.endif
|
||||
|
||||
.if defined(PROG)
|
||||
OBJS_DEPEND_GUESS+= ${SRCS:M*.h}
|
||||
.endif
|
||||
|
|
|
@ -160,7 +160,6 @@ __DEFAULT_YES_OPTIONS = \
|
|||
TCP_WRAPPERS \
|
||||
TCSH \
|
||||
TELNET \
|
||||
TESTS \
|
||||
TEXTPROC \
|
||||
TFTP \
|
||||
TIMED \
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
.error suite.test.mk cannot be included directly.
|
||||
.endif
|
||||
|
||||
.include <bsd.opts.mk>
|
||||
|
||||
# Name of the test suite these tests belong to. Should rarely be changed for
|
||||
# Makefiles built into the FreeBSD src tree.
|
||||
TESTSUITE?= FreeBSD
|
||||
|
@ -75,8 +77,6 @@ Kyuafile: Makefile
|
|||
@mv ${.TARGET}.tmp ${.TARGET}
|
||||
.endif
|
||||
|
||||
CHECKDIR?= ${DESTDIR}${TESTSDIR}
|
||||
|
||||
KYUA= ${LOCALBASE}/bin/kyua
|
||||
|
||||
# Definition of the "make check" target and supporting variables.
|
||||
|
@ -99,4 +99,26 @@ realcheck: .PHONY
|
|||
echo "LOCALBASE=\"${LOCALBASE}\""; \
|
||||
false; \
|
||||
fi
|
||||
@${KYUA} test -k ${CHECKDIR}/Kyuafile
|
||||
@env ${TESTS_ENV:Q} ${KYUA} test -k ${DESTDIR}${TESTSDIR}/Kyuafile
|
||||
|
||||
MAKE_CHECK_SANDBOX_DIR= ${.OBJDIR}/checkdir
|
||||
CLEANDIRS+= ${MAKE_CHECK_SANDBOX_DIR}
|
||||
|
||||
.if ${MK_MAKE_CHECK_USE_SANDBOX} != "no" && make(check)
|
||||
DESTDIR:= ${MAKE_CHECK_SANDBOX_DIR}
|
||||
|
||||
beforecheck:
|
||||
.for t in clean depend all
|
||||
@cd ${.CURDIR} && ${MAKE} $t
|
||||
.endfor
|
||||
@cd ${SRCTOP} && ${MAKE} hierarchy DESTDIR=${DESTDIR}
|
||||
@cd ${.CURDIR} && ${MAKE} install \
|
||||
DESTDIR=${DESTDIR}
|
||||
|
||||
# NOTE: this is intentional to ensure that "make check" can be run multiple
|
||||
# times. "aftercheck" won't be run if "make check" fails, is interrupted,
|
||||
# etc.
|
||||
aftercheck:
|
||||
@cd ${.CURDIR} && ${MAKE} clean
|
||||
|
||||
.endif
|
||||
|
|
|
@ -131,6 +131,7 @@ afterinstall:
|
|||
echo "Run tzsetup(8) manually to update /etc/localtime."; \
|
||||
fi
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -166,15 +166,21 @@ trap(struct trapframe *frame)
|
|||
#ifdef KDTRACE_HOOKS
|
||||
struct reg regs;
|
||||
#endif
|
||||
struct thread *td = curthread;
|
||||
struct proc *p = td->td_proc;
|
||||
ksiginfo_t ksi;
|
||||
struct thread *td;
|
||||
struct proc *p;
|
||||
register_t addr;
|
||||
#ifdef KDB
|
||||
register_t dr6;
|
||||
#endif
|
||||
int i = 0, ucode = 0;
|
||||
int i, ucode;
|
||||
u_int type;
|
||||
register_t addr = 0;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
i = 0;
|
||||
ucode = 0;
|
||||
addr = 0;
|
||||
|
||||
VM_CNT_INC(v_trap);
|
||||
type = frame->tf_trapno;
|
||||
|
@ -816,10 +822,24 @@ dblfault_handler(struct trapframe *frame)
|
|||
if (dtrace_doubletrap_func != NULL)
|
||||
(*dtrace_doubletrap_func)();
|
||||
#endif
|
||||
printf("\nFatal double fault\n");
|
||||
printf("rip = 0x%lx\n", frame->tf_rip);
|
||||
printf("rsp = 0x%lx\n", frame->tf_rsp);
|
||||
printf("rbp = 0x%lx\n", frame->tf_rbp);
|
||||
printf("\nFatal double fault\n"
|
||||
"rip %#lx rsp %#lx rbp %#lx\n"
|
||||
"rax %#lx rdx %#lx rbx %#lx\n"
|
||||
"rcx %#lx rsi %#lx rdi %#lx\n"
|
||||
"r8 %#lx r9 %#lx r10 %#lx\n"
|
||||
"r11 %#lx r12 %#lx r13 %#lx\n"
|
||||
"r14 %#lx r15 %#lx rflags %#lx\n"
|
||||
"cs %#lx ss %#lx ds %#hx es %#hx fs %#hx gs %#hx\n"
|
||||
"fsbase %#lx gsbase %#lx kgsbase %#lx\n",
|
||||
frame->tf_rip, frame->tf_rsp, frame->tf_rbp,
|
||||
frame->tf_rax, frame->tf_rdx, frame->tf_rbx,
|
||||
frame->tf_rcx, frame->tf_rdi, frame->tf_rsi,
|
||||
frame->tf_r8, frame->tf_r9, frame->tf_r10,
|
||||
frame->tf_r11, frame->tf_r12, frame->tf_r13,
|
||||
frame->tf_r14, frame->tf_r15, frame->tf_rflags,
|
||||
frame->tf_cs, frame->tf_ss, frame->tf_ds, frame->tf_es,
|
||||
frame->tf_fs, frame->tf_gs,
|
||||
rdmsr(MSR_FSBASE), rdmsr(MSR_GSBASE), rdmsr(MSR_KGSBASE));
|
||||
#ifdef SMP
|
||||
/* two separate prints in case of a trap on an unmapped page */
|
||||
printf("cpuid = %d; ", PCPU_GET(cpuid));
|
||||
|
|
|
@ -651,6 +651,38 @@ load_gs(u_short sel)
|
|||
}
|
||||
#endif
|
||||
|
||||
static __inline uint64_t
|
||||
rdfsbase(void)
|
||||
{
|
||||
uint64_t x;
|
||||
|
||||
__asm __volatile("rdfsbase %0" : "=r" (x));
|
||||
return (x);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wrfsbase(uint64_t x)
|
||||
{
|
||||
|
||||
__asm __volatile("wrfsbase %0" : : "r" (x));
|
||||
}
|
||||
|
||||
static __inline uint64_t
|
||||
rdgsbase(void)
|
||||
{
|
||||
uint64_t x;
|
||||
|
||||
__asm __volatile("rdgsbase %0" : "=r" (x));
|
||||
return (x);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wrgsbase(uint64_t x)
|
||||
{
|
||||
|
||||
__asm __volatile("wrgsbase %0" : : "r" (x));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
bare_lgdt(struct region_descriptor *addr)
|
||||
{
|
||||
|
|
|
@ -139,9 +139,11 @@ device twl_clks # twl external clocks
|
|||
|
||||
# i2c RTCs
|
||||
device ds1307 # Dallas DS1307 RTC and compatible
|
||||
device ds13rtc # All Dallas/Maxim DS13xx RTCs
|
||||
device ds1672 # Dallas DS1672 RTC
|
||||
device ds3231 # Dallas DS3231 RTC + temperature
|
||||
device nxprtc # NXP RTCs: PCA/PFC212x PCA/PCF85xx
|
||||
device s35390a # Seiko s3539x RTCs
|
||||
|
||||
# GPIO
|
||||
device gpio
|
||||
|
|
|
@ -374,7 +374,7 @@ gic_v3_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
|
|||
|
||||
switch (which) {
|
||||
case GICV3_IVAR_NIRQS:
|
||||
*result = sc->gic_nirqs;
|
||||
*result = (NIRQ - sc->gic_nirqs) / sc->gic_nchildren;
|
||||
return (0);
|
||||
case GICV3_IVAR_REDIST_VADDR:
|
||||
*result = (uintptr_t)rman_get_virtual(
|
||||
|
|
|
@ -266,10 +266,12 @@ static int
|
|||
gic_v3_ofw_bus_attach(device_t dev)
|
||||
{
|
||||
struct gic_v3_ofw_devinfo *di;
|
||||
struct gic_v3_softc *sc;
|
||||
device_t child;
|
||||
phandle_t parent, node;
|
||||
pcell_t addr_cells, size_cells;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
parent = ofw_bus_get_node(dev);
|
||||
if (parent > 0) {
|
||||
addr_cells = 2;
|
||||
|
@ -320,6 +322,7 @@ gic_v3_ofw_bus_attach(device_t dev)
|
|||
continue;
|
||||
}
|
||||
|
||||
sc->gic_nchildren++;
|
||||
device_set_ivars(child, di);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -228,6 +228,9 @@ struct gicv3_its_softc {
|
|||
struct intr_pic *sc_pic;
|
||||
struct resource *sc_its_res;
|
||||
|
||||
cpuset_t sc_cpus;
|
||||
u_int gic_irq_cpu;
|
||||
|
||||
struct its_ptable sc_its_ptab[GITS_BASER_NUM];
|
||||
struct its_col *sc_its_cols[MAXCPU]; /* Per-CPU collections */
|
||||
|
||||
|
@ -245,6 +248,8 @@ struct gicv3_its_softc {
|
|||
|
||||
vmem_t *sc_irq_alloc;
|
||||
struct gicv3_its_irqsrc *sc_irqs;
|
||||
u_int sc_irq_base;
|
||||
u_int sc_irq_length;
|
||||
|
||||
struct mtx sc_its_dev_lock;
|
||||
TAILQ_HEAD(its_dev_list, its_dev) sc_its_dev_list;
|
||||
|
@ -274,8 +279,6 @@ static const struct {
|
|||
},
|
||||
};
|
||||
|
||||
static u_int gic_irq_cpu;
|
||||
|
||||
#define gic_its_read_4(sc, reg) \
|
||||
bus_read_4((sc)->sc_its_res, (reg))
|
||||
#define gic_its_read_8(sc, reg) \
|
||||
|
@ -555,7 +558,7 @@ gicv3_its_pendtables_init(struct gicv3_its_softc *sc)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < mp_ncpus; i++) {
|
||||
if (CPU_ISSET(i, &all_cpus) == 0)
|
||||
if (CPU_ISSET(i, &sc->sc_cpus) == 0)
|
||||
continue;
|
||||
|
||||
sc->sc_pend_base[i] = (vm_offset_t)contigmalloc(
|
||||
|
@ -578,6 +581,9 @@ its_init_cpu(device_t dev, struct gicv3_its_softc *sc)
|
|||
u_int cpuid;
|
||||
int domain;
|
||||
|
||||
if (!CPU_ISSET(PCPU_GET(cpuid), &sc->sc_cpus))
|
||||
return (0);
|
||||
|
||||
if (bus_get_domain(dev, &domain) == 0) {
|
||||
if (PCPU_GET(domain) != domain)
|
||||
return (0);
|
||||
|
@ -683,7 +689,7 @@ gicv3_its_attach(device_t dev)
|
|||
struct gicv3_its_softc *sc;
|
||||
const char *name;
|
||||
uint32_t iidr;
|
||||
int err, i, rid;
|
||||
int domain, err, i, rid;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
|
@ -718,12 +724,20 @@ gicv3_its_attach(device_t dev)
|
|||
/* Protects access to the ITS command circular buffer. */
|
||||
mtx_init(&sc->sc_its_cmd_lock, "ITS cmd lock", NULL, MTX_SPIN);
|
||||
|
||||
if (bus_get_domain(dev, &domain) == 0) {
|
||||
CPU_ZERO(&sc->sc_cpus);
|
||||
if (domain < MAXMEMDOM)
|
||||
CPU_COPY(&cpuset_domain[domain], &sc->sc_cpus);
|
||||
} else {
|
||||
CPU_COPY(&all_cpus, &sc->sc_cpus);
|
||||
}
|
||||
|
||||
/* Allocate the command circular buffer */
|
||||
gicv3_its_cmdq_init(sc);
|
||||
|
||||
/* Allocate the per-CPU collections */
|
||||
for (int cpu = 0; cpu < mp_ncpus; cpu++)
|
||||
if (CPU_ISSET(cpu, &all_cpus) != 0)
|
||||
if (CPU_ISSET(cpu, &sc->sc_cpus) != 0)
|
||||
sc->sc_its_cols[cpu] = malloc(
|
||||
sizeof(*sc->sc_its_cols[0]), M_GICV3_ITS,
|
||||
M_WAITOK | M_ZERO);
|
||||
|
@ -746,18 +760,18 @@ gicv3_its_attach(device_t dev)
|
|||
TAILQ_INIT(&sc->sc_its_dev_list);
|
||||
|
||||
/*
|
||||
* Create the vmem object to allocate IRQs from. We try to use all
|
||||
* IRQs not already used by the GICv3.
|
||||
* Create the vmem object to allocate INTRNG IRQs from. We try to
|
||||
* use all IRQs not already used by the GICv3.
|
||||
* XXX: This assumes there are no other interrupt controllers in the
|
||||
* system.
|
||||
*/
|
||||
sc->sc_irq_alloc = vmem_create("GICv3 ITS IRQs", 0,
|
||||
NIRQ - gicv3_get_nirqs(dev), 1, 1, M_FIRSTFIT | M_WAITOK);
|
||||
gicv3_get_nirqs(dev), 1, 1, M_FIRSTFIT | M_WAITOK);
|
||||
|
||||
sc->sc_irqs = malloc(sizeof(*sc->sc_irqs) * LPI_NIRQS, M_GICV3_ITS,
|
||||
M_WAITOK | M_ZERO);
|
||||
sc->sc_irqs = malloc(sizeof(*sc->sc_irqs) * sc->sc_irq_length,
|
||||
M_GICV3_ITS, M_WAITOK | M_ZERO);
|
||||
name = device_get_nameunit(dev);
|
||||
for (i = 0; i < LPI_NIRQS; i++) {
|
||||
for (i = 0; i < sc->sc_irq_length; i++) {
|
||||
sc->sc_irqs[i].gi_irq = i;
|
||||
err = intr_isrc_register(&sc->sc_irqs[i].gi_isrc, dev, 0,
|
||||
"%s,%u", name, i);
|
||||
|
@ -837,11 +851,11 @@ gicv3_its_intr(void *arg, uintptr_t irq)
|
|||
struct gicv3_its_irqsrc *girq;
|
||||
struct trapframe *tf;
|
||||
|
||||
irq -= GIC_FIRST_LPI;
|
||||
irq -= sc->sc_irq_base;
|
||||
girq = &sc->sc_irqs[irq];
|
||||
if (girq == NULL)
|
||||
panic("gicv3_its_intr: Invalid interrupt %ld",
|
||||
irq + GIC_FIRST_LPI);
|
||||
irq + sc->sc_irq_base);
|
||||
|
||||
tf = curthread->td_intr_frame;
|
||||
intr_isrc_dispatch(&girq->gi_isrc, tf);
|
||||
|
@ -852,10 +866,12 @@ static void
|
|||
gicv3_its_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
|
||||
{
|
||||
struct gicv3_its_irqsrc *girq;
|
||||
struct gicv3_its_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
girq = (struct gicv3_its_irqsrc *)isrc;
|
||||
gicv3_its_disable_intr(dev, isrc);
|
||||
gic_icc_write(EOIR1, girq->gi_irq + GIC_FIRST_LPI);
|
||||
gic_icc_write(EOIR1, girq->gi_irq + sc->sc_irq_base);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -869,20 +885,25 @@ static void
|
|||
gicv3_its_post_filter(device_t dev, struct intr_irqsrc *isrc)
|
||||
{
|
||||
struct gicv3_its_irqsrc *girq;
|
||||
struct gicv3_its_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
girq = (struct gicv3_its_irqsrc *)isrc;
|
||||
gic_icc_write(EOIR1, girq->gi_irq + GIC_FIRST_LPI);
|
||||
gic_icc_write(EOIR1, girq->gi_irq + sc->sc_irq_base);
|
||||
}
|
||||
|
||||
static int
|
||||
gicv3_its_bind_intr(device_t dev, struct intr_irqsrc *isrc)
|
||||
{
|
||||
struct gicv3_its_irqsrc *girq;
|
||||
struct gicv3_its_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
girq = (struct gicv3_its_irqsrc *)isrc;
|
||||
if (CPU_EMPTY(&isrc->isrc_cpu)) {
|
||||
gic_irq_cpu = intr_irq_next_cpu(gic_irq_cpu, &all_cpus);
|
||||
CPU_SETOF(gic_irq_cpu, &isrc->isrc_cpu);
|
||||
sc->gic_irq_cpu = intr_irq_next_cpu(sc->gic_irq_cpu,
|
||||
&sc->sc_cpus);
|
||||
CPU_SETOF(sc->gic_irq_cpu, &isrc->isrc_cpu);
|
||||
}
|
||||
|
||||
its_cmd_movi(dev, girq);
|
||||
|
@ -1558,7 +1579,7 @@ its_cmd_mapti(device_t dev, struct gicv3_its_irqsrc *girq)
|
|||
/* The EventID sent to the device */
|
||||
desc.cmd_desc_mapvi.id = girq->gi_irq - girq->gi_its_dev->lpis.lpi_base;
|
||||
/* The physical interrupt presented to softeware */
|
||||
desc.cmd_desc_mapvi.pid = girq->gi_irq + GIC_FIRST_LPI;
|
||||
desc.cmd_desc_mapvi.pid = girq->gi_irq + sc->sc_irq_base;
|
||||
|
||||
its_cmd_send(dev, &desc);
|
||||
}
|
||||
|
@ -1649,17 +1670,21 @@ gicv3_its_fdt_attach(device_t dev)
|
|||
phandle_t xref;
|
||||
int err;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
sc->sc_irq_length = gicv3_get_nirqs(dev);
|
||||
sc->sc_irq_base = GIC_FIRST_LPI;
|
||||
sc->sc_irq_base += device_get_unit(dev) * sc->sc_irq_length;
|
||||
|
||||
err = gicv3_its_attach(dev);
|
||||
if (err != 0)
|
||||
return (err);
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
/* Register this device as a interrupt controller */
|
||||
xref = OF_xref_from_node(ofw_bus_get_node(dev));
|
||||
sc->sc_pic = intr_pic_register(dev, xref);
|
||||
intr_pic_add_handler(device_get_parent(dev), sc->sc_pic,
|
||||
gicv3_its_intr, sc, GIC_FIRST_LPI, LPI_NIRQS);
|
||||
gicv3_its_intr, sc, sc->sc_irq_base, sc->sc_irq_length);
|
||||
|
||||
/* Register this device to handle MSI interrupts */
|
||||
intr_msi_register(dev, xref);
|
||||
|
|
|
@ -2524,8 +2524,7 @@ device iicoc # OpenCores I2C controller support
|
|||
# I2C peripheral devices
|
||||
#
|
||||
device ds1307 # Dallas DS1307 RTC and compatible
|
||||
device ds133x # Dallas DS1337, DS1338 and DS1339 RTC
|
||||
device ds1374 # Dallas DS1374 RTC
|
||||
device ds13rtc # All Dallas/Maxim ds13xx chips
|
||||
device ds1672 # Dallas DS1672 RTC
|
||||
device ds3231 # Dallas DS3231 RTC + temperature
|
||||
device icee # AT24Cxxx and compatible EEPROMs
|
||||
|
|
|
@ -1752,8 +1752,7 @@ dev/ida/ida_disk.c optional ida
|
|||
dev/ida/ida_pci.c optional ida pci
|
||||
dev/iicbus/ad7418.c optional ad7418
|
||||
dev/iicbus/ds1307.c optional ds1307
|
||||
dev/iicbus/ds133x.c optional ds133x
|
||||
dev/iicbus/ds1374.c optional ds1374
|
||||
dev/iicbus/ds13rtc.c optional ds13rtc | ds133x | ds1374
|
||||
dev/iicbus/ds1672.c optional ds1672
|
||||
dev/iicbus/ds3231.c optional ds3231
|
||||
dev/iicbus/icee.c optional icee
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2009-2012,2016 Microsoft Corp.
|
||||
* Copyright (c) 2009-2012,2016-2017 Microsoft Corp.
|
||||
* Copyright (c) 2012 NetApp Inc.
|
||||
* Copyright (c) 2012 Citrix Inc.
|
||||
* All rights reserved.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2009-2012,2016 Microsoft Corp.
|
||||
* Copyright (c) 2009-2012,2016-2017 Microsoft Corp.
|
||||
* Copyright (c) 2010-2012 Citrix Inc.
|
||||
* Copyright (c) 2012 NetApp Inc.
|
||||
* All rights reserved.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2009-2012,2016 Microsoft Corp.
|
||||
* Copyright (c) 2009-2012,2016-2017 Microsoft Corp.
|
||||
* Copyright (c) 2010-2012 Citrix Inc.
|
||||
* Copyright (c) 2012 NetApp Inc.
|
||||
* All rights reserved.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2009-2012,2016 Microsoft Corp.
|
||||
* Copyright (c) 2009-2012,2016-2017 Microsoft Corp.
|
||||
* Copyright (c) 2010-2012 Citrix Inc.
|
||||
* Copyright (c) 2012 NetApp Inc.
|
||||
* All rights reserved.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2009-2012,2016 Microsoft Corp.
|
||||
* Copyright (c) 2009-2012,2016-2017 Microsoft Corp.
|
||||
* Copyright (c) 2010-2012 Citrix Inc.
|
||||
* Copyright (c) 2012 NetApp Inc.
|
||||
* All rights reserved.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*-
|
||||
* Copyright (c) 2010-2012 Citrix Inc.
|
||||
* Copyright (c) 2009-2012,2016 Microsoft Corp.
|
||||
* Copyright (c) 2009-2012,2016-2017 Microsoft Corp.
|
||||
* Copyright (c) 2012 NetApp Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -282,6 +282,8 @@ static bool hn_xpnt_vf_isready(struct hn_softc *);
|
|||
static void hn_xpnt_vf_setready(struct hn_softc *);
|
||||
static void hn_xpnt_vf_init_taskfunc(void *, int);
|
||||
static void hn_xpnt_vf_init(struct hn_softc *);
|
||||
static void hn_xpnt_vf_setenable(struct hn_softc *);
|
||||
static void hn_xpnt_vf_setdisable(struct hn_softc *, bool);
|
||||
|
||||
static int hn_rndis_rxinfo(const void *, int,
|
||||
struct hn_rxinfo *);
|
||||
|
@ -578,6 +580,12 @@ hn_rss_key_default[NDIS_HASH_KEYSIZE_TOEPLITZ] = {
|
|||
};
|
||||
#endif /* !RSS */
|
||||
|
||||
static const struct hyperv_guid hn_guid = {
|
||||
.hv_guid = {
|
||||
0x63, 0x51, 0x61, 0xf8, 0x3e, 0xdf, 0xc5, 0x46,
|
||||
0x91, 0x3f, 0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e }
|
||||
};
|
||||
|
||||
static device_method_t hn_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, hn_probe),
|
||||
|
@ -1266,16 +1274,37 @@ hn_xpnt_vf_input(struct ifnet *vf_ifp, struct mbuf *m)
|
|||
rm_runlock(&hn_vfmap_lock, &pt);
|
||||
|
||||
if (hn_ifp != NULL) {
|
||||
/*
|
||||
* Fix up rcvif and go through hn(4)'s if_input and
|
||||
* increase ipackets.
|
||||
*/
|
||||
for (mn = m; mn != NULL; mn = mn->m_nextpkt) {
|
||||
/* Allow tapping on the VF. */
|
||||
/*
|
||||
* Allow tapping on the VF.
|
||||
*/
|
||||
ETHER_BPF_MTAP(vf_ifp, mn);
|
||||
|
||||
/*
|
||||
* Update VF stats.
|
||||
*/
|
||||
if ((vf_ifp->if_capenable & IFCAP_HWSTATS) == 0) {
|
||||
if_inc_counter(vf_ifp, IFCOUNTER_IBYTES,
|
||||
mn->m_pkthdr.len);
|
||||
}
|
||||
/*
|
||||
* XXX IFCOUNTER_IMCAST
|
||||
* This stat updating is kinda invasive, since it
|
||||
* requires two checks on the mbuf: the length check
|
||||
* and the ethernet header check. As of this write,
|
||||
* all multicast packets go directly to hn(4), which
|
||||
* makes imcast stat updating in the VF a try in vian.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Fix up rcvif and increase hn(4)'s ipackets.
|
||||
*/
|
||||
mn->m_pkthdr.rcvif = hn_ifp;
|
||||
if_inc_counter(hn_ifp, IFCOUNTER_IPACKETS, 1);
|
||||
}
|
||||
/*
|
||||
* Go through hn(4)'s if_input.
|
||||
*/
|
||||
hn_ifp->if_input(hn_ifp, m);
|
||||
} else {
|
||||
/*
|
||||
|
@ -1405,6 +1434,40 @@ hn_xpnt_vf_isready(struct hn_softc *sc)
|
|||
return (true);
|
||||
}
|
||||
|
||||
static void
|
||||
hn_xpnt_vf_setenable(struct hn_softc *sc)
|
||||
{
|
||||
int i;
|
||||
|
||||
HN_LOCK_ASSERT(sc);
|
||||
|
||||
/* NOTE: hn_vf_lock for hn_transmit()/hn_qflush() */
|
||||
rm_wlock(&sc->hn_vf_lock);
|
||||
sc->hn_xvf_flags |= HN_XVFFLAG_ENABLED;
|
||||
rm_wunlock(&sc->hn_vf_lock);
|
||||
|
||||
for (i = 0; i < sc->hn_rx_ring_cnt; ++i)
|
||||
sc->hn_rx_ring[i].hn_rx_flags |= HN_RX_FLAG_XPNT_VF;
|
||||
}
|
||||
|
||||
static void
|
||||
hn_xpnt_vf_setdisable(struct hn_softc *sc, bool clear_vf)
|
||||
{
|
||||
int i;
|
||||
|
||||
HN_LOCK_ASSERT(sc);
|
||||
|
||||
/* NOTE: hn_vf_lock for hn_transmit()/hn_qflush() */
|
||||
rm_wlock(&sc->hn_vf_lock);
|
||||
sc->hn_xvf_flags &= ~HN_XVFFLAG_ENABLED;
|
||||
if (clear_vf)
|
||||
sc->hn_vf_ifp = NULL;
|
||||
rm_wunlock(&sc->hn_vf_lock);
|
||||
|
||||
for (i = 0; i < sc->hn_rx_ring_cnt; ++i)
|
||||
sc->hn_rx_ring[i].hn_rx_flags &= ~HN_RX_FLAG_XPNT_VF;
|
||||
}
|
||||
|
||||
static void
|
||||
hn_xpnt_vf_init(struct hn_softc *sc)
|
||||
{
|
||||
|
@ -1438,10 +1501,8 @@ hn_xpnt_vf_init(struct hn_softc *sc)
|
|||
*/
|
||||
hn_nvs_set_datapath(sc, HN_NVS_DATAPATH_VF);
|
||||
|
||||
/* NOTE: hn_vf_lock for hn_transmit()/hn_qflush() */
|
||||
rm_wlock(&sc->hn_vf_lock);
|
||||
sc->hn_xvf_flags |= HN_XVFFLAG_ENABLED;
|
||||
rm_wunlock(&sc->hn_vf_lock);
|
||||
/* Mark transparent mode VF as enabled. */
|
||||
hn_xpnt_vf_setenable(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1627,11 +1688,8 @@ hn_ifnet_detevent(void *xsc, struct ifnet *ifp)
|
|||
hn_resume_mgmt(sc);
|
||||
}
|
||||
|
||||
/* NOTE: hn_vf_lock for hn_transmit()/hn_qflush() */
|
||||
rm_wlock(&sc->hn_vf_lock);
|
||||
sc->hn_xvf_flags &= ~HN_XVFFLAG_ENABLED;
|
||||
sc->hn_vf_ifp = NULL;
|
||||
rm_wunlock(&sc->hn_vf_lock);
|
||||
/* Mark transparent mode VF as disabled. */
|
||||
hn_xpnt_vf_setdisable(sc, true /* clear hn_vf_ifp */);
|
||||
|
||||
rm_wlock(&hn_vfmap_lock);
|
||||
|
||||
|
@ -1659,18 +1717,11 @@ hn_ifnet_lnkevent(void *xsc, struct ifnet *ifp, int link_state)
|
|||
if_link_state_change(sc->hn_ifp, link_state);
|
||||
}
|
||||
|
||||
/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
|
||||
static const struct hyperv_guid g_net_vsc_device_type = {
|
||||
.hv_guid = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
|
||||
0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E}
|
||||
};
|
||||
|
||||
static int
|
||||
hn_probe(device_t dev)
|
||||
{
|
||||
|
||||
if (VMBUS_PROBE_GUID(device_get_parent(dev), dev,
|
||||
&g_net_vsc_device_type) == 0) {
|
||||
if (VMBUS_PROBE_GUID(device_get_parent(dev), dev, &hn_guid) == 0) {
|
||||
device_set_desc(dev, "Hyper-V Network Interface");
|
||||
return BUS_PROBE_DEFAULT;
|
||||
}
|
||||
|
@ -2973,13 +3024,16 @@ static int
|
|||
hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen,
|
||||
const struct hn_rxinfo *info)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct ifnet *ifp, *hn_ifp = rxr->hn_ifp;
|
||||
struct mbuf *m_new;
|
||||
int size, do_lro = 0, do_csum = 1;
|
||||
int hash_type;
|
||||
|
||||
/* If the VF is active, inject the packet through the VF */
|
||||
ifp = rxr->hn_rxvf_ifp ? rxr->hn_rxvf_ifp : rxr->hn_ifp;
|
||||
/*
|
||||
* If the non-transparent mode VF is active, inject this packet
|
||||
* into the VF.
|
||||
*/
|
||||
ifp = rxr->hn_rxvf_ifp ? rxr->hn_rxvf_ifp : hn_ifp;
|
||||
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
|
||||
/*
|
||||
|
@ -2993,10 +3047,15 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen,
|
|||
return (0);
|
||||
}
|
||||
|
||||
if (__predict_false(dlen < ETHER_HDR_LEN)) {
|
||||
if_inc_counter(hn_ifp, IFCOUNTER_IERRORS, 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (dlen <= MHLEN) {
|
||||
m_new = m_gethdr(M_NOWAIT, MT_DATA);
|
||||
if (m_new == NULL) {
|
||||
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
|
||||
if_inc_counter(hn_ifp, IFCOUNTER_IQDROPS, 1);
|
||||
return (0);
|
||||
}
|
||||
memcpy(mtod(m_new, void *), data, dlen);
|
||||
|
@ -3017,7 +3076,7 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen,
|
|||
|
||||
m_new = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, size);
|
||||
if (m_new == NULL) {
|
||||
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
|
||||
if_inc_counter(hn_ifp, IFCOUNTER_IQDROPS, 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -3025,7 +3084,7 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen,
|
|||
}
|
||||
m_new->m_pkthdr.rcvif = ifp;
|
||||
|
||||
if (__predict_false((ifp->if_capenable & IFCAP_RXCSUM) == 0))
|
||||
if (__predict_false((hn_ifp->if_capenable & IFCAP_RXCSUM) == 0))
|
||||
do_csum = 0;
|
||||
|
||||
/* receive side checksum offload */
|
||||
|
@ -3066,8 +3125,9 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen,
|
|||
int hoff;
|
||||
|
||||
hoff = sizeof(*eh);
|
||||
if (m_new->m_len < hoff)
|
||||
goto skip;
|
||||
/* Checked at the beginning of this function. */
|
||||
KASSERT(m_new->m_len >= hoff, ("not ethernet frame"));
|
||||
|
||||
eh = mtod(m_new, struct ether_header *);
|
||||
etype = ntohs(eh->ether_type);
|
||||
if (etype == ETHERTYPE_VLAN) {
|
||||
|
@ -3122,6 +3182,37 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen,
|
|||
m_new->m_flags |= M_VLANTAG;
|
||||
}
|
||||
|
||||
/*
|
||||
* If VF is activated (tranparent/non-transparent mode does not
|
||||
* matter here).
|
||||
*
|
||||
* - Don't setup mbuf hash, if 'options RSS' is set.
|
||||
*
|
||||
* In Azure, when VF is activated, TCP SYN and SYN|ACK go
|
||||
* through hn(4) while the rest of segments and ACKs belonging
|
||||
* to the same TCP 4-tuple go through the VF. So don't setup
|
||||
* mbuf hash, if a VF is activated and 'options RSS' is not
|
||||
* enabled. hn(4) and the VF may use neither the same RSS
|
||||
* hash key nor the same RSS hash function, so the hash value
|
||||
* for packets belonging to the same flow could be different!
|
||||
*
|
||||
* - Disable LRO
|
||||
*
|
||||
* hn(4) will only receive broadcast packets, multicast packets,
|
||||
* TCP SYN and SYN|ACK (in Azure), LRO is useless for these
|
||||
* packet types.
|
||||
*
|
||||
* For non-transparent, we definitely _cannot_ enable LRO at
|
||||
* all, since the LRO flush will use hn(4) as the receiving
|
||||
* interface; i.e. hn_ifp->if_input(hn_ifp, m).
|
||||
*/
|
||||
if (hn_ifp != ifp || (rxr->hn_rx_flags & HN_RX_FLAG_XPNT_VF)) {
|
||||
do_lro = 0; /* disable LRO. */
|
||||
#ifndef RSS
|
||||
goto skip_hash; /* skip mbuf hash setup */
|
||||
#endif
|
||||
}
|
||||
|
||||
if (info->hash_info != HN_NDIS_HASH_INFO_INVALID) {
|
||||
rxr->hn_rss_pkts++;
|
||||
m_new->m_pkthdr.flowid = info->hash_value;
|
||||
|
@ -3171,15 +3262,36 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen,
|
|||
}
|
||||
M_HASHTYPE_SET(m_new, hash_type);
|
||||
|
||||
/*
|
||||
* Note: Moved RX completion back to hv_nv_on_receive() so all
|
||||
* messages (not just data messages) will trigger a response.
|
||||
*/
|
||||
|
||||
#ifndef RSS
|
||||
skip_hash:
|
||||
#endif
|
||||
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
|
||||
if (hn_ifp != ifp) {
|
||||
const struct ether_header *eh;
|
||||
|
||||
/*
|
||||
* Non-transparent mode VF is activated.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Allow tapping on hn(4).
|
||||
*/
|
||||
ETHER_BPF_MTAP(hn_ifp, m_new);
|
||||
|
||||
/*
|
||||
* Update hn(4)'s stats.
|
||||
*/
|
||||
if_inc_counter(hn_ifp, IFCOUNTER_IPACKETS, 1);
|
||||
if_inc_counter(hn_ifp, IFCOUNTER_IBYTES, m_new->m_pkthdr.len);
|
||||
/* Checked at the beginning of this function. */
|
||||
KASSERT(m_new->m_len >= ETHER_HDR_LEN, ("not ethernet frame"));
|
||||
eh = mtod(m_new, struct ether_header *);
|
||||
if (ETHER_IS_MULTICAST(eh->ether_dhost))
|
||||
if_inc_counter(hn_ifp, IFCOUNTER_IMCASTS, 1);
|
||||
}
|
||||
rxr->hn_pkts++;
|
||||
|
||||
if ((ifp->if_capenable & IFCAP_LRO) && do_lro) {
|
||||
if ((hn_ifp->if_capenable & IFCAP_LRO) && do_lro) {
|
||||
#if defined(INET) || defined(INET6)
|
||||
struct lro_ctrl *lro = &rxr->hn_lro;
|
||||
|
||||
|
@ -3192,9 +3304,7 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen,
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* We're not holding the lock here, so don't release it */
|
||||
(*ifp->if_input)(ifp, m_new);
|
||||
ifp->if_input(ifp, m_new);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -3293,7 +3403,8 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
|||
*/
|
||||
hn_resume(sc);
|
||||
|
||||
if (sc->hn_xvf_flags & HN_XVFFLAG_ENABLED) {
|
||||
if ((sc->hn_flags & HN_FLAG_RXVF) ||
|
||||
(sc->hn_xvf_flags & HN_XVFFLAG_ENABLED)) {
|
||||
/*
|
||||
* Since we have reattached the NVS part,
|
||||
* change the datapath to VF again; in case
|
||||
|
@ -3490,10 +3601,8 @@ hn_stop(struct hn_softc *sc, bool detaching)
|
|||
KASSERT(sc->hn_vf_ifp != NULL,
|
||||
("%s: VF is not attached", ifp->if_xname));
|
||||
|
||||
/* NOTE: hn_vf_lock for hn_transmit() */
|
||||
rm_wlock(&sc->hn_vf_lock);
|
||||
sc->hn_xvf_flags &= ~HN_XVFFLAG_ENABLED;
|
||||
rm_wunlock(&sc->hn_vf_lock);
|
||||
/* Mark transparent mode VF as disabled. */
|
||||
hn_xpnt_vf_setdisable(sc, false /* keep hn_vf_ifp */);
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2016 Microsoft Corp.
|
||||
* Copyright (c) 2016-2017 Microsoft Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2016 Microsoft Corp.
|
||||
* Copyright (c) 2016-2017 Microsoft Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -63,6 +63,7 @@ struct hn_rx_ring {
|
|||
struct hn_tx_ring *hn_txr;
|
||||
void *hn_pktbuf;
|
||||
int hn_pktbuf_len;
|
||||
int hn_rx_flags; /* HN_RX_FLAG_ */
|
||||
uint8_t *hn_rxbuf; /* shadow sc->hn_rxbuf */
|
||||
int hn_rx_idx;
|
||||
|
||||
|
@ -82,7 +83,6 @@ struct hn_rx_ring {
|
|||
|
||||
/* Rarely used stuffs */
|
||||
struct sysctl_oid *hn_rx_sysctl_tree;
|
||||
int hn_rx_flags;
|
||||
|
||||
void *hn_br; /* TX/RX bufring */
|
||||
struct hyperv_dma hn_br_dma;
|
||||
|
@ -96,6 +96,7 @@ struct hn_rx_ring {
|
|||
|
||||
#define HN_RX_FLAG_ATTACHED 0x0001
|
||||
#define HN_RX_FLAG_BR_REF 0x0002
|
||||
#define HN_RX_FLAG_XPNT_VF 0x0004
|
||||
|
||||
struct hn_tx_ring {
|
||||
#ifndef HN_USE_TXDESC_BUFRING
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2016 Microsoft Corp.
|
||||
* Copyright (c) 2016-2017 Microsoft Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2009-2012,2016 Microsoft Corp.
|
||||
* Copyright (c) 2009-2012,2016-2017 Microsoft Corp.
|
||||
* Copyright (c) 2012 NetApp Inc.
|
||||
* Copyright (c) 2012 Citrix Inc.
|
||||
* All rights reserved.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2009-2012 Microsoft Corp.
|
||||
* Copyright (c) 2009-2012,2017 Microsoft Corp.
|
||||
* Copyright (c) 2012 NetApp Inc.
|
||||
* Copyright (c) 2012 Citrix Inc.
|
||||
* All rights reserved.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2014,2016 Microsoft Corp.
|
||||
* Copyright (c) 2014,2016-2017 Microsoft Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2014,2016 Microsoft Corp.
|
||||
* Copyright (c) 2014,2016-2017 Microsoft Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2016 Microsoft Corp.
|
||||
* Copyright (c) 2016-2017 Microsoft Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2009-2012,2016 Microsoft Corp.
|
||||
* Copyright (c) 2009-2012,2016-2017 Microsoft Corp.
|
||||
* Copyright (c) 2012 NetApp Inc.
|
||||
* Copyright (c) 2012 Citrix Inc.
|
||||
* All rights reserved.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2009-2012,2016 Microsoft Corp.
|
||||
* Copyright (c) 2009-2012,2016-2017 Microsoft Corp.
|
||||
* Copyright (c) 2012 NetApp Inc.
|
||||
* Copyright (c) 2012 Citrix Inc.
|
||||
* All rights reserved.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2015,2016 Microsoft Corp.
|
||||
* Copyright (c) 2015,2016-2017 Microsoft Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,363 +0,0 @@
|
|||
/*-
|
||||
* Copyright (c) 2008 Stanislav Sedov <stas@FreeBSD.org>,
|
||||
* Rafal Jaworowski <raj@FreeBSD.org>,
|
||||
* Piotr Ziecik <kosmo@semihalf.com>.
|
||||
* 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 ``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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
/*
|
||||
* Dallas Semiconductor DS133X RTC sitting on the I2C bus.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/clock.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/iicbus/iicbus.h>
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
|
||||
#include "iicbus_if.h"
|
||||
#include "clock_if.h"
|
||||
|
||||
#define DS133X_DEVNAME "ds133x_rtc"
|
||||
|
||||
#define DS133X_ADDR 0xd0 /* slave address */
|
||||
#define DS133X_DATE_REG 0x0
|
||||
#define DS133X_CTRL_REG 0x0e
|
||||
#define DS133X_OSCD_FLAG 0x80
|
||||
#define DS133X_OSF_FLAG 0x80
|
||||
|
||||
#define DS133X_24H_FLAG 0x40 /* 24 hours mode. */
|
||||
#define DS133X_PM_FLAG 0x20 /* AM/PM bit. */
|
||||
#define DS133X_CENT_FLAG 0x80 /* Century selector. */
|
||||
#define DS133X_CENT_SHIFT 7
|
||||
|
||||
#define DS1338_REG_CLOCK_HALT 0x00
|
||||
#define DS1338_REG_CONTROL 0x07
|
||||
#define DS1338_CLOCK_HALT (1 << 7)
|
||||
#define DS1338_OSC_STOP (1 << 5)
|
||||
|
||||
#define DS1339_REG_CONTROL 0x0E
|
||||
#define DS1339_REG_STATUS 0x0F
|
||||
#define DS1339_OSC_STOP (1 << 7)
|
||||
#define DS1339_ENABLE_OSC (1 << 7)
|
||||
#define DS1339_BBSQI (1 << 5)
|
||||
|
||||
#define HALFSEC 500000000 /* 1/2 of second. */
|
||||
|
||||
#define MAX_IIC_DATA_SIZE 7
|
||||
|
||||
enum {
|
||||
DS1337,
|
||||
DS1338,
|
||||
DS1339,
|
||||
};
|
||||
|
||||
struct ds133x_softc {
|
||||
int sc_type;
|
||||
device_t sc_dev;
|
||||
};
|
||||
|
||||
static int
|
||||
ds133x_read(device_t dev, uint8_t address, uint8_t *data, uint8_t size)
|
||||
{
|
||||
struct iic_msg msg[] = {
|
||||
{ DS133X_ADDR, IIC_M_WR, 1, &address },
|
||||
{ DS133X_ADDR, IIC_M_RD, size, data },
|
||||
};
|
||||
|
||||
return (iicbus_transfer(dev, msg, 2));
|
||||
}
|
||||
|
||||
static int
|
||||
ds133x_write(device_t dev, uint8_t address, uint8_t *data, uint8_t size)
|
||||
{
|
||||
uint8_t buffer[MAX_IIC_DATA_SIZE + 1];
|
||||
struct iic_msg msg[] = {
|
||||
{ DS133X_ADDR, IIC_M_WR, size + 1, buffer },
|
||||
};
|
||||
|
||||
if (size > MAX_IIC_DATA_SIZE)
|
||||
return (ENOMEM);
|
||||
|
||||
buffer[0] = address;
|
||||
memcpy(buffer + 1, data, size);
|
||||
|
||||
return (iicbus_transfer(dev, msg, 1));
|
||||
}
|
||||
|
||||
static int
|
||||
ds133x_detect(device_t dev, int *sc_type)
|
||||
{
|
||||
int error;
|
||||
uint8_t reg, orig;
|
||||
|
||||
/*
|
||||
* Check for DS1338. At address 0x0F this chip has RAM, however
|
||||
* DS1337 and DS1339 have status register. Bits 6-2 in status
|
||||
* register will be always read as 0.
|
||||
*/
|
||||
|
||||
if ((error = ds133x_read(dev, DS1339_REG_STATUS, ®, 1)))
|
||||
return (error);
|
||||
|
||||
orig = reg;
|
||||
reg |= 0x7C;
|
||||
|
||||
if ((error = ds133x_write(dev, DS1339_REG_STATUS, ®, 1)))
|
||||
return (error);
|
||||
|
||||
if ((error = ds133x_read(dev, DS1339_REG_STATUS, ®, 1)))
|
||||
return (error);
|
||||
|
||||
if ((reg & 0x7C) != 0) {
|
||||
/* This is DS1338 */
|
||||
|
||||
if ((error = ds133x_write(dev, DS1339_REG_STATUS, &orig, 1)))
|
||||
return (error);
|
||||
|
||||
*sc_type = DS1338;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now Check for DS1337. Bit 5 in control register of this chip will be
|
||||
* always read as 0. In DS1339 changing of this bit is safe until
|
||||
* chip is powered up.
|
||||
*/
|
||||
|
||||
if ((error = ds133x_read(dev, DS1339_REG_CONTROL, ®, 1)))
|
||||
return (error);
|
||||
|
||||
orig = reg;
|
||||
reg |= DS1339_BBSQI;
|
||||
|
||||
if ((error = ds133x_write(dev, DS1339_REG_CONTROL, ®, 1)))
|
||||
return (error);
|
||||
|
||||
if ((error = ds133x_read(dev, DS1339_REG_CONTROL, ®, 1)))
|
||||
return (error);
|
||||
|
||||
if ((reg & DS1339_BBSQI) != 0) {
|
||||
/* This is DS1339 */
|
||||
|
||||
if ((error = ds133x_write(dev, DS1339_REG_CONTROL, &orig, 1)))
|
||||
return (error);
|
||||
|
||||
*sc_type = DS1339;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* This is DS1337 */
|
||||
*sc_type = DS1337;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ds133x_init(device_t dev, uint8_t cs_reg, uint8_t cs_bit, uint8_t osf_reg,
|
||||
uint8_t osf_bit)
|
||||
{
|
||||
int error;
|
||||
uint8_t reg;
|
||||
|
||||
if ((error = ds133x_read(dev, cs_reg, ®, 1)))
|
||||
return (error);
|
||||
|
||||
if (reg & cs_bit) { /* If clock is stopped - start it */
|
||||
reg &= ~cs_bit;
|
||||
if ((error = ds133x_write(dev, cs_reg, ®, 1)))
|
||||
return (error);
|
||||
}
|
||||
|
||||
if ((error = ds133x_read(dev, osf_reg, ®, 1)))
|
||||
return (error);
|
||||
|
||||
if (reg & osf_bit) { /* Clear oscillator stop flag */
|
||||
device_printf(dev, "RTC oscillator was stopped. Check system"
|
||||
" time and RTC battery.\n");
|
||||
reg &= ~osf_bit;
|
||||
if ((error = ds133x_write(dev, osf_reg, ®, 1)))
|
||||
return (error);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ds133x_identify(driver_t *driver, device_t parent)
|
||||
{
|
||||
|
||||
if (device_find_child(parent, DS133X_DEVNAME, -1) == NULL)
|
||||
BUS_ADD_CHILD(parent, 0, DS133X_DEVNAME, -1);
|
||||
}
|
||||
|
||||
static int
|
||||
ds133x_probe(device_t dev)
|
||||
{
|
||||
struct ds133x_softc *sc;
|
||||
int error;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
if ((error = ds133x_detect(dev, &sc->sc_type)))
|
||||
return (error);
|
||||
|
||||
switch (sc->sc_type) {
|
||||
case DS1337:
|
||||
device_set_desc(dev, "Dallas Semiconductor DS1337 RTC");
|
||||
break;
|
||||
case DS1338:
|
||||
device_set_desc(dev, "Dallas Semiconductor DS1338 RTC");
|
||||
break;
|
||||
case DS1339:
|
||||
device_set_desc(dev, "Dallas Semiconductor DS1339 RTC");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ds133x_attach(device_t dev)
|
||||
{
|
||||
struct ds133x_softc *sc = device_get_softc(dev);
|
||||
|
||||
sc->sc_dev = dev;
|
||||
|
||||
if (sc->sc_type == DS1338)
|
||||
ds133x_init(dev, DS1338_REG_CLOCK_HALT, DS1338_CLOCK_HALT,
|
||||
DS1338_REG_CONTROL, DS1338_OSC_STOP);
|
||||
else
|
||||
ds133x_init(dev, DS1339_REG_CONTROL, DS1339_ENABLE_OSC,
|
||||
DS1339_REG_STATUS, DS1339_OSC_STOP);
|
||||
|
||||
clock_register(dev, 1000000);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
ds133x_get_hours(uint8_t val)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
if (!(val & DS133X_24H_FLAG))
|
||||
ret = FROMBCD(val & 0x3f);
|
||||
else if (!(val & DS133X_PM_FLAG))
|
||||
ret = FROMBCD(val & 0x1f);
|
||||
else
|
||||
ret = FROMBCD(val & 0x1f) + 12;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
ds133x_gettime(device_t dev, struct timespec *ts)
|
||||
{
|
||||
struct ds133x_softc *sc = device_get_softc(dev);
|
||||
struct clocktime ct;
|
||||
uint8_t date[7];
|
||||
int error;
|
||||
|
||||
error = ds133x_read(dev, DS133X_DATE_REG, date, 7);
|
||||
if (error == 0) {
|
||||
ct.nsec = 0;
|
||||
ct.sec = FROMBCD(date[0] & 0x7f);
|
||||
ct.min = FROMBCD(date[1] & 0x7f);
|
||||
ct.hour = ds133x_get_hours(date[2]);
|
||||
ct.dow = FROMBCD(date[3] & 0x07) - 1;
|
||||
ct.day = FROMBCD(date[4] & 0x3f);
|
||||
ct.mon = FROMBCD(date[5] & 0x1f);
|
||||
|
||||
if (sc->sc_type == DS1338)
|
||||
ct.year = 2000 + FROMBCD(date[6]);
|
||||
else
|
||||
ct.year = 1900 + FROMBCD(date[6]) +
|
||||
((date[5] & DS133X_CENT_FLAG) >> DS133X_CENT_SHIFT) * 100;
|
||||
|
||||
error = clock_ct_to_ts(&ct, ts);
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
ds133x_settime(device_t dev, struct timespec *ts)
|
||||
{
|
||||
struct ds133x_softc *sc = device_get_softc(dev);
|
||||
struct clocktime ct;
|
||||
uint8_t date[7];
|
||||
|
||||
clock_ts_to_ct(ts, &ct);
|
||||
|
||||
date[0] = TOBCD(ct.nsec >= HALFSEC ? ct.sec + 1 : ct.sec) & 0x7f;
|
||||
date[1] = TOBCD(ct.min) & 0x7f;
|
||||
date[2] = TOBCD(ct.hour) & 0x3f; /* We use 24-hours mode. */
|
||||
date[3] = TOBCD(ct.dow + 1) & 0x07;
|
||||
date[4] = TOBCD(ct.day) & 0x3f;
|
||||
date[5] = TOBCD(ct.mon) & 0x1f;
|
||||
if (sc->sc_type == DS1338)
|
||||
date[6] = TOBCD(ct.year - 2000);
|
||||
else if (ct.year >= 2000) {
|
||||
date[5] |= DS133X_CENT_FLAG;
|
||||
date[6] = TOBCD(ct.year - 2000);
|
||||
} else
|
||||
date[6] = TOBCD(ct.year - 1900);
|
||||
|
||||
return (ds133x_write(dev, DS133X_DATE_REG, date, 7));
|
||||
}
|
||||
|
||||
static device_method_t ds133x_methods[] = {
|
||||
DEVMETHOD(device_identify, ds133x_identify),
|
||||
DEVMETHOD(device_probe, ds133x_probe),
|
||||
DEVMETHOD(device_attach, ds133x_attach),
|
||||
|
||||
DEVMETHOD(clock_gettime, ds133x_gettime),
|
||||
DEVMETHOD(clock_settime, ds133x_settime),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t ds133x_driver = {
|
||||
DS133X_DEVNAME,
|
||||
ds133x_methods,
|
||||
sizeof(struct ds133x_softc),
|
||||
};
|
||||
|
||||
static devclass_t ds133x_devclass;
|
||||
|
||||
DRIVER_MODULE(ds133x, iicbus, ds133x_driver, ds133x_devclass, 0, 0);
|
||||
MODULE_VERSION(ds133x, 1);
|
||||
MODULE_DEPEND(ds133x, iicbus, 1, 1, 1);
|
|
@ -1,137 +0,0 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2012 Broadcom Corporation
|
||||
* 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 BROADCOM ``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 BROADCOM 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/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/clock.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
#include <dev/iicbus/iicbus.h>
|
||||
|
||||
#include "iicbus_if.h"
|
||||
#include "clock_if.h"
|
||||
|
||||
#define DS1374_RTC_COUNTER 0 /* counter (bytes 0-3) */
|
||||
|
||||
struct ds1374_softc {
|
||||
uint32_t sc_addr;
|
||||
device_t sc_dev;
|
||||
};
|
||||
|
||||
static int
|
||||
ds1374_probe(device_t dev)
|
||||
{
|
||||
device_set_desc(dev, "DS1374 RTC");
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ds1374_attach(device_t dev)
|
||||
{
|
||||
struct ds1374_softc *sc = device_get_softc(dev);
|
||||
|
||||
if(sc==NULL) {
|
||||
printf("ds1374_attach device_get_softc failed\n");
|
||||
return (0);
|
||||
}
|
||||
sc->sc_dev = dev;
|
||||
sc->sc_addr = iicbus_get_addr(dev);
|
||||
|
||||
clock_register(dev, 1000);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ds1374_settime(device_t dev, struct timespec *ts)
|
||||
{
|
||||
/* NB: register pointer precedes actual data */
|
||||
uint8_t data[5] = { DS1374_RTC_COUNTER };
|
||||
struct ds1374_softc *sc = device_get_softc(dev);
|
||||
struct iic_msg msgs[1] = {
|
||||
{ sc->sc_addr, IIC_M_WR, 5, data },
|
||||
};
|
||||
|
||||
data[1] = (ts->tv_sec >> 0) & 0xff;
|
||||
data[2] = (ts->tv_sec >> 8) & 0xff;
|
||||
data[3] = (ts->tv_sec >> 16) & 0xff;
|
||||
data[4] = (ts->tv_sec >> 24) & 0xff;
|
||||
|
||||
return iicbus_transfer(dev, msgs, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
ds1374_gettime(device_t dev, struct timespec *ts)
|
||||
{
|
||||
struct ds1374_softc *sc = device_get_softc(dev);
|
||||
uint8_t addr[1] = { DS1374_RTC_COUNTER };
|
||||
uint8_t secs[4];
|
||||
struct iic_msg msgs[2] = {
|
||||
{ sc->sc_addr, IIC_M_WR, 1, addr },
|
||||
{ sc->sc_addr, IIC_M_RD, 4, secs },
|
||||
};
|
||||
int error;
|
||||
|
||||
error = iicbus_transfer(dev, msgs, 2);
|
||||
if (error == 0) {
|
||||
/* counter has seconds since epoch */
|
||||
ts->tv_sec = (secs[3] << 24) | (secs[2] << 16)
|
||||
| (secs[1] << 8) | (secs[0] << 0);
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static device_method_t ds1374_methods[] = {
|
||||
DEVMETHOD(device_probe, ds1374_probe),
|
||||
DEVMETHOD(device_attach, ds1374_attach),
|
||||
|
||||
DEVMETHOD(clock_gettime, ds1374_gettime),
|
||||
DEVMETHOD(clock_settime, ds1374_settime),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t ds1374_driver = {
|
||||
"ds1374_rtc",
|
||||
ds1374_methods,
|
||||
sizeof(struct ds1374_softc),
|
||||
};
|
||||
static devclass_t ds1374_devclass;
|
||||
|
||||
DRIVER_MODULE(ds1374, iicbus, ds1374_driver, ds1374_devclass, 0, 0);
|
||||
MODULE_VERSION(ds1374, 1);
|
||||
MODULE_DEPEND(ds1374, iicbus, 1, 1, 1);
|
629
sys/dev/iicbus/ds13rtc.c
Normal file
629
sys/dev/iicbus/ds13rtc.c
Normal file
|
@ -0,0 +1,629 @@
|
|||
/*-
|
||||
* Copyright (c) 2017 Ian Lepore <ian@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$");
|
||||
|
||||
/*
|
||||
* Driver for Dallas/Maxim DS13xx real-time clock/calendar chips:
|
||||
*
|
||||
* - DS1307 = Original/basic rtc + 56 bytes ram; 5v only.
|
||||
* - DS1308 = Updated 1307, available in 1.8v-5v variations.
|
||||
* - DS1337 = Like 1308, integrated xtal, 32khz output on at powerup.
|
||||
* - DS1338 = Like 1308, integrated xtal.
|
||||
* - DS1339 = Like 1337, integrated xtal, integrated trickle charger.
|
||||
* - DS1340 = Like 1338, ST M41T00 compatible.
|
||||
* - DS1341 = Like 1338, can slave-sync osc to external clock signal.
|
||||
* - DS1342 = Like 1341 but requires different xtal.
|
||||
* - DS1371 = 32-bit binary counter, watchdog timer.
|
||||
* - DS1372 = 32-bit binary counter, 64-bit unique id in rom.
|
||||
* - DS1374 = 32-bit binary counter, watchdog timer, trickle charger.
|
||||
* - DS1375 = Like 1308 but only 16 bytes ram.
|
||||
* - DS1388 = Rtc, watchdog timer, 512 bytes eeprom (not sram).
|
||||
*
|
||||
* This driver supports only basic timekeeping functions. It provides no access
|
||||
* to or control over any other functionality provided by the chips.
|
||||
*/
|
||||
|
||||
#include "opt_platform.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/clock.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/libkern.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <dev/iicbus/iicbus.h>
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
#ifdef FDT
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
#endif
|
||||
|
||||
#include "clock_if.h"
|
||||
#include "iicbus_if.h"
|
||||
|
||||
/*
|
||||
* I2C address 1101 000x
|
||||
*/
|
||||
#define DS13xx_ADDR 0xd0
|
||||
|
||||
/*
|
||||
* Registers, bits within them, and masks for the various chip types.
|
||||
*/
|
||||
|
||||
#define DS13xx_R_NONE 0xff /* Placeholder */
|
||||
|
||||
#define DS130x_R_CONTROL 0x07
|
||||
#define DS133x_R_CONTROL 0x0e
|
||||
#define DS1340_R_CONTROL 0x07
|
||||
#define DS1341_R_CONTROL 0x0e
|
||||
#define DS1371_R_CONTROL 0x07
|
||||
#define DS1372_R_CONTROL 0x07
|
||||
#define DS1374_R_CONTROL 0x07
|
||||
#define DS1375_R_CONTROL 0x0e
|
||||
#define DS1388_R_CONTROL 0x0c
|
||||
|
||||
#define DS13xx_R_SECOND 0x00
|
||||
#define DS1388_R_SECOND 0x01
|
||||
|
||||
#define DS130x_R_STATUS DS13xx_R_NONE
|
||||
#define DS133x_R_STATUS 0x0f
|
||||
#define DS1340_R_STATUS 0x09
|
||||
#define DS137x_R_STATUS 0x08
|
||||
#define DS1388_R_STATUS 0x0b
|
||||
|
||||
#define DS13xx_B_STATUS_OSF 0x80 /* OSF is 1<<7 in status and sec regs */
|
||||
#define DS13xx_B_HOUR_AMPM 0x40 /* AMPM mode is bit 1<<6 */
|
||||
#define DS13xx_B_HOUR_PM 0x20 /* PM hours indicated by 1<<5 */
|
||||
#define DS13xx_B_MONTH_CENTURY 0x80 /* 21st century indicated by 1<<7 */
|
||||
|
||||
#define DS13xx_M_SECOND 0x7f /* Masks for all BCD time regs... */
|
||||
#define DS13xx_M_MINUTE 0x7f
|
||||
#define DS13xx_M_12HOUR 0x1f
|
||||
#define DS13xx_M_24HOUR 0x3f
|
||||
#define DS13xx_M_DAY 0x3f
|
||||
#define DS13xx_M_MONTH 0x1f
|
||||
#define DS13xx_M_YEAR 0xff
|
||||
|
||||
/*
|
||||
* The chip types we support.
|
||||
*/
|
||||
enum {
|
||||
TYPE_NONE,
|
||||
TYPE_DS1307,
|
||||
TYPE_DS1308,
|
||||
TYPE_DS1337,
|
||||
TYPE_DS1338,
|
||||
TYPE_DS1339,
|
||||
TYPE_DS1340,
|
||||
TYPE_DS1341,
|
||||
TYPE_DS1342,
|
||||
TYPE_DS1371,
|
||||
TYPE_DS1372,
|
||||
TYPE_DS1374,
|
||||
TYPE_DS1375,
|
||||
TYPE_DS1388,
|
||||
|
||||
TYPE_COUNT
|
||||
};
|
||||
static const char *desc_strings[] = {
|
||||
"",
|
||||
"Dallas/Maxim DS1307 RTC",
|
||||
"Dallas/Maxim DS1308 RTC",
|
||||
"Dallas/Maxim DS1337 RTC",
|
||||
"Dallas/Maxim DS1338 RTC",
|
||||
"Dallas/Maxim DS1339 RTC",
|
||||
"Dallas/Maxim DS1340 RTC",
|
||||
"Dallas/Maxim DS1341 RTC",
|
||||
"Dallas/Maxim DS1342 RTC",
|
||||
"Dallas/Maxim DS1371 RTC",
|
||||
"Dallas/Maxim DS1372 RTC",
|
||||
"Dallas/Maxim DS1374 RTC",
|
||||
"Dallas/Maxim DS1375 RTC",
|
||||
"Dallas/Maxim DS1388 RTC",
|
||||
};
|
||||
CTASSERT(nitems(desc_strings) == TYPE_COUNT);
|
||||
|
||||
/*
|
||||
* The time registers in the order they are laid out in hardware.
|
||||
*/
|
||||
struct time_regs {
|
||||
uint8_t sec, min, hour, wday, day, month, year;
|
||||
};
|
||||
|
||||
struct ds13rtc_softc {
|
||||
device_t dev;
|
||||
device_t busdev;
|
||||
u_int flags; /* SC_F_* flags */
|
||||
u_int chiptype; /* Type of DS13xx chip */
|
||||
uint8_t secaddr; /* Address of seconds register */
|
||||
uint8_t osfaddr; /* Address of register with OSF */
|
||||
};
|
||||
|
||||
#define SC_F_BINARY (1u << 0) /* Time is 32-bit binary counter */
|
||||
#define SC_F_AMPM (1u << 1) /* Use PM flag in hours reg */
|
||||
#define SC_F_CENTURY (1u << 2) /* Use century bit */
|
||||
|
||||
/*
|
||||
* We use the compat_data table to look up hint strings in the non-FDT case, so
|
||||
* define the struct locally when we don't get it from ofw_bus_subr.h.
|
||||
*/
|
||||
#ifdef FDT
|
||||
typedef struct ofw_compat_data ds13_compat_data;
|
||||
#else
|
||||
typedef struct {
|
||||
const char *ocd_str;
|
||||
uintptr_t ocd_data;
|
||||
} ds13_compat_data;
|
||||
#endif
|
||||
|
||||
static ds13_compat_data compat_data[] = {
|
||||
{"dallas,ds1307", TYPE_DS1307},
|
||||
{"dallas,ds1308", TYPE_DS1308},
|
||||
{"dallas,ds1337", TYPE_DS1337},
|
||||
{"dallas,ds1338", TYPE_DS1338},
|
||||
{"dallas,ds1339", TYPE_DS1339},
|
||||
{"dallas,ds1340", TYPE_DS1340},
|
||||
{"dallas,ds1341", TYPE_DS1341},
|
||||
{"dallas,ds1342", TYPE_DS1342},
|
||||
{"dallas,ds1371", TYPE_DS1371},
|
||||
{"dallas,ds1372", TYPE_DS1372},
|
||||
{"dallas,ds1374", TYPE_DS1374},
|
||||
{"dallas,ds1375", TYPE_DS1375},
|
||||
{"dallas,ds1388", TYPE_DS1388},
|
||||
|
||||
{NULL, TYPE_NONE},
|
||||
};
|
||||
|
||||
static int
|
||||
read_reg(struct ds13rtc_softc *sc, uint8_t reg, uint8_t *val)
|
||||
{
|
||||
|
||||
return (iicdev_readfrom(sc->dev, reg, val, sizeof(*val), IIC_WAIT));
|
||||
}
|
||||
|
||||
static int
|
||||
write_reg(struct ds13rtc_softc *sc, uint8_t reg, uint8_t val)
|
||||
{
|
||||
|
||||
return (iicdev_writeto(sc->dev, reg, &val, sizeof(val), IIC_WAIT));
|
||||
}
|
||||
|
||||
static int
|
||||
read_timeregs(struct ds13rtc_softc *sc, struct time_regs *tregs)
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((err = iicdev_readfrom(sc->dev, sc->secaddr, tregs,
|
||||
sizeof(*tregs), IIC_WAIT)) != 0)
|
||||
return (err);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
write_timeregs(struct ds13rtc_softc *sc, struct time_regs *tregs)
|
||||
{
|
||||
|
||||
return (iicdev_writeto(sc->dev, sc->secaddr, tregs,
|
||||
sizeof(*tregs), IIC_WAIT));
|
||||
}
|
||||
|
||||
static int
|
||||
read_timeword(struct ds13rtc_softc *sc, time_t *secs)
|
||||
{
|
||||
int err;
|
||||
uint8_t buf[4];
|
||||
|
||||
if ((err = iicdev_readfrom(sc->dev, sc->secaddr, buf, sizeof(buf),
|
||||
IIC_WAIT)) == 0)
|
||||
*secs = le32dec(buf);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
write_timeword(struct ds13rtc_softc *sc, time_t secs)
|
||||
{
|
||||
uint8_t buf[4];
|
||||
|
||||
le32enc(buf, (uint32_t)secs);
|
||||
return (iicdev_writeto(sc->dev, sc->secaddr, buf, sizeof(buf),
|
||||
IIC_WAIT));
|
||||
}
|
||||
|
||||
static void
|
||||
ds13rtc_start(void *arg)
|
||||
{
|
||||
struct ds13rtc_softc *sc;
|
||||
uint8_t ctlreg, statreg;
|
||||
|
||||
sc = arg;
|
||||
|
||||
/*
|
||||
* Every chip in this family can be usefully initialized by writing 0 to
|
||||
* the control register, except DS1375 which has an external oscillator
|
||||
* controlled by values in the ctlreg that we know nothing about, so
|
||||
* we'd best leave them alone. For all other chips, writing 0 enables
|
||||
* the oscillator, disables signals/outputs in battery-backed mode
|
||||
* (saves power) and disables features like watchdog timers and alarms.
|
||||
*/
|
||||
switch (sc->chiptype) {
|
||||
case TYPE_DS1307:
|
||||
case TYPE_DS1308:
|
||||
case TYPE_DS1338:
|
||||
case TYPE_DS1340:
|
||||
case TYPE_DS1371:
|
||||
case TYPE_DS1372:
|
||||
case TYPE_DS1374:
|
||||
ctlreg = DS130x_R_CONTROL;
|
||||
break;
|
||||
case TYPE_DS1337:
|
||||
case TYPE_DS1339:
|
||||
ctlreg = DS133x_R_CONTROL;
|
||||
break;
|
||||
case TYPE_DS1341:
|
||||
case TYPE_DS1342:
|
||||
ctlreg = DS1341_R_CONTROL;
|
||||
break;
|
||||
case TYPE_DS1375:
|
||||
ctlreg = DS13xx_R_NONE;
|
||||
break;
|
||||
case TYPE_DS1388:
|
||||
ctlreg = DS1388_R_CONTROL;
|
||||
break;
|
||||
default:
|
||||
device_printf(sc->dev, "missing init code for this chiptype\n");
|
||||
return;
|
||||
}
|
||||
if (ctlreg != DS13xx_R_NONE)
|
||||
write_reg(sc, ctlreg, 0);
|
||||
|
||||
/*
|
||||
* Common init. Read the OSF/CH status bit and report stopped clocks to
|
||||
* the user. The status bit will be cleared the first time we write
|
||||
* valid time to the chip (and must not be cleared before that).
|
||||
*/
|
||||
if (read_reg(sc, sc->osfaddr, &statreg) != 0) {
|
||||
device_printf(sc->dev, "cannot read RTC clock status bit\n");
|
||||
return;
|
||||
}
|
||||
if (statreg & DS13xx_B_STATUS_OSF) {
|
||||
device_printf(sc->dev,
|
||||
"WARNING: RTC battery failed; time is invalid\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Figure out whether the chip is configured for AM/PM mode. On all
|
||||
* chips that do AM/PM mode, the flag bit is in the hours register,
|
||||
* which is secaddr+2.
|
||||
*/
|
||||
if ((sc->chiptype != TYPE_DS1340) && !(sc->flags & SC_F_BINARY)) {
|
||||
if (read_reg(sc, sc->secaddr + 2, &statreg) != 0) {
|
||||
device_printf(sc->dev,
|
||||
"cannot read RTC clock AM/PM bit\n");
|
||||
return;
|
||||
}
|
||||
if (statreg & DS13xx_B_HOUR_AMPM)
|
||||
sc->flags |= SC_F_AMPM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Everything looks good if we make it to here; register as an RTC.
|
||||
* Schedule RTC updates to happen just after top-of-second.
|
||||
*/
|
||||
clock_register_flags(sc->dev, 1000000, CLOCKF_SETTIME_NO_ADJ);
|
||||
clock_schedule(sc->dev, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
ds13rtc_gettime(device_t dev, struct timespec *ts)
|
||||
{
|
||||
struct clocktime ct;
|
||||
struct time_regs tregs;
|
||||
struct ds13rtc_softc *sc;
|
||||
int err;
|
||||
uint8_t statreg, hourmask;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
/* Read the OSF/CH bit; if the clock stopped we can't provide time. */
|
||||
if ((err = read_reg(sc, sc->osfaddr, &statreg)) != 0) {
|
||||
return (err);
|
||||
}
|
||||
if (statreg & DS13xx_B_STATUS_OSF)
|
||||
return (EINVAL); /* hardware is good, time is not. */
|
||||
|
||||
/* If the chip counts time in binary, we just read and return it. */
|
||||
if (sc->flags & SC_F_BINARY) {
|
||||
if ((err = read_timeword(sc, &ts->tv_sec)) != 0)
|
||||
return (err);
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Chip counts in BCD, read and decode it...
|
||||
*/
|
||||
if ((err = read_timeregs(sc, &tregs)) != 0) {
|
||||
device_printf(dev, "cannot read RTC time\n");
|
||||
return (err);
|
||||
}
|
||||
|
||||
if (sc->flags & SC_F_AMPM)
|
||||
hourmask = DS13xx_M_12HOUR;
|
||||
else
|
||||
hourmask = DS13xx_M_24HOUR;
|
||||
|
||||
ct.sec = FROMBCD(tregs.sec & DS13xx_M_SECOND);
|
||||
ct.min = FROMBCD(tregs.min & DS13xx_M_MINUTE);
|
||||
ct.hour = FROMBCD(tregs.hour & hourmask);
|
||||
ct.day = FROMBCD(tregs.day & DS13xx_M_DAY);
|
||||
ct.mon = FROMBCD(tregs.month & DS13xx_M_MONTH);
|
||||
ct.year = FROMBCD(tregs.year & DS13xx_M_YEAR);
|
||||
ct.nsec = 0;
|
||||
|
||||
if (sc->flags & SC_F_AMPM) {
|
||||
if (ct.hour == 12)
|
||||
ct.hour = 0;
|
||||
if (tregs.hour & DS13xx_B_HOUR_PM)
|
||||
ct.hour += 12;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this chip has a century bit, honor it. Otherwise let
|
||||
* clock_ct_to_ts() infer the century from the 2-digit year.
|
||||
*/
|
||||
if (sc->flags & SC_F_CENTURY)
|
||||
ct.year += (tregs.month & DS13xx_B_MONTH_CENTURY) ? 2000 : 1900;
|
||||
|
||||
err = clock_ct_to_ts(&ct, ts);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
ds13rtc_settime(device_t dev, struct timespec *ts)
|
||||
{
|
||||
struct clocktime ct;
|
||||
struct time_regs tregs;
|
||||
struct ds13rtc_softc *sc;
|
||||
int err;
|
||||
uint8_t cflag, statreg, pmflag;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
/*
|
||||
* We request a timespec with no resolution-adjustment. That also
|
||||
* disables utc adjustment, so apply that ourselves.
|
||||
*/
|
||||
ts->tv_sec -= utc_offset();
|
||||
|
||||
/* If the chip counts time in binary, store tv_sec and we're done. */
|
||||
if (sc->flags & SC_F_BINARY)
|
||||
return (write_timeword(sc, ts->tv_sec));
|
||||
|
||||
clock_ts_to_ct(ts, &ct);
|
||||
|
||||
/* If the chip is in AMPM mode deal with the PM flag. */
|
||||
pmflag = 0;
|
||||
if (sc->flags & SC_F_AMPM) {
|
||||
if (ct.hour >= 12) {
|
||||
ct.hour -= 12;
|
||||
pmflag = DS13xx_B_HOUR_PM;
|
||||
}
|
||||
if (ct.hour == 0)
|
||||
ct.hour = 12;
|
||||
}
|
||||
|
||||
/* If the chip has a century bit, set it as needed. */
|
||||
cflag = 0;
|
||||
if (sc->flags & SC_F_CENTURY) {
|
||||
if (ct.year >= 2000)
|
||||
cflag |= DS13xx_B_MONTH_CENTURY;
|
||||
}
|
||||
|
||||
tregs.sec = TOBCD(ct.sec);
|
||||
tregs.min = TOBCD(ct.min);
|
||||
tregs.hour = TOBCD(ct.hour) | pmflag;
|
||||
tregs.day = TOBCD(ct.day);
|
||||
tregs.month = TOBCD(ct.mon) | cflag;
|
||||
tregs.year = TOBCD(ct.year % 100);
|
||||
tregs.wday = ct.dow;
|
||||
|
||||
/*
|
||||
* Set the time. Reset the OSF bit if it is on and it is not part of
|
||||
* the time registers (in which case writing time resets it).
|
||||
*/
|
||||
if ((err = write_timeregs(sc, &tregs)) != 0)
|
||||
goto errout;
|
||||
if (sc->osfaddr != sc->secaddr) {
|
||||
if ((err = read_reg(sc, sc->osfaddr, &statreg)) != 0)
|
||||
goto errout;
|
||||
if (statreg & DS13xx_B_STATUS_OSF) {
|
||||
statreg &= ~DS13xx_B_STATUS_OSF;
|
||||
err = write_reg(sc, sc->osfaddr, statreg);
|
||||
}
|
||||
}
|
||||
|
||||
errout:
|
||||
|
||||
if (err != 0)
|
||||
device_printf(dev, "cannot update RTC time\n");
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
ds13rtc_get_chiptype(device_t dev)
|
||||
{
|
||||
#ifdef FDT
|
||||
|
||||
return (ofw_bus_search_compatible(dev, compat_data)->ocd_data);
|
||||
#else
|
||||
ds13_compat_data *cdata;
|
||||
const char *htype;
|
||||
|
||||
/*
|
||||
* We can only attach if provided a chiptype hint string.
|
||||
*/
|
||||
if (resource_string_value(device_get_name(dev),
|
||||
device_get_unit(dev), "compatible", &htype) != 0)
|
||||
return (TYPE_NONE);
|
||||
|
||||
/*
|
||||
* Loop through the ofw compat data comparing the hinted chip type to
|
||||
* the compat strings.
|
||||
*/
|
||||
for (cdata = compat_data; cdata->ocd_str != NULL; ++cdata) {
|
||||
if (strcmp(htype, cdata->ocd_str) == 0)
|
||||
break;
|
||||
}
|
||||
return (cdata->ocd_data);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
ds13rtc_probe(device_t dev)
|
||||
{
|
||||
int chiptype, goodrv;
|
||||
|
||||
#ifdef FDT
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
goodrv = BUS_PROBE_GENERIC;
|
||||
#else
|
||||
goodrv = BUS_PROBE_NOWILDCARD;
|
||||
#endif
|
||||
|
||||
chiptype = ds13rtc_get_chiptype(dev);
|
||||
if (chiptype == TYPE_NONE)
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, desc_strings[chiptype]);
|
||||
return (goodrv);
|
||||
}
|
||||
|
||||
static int
|
||||
ds13rtc_attach(device_t dev)
|
||||
{
|
||||
struct ds13rtc_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->dev = dev;
|
||||
sc->busdev = device_get_parent(dev);
|
||||
|
||||
/*
|
||||
* We need to know what kind of chip we're driving.
|
||||
*/
|
||||
if ((sc->chiptype = ds13rtc_get_chiptype(dev)) == TYPE_NONE) {
|
||||
device_printf(dev, "impossible: cannot determine chip type\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/* The seconds register is in the same place on all except DS1388. */
|
||||
if (sc->chiptype == TYPE_DS1388)
|
||||
sc->secaddr = DS1388_R_SECOND;
|
||||
else
|
||||
sc->secaddr = DS13xx_R_SECOND;
|
||||
|
||||
/*
|
||||
* The OSF/CH (osc failed/clock-halted) bit appears in different
|
||||
* registers for different chip types. The DS1375 has no OSF indicator
|
||||
* because it has no internal oscillator; we just point to an always-
|
||||
* zero bit in the status register for that chip.
|
||||
*/
|
||||
switch (sc->chiptype) {
|
||||
case TYPE_DS1307:
|
||||
case TYPE_DS1308:
|
||||
case TYPE_DS1338:
|
||||
sc->osfaddr = DS13xx_R_SECOND;
|
||||
break;
|
||||
case TYPE_DS1337:
|
||||
case TYPE_DS1339:
|
||||
case TYPE_DS1341:
|
||||
case TYPE_DS1342:
|
||||
case TYPE_DS1375:
|
||||
sc->osfaddr = DS133x_R_STATUS;
|
||||
sc->flags |= SC_F_CENTURY;
|
||||
break;
|
||||
case TYPE_DS1340:
|
||||
sc->osfaddr = DS1340_R_STATUS;
|
||||
break;
|
||||
case TYPE_DS1371:
|
||||
case TYPE_DS1372:
|
||||
case TYPE_DS1374:
|
||||
sc->osfaddr = DS137x_R_STATUS;
|
||||
sc->flags |= SC_F_BINARY;
|
||||
break;
|
||||
case TYPE_DS1388:
|
||||
sc->osfaddr = DS1388_R_STATUS;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have to wait until interrupts are enabled. Sometimes I2C read
|
||||
* and write only works when the interrupts are available.
|
||||
*/
|
||||
config_intrhook_oneshot(ds13rtc_start, sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ds13rtc_detach(device_t dev)
|
||||
{
|
||||
|
||||
clock_unregister(dev);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_method_t ds13rtc_methods[] = {
|
||||
DEVMETHOD(device_probe, ds13rtc_probe),
|
||||
DEVMETHOD(device_attach, ds13rtc_attach),
|
||||
DEVMETHOD(device_detach, ds13rtc_detach),
|
||||
|
||||
DEVMETHOD(clock_gettime, ds13rtc_gettime),
|
||||
DEVMETHOD(clock_settime, ds13rtc_settime),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t ds13rtc_driver = {
|
||||
"ds13rtc",
|
||||
ds13rtc_methods,
|
||||
sizeof(struct ds13rtc_softc),
|
||||
};
|
||||
|
||||
static devclass_t ds13rtc_devclass;
|
||||
|
||||
DRIVER_MODULE(ds13rtc, iicbus, ds13rtc_driver, ds13rtc_devclass, NULL, NULL);
|
||||
MODULE_VERSION(ds13rtc, 1);
|
||||
MODULE_DEPEND(ds13rtc, iicbus, IICBB_MINVER, IICBB_PREFVER, IICBB_MAXVER);
|
|
@ -191,15 +191,26 @@ struct nxprtc_softc {
|
|||
u_int chiptype; /* Type of PCF85xx chip */
|
||||
uint8_t secaddr; /* Address of seconds register */
|
||||
uint8_t tmcaddr; /* Address of timer count register */
|
||||
uint8_t slave_addr; /* PCF85xx slave address */
|
||||
bool use_timer; /* Use timer for fractional sec */
|
||||
};
|
||||
|
||||
#define SC_F_CPOL (1 << 0) /* Century bit means 19xx */
|
||||
#define SC_F_AMPM (1 << 1) /* Use PM flag in hours reg */
|
||||
|
||||
/*
|
||||
* We use the compat_data table to look up hint strings in the non-FDT case, so
|
||||
* define the struct locally when we don't get it from ofw_bus_subr.h.
|
||||
*/
|
||||
#ifdef FDT
|
||||
static struct ofw_compat_data compat_data[] = {
|
||||
typedef struct ofw_compat_data nxprtc_compat_data;
|
||||
#else
|
||||
typedef struct {
|
||||
const char *ocd_str;
|
||||
uintptr_t ocd_data;
|
||||
} nxprtc_compat_data;
|
||||
#endif
|
||||
|
||||
static nxprtc_compat_data compat_data[] = {
|
||||
{"nxp,pca2129", TYPE_PCA2129},
|
||||
{"nxp,pca8565", TYPE_PCA8565},
|
||||
{"nxp,pcf2127", TYPE_PCF2127},
|
||||
|
@ -214,7 +225,6 @@ static struct ofw_compat_data compat_data[] = {
|
|||
|
||||
{NULL, TYPE_NONE},
|
||||
};
|
||||
#endif
|
||||
|
||||
static int
|
||||
read_reg(struct nxprtc_softc *sc, uint8_t reg, uint8_t *val)
|
||||
|
@ -476,19 +486,25 @@ nxprtc_start(void *dev)
|
|||
case TYPE_PCF2127:
|
||||
if (pcf8523_start(sc) != 0)
|
||||
return;
|
||||
if (pcf2127_start_timer(sc) != 0)
|
||||
if (pcf2127_start_timer(sc) != 0) {
|
||||
device_printf(sc->dev, "cannot set up timer\n");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case TYPE_PCF8523:
|
||||
if (pcf8523_start(sc) != 0)
|
||||
return;
|
||||
if (pcf8523_start_timer(sc) != 0)
|
||||
if (pcf8523_start_timer(sc) != 0) {
|
||||
device_printf(sc->dev, "cannot set up timer\n");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case TYPE_PCA8565:
|
||||
case TYPE_PCF8563:
|
||||
if (pcf8563_start_timer(sc) != 0)
|
||||
if (pcf8563_start_timer(sc) != 0) {
|
||||
device_printf(sc->dev, "cannot set up timer\n");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
device_printf(sc->dev, "missing init code for this chiptype\n");
|
||||
|
@ -684,25 +700,60 @@ nxprtc_settime(device_t dev, struct timespec *ts)
|
|||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
nxprtc_get_chiptype(device_t dev)
|
||||
{
|
||||
#ifdef FDT
|
||||
|
||||
return (ofw_bus_search_compatible(dev, compat_data)->ocd_data);
|
||||
#else
|
||||
nxprtc_compat_data *cdata;
|
||||
const char *htype;
|
||||
int chiptype;
|
||||
|
||||
/*
|
||||
* If given a chiptype hint string, loop through the ofw compat data
|
||||
* comparing the hinted chip type to the compat strings. The table end
|
||||
* marker ocd_data is TYPE_NONE.
|
||||
*/
|
||||
if (resource_string_value(device_get_name(dev),
|
||||
device_get_unit(dev), "compatible", &htype) == 0) {
|
||||
for (cdata = compat_data; cdata->ocd_str != NULL; ++cdata) {
|
||||
if (strcmp(htype, cdata->ocd_str) == 0)
|
||||
break;
|
||||
}
|
||||
chiptype = cdata->ocd_data;
|
||||
} else
|
||||
chiptype = TYPE_NONE;
|
||||
|
||||
/*
|
||||
* On non-FDT systems the historical behavior of this driver was to
|
||||
* assume a PCF8563; keep doing that for compatibility.
|
||||
*/
|
||||
if (chiptype == TYPE_NONE)
|
||||
return (TYPE_PCF8563);
|
||||
else
|
||||
return (chiptype);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
nxprtc_probe(device_t dev)
|
||||
{
|
||||
int chiptype;
|
||||
int chiptype, rv;
|
||||
|
||||
#ifdef FDT
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
chiptype = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
|
||||
if (chiptype == TYPE_NONE)
|
||||
return (ENXIO);
|
||||
rv = BUS_PROBE_GENERIC;
|
||||
#else
|
||||
/* Historically the non-FDT driver supports only PCF8563. */
|
||||
chiptype = TYPE_PCF8563;
|
||||
rv = BUS_PROBE_NOWILDCARD;
|
||||
#endif
|
||||
device_set_desc(dev, desc_strings[chiptype]);
|
||||
if ((chiptype = nxprtc_get_chiptype(dev)) == TYPE_NONE)
|
||||
return (ENXIO);
|
||||
|
||||
return (BUS_PROBE_GENERIC);
|
||||
device_set_desc(dev, desc_strings[chiptype]);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -713,21 +764,9 @@ nxprtc_attach(device_t dev)
|
|||
sc = device_get_softc(dev);
|
||||
sc->dev = dev;
|
||||
sc->busdev = device_get_parent(dev);
|
||||
sc->slave_addr = iicbus_get_addr(dev);
|
||||
|
||||
/*
|
||||
* We need to know what kind of chip we're driving. Historically the
|
||||
* non-FDT driver supported only PCF8563. There is no machine-readable
|
||||
* identifier in the chip so we would need a set of hints defined to use
|
||||
* the other chips on non-FDT systems.
|
||||
*/
|
||||
#ifdef FDT
|
||||
sc->chiptype = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
|
||||
#else
|
||||
sc->chiptype = TYPE_PCF8563;
|
||||
if (sc->slave_addr == 0)
|
||||
sc->slave_addr = PCF8563_ADDR;
|
||||
#endif
|
||||
/* We need to know what kind of chip we're driving. */
|
||||
sc->chiptype = nxprtc_get_chiptype(dev);
|
||||
|
||||
/* The features and some register addresses vary by chip type. */
|
||||
switch (sc->chiptype) {
|
||||
|
|
|
@ -59,6 +59,8 @@ __FBSDID("$FreeBSD$");
|
|||
* Driver for Seiko Instruments S-35390A Real-time Clock
|
||||
*/
|
||||
|
||||
#include "opt_platform.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
|
@ -69,6 +71,12 @@ __FBSDID("$FreeBSD$");
|
|||
#include <dev/iicbus/iicbus.h>
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
|
||||
#ifdef FDT
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
#endif
|
||||
|
||||
#include "clock_if.h"
|
||||
#include "iicbus_if.h"
|
||||
|
||||
|
@ -159,7 +167,7 @@ s390rtc_read(device_t dev, uint8_t reg, uint8_t *buf, size_t len)
|
|||
int i;
|
||||
int error;
|
||||
|
||||
error = iicbus_transfer(dev, msg, 1);
|
||||
error = iicbus_transfer_excl(dev, msg, 1, IIC_WAIT);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
|
@ -188,13 +196,20 @@ s390rtc_write(device_t dev, uint8_t reg, uint8_t *buf, size_t len)
|
|||
for (i = 0; i < len; ++i)
|
||||
buf[i] = bitreverse(buf[i]);
|
||||
|
||||
return (iicbus_transfer(dev, msg, 1));
|
||||
return (iicbus_transfer_excl(dev, msg, 1, IIC_WAIT));
|
||||
}
|
||||
|
||||
static int
|
||||
s390rtc_probe(device_t dev)
|
||||
{
|
||||
|
||||
#ifdef FDT
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
if (!ofw_bus_is_compatible(dev, "sii,s35390a"))
|
||||
return (ENXIO);
|
||||
#else
|
||||
if (iicbus_get_addr(dev) != S390_ADDR) {
|
||||
if (bootverbose)
|
||||
device_printf(dev, "slave address mismatch. "
|
||||
|
@ -202,35 +217,35 @@ s390rtc_probe(device_t dev)
|
|||
S390_ADDR);
|
||||
return (ENXIO);
|
||||
}
|
||||
device_set_desc(dev, "Seiko Instruments S-35390A Real-time Clock");
|
||||
#endif
|
||||
device_set_desc(dev, "Seiko Instruments S-35390A RTC");
|
||||
|
||||
return (BUS_PROBE_SPECIFIC);
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
s390rtc_attach(device_t dev)
|
||||
static void
|
||||
s390rtc_start(void *arg)
|
||||
{
|
||||
struct s390rtc_softc *sc;
|
||||
device_t dev;
|
||||
uint8_t reg;
|
||||
int error;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->sc_dev = dev;
|
||||
sc->sc_addr = iicbus_get_addr(dev);
|
||||
dev = arg;
|
||||
|
||||
/* Reset the chip and turn on 24h mode, after power-off or battery. */
|
||||
error = s390rtc_read(dev, S390_STATUS1, ®, 1);
|
||||
if (error) {
|
||||
device_printf(dev, "%s: cannot read status1 register\n",
|
||||
__func__);
|
||||
return (error);
|
||||
return;
|
||||
}
|
||||
if (reg & (S390_ST1_POC | S390_ST1_BLD)) {
|
||||
reg |= S390_ST1_24H | S390_ST1_RESET;
|
||||
error = s390rtc_write(dev, S390_STATUS1, ®, 1);
|
||||
if (error) {
|
||||
device_printf(dev, "%s: cannot initialize\n", __func__);
|
||||
return (error);
|
||||
device_printf(dev,
|
||||
"%s: cannot initialize\n", __func__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,7 +254,7 @@ s390rtc_attach(device_t dev)
|
|||
if (error) {
|
||||
device_printf(dev, "%s: cannot read status2 register\n",
|
||||
__func__);
|
||||
return (error);
|
||||
return;
|
||||
}
|
||||
if (reg & S390_ST2_TEST) {
|
||||
reg &= ~S390_ST2_TEST;
|
||||
|
@ -247,11 +262,32 @@ s390rtc_attach(device_t dev)
|
|||
if (error) {
|
||||
device_printf(dev,
|
||||
"%s: cannot disable the test mode\n", __func__);
|
||||
return (error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
clock_register(dev, 1000000); /* 1 second resolution */
|
||||
}
|
||||
|
||||
static int
|
||||
s390rtc_attach(device_t dev)
|
||||
{
|
||||
struct s390rtc_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->sc_dev = dev;
|
||||
sc->sc_addr = iicbus_get_addr(dev);
|
||||
|
||||
config_intrhook_oneshot(s390rtc_start, dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
s390rtc_detach(device_t dev)
|
||||
{
|
||||
|
||||
clock_unregister(dev);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -310,6 +346,7 @@ s390rtc_settime(device_t dev, struct timespec *ts)
|
|||
static device_method_t s390rtc_methods[] = {
|
||||
DEVMETHOD(device_probe, s390rtc_probe),
|
||||
DEVMETHOD(device_attach, s390rtc_attach),
|
||||
DEVMETHOD(device_detach, s390rtc_detach),
|
||||
|
||||
DEVMETHOD(clock_gettime, s390rtc_gettime),
|
||||
DEVMETHOD(clock_settime, s390rtc_settime),
|
||||
|
|
|
@ -1236,7 +1236,7 @@ g_journal_flush(struct g_journal_softc *sc)
|
|||
struct g_provider *pp;
|
||||
struct bio **bioq;
|
||||
struct bio *bp, *fbp, *pbp;
|
||||
off_t joffset, size;
|
||||
off_t joffset;
|
||||
u_char *data, hash[16];
|
||||
MD5_CTX ctx;
|
||||
u_int i;
|
||||
|
@ -1244,7 +1244,6 @@ g_journal_flush(struct g_journal_softc *sc)
|
|||
if (sc->sc_current_count == 0)
|
||||
return;
|
||||
|
||||
size = 0;
|
||||
pp = sc->sc_jprovider;
|
||||
GJ_VALIDATE_OFFSET(sc->sc_journal_offset, sc);
|
||||
joffset = sc->sc_journal_offset;
|
||||
|
@ -1294,7 +1293,6 @@ g_journal_flush(struct g_journal_softc *sc)
|
|||
ent->je_offset = bp->bio_offset;
|
||||
ent->je_joffset = joffset;
|
||||
ent->je_length = bp->bio_length;
|
||||
size += ent->je_length;
|
||||
|
||||
data = bp->bio_data;
|
||||
if (sc->sc_flags & GJF_DEVICE_CHECKSUM)
|
||||
|
@ -1516,49 +1514,10 @@ g_journal_read_find(struct bio *head, int sorted, struct bio *pbp, off_t ostart,
|
|||
}
|
||||
|
||||
/*
|
||||
* Try to find requested data in cache.
|
||||
*/
|
||||
static struct bio *
|
||||
g_journal_read_queue_find(struct bio_queue *head, struct bio *pbp, off_t ostart,
|
||||
off_t oend)
|
||||
{
|
||||
off_t cstart, cend;
|
||||
struct bio *bp;
|
||||
|
||||
TAILQ_FOREACH(bp, head, bio_queue) {
|
||||
cstart = MAX(ostart, bp->bio_offset);
|
||||
cend = MIN(oend, bp->bio_offset + bp->bio_length);
|
||||
if (cend <= ostart)
|
||||
continue;
|
||||
else if (cstart >= oend)
|
||||
continue;
|
||||
KASSERT(bp->bio_data != NULL,
|
||||
("%s: bio_data == NULL", __func__));
|
||||
GJ_DEBUG(3, "READ(%p): (%jd, %jd) (bp=%p)", head, cstart, cend,
|
||||
bp);
|
||||
bcopy(bp->bio_data + cstart - bp->bio_offset,
|
||||
pbp->bio_data + cstart - pbp->bio_offset, cend - cstart);
|
||||
pbp->bio_completed += cend - cstart;
|
||||
if (pbp->bio_completed == pbp->bio_length) {
|
||||
/*
|
||||
* Cool, the whole request was in cache, deliver happy
|
||||
* message.
|
||||
*/
|
||||
g_io_deliver(pbp, 0);
|
||||
return (pbp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (bp);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is used for colecting data on read.
|
||||
* This function is used for collecting data on read.
|
||||
* The complexity is because parts of the data can be stored in four different
|
||||
* places:
|
||||
* - in delayed requests
|
||||
* - in memory - the data not yet send to the active journal provider
|
||||
* - in requests which are going to be sent to the active journal
|
||||
* - in the active journal
|
||||
* - in the inactive journal
|
||||
* - in the data provider
|
||||
|
@ -1576,20 +1535,14 @@ g_journal_read(struct g_journal_softc *sc, struct bio *pbp, off_t ostart,
|
|||
cstart = cend = -1;
|
||||
bp = NULL;
|
||||
head = NULL;
|
||||
for (i = 0; i <= 5; i++) {
|
||||
for (i = 1; i <= 5; i++) {
|
||||
switch (i) {
|
||||
case 0: /* Delayed requests. */
|
||||
head = NULL;
|
||||
sorted = 0;
|
||||
break;
|
||||
case 1: /* Not-yet-send data. */
|
||||
head = sc->sc_current_queue;
|
||||
sorted = 1;
|
||||
break;
|
||||
case 2: /* In-flight to the active journal. */
|
||||
head = sc->sc_flush_queue;
|
||||
sorted = 0;
|
||||
break;
|
||||
case 2: /* Skip flush queue as they are also in active queue */
|
||||
continue;
|
||||
case 3: /* Active journal. */
|
||||
head = sc->sc_active.jj_queue;
|
||||
sorted = 1;
|
||||
|
@ -1608,10 +1561,7 @@ g_journal_read(struct g_journal_softc *sc, struct bio *pbp, off_t ostart,
|
|||
default:
|
||||
panic("gjournal %s: i=%d", __func__, i);
|
||||
}
|
||||
if (i == 0)
|
||||
bp = g_journal_read_queue_find(&sc->sc_delayed_queue.queue, pbp, ostart, oend);
|
||||
else
|
||||
bp = g_journal_read_find(head, sorted, pbp, ostart, oend);
|
||||
bp = g_journal_read_find(head, sorted, pbp, ostart, oend);
|
||||
if (bp == pbp) { /* Got the whole request. */
|
||||
GJ_DEBUG(2, "Got the whole request from %u.", i);
|
||||
return;
|
||||
|
|
|
@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
|
|||
#include <sys/kernel.h>
|
||||
#include <sys/linker.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
|
@ -62,6 +63,27 @@ MTX_SYSINIT(intr_config_hook, &intr_config_hook_lock, "intr config", MTX_DEF);
|
|||
/* ARGSUSED */
|
||||
static void run_interrupt_driven_config_hooks(void);
|
||||
|
||||
/*
|
||||
* Private data and a shim function for implementing config_interhook_oneshot().
|
||||
*/
|
||||
struct oneshot_config_hook {
|
||||
struct intr_config_hook
|
||||
och_hook; /* Must be first */
|
||||
ich_func_t och_func;
|
||||
void *och_arg;
|
||||
};
|
||||
|
||||
static void
|
||||
config_intrhook_oneshot_func(void *arg)
|
||||
{
|
||||
struct oneshot_config_hook *ohook;
|
||||
|
||||
ohook = arg;
|
||||
ohook->och_func(ohook->och_arg);
|
||||
config_intrhook_disestablish(&ohook->och_hook);
|
||||
free(ohook, M_DEVBUF);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we wait too long for an interrupt-driven config hook to return, print
|
||||
* a diagnostic.
|
||||
|
@ -183,6 +205,22 @@ config_intrhook_establish(struct intr_config_hook *hook)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register a hook function that is automatically unregistered after it runs.
|
||||
*/
|
||||
void
|
||||
config_intrhook_oneshot(ich_func_t func, void *arg)
|
||||
{
|
||||
struct oneshot_config_hook *ohook;
|
||||
|
||||
ohook = malloc(sizeof(*ohook), M_DEVBUF, M_WAITOK);
|
||||
ohook->och_func = func;
|
||||
ohook->och_arg = arg;
|
||||
ohook->och_hook.ich_func = config_intrhook_oneshot_func;
|
||||
ohook->och_hook.ich_arg = ohook;
|
||||
config_intrhook_establish(&ohook->och_hook);
|
||||
}
|
||||
|
||||
void
|
||||
config_intrhook_disestablish(struct intr_config_hook *hook)
|
||||
{
|
||||
|
|
|
@ -123,16 +123,16 @@ void panic(const char *ctl, ...);
|
|||
*/
|
||||
static daddr_t blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count,
|
||||
daddr_t cursor);
|
||||
static daddr_t blst_meta_alloc(blmeta_t *scan, daddr_t blk, daddr_t count,
|
||||
daddr_t radix, daddr_t cursor);
|
||||
static daddr_t blst_meta_alloc(blmeta_t *scan, daddr_t cursor, daddr_t count,
|
||||
u_daddr_t radix);
|
||||
static void blst_leaf_free(blmeta_t *scan, daddr_t relblk, int count);
|
||||
static void blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count,
|
||||
daddr_t radix, daddr_t blk);
|
||||
u_daddr_t radix);
|
||||
static void blst_copy(blmeta_t *scan, daddr_t blk, daddr_t radix,
|
||||
blist_t dest, daddr_t count);
|
||||
static daddr_t blst_leaf_fill(blmeta_t *scan, daddr_t blk, int count);
|
||||
static daddr_t blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count,
|
||||
daddr_t radix, daddr_t blk);
|
||||
u_daddr_t radix);
|
||||
static daddr_t blst_radix_init(blmeta_t *scan, daddr_t radix, daddr_t count);
|
||||
#ifndef _KERNEL
|
||||
static void blst_radix_print(blmeta_t *scan, daddr_t blk, daddr_t radix,
|
||||
|
@ -247,8 +247,8 @@ blist_alloc(blist_t bl, daddr_t count)
|
|||
* reduce the hint, stopping further iterations.
|
||||
*/
|
||||
while (count <= bl->bl_root->bm_bighint) {
|
||||
blk = blst_meta_alloc(bl->bl_root, 0, count, bl->bl_radix,
|
||||
bl->bl_cursor);
|
||||
blk = blst_meta_alloc(bl->bl_root, bl->bl_cursor, count,
|
||||
bl->bl_radix);
|
||||
if (blk != SWAPBLK_NONE) {
|
||||
bl->bl_cursor = blk + count;
|
||||
return (blk);
|
||||
|
@ -280,7 +280,7 @@ void
|
|||
blist_free(blist_t bl, daddr_t blkno, daddr_t count)
|
||||
{
|
||||
|
||||
blst_meta_free(bl->bl_root, blkno, count, bl->bl_radix, 0);
|
||||
blst_meta_free(bl->bl_root, blkno, count, bl->bl_radix);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -293,7 +293,7 @@ daddr_t
|
|||
blist_fill(blist_t bl, daddr_t blkno, daddr_t count)
|
||||
{
|
||||
|
||||
return (blst_meta_fill(bl->bl_root, blkno, count, bl->bl_radix, 0));
|
||||
return (blst_meta_fill(bl->bl_root, blkno, count, bl->bl_radix));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -447,13 +447,13 @@ blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count, daddr_t cursor)
|
|||
* and we have a few optimizations strewn in as well.
|
||||
*/
|
||||
static daddr_t
|
||||
blst_meta_alloc(blmeta_t *scan, daddr_t blk, daddr_t count, daddr_t radix,
|
||||
daddr_t cursor)
|
||||
blst_meta_alloc(blmeta_t *scan, daddr_t cursor, daddr_t count, u_daddr_t radix)
|
||||
{
|
||||
daddr_t i, next_skip, r, skip;
|
||||
daddr_t blk, i, next_skip, r, skip;
|
||||
int child;
|
||||
bool scan_from_start;
|
||||
|
||||
blk = cursor & -radix;
|
||||
if (radix == BLIST_BMAP_RADIX)
|
||||
return (blst_leaf_alloc(scan, blk, count, cursor));
|
||||
if (scan->u.bmu_avail < count) {
|
||||
|
@ -505,8 +505,8 @@ blst_meta_alloc(blmeta_t *scan, daddr_t blk, daddr_t count, daddr_t radix,
|
|||
/*
|
||||
* The allocation might fit in the i'th subtree.
|
||||
*/
|
||||
r = blst_meta_alloc(&scan[i], blk, count, radix,
|
||||
cursor > blk ? cursor : blk);
|
||||
r = blst_meta_alloc(&scan[i],
|
||||
cursor > blk ? cursor : blk, count, radix);
|
||||
if (r != SWAPBLK_NONE) {
|
||||
scan->u.bmu_avail -= count;
|
||||
return (r);
|
||||
|
@ -574,10 +574,9 @@ blst_leaf_free(blmeta_t *scan, daddr_t blk, int count)
|
|||
* range).
|
||||
*/
|
||||
static void
|
||||
blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count, daddr_t radix,
|
||||
daddr_t blk)
|
||||
blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count, u_daddr_t radix)
|
||||
{
|
||||
daddr_t i, next_skip, skip, v;
|
||||
daddr_t blk, i, next_skip, skip, v;
|
||||
int child;
|
||||
|
||||
if (scan->bm_bighint == (daddr_t)-1)
|
||||
|
@ -628,6 +627,7 @@ blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count, daddr_t radix,
|
|||
* Break the free down into its components
|
||||
*/
|
||||
|
||||
blk = freeBlk & -radix;
|
||||
radix /= BLIST_META_RADIX;
|
||||
|
||||
child = (freeBlk - blk) / radix;
|
||||
|
@ -637,7 +637,7 @@ blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count, daddr_t radix,
|
|||
v = blk + radix - freeBlk;
|
||||
if (v > count)
|
||||
v = count;
|
||||
blst_meta_free(&scan[i], freeBlk, v, radix, blk);
|
||||
blst_meta_free(&scan[i], freeBlk, v, radix);
|
||||
if (scan->bm_bighint < scan[i].bm_bighint)
|
||||
scan->bm_bighint = scan[i].bm_bighint;
|
||||
count -= v;
|
||||
|
@ -755,10 +755,9 @@ blst_leaf_fill(blmeta_t *scan, daddr_t blk, int count)
|
|||
* number of blocks allocated by the call.
|
||||
*/
|
||||
static daddr_t
|
||||
blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, daddr_t radix,
|
||||
daddr_t blk)
|
||||
blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, u_daddr_t radix)
|
||||
{
|
||||
daddr_t i, nblks, next_skip, skip, v;
|
||||
daddr_t blk, i, nblks, next_skip, skip, v;
|
||||
int child;
|
||||
|
||||
if (scan->bm_bighint == (daddr_t)-1)
|
||||
|
@ -783,6 +782,7 @@ blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, daddr_t radix,
|
|||
}
|
||||
skip = radix_to_skip(radix);
|
||||
next_skip = skip / BLIST_META_RADIX;
|
||||
blk = allocBlk & -radix;
|
||||
|
||||
/*
|
||||
* An ALL-FREE meta node requires special handling before allocating
|
||||
|
@ -814,7 +814,7 @@ blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, daddr_t radix,
|
|||
v = blk + radix - allocBlk;
|
||||
if (v > count)
|
||||
v = count;
|
||||
nblks += blst_meta_fill(&scan[i], allocBlk, v, radix, blk);
|
||||
nblks += blst_meta_fill(&scan[i], allocBlk, v, radix);
|
||||
count -= v;
|
||||
allocBlk += v;
|
||||
blk += radix;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# $FreeBSD$
|
||||
|
||||
# RTC
|
||||
hint.ds1374_rtc.0.at="iicbus1"
|
||||
hint.ds1374_rtc.0.addr=0xd0
|
||||
hint.ds13rtc.0.at="iicbus1"
|
||||
hint.ds13rtc.0.addr=0xd0
|
||||
hint.ds13rtc.0.compatible="dallas,ds1374"
|
||||
|
|
|
@ -136,7 +136,7 @@ device ic
|
|||
device iic
|
||||
device iicbb
|
||||
device iicbus
|
||||
device ds1374 # RTC on XLR boards
|
||||
device ds13rtc # RTC on XLR boards
|
||||
device max6657 # Temparature sensor on XLR boards
|
||||
device at24co2n # EEPROM on XLR boards
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue