MFhead@r322515

This commit is contained in:
Enji Cooper 2017-08-14 19:28:49 +00:00
commit 82baa8db5e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/runtime-coverage/; revision=322517
179 changed files with 1394 additions and 757 deletions

View file

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

View file

@ -6,6 +6,7 @@
PACKAGE=runtime
PROG= cat
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

@ -6,6 +6,7 @@
PACKAGE=runtime
PROG= chmod
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

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

View file

@ -38,6 +38,7 @@ test: ${PROG} gen
@rm -f gen 1M_zeroes* obs_zeroes
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

@ -6,6 +6,7 @@
PACKAGE=runtime
PROG= echo
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

@ -12,6 +12,7 @@ CFLAGS+= -fwrapv
NO_WMISSING_VARIABLE_DECLARATIONS=
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

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

View file

@ -14,6 +14,7 @@ CFLAGS+= -DCOLORLS
LIBADD+= termcapw
.endif
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

@ -6,6 +6,7 @@
PACKAGE=runtime
PROG= mv
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

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

View file

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

View file

@ -5,6 +5,7 @@
PACKAGE=runtime
PROG= pwait
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

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

View file

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

View file

@ -0,0 +1,3 @@
# $FreeBSD$
! echo echo bad | ${SH} -c 2>/dev/null

View file

@ -6,6 +6,7 @@
PACKAGE=runtime
PROG= sleep
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

@ -8,6 +8,7 @@ PROG= test
LINKS= ${BINDIR}/test ${BINDIR}/[
MLINKS= test.1 [.1
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -47,6 +47,7 @@ SHLIB_MAJOR= 7
.include <src.opts.mk>
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.lib.mk>

View file

@ -18,6 +18,7 @@ LIBADD= nv
CFLAGS+=-I${.CURDIR}
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.lib.mk>

View file

@ -18,6 +18,7 @@ LIBADD= nv
CFLAGS+=-I${.CURDIR}
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.lib.mk>

View file

@ -18,6 +18,7 @@ LIBADD= nv
CFLAGS+=-I${.CURDIR}
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.lib.mk>

View file

@ -18,6 +18,7 @@ LIBADD= nv
CFLAGS+=-I${.CURDIR}
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.lib.mk>

View file

@ -43,6 +43,7 @@ WARNS?= 2
PRECIOUSLIB=
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.lib.mk>

View file

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

View file

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

View file

@ -17,6 +17,7 @@ SRCS+= msgio.c
SRCS+= nvlist.c
SRCS+= nvpair.c
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.lib.mk>

View file

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

View file

@ -41,6 +41,7 @@ SHLIB_MAJOR= 4
MAN=
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.lib.mk>

View file

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

View file

@ -14,6 +14,7 @@ VERSION_DEF= ${.CURDIR}/Version.def
.PATH: ${SRCTOP}/sys/kern
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.lib.mk>

View file

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

View file

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

View file

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

View file

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

View file

@ -40,6 +40,7 @@ CFLAGS+= -DATF_SHELL='"/bin/sh"'
LIBADD= atf_cxx
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

@ -72,6 +72,7 @@ FILESGROUPS= SUBR
SUBRDIR= ${SHAREDIR}/atf
SUBR= libatf-sh.subr
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include "../../../lib/atf/common.mk"

View file

@ -85,6 +85,7 @@ beforeinstall:
.PATH: ${.CURDIR}/${RTLD_ARCH}
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

@ -18,6 +18,7 @@ CFLAGS+=-I. -I${.CURDIR}
CLEANFILES= y.output
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

@ -46,6 +46,7 @@ LIBADD= util
WARNS?= 2
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

@ -22,6 +22,7 @@ NO_WCAST_ALIGN= yes
LIBADD= util
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

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

View file

@ -8,6 +8,7 @@ MAN= mdconfig.8
LIBADD= util geom
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

@ -31,6 +31,7 @@ YFLAGS=
LIBADD= m md
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View file

@ -266,6 +266,7 @@ SUBDIR+=pf
.endif
.endif
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
SUBDIR_PARALLEL=

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -160,7 +160,6 @@ __DEFAULT_YES_OPTIONS = \
TCP_WRAPPERS \
TCSH \
TELNET \
TESTS \
TEXTPROC \
TFTP \
TIMED \

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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, &reg, 1)))
return (error);
orig = reg;
reg |= 0x7C;
if ((error = ds133x_write(dev, DS1339_REG_STATUS, &reg, 1)))
return (error);
if ((error = ds133x_read(dev, DS1339_REG_STATUS, &reg, 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, &reg, 1)))
return (error);
orig = reg;
reg |= DS1339_BBSQI;
if ((error = ds133x_write(dev, DS1339_REG_CONTROL, &reg, 1)))
return (error);
if ((error = ds133x_read(dev, DS1339_REG_CONTROL, &reg, 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, &reg, 1)))
return (error);
if (reg & cs_bit) { /* If clock is stopped - start it */
reg &= ~cs_bit;
if ((error = ds133x_write(dev, cs_reg, &reg, 1)))
return (error);
}
if ((error = ds133x_read(dev, osf_reg, &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, &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);

View file

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

View file

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

View file

@ -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, &reg, 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, &reg, 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),

View file

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

View file

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

View file

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

View file

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

View file

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