diff --git a/MAINTAINERS b/MAINTAINERS index 19222d702414..73d6e500e72d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -26,7 +26,38 @@ sub-system. subsystem login notes ----------------------------- +opencrypto jmg Pre-commit review requested. Documentation Required. kqueue jmg Pre-commit review requested. Documentation Required. +share/mk imp, bapt, bdrewery, emaste, sjg Make is hard. +ath(4) adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org +net80211 adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org +iwn(4) adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org +iwm(4) adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org +otus(4) adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org +dev/usb/wlan adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org +openssl benl,jkim Pre-commit review requested. +release/release.sh gjb,re Pre-commit review and regression tests + requested. +sh(1) jilles Pre-commit review requested. This also applies + to kill(1), printf(1) and test(1) which are + compiled in as builtins. +isci(4) jimharris Pre-commit review requested. +nvme(4) jimharris Pre-commit review requested. +nvd(4) jimharris Pre-commit review requested. +nvmecontrol(8) jimharris Pre-commit review requested. +libfetch des Advance notification requested. +fetch des Advance notification requested. +libpam des Pre-commit review requested. +openssh des Pre-commit review requested. +pseudofs des Pre-commit review requested. +procfs des Pre-commit review requested. +linprocfs des Pre-commit review requested. +contrib/compiler-rt dim Pre-commit review preferred. +contrib/libc++ dim Pre-commit review preferred. +contrib/libcxxrt dim Pre-commit review preferred. +contrib/llvm dim Pre-commit review preferred. +contrib/llvm/tools/lldb emaste Pre-commit review preferred. +---- OLD ---- libc/posix1e rwatson Pre-commit review requested. POSIX.1e ACLs rwatson Pre-commit review requested. UFS EAs rwatson Pre-commit review requested. @@ -34,7 +65,6 @@ MAC Framework rwatson Pre-commit review requested. MAC Modules rwatson Pre-commit review requested. contrib/openbsm rwatson Pre-commit review requested. sys/security/audit rwatson Pre-commit review requested. -ath(4) adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org ahc(4) gibbs Pre-commit review requested. ahd(4) gibbs Pre-commit review requested. pci bus imp,jhb Pre-commit review requested. @@ -57,20 +87,11 @@ etc/mail gshapiro Pre-commit review requested. Keep in sync with -STABLE. etc/sendmail gshapiro Pre-commit review requested. Keep in sync with -STABLE. -libfetch des Advance notification requested. -fetch des Advance notification requested. -libpam des Pre-commit review requested. -openssh des Pre-commit review requested. -pseudofs des Pre-commit review requested. -procfs des Pre-commit review requested. -linprocfs des Pre-commit review requested. lpr gad Pre-commit review requested, particularly for lpd/recvjob.c and lpd/printjob.c. -net80211 adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org nvi peter Try not to break it. libz peter Try not to break it. groff ru Recommends pre-commit review. -share/mk imp, bapt, bdrewery, emaste, sjg Make is hard. ipfw ipfw Pre-commit review preferred. send to ipfw@freebsd.org drm rnoland Just keep me informed of changes, try not to break it. unifdef(1) fanf Pre-commit review requested. @@ -102,7 +123,6 @@ linux emul emulation Please discuss changes here. bs{diff,patch} cperciva Pre-commit review requested. portsnap cperciva Pre-commit review requested. freebsd-update cperciva Pre-commit review requested. -openssl benl,jkim Pre-commit review requested. sys/dev/usb hselasky If in doubt, ask. sys/dev/sound/usb hselasky If in doubt, ask. sys/compat/linuxkpi hselasky If in doubt, ask. @@ -120,18 +140,8 @@ usr.sbin/zic edwin Heads-up appreciated, since this code is lib/libc/stdtime edwin Heads-up appreciated, since parts of this code is maintained by a third party source. sbin/routed bms Pre-commit review; notify vendor at rhyolite.com -isci(4) jimharris Pre-commit review requested. cmx daniel@roe.ch Pre-commit review preferred. filemon obrien Pre-commit review preferred. sysdoc trhodes Pre-commit review preferred. -sh(1) jilles Pre-commit review requested. This also applies - to kill(1), printf(1) and test(1) which are - compiled in as builtins. -nvme(4) jimharris Pre-commit review requested. -nvd(4) jimharris Pre-commit review requested. -nvmecontrol(8) jimharris Pre-commit review requested. -release/release.sh gjb Pre-commit review and regression tests - requested. nanobsd imp Pre-commit review requested for coordination. vmm(4) neel,grehan Pre-commit review requested. -opencrypto jmg Pre-commit review requested. Documentation Required. diff --git a/Makefile.inc1 b/Makefile.inc1 index 767387a114be..12759c330fc9 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -27,7 +27,7 @@ # when NO_ROOT is set. (default: ${DESTDIR}/METALOG) # TARGET="machine" to crossbuild world for a different machine type # TARGET_ARCH= may be required when a TARGET supports multiple endians -# BUILDENV_SHELL= shell to launch for the buildenv target (def:/bin/sh) +# BUILDENV_SHELL= shell to launch for the buildenv target (def:${SHELL}) # WORLD_FLAGS= additional flags to pass to make(1) during buildworld # KERNEL_FLAGS= additional flags to pass to make(1) during buildkernel # SUBDIR_OVERRIDE="list of dirs" to build rather than everything. @@ -48,9 +48,15 @@ .error "Both TARGET and TARGET_ARCH must be defined." .endif -.include "share/mk/src.opts.mk" -.include -.include +# Cross toolchain changes must be in effect before bsd.compiler.mk +# so that gets the right CC, and pass CROSS_TOOLCHAIN to submakes. +.if defined(CROSS_TOOLCHAIN) +LOCALBASE?= /usr/local +.include "${LOCALBASE}/share/toolchains/${CROSS_TOOLCHAIN}.mk" +CROSSENV+=CROSS_TOOLCHAIN="${CROSS_TOOLCHAIN}" +.endif +.include # don't depend on src.opts.mk doing it +.include "share/mk/src.opts.mk" # We must do lib/ and libexec/ before bin/ in case of a mid-install error to # keep the users system reasonably usable. For static->dynamic root upgrades, @@ -139,7 +145,7 @@ CLEANDIR= cleandir LOCAL_TOOL_DIRS?= -BUILDENV_SHELL?=/bin/sh +BUILDENV_SHELL?=${SHELL} SVN?= /usr/local/bin/svn SVNFLAGS?= -r HEAD @@ -254,7 +260,7 @@ INSTALLTMP!= /usr/bin/mktemp -d -u -t install BOOTSTRAPPING?= 0 # Common environment for world related stages -CROSSENV= MAKEOBJDIRPREFIX=${OBJTREE} \ +CROSSENV+= MAKEOBJDIRPREFIX=${OBJTREE} \ MACHINE_ARCH=${TARGET_ARCH} \ MACHINE=${TARGET} \ CPUTYPE=${TARGET_CPUTYPE} @@ -329,10 +335,6 @@ HMAKE= PATH=${TMPPATH} ${MAKE} LOCAL_MTREE=${LOCAL_MTREE:Q} HMAKE+= PATH=${TMPPATH} METALOG=${METALOG} -DNO_ROOT .endif -.if defined(CROSS_TOOLCHAIN) -LOCALBASE?= /usr/local -.include "${LOCALBASE}/share/toolchains/${CROSS_TOOLCHAIN}.mk" -.endif .if defined(CROSS_TOOLCHAIN_PREFIX) CROSS_COMPILER_PREFIX?=${CROSS_TOOLCHAIN_PREFIX} CROSS_BINUTILS_PREFIX?=${CROSS_TOOLCHAIN_PREFIX} @@ -369,7 +371,7 @@ X${BINUTIL}?= ${CROSS_BINUTILS_PREFIX}${${BINUTIL}} X${BINUTIL}?= ${${BINUTIL}} .endif .endfor -WMAKEENV+= CC="${XCC} ${XCFLAGS}" CXX="${XCXX} ${XCFLAGS} ${XCXXFLAGS}" \ +CROSSENV+= CC="${XCC} ${XCFLAGS}" CXX="${XCXX} ${XCFLAGS} ${XCXXFLAGS}" \ DEPFLAGS="${DEPFLAGS}" \ CPP="${XCPP} ${XCFLAGS}" \ AS="${XAS}" AR="${XAR}" LD="${XLD}" NM=${XNM} \ @@ -771,7 +773,7 @@ buildworld_epilogue: # modification of the current environment's PATH. In addition, we need # to quote multiword values. # -buildenvvars: +buildenvvars: .PHONY @echo ${WMAKEENV:Q} ${.MAKE.EXPORTED:@v@$v=\"${$v}\"@} .if ${.TARGETS:Mbuildenv} @@ -779,9 +781,11 @@ buildenvvars: .error The buildenv target is incompatible with -j .endif .endif -buildenv: +BUILDENV_DIR?= ${.CURDIR} +buildenv: .PHONY @echo Entering world for ${TARGET_ARCH}:${TARGET} - @cd ${.CURDIR} && env ${WMAKEENV} ${BUILDENV_SHELL} || true + @cd ${BUILDENV_DIR} && env ${WMAKEENV} BUILDENV=1 ${BUILDENV_SHELL} \ + || true TOOLCHAIN_TGTS= ${WMAKE_TGTS:N_depend:Neverything:Nbuild32} toolchain: ${TOOLCHAIN_TGTS} @@ -1367,10 +1371,10 @@ _sed= usr.bin/sed .endif .if ${BOOTSTRAPPING} < 1000002 -_libohash= lib/libohash +_libopenbsd= lib/libopenbsd _m4= usr.bin/m4 -${_bt}-usr.bin/m4: ${_bt}-lib/libohash +${_bt}-usr.bin/m4: ${_bt}-lib/libopenbsd .endif .if ${BOOTSTRAPPING} < 1000026 @@ -1443,10 +1447,10 @@ _kerberos5_bootstrap_tools= \ .endif .if ${MK_MANDOCDB} != "no" -_libohash?= lib/libohash +_libopenbsd?= lib/libopenbsd _makewhatis= lib/libsqlite3 \ usr.bin/mandoc -${_bt}-usr.bin/mandoc: ${_bt}-lib/libohash ${_bt}-lib/libsqlite3 +${_bt}-usr.bin/mandoc: ${_bt}-lib/libopenbsd ${_bt}-lib/libsqlite3 .else _makewhatis=usr.bin/makewhatis .endif @@ -1469,7 +1473,7 @@ bootstrap-tools: .PHONY ${_awk} \ ${_cat} \ usr.bin/lorder \ - ${_libohash} \ + ${_libopenbsd} \ ${_makewhatis} \ usr.bin/rpcgen \ ${_sed} \ diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 0af25db96b0c..099a4ab4feaf 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,7 +38,7 @@ # xargs -n1 | sort | uniq -d; # done -# XXXXX: String collation improvements +# 20151107: String collation improvements OLD_FILES+=usr/share/locale/kk_KZ.PT154/LC_COLLATE OLD_FILES+=usr/share/locale/kk_KZ.PT154/LC_CTYPE OLD_FILES+=usr/share/locale/kk_KZ.PT154/LC_MESSAGES @@ -97,6 +97,39 @@ OLD_FILES+=usr/bin/colldef OLD_FILES+=usr/share/man/man1/colldef.1.gz OLD_FILES+=usr/bin/mklocale OLD_FILES+=usr/share/man/man1/mklocale.1.gz +# 20151101: added missing _test suffix on multiple tests in lib/libc +OLD_FILES+=usr/tests/lib/libc/c063/faccessat +OLD_FILES+=usr/tests/lib/libc/c063/fchmodat +OLD_FILES+=usr/tests/lib/libc/c063/fchownat +OLD_FILES+=usr/tests/lib/libc/c063/fexecve +OLD_FILES+=usr/tests/lib/libc/c063/fstatat +OLD_FILES+=usr/tests/lib/libc/c063/linkat +OLD_FILES+=usr/tests/lib/libc/c063/mkdirat +OLD_FILES+=usr/tests/lib/libc/c063/mkfifoat +OLD_FILES+=usr/tests/lib/libc/c063/mknodat +OLD_FILES+=usr/tests/lib/libc/c063/openat +OLD_FILES+=usr/tests/lib/libc/c063/readlinkat +OLD_FILES+=usr/tests/lib/libc/c063/renameat +OLD_FILES+=usr/tests/lib/libc/c063/symlinkat +OLD_FILES+=usr/tests/lib/libc/c063/unlinkat +OLD_FILES+=usr/tests/lib/libc/c063/utimensat +OLD_FILES+=usr/tests/lib/libc/string/memchr +OLD_FILES+=usr/tests/lib/libc/string/memcpy +OLD_FILES+=usr/tests/lib/libc/string/memmem +OLD_FILES+=usr/tests/lib/libc/string/memset +OLD_FILES+=usr/tests/lib/libc/string/strcat +OLD_FILES+=usr/tests/lib/libc/string/strchr +OLD_FILES+=usr/tests/lib/libc/string/strcmp +OLD_FILES+=usr/tests/lib/libc/string/strcpy +OLD_FILES+=usr/tests/lib/libc/string/strcspn +OLD_FILES+=usr/tests/lib/libc/string/strerror +OLD_FILES+=usr/tests/lib/libc/string/strlen +OLD_FILES+=usr/tests/lib/libc/string/strpbrk +OLD_FILES+=usr/tests/lib/libc/string/strrchr +OLD_FILES+=usr/tests/lib/libc/string/strspn +OLD_FILES+=usr/tests/lib/libc/string/swab +# 20151101: 430.status-rwho was renamed to 430.status-uptime +OLD_FILES+=etc/periodic/daily/430.status-rwho # 20151030: OpenSSL 1.0.2d import OLD_FILES+=usr/share/openssl/man/man3/CMS_set1_signer_certs.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_PKEY_ctrl.3.gz diff --git a/bin/rm/rm.1 b/bin/rm/rm.1 index 840b560a7d4f..4b53c2a2e102 100644 --- a/bin/rm/rm.1 +++ b/bin/rm/rm.1 @@ -32,7 +32,7 @@ .\" @(#)rm.1 8.5 (Berkeley) 12/5/94 .\" $FreeBSD$ .\" -.Dd April 25, 2013 +.Dd November 7, 2015 .Dt RM 1 .Os .Sh NAME @@ -234,7 +234,7 @@ not the standard error output. The .Nm command conforms to -.St -p1003.2 . +.St -p1003.1-2013 . .Pp The simplified .Nm unlink diff --git a/bin/rm/rm.c b/bin/rm/rm.c index d91af54a5c12..7beae2d62766 100644 --- a/bin/rm/rm.c +++ b/bin/rm/rm.c @@ -155,8 +155,7 @@ main(int argc, char *argv[]) } checkdot(argv); - if (getenv("POSIXLY_CORRECT") == NULL) - checkslash(argv); + checkslash(argv); uid = geteuid(); (void)signal(SIGINFO, siginfo); diff --git a/bin/sh/eval.c b/bin/sh/eval.c index dfbbc04028f3..46c00de75b99 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -750,7 +750,7 @@ isdeclarationcmd(struct narg *arg) } static void -xtracecommand(struct arglist *varlist, struct arglist *arglist) +xtracecommand(struct arglist *varlist, int argc, char **argv) { char sep = 0; const char *text, *p, *ps4; @@ -771,8 +771,8 @@ xtracecommand(struct arglist *varlist, struct arglist *arglist) out2qstr(text); sep = ' '; } - for (i = 0; i < arglist->count; i++) { - text = arglist->args[i]; + for (i = 0; i < argc; i++) { + text = argv[i]; if (sep != 0) out2c(' '); out2qstr(text); @@ -849,6 +849,8 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) do_clearcmdentry = 0; oexitstatus = exitstatus; exitstatus = 0; + /* Add one slot at the beginning for tryexec(). */ + appendarglist(&arglist, nullstr); for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) { if (varflag && isassignment(argp->narg.text)) { expandarg(argp, varflag == 1 ? &varlist : &arglist, @@ -858,13 +860,11 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) varflag = isdeclarationcmd(&argp->narg) ? 2 : 0; expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); } + appendarglist(&arglist, nullstr); expredir(cmd->ncmd.redirect); - argc = arglist.count; - /* Add one slot at the beginning for tryexec(). */ - argv = stalloc(sizeof (char *) * (argc + 2)); - argv++; + argc = arglist.count - 2; + argv = &arglist.args[1]; - memcpy(argv, arglist.args, sizeof(*argv) * argc); argv[argc] = NULL; lastarg = NULL; if (iflag && funcnest == 0 && argc > 0) @@ -872,7 +872,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) /* Print the command if xflag is set. */ if (xflag) - xtracecommand(&varlist, &arglist); + xtracecommand(&varlist, argc, argv); /* Now locate the command. */ if (argc == 0) { diff --git a/bin/sh/expand.c b/bin/sh/expand.c index 567b8a48423a..f7c6735f9e33 100644 --- a/bin/sh/expand.c +++ b/bin/sh/expand.c @@ -114,7 +114,6 @@ static void expmeta(char *, char *, struct arglist *); static int expsortcmp(const void *, const void *); static int patmatch(const char *, const char *, int); static char *cvtnum(int, char *); -static void appendarglist(struct arglist *, char *); static int collate_range_cmp(wchar_t, wchar_t); void @@ -126,7 +125,7 @@ emptyarglist(struct arglist *list) list->capacity = sizeof(list->smallarg) / sizeof(list->smallarg[0]); } -static void +void appendarglist(struct arglist *list, char *str) { char **newargs; diff --git a/bin/sh/expand.h b/bin/sh/expand.h index c377156c9c33..d024e8f6b7af 100644 --- a/bin/sh/expand.h +++ b/bin/sh/expand.h @@ -52,6 +52,7 @@ struct arglist { void emptyarglist(struct arglist *); +void appendarglist(struct arglist *, char *); union node; void expandarg(union node *, struct arglist *, int); void rmescapes(char *); diff --git a/contrib/libexecinfo/backtrace.3 b/contrib/libexecinfo/backtrace.3 index fdd8cec5653b..d0dfb9579d90 100644 --- a/contrib/libexecinfo/backtrace.3 +++ b/contrib/libexecinfo/backtrace.3 @@ -28,7 +28,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd August 23, 2013 +.Dd November 3, 2015 .Dt BACKTRACE 3 .Os .Sh NAME @@ -47,7 +47,7 @@ .Ft "char **" .Fn backtrace_symbols_fmt "void * const *addrlist" "size_t len" "const char *fmt" .Ft int -.Fn backtrace_symbols_fmt_fd "void * const *addrlist" "size_t len" "const char *fmt" "int fd" +.Fn backtrace_symbols_fd_fmt "void * const *addrlist" "size_t len" "const char *fmt" "int fd" .Sh DESCRIPTION The .Fn backtrace @@ -106,7 +106,7 @@ with a format argument of The .Fn backtrace_symbols_fd and -.Fn backtrace_symbols_fmt_fd +.Fn backtrace_symbols_fd_fmt are similar to the non _fd named functions, only instead of returning an array or strings, they print a new-line separated array of strings in fd, and return diff --git a/contrib/libxo/libxo/xo_format.5 b/contrib/libxo/libxo/xo_format.5 index 1db4fc8dc118..89c010391d51 100644 --- a/contrib/libxo/libxo/xo_format.5 +++ b/contrib/libxo/libxo/xo_format.5 @@ -7,7 +7,7 @@ .\" # LICENSE. .\" # Phil Shafer, July 2014 .\" -.Dd December 4, 2014 +.Dd November 6, 2015 .Dt LIBXO 3 .Os .Sh NAME @@ -367,7 +367,7 @@ particular output styles: .It l "leaf-list " "Field is a leaf-list, a list of leaf values" .It n "no-quotes " "Do not quote the field when using JSON style" .It q "quotes " "Quote the field when using JSON style" -.It q "trim " "Trim leading and trailing whitespace" +.It t "trim " "Trim leading and trailing whitespace" .It w "white space " "A blank ("" "") is appended after the label" .El .Pp diff --git a/etc/defaults/periodic.conf b/etc/defaults/periodic.conf index fbc5d0ae1ebd..855d5609cb84 100644 --- a/etc/defaults/periodic.conf +++ b/etc/defaults/periodic.conf @@ -115,8 +115,8 @@ daily_status_network_enable="YES" # Check network status daily_status_network_usedns="YES" # DNS lookups are ok daily_status_network_netstat_flags="-d" # netstat(1) flags -# 430.status-rwho -daily_status_rwho_enable="YES" # Check system status +# 430.status-uptime +daily_status_uptime_enable="YES" # Check system uptime # 440.status-mailq daily_status_mailq_enable="YES" # Check mail status diff --git a/etc/periodic/daily/430.status-rwho b/etc/periodic/daily/430.status-uptime similarity index 93% rename from etc/periodic/daily/430.status-rwho rename to etc/periodic/daily/430.status-uptime index 44761368c933..0c8c591a5973 100755 --- a/etc/periodic/daily/430.status-rwho +++ b/etc/periodic/daily/430.status-uptime @@ -11,7 +11,7 @@ then source_periodic_confs fi -case "$daily_status_rwho_enable" in +case "$daily_status_uptime_enable" in [Yy][Ee][Ss]) rwho=$(echo /var/rwho/*) if [ -f "${rwho%% *}" ] diff --git a/etc/periodic/daily/Makefile b/etc/periodic/daily/Makefile index 15b6ae8a80e6..939dd150e4a9 100644 --- a/etc/periodic/daily/Makefile +++ b/etc/periodic/daily/Makefile @@ -15,6 +15,7 @@ FILES= 100.clean-disks \ 408.status-gstripe \ 409.status-gconcat \ 420.status-network \ + 430.status-uptime \ 450.status-security \ 510.status-world-kernel \ 999.local @@ -38,8 +39,7 @@ FILES+= 480.status-ntpd .endif .if ${MK_RCMDS} != "no" -FILES+= 140.clean-rwho \ - 430.status-rwho +FILES+= 140.clean-rwho .endif .if ${MK_SENDMAIL} != "no" diff --git a/etc/periodic/security/520.pfdenied b/etc/periodic/security/520.pfdenied index 7a32bf2a193b..3fea360f4582 100755 --- a/etc/periodic/security/520.pfdenied +++ b/etc/periodic/security/520.pfdenied @@ -44,7 +44,7 @@ rc=0 if check_yesno_period security_status_pfdenied_enable then TMP=`mktemp -t security` - if pfctl -sr -v 2>/dev/null | nawk '{if (/^block/) {buf=$0; getline; gsub(" +"," ",$0); print buf$0;} }' > ${TMP}; then + if pfctl -sr -v 2>/dev/null | nawk '{if (/^block/) {buf=$0; getline; gsub(" +"," ",$0); if ($5 > 0) print buf$0;} }' > ${TMP}; then check_diff new_only pf ${TMP} "${host} pf denied packets:" fi rc=$? diff --git a/gnu/usr.bin/grep/savedir.c b/gnu/usr.bin/grep/savedir.c index cfba77cec4d4..6aabe31e793c 100644 --- a/gnu/usr.bin/grep/savedir.c +++ b/gnu/usr.bin/grep/savedir.c @@ -71,6 +71,7 @@ char *stpcpy (); #include #include "savedir.h" +#include "system.h" char *path; size_t pathlen; diff --git a/include/unistd.h b/include/unistd.h index ef77133d0ba5..4c26a042674e 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -327,9 +327,9 @@ int close(int); void closefrom(int); int dup(int); int dup2(int, int); -int execl(const char *, const char *, ...) __sentinel; +int execl(const char *, const char *, ...) __null_sentinel; int execle(const char *, const char *, ...); -int execlp(const char *, const char *, ...) __sentinel; +int execlp(const char *, const char *, ...) __null_sentinel; int execv(const char *, char * const *); int execve(const char *, char * const *, char * const *); int execvp(const char *, char * const *); diff --git a/lib/Makefile b/lib/Makefile index a3321af9aed0..38003b8fec67 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -75,7 +75,7 @@ SUBDIR= ${SUBDIR_ORDERED} \ ${_libnetgraph} \ ${_libngatm} \ libnv \ - libohash \ + libopenbsd \ libopie \ libpam \ libpcap \ diff --git a/lib/libc/net/getnameinfo.c b/lib/libc/net/getnameinfo.c index c81318926ba1..4b7aecbc6f02 100644 --- a/lib/libc/net/getnameinfo.c +++ b/lib/libc/net/getnameinfo.c @@ -122,7 +122,8 @@ getnameinfo(const struct sockaddr *sa, socklen_t salen, afd = find_afd(sa->sa_family); if (afd == NULL) return (EAI_FAMILY); - if (sa->sa_family == PF_LOCAL) { + switch (sa->sa_family) { + case PF_LOCAL: /* * PF_LOCAL uses variable sa->sa_len depending on the * content length of sun_path. Require 1 byte in @@ -132,8 +133,17 @@ getnameinfo(const struct sockaddr *sa, socklen_t salen, salen <= afd->a_socklen - sizeofmember(struct sockaddr_un, sun_path)) return (EAI_FAIL); - } else if (salen != afd->a_socklen) - return (EAI_FAIL); + break; + case PF_LINK: + if (salen <= afd->a_socklen - + sizeofmember(struct sockaddr_dl, sdl_data)) + return (EAI_FAIL); + break; + default: + if (salen != afd->a_socklen) + return (EAI_FAIL); + break; + } return ((*afd->a_func)(afd, sa, salen, host, hostlen, serv, servlen, flags)); diff --git a/lib/libc/rpc/clnt_bcast.c b/lib/libc/rpc/clnt_bcast.c index 7242aa4b68df..a194ba6c77cc 100644 --- a/lib/libc/rpc/clnt_bcast.c +++ b/lib/libc/rpc/clnt_bcast.c @@ -636,13 +636,10 @@ rpc_broadcast_exp(rpcprog_t prog, rpcvers_t vers, rpcproc_t proc, } /* The giant for loop */ done_broad: - if (inbuf) - (void) free(inbuf); - if (outbuf) - (void) free(outbuf); + free(inbuf); + free(outbuf); #ifdef PORTMAP - if (outbuf_pmap) - (void) free(outbuf_pmap); + free(outbuf_pmap); #endif /* PORTMAP */ for (i = 0; i < fdlistno; i++) { (void)_close(fdlist[i].fd); diff --git a/lib/libc/rpc/clnt_vc.c b/lib/libc/rpc/clnt_vc.c index e463165069dd..aa16b9690a0b 100644 --- a/lib/libc/rpc/clnt_vc.c +++ b/lib/libc/rpc/clnt_vc.c @@ -651,8 +651,7 @@ clnt_vc_destroy(CLIENT *cl) (void)_close(ct->ct_fd); } XDR_DESTROY(&(ct->ct_xdrs)); - if (ct->ct_addr.buf) - free(ct->ct_addr.buf); + free(ct->ct_addr.buf); mem_free(ct, sizeof(struct ct_data)); if (cl->cl_netid && cl->cl_netid[0]) mem_free(cl->cl_netid, strlen(cl->cl_netid) +1); diff --git a/lib/libc/rpc/getnetconfig.c b/lib/libc/rpc/getnetconfig.c index c1e22da52e46..6d668bf5c2fc 100644 --- a/lib/libc/rpc/getnetconfig.c +++ b/lib/libc/rpc/getnetconfig.c @@ -164,8 +164,7 @@ __nc_error(void) if ((nc_addr = (int *)thr_getspecific(nc_key)) == NULL) { nc_addr = (int *)malloc(sizeof (int)); if (thr_setspecific(nc_key, (void *) nc_addr) != 0) { - if (nc_addr) - free(nc_addr); + free(nc_addr); return (&nc_error); } *nc_addr = 0; @@ -417,7 +416,7 @@ endnetconfig(void *handlep) while (q != NULL) { p = q->next; - if (q->ncp->nc_lookups != NULL) free(q->ncp->nc_lookups); + free(q->ncp->nc_lookups); free(q->ncp); free(q->linep); free(q); @@ -537,8 +536,7 @@ freenetconfigent(struct netconfig *netconfigp) { if (netconfigp != NULL) { free(netconfigp->nc_netid); /* holds all netconfigp's strings */ - if (netconfigp->nc_lookups != NULL) - free(netconfigp->nc_lookups); + free(netconfigp->nc_lookups); free(netconfigp); } return; @@ -628,8 +626,7 @@ parse_ncp(char *stringp, struct netconfig *ncp) } else { char *cp; /* tmp string */ - if (ncp->nc_lookups != NULL) /* from last visit */ - free(ncp->nc_lookups); + free(ncp->nc_lookups); /* from last visit */ ncp->nc_lookups = NULL; ncp->nc_nlookups = 0; while ((cp = tokenp) != NULL) { diff --git a/lib/libc/rpc/mt_misc.c b/lib/libc/rpc/mt_misc.c index 2e17c27f444c..0ec4d8a8b79d 100644 --- a/lib/libc/rpc/mt_misc.c +++ b/lib/libc/rpc/mt_misc.c @@ -106,8 +106,7 @@ __rpc_createerr(void) rce_addr = (struct rpc_createerr *) malloc(sizeof (struct rpc_createerr)); if (thr_setspecific(rce_key, (void *) rce_addr) != 0) { - if (rce_addr) - free(rce_addr); + free(rce_addr); return (&rpc_createerr); } memset(rce_addr, 0, sizeof (struct rpc_createerr)); diff --git a/lib/libc/rpc/rpc_soc.c b/lib/libc/rpc/rpc_soc.c index 8fc91ffde304..11fc80302a12 100644 --- a/lib/libc/rpc/rpc_soc.c +++ b/lib/libc/rpc/rpc_soc.c @@ -432,8 +432,7 @@ clntunix_create(struct sockaddr_un *raddr, u_long prog, u_long vers, int *sockp, if ((raddr->sun_len == 0) || ((svcaddr = malloc(sizeof(struct netbuf))) == NULL ) || ((svcaddr->buf = malloc(sizeof(struct sockaddr_un))) == NULL)) { - if (svcaddr != NULL) - free(svcaddr); + free(svcaddr); rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; return(cl); diff --git a/lib/libc/rpc/rpcb_clnt.c b/lib/libc/rpc/rpcb_clnt.c index d53d908fc2e4..49300ed37db0 100644 --- a/lib/libc/rpc/rpcb_clnt.c +++ b/lib/libc/rpc/rpcb_clnt.c @@ -179,8 +179,7 @@ delete_cache(struct netbuf *addr) free(cptr->ac_netid); free(cptr->ac_taddr->buf); free(cptr->ac_taddr); - if (cptr->ac_uaddr) - free(cptr->ac_uaddr); + free(cptr->ac_uaddr); if (prevptr) prevptr->ac_next = cptr->ac_next; else @@ -216,14 +215,10 @@ add_cache(const char *host, const char *netid, struct netbuf *taddr, ad_cache->ac_taddr->buf = (char *) malloc(taddr->len); if (ad_cache->ac_taddr->buf == NULL) { out: - if (ad_cache->ac_host) - free(ad_cache->ac_host); - if (ad_cache->ac_netid) - free(ad_cache->ac_netid); - if (ad_cache->ac_uaddr) - free(ad_cache->ac_uaddr); - if (ad_cache->ac_taddr) - free(ad_cache->ac_taddr); + free(ad_cache->ac_host); + free(ad_cache->ac_netid); + free(ad_cache->ac_uaddr); + free(ad_cache->ac_taddr); free(ad_cache); return; } @@ -256,8 +251,7 @@ add_cache(const char *host, const char *netid, struct netbuf *taddr, free(cptr->ac_netid); free(cptr->ac_taddr->buf); free(cptr->ac_taddr); - if (cptr->ac_uaddr) - free(cptr->ac_uaddr); + free(cptr->ac_uaddr); if (prevptr) { prevptr->ac_next = NULL; @@ -798,10 +792,8 @@ __rpcb_findaddr_timed(rpcprog_t program, rpcvers_t version, malloc(remote.len)) == NULL)) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; clnt_geterr(client, &rpc_createerr.cf_error); - if (address) { - free(address); - address = NULL; - } + free(address); + address = NULL; goto error; } memcpy(address->buf, remote.buf, remote.len); diff --git a/lib/libc/rpc/svc.c b/lib/libc/rpc/svc.c index 38cbb797f83e..d68fa9f83319 100644 --- a/lib/libc/rpc/svc.c +++ b/lib/libc/rpc/svc.c @@ -198,8 +198,7 @@ svc_reg(SVCXPRT *xprt, const rpcprog_t prog, const rpcvers_t vers, rwlock_wrlock(&svc_lock); if ((s = svc_find(prog, vers, &prev, netid)) != NULL) { - if (netid) - free(netid); + free(netid); if (s->sc_dispatch == dispatch) goto rpcb_it; /* he is registering another xptr */ rwlock_unlock(&svc_lock); @@ -207,8 +206,7 @@ svc_reg(SVCXPRT *xprt, const rpcprog_t prog, const rpcvers_t vers, } s = mem_alloc(sizeof (struct svc_callout)); if (s == NULL) { - if (netid) - free(netid); + free(netid); rwlock_unlock(&svc_lock); return (FALSE); } diff --git a/lib/libc/rpc/svc_dg.c b/lib/libc/rpc/svc_dg.c index 1957d64b4ea3..5d9baaa81f66 100644 --- a/lib/libc/rpc/svc_dg.c +++ b/lib/libc/rpc/svc_dg.c @@ -406,8 +406,7 @@ svc_dg_destroy(SVCXPRT *xprt) (void) mem_free(xprt->xp_rtaddr.buf, xprt->xp_rtaddr.maxlen); if (xprt->xp_ltaddr.buf) (void) mem_free(xprt->xp_ltaddr.buf, xprt->xp_ltaddr.maxlen); - if (xprt->xp_tp) - (void) free(xprt->xp_tp); + free(xprt->xp_tp); svc_xprt_free(xprt); } diff --git a/lib/libc/rpc/svc_simple.c b/lib/libc/rpc/svc_simple.c index 4713efcfc558..9ce3f8d4efbc 100644 --- a/lib/libc/rpc/svc_simple.c +++ b/lib/libc/rpc/svc_simple.c @@ -166,10 +166,8 @@ rpc_reg(rpcprog_t prognum, rpcvers_t versnum, rpcproc_t procnum, if (((xdrbuf = malloc((unsigned)recvsz)) == NULL) || ((netid = strdup(nconf->nc_netid)) == NULL)) { warnx(rpc_reg_err, rpc_reg_msg, __no_mem_str); - if (xdrbuf != NULL) - free(xdrbuf); - if (netid != NULL) - free(netid); + free(xdrbuf); + free(netid); SVC_DESTROY(svcxprt); break; } diff --git a/lib/libc/rpc/svc_vc.c b/lib/libc/rpc/svc_vc.c index ca4b93e4fbf7..bafb725696f2 100644 --- a/lib/libc/rpc/svc_vc.c +++ b/lib/libc/rpc/svc_vc.c @@ -394,10 +394,8 @@ __svc_vc_dodestroy(SVCXPRT *xprt) mem_free(xprt->xp_rtaddr.buf, xprt->xp_rtaddr.maxlen); if (xprt->xp_ltaddr.buf) mem_free(xprt->xp_ltaddr.buf, xprt->xp_ltaddr.maxlen); - if (xprt->xp_tp) - free(xprt->xp_tp); - if (xprt->xp_netid) - free(xprt->xp_netid); + free(xprt->xp_tp); + free(xprt->xp_netid); svc_xprt_free(xprt); } diff --git a/lib/libc/tests/c063/Makefile b/lib/libc/tests/c063/Makefile index 2e4565cdf318..05da6ea212a9 100644 --- a/lib/libc/tests/c063/Makefile +++ b/lib/libc/tests/c063/Makefile @@ -2,21 +2,21 @@ #TODO: t_o_search -NETBSD_ATF_TESTS_C= faccessat -NETBSD_ATF_TESTS_C+= fchmodat -NETBSD_ATF_TESTS_C+= fchownat -NETBSD_ATF_TESTS_C+= fexecve -NETBSD_ATF_TESTS_C+= fstatat -NETBSD_ATF_TESTS_C+= linkat -NETBSD_ATF_TESTS_C+= mkdirat -NETBSD_ATF_TESTS_C+= mkfifoat -NETBSD_ATF_TESTS_C+= mknodat -NETBSD_ATF_TESTS_C+= openat -NETBSD_ATF_TESTS_C+= readlinkat -NETBSD_ATF_TESTS_C+= renameat -NETBSD_ATF_TESTS_C+= symlinkat -NETBSD_ATF_TESTS_C+= unlinkat -NETBSD_ATF_TESTS_C+= utimensat +NETBSD_ATF_TESTS_C= faccessat_test +NETBSD_ATF_TESTS_C+= fchmodat_test +NETBSD_ATF_TESTS_C+= fchownat_test +NETBSD_ATF_TESTS_C+= fexecve_test +NETBSD_ATF_TESTS_C+= fstatat_test +NETBSD_ATF_TESTS_C+= linkat_test +NETBSD_ATF_TESTS_C+= mkdirat_test +NETBSD_ATF_TESTS_C+= mkfifoat_test +NETBSD_ATF_TESTS_C+= mknodat_test +NETBSD_ATF_TESTS_C+= openat_test +NETBSD_ATF_TESTS_C+= readlinkat_test +NETBSD_ATF_TESTS_C+= renameat_test +NETBSD_ATF_TESTS_C+= symlinkat_test +NETBSD_ATF_TESTS_C+= unlinkat_test +NETBSD_ATF_TESTS_C+= utimensat_test CFLAGS+= -D_INCOMPLETE_XOPEN_C063 diff --git a/lib/libc/tests/setjmp/Makefile b/lib/libc/tests/setjmp/Makefile index 0ca25774beef..ac962c2d8d6d 100644 --- a/lib/libc/tests/setjmp/Makefile +++ b/lib/libc/tests/setjmp/Makefile @@ -1,10 +1,10 @@ # $FreeBSD$ -NETBSD_ATF_TESTS_C= t_setjmp -NETBSD_ATF_TESTS_C+= t_threadjmp +NETBSD_ATF_TESTS_C= setjmp_test +NETBSD_ATF_TESTS_C+= threadjmp_test -DPADD.t_threadjmp+= ${LIBPTHREAD} -LDADD.t_threadjmp+= -lpthread +DPADD.threadjmp_test+= ${LIBPTHREAD} +LDADD.threadjmp_test+= -lpthread WARNS?= 4 diff --git a/lib/libc/tests/string/Makefile b/lib/libc/tests/string/Makefile index d91af08a27f1..fc9c1af4ded4 100644 --- a/lib/libc/tests/string/Makefile +++ b/lib/libc/tests/string/Makefile @@ -4,28 +4,28 @@ # TODO: popcount, stresep -NETBSD_ATF_TESTS_C+= memchr -NETBSD_ATF_TESTS_C+= memcpy -NETBSD_ATF_TESTS_C+= memmem -NETBSD_ATF_TESTS_C+= memset -NETBSD_ATF_TESTS_C+= strcat -NETBSD_ATF_TESTS_C+= strchr -NETBSD_ATF_TESTS_C+= strcmp -NETBSD_ATF_TESTS_C+= strcpy -NETBSD_ATF_TESTS_C+= strcspn -NETBSD_ATF_TESTS_C+= strerror -NETBSD_ATF_TESTS_C+= strlen -NETBSD_ATF_TESTS_C+= strpbrk -NETBSD_ATF_TESTS_C+= strrchr -NETBSD_ATF_TESTS_C+= strspn -NETBSD_ATF_TESTS_C+= swab +NETBSD_ATF_TESTS_C+= memchr_test +NETBSD_ATF_TESTS_C+= memcpy_test +NETBSD_ATF_TESTS_C+= memmem_test +NETBSD_ATF_TESTS_C+= memset_test +NETBSD_ATF_TESTS_C+= strcat_test +NETBSD_ATF_TESTS_C+= strchr_test +NETBSD_ATF_TESTS_C+= strcmp_test +NETBSD_ATF_TESTS_C+= strcpy_test +NETBSD_ATF_TESTS_C+= strcspn_test +NETBSD_ATF_TESTS_C+= strerror_test +NETBSD_ATF_TESTS_C+= strlen_test +NETBSD_ATF_TESTS_C+= strpbrk_test +NETBSD_ATF_TESTS_C+= strrchr_test +NETBSD_ATF_TESTS_C+= strspn_test +NETBSD_ATF_TESTS_C+= swab_test .include "../Makefile.netbsd-tests" -LDADD.memchr+= -lmd -DPADD.memchr+= ${LIBMD} +LDADD.memchr_test+= -lmd +DPADD.memchr_test+= ${LIBMD} -LDADD.memcpy+= -lmd -DPADD.memcpy+= ${LIBMD} +LDADD.memcpy_test+= -lmd +DPADD.memcpy_test+= ${LIBMD} .include diff --git a/lib/libc/tests/tls_dso/Makefile b/lib/libc/tests/tls_dso/Makefile index b37ffec76659..5449799de96c 100644 --- a/lib/libc/tests/tls_dso/Makefile +++ b/lib/libc/tests/tls_dso/Makefile @@ -1,7 +1,5 @@ # $FreeBSD$ -SRCDIR= ${SRCTOP}/contrib/netbsd/ - .include LIB= h_tls_dynamic diff --git a/lib/libdpv/dialogrc.c b/lib/libdpv/dialogrc.c index eb4a53621084..e199d415c539 100644 --- a/lib/libdpv/dialogrc.c +++ b/lib/libdpv/dialogrc.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2013-2014 Devin Teske + * Copyright (c) 2013-2015 Devin Teske * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,58 +49,58 @@ char gauge_color[STR_BUFSIZE] = "47b"; /* (BLUE,WHITE,ON) */ char separator[STR_BUFSIZE] = ""; /* Function prototypes */ -static int setattr(struct fp_config *, uint32_t, char *, char *); -static int setbool(struct fp_config *, uint32_t, char *, char *); -static int setnum(struct fp_config *, uint32_t, char *, char *); -static int setstr(struct fp_config *, uint32_t, char *, char *); +static int setattr(struct figpar_config *, uint32_t, char *, char *); +static int setbool(struct figpar_config *, uint32_t, char *, char *); +static int setnum(struct figpar_config *, uint32_t, char *, char *); +static int setstr(struct figpar_config *, uint32_t, char *, char *); /* * Anatomy of DIALOGRC (~/.dialogrc by default) * NOTE: Must appear after private function prototypes (above) * NB: Brace-initialization of union requires cast to *first* member of union */ -static struct fp_config dialogrc_config[] = { - /* TYPE Directive DEFAULT HANDLER */ - {FP_TYPE_INT, "aspect", {(void *)0}, &setnum}, - {FP_TYPE_STR, "separate_widget", {separator}, &setstr}, - {FP_TYPE_INT, "tab_len", {(void *)0}, &setnum}, - {FP_TYPE_BOOL, "visit_items", {(void *)0}, &setbool}, - {FP_TYPE_BOOL, "use_shadow", {(void *)1}, &setbool}, - {FP_TYPE_BOOL, "use_colors", {(void *)1}, &setbool}, - {FP_TYPE_STR, "screen_color", {NULL}, &setattr}, - {FP_TYPE_STR, "shadow_color", {NULL}, &setattr}, - {FP_TYPE_STR, "dialog_color", {NULL}, &setattr}, - {FP_TYPE_STR, "title_color", {NULL}, &setattr}, - {FP_TYPE_STR, "border_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_active_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_inactive_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_key_active_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_key_inactive_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_label_active_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_label_inactive_color",{NULL}, &setattr}, - {FP_TYPE_STR, "inputbox_color", {NULL}, &setattr}, - {FP_TYPE_STR, "inputbox_border_color", {NULL}, &setattr}, - {FP_TYPE_STR, "searchbox_color", {NULL}, &setattr}, - {FP_TYPE_STR, "searchbox_title_color", {NULL}, &setattr}, - {FP_TYPE_STR, "searchbox_border_color", {NULL}, &setattr}, - {FP_TYPE_STR, "position_indicator_color", {NULL}, &setattr}, - {FP_TYPE_STR, "menubox_color", {NULL}, &setattr}, - {FP_TYPE_STR, "menubox_border_color", {NULL}, &setattr}, - {FP_TYPE_STR, "item_color", {NULL}, &setattr}, - {FP_TYPE_STR, "item_selected_color", {NULL}, &setattr}, - {FP_TYPE_STR, "tag_color", {NULL}, &setattr}, - {FP_TYPE_STR, "tag_selected_color", {NULL}, &setattr}, - {FP_TYPE_STR, "tag_key_color", {NULL}, &setattr}, - {FP_TYPE_STR, "tag_key_selected_color", {NULL}, &setattr}, - {FP_TYPE_STR, "check_color", {NULL}, &setattr}, - {FP_TYPE_STR, "check_selected_color", {NULL}, &setattr}, - {FP_TYPE_STR, "uarrow_color", {NULL}, &setattr}, - {FP_TYPE_STR, "darrow_color", {NULL}, &setattr}, - {FP_TYPE_STR, "itemhelp_color", {NULL}, &setattr}, - {FP_TYPE_STR, "form_active_text_color", {NULL}, &setattr}, - {FP_TYPE_STR, "form_text_color", {NULL}, &setattr}, - {FP_TYPE_STR, "form_item_readonly_color", {NULL}, &setattr}, - {FP_TYPE_STR, "gauge_color", {gauge_color}, &setattr}, +static struct figpar_config dialogrc_config[] = { + /* TYPE DIRECTIVE DEFAULT HANDLER */ + {FIGPAR_TYPE_INT, "aspect", {(void *)0}, &setnum}, + {FIGPAR_TYPE_STR, "separate_widget", {separator}, &setstr}, + {FIGPAR_TYPE_INT, "tab_len", {(void *)0}, &setnum}, + {FIGPAR_TYPE_BOOL, "visit_items", {(void *)0}, &setbool}, + {FIGPAR_TYPE_BOOL, "use_shadow", {(void *)1}, &setbool}, + {FIGPAR_TYPE_BOOL, "use_colors", {(void *)1}, &setbool}, + {FIGPAR_TYPE_STR, "screen_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "shadow_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "dialog_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "title_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "border_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "button_active_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "button_inactive_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "button_key_active_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "button_key_inactive_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "button_label_active_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "button_label_inactive_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "inputbox_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "inputbox_border_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "searchbox_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "searchbox_title_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "searchbox_border_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "position_indicator_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "menubox_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "menubox_border_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "item_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "item_selected_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "tag_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "tag_selected_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "tag_key_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "tag_key_selected_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "check_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "check_selected_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "uarrow_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "darrow_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "itemhelp_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "form_active_text_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "form_text_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "form_item_readonly_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "gauge_color", {gauge_color}, &setattr}, {0, NULL, {0}, NULL} }; @@ -108,7 +108,7 @@ static struct fp_config dialogrc_config[] = { * figpar call-back for interpreting value as .dialogrc `Attribute' */ static int -setattr(struct fp_config *option, uint32_t line __unused, +setattr(struct figpar_config *option, uint32_t line __unused, char *directive __unused, char *value) { char *cp = value; @@ -204,7 +204,7 @@ setattr(struct fp_config *option, uint32_t line __unused, * figpar call-back for interpreting value as .dialogrc `Boolean' */ static int -setbool(struct fp_config *option, uint32_t line __unused, +setbool(struct figpar_config *option, uint32_t line __unused, char *directive __unused, char *value) { @@ -227,7 +227,7 @@ setbool(struct fp_config *option, uint32_t line __unused, * figpar call-back for interpreting value as .dialogrc `Number' */ static int -setnum(struct fp_config *option, uint32_t line __unused, +setnum(struct figpar_config *option, uint32_t line __unused, char *directive __unused, char *value) { @@ -247,7 +247,7 @@ setnum(struct fp_config *option, uint32_t line __unused, * figpar call-back for interpreting value as .dialogrc `String' */ static int -setstr(struct fp_config *option, uint32_t line __unused, +setstr(struct figpar_config *option, uint32_t line __unused, char *directive __unused, char *value) { size_t len; @@ -315,7 +315,8 @@ parse_dialogrc(void) } /* Process file (either $DIALOGRC if set, or `$HOME/.dialogrc') */ - res = parse_config(dialogrc_config, path, NULL, FP_BREAK_ON_EQUALS); + res = parse_config(dialogrc_config, + path, NULL, FIGPAR_BREAK_ON_EQUALS); /* Set some globals based on what we parsed */ use_shadow = dialogrc_config_option("use_shadow")->value.boolean; @@ -328,10 +329,10 @@ parse_dialogrc(void) /* * Return a pointer to the `.dialogrc' config option specific to `directive' or - * static fp_dummy_config (full of NULLs) if none found (see + * static figpar_dummy_config (full of NULLs) if none found (see * get_config_option(3); part of figpar(3)). */ -struct fp_config * +struct figpar_config * dialogrc_config_option(const char *directive) { return (get_config_option(dialogrc_config, directive)); diff --git a/lib/libdpv/dialogrc.h b/lib/libdpv/dialogrc.h index 7d1723584d51..a2eb1fbc24aa 100644 --- a/lib/libdpv/dialogrc.h +++ b/lib/libdpv/dialogrc.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2013-2014 Devin Teske + * Copyright (c) 2013-2015 Devin Teske * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,7 +50,7 @@ extern char separator[]; __BEGIN_DECLS void dialogrc_free(void); int parse_dialogrc(void); -struct fp_config *dialogrc_config_option(const char *_directive); +struct figpar_config *dialogrc_config_option(const char *_directive); __END_DECLS #endif /* !_DIALOGRC_H_ */ diff --git a/lib/libfigpar/figpar.3 b/lib/libfigpar/figpar.3 index 8fd49d37c43e..60ab2b50eb85 100644 --- a/lib/libfigpar/figpar.3 +++ b/lib/libfigpar/figpar.3 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd Oct 22, 2015 +.Dd Nov 2, 2015 .Dt FIGPAR 3 .Os .Sh NAME @@ -38,13 +38,13 @@ .In figpar.h .Ft int .Fo parse_config -.Fa "struct fp_config options[], const char *path" -.Fa "int \*[lp]*unknown\*[rp]\*[lp]struct fp_config *option, uint32_t line" +.Fa "struct figpar_config options[], const char *path" +.Fa "int \*[lp]*unknown\*[rp]\*[lp]struct figpar_config *option, uint32_t line" .Fa "char *directive, char *value\*[rp], uint8_t processing_options" .Fc -.Ft "struct fp_config *" +.Ft "struct figpar_config *" .Fo get_config_option -.Fa "struct fp_config options[], const char *directive" +.Fa "struct figpar_config options[], const char *directive" .Fc .In string_m.h .Ft int @@ -91,32 +91,32 @@ Configuration directives, types, and callback functions are provided through data structures defined in .In figpar.h : .Bd -literal -offset indent -struct fp_config { - enum fp_cfgtype type; /* value type */ - const char *directive; /* keyword */ - union fp_cfgvalue value; /* value */ +struct figpar_config { + enum figpar_cfgtype type; /* value type */ + const char *directive; /* keyword */ + union figpar_cfgvalue value; /* value */ /* Pointer to function used when directive is found */ - int (*action)(struct fp_config *option, uint32_t line, + int (*action)(struct figpar_config *option, uint32_t line, char *directive, char *value); }; -enum fp_cfgtype { - FP_TYPE_NONE = 0x0000, /* for directives with no value */ - FP_TYPE_BOOL = 0x0001, /* boolean */ - FP_TYPE_INT = 0x0002, /* signed 32 bit integer */ - FP_TYPE_UINT = 0x0004, /* unsigned 32 bit integer */ - FP_TYPE_STR = 0x0008, /* string pointer */ - FP_TYPE_STRARRAY = 0x0010, /* string array pointer */ - FP_TYPE_DATA1 = 0x0020, /* void data type-1 (whatever) */ - FP_TYPE_DATA2 = 0x0040, /* void data type-2 (whatever) */ - FP_TYPE_DATA3 = 0x0080, /* void data type-3 (whatever) */ - FP_TYPE_RESERVED1 = 0x0100, /* reserved data type-1 (future) */ - FP_TYPE_RESERVED2 = 0x0200, /* reserved data type-2 (future) */ - FP_TYPE_RESERVED3 = 0x0400, /* reserved data type-3 (future) */ +enum figpar_cfgtype { + FIGPAR_TYPE_NONE = 0x0000, /* directives with no value */ + FIGPAR_TYPE_BOOL = 0x0001, /* boolean */ + FIGPAR_TYPE_INT = 0x0002, /* signed 32 bit integer */ + FIGPAR_TYPE_UINT = 0x0004, /* unsigned 32 bit integer */ + FIGPAR_TYPE_STR = 0x0008, /* string pointer */ + FIGPAR_TYPE_STRARRAY = 0x0010, /* string array pointer */ + FIGPAR_TYPE_DATA1 = 0x0020, /* void data type-1 (open) */ + FIGPAR_TYPE_DATA2 = 0x0040, /* void data type-2 (open) */ + FIGPAR_TYPE_DATA3 = 0x0080, /* void data type-3 (open) */ + FIGPAR_TYPE_RESERVED1 = 0x0100, /* reserved data type-1 */ + FIGPAR_TYPE_RESERVED2 = 0x0200, /* reserved data type-2 */ + FIGPAR_TYPE_RESERVED3 = 0x0400, /* reserved data type-3 */ }; -union fp_cfgvalue { +union figpar_cfgvalue { void *data; /* Pointer to NUL-terminated string */ char *str; /* Pointer to NUL-terminated string */ char **strarray; /* Pointer to an array of strings */ @@ -133,26 +133,26 @@ argument to is a mask of bit fields which indicate various processing options. The possible flags are as follows: -.Bl -tag -width FP_BREAK_ON_SEMICOLON -.It Dv FP_BREAK_ON_EQUALS +.Bl -tag -width FIGPAR_BREAK_ON_SEMICOLON +.It Dv FIGPAR_BREAK_ON_EQUALS An equals sign .Pq Ql Li = is normally considered part of the directive. This flag enables terminating the directive at the equals sign. Also makes equals sign optional and transient. -.It Dv FP_BREAK_ON_SEMICOLON +.It Dv FIGPAR_BREAK_ON_SEMICOLON A semicolon .Pq Ql Li \; is normally considered part of the value. This flag enables terminating the value at the semicolon. Also allows multiple statements on a single line separated by semicolon. -.It Dv FP_CASE_SENSITIVE +.It Dv FIGPAR_CASE_SENSITIVE Normally directives are matched case insensitively using .Xr fnmatch 3 . This flag enables directive matching to be case sensitive. -.It Dv FP_REQUIRE_EQUALS +.It Dv FIGPAR_REQUIRE_EQUALS If a directive is not followed by an equals, processing is aborted. -.It Dv FP_STRICT_EQUALS +.It Dv FIGPAR_STRICT_EQUALS Equals must be part of the directive to be considered a delimiter between directive and value. .El @@ -163,14 +163,14 @@ struct array pointer can be NULL and every directive will invoke the .Fn unknown function argument. .Pp -The directive for each fp_config item in the +The directive for each figpar_config item in the .Fn parse_config options argument is matched against each parsed directive using .Xr fnmatch 3 until a match is found. If a match is found, the .Fn action -function for that fp_config directive is invoked with the line number, +function for that figpar_config directive is invoked with the line number, directive, and value. Otherwise if no match, the .Fn unknown @@ -192,11 +192,11 @@ or if no match a pointer to a static dummy struct is returned .Pq whose values are all zero or NULL . .Pp The use of -.Fa "struct fp_config" +.Fa "struct figpar_config" is entirely optional as-is the use of -.Fa "enum fp_cfgtype" +.Fa "enum figpar_cfgtype" or -.Fa "union fp_cfgvalue" . +.Fa "union figpar_cfgvalue" . For example, you could choose to pass a NULL pointer to .Fn parse_config for the first argument and then provide a simple diff --git a/lib/libfigpar/figpar.c b/lib/libfigpar/figpar.c index a97fc85e9097..0a727ff6f041 100644 --- a/lib/libfigpar/figpar.c +++ b/lib/libfigpar/figpar.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2002-2014 Devin Teske + * Copyright (c) 2002-2015 Devin Teske * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,24 +40,25 @@ __FBSDID("$FreeBSD$"); #include "figpar.h" #include "string_m.h" -struct fp_config fp_dummy_config = {0, NULL, {0}, NULL}; +struct figpar_config figpar_dummy_config = {0, NULL, {0}, NULL}; /* - * Search for config option (struct fp_config) in the array of config options, - * returning the struct whose directive matches the given parameter. If no - * match is found, a pointer to the static dummy array (above) is returned. + * Search for config option (struct figpar_config) in the array of config + * options, returning the struct whose directive matches the given parameter. + * If no match is found, a pointer to the static dummy array (above) is + * returned. * * This is to eliminate dependency on the index position of an item in the * array, since the index position is more apt to be changed as code grows. */ -struct fp_config * -get_config_option(struct fp_config options[], const char *directive) +struct figpar_config * +get_config_option(struct figpar_config options[], const char *directive) { uint32_t n; /* Check arguments */ if (options == NULL || directive == NULL) - return (&fp_dummy_config); + return (&figpar_dummy_config); /* Loop through the array, return the index of the first match */ for (n = 0; options[n].directive != NULL; n++) @@ -65,12 +66,12 @@ get_config_option(struct fp_config options[], const char *directive) return (&(options[n])); /* Re-initialize the dummy variable in case it was written to */ - fp_dummy_config.directive = NULL; - fp_dummy_config.type = 0; - fp_dummy_config.action = NULL; - fp_dummy_config.value.u_num = 0; + figpar_dummy_config.directive = NULL; + figpar_dummy_config.type = 0; + figpar_dummy_config.action = NULL; + figpar_dummy_config.value.u_num = 0; - return (&fp_dummy_config); + return (&figpar_dummy_config); } /* @@ -84,9 +85,9 @@ get_config_option(struct fp_config options[], const char *directive) * Returns zero on success; otherwise returns -1 and errno should be consulted. */ int -parse_config(struct fp_config options[], const char *path, - int (*unknown)(struct fp_config *option, uint32_t line, char *directive, - char *value), uint16_t processing_options) +parse_config(struct figpar_config options[], const char *path, + int (*unknown)(struct figpar_config *option, uint32_t line, + char *directive, char *value), uint16_t processing_options) { uint8_t bequals; uint8_t bsemicolon; @@ -119,11 +120,15 @@ parse_config(struct fp_config options[], const char *path, return (-1); /* Processing options */ - bequals = (processing_options & FP_BREAK_ON_EQUALS) == 0 ? 0 : 1; - bsemicolon = (processing_options & FP_BREAK_ON_SEMICOLON) == 0 ? 0 : 1; - case_sensitive = (processing_options & FP_CASE_SENSITIVE) == 0 ? 0 : 1; - require_equals = (processing_options & FP_REQUIRE_EQUALS) == 0 ? 0 : 1; - strict_equals = (processing_options & FP_STRICT_EQUALS) == 0 ? 0 : 1; + bequals = (processing_options & FIGPAR_BREAK_ON_EQUALS) == 0 ? 0 : 1; + bsemicolon = + (processing_options & FIGPAR_BREAK_ON_SEMICOLON) == 0 ? 0 : 1; + case_sensitive = + (processing_options & FIGPAR_CASE_SENSITIVE) == 0 ? 0 : 1; + require_equals = + (processing_options & FIGPAR_REQUIRE_EQUALS) == 0 ? 0 : 1; + strict_equals = + (processing_options & FIGPAR_STRICT_EQUALS) == 0 ? 0 : 1; /* Initialize strings */ directive = value = 0; diff --git a/lib/libfigpar/figpar.h b/lib/libfigpar/figpar.h index 16f825a88502..f2dc45b288ae 100644 --- a/lib/libfigpar/figpar.h +++ b/lib/libfigpar/figpar.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2002-2014 Devin Teske + * Copyright (c) 2002-2015 Devin Teske * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ /* * Union for storing various types of data in a single common container. */ -union fp_cfgvalue { +union figpar_cfgvalue { void *data; /* Pointer to NUL-terminated string */ char *str; /* Pointer to NUL-terminated string */ char **strarray; /* Pointer to an array of strings */ @@ -46,53 +46,53 @@ union fp_cfgvalue { /* * Option types (based on above cfgvalue union) */ -enum fp_cfgtype { - FP_TYPE_NONE = 0x0000, /* for directives with no value */ - FP_TYPE_BOOL = 0x0001, /* boolean */ - FP_TYPE_INT = 0x0002, /* signed 32 bit integer */ - FP_TYPE_UINT = 0x0004, /* unsigned 32 bit integer */ - FP_TYPE_STR = 0x0008, /* string pointer */ - FP_TYPE_STRARRAY = 0x0010, /* string array pointer */ - FP_TYPE_DATA1 = 0x0020, /* void data type-1 (whatever) */ - FP_TYPE_DATA2 = 0x0040, /* void data type-2 (whatever) */ - FP_TYPE_DATA3 = 0x0080, /* void data type-3 (whatever) */ - FP_TYPE_RESERVED1 = 0x0100, /* reserved data type-1 (future) */ - FP_TYPE_RESERVED2 = 0x0200, /* reserved data type-2 (future) */ - FP_TYPE_RESERVED3 = 0x0400, /* reserved data type-3 (future) */ +enum figpar_cfgtype { + FIGPAR_TYPE_NONE = 0x0000, /* directives with no value */ + FIGPAR_TYPE_BOOL = 0x0001, /* boolean */ + FIGPAR_TYPE_INT = 0x0002, /* signed 32 bit integer */ + FIGPAR_TYPE_UINT = 0x0004, /* unsigned 32 bit integer */ + FIGPAR_TYPE_STR = 0x0008, /* string pointer */ + FIGPAR_TYPE_STRARRAY = 0x0010, /* string array pointer */ + FIGPAR_TYPE_DATA1 = 0x0020, /* void data type-1 (open) */ + FIGPAR_TYPE_DATA2 = 0x0040, /* void data type-2 (open) */ + FIGPAR_TYPE_DATA3 = 0x0080, /* void data type-3 (open) */ + FIGPAR_TYPE_RESERVED1 = 0x0100, /* reserved data type-1 */ + FIGPAR_TYPE_RESERVED2 = 0x0200, /* reserved data type-2 */ + FIGPAR_TYPE_RESERVED3 = 0x0400, /* reserved data type-3 */ }; /* * Options to parse_config() for processing_options bitmask */ -#define FP_BREAK_ON_EQUALS 0x0001 /* stop reading directive at `=' */ -#define FP_BREAK_ON_SEMICOLON 0x0002 /* `;' starts a new line */ -#define FP_CASE_SENSITIVE 0x0004 /* directives are case sensitive */ -#define FP_REQUIRE_EQUALS 0x0008 /* assignment directives only */ -#define FP_STRICT_EQUALS 0x0010 /* `=' must be part of directive */ +#define FIGPAR_BREAK_ON_EQUALS 0x0001 /* stop reading directive at `=' */ +#define FIGPAR_BREAK_ON_SEMICOLON 0x0002 /* `;' starts a new line */ +#define FIGPAR_CASE_SENSITIVE 0x0004 /* directives are case sensitive */ +#define FIGPAR_REQUIRE_EQUALS 0x0008 /* assignment directives only */ +#define FIGPAR_STRICT_EQUALS 0x0010 /* `=' must be part of directive */ /* * Anatomy of a config file option */ -struct fp_config { - enum fp_cfgtype type; /* Option value type */ +struct figpar_config { + enum figpar_cfgtype type; /* Option value type */ const char *directive; /* config file keyword */ - union fp_cfgvalue value; /* NB: set by action */ + union figpar_cfgvalue value; /* NB: set by action */ /* * Function pointer; action to be taken when the directive is found */ - int (*action)(struct fp_config *option, uint32_t line, char *directive, - char *value); + int (*action)(struct figpar_config *option, uint32_t line, + char *directive, char *value); }; -extern struct fp_config fp_dummy_config; +extern struct figpar_config figpar_dummy_config; __BEGIN_DECLS -int parse_config(struct fp_config _options[], +int parse_config(struct figpar_config _options[], const char *_path, - int (*_unknown)(struct fp_config *_option, + int (*_unknown)(struct figpar_config *_option, uint32_t _line, char *_directive, char *_value), uint16_t _processing_options); -struct fp_config *get_config_option(struct fp_config _options[], +struct figpar_config *get_config_option(struct figpar_config _options[], const char *_directive); __END_DECLS diff --git a/lib/libnetbsd/README b/lib/libnetbsd/README index ab303007cce4..49afa0b436bf 100644 --- a/lib/libnetbsd/README +++ b/lib/libnetbsd/README @@ -2,6 +2,6 @@ $FreeBSD$ libnetbsd is a thin compatibility layer intended to allow a limited set of NetBSD software to compile as part of the FreeBSD build with -little or no modifiction. It is built as a static library and not +little or no modification. It is built as a static library and not installed for general use. Likewise, its header files are not installed. diff --git a/lib/libohash/Makefile b/lib/libopenbsd/Makefile similarity index 84% rename from lib/libohash/Makefile rename to lib/libopenbsd/Makefile index 198093e289b0..33b9ff0874cb 100644 --- a/lib/libohash/Makefile +++ b/lib/libopenbsd/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -LIB= ohash +LIB= openbsd SRCS= ohash.c INTERNALLIB= diff --git a/lib/libohash/Makefile.depend b/lib/libopenbsd/Makefile.depend similarity index 100% rename from lib/libohash/Makefile.depend rename to lib/libopenbsd/Makefile.depend diff --git a/lib/libopenbsd/README b/lib/libopenbsd/README new file mode 100644 index 000000000000..e9f6d70b5fc5 --- /dev/null +++ b/lib/libopenbsd/README @@ -0,0 +1,7 @@ +$FreeBSD$ + +libopenbsd is a thin compatibility layer intended to allow a limited +set of OpenBSD software to compile as part of the FreeBSD build with +little or no modification. It is built as a static library and not +installed for general use. Likewise, its header files are not +installed. diff --git a/lib/libopenbsd/imsg-buffer.c b/lib/libopenbsd/imsg-buffer.c new file mode 100644 index 000000000000..2ea4d20b9fcd --- /dev/null +++ b/lib/libopenbsd/imsg-buffer.c @@ -0,0 +1,309 @@ +/* $OpenBSD: imsg-buffer.c,v 1.7 2015/07/12 18:40:49 nicm Exp $ */ + +/* + * Copyright (c) 2003, 2004 Henning Brauer + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "imsg.h" + +int ibuf_realloc(struct ibuf *, size_t); +void ibuf_enqueue(struct msgbuf *, struct ibuf *); +void ibuf_dequeue(struct msgbuf *, struct ibuf *); + +struct ibuf * +ibuf_open(size_t len) +{ + struct ibuf *buf; + + if ((buf = calloc(1, sizeof(struct ibuf))) == NULL) + return (NULL); + if ((buf->buf = malloc(len)) == NULL) { + free(buf); + return (NULL); + } + buf->size = buf->max = len; + buf->fd = -1; + + return (buf); +} + +struct ibuf * +ibuf_dynamic(size_t len, size_t max) +{ + struct ibuf *buf; + + if (max < len) + return (NULL); + + if ((buf = ibuf_open(len)) == NULL) + return (NULL); + + if (max > 0) + buf->max = max; + + return (buf); +} + +int +ibuf_realloc(struct ibuf *buf, size_t len) +{ + u_char *b; + + /* on static buffers max is eq size and so the following fails */ + if (buf->wpos + len > buf->max) { + errno = ERANGE; + return (-1); + } + + b = realloc(buf->buf, buf->wpos + len); + if (b == NULL) + return (-1); + buf->buf = b; + buf->size = buf->wpos + len; + + return (0); +} + +int +ibuf_add(struct ibuf *buf, const void *data, size_t len) +{ + if (buf->wpos + len > buf->size) + if (ibuf_realloc(buf, len) == -1) + return (-1); + + memcpy(buf->buf + buf->wpos, data, len); + buf->wpos += len; + return (0); +} + +void * +ibuf_reserve(struct ibuf *buf, size_t len) +{ + void *b; + + if (buf->wpos + len > buf->size) + if (ibuf_realloc(buf, len) == -1) + return (NULL); + + b = buf->buf + buf->wpos; + buf->wpos += len; + return (b); +} + +void * +ibuf_seek(struct ibuf *buf, size_t pos, size_t len) +{ + /* only allowed to seek in already written parts */ + if (pos + len > buf->wpos) + return (NULL); + + return (buf->buf + pos); +} + +size_t +ibuf_size(struct ibuf *buf) +{ + return (buf->wpos); +} + +size_t +ibuf_left(struct ibuf *buf) +{ + return (buf->max - buf->wpos); +} + +void +ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf) +{ + ibuf_enqueue(msgbuf, buf); +} + +int +ibuf_write(struct msgbuf *msgbuf) +{ + struct iovec iov[IOV_MAX]; + struct ibuf *buf; + unsigned int i = 0; + ssize_t n; + + memset(&iov, 0, sizeof(iov)); + TAILQ_FOREACH(buf, &msgbuf->bufs, entry) { + if (i >= IOV_MAX) + break; + iov[i].iov_base = buf->buf + buf->rpos; + iov[i].iov_len = buf->wpos - buf->rpos; + i++; + } + +again: + if ((n = writev(msgbuf->fd, iov, i)) == -1) { + if (errno == EINTR) + goto again; + if (errno == ENOBUFS) + errno = EAGAIN; + return (-1); + } + + if (n == 0) { /* connection closed */ + errno = 0; + return (0); + } + + msgbuf_drain(msgbuf, n); + + return (1); +} + +void +ibuf_free(struct ibuf *buf) +{ + free(buf->buf); + free(buf); +} + +void +msgbuf_init(struct msgbuf *msgbuf) +{ + msgbuf->queued = 0; + msgbuf->fd = -1; + TAILQ_INIT(&msgbuf->bufs); +} + +void +msgbuf_drain(struct msgbuf *msgbuf, size_t n) +{ + struct ibuf *buf, *next; + + for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; + buf = next) { + next = TAILQ_NEXT(buf, entry); + if (buf->rpos + n >= buf->wpos) { + n -= buf->wpos - buf->rpos; + ibuf_dequeue(msgbuf, buf); + } else { + buf->rpos += n; + n = 0; + } + } +} + +void +msgbuf_clear(struct msgbuf *msgbuf) +{ + struct ibuf *buf; + + while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL) + ibuf_dequeue(msgbuf, buf); +} + +int +msgbuf_write(struct msgbuf *msgbuf) +{ + struct iovec iov[IOV_MAX]; + struct ibuf *buf; + unsigned int i = 0; + ssize_t n; + struct msghdr msg; + struct cmsghdr *cmsg; + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(int))]; + } cmsgbuf; + + memset(&iov, 0, sizeof(iov)); + memset(&msg, 0, sizeof(msg)); + memset(&cmsgbuf, 0, sizeof(cmsgbuf)); + TAILQ_FOREACH(buf, &msgbuf->bufs, entry) { + if (i >= IOV_MAX) + break; + iov[i].iov_base = buf->buf + buf->rpos; + iov[i].iov_len = buf->wpos - buf->rpos; + i++; + if (buf->fd != -1) + break; + } + + msg.msg_iov = iov; + msg.msg_iovlen = i; + + if (buf != NULL && buf->fd != -1) { + msg.msg_control = (caddr_t)&cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsg) = buf->fd; + } + +again: + if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) { + if (errno == EINTR) + goto again; + if (errno == ENOBUFS) + errno = EAGAIN; + return (-1); + } + + if (n == 0) { /* connection closed */ + errno = 0; + return (0); + } + + /* + * assumption: fd got sent if sendmsg sent anything + * this works because fds are passed one at a time + */ + if (buf != NULL && buf->fd != -1) { + close(buf->fd); + buf->fd = -1; + } + + msgbuf_drain(msgbuf, n); + + return (1); +} + +void +ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf) +{ + TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry); + msgbuf->queued++; +} + +void +ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf) +{ + TAILQ_REMOVE(&msgbuf->bufs, buf, entry); + + if (buf->fd != -1) + close(buf->fd); + + msgbuf->queued--; + ibuf_free(buf); +} diff --git a/lib/libopenbsd/imsg.c b/lib/libopenbsd/imsg.c new file mode 100644 index 000000000000..cb16bd7c284c --- /dev/null +++ b/lib/libopenbsd/imsg.c @@ -0,0 +1,307 @@ +/* $OpenBSD: imsg.c,v 1.10 2015/07/19 07:18:59 nicm Exp $ */ + +/* + * Copyright (c) 2003, 2004 Henning Brauer + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "imsg.h" + +int imsg_fd_overhead = 0; + +int imsg_get_fd(struct imsgbuf *); + +void +imsg_init(struct imsgbuf *ibuf, int fd) +{ + msgbuf_init(&ibuf->w); + memset(&ibuf->r, 0, sizeof(ibuf->r)); + ibuf->fd = fd; + ibuf->w.fd = fd; + ibuf->pid = getpid(); + TAILQ_INIT(&ibuf->fds); +} + +ssize_t +imsg_read(struct imsgbuf *ibuf) +{ + struct msghdr msg; + struct cmsghdr *cmsg; + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(int) * 1)]; + } cmsgbuf; + struct iovec iov; + ssize_t n = -1; + int fd; + struct imsg_fd *ifd; + + memset(&msg, 0, sizeof(msg)); + memset(&cmsgbuf, 0, sizeof(cmsgbuf)); + + iov.iov_base = ibuf->r.buf + ibuf->r.wpos; + iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = &cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); + + if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL) + return (-1); + +again: + if (getdtablecount() + imsg_fd_overhead + + (CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int) + >= getdtablesize()) { + errno = EAGAIN; + free(ifd); + return (-1); + } + + if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) { + if (errno == EMSGSIZE) + goto fail; + if (errno != EINTR && errno != EAGAIN) + goto fail; + goto again; + } + + ibuf->r.wpos += n; + + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_RIGHTS) { + int i; + int j; + + /* + * We only accept one file descriptor. Due to C + * padding rules, our control buffer might contain + * more than one fd, and we must close them. + */ + j = ((char *)cmsg + cmsg->cmsg_len - + (char *)CMSG_DATA(cmsg)) / sizeof(int); + for (i = 0; i < j; i++) { + fd = ((int *)CMSG_DATA(cmsg))[i]; + if (ifd != NULL) { + ifd->fd = fd; + TAILQ_INSERT_TAIL(&ibuf->fds, ifd, + entry); + ifd = NULL; + } else + close(fd); + } + } + /* we do not handle other ctl data level */ + } + +fail: + if (ifd) + free(ifd); + return (n); +} + +ssize_t +imsg_get(struct imsgbuf *ibuf, struct imsg *imsg) +{ + size_t av, left, datalen; + + av = ibuf->r.wpos; + + if (IMSG_HEADER_SIZE > av) + return (0); + + memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr)); + if (imsg->hdr.len < IMSG_HEADER_SIZE || + imsg->hdr.len > MAX_IMSGSIZE) { + errno = ERANGE; + return (-1); + } + if (imsg->hdr.len > av) + return (0); + datalen = imsg->hdr.len - IMSG_HEADER_SIZE; + ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE; + if (datalen == 0) + imsg->data = NULL; + else if ((imsg->data = malloc(datalen)) == NULL) + return (-1); + + if (imsg->hdr.flags & IMSGF_HASFD) + imsg->fd = imsg_get_fd(ibuf); + else + imsg->fd = -1; + + memcpy(imsg->data, ibuf->r.rptr, datalen); + + if (imsg->hdr.len < av) { + left = av - imsg->hdr.len; + memmove(&ibuf->r.buf, ibuf->r.buf + imsg->hdr.len, left); + ibuf->r.wpos = left; + } else + ibuf->r.wpos = 0; + + return (datalen + IMSG_HEADER_SIZE); +} + +int +imsg_compose(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid, + pid_t pid, int fd, const void *data, u_int16_t datalen) +{ + struct ibuf *wbuf; + + if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) + return (-1); + + if (imsg_add(wbuf, data, datalen) == -1) + return (-1); + + wbuf->fd = fd; + + imsg_close(ibuf, wbuf); + + return (1); +} + +int +imsg_composev(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid, + pid_t pid, int fd, const struct iovec *iov, int iovcnt) +{ + struct ibuf *wbuf; + int i, datalen = 0; + + for (i = 0; i < iovcnt; i++) + datalen += iov[i].iov_len; + + if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) + return (-1); + + for (i = 0; i < iovcnt; i++) + if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1) + return (-1); + + wbuf->fd = fd; + + imsg_close(ibuf, wbuf); + + return (1); +} + +/* ARGSUSED */ +struct ibuf * +imsg_create(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid, + pid_t pid, u_int16_t datalen) +{ + struct ibuf *wbuf; + struct imsg_hdr hdr; + + datalen += IMSG_HEADER_SIZE; + if (datalen > MAX_IMSGSIZE) { + errno = ERANGE; + return (NULL); + } + + hdr.type = type; + hdr.flags = 0; + hdr.peerid = peerid; + if ((hdr.pid = pid) == 0) + hdr.pid = ibuf->pid; + if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) { + return (NULL); + } + if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1) + return (NULL); + + return (wbuf); +} + +int +imsg_add(struct ibuf *msg, const void *data, u_int16_t datalen) +{ + if (datalen) + if (ibuf_add(msg, data, datalen) == -1) { + ibuf_free(msg); + return (-1); + } + return (datalen); +} + +void +imsg_close(struct imsgbuf *ibuf, struct ibuf *msg) +{ + struct imsg_hdr *hdr; + + hdr = (struct imsg_hdr *)msg->buf; + + hdr->flags &= ~IMSGF_HASFD; + if (msg->fd != -1) + hdr->flags |= IMSGF_HASFD; + + hdr->len = (u_int16_t)msg->wpos; + + ibuf_close(&ibuf->w, msg); +} + +void +imsg_free(struct imsg *imsg) +{ + free(imsg->data); +} + +int +imsg_get_fd(struct imsgbuf *ibuf) +{ + int fd; + struct imsg_fd *ifd; + + if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL) + return (-1); + + fd = ifd->fd; + TAILQ_REMOVE(&ibuf->fds, ifd, entry); + free(ifd); + + return (fd); +} + +int +imsg_flush(struct imsgbuf *ibuf) +{ + while (ibuf->w.queued) + if (msgbuf_write(&ibuf->w) <= 0) + return (-1); + return (0); +} + +void +imsg_clear(struct imsgbuf *ibuf) +{ + int fd; + + msgbuf_clear(&ibuf->w); + while ((fd = imsg_get_fd(ibuf)) != -1) + close(fd); +} diff --git a/lib/libopenbsd/imsg.h b/lib/libopenbsd/imsg.h new file mode 100644 index 000000000000..10d684736ed2 --- /dev/null +++ b/lib/libopenbsd/imsg.h @@ -0,0 +1,114 @@ +/* $OpenBSD: imsg.h,v 1.3 2013/12/26 17:32:33 eric Exp $ */ + +/* + * Copyright (c) 2006, 2007 Pierre-Yves Ritschard + * Copyright (c) 2006, 2007, 2008 Reyk Floeter + * Copyright (c) 2003, 2004 Henning Brauer + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +#ifndef _IMSG_H_ +#define _IMSG_H_ + +#define IBUF_READ_SIZE 65535 +#define IMSG_HEADER_SIZE sizeof(struct imsg_hdr) +#define MAX_IMSGSIZE 16384 + +struct ibuf { + TAILQ_ENTRY(ibuf) entry; + u_char *buf; + size_t size; + size_t max; + size_t wpos; + size_t rpos; + int fd; +}; + +struct msgbuf { + TAILQ_HEAD(, ibuf) bufs; + u_int32_t queued; + int fd; +}; + +struct ibuf_read { + u_char buf[IBUF_READ_SIZE]; + u_char *rptr; + size_t wpos; +}; + +struct imsg_fd { + TAILQ_ENTRY(imsg_fd) entry; + int fd; +}; + +struct imsgbuf { + TAILQ_HEAD(, imsg_fd) fds; + struct ibuf_read r; + struct msgbuf w; + int fd; + pid_t pid; +}; + +#define IMSGF_HASFD 1 + +struct imsg_hdr { + u_int32_t type; + u_int16_t len; + u_int16_t flags; + u_int32_t peerid; + u_int32_t pid; +}; + +struct imsg { + struct imsg_hdr hdr; + int fd; + void *data; +}; + + +/* buffer.c */ +struct ibuf *ibuf_open(size_t); +struct ibuf *ibuf_dynamic(size_t, size_t); +int ibuf_add(struct ibuf *, const void *, size_t); +void *ibuf_reserve(struct ibuf *, size_t); +void *ibuf_seek(struct ibuf *, size_t, size_t); +size_t ibuf_size(struct ibuf *); +size_t ibuf_left(struct ibuf *); +void ibuf_close(struct msgbuf *, struct ibuf *); +int ibuf_write(struct msgbuf *); +void ibuf_free(struct ibuf *); +void msgbuf_init(struct msgbuf *); +void msgbuf_clear(struct msgbuf *); +int msgbuf_write(struct msgbuf *); +void msgbuf_drain(struct msgbuf *, size_t); + +/* imsg.c */ +void imsg_init(struct imsgbuf *, int); +ssize_t imsg_read(struct imsgbuf *); +ssize_t imsg_get(struct imsgbuf *, struct imsg *); +int imsg_compose(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, + int, const void *, u_int16_t); +int imsg_composev(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, + int, const struct iovec *, int); +struct ibuf *imsg_create(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, + u_int16_t); +int imsg_add(struct ibuf *, const void *, u_int16_t); +void imsg_close(struct imsgbuf *, struct ibuf *); +void imsg_free(struct imsg *); +int imsg_flush(struct imsgbuf *); +void imsg_clear(struct imsgbuf *); + +#endif diff --git a/lib/libopenbsd/imsg_init.3 b/lib/libopenbsd/imsg_init.3 new file mode 100644 index 000000000000..eb4b1a665d55 --- /dev/null +++ b/lib/libopenbsd/imsg_init.3 @@ -0,0 +1,549 @@ +.\" $OpenBSD: imsg_init.3,v 1.13 2015/07/11 16:23:59 deraadt Exp $ +.\" +.\" Copyright (c) 2010 Nicholas Marriott +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER +.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING +.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" $FreeBSD$ +.\" +.Dd $Mdocdate: July 11 2015 $ +.Dt IMSG_INIT 3 +.Os +.Sh NAME +.Nm imsg_init , +.Nm imsg_read , +.Nm imsg_get , +.Nm imsg_compose , +.Nm imsg_composev , +.Nm imsg_create , +.Nm imsg_add , +.Nm imsg_close , +.Nm imsg_free , +.Nm imsg_flush , +.Nm imsg_clear , +.Nm ibuf_open , +.Nm ibuf_dynamic , +.Nm ibuf_add , +.Nm ibuf_reserve , +.Nm ibuf_seek , +.Nm ibuf_size , +.Nm ibuf_left , +.Nm ibuf_close , +.Nm ibuf_write , +.Nm ibuf_free , +.Nm msgbuf_init , +.Nm msgbuf_clear , +.Nm msgbuf_write , +.Nm msgbuf_drain +.Nd IPC messaging functions +.Sh SYNOPSIS +.In sys/types.h +.In sys/queue.h +.In sys/uio.h +.In imsg.h +.Ft void +.Fn imsg_init "struct imsgbuf *ibuf" "int fd" +.Ft ssize_t +.Fn imsg_read "struct imsgbuf *ibuf" +.Ft ssize_t +.Fn imsg_get "struct imsgbuf *ibuf" "struct imsg *imsg" +.Ft int +.Fn imsg_compose "struct imsgbuf *ibuf" "u_int32_t type" "uint32_t peerid" \ + "pid_t pid" "int fd" "const void *data" "u_int16_t datalen" +.Ft int +.Fn imsg_composev "struct imsgbuf *ibuf" "u_int32_t type" "u_int32_t peerid" \ + "pid_t pid" "int fd" "const struct iovec *iov" "int iovcnt" +.Ft "struct ibuf *" +.Fn imsg_create "struct imsgbuf *ibuf" "u_int32_t type" "u_int32_t peerid" \ + "pid_t pid" "u_int16_t datalen" +.Ft int +.Fn imsg_add "struct ibuf *buf" "const void *data" "u_int16_t datalen" +.Ft void +.Fn imsg_close "struct imsgbuf *ibuf" "struct ibuf *msg" +.Ft void +.Fn imsg_free "struct imsg *imsg" +.Ft int +.Fn imsg_flush "struct imsgbuf *ibuf" +.Ft void +.Fn imsg_clear "struct imsgbuf *ibuf" +.Ft "struct ibuf *" +.Fn ibuf_open "size_t len" +.Ft "struct ibuf *" +.Fn ibuf_dynamic "size_t len" "size_t max" +.Ft int +.Fn ibuf_add "struct ibuf *buf" "const void *data" "size_t len" +.Ft "void *" +.Fn ibuf_reserve "struct ibuf *buf" "size_t len" +.Ft "void *" +.Fn ibuf_seek "struct ibuf *buf" "size_t pos" "size_t len" +.Ft size_t +.Fn ibuf_size "struct ibuf *buf" +.Ft size_t +.Fn ibuf_left "struct ibuf *buf" +.Ft void +.Fn ibuf_close "struct msgbuf *msgbuf" "struct ibuf *buf" +.Ft int +.Fn ibuf_write "struct msgbuf *msgbuf" +.Ft void +.Fn ibuf_free "struct ibuf *buf" +.Ft void +.Fn msgbuf_init "struct msgbuf *msgbuf" +.Ft void +.Fn msgbuf_clear "struct msgbuf *msgbuf" +.Ft int +.Fn msgbuf_write "struct msgbuf *msgbuf" +.Ft void +.Fn msgbuf_drain "struct msgbuf *msgbuf" "size_t n" +.Sh DESCRIPTION +The +.Nm imsg +functions provide a simple mechanism for communication between processes +using sockets. +Each transmitted message is guaranteed to be presented to the receiving program +whole. +They are commonly used in privilege separated processes, where processes with +different rights are required to cooperate. +.Pp +A program using these functions should be linked with +.Em -lutil . +.Pp +The basic +.Nm +structure is the +.Em imsgbuf , +which wraps a file descriptor and represents one side of a channel on which +messages are sent and received: +.Bd -literal -offset indent +struct imsgbuf { + TAILQ_HEAD(, imsg_fd) fds; + struct ibuf_read r; + struct msgbuf w; + int fd; + pid_t pid; +}; +.Ed +.Pp +.Fn imsg_init +is a routine which initializes +.Fa ibuf +as one side of a channel associated with +.Fa fd . +The file descriptor is used to send and receive messages, +but is not closed by any of the imsg functions. +An imsgbuf is initialized with the +.Em w +member as the output buffer queue, +.Em fd +with the file descriptor passed to +.Fn imsg_init +and the other members for internal use only. +.Pp +The +.Fn imsg_clear +function frees any data allocated as part of an imsgbuf. +.Pp +.Fn imsg_create , +.Fn imsg_add +and +.Fn imsg_close +are generic construction routines for messages that are to be sent using an +imsgbuf. +.Pp +.Fn imsg_create +creates a new message with header specified by +.Fa type , +.Fa peerid +and +.Fa pid . +A +.Fa pid +of zero uses the process ID returned by +.Xr getpid 2 +when +.Fa ibuf +was initialized. +In addition to this common imsg header, +.Fa datalen +bytes of space may be reserved for attaching to this imsg. +This space is populated using +.Fn imsg_add . +Additionally, the file descriptor +.Fa fd +may be passed over the socket to the other process. +If +.Fa fd +is given, it is closed in the sending program after the message is sent. +A value of \-1 indicates no file descriptor should be passed. +.Fn imsg_create +returns a pointer to a new message if it succeeds, NULL otherwise. +.Pp +.Fn imsg_add +appends to +.Fa imsg +.Fa len +bytes of ancillary data pointed to by +.Fa buf . +It returns +.Fa len +if it succeeds, \-1 otherwise. +.Pp +.Fn imsg_close +completes creation of +.Fa imsg +by adding it to +.Fa imsgbuf +output buffer. +.Pp +.Fn imsg_compose +is a routine which is used to quickly create and queue an imsg. +It takes the same parameters as the +.Fn imsg_create , +.Fn imsg_add +and +.Fn imsg_close +routines, +except that only one ancillary data buffer can be provided. +This routine returns 1 if it succeeds, \-1 otherwise. +.Pp +.Fn imsg_composev +is similar to +.Fn imsg_compose . +It takes the same parameters, except that the ancillary data buffer is specified +by +.Fa iovec . +.Pp +.Fn imsg_flush +is a function which calls +.Fn msgbuf_write +in a loop until all imsgs in the output buffer are sent. +It returns 0 if it succeeds, \-1 otherwise. +.Pp +The +.Fn imsg_read +routine reads pending data with +.Xr recvmsg 2 +and queues it as individual messages on +.Fa imsgbuf . +It returns the number of bytes read on success, or \-1 on error. +A return value of \-1 from +.Fn imsg_read +invalidates +.Fa imsgbuf , +and renders it suitable only for passing to +.Fn imsg_clear . +.Pp +.Fn imsg_get +fills in an individual imsg pending on +.Fa imsgbuf +into the structure pointed to by +.Fa imsg . +It returns the total size of the message, 0 if no messages are ready, or \-1 +for an error. +Received messages are returned as a +.Em struct imsg , +which must be freed by +.Fn imsg_free +when no longer required. +.Em struct imsg +has this form: +.Bd -literal -offset indent +struct imsg { + struct imsg_hdr hdr; + int fd; + void *data; +}; + +struct imsg_hdr { + u_int32_t type; + u_int16_t len; + u_int16_t flags; + u_int32_t peerid; + u_int32_t pid; +}; +.Ed +.Pp +The header members are: +.Bl -tag -width Ds -offset indent +.It type +A integer identifier, typically used to express the meaning of the message. +.It len +The total length of the imsg, including the header and any ancillary data +transmitted with the message (pointed to by the +.Em data +member of the message itself). +.It flags +Flags used internally by the imsg functions: should not be used by application +programs. +.It peerid, pid +32-bit values specified on message creation and free for any use by the +caller, normally used to identify the message sender. +.El +.Pp +In addition, +.Em struct imsg +has the following: +.Bl -tag -width Ds -offset indent +.It fd +The file descriptor specified when the message was created and passed using the +socket control message API, or \-1 if no file descriptor was sent. +.It data +A pointer to the ancillary data transmitted with the imsg. +.El +.Pp +The IMSG_HEADER_SIZE define is the size of the imsg message header, which +may be subtracted from the +.Fa len +member of +.Em struct imsg_hdr +to obtain the length of any additional data passed with the message. +.Pp +MAX_IMSGSIZE is defined as the maximum size of a single imsg, currently +16384 bytes. +.Sh BUFFERS +The imsg API defines functions to manipulate buffers, used internally and during +construction of imsgs with +.Fn imsg_create . +A +.Em struct ibuf +is a single buffer and a +.Em struct msgbuf +a queue of output buffers for transmission: +.Bd -literal -offset indent +struct ibuf { + TAILQ_ENTRY(ibuf) entry; + u_char *buf; + size_t size; + size_t max; + size_t wpos; + size_t rpos; + int fd; +}; + +struct msgbuf { + TAILQ_HEAD(, ibuf) bufs; + u_int32_t queued; + int fd; +}; +.Ed +.Pp +The +.Fn ibuf_open +function allocates a fixed-length buffer. +The buffer may not be resized and may contain a maximum of +.Fa len +bytes. +On success +.Fn ibuf_open +returns a pointer to the buffer; on failure it returns NULL. +.Pp +.Fn ibuf_dynamic +allocates a resizeable buffer of initial length +.Fa len +and maximum size +.Fa max . +Buffers allocated with +.Fn ibuf_dynamic +are automatically grown if necessary when data is added. +.Pp +.Fn ibuf_add +is a routine which appends a block of data to +.Fa buf . +0 is returned on success and \-1 on failure. +.Pp +.Fn ibuf_reserve +is used to reserve +.Fa len +bytes in +.Fa buf . +A pointer to the start of the reserved space is returned, or NULL on error. +.Pp +.Fn ibuf_seek +is a function which returns a pointer to the part of the buffer at offset +.Fa pos +and of extent +.Fa len . +NULL is returned if the requested range is outside the part of the buffer +in use. +.Pp +.Fn ibuf_size +and +.Fn ibuf_left +are functions which return the total bytes used and available in +.Fa buf +respectively. +.Pp +.Fn ibuf_close +appends +.Fa buf +to +.Fa msgbuf +ready to be sent. +.Pp +The +.Fn ibuf_write +routine transmits as many pending buffers as possible from +.Fn msgbuf +using +.Xr writev 2 . +It returns 1 if it succeeds, \-1 on error and 0 when no buffers were +pending or an EOF condition on the socket is detected. +Temporary resource shortages are returned with errno +.Er EAGAIN +and require the application to retry again in the future. +.Pp +.Fn ibuf_free +frees +.Fa buf +and any associated storage. +.Pp +The +.Fn msgbuf_init +function initializes +.Fa msgbuf +so that buffers may be appended to it. +The +.Em fd +member should also be set directly before +.Fn msgbuf_write +is used. +.Pp +.Fn msgbuf_clear +empties a msgbuf, removing and discarding any queued buffers. +.Pp +The +.Fn msgbuf_write +routine calls +.Xr sendmsg 2 +to transmit buffers queued in +.Fa msgbuf . +It returns 1 if it succeeds, \-1 on error, and 0 when the queue was empty +or an EOF condition on the socket is detected. +Temporary resource shortages are returned with errno +.Er EAGAIN +and require the application to retry again in the future. +.Pp +.Fn msgbuf_drain +discards data from buffers queued in +.Fa msgbuf +until +.Fa n +bytes have been removed or +.Fa msgbuf +is empty. +.Sh EXAMPLES +In a typical program, a channel between two processes is created with +.Xr socketpair 2 , +and an +.Em imsgbuf +created around one file descriptor in each process: +.Bd -literal -offset indent +struct imsgbuf parent_ibuf, child_ibuf; +int imsg_fds[2]; + +if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) + err(1, "socketpair"); + +switch (fork()) { +case -1: + err(1, "fork"); +case 0: + /* child */ + close(imsg_fds[0]); + imsg_init(&child_ibuf, imsg_fds[1]); + exit(child_main(&child_ibuf)); +} + +/* parent */ +close(imsg_fds[1]); +imsg_init(&parent_ibuf, imsg_fds[0]); +exit(parent_main(&parent_ibuf)); +.Ed +.Pp +Messages may then be composed and queued on the +.Em imsgbuf , +for example using the +.Fn imsg_compose +function: +.Bd -literal -offset indent +enum imsg_type { + IMSG_A_MESSAGE, + IMSG_MESSAGE2 +}; + +int +child_main(struct imsgbuf *ibuf) +{ + int idata; + ... + idata = 42; + imsg_compose(ibuf, IMSG_A_MESSAGE, + 0, 0, -1, &idata, sizeof idata); + ... +} +.Ed +.Pp +A mechanism such as +.Xr poll 2 +or the +.Xr event 3 +library is used to monitor the socket file descriptor. +When the socket is ready for writing, queued messages are transmitted with +.Fn msgbuf_write : +.Bd -literal -offset indent + if (msgbuf_write(&ibuf-\*(Gtw) \*(Lt= 0 && errno != EAGAIN) { + /* handle write failure */ + } +.Ed +.Pp +And when ready for reading, messages are first received using +.Fn imsg_read +and then extracted with +.Fn imsg_get : +.Bd -literal -offset indent +void +dispatch_imsg(struct imsgbuf *ibuf) +{ + struct imsg imsg; + ssize_t n, datalen; + int idata; + + if ((n = imsg_read(ibuf)) == -1 || n == 0) { + /* handle socket error */ + } + + for (;;) { + if ((n = imsg_get(ibuf, &imsg)) == -1) { + /* handle read error */ + } + if (n == 0) /* no more messages */ + return; + datalen = imsg.hdr.len - IMSG_HEADER_SIZE; + + switch (imsg.hdr.type) { + case IMSG_A_MESSAGE: + if (datalen \*(Lt sizeof idata) { + /* handle corrupt message */ + } + memcpy(&idata, imsg.data, sizeof idata); + /* handle message received */ + break; + ... + } + + imsg_free(&imsg); + } +} +.Ed +.Sh SEE ALSO +.Xr socketpair 2 , +.Xr unix 4 diff --git a/lib/libohash/ohash.c b/lib/libopenbsd/ohash.c similarity index 100% rename from lib/libohash/ohash.c rename to lib/libopenbsd/ohash.c diff --git a/lib/libohash/ohash.h b/lib/libopenbsd/ohash.h similarity index 100% rename from lib/libohash/ohash.h rename to lib/libopenbsd/ohash.h diff --git a/lib/libohash/ohash_init.3 b/lib/libopenbsd/ohash_init.3 similarity index 100% rename from lib/libohash/ohash_init.3 rename to lib/libopenbsd/ohash_init.3 diff --git a/lib/libohash/ohash_interval.3 b/lib/libopenbsd/ohash_interval.3 similarity index 100% rename from lib/libohash/ohash_interval.3 rename to lib/libopenbsd/ohash_interval.3 diff --git a/lib/libutil/pty.3 b/lib/libutil/pty.3 index f71cc5323d72..0f06cc17811e 100644 --- a/lib/libutil/pty.3 +++ b/lib/libutil/pty.3 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" " -.Dd December 29, 1996 +.Dd November 11, 2015 .Dt PTY 3 .Os .Sh NAME @@ -120,7 +120,7 @@ function may fail and set the global variable .Dv errno for any of the errors specified for the .Xr grantpt 3 , -.Xr posix_openpt 3 , +.Xr posix_openpt 2 , .Xr ptsname 3 , and .Xr unlockpt 3 diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index 9e31e5b22cb2..a5d7380ff68d 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -28,7 +28,7 @@ .\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94 .\" $FreeBSD$ .\" -.Dd Aug 12, 2015 +.Dd November 6, 2015 .Dt IFCONFIG 8 .Os .Sh NAME @@ -2400,6 +2400,21 @@ which are shifted by the number of this parameter. Enable lacp fast-timeout on the interface. .It Cm -lacp_fast_timeout Disable lacp fast-timeout on the interface. +.It Cm lacp_strict +Enable lacp strict compliance on the interface. +The default value can be set via the +.Va net.link.lagg.lacp.default_strict_mode +.Xr sysctl 8 +variable. +.Li 0 +means +.Dq disabled +and +.Li 1 +means +.Dq enabled . +.It Cm -lacp_strict +Disable lacp strict compliance on the interface. .El .Pp The following parameters are specific to IP tunnel interfaces, diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c index accb1754117a..69ffe698ffed 100644 --- a/sbin/ifconfig/ifieee80211.c +++ b/sbin/ifconfig/ifieee80211.c @@ -3185,7 +3185,7 @@ list_scan(int s) getchaninfo(s); ssidmax = verbose ? IEEE80211_NWID_LEN - 1 : 14; - printf("%-*.*s %-17.17s %4s %4s %-7s %3s %4s\n" + printf("%-*.*s %-17.17s %4s %4s %-7s %3s %4s\n" , ssidmax, ssidmax, "SSID/MESH ID" , "BSSID" , "CHAN" @@ -3208,7 +3208,7 @@ list_scan(int s) idp = vp; idlen = sr->isr_ssid_len; } - printf("%-*.*s %s %3d %3dM %3d:%-3d %3d %-4.4s" + printf("%-*.*s %s %3d %3dM %4d:%-4d %4d %-4.4s" , ssidmax , copy_essid(ssid, ssidmax, idp, idlen) , ssid diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c index bc8af9f833a6..366f77f6969f 100644 --- a/sbin/ipfw/ipfw2.c +++ b/sbin/ipfw/ipfw2.c @@ -4983,10 +4983,48 @@ ipfw_flush(int force) static struct _s_x intcmds[] = { { "talist", TOK_TALIST }, { "iflist", TOK_IFLIST }, + { "olist", TOK_OLIST }, { "vlist", TOK_VLIST }, { NULL, 0 } }; +static void +ipfw_list_objects(int ac, char *av[]) +{ + ipfw_obj_lheader req, *olh; + ipfw_obj_ntlv *ntlv; + size_t sz; + int i; + + memset(&req, 0, sizeof(req)); + sz = sizeof(req); + if (do_get3(IP_FW_DUMP_SRVOBJECTS, &req.opheader, &sz) != 0) + if (errno != ENOMEM) + return; + + sz = req.size; + if ((olh = calloc(1, sz)) == NULL) + return; + + olh->size = sz; + if (do_get3(IP_FW_DUMP_SRVOBJECTS, &olh->opheader, &sz) != 0) { + free(olh); + return; + } + + if (olh->count > 0) + printf("Objects list:\n"); + else + printf("There are no objects\n"); + ntlv = (ipfw_obj_ntlv *)(olh + 1); + for (i = 0; i < olh->count; i++) { + printf(" kidx: %4d\ttype: %2d\tname: %s\n", ntlv->idx, + ntlv->head.type, ntlv->name); + ntlv++; + } + free(olh); +} + void ipfw_internal_handler(int ac, char *av[]) { @@ -5005,6 +5043,9 @@ ipfw_internal_handler(int ac, char *av[]) case TOK_TALIST: ipfw_list_ta(ac, av); break; + case TOK_OLIST: + ipfw_list_objects(ac, av); + break; case TOK_VLIST: ipfw_list_values(ac, av); break; diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h index 5a083216d53b..86f2a41733f5 100644 --- a/sbin/ipfw/ipfw2.h +++ b/sbin/ipfw/ipfw2.h @@ -227,6 +227,7 @@ enum tokens { TOK_LOCK, TOK_UNLOCK, TOK_VLIST, + TOK_OLIST, }; /* diff --git a/sbin/savecore/savecore.c b/sbin/savecore/savecore.c index b87b95b3276e..0c1e806e8e9d 100644 --- a/sbin/savecore/savecore.c +++ b/sbin/savecore/savecore.c @@ -491,9 +491,8 @@ DoFile(const char *savedir, const char *device) } lasthd = mediasize - sectorsize; - lseek(fd, lasthd, SEEK_SET); - error = read(fd, &kdhl, sizeof kdhl); - if (error != sizeof kdhl) { + if (lseek(fd, lasthd, SEEK_SET) != lasthd || + read(fd, &kdhl, sizeof(kdhl)) != sizeof(kdhl)) { syslog(LOG_ERR, "error reading last dump header at offset %lld in %s: %m", (long long)lasthd, device); @@ -569,9 +568,8 @@ DoFile(const char *savedir, const char *device) } dumpsize = dtoh64(kdhl.dumplength); firsthd = lasthd - dumpsize - sizeof kdhf; - lseek(fd, firsthd, SEEK_SET); - error = read(fd, &kdhf, sizeof kdhf); - if (error != sizeof kdhf) { + if (lseek(fd, firsthd, SEEK_SET) != firsthd || + read(fd, &kdhf, sizeof(kdhf)) != sizeof(kdhf)) { syslog(LOG_ERR, "error reading first dump header at offset %lld in %s: %m", (long long)firsthd, device); diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c index c89315f28618..1cd31c0670da 100644 --- a/sbin/sysctl/sysctl.c +++ b/sbin/sysctl/sysctl.c @@ -86,29 +86,40 @@ static int strIKtoi(const char *, char **, const char *); static int ctl_sign[CTLTYPE+1] = { [CTLTYPE_INT] = 1, [CTLTYPE_LONG] = 1, + [CTLTYPE_S8] = 1, + [CTLTYPE_S16] = 1, + [CTLTYPE_S32] = 1, [CTLTYPE_S64] = 1, }; static int ctl_size[CTLTYPE+1] = { - [CTLTYPE_U8] = sizeof(uint8_t), - [CTLTYPE_U16] = sizeof(uint16_t), [CTLTYPE_INT] = sizeof(int), [CTLTYPE_UINT] = sizeof(u_int), [CTLTYPE_LONG] = sizeof(long), [CTLTYPE_ULONG] = sizeof(u_long), + [CTLTYPE_S8] = sizeof(int8_t), + [CTLTYPE_S16] = sizeof(int16_t), + [CTLTYPE_S32] = sizeof(int32_t), [CTLTYPE_S64] = sizeof(int64_t), + [CTLTYPE_U8] = sizeof(uint8_t), + [CTLTYPE_U16] = sizeof(uint16_t), + [CTLTYPE_U32] = sizeof(uint32_t), [CTLTYPE_U64] = sizeof(uint64_t), }; static const char *ctl_typename[CTLTYPE+1] = { - [CTLTYPE_U8] = "uint8_t", - [CTLTYPE_U16] = "uint16_t", [CTLTYPE_INT] = "integer", [CTLTYPE_UINT] = "unsigned integer", [CTLTYPE_LONG] = "long integer", [CTLTYPE_ULONG] = "unsigned long", - [CTLTYPE_S64] = "int64_t", + [CTLTYPE_U8] = "uint8_t", + [CTLTYPE_U16] = "uint16_t", + [CTLTYPE_U32] = "uint16_t", [CTLTYPE_U64] = "uint64_t", + [CTLTYPE_S8] = "int8_t", + [CTLTYPE_S16] = "int16_t", + [CTLTYPE_S32] = "int32_t", + [CTLTYPE_S64] = "int64_t", }; static void @@ -225,8 +236,12 @@ parse(const char *string, int lineno) int len, i, j; const void *newval; const char *newvalstr = NULL; + int8_t i8val; uint8_t u8val; + int16_t i16val; uint16_t u16val; + int32_t i32val; + uint32_t u32val; int intval; unsigned int uintval; long longval; @@ -328,13 +343,17 @@ parse(const char *string, int lineno) } switch (kind & CTLTYPE) { - case CTLTYPE_U8: - case CTLTYPE_U16: case CTLTYPE_INT: case CTLTYPE_UINT: case CTLTYPE_LONG: case CTLTYPE_ULONG: + case CTLTYPE_S8: + case CTLTYPE_S16: + case CTLTYPE_S32: case CTLTYPE_S64: + case CTLTYPE_U8: + case CTLTYPE_U16: + case CTLTYPE_U32: case CTLTYPE_U64: if (strlen(newvalstr) == 0) { warnx("empty numeric value"); @@ -353,17 +372,6 @@ parse(const char *string, int lineno) errno = 0; switch (kind & CTLTYPE) { - case CTLTYPE_U8: - u8val = (uint8_t)strtoul(newvalstr, &endptr, 0); - newval = &u8val; - newsize = sizeof(u8val); - break; - case CTLTYPE_U16: - u16val = (uint16_t)strtoul(newvalstr, &endptr, - 0); - newval = &u16val; - newsize = sizeof(u16val); - break; case CTLTYPE_INT: if (strncmp(fmt, "IK", 2) == 0) intval = strIKtoi(newvalstr, &endptr, fmt); @@ -391,11 +399,45 @@ parse(const char *string, int lineno) case CTLTYPE_STRING: newval = newvalstr; break; + case CTLTYPE_S8: + i8val = (int8_t)strtol(newvalstr, &endptr, 0); + newval = &i8val; + newsize = sizeof(i8val); + break; + case CTLTYPE_S16: + i16val = (int16_t)strtol(newvalstr, &endptr, + 0); + newval = &i16val; + newsize = sizeof(i16val); + break; + case CTLTYPE_S32: + i32val = (int32_t)strtol(newvalstr, &endptr, + 0); + newval = &i32val; + newsize = sizeof(i32val); + break; case CTLTYPE_S64: i64val = strtoimax(newvalstr, &endptr, 0); newval = &i64val; newsize = sizeof(i64val); break; + case CTLTYPE_U8: + u8val = (uint8_t)strtoul(newvalstr, &endptr, 0); + newval = &u8val; + newsize = sizeof(u8val); + break; + case CTLTYPE_U16: + u16val = (uint16_t)strtoul(newvalstr, &endptr, + 0); + newval = &u16val; + newsize = sizeof(u16val); + break; + case CTLTYPE_U32: + u32val = (uint32_t)strtoul(newvalstr, &endptr, + 0); + newval = &u32val; + newsize = sizeof(u32val); + break; case CTLTYPE_U64: u64val = strtoumax(newvalstr, &endptr, 0); newval = &u64val; @@ -909,13 +951,17 @@ show_var(int *oid, int nlen) free(oval); return (0); - case CTLTYPE_U8: - case CTLTYPE_U16: case CTLTYPE_INT: case CTLTYPE_UINT: case CTLTYPE_LONG: case CTLTYPE_ULONG: + case CTLTYPE_S8: + case CTLTYPE_S16: + case CTLTYPE_S32: case CTLTYPE_S64: + case CTLTYPE_U8: + case CTLTYPE_U16: + case CTLTYPE_U32: case CTLTYPE_U64: if (!nflag) printf("%s%s", name, sep); @@ -923,14 +969,6 @@ show_var(int *oid, int nlen) sep1 = ""; while (len >= intlen) { switch (kind & CTLTYPE) { - case CTLTYPE_U8: - umv = *(uint8_t *)p; - mv = *(int8_t *)p; - break; - case CTLTYPE_U16: - umv = *(uint16_t *)p; - mv = *(int16_t *)p; - break; case CTLTYPE_INT: case CTLTYPE_UINT: umv = *(u_int *)p; @@ -941,6 +979,21 @@ show_var(int *oid, int nlen) umv = *(u_long *)p; mv = *(long *)p; break; + case CTLTYPE_S8: + case CTLTYPE_U8: + umv = *(uint8_t *)p; + mv = *(int8_t *)p; + break; + case CTLTYPE_S16: + case CTLTYPE_U16: + umv = *(uint16_t *)p; + mv = *(int16_t *)p; + break; + case CTLTYPE_S32: + case CTLTYPE_U32: + umv = *(uint32_t *)p; + mv = *(int32_t *)p; + break; case CTLTYPE_S64: case CTLTYPE_U64: umv = *(uint64_t *)p; diff --git a/secure/lib/libcrypto/Makefile b/secure/lib/libcrypto/Makefile index 43122d7b0e53..fbb38e950c72 100644 --- a/secure/lib/libcrypto/Makefile +++ b/secure/lib/libcrypto/Makefile @@ -14,12 +14,12 @@ NO_LINT= .if exists(Makefile.man) .include "Makefile.man" .endif +.include "Makefile.inc" + .if defined(NOTYET) MAN+= config.5 des_modes.7 .endif -.include "Makefile.inc" - # base sources SRCS= cpt_err.c cryptlib.c cversion.c ex_data.c mem.c mem_dbg.c o_dir.c \ o_fips.c o_init.c o_str.c o_time.c uid.c @@ -380,6 +380,8 @@ INCSDIR= ${INCLUDEDIR}/openssl CSTD= gnu89 +CFLAGS+= -I${.OBJDIR} +CFLAGS+= -I${LCRYPTO_SRC}/crypto CFLAGS+= -I${LCRYPTO_SRC}/crypto/asn1 CFLAGS+= -I${LCRYPTO_SRC}/crypto/evp CFLAGS+= -I${LCRYPTO_SRC}/crypto/modes @@ -391,32 +393,32 @@ AFLAGS+= --noexecstack ACFLAGS+= -Wa,--noexecstack .endif +.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" +OPENSSLCONF_H= opensslconf-x86.h +.else +OPENSSLCONF_H= opensslconf-${MACHINE_CPUARCH}.h +.endif + CLEANFILES= buildinf.h opensslconf.h -buildinf.h: ${.CURDIR}/Makefile +buildinf.h: Makefile ( echo "#ifndef MK1MF_BUILD"; \ echo " /* auto-generated by util/mkbuildinf.pl for crypto/cversion.c */"; \ echo " #define CFLAGS \"compiler: ${COMPILER_TYPE}\""; \ echo " #define PLATFORM \"platform: FreeBSD-${MACHINE_ARCH}\""; \ echo "#endif" ) > ${.TARGET} -.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" -opensslconf.h: opensslconf-x86.h -.else -opensslconf.h: opensslconf-${MACHINE_CPUARCH}.h -.endif +opensslconf.h: ${OPENSSLCONF_H} ${CP} ${.ALLSRC} ${.TARGET} .include .if ${MACHINE_CPUARCH} == "amd64" -.PATH: ${.CURDIR}/amd64 -.elif ${MACHINE_CPUARCH} == "i386" -.PATH: ${.CURDIR}/i386 +_bn_asmpath= ${LCRYPTO_SRC}/crypto/bn/asm .endif -.if ${MACHINE_CPUARCH} == "amd64" -_bn_asmpath= ${LCRYPTO_SRC}/crypto/bn/asm +.if exists(${.CURDIR}/${MACHINE_CPUARCH}) +.PATH: ${.CURDIR}/${MACHINE_CPUARCH} .endif .PATH: ${LCRYPTO_SRC}/crypto \ diff --git a/secure/lib/libcrypto/Makefile.inc b/secure/lib/libcrypto/Makefile.inc index a9387c09ad69..c791d79b893d 100644 --- a/secure/lib/libcrypto/Makefile.inc +++ b/secure/lib/libcrypto/Makefile.inc @@ -7,10 +7,10 @@ OPENSSL_VER= 1.0.2d OPENSSL_DATE= 2015-07-09 LCRYPTO_SRC= ${.CURDIR}/../../../crypto/openssl -LCRYPTO_DOC= ${.CURDIR}/../../../crypto/openssl/doc +LCRYPTO_DOC= ${LCRYPTO_SRC}/doc +CFLAGS+= -I${LCRYPTO_SRC} CFLAGS+= -DTERMIOS -DANSI_SOURCE -CFLAGS+= -I${LCRYPTO_SRC} -I${LCRYPTO_SRC}/crypto -I${.OBJDIR} CFLAGS+= -DOPENSSL_THREADS -DDSO_DLFCN -DHAVE_DLFCN_H .include diff --git a/secure/lib/libssl/Makefile b/secure/lib/libssl/Makefile index 6b2bf3a075a2..5e538def21fe 100644 --- a/secure/lib/libssl/Makefile +++ b/secure/lib/libssl/Makefile @@ -23,6 +23,8 @@ INCSDIR=${INCLUDEDIR}/openssl LIBADD= crypto +CFLAGS+= -I${LCRYPTO_SRC}/crypto + .include .PATH: ${LCRYPTO_SRC}/ssl \ diff --git a/secure/usr.bin/openssl/Makefile b/secure/usr.bin/openssl/Makefile index ccc1b6f08d7c..fad775faab5f 100644 --- a/secure/usr.bin/openssl/Makefile +++ b/secure/usr.bin/openssl/Makefile @@ -9,7 +9,7 @@ LIBADD= ssl crypto .endif .include "../../lib/libcrypto/Makefile.inc" -CFLAGS+=-DMONOLITH -I${.CURDIR} +CFLAGS+= -DMONOLITH SRCS+= app_rand.c apps.c asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c \ dgst.c dh.c dhparam.c dsa.c dsaparam.c ec.c ecparam.c enc.c engine.c \ diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index cfb66468ca47..68862e5d64ed 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -379,8 +379,6 @@ MAN= aac.4 \ oce.4 \ ohci.4 \ orm.4 \ - otus.4 \ - otusfw.4 \ ow.4 \ ow_temp.4 \ owc.4 \ @@ -425,8 +423,6 @@ MAN= aac.4 \ rndtest.4 \ route.4 \ rp.4 \ - rsu.4 \ - rsufw.4 \ rue.4 \ rum.4 \ run.4 \ @@ -672,7 +668,6 @@ MLINKS+=nge.4 if_nge.4 MLINKS+=${_ntb.4} ${_if_ntb.4} \ ${_ntb.4} ${_ntb_hw.4} MLINKS+=${_nxge.4} ${_if_nxge.4} -MLINKS+=otus.4 if_otus.4 MLINKS+=ow.4 onewire.4 MLINKS+=patm.4 if_patm.4 MLINKS+=pccbb.4 cbb.4 @@ -686,7 +681,6 @@ MLINKS+=rl.4 if_rl.4 MLINKS+=rue.4 if_rue.4 MLINKS+=rum.4 if_rum.4 MLINKS+=run.4 if_run.4 -MLINKS+=rsu.4 if_rsu.4 MLINKS+=scsi.4 CAM.4 \ scsi.4 cam.4 \ scsi.4 scbus.4 \ @@ -715,7 +709,6 @@ MLINKS+=tl.4 if_tl.4 MLINKS+=tun.4 if_tun.4 MLINKS+=tx.4 if_tx.4 MLINKS+=txp.4 if_txp.4 -MLINKS+=urtwn.4 if_urtwn.4 MLINKS+=vge.4 if_vge.4 MLINKS+=vlan.4 if_vlan.4 MLINKS+=vxlan.4 if_vxlan.4 @@ -869,6 +862,10 @@ _pfsync.4= pfsync.4 .if ${MK_USB} != "no" MAN+= \ + otus.4 \ + otusfw.4 \ + rsu.4 \ + rsufw.4 \ u3g.4 \ uark.4 \ uart.4 \ @@ -922,6 +919,8 @@ MAN+= \ uvisor.4 \ uvscom.4 \ +MLINKS+=otus.4 if_otus.4 +MLINKS+=rsu.4 if_rsu.4 MLINKS+=u3g.4 u3gstub.4 MLINKS+=uath.4 if_uath.4 MLINKS+=udav.4 if_udav.4 @@ -929,6 +928,7 @@ MLINKS+=upgt.4 if_upgt.4 MLINKS+=ural.4 if_ural.4 MLINKS+=urndis.4 if_urndis.4 MLINKS+=${_urtw.4} ${_if_urtw.4} +MLINKS+=urtwn.4 if_urtwn.4 .endif .include diff --git a/share/man/man4/ddb.4 b/share/man/man4/ddb.4 index 8d2a947c9679..d29bcdda78a0 100644 --- a/share/man/man4/ddb.4 +++ b/share/man/man4/ddb.4 @@ -60,7 +60,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 16, 2015 +.Dd November 5, 2015 .Dt DDB 4 .Os .Sh NAME @@ -560,8 +560,8 @@ The same as "show pcpu", but for every CPU present in the system. .Pp .It Ic show Cm allrman Show information related with resource management, including -interrupt request lines, DMA request lines, I/O ports and I/O memory -addresses. +interrupt request lines, DMA request lines, I/O ports, I/O memory +addresses, and Resource IDs. .\" .Pp .It Ic show Cm apic diff --git a/share/man/man4/lagg.4 b/share/man/man4/lagg.4 index 0b66c3df5e5d..da070f158d0e 100644 --- a/share/man/man4/lagg.4 +++ b/share/man/man4/lagg.4 @@ -16,7 +16,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 1, 2014 +.Dd November 6, 2015 .Dt LAGG 4 .Os .Sh NAME @@ -156,6 +156,7 @@ Gigabit Ethernet interfaces: .Bd -literal -offset indent # ifconfig bge0 up # ifconfig bge1 up +# ifconfig lagg0 create # ifconfig lagg0 laggproto lacp laggport bge0 laggport bge1 \e 192.168.1.1 netmask 255.255.255.0 .Ed @@ -168,6 +169,7 @@ device will be used: # ifconfig em0 up # ifconfig ath0 ether 00:11:22:33:44:55 # ifconfig create wlan0 wlandev ath0 ssid my_net up +# ifconfig lagg0 create # ifconfig lagg0 laggproto failover laggport em0 laggport wlan0 \e 192.168.1.1 netmask 255.255.255.0 .Ed diff --git a/share/man/man4/xnb.4 b/share/man/man4/xnb.4 index a0c1c60ac52d..a23547d68ef0 100644 --- a/share/man/man4/xnb.4 +++ b/share/man/man4/xnb.4 @@ -57,12 +57,12 @@ will run on Domain 0 and the netfront driver will run on a guest domain. However, it is also possible to run .Nm on a guest domain. -It may be bridged or routed to provide the netfront's +It may be bridged or routed to provide the netfront domain access to other guest domains or to a physical network. .Pp In most respects, the .Nm -device appears to the OS as an other Ethernet device. +device appears to the OS as any other Ethernet device. It can be configured at runtime entirely with .Xr ifconfig 8 . In particular, it supports MAC changing, arbitrary MTU sizes, checksum @@ -101,9 +101,8 @@ device driver first appeared in The .Nm driver was written by -.An Alan Somers Aq Mt alans@spectralogic.com -and -.An John Suykerbuyk Aq Mt johns@spectralogic.com . +.An Alan Somers Aq Mt asomers@FreeBSD.org +and John Suykerbuyk. .Sh CAVEATS Packets sent through Xennet pass over shared memory, so the protocol includes no form of link-layer checksum or CRC. diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5 index 543f34431988..192ea89c8925 100644 --- a/share/man/man5/src.conf.5 +++ b/share/man/man5/src.conf.5 @@ -1,7 +1,7 @@ .\" DO NOT EDIT-- this file is automatically generated. -.\" from FreeBSD: head/tools/build/options/makeman 287942 2015-09-17 22:04:46Z bdrewery +.\" from FreeBSD: head/tools/build/options/makeman 290435 2015-11-06 05:28:08Z bdrewery .\" $FreeBSD$ -.Dd September 18, 2015 +.Dd November 5, 2015 .Dt SRC.CONF 5 .Os .Sh NAME @@ -484,6 +484,14 @@ arm64/aarch64. .\" from FreeBSD: head/tools/build/options/WITHOUT_EXAMPLES 156938 2006-03-21 09:06:24Z ru Set to avoid installing examples to .Pa /usr/share/examples/ . +.It Va WITH_FAST_DEPEND +.\" from FreeBSD: head/tools/build/options/WITH_FAST_DEPEND 290433 2015-11-06 04:45:29Z bdrewery +Set to generate +.Sy .depend +files in the build during compilation instead of the +historial +.Xr mkdep 1 +call during the "make depend" phase. .It Va WITHOUT_FDT .\" from FreeBSD: head/tools/build/options/WITHOUT_FDT 221539 2011-05-06 19:10:27Z ru Set to not build Flattened Device Tree support as part of the base system. diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 516d6c3ebe77..f5f51640225b 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -1274,6 +1274,7 @@ MLINKS+=pci.9 pci_alloc_msi.9 \ pci.9 pci_find_device.9 \ pci.9 pci_find_extcap.9 \ pci.9 pci_find_htcap.9 \ + pci.9 pci_find_pcie_root_port.9 \ pci.9 pci_get_max_read_req.9 \ pci.9 pci_get_powerstate.9 \ pci.9 pci_get_vpd_ident.9 \ @@ -1290,7 +1291,10 @@ MLINKS+=pci.9 pci_alloc_msi.9 \ pci.9 pci_save_state.9 \ pci.9 pci_set_powerstate.9 \ pci.9 pci_set_max_read_req.9 \ - pci.9 pci_write_config.9 + pci.9 pci_write_config.9 \ + pci.9 pcie_adjust_config.9 \ + pci.9 pcie_read_config.9 \ + pci.9 pcie_write_config.9 MLINKS+=pci_iov_schema.9 pci_iov_schema_alloc_node.9 \ pci_iov_schema.9 pci_iov_schema_add_bool.9 \ pci_iov_schema.9 pci_iov_schema_add_string.9 \ @@ -1627,10 +1631,16 @@ MLINKS+=sysctl.9 SYSCTL_DECL.9 \ sysctl.9 SYSCTL_ADD_PROC.9 \ sysctl.9 SYSCTL_ADD_QUAD.9 \ sysctl.9 SYSCTL_ADD_ROOT_NODE.9 \ + sysctl.9 SYSCTL_ADD_S8.9 \ + sysctl.9 SYSCTL_ADD_S16.9 \ + sysctl.9 SYSCTL_ADD_S32.9 \ + sysctl.9 SYSCTL_ADD_S64.9 \ sysctl.9 SYSCTL_ADD_STRING.9 \ sysctl.9 SYSCTL_ADD_STRUCT.9 \ sysctl.9 SYSCTL_ADD_U8.9 \ sysctl.9 SYSCTL_ADD_U16.9 \ + sysctl.9 SYSCTL_ADD_U32.9 \ + sysctl.9 SYSCTL_ADD_U64.9 \ sysctl.9 SYSCTL_ADD_UAUTO.9 \ sysctl.9 SYSCTL_ADD_UINT.9 \ sysctl.9 SYSCTL_ADD_ULONG.9 \ @@ -1646,10 +1656,16 @@ MLINKS+=sysctl.9 SYSCTL_DECL.9 \ sysctl.9 SYSCTL_PROC.9 \ sysctl.9 SYSCTL_QUAD.9 \ sysctl.9 SYSCTL_ROOT_NODE.9 \ + sysctl.9 SYSCTL_S8.9 \ + sysctl.9 SYSCTL_S16.9 \ + sysctl.9 SYSCTL_S32.9 \ + sysctl.9 SYSCTL_S64.9 \ sysctl.9 SYSCTL_STRING.9 \ sysctl.9 SYSCTL_STRUCT.9 \ sysctl.9 SYSCTL_U8.9 \ sysctl.9 SYSCTL_U16.9 \ + sysctl.9 SYSCTL_U32.9 \ + sysctl.9 SYSCTL_U64.9 \ sysctl.9 SYSCTL_UINT.9 \ sysctl.9 SYSCTL_ULONG.9 \ sysctl.9 SYSCTL_UQUAD.9 diff --git a/share/man/man9/pci.9 b/share/man/man9/pci.9 index 5d98e9cd4f92..4faa5f2a4a9d 100644 --- a/share/man/man9/pci.9 +++ b/share/man/man9/pci.9 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 8, 2015 +.Dd November 5, 2015 .Dt PCI 9 .Os .Sh NAME @@ -42,6 +42,7 @@ .Nm pci_find_device , .Nm pci_find_extcap , .Nm pci_find_htcap , +.Nm pci_find_pcie_root_port , .Nm pci_get_max_read_req , .Nm pci_get_powerstate , .Nm pci_get_vpd_ident , @@ -58,7 +59,10 @@ .Nm pci_save_state , .Nm pci_set_max_read_req , .Nm pci_set_powerstate , -.Nm pci_write_config +.Nm pci_write_config , +.Nm pcie_adjust_config , +.Nm pcie_read_config , +.Nm pcie_write_config .Nd PCI bus interface .Sh SYNOPSIS .In sys/bus.h @@ -88,6 +92,8 @@ .Fn pci_find_extcap "device_t dev" "int capability" "int *capreg" .Ft int .Fn pci_find_htcap "device_t dev" "int capability" "int *capreg" +.Ft device_t +.Fn pci_find_pcie_root_port "device_t dev" .Ft int .Fn pci_get_max_read_req "device_t dev" .Ft int @@ -118,6 +124,18 @@ .Fn pci_set_powerstate "device_t dev" "int state" .Ft void .Fn pci_write_config "device_t dev" "int reg" "uint32_t val" "int width" +.Ft uint32_t +.Fo pcie_adjust_config +.Fa "device_t dev" +.Fa "int reg" +.Fa "uint32_t mask" +.Fa "uint32_t val" +.Fa "int width" +.Fc +.Ft uint32_t +.Fn pcie_read_config "device_t dev" "int reg" "int width" +.Ft void +.Fn pcie_write_config "device_t dev" "int reg" "uint32_t val" "int width" .In dev/pci/pci_iov.h .Ft int .Fn pci_iov_attach "device_t dev" "nvlist_t *pf_schema" "nvlist_t *vf_schema" @@ -159,6 +177,48 @@ with .Fa width specifying the size of the access. .Pp +The +.Fn pcie_adjust_config +function is used to modify the value of a register in the PCI-express +capability register set of device +.Fa dev . +The offset +.Fa reg +specifies a relative offset in the register set with +.Fa width +specifying the size of the access. +The new value of the register is computed by modifying bits set in +.Fa mask +to the value in +.Fa val . +Any bits not specified in +.Fa mask +are preserved. +The previous value of the register is returned. +.Pp +The +.Fn pcie_read_config +function is used to read the value of a register in the PCI-express +capability register set of device +.Fa dev . +The offset +.Fa reg +specifies a relative offset in the register set with +.Fa width +specifying the size of the access. +.Pp +The +.Fn pcie_write_config +function is used to write the value +.Fa val +to a register in the PCI-express capability register set of device +.Fa dev . +The offset +.Fa reg +specifies a relative offset in the register set with +.Fa width +specifying the size of the access. +.Pp .Em NOTE : Device drivers should only use these functions for functionality that is not available via another @@ -281,6 +341,16 @@ If the capability is not found or the device is not a HyperTransport device, returns an error. .Pp The +.Fn pci_find_pcie_root_port +function walks up the PCI device hierarchy to locate the PCI-express root +port upstream of +.Fa dev . +If a root port is not found, +.Fn pci_find_pcie_root_port +returns +.Dv NULL . +.Pp +The .Fn pci_get_vpd_ident function is used to fetch a device's Vital Product Data .Pq VPD diff --git a/share/man/man9/sysctl.9 b/share/man/man9/sysctl.9 index c0f836314a05..ba1ffd9f2c8e 100644 --- a/share/man/man9/sysctl.9 +++ b/share/man/man9/sysctl.9 @@ -37,10 +37,16 @@ .Nm SYSCTL_ADD_PROC , .Nm SYSCTL_ADD_QUAD , .Nm SYSCTL_ADD_ROOT_NODE , +.Nm SYSCTL_ADD_S8 , +.Nm SYSCTL_ADD_S16 , +.Nm SYSCTL_ADD_S32 , +.Nm SYSCTL_ADD_S64 , .Nm SYSCTL_ADD_STRING , .Nm SYSCTL_ADD_STRUCT , .Nm SYSCTL_ADD_U8 , .Nm SYSCTL_ADD_U16 , +.Nm SYSCTL_ADD_U32 , +.Nm SYSCTL_ADD_U64 , .Nm SYSCTL_ADD_UAUTO , .Nm SYSCTL_ADD_UINT , .Nm SYSCTL_ADD_ULONG , @@ -56,10 +62,16 @@ .Nm SYSCTL_PROC , .Nm SYSCTL_QUAD , .Nm SYSCTL_ROOT_NODE , +.Nm SYSCTL_S8 , +.Nm SYSCTL_S16 , +.Nm SYSCTL_S32 , +.Nm SYSCTL_S64 , .Nm SYSCTL_STRING , .Nm SYSCTL_STRUCT , .Nm SYSCTL_U8 , .Nm SYSCTL_U16 , +.Nm SYSCTL_U32 , +.Nm SYSCTL_U64 , .Nm SYSCTL_UINT , .Nm SYSCTL_ULONG , .Nm SYSCTL_UQUAD @@ -76,7 +88,7 @@ .Fa "const char *name" .Fa "int ctlflags" .Fa "int *ptr" -.Fa "intptr_t val" +.Fa "int val" .Fa "const char *descr" .Fc .Ft struct sysctl_oid * @@ -131,7 +143,7 @@ .Fa "int number" .Fa "const char *name" .Fa "int ctlflags" -.Fa "quad_t *ptr" +.Fa "int64_t *ptr" .Fa "const char *descr" .Fc .Ft struct sysctl_oid * @@ -144,6 +156,50 @@ .Fa "const char *descr" .Fc .Ft struct sysctl_oid * +.Fo SYSCTL_ADD_S8 +.Fa "struct sysctl_ctx_list *ctx" +.Fa "struct sysctl_oid_list *parent" +.Fa "int number" +.Fa "const char *name" +.Fa "int ctlflags" +.Fa "int8_t *ptr" +.Fa "int8_t val" +.Fa "const char *descr" +.Fc +.Ft struct sysctl_oid * +.Fo SYSCTL_ADD_S16 +.Fa "struct sysctl_ctx_list *ctx" +.Fa "struct sysctl_oid_list *parent" +.Fa "int number" +.Fa "const char *name" +.Fa "int ctlflags" +.Fa "int16_t *ptr" +.Fa "int16_t val" +.Fa "const char *descr" +.Fc +.Ft struct sysctl_oid * +.Fo SYSCTL_ADD_S32 +.Fa "struct sysctl_ctx_list *ctx" +.Fa "struct sysctl_oid_list *parent" +.Fa "int number" +.Fa "const char *name" +.Fa "int ctlflags" +.Fa "int32_t *ptr" +.Fa "int32_t val" +.Fa "const char *descr" +.Fc +.Ft struct sysctl_oid * +.Fo SYSCTL_ADD_S64 +.Fa "struct sysctl_ctx_list *ctx" +.Fa "struct sysctl_oid_list *parent" +.Fa "int number" +.Fa "const char *name" +.Fa "int ctlflags" +.Fa "int64_t *ptr" +.Fa "int64_t val" +.Fa "const char *descr" +.Fc +.Ft struct sysctl_oid * .Fo SYSCTL_ADD_STRING .Fa "struct sysctl_ctx_list *ctx" .Fa "struct sysctl_oid_list *parent" @@ -172,8 +228,8 @@ .Fa "int number" .Fa "const char *name" .Fa "int ctlflags" -.Fa "unsigned int *ptr" -.Fa "intptr_t val" +.Fa "uint8_t *ptr" +.Fa "uint8_t val" .Fa "const char *descr" .Fc .Ft struct sysctl_oid * @@ -183,8 +239,30 @@ .Fa "int number" .Fa "const char *name" .Fa "int ctlflags" -.Fa "unsigned int *ptr" -.Fa "intptr_t val" +.Fa "uint16_t *ptr" +.Fa "uint16_t val" +.Fa "const char *descr" +.Fc +.Ft struct sysctl_oid * +.Fo SYSCTL_ADD_U32 +.Fa "struct sysctl_ctx_list *ctx" +.Fa "struct sysctl_oid_list *parent" +.Fa "int number" +.Fa "const char *name" +.Fa "int ctlflags" +.Fa "uint32_t *ptr" +.Fa "uint32_t val" +.Fa "const char *descr" +.Fc +.Ft struct sysctl_oid * +.Fo SYSCTL_ADD_U64 +.Fa "struct sysctl_ctx_list *ctx" +.Fa "struct sysctl_oid_list *parent" +.Fa "int number" +.Fa "const char *name" +.Fa "int ctlflags" +.Fa "uint64_t *ptr" +.Fa "uint64_t val" .Fa "const char *descr" .Fc .Ft struct sysctl_oid * @@ -195,7 +273,7 @@ .Fa "const char *name" .Fa "int ctlflags" .Fa "unsigned int *ptr" -.Fa "intptr_t val" +.Fa "unsigned int val" .Fa "const char *descr" .Fc .Ft struct sysctl_oid * @@ -215,7 +293,7 @@ .Fa "int number" .Fa "const char *name" .Fa "int ctlflags" -.Fa "u_quad_t *ptr" +.Fa "uint64_t *ptr" .Fa "const char *descr" .Fc .Ft struct sysctl_oid * @@ -251,11 +329,17 @@ .Fn SYSCTL_OPAQUE parent number name ctlflags ptr len format descr .Fn SYSCTL_PROC parent number name ctlflags arg1 arg2 handler format descr .Fn SYSCTL_QUAD parent number name ctlflags ptr val descr +.Fn SYSCTL_ROOT_NODE number name ctlflags handler descr +.Fn SYSCTL_S8 parent number name ctlflags ptr val descr +.Fn SYSCTL_S16 parent number name ctlflags ptr val descr +.Fn SYSCTL_S32 parent number name ctlflags ptr val descr +.Fn SYSCTL_S64 parent number name ctlflags ptr val descr .Fn SYSCTL_STRING parent number name ctlflags arg len descr .Fn SYSCTL_STRUCT parent number name ctlflags ptr struct_type descr -.Fn SYSCTL_ROOT_NODE number name ctlflags handler descr .Fn SYSCTL_U8 parent number name ctlflags ptr val descr .Fn SYSCTL_U16 parent number name ctlflags ptr val descr +.Fn SYSCTL_U32 parent number name ctlflags ptr val descr +.Fn SYSCTL_U64 parent number name ctlflags ptr val descr .Fn SYSCTL_UINT parent number name ctlflags ptr val descr .Fn SYSCTL_ULONG parent number name ctlflags ptr val descr .Fn SYSCTL_UQUAD parent number name ctlflags ptr val descr @@ -439,10 +523,16 @@ Static sysctls are declared using one of the .Fn SYSCTL_PROC , .Fn SYSCTL_QUAD , .Fn SYSCTL_ROOT_NODE , +.Fn SYSCTL_S8 , +.Fn SYSCTL_S16 , +.Fn SYSCTL_S32 , +.Fn SYSCTL_S64 , .Fn SYSCTL_STRING , .Fn SYSCTL_STRUCT , .Fn SYSCTL_U8 , .Fn SYSCTL_U16 , +.Fn SYSCTL_U32 , +.Fn SYSCTL_U64 , .Fn SYSCTL_UINT , .Fn SYSCTL_ULONG or @@ -457,10 +547,16 @@ Dynamic nodes are created using one of the .Fn SYSCTL_ADD_PROC , .Fn SYSCTL_ADD_QUAD , .Fn SYSCTL_ADD_ROOT_NODE , +.Fn SYSCTL_ADD_S8 , +.Fn SYSCTL_ADD_S16 , +.Fn SYSCTL_ADD_S32 , +.Fn SYSCTL_ADD_S64 , .Fn SYSCTL_ADD_STRING , .Fn SYSCTL_ADD_STRUCT , .Fn SYSCTL_ADD_U8 , .Fn SYSCTL_ADD_U16 , +.Fn SYSCTL_ADD_U32 , +.Fn SYSCTL_ADD_U64 , .Fn SYSCTL_ADD_UAUTO , .Fn SYSCTL_ADD_UINT , .Fn SYSCTL_ADD_ULONG , @@ -484,6 +580,12 @@ This is a node intended to be a parent for other nodes. This is a signed integer. .It Dv CTLTYPE_STRING This is a nul-terminated string stored in a character array. +.It Dv CTLTYPE_S8 +This is an 8-bit signed integer. +.It Dv CTLTYPE_S16 +This is a 16-bit signed integer. +.It Dv CTLTYPE_S32 +This is a 32-bit signed integer. .It Dv CTLTYPE_S64 This is a 64-bit signed integer. .It Dv CTLTYPE_OPAQUE @@ -495,14 +597,16 @@ Alias for This is an 8-bit unsigned integer. .It Dv CTLTYPE_U16 This is a 16-bit unsigned integer. +.It Dv CTLTYPE_U32 +This is a 32-bit unsigned integer. +.It Dv CTLTYPE_U64 +This is a 64-bit unsigned integer. .It Dv CTLTYPE_UINT This is an unsigned integer. .It Dv CTLTYPE_LONG This is a signed long. .It Dv CTLTYPE_ULONG This is an unsigned long. -.It Dv CTLTYPE_U64 -This is a 64-bit unsigned integer. .El .Pp All sysctl types except for new node declarations require one of the following diff --git a/share/man/man9/sysctl_add_oid.9 b/share/man/man9/sysctl_add_oid.9 index e2c75e82a280..e309f6529fdf 100644 --- a/share/man/man9/sysctl_add_oid.9 +++ b/share/man/man9/sysctl_add_oid.9 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 28, 2014 +.Dd November 6, 2015 .Dt SYSCTL_ADD_OID 9 .Os .Sh NAME @@ -47,7 +47,7 @@ .Fa "const char *name" .Fa "int kind" .Fa "void *arg1" -.Fa "intptr_t arg2" +.Fa "intmax_t arg2" .Fa "int (*handler) (SYSCTL_HANDLER_ARGS)" .Fa "const char *format" .Fa "const char *descr" diff --git a/share/mk/bsd.dep.mk b/share/mk/bsd.dep.mk index 965f7034bdb8..8cc814dffc3d 100644 --- a/share/mk/bsd.dep.mk +++ b/share/mk/bsd.dep.mk @@ -54,6 +54,18 @@ MKDEPCMD?= CC='${CC} ${DEPFLAGS}' mkdep MKDEPCMD?= mkdep .endif DEPENDFILE?= .depend +DEPENDFILES= ${DEPENDFILE} +.if ${MK_FAST_DEPEND} == "yes" +DEPENDFILES+= ${DEPENDFILE}.* +DEPEND_CFLAGS+= -MD -MP -MF${DEPENDFILE}.${.TARGET} +DEPEND_CFLAGS+= -MT${.TARGET} +CFLAGS+= ${DEPEND_CFLAGS} +DEPENDOBJS+= ${OBJS} ${POBJS} ${SOBJS} +.for __obj in ${DEPENDOBJS:O:u} +.sinclude "${DEPENDFILE}.${__obj}" +DEPENDFILES_OBJS+= ${DEPENDFILE}.${__obj} +.endfor +.endif # ${MK_FAST_DEPEND} == "yes" # Keep `tags' here, before SRCS are mangled below for `depend'. .if !target(tags) && defined(SRCS) && !defined(NO_TAGS) @@ -161,7 +173,7 @@ afterdepend: beforedepend depend: beforedepend ${DEPENDFILE} afterdepend # Tell bmake not to look for generated files via .PATH -.NOPATH: ${DEPENDFILE} +.NOPATH: ${DEPENDFILE} ${DEPENDFILES_OBJS} # Different types of sources are compiled with slightly different flags. # Split up the sources, and filter out headers and non-applicable flags. @@ -172,6 +184,7 @@ MKDEP_CXXFLAGS= ${CXXFLAGS:M-nostdinc*} ${CXXFLAGS:M-[BIDU]*} \ DPSRCS+= ${SRCS} ${DEPENDFILE}: ${DPSRCS} +.if ${MK_FAST_DEPEND} == "no" rm -f ${DEPENDFILE} .if !empty(DPSRCS:M*.[cS]) ${MKDEPCMD} -f ${DEPENDFILE} -a ${MKDEP} \ @@ -182,7 +195,11 @@ ${DEPENDFILE}: ${DPSRCS} ${MKDEPCMD} -f ${DEPENDFILE} -a ${MKDEP} \ ${MKDEP_CXXFLAGS} \ ${.ALLSRC:M*.cc} ${.ALLSRC:M*.C} ${.ALLSRC:M*.cpp} ${.ALLSRC:M*.cxx} +.else .endif +.else + : > ${.TARGET} +.endif # ${MK_FAST_DEPEND} == "no" .if target(_EXTRADEPEND) _EXTRADEPEND: .USE ${DEPENDFILE}: _EXTRADEPEND @@ -207,12 +224,12 @@ afterdepend: cleandepend: .if defined(SRCS) .if ${CTAGS:T} == "gtags" - rm -f ${DEPENDFILE} GPATH GRTAGS GSYMS GTAGS + rm -f ${DEPENDFILES} GPATH GRTAGS GSYMS GTAGS .if defined(HTML) rm -rf HTML .endif .else - rm -f ${DEPENDFILE} tags + rm -f ${DEPENDFILES} tags .endif .endif .endif diff --git a/share/mk/bsd.lib.mk b/share/mk/bsd.lib.mk index e906ab7e83a6..579e36cd9240 100644 --- a/share/mk/bsd.lib.mk +++ b/share/mk/bsd.lib.mk @@ -305,10 +305,12 @@ all: _manpages .endif _EXTRADEPEND: +.if ${MK_FAST_DEPEND} == "no" @TMP=_depend$$$$; \ sed -e 's/^\([^\.]*\).o[ ]*:/\1.o \1.po \1.So:/' < ${DEPENDFILE} \ > $$TMP; \ mv $$TMP ${DEPENDFILE} +.endif .if !defined(NO_EXTRADEPEND) && defined(SHLIB_NAME) .if defined(DPADD) && !empty(DPADD) echo ${SHLIB_NAME_FULL}: ${DPADD} >> ${DEPENDFILE} diff --git a/share/mk/bsd.opts.mk b/share/mk/bsd.opts.mk index 88f5196db89f..a1f4ccec2aab 100644 --- a/share/mk/bsd.opts.mk +++ b/share/mk/bsd.opts.mk @@ -66,6 +66,7 @@ __DEFAULT_YES_OPTIONS = \ WARNS __DEFAULT_NO_OPTIONS = \ + FAST_DEPEND \ CTF \ DEBUG_FILES \ INSTALL_AS_USER \ diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk index 2f20da8620be..cf3bee6b2f00 100644 --- a/share/mk/bsd.own.mk +++ b/share/mk/bsd.own.mk @@ -1,6 +1,6 @@ # $FreeBSD$ # -# The include file set common variables for owner, +# The include file set common variables for owner, # group, mode, and directories. Defaults are in brackets. # # diff --git a/share/mk/bsd.prog.mk b/share/mk/bsd.prog.mk index fbb6922f7f61..37ede4c94c6f 100644 --- a/share/mk/bsd.prog.mk +++ b/share/mk/bsd.prog.mk @@ -82,9 +82,9 @@ ${PROG_FULL}: beforelinking .endif ${PROG_FULL}: ${OBJS} .if defined(PROG_CXX) - ${CXX} ${CXXFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD} + ${CXX} ${CXXFLAGS:N-M*} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD} .else - ${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD} + ${CC} ${CFLAGS:N-M*} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD} .endif .if ${MK_CTF} != "no" ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS} @@ -112,9 +112,9 @@ ${PROG_FULL}: beforelinking .endif ${PROG_FULL}: ${OBJS} .if defined(PROG_CXX) - ${CXX} ${CXXFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD} + ${CXX} ${CXXFLAGS:N-M*} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD} .else - ${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD} + ${CC} ${CFLAGS:N-M*} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD} .endif .if ${MK_CTF} != "no" ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS} diff --git a/share/mk/local.init.mk b/share/mk/local.init.mk index 85303c381bae..a30ed0e7085a 100644 --- a/share/mk/local.init.mk +++ b/share/mk/local.init.mk @@ -38,3 +38,5 @@ CPP= ${HOST_CPP} HOST_CFLAGS+= -DHOSTPROG CFLAGS+= ${HOST_CFLAGS} .endif + +.-include "src.init.mk" diff --git a/share/mk/src.init.mk b/share/mk/src.init.mk new file mode 100644 index 000000000000..2067dcdbbabc --- /dev/null +++ b/share/mk/src.init.mk @@ -0,0 +1,11 @@ +# $FreeBSD$ + +.if !target(____) +____: + +.if !target(buildenv) +buildenv: .PHONY + ${_+_}@env BUILDENV_DIR=${.CURDIR} ${MAKE} -C ${SRCTOP} buildenv +.endif + +.endif # !target(____) diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk index 61f9d79ad4f7..d78d6e21db3f 100644 --- a/share/mk/src.libnames.mk +++ b/share/mk/src.libnames.mk @@ -39,7 +39,7 @@ _INTERNALLIBS= \ netbsd \ ntp \ ntpevent \ - ohash \ + openbsd \ opts \ parse \ readline \ @@ -314,8 +314,8 @@ LIBELFTC?= ${LIBELFTCDIR}/libelftc.a LIBREADLINEDIR= ${ROOTOBJDIR}/gnu/lib/libreadline/readline LIBREADLINE?= ${LIBREADLINEDIR}/libreadline.a -LIBOHASHDIR= ${ROOTOBJDIR}/lib/libohash -LIBOHASH?= ${LIBOHASHDIR}/libohash.a +LIBOPENBSDDIR= ${ROOTOBJDIR}/lib/libopenbsd +LIBOPENBSD?= ${LIBOPENBSDDIR}/libopenbsd.a LIBSMDIR= ${ROOTOBJDIR}/lib/libsm LIBSM?= ${LIBSMDIR}/libsm.a diff --git a/sys/arm/arm/busdma_machdep-v6.c b/sys/arm/arm/busdma_machdep-v6.c index d62522e62c69..a75574072548 100644 --- a/sys/arm/arm/busdma_machdep-v6.c +++ b/sys/arm/arm/busdma_machdep-v6.c @@ -473,11 +473,6 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, bus_dma_tag_t newtag; int error = 0; -#if 0 - if (!parent) - parent = arm_root_dma_tag; -#endif - /* Basic sanity checking. */ KASSERT(boundary == 0 || powerof2(boundary), ("dma tag boundary %lu, must be a power of 2", boundary)); diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c index d2f517a8d71d..f7e0e261a097 100644 --- a/sys/arm/arm/busdma_machdep.c +++ b/sys/arm/arm/busdma_machdep.c @@ -224,9 +224,6 @@ static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage); static void bus_dmamap_sync_sl(struct sync_list *sl, bus_dmasync_op_t op, int bufaligned); -/* Default tag, as most drivers provide no parent tag. */ -bus_dma_tag_t arm_root_dma_tag; - /* * ---------------------------------------------------------------------------- * Begin block of code useful to transplant to other implementations. @@ -406,8 +403,6 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, int error = 0; /* Return a NULL tag on failure */ *dmat = NULL; - if (!parent) - parent = arm_root_dma_tag; newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_BUSDMA, M_NOWAIT); if (newtag == NULL) { diff --git a/sys/arm/arm/db_interface.c b/sys/arm/arm/db_interface.c index 3a2515e7ad49..25d1706c8ff1 100644 --- a/sys/arm/arm/db_interface.c +++ b/sys/arm/arm/db_interface.c @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -291,94 +292,35 @@ db_fetch_reg(int reg) } } +static u_int +db_branch_taken_read_int(void *cookie __unused, vm_offset_t offset, u_int *val) +{ + u_int ret; + + db_read_bytes(offset, 4, (char *)&ret); + *val = ret; + + return (0); +} + +static u_int +db_branch_taken_fetch_reg(void *cookie __unused, int reg) +{ + + return (db_fetch_reg(reg)); +} + u_int branch_taken(u_int insn, db_addr_t pc) { - u_int addr, nregs, offset = 0; + register_t new_pc; + int ret; - switch ((insn >> 24) & 0xf) { - case 0x2: /* add pc, reg1, #value */ - case 0x0: /* add pc, reg1, reg2, lsl #offset */ - addr = db_fetch_reg((insn >> 16) & 0xf); - if (((insn >> 16) & 0xf) == 15) - addr += 8; - if (insn & 0x0200000) { - offset = (insn >> 7) & 0x1e; - offset = (insn & 0xff) << (32 - offset) | - (insn & 0xff) >> offset; - } else { + ret = arm_predict_branch(NULL, insn, (register_t)pc, &new_pc, + db_branch_taken_fetch_reg, db_branch_taken_read_int); - offset = db_fetch_reg(insn & 0x0f); - if ((insn & 0x0000ff0) != 0x00000000) { - if (insn & 0x10) - nregs = db_fetch_reg((insn >> 8) & 0xf); - else - nregs = (insn >> 7) & 0x1f; - switch ((insn >> 5) & 3) { - case 0: - /* lsl */ - offset = offset << nregs; - break; - case 1: - /* lsr */ - offset = offset >> nregs; - break; - default: - break; /* XXX */ - } - } - return (addr + offset); - } - case 0xa: /* b ... */ - case 0xb: /* bl ... */ - addr = ((insn << 2) & 0x03ffffff); - if (addr & 0x02000000) - addr |= 0xfc000000; - return (pc + 8 + addr); - case 0x7: /* ldr pc, [pc, reg, lsl #2] */ - addr = db_fetch_reg(insn & 0xf); - addr = pc + 8 + (addr << 2); - db_read_bytes(addr, 4, (char *)&addr); - return (addr); - case 0x1: /* mov pc, reg */ - addr = db_fetch_reg(insn & 0xf); - return (addr); - case 0x4: - case 0x5: /* ldr pc, [reg] */ - addr = db_fetch_reg((insn >> 16) & 0xf); - /* ldr pc, [reg, #offset] */ - if (insn & (1 << 24)) - offset = insn & 0xfff; - if (insn & 0x00800000) - addr += offset; - else - addr -= offset; - db_read_bytes(addr, 4, (char *)&addr); - return (addr); - case 0x8: /* ldmxx reg, {..., pc} */ - case 0x9: - addr = db_fetch_reg((insn >> 16) & 0xf); - nregs = (insn & 0x5555) + ((insn >> 1) & 0x5555); - nregs = (nregs & 0x3333) + ((nregs >> 2) & 0x3333); - nregs = (nregs + (nregs >> 4)) & 0x0f0f; - nregs = (nregs + (nregs >> 8)) & 0x001f; - switch ((insn >> 23) & 0x3) { - case 0x0: /* ldmda */ - addr = addr - 0; - break; - case 0x1: /* ldmia */ - addr = addr + 0 + ((nregs - 1) << 2); - break; - case 0x2: /* ldmdb */ - addr = addr - 4; - break; - case 0x3: /* ldmib */ - addr = addr + 4 + ((nregs - 1) << 2); - break; - } - db_read_bytes(addr, 4, (char *)&addr); - return (addr); - default: - panic("branch_taken: botch"); - } + if (ret != 0) + kdb_reenter(); + + return (new_pc); } diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index 1c422f3b7d8c..bd01383ed946 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -95,6 +95,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -627,11 +628,81 @@ ptrace_write_int(struct thread *td, vm_offset_t addr, u_int32_t v) return proc_rwmem(td->td_proc, &uio); } +static u_int +ptrace_get_usr_reg(void *cookie, int reg) +{ + int ret; + struct thread *td = cookie; + + KASSERT(((reg >= 0) && (reg <= ARM_REG_NUM_PC)), + ("reg is outside range")); + + switch(reg) { + case ARM_REG_NUM_PC: + ret = td->td_frame->tf_pc; + break; + case ARM_REG_NUM_LR: + ret = td->td_frame->tf_usr_lr; + break; + case ARM_REG_NUM_SP: + ret = td->td_frame->tf_usr_sp; + break; + default: + ret = *((register_t*)&td->td_frame->tf_r0 + reg); + break; + } + + return (ret); +} + +static u_int +ptrace_get_usr_int(void* cookie, vm_offset_t offset, u_int* val) +{ + struct thread *td = cookie; + u_int error; + + error = ptrace_read_int(td, offset, val); + + return (error); +} + +/** + * This function parses current instruction opcode and decodes + * any possible jump (change in PC) which might occur after + * the instruction is executed. + * + * @param td Thread structure of analysed task + * @param cur_instr Currently executed instruction + * @param alt_next_address Pointer to the variable where + * the destination address of the + * jump instruction shall be stored. + * + * @return <0> when jump is possible + * otherwise + */ +static int +ptrace_get_alternative_next(struct thread *td, uint32_t cur_instr, + uint32_t *alt_next_address) +{ + int error; + + if (inst_branch(cur_instr) || inst_call(cur_instr) || + inst_return(cur_instr)) { + error = arm_predict_branch(td, cur_instr, td->td_frame->tf_pc, + alt_next_address, ptrace_get_usr_reg, ptrace_get_usr_int); + + return (error); + } + + return (EINVAL); +} + int ptrace_single_step(struct thread *td) { struct proc *p; - int error; + int error, error_alt; + uint32_t cur_instr, alt_next = 0; /* TODO: This needs to be updated for Thumb-2 */ if ((td->td_frame->tf_spsr & PSR_T) != 0) @@ -639,20 +710,48 @@ ptrace_single_step(struct thread *td) KASSERT(td->td_md.md_ptrace_instr == 0, ("Didn't clear single step")); + KASSERT(td->td_md.md_ptrace_instr_alt == 0, + ("Didn't clear alternative single step")); p = td->td_proc; PROC_UNLOCK(p); - error = ptrace_read_int(td, td->td_frame->tf_pc + 4, - &td->td_md.md_ptrace_instr); + + error = ptrace_read_int(td, td->td_frame->tf_pc, + &cur_instr); if (error) goto out; - error = ptrace_write_int(td, td->td_frame->tf_pc + 4, - PTRACE_BREAKPOINT); - if (error) - td->td_md.md_ptrace_instr = 0; - td->td_md.md_ptrace_addr = td->td_frame->tf_pc + 4; + + error = ptrace_read_int(td, td->td_frame->tf_pc + INSN_SIZE, + &td->td_md.md_ptrace_instr); + if (error == 0) { + error = ptrace_write_int(td, td->td_frame->tf_pc + INSN_SIZE, + PTRACE_BREAKPOINT); + if (error) { + td->td_md.md_ptrace_instr = 0; + } else { + td->td_md.md_ptrace_addr = td->td_frame->tf_pc + + INSN_SIZE; + } + } + + error_alt = ptrace_get_alternative_next(td, cur_instr, &alt_next); + if (error_alt == 0) { + error_alt = ptrace_read_int(td, alt_next, + &td->td_md.md_ptrace_instr_alt); + if (error_alt) { + td->td_md.md_ptrace_instr_alt = 0; + } else { + error_alt = ptrace_write_int(td, alt_next, + PTRACE_BREAKPOINT); + if (error_alt) + td->td_md.md_ptrace_instr_alt = 0; + else + td->td_md.md_ptrace_addr_alt = alt_next; + } + } + out: PROC_LOCK(p); - return (error); + return ((error != 0) && (error_alt != 0)); } int @@ -664,7 +763,7 @@ ptrace_clear_single_step(struct thread *td) if ((td->td_frame->tf_spsr & PSR_T) != 0) return (EINVAL); - if (td->td_md.md_ptrace_instr) { + if (td->td_md.md_ptrace_instr != 0) { p = td->td_proc; PROC_UNLOCK(p); ptrace_write_int(td, td->td_md.md_ptrace_addr, @@ -672,6 +771,16 @@ ptrace_clear_single_step(struct thread *td) PROC_LOCK(p); td->td_md.md_ptrace_instr = 0; } + + if (td->td_md.md_ptrace_instr_alt != 0) { + p = td->td_proc; + PROC_UNLOCK(p); + ptrace_write_int(td, td->td_md.md_ptrace_addr_alt, + td->td_md.md_ptrace_instr_alt); + PROC_LOCK(p); + td->td_md.md_ptrace_instr_alt = 0; + } + return (0); } @@ -1074,6 +1183,111 @@ init_proc0(vm_offset_t kstack) pcpup->pc_curpcb = thread0.td_pcb; } +int +arm_predict_branch(void *cookie, u_int insn, register_t pc, register_t *new_pc, + u_int (*fetch_reg)(void*, int), u_int (*read_int)(void*, vm_offset_t, u_int*)) +{ + u_int addr, nregs, offset = 0; + int error = 0; + + switch ((insn >> 24) & 0xf) { + case 0x2: /* add pc, reg1, #value */ + case 0x0: /* add pc, reg1, reg2, lsl #offset */ + addr = fetch_reg(cookie, (insn >> 16) & 0xf); + if (((insn >> 16) & 0xf) == 15) + addr += 8; + if (insn & 0x0200000) { + offset = (insn >> 7) & 0x1e; + offset = (insn & 0xff) << (32 - offset) | + (insn & 0xff) >> offset; + } else { + + offset = fetch_reg(cookie, insn & 0x0f); + if ((insn & 0x0000ff0) != 0x00000000) { + if (insn & 0x10) + nregs = fetch_reg(cookie, + (insn >> 8) & 0xf); + else + nregs = (insn >> 7) & 0x1f; + switch ((insn >> 5) & 3) { + case 0: + /* lsl */ + offset = offset << nregs; + break; + case 1: + /* lsr */ + offset = offset >> nregs; + break; + default: + break; /* XXX */ + } + + } + *new_pc = addr + offset; + return (0); + + } + + case 0xa: /* b ... */ + case 0xb: /* bl ... */ + addr = ((insn << 2) & 0x03ffffff); + if (addr & 0x02000000) + addr |= 0xfc000000; + *new_pc = (pc + 8 + addr); + return (0); + case 0x7: /* ldr pc, [pc, reg, lsl #2] */ + addr = fetch_reg(cookie, insn & 0xf); + addr = pc + 8 + (addr << 2); + error = read_int(cookie, addr, &addr); + *new_pc = addr; + return (error); + case 0x1: /* mov pc, reg */ + *new_pc = fetch_reg(cookie, insn & 0xf); + return (0); + case 0x4: + case 0x5: /* ldr pc, [reg] */ + addr = fetch_reg(cookie, (insn >> 16) & 0xf); + /* ldr pc, [reg, #offset] */ + if (insn & (1 << 24)) + offset = insn & 0xfff; + if (insn & 0x00800000) + addr += offset; + else + addr -= offset; + error = read_int(cookie, addr, &addr); + *new_pc = addr; + + return (error); + case 0x8: /* ldmxx reg, {..., pc} */ + case 0x9: + addr = fetch_reg(cookie, (insn >> 16) & 0xf); + nregs = (insn & 0x5555) + ((insn >> 1) & 0x5555); + nregs = (nregs & 0x3333) + ((nregs >> 2) & 0x3333); + nregs = (nregs + (nregs >> 4)) & 0x0f0f; + nregs = (nregs + (nregs >> 8)) & 0x001f; + switch ((insn >> 23) & 0x3) { + case 0x0: /* ldmda */ + addr = addr - 0; + break; + case 0x1: /* ldmia */ + addr = addr + 0 + ((nregs - 1) << 2); + break; + case 0x2: /* ldmdb */ + addr = addr - 4; + break; + case 0x3: /* ldmib */ + addr = addr + 4 + ((nregs - 1) << 2); + break; + } + error = read_int(cookie, addr, &addr); + *new_pc = addr; + + return (error); + default: + return (EINVAL); + } +} + #ifdef ARM_NEW_PMAP void set_stackptrs(int cpu) diff --git a/sys/arm/arm/trap-v6.c b/sys/arm/arm/trap-v6.c index b7b6629859d5..6dd38eb2e477 100644 --- a/sys/arm/arm/trap-v6.c +++ b/sys/arm/arm/trap-v6.c @@ -98,18 +98,18 @@ struct abort { * - Always fatal as we do not know what does it mean. * Imprecise External Abort: * - Always fatal, but can be handled somehow in the future. - * Now, due to PCIe buggy harware, ignored. + * Now, due to PCIe buggy hardware, ignored. * Precise External Abort: * - Always fatal, but who knows in the future??? * Debug Event: * - Special handling. * External Translation Abort (L1 & L2) - * - Always fatal as something is screwed up in page tables or harware. + * - Always fatal as something is screwed up in page tables or hardware. * Domain Fault (L1 & L2): * - Always fatal as we do not play game with domains. * Alignment Fault: - * - Everything should be aligned in kernel including user to kernel and - * vice versa data copying, so we ignore pcb_onfault, and it's always fatal. + * - Everything should be aligned in kernel with exception of user to kernel + * and vice versa data copying, so if pcb_onfault is not set, it's fatal. * We generate signal in case of abort from user mode. * Instruction cache maintenance: * - According to manual, this is translation fault during cache maintenance @@ -125,7 +125,7 @@ struct abort { * Translation Fault (L1 & L2): * - Standard fault mechanism is held including vm_fault(). * Permission Fault (L1 & L2): - * - Fast harware emulation of modify bits and in other cases, standard + * - Fast hardware emulation of modify bits and in other cases, standard * fault mechanism is held including vm_fault(). */ @@ -167,7 +167,6 @@ static const struct abort aborts[] = { {abort_fatal, "Undefined Code (0x40F)"} }; - static __inline void call_trapsignal(struct thread *td, int sig, int code, vm_offset_t addr) { @@ -195,7 +194,7 @@ call_trapsignal(struct thread *td, int sig, int code, vm_offset_t addr) * * The imprecise means that we don't know where the abort happened, * thus FAR is undefined. The abort should not never fire, but hot - * plugging or accidental harware failure can be the cause of it. + * plugging or accidental hardware failure can be the cause of it. * If the abort happens, it can even be on different (thread) context. * Without any additional support, the abort is fatal, as we do not * know what really happened. @@ -214,7 +213,9 @@ call_trapsignal(struct thread *td, int sig, int code, vm_offset_t addr) static __inline void abort_imprecise(struct trapframe *tf, u_int fsr, u_int prefetch, u_int usermode) { - /* XXXX We can got imprecise abort as result of access + + /* + * XXX - We can got imprecise abort as result of access * to not-present PCI/PCIe configuration space. */ #if 0 @@ -245,6 +246,7 @@ static __inline void abort_debug(struct trapframe *tf, u_int fsr, u_int prefetch, u_int usermode, u_int far) { + if (usermode) { struct thread *td; @@ -316,6 +318,18 @@ abort_handler(struct trapframe *tf, int prefetch) return; } + /* + * ARM has a set of unprivileged load and store instructions + * (LDRT/LDRBT/STRT/STRBT ...) which are supposed to be used in other + * than user mode and OS should recognize their aborts and behave + * appropriately. However, there is no way how to do that reasonably + * in general unless we restrict the handling somehow. + * + * For now, these instructions are used only in copyin()/copyout() + * like functions where usermode buffers are checked in advance that + * they are not from KVA space. Thus, no action is needed here. + */ + #ifdef ARM_NEW_PMAP rv = pmap_fault(PCPU_GET(curpmap), far, fsr, idx, usermode); if (rv == 0) { @@ -330,7 +344,6 @@ abort_handler(struct trapframe *tf, int prefetch) /* * Now, when we handled imprecise and debug aborts, the rest of * aborts should be really related to mapping. - * */ PCPU_INC(cnt.v_trap); @@ -417,7 +430,7 @@ abort_handler(struct trapframe *tf, int prefetch) return; } - /* Handle remaining I cache aborts. */ + /* Handle remaining I-cache aborts. */ if (idx == FAULT_ICACHE) { if (abort_icache(tf, idx, fsr, far, prefetch, td, &ksig)) goto do_trapsignal; @@ -434,7 +447,7 @@ abort_handler(struct trapframe *tf, int prefetch) * the MMU. */ - /* fusubailout is used by [fs]uswintr to avoid page faulting */ + /* fusubailout is used by [fs]uswintr to avoid page faulting. */ pcb = td->td_pcb; if (__predict_false(pcb->pcb_onfault == fusubailout)) { tf->tf_r0 = EFAULT; @@ -442,19 +455,6 @@ abort_handler(struct trapframe *tf, int prefetch) return; } - /* - * QQQ: ARM has a set of unprivileged load and store instructions - * (LDRT/LDRBT/STRT/STRBT ...) which are supposed to be used - * in other than user mode and OS should recognize their - * aborts and behaved appropriately. However, there is no way - * how to do that reasonably in general unless we restrict - * the handling somehow. One way is to limit the handling for - * aborts which come from undefined mode only. - * - * Anyhow, we do not use these instructions and do not implement - * any special handling for them. - */ - va = trunc_page(far); if (va >= KERNBASE) { /* @@ -536,7 +536,7 @@ abort_handler(struct trapframe *tf, int prefetch) /* * abort_fatal() handles the following data aborts: - + * * FAULT_DEBUG - Debug Event * FAULT_ACCESS_xx - Acces Bit * FAULT_EA_PREC - Precise External Abort @@ -553,8 +553,8 @@ abort_handler(struct trapframe *tf, int prefetch) * Note: If 'l' is NULL, we assume we're dealing with a prefetch abort. */ static int -abort_fatal(struct trapframe *tf, u_int idx, u_int fsr, u_int far, u_int prefetch, - struct thread *td, struct ksig *ksig) +abort_fatal(struct trapframe *tf, u_int idx, u_int fsr, u_int far, + u_int prefetch, struct thread *td, struct ksig *ksig) { u_int usermode; const char *mode; @@ -609,37 +609,28 @@ abort_fatal(struct trapframe *tf, u_int idx, u_int fsr, u_int far, u_int prefetc * * FAULT_ALIGN - Alignment fault * - * Every memory access should be correctly aligned in kernel including - * user to kernel and vice versa data copying, so we ignore pcb_onfault, - * and it's always fatal. We generate a signal in case of abort from user mode. + * Everything should be aligned in kernel with exception of user to kernel + * and vice versa data copying, so if pcb_onfault is not set, it's fatal. + * We generate signal in case of abort from user mode. */ static int -abort_align(struct trapframe *tf, u_int idx, u_int fsr, u_int far, u_int prefetch, - struct thread *td, struct ksig *ksig) +abort_align(struct trapframe *tf, u_int idx, u_int fsr, u_int far, + u_int prefetch, struct thread *td, struct ksig *ksig) { u_int usermode; usermode = TRAPF_USERMODE(tf); - - /* - * Alignment faults are always fatal if they occur in any but user mode. - * - * XXX The old trap code handles pcb fault even for alignment traps. - * Unfortunately, we don't known why and if is this need. - */ if (!usermode) { if (td->td_intr_nesting_level == 0 && td != NULL && td->td_pcb->pcb_onfault != NULL) { - printf("%s: Got alignment fault with pcb_onfault set" - ", please report this issue\n", __func__); - tf->tf_r0 = EFAULT;; + tf->tf_r0 = EFAULT; tf->tf_pc = (int)td->td_pcb->pcb_onfault; return (0); } abort_fatal(tf, idx, fsr, far, prefetch, td, ksig); } /* Deliver a bus error signal to the process */ - ksig->code = 0; + ksig->code = BUS_ADRALN; ksig->sig = SIGBUS; ksig->addr = far; return (1); @@ -660,9 +651,10 @@ abort_align(struct trapframe *tf, u_int idx, u_int fsr, u_int far, u_int prefetc * should be held here including vm_fault() calling. */ static int -abort_icache(struct trapframe *tf, u_int idx, u_int fsr, u_int far, u_int prefetch, - struct thread *td, struct ksig *ksig) +abort_icache(struct trapframe *tf, u_int idx, u_int fsr, u_int far, + u_int prefetch, struct thread *td, struct ksig *ksig) { + abort_fatal(tf, idx, fsr, far, prefetch, td, ksig); return(0); } diff --git a/sys/arm/at91/at91_pmc.c b/sys/arm/at91/at91_pmc.c index 13d5ff7f7479..16f62ec14331 100644 --- a/sys/arm/at91/at91_pmc.c +++ b/sys/arm/at91/at91_pmc.c @@ -661,7 +661,10 @@ static int at91_pmc_probe(device_t dev) { #ifdef FDT - if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-pmc")) + if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-pmc") && + !ofw_bus_is_compatible(dev, "atmel,at91sam9260-pmc") && + !ofw_bus_is_compatible(dev, "atmel,at91sam9g45-pmc") && + !ofw_bus_is_compatible(dev, "atmel,at91sam9x5-pmc")) return (ENXIO); #endif device_set_desc(dev, "PMC"); diff --git a/sys/arm/at91/if_macb.c b/sys/arm/at91/if_macb.c index a7acc31d4399..6ad167ccb680 100644 --- a/sys/arm/at91/if_macb.c +++ b/sys/arm/at91/if_macb.c @@ -24,6 +24,8 @@ * SUCH DAMAGE. */ +#include "opt_platform.h" + #include __FBSDID("$FreeBSD$"); @@ -72,6 +74,12 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef FDT +#include +#include +#include +#endif + /* "device miibus" required. See GENERIC if you get errors here. */ #include "miibus_if.h" @@ -1196,6 +1204,11 @@ macbioctl(struct ifnet * ifp, u_long cmd, caddr_t data) static int macb_probe(device_t dev) { +#ifdef FDT + if (!ofw_bus_is_compatible(dev, "cdns,at32ap7000-macb")) + return (ENXIO); +#endif + device_set_desc(dev, "macb"); return (0); } @@ -1546,7 +1559,11 @@ static driver_t macb_driver = { }; +#ifdef FDT +DRIVER_MODULE(macb, simplebus, macb_driver, macb_devclass, NULL, NULL); +#else DRIVER_MODULE(macb, atmelarm, macb_driver, macb_devclass, 0, 0); +#endif DRIVER_MODULE(miibus, macb, miibus_driver, miibus_devclass, 0, 0); MODULE_DEPEND(macb, miibus, 1, 1, 1); MODULE_DEPEND(macb, ether, 1, 1, 1); diff --git a/sys/arm/broadcom/bcm2835/bcm2835_fbd.c b/sys/arm/broadcom/bcm2835/bcm2835_fbd.c index 34a7af8a07b6..b47c60245e00 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_fbd.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_fbd.c @@ -81,7 +81,7 @@ bcm_fb_attach(device_t dev) { char bootargs[2048], *n, *p, *v; device_t fbd; - int fbswap; + int fbswap, err; phandle_t chosen; struct bcm2835_fb_config fb; struct bcmsc_softc *sc; @@ -89,11 +89,13 @@ bcm_fb_attach(device_t dev) sc = device_get_softc(dev); memset(&fb, 0, sizeof(fb)); - if (bcm2835_mbox_fb_get_w_h(dev, &fb) != 0) + if (bcm2835_mbox_fb_get_w_h(&fb) != 0) return (ENXIO); fb.bpp = FB_DEPTH; - if (bcm2835_mbox_fb_init(dev, &fb) != 0) + if ((err = bcm2835_mbox_fb_init(&fb)) != 0) { + device_printf(dev, "bcm2835_mbox_fb_init failed, err=%d\n", err); return (ENXIO); + } info = malloc(sizeof(struct fb_info), M_DEVBUF, M_WAITOK | M_ZERO); info->fb_name = device_get_nameunit(dev); diff --git a/sys/arm/broadcom/bcm2835/bcm2835_intr.c b/sys/arm/broadcom/bcm2835/bcm2835_intr.c index 45c2e97844d6..d8574e6c3a1c 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_intr.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_intr.c @@ -163,7 +163,9 @@ arm_get_next_irq(int last_irq) irq = 0; #ifdef SOC_BCM2836 - if ((ret = bcm2836_get_next_irq(irq)) >= 0) + if ((ret = bcm2836_get_next_irq(irq)) < 0) + return (-1); + if (ret != BCM2836_GPU_IRQ) return (ret + BANK3_START); #endif diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c index 78384ebc9236..dd2bb45a9680 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c @@ -360,230 +360,162 @@ bcm2835_mbox_err(device_t dev, bus_addr_t msg_phys, uint32_t resp_phys, } int -bcm2835_mbox_set_power_state(device_t dev, uint32_t device_id, boolean_t on) +bcm2835_mbox_property(void *msg, size_t msg_size) { - struct msg_set_power_state *msg; + struct msg_set_power_state *buf; bus_dma_tag_t msg_tag; bus_dmamap_t msg_map; bus_addr_t msg_phys; uint32_t reg; device_t mbox; + int err; /* get mbox device */ mbox = devclass_get_device(devclass_find("mbox"), 0); - if (mbox == NULL) { - device_printf(dev, "can't find mbox\n"); + if (mbox == NULL) return (ENXIO); - } /* Allocate memory for the message */ - msg = bcm2835_mbox_init_dma(dev, sizeof(*msg), &msg_tag, &msg_map, + buf = bcm2835_mbox_init_dma(mbox, msg_size, &msg_tag, &msg_map, &msg_phys); - if (msg == NULL) + if (buf == NULL) return (ENOMEM); - memset(msg, 0, sizeof(*msg)); - msg->hdr.buf_size = sizeof(*msg); - msg->hdr.code = BCM2835_MBOX_CODE_REQ; - msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_POWER_STATE; - msg->tag_hdr.val_buf_size = sizeof(msg->body); - msg->tag_hdr.val_len = sizeof(msg->body.req); - msg->body.req.device_id = device_id; - msg->body.req.state = (on ? BCM2835_MBOX_POWER_ON : 0) | - BCM2835_MBOX_POWER_WAIT; - msg->end_tag = 0; + memcpy(buf, msg, msg_size); bus_dmamap_sync(msg_tag, msg_map, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + BUS_DMASYNC_PREWRITE); MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)msg_phys); MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, ®); - bus_dmamap_unload(msg_tag, msg_map); - bus_dmamem_free(msg_tag, msg, msg_map); - bus_dma_tag_destroy(msg_tag); + bus_dmamap_sync(msg_tag, msg_map, + BUS_DMASYNC_PREREAD); - return (0); -} + memcpy(msg, buf, msg_size); -int -bcm2835_mbox_get_clock_rate(device_t dev, uint32_t clock_id, uint32_t *hz) -{ - struct msg_get_clock_rate *msg; - bus_dma_tag_t msg_tag; - bus_dmamap_t msg_map; - bus_addr_t msg_phys; - uint32_t reg; - device_t mbox; - - /* get mbox device */ - mbox = devclass_get_device(devclass_find("mbox"), 0); - if (mbox == NULL) { - device_printf(dev, "can't find mbox\n"); - return (ENXIO); - } - - /* Allocate memory for the message */ - msg = bcm2835_mbox_init_dma(dev, sizeof(*msg), &msg_tag, &msg_map, - &msg_phys); - if (msg == NULL) - return (ENOMEM); - - memset(msg, 0, sizeof(*msg)); - msg->hdr.buf_size = sizeof(*msg); - msg->hdr.code = BCM2835_MBOX_CODE_REQ; - msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_CLOCK_RATE; - msg->tag_hdr.val_buf_size = sizeof(msg->body); - msg->tag_hdr.val_len = sizeof(msg->body.req); - msg->body.req.clock_id = clock_id; - msg->end_tag = 0; - - bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREWRITE); - MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)msg_phys); - bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTWRITE); - - bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREREAD); - MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, ®); - bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTREAD); - - *hz = msg->body.resp.rate_hz; + err = bcm2835_mbox_err(mbox, msg_phys, reg, + (struct bcm2835_mbox_hdr *)msg, msg_size); bus_dmamap_unload(msg_tag, msg_map); - bus_dmamem_free(msg_tag, msg, msg_map); - bus_dma_tag_destroy(msg_tag); - - return (0); -} - -int -bcm2835_mbox_fb_get_w_h(device_t dev, struct bcm2835_fb_config *fb) -{ - device_t mbox; - int err; - bus_dma_tag_t msg_tag; - bus_dmamap_t msg_map; - bus_addr_t msg_phys; - struct msg_fb_get_w_h *msg; - uint32_t reg; - - /* get mbox device */ - mbox = devclass_get_device(devclass_find("mbox"), 0); - if (mbox == NULL) { - device_printf(dev, "can't find mbox\n"); - return (ENXIO); - } - - /* Allocate memory for the message */ - msg = bcm2835_mbox_init_dma(dev, sizeof(*msg), &msg_tag, &msg_map, - &msg_phys); - if (msg == NULL) - return (ENOMEM); - - memset(msg, 0, sizeof(*msg)); - msg->hdr.buf_size = sizeof(*msg); - msg->hdr.code = BCM2835_MBOX_CODE_REQ; - BCM2835_MBOX_INIT_TAG(&msg->physical_w_h, GET_PHYSICAL_W_H); - msg->physical_w_h.tag_hdr.val_len = 0; - BCM2835_MBOX_INIT_TAG(&msg->virtual_w_h, GET_VIRTUAL_W_H); - msg->virtual_w_h.tag_hdr.val_len = 0; - BCM2835_MBOX_INIT_TAG(&msg->offset, GET_VIRTUAL_OFFSET); - msg->offset.tag_hdr.val_len = 0; - msg->end_tag = 0; - - bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREWRITE); - MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)msg_phys); - bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTWRITE); - - bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREREAD); - MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, ®); - bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTREAD); - - err = bcm2835_mbox_err(dev, msg_phys, reg, &msg->hdr, sizeof(*msg)); - if (err == 0) { - fb->xres = msg->physical_w_h.body.resp.width; - fb->yres = msg->physical_w_h.body.resp.height; - fb->vxres = msg->virtual_w_h.body.resp.width; - fb->vyres = msg->virtual_w_h.body.resp.height; - fb->xoffset = msg->offset.body.resp.x; - fb->yoffset = msg->offset.body.resp.y; - } - - bus_dmamap_unload(msg_tag, msg_map); - bus_dmamem_free(msg_tag, msg, msg_map); + bus_dmamem_free(msg_tag, buf, msg_map); bus_dma_tag_destroy(msg_tag); return (err); } int -bcm2835_mbox_fb_init(device_t dev, struct bcm2835_fb_config *fb) +bcm2835_mbox_set_power_state(uint32_t device_id, boolean_t on) { - device_t mbox; + struct msg_set_power_state msg; int err; - bus_dma_tag_t msg_tag; - bus_dmamap_t msg_map; - bus_addr_t msg_phys; - struct msg_fb_setup *msg; - uint32_t reg; - /* get mbox device */ - mbox = devclass_get_device(devclass_find("mbox"), 0); - if (mbox == NULL) { - device_printf(dev, "can't find mbox\n"); - return (ENXIO); - } + memset(&msg, 0, sizeof(msg)); + msg.hdr.buf_size = sizeof(msg); + msg.hdr.code = BCM2835_MBOX_CODE_REQ; + msg.tag_hdr.tag = BCM2835_MBOX_TAG_SET_POWER_STATE; + msg.tag_hdr.val_buf_size = sizeof(msg.body); + msg.tag_hdr.val_len = sizeof(msg.body.req); + msg.body.req.device_id = device_id; + msg.body.req.state = (on ? BCM2835_MBOX_POWER_ON : 0) | + BCM2835_MBOX_POWER_WAIT; + msg.end_tag = 0; - /* Allocate memory for the message */ - msg = bcm2835_mbox_init_dma(dev, sizeof(*msg), &msg_tag, &msg_map, - &msg_phys); - if (msg == NULL) - return (ENOMEM); - - memset(msg, 0, sizeof(*msg)); - msg->hdr.buf_size = sizeof(*msg); - msg->hdr.code = BCM2835_MBOX_CODE_REQ; - BCM2835_MBOX_INIT_TAG(&msg->physical_w_h, SET_PHYSICAL_W_H); - msg->physical_w_h.body.req.width = fb->xres; - msg->physical_w_h.body.req.height = fb->yres; - BCM2835_MBOX_INIT_TAG(&msg->virtual_w_h, SET_VIRTUAL_W_H); - msg->virtual_w_h.body.req.width = fb->vxres; - msg->virtual_w_h.body.req.height = fb->vyres; - BCM2835_MBOX_INIT_TAG(&msg->offset, GET_VIRTUAL_OFFSET); - msg->offset.body.req.x = fb->xoffset; - msg->offset.body.req.y = fb->yoffset; - BCM2835_MBOX_INIT_TAG(&msg->depth, SET_DEPTH); - msg->depth.body.req.bpp = fb->bpp; - BCM2835_MBOX_INIT_TAG(&msg->alpha, SET_ALPHA_MODE); - msg->alpha.body.req.alpha = BCM2835_MBOX_ALPHA_MODE_IGNORED; - BCM2835_MBOX_INIT_TAG(&msg->buffer, ALLOCATE_BUFFER); - msg->buffer.body.req.alignment = PAGE_SIZE; - BCM2835_MBOX_INIT_TAG(&msg->pitch, GET_PITCH); - msg->end_tag = 0; - - bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREWRITE); - MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)msg_phys); - bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTWRITE); - - bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREREAD); - MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, ®); - bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTREAD); - - err = bcm2835_mbox_err(dev, msg_phys, reg, &msg->hdr, sizeof(*msg)); - if (err == 0) { - fb->xres = msg->physical_w_h.body.resp.width; - fb->yres = msg->physical_w_h.body.resp.height; - fb->vxres = msg->virtual_w_h.body.resp.width; - fb->vyres = msg->virtual_w_h.body.resp.height; - fb->xoffset = msg->offset.body.resp.x; - fb->yoffset = msg->offset.body.resp.y; - fb->pitch = msg->pitch.body.resp.pitch; - fb->base = VCBUS_TO_PHYS(msg->buffer.body.resp.fb_address); - fb->size = msg->buffer.body.resp.fb_size; - } - - bus_dmamap_unload(msg_tag, msg_map); - bus_dmamem_free(msg_tag, msg, msg_map); - bus_dma_tag_destroy(msg_tag); + err = bcm2835_mbox_property(&msg, sizeof(msg)); + + return (err); +} + +int +bcm2835_mbox_get_clock_rate(uint32_t clock_id, uint32_t *hz) +{ + struct msg_get_clock_rate msg; + int err; + + memset(&msg, 0, sizeof(msg)); + msg.hdr.buf_size = sizeof(msg); + msg.hdr.code = BCM2835_MBOX_CODE_REQ; + msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_CLOCK_RATE; + msg.tag_hdr.val_buf_size = sizeof(msg.body); + msg.tag_hdr.val_len = sizeof(msg.body.req); + msg.body.req.clock_id = clock_id; + msg.end_tag = 0; + + err = bcm2835_mbox_property(&msg, sizeof(msg)); + *hz = msg.body.resp.rate_hz; + + return (err); +} + +int +bcm2835_mbox_fb_get_w_h(struct bcm2835_fb_config *fb) +{ + int err; + struct msg_fb_get_w_h msg; + + memset(&msg, 0, sizeof(msg)); + msg.hdr.buf_size = sizeof(msg); + msg.hdr.code = BCM2835_MBOX_CODE_REQ; + BCM2835_MBOX_INIT_TAG(&msg.physical_w_h, GET_PHYSICAL_W_H); + msg.physical_w_h.tag_hdr.val_len = 0; + BCM2835_MBOX_INIT_TAG(&msg.virtual_w_h, GET_VIRTUAL_W_H); + msg.virtual_w_h.tag_hdr.val_len = 0; + BCM2835_MBOX_INIT_TAG(&msg.offset, GET_VIRTUAL_OFFSET); + msg.offset.tag_hdr.val_len = 0; + msg.end_tag = 0; + + err = bcm2835_mbox_property(&msg, sizeof(msg)); + if (err == 0) { + fb->xres = msg.physical_w_h.body.resp.width; + fb->yres = msg.physical_w_h.body.resp.height; + fb->vxres = msg.virtual_w_h.body.resp.width; + fb->vyres = msg.virtual_w_h.body.resp.height; + fb->xoffset = msg.offset.body.resp.x; + fb->yoffset = msg.offset.body.resp.y; + } + + return (err); +} + +int +bcm2835_mbox_fb_init(struct bcm2835_fb_config *fb) +{ + int err; + struct msg_fb_setup msg; + + memset(&msg, 0, sizeof(msg)); + msg.hdr.buf_size = sizeof(msg); + msg.hdr.code = BCM2835_MBOX_CODE_REQ; + BCM2835_MBOX_INIT_TAG(&msg.physical_w_h, SET_PHYSICAL_W_H); + msg.physical_w_h.body.req.width = fb->xres; + msg.physical_w_h.body.req.height = fb->yres; + BCM2835_MBOX_INIT_TAG(&msg.virtual_w_h, SET_VIRTUAL_W_H); + msg.virtual_w_h.body.req.width = fb->vxres; + msg.virtual_w_h.body.req.height = fb->vyres; + BCM2835_MBOX_INIT_TAG(&msg.offset, GET_VIRTUAL_OFFSET); + msg.offset.body.req.x = fb->xoffset; + msg.offset.body.req.y = fb->yoffset; + BCM2835_MBOX_INIT_TAG(&msg.depth, SET_DEPTH); + msg.depth.body.req.bpp = fb->bpp; + BCM2835_MBOX_INIT_TAG(&msg.alpha, SET_ALPHA_MODE); + msg.alpha.body.req.alpha = BCM2835_MBOX_ALPHA_MODE_IGNORED; + BCM2835_MBOX_INIT_TAG(&msg.buffer, ALLOCATE_BUFFER); + msg.buffer.body.req.alignment = PAGE_SIZE; + BCM2835_MBOX_INIT_TAG(&msg.pitch, GET_PITCH); + msg.end_tag = 0; + + err = bcm2835_mbox_property(&msg, sizeof(msg)); + if (err == 0) { + fb->xres = msg.physical_w_h.body.resp.width; + fb->yres = msg.physical_w_h.body.resp.height; + fb->vxres = msg.virtual_w_h.body.resp.width; + fb->vyres = msg.virtual_w_h.body.resp.height; + fb->xoffset = msg.offset.body.resp.x; + fb->yoffset = msg.offset.body.resp.y; + fb->pitch = msg.pitch.body.resp.pitch; + fb->base = VCBUS_TO_PHYS(msg.buffer.body.resp.fb_address); + fb->size = msg.buffer.body.resp.fb_size; + } return (err); } diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h b/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h index a425f2a024ce..68befef2aae1 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h +++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h @@ -106,7 +106,7 @@ struct msg_set_power_state { }; /* Sets the power state for a given device */ -int bcm2835_mbox_set_power_state(device_t, uint32_t, boolean_t); +int bcm2835_mbox_set_power_state(uint32_t, boolean_t); #define BCM2835_MBOX_CLOCK_ID_EMMC 0x00000001 #define BCM2835_MBOX_CLOCK_ID_UART 0x00000002 @@ -185,7 +185,7 @@ struct msg_get_min_clock_rate { uint32_t end_tag; }; -int bcm2835_mbox_get_clock_rate(device_t, uint32_t, uint32_t *); +int bcm2835_mbox_get_clock_rate(uint32_t, uint32_t *); #define BCM2835_MBOX_TURBO_ON 1 #define BCM2835_MBOX_TURBO_OFF 0 @@ -438,6 +438,21 @@ struct bcm2835_mbox_tag_release_buffer { } body; }; +#define BCM2835_MBOX_TAG_GET_TOUCHBUF 0x0004000f + +struct bcm2835_mbox_tag_touchbuf { + struct bcm2835_mbox_hdr hdr; + struct bcm2835_mbox_tag_hdr tag_hdr; + union { + struct { + } req; + struct { + uint32_t address; + } resp; + } body; + uint32_t end_tag; +}; + struct bcm2835_fb_config { uint32_t xres; uint32_t yres; @@ -459,7 +474,7 @@ struct msg_fb_get_w_h { uint32_t end_tag; }; -int bcm2835_mbox_fb_get_w_h(device_t, struct bcm2835_fb_config *); +int bcm2835_mbox_fb_get_w_h(struct bcm2835_fb_config *); struct msg_fb_setup { struct bcm2835_mbox_hdr hdr; @@ -473,6 +488,8 @@ struct msg_fb_setup { uint32_t end_tag; }; -int bcm2835_mbox_fb_init(device_t, struct bcm2835_fb_config *); +int bcm2835_mbox_fb_init(struct bcm2835_fb_config *); + +int bcm2835_mbox_property(void *, size_t); #endif /* _BCM2835_MBOX_PROP_H_ */ diff --git a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c index 33204badd0bf..ace3d74ca224 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c @@ -145,7 +145,7 @@ bcm_sdhci_attach(device_t dev) sc->sc_dev = dev; sc->sc_req = NULL; - err = bcm2835_mbox_set_power_state(dev, BCM2835_MBOX_POWER_ID_EMMC, + err = bcm2835_mbox_set_power_state(BCM2835_MBOX_POWER_ID_EMMC, TRUE); if (err != 0) { if (bootverbose) @@ -154,7 +154,7 @@ bcm_sdhci_attach(device_t dev) } default_freq = 0; - err = bcm2835_mbox_get_clock_rate(dev, BCM2835_MBOX_CLOCK_ID_EMMC, + err = bcm2835_mbox_get_clock_rate(BCM2835_MBOX_CLOCK_ID_EMMC, &default_freq); if (err == 0) { /* Convert to MHz */ diff --git a/sys/arm/broadcom/bcm2835/bcm2835_vcio.c b/sys/arm/broadcom/bcm2835/bcm2835_vcio.c new file mode 100644 index 000000000000..4c215c6eeebc --- /dev/null +++ b/sys/arm/broadcom/bcm2835/bcm2835_vcio.c @@ -0,0 +1,122 @@ +/*- + * Copyright (c) 2015 Oleksandr Tymoshenko + * + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +MALLOC_DECLARE(M_VCIO); +MALLOC_DEFINE(M_VCIO, "vcio", "VCIO temporary buffers"); + +static struct cdev *sdev; +static d_ioctl_t vcio_ioctl; + +static struct cdevsw vcio_devsw = { + /* version */ .d_version = D_VERSION, + /* ioctl */ .d_ioctl = vcio_ioctl, +}; + +#define VCIO_IOC_MAGIC 100 +#define IOCTL_MBOX_PROPERTY _IOWR(VCIO_IOC_MAGIC, 0, char *) + +int +vcio_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int mode, + struct thread *td) +{ + int error; + void *ptr; + uint32_t size; + uint8_t *property; + + error = 0; + switch(cmd) { + case IOCTL_MBOX_PROPERTY: + memcpy (&ptr, arg, sizeof(ptr)); + error = copyin(ptr, &size, sizeof(size)); + + if (error != 0) + break; + property = malloc(size, M_VCIO, M_WAITOK); + if (property == NULL) { + error = ENOMEM; + break; + } + + error = copyin(ptr, property, size); + if (error) { + free(property, M_VCIO); + break; + } + + error = bcm2835_mbox_property(property, size); + if (error) { + free(property, M_VCIO); + break; + } + + error = copyout(property, ptr, size); + free(property, M_VCIO); + + break; + default: + error = EINVAL; + break; + } + return (error); +} + +static int +vcio_load(module_t mod, int cmd, void *arg) +{ + int err = 0; + + switch (cmd) { + case MOD_LOAD: + sdev = make_dev(&vcio_devsw, 0, UID_ROOT, GID_WHEEL, 0600, "vcio"); + break; + + case MOD_UNLOAD: + destroy_dev(sdev); + break; + + default: + err = EOPNOTSUPP; + break; + } + + return(err); +} + +DEV_MODULE(vcio, vcio_load, NULL); +MODULE_DEPEND(vcio, mbox, 1, 1, 1); diff --git a/sys/arm/broadcom/bcm2835/bcm2836.c b/sys/arm/broadcom/bcm2835/bcm2836.c index 58ad8e4f921d..c6f8cb0954ce 100644 --- a/sys/arm/broadcom/bcm2835/bcm2836.c +++ b/sys/arm/broadcom/bcm2835/bcm2836.c @@ -52,7 +52,7 @@ __FBSDID("$FreeBSD$"); #define ARM_LOCAL_INT_TIMER(n) (0x40 + (n) * 4) #define ARM_LOCAL_INT_MAILBOX(n) (0x50 + (n) * 4) #define ARM_LOCAL_INT_PENDING(n) (0x60 + (n) * 4) -#define INT_PENDING_MASK 0x01f +#define INT_PENDING_MASK 0x011f #define MAILBOX0_IRQ 4 #define MAILBOX0_IRQEN (1 << 0) diff --git a/sys/arm/broadcom/bcm2835/bcm2836.h b/sys/arm/broadcom/bcm2835/bcm2836.h index 217dae153c3b..7acd41be1576 100644 --- a/sys/arm/broadcom/bcm2835/bcm2836.h +++ b/sys/arm/broadcom/bcm2835/bcm2836.h @@ -30,6 +30,8 @@ #ifndef _BCM2815_BCM2836_H #define _BCM2815_BCM2836_H +#define BCM2836_GPU_IRQ 8 + int bcm2836_get_next_irq(int); void bcm2836_mask_irq(uintptr_t); void bcm2836_unmask_irq(uintptr_t); diff --git a/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c b/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c index a553fce77498..75b505c8d82d 100644 --- a/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c +++ b/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c @@ -72,8 +72,12 @@ bcm283x_dwc_otg_probe(device_t dev) static int bcm283x_dwc_otg_attach(device_t dev) { + int err; + + err = bcm2835_mbox_set_power_state(BCM2835_MBOX_POWER_ID_USB_HCD, TRUE); + if (err) + device_printf(dev, "failed to set power state, err=%d\n", err); - bcm2835_mbox_set_power_state(dev, BCM2835_MBOX_POWER_ID_USB_HCD, TRUE); return (dwc_otg_attach(dev)); } diff --git a/sys/arm/broadcom/bcm2835/files.bcm283x b/sys/arm/broadcom/bcm2835/files.bcm283x index f028496250da..7e8c8aaed49a 100644 --- a/sys/arm/broadcom/bcm2835/files.bcm283x +++ b/sys/arm/broadcom/bcm2835/files.bcm283x @@ -12,6 +12,7 @@ arm/broadcom/bcm2835/bcm2835_machdep.c standard arm/broadcom/bcm2835/bcm2835_mbox.c standard arm/broadcom/bcm2835/bcm2835_sdhci.c optional sdhci arm/broadcom/bcm2835/bcm2835_spi.c optional bcm2835_spi +arm/broadcom/bcm2835/bcm2835_vcio.c standard arm/broadcom/bcm2835/bcm2835_wdog.c standard arm/broadcom/bcm2835/bcm283x_dwc_fdt.c optional dwcotg fdt diff --git a/sys/arm/include/armreg.h b/sys/arm/include/armreg.h index a300ddfb9b31..3518d3396aa9 100644 --- a/sys/arm/include/armreg.h +++ b/sys/arm/include/armreg.h @@ -403,7 +403,7 @@ #define FAULT_PERM_L1 0x00D /* Permission Fault (L1) */ #define FAULT_EA_TRAN_L2 0x00E /* External Translation Abort (L2) */ #define FAULT_PERM_L2 0x00F /* Permission Fault (L2) */ -#define FAULT_TLB_CONFLICT 0x010 /* Permission Fault (L2) */ +#define FAULT_TLB_CONFLICT 0x010 /* TLB Conflict Abort */ #define FAULT_EA_IMPREC 0x016 /* Asynchronous External Abort */ #define FAULT_PE_IMPREC 0x018 /* Asynchronous Parity Error */ #define FAULT_PARITY 0x019 /* Parity Error */ @@ -444,6 +444,12 @@ #define INSN_COND_MASK 0xf0000000 /* Condition mask */ #define INSN_COND_AL 0xe0000000 /* Always condition */ +/* ARM register defines */ +#define ARM_REG_SIZE 4 +#define ARM_REG_NUM_PC 15 +#define ARM_REG_NUM_LR 14 +#define ARM_REG_NUM_SP 13 + #define THUMB_INSN_SIZE 2 /* Some are 4 bytes. */ #endif /* !MACHINE_ARMREG_H */ diff --git a/sys/arm/include/bus_dma.h b/sys/arm/include/bus_dma.h index 98803efd6b7f..ddf5504dbafd 100644 --- a/sys/arm/include/bus_dma.h +++ b/sys/arm/include/bus_dma.h @@ -94,8 +94,6 @@ struct arm32_dma_range { struct arm32_dma_range *bus_dma_get_range(void); int bus_dma_get_range_nb(void); -extern bus_dma_tag_t arm_root_dma_tag; - #endif /* _ARM32_BUS_DMA_PRIVATE */ #endif /* _ARM_BUS_DMA_H */ diff --git a/sys/arm/include/db_machdep.h b/sys/arm/include/db_machdep.h index 741cae999229..42d313599333 100644 --- a/sys/arm/include/db_machdep.h +++ b/sys/arm/include/db_machdep.h @@ -74,7 +74,7 @@ typedef int db_expr_t; #define inst_branch(ins) (((ins) & 0x0f000000) == 0x0a000000 || \ ((ins) & 0x0fdffff0) == 0x079ff100 || \ - ((ins) & 0x0cf0f000) == 0x0490f000 || \ + ((ins) & 0x0cd0f000) == 0x0490f000 || \ ((ins) & 0x0ffffff0) == 0x012fff30 || /* blx */ \ ((ins) & 0x0de0f000) == 0x0080f000) @@ -90,7 +90,7 @@ typedef int db_expr_t; int db_validate_address(vm_offset_t); -u_int branch_taken (u_int insn, u_int pc); +u_int branch_taken (u_int insn, db_addr_t pc); #ifdef __ARMEB__ #define BYTE_MSF (1) diff --git a/sys/arm/include/machdep.h b/sys/arm/include/machdep.h index 0f43284c852d..fdf59beedb33 100644 --- a/sys/arm/include/machdep.h +++ b/sys/arm/include/machdep.h @@ -43,4 +43,7 @@ void arm_generic_initclocks(void); void board_set_serial(uint64_t); void board_set_revision(uint32_t); +int arm_predict_branch(void *, u_int, register_t, register_t *, + u_int (*)(void*, int), u_int (*)(void*, vm_offset_t, u_int*)); + #endif /* !_MACHINE_MACHDEP_H_ */ diff --git a/sys/arm/include/proc.h b/sys/arm/include/proc.h index 1409a9d77802..090aaba6360d 100644 --- a/sys/arm/include/proc.h +++ b/sys/arm/include/proc.h @@ -51,6 +51,8 @@ struct mdthread { register_t md_spurflt_addr; /* (k) Spurious page fault address. */ int md_ptrace_instr; int md_ptrace_addr; + int md_ptrace_instr_alt; + int md_ptrace_addr_alt; register_t md_tp; void *md_ras_start; void *md_ras_end; diff --git a/sys/arm/include/vfp.h b/sys/arm/include/vfp.h index 62345cec6107..2b91043a17d0 100644 --- a/sys/arm/include/vfp.h +++ b/sys/arm/include/vfp.h @@ -92,6 +92,7 @@ /* VFPEXC */ #define VFPEXC_EX (0x80000000) /* exception v1 v2 */ #define VFPEXC_EN (0x40000000) /* vfp enable */ +#define VFPEXC_DEX (0x20000000) /* Synchronous exception */ #define VFPEXC_FP2V (0x10000000) /* FPINST2 valid */ #define VFPEXC_INV (0x00000080) /* Input exception */ #define VFPEXC_UFC (0x00000008) /* Underflow exception */ diff --git a/sys/arm/ti/ti_common.c b/sys/arm/ti/ti_common.c index 31a6a32eed7a..8a4d7e78b3d0 100644 --- a/sys/arm/ti/ti_common.c +++ b/sys/arm/ti/ti_common.c @@ -29,6 +29,8 @@ * SUCH DAMAGE. */ +#include "opt_platform.h" + #include __FBSDID("$FreeBSD$"); diff --git a/sys/arm/xscale/ixp425/ixp425_pci.c b/sys/arm/xscale/ixp425/ixp425_pci.c index 5a1321864621..9bda385cf8fd 100644 --- a/sys/arm/xscale/ixp425/ixp425_pci.c +++ b/sys/arm/xscale/ixp425/ixp425_pci.c @@ -135,14 +135,6 @@ ixppcib_attach(device_t dev) BUS_SPACE_MAXADDR, NULL, NULL, 0xffffffff, 0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_dmat)) panic("couldn't create the PCI dma tag !"); - /* - * The PCI bus can only address 64MB. However, due to the way our - * implementation of busdma works, busdma can't tell if a device - * is a PCI device or not. So defaults to the PCI dma tag, which - * restrict the DMA'able memory to the first 64MB, and explicitely - * create less restrictive tags for non-PCI devices. - */ - arm_root_dma_tag = sc->sc_dmat; /* * Initialize the bus space tags. */ @@ -361,6 +353,14 @@ ixppcib_release_resource(device_t bus, device_t child, int type, int rid, return (ENXIO); } +static bus_dma_tag_t +ixppcib_get_dma_tag(device_t bus, device_t child) +{ + struct ixppcib_softc *sc = device_get_softc(bus); + + return (sc->sc_dmat); +} + static void ixppcib_conf_setup(struct ixppcib_softc *sc, int bus, int slot, int func, int reg) @@ -459,7 +459,7 @@ static device_method_t ixppcib_methods[] = { DEVMETHOD(bus_activate_resource, ixppcib_activate_resource), DEVMETHOD(bus_deactivate_resource, ixppcib_deactivate_resource), DEVMETHOD(bus_release_resource, ixppcib_release_resource), - /* DEVMETHOD(bus_get_dma_tag, ixppcib_get_dma_tag), */ + DEVMETHOD(bus_get_dma_tag, ixppcib_get_dma_tag), /* pcib interface */ DEVMETHOD(pcib_maxslots, ixppcib_maxslots), diff --git a/sys/arm64/arm64/busdma_bounce.c b/sys/arm64/arm64/busdma_bounce.c index cd0c087a0077..57e44cc8742d 100644 --- a/sys/arm64/arm64/busdma_bounce.c +++ b/sys/arm64/arm64/busdma_bounce.c @@ -401,14 +401,14 @@ bounce_bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, /* * XXX: - * (dmat->alignment < dmat->maxsize) is just a quick hack; the exact + * (dmat->alignment <= dmat->maxsize) is just a quick hack; the exact * alignment guarantees of malloc need to be nailed down, and the * code below should be rewritten to take that into account. * * In the meantime, we'll warn the user if malloc gets it wrong. */ if ((dmat->common.maxsize <= PAGE_SIZE) && - (dmat->common.alignment < dmat->common.maxsize) && + (dmat->common.alignment <= dmat->common.maxsize) && dmat->common.lowaddr >= ptoa((vm_paddr_t)Maxmem) && attr == VM_MEMATTR_DEFAULT) { *vaddr = malloc(dmat->common.maxsize, M_DEVBUF, mflags); diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c index 688cc7913d9c..73adb760e05d 100644 --- a/sys/arm64/arm64/mp_machdep.c +++ b/sys/arm64/arm64/mp_machdep.c @@ -137,6 +137,7 @@ arm64_cpu_probe(device_t dev) if (cpuid >= MAXCPU || cpuid > mp_maxid) return (EINVAL); + device_quiet(dev); return (0); } @@ -158,10 +159,12 @@ arm64_cpu_attach(device_t dev) if (reg == NULL) return (EINVAL); - device_printf(dev, "Found register:"); - for (i = 0; i < reg_size; i++) - printf(" %x", reg[i]); - printf("\n"); + if (bootverbose) { + device_printf(dev, "register <"); + for (i = 0; i < reg_size; i++) + printf("%s%x", (i == 0) ? "" : " ", reg[i]); + printf(">\n"); + } /* Set the device to start it later */ cpu_list[cpuid] = dev; diff --git a/sys/arm64/arm64/nexus.c b/sys/arm64/arm64/nexus.c index 764012e94154..807993bedf75 100644 --- a/sys/arm64/arm64/nexus.c +++ b/sys/arm64/arm64/nexus.c @@ -134,13 +134,11 @@ static device_method_t nexus_methods[] = { { 0, 0 } }; -static devclass_t nexus_devclass; static driver_t nexus_driver = { "nexus", nexus_methods, 1 /* no softc */ }; -DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0); static int nexus_attach(device_t dev) @@ -380,7 +378,8 @@ DEFINE_CLASS_1(nexus, nexus_fdt_driver, nexus_fdt_methods, 1, nexus_driver); #undef nexus_baseclasses static devclass_t nexus_fdt_devclass; -DRIVER_MODULE(nexus_fdt, root, nexus_fdt_driver, nexus_fdt_devclass, 0, 0); +EARLY_DRIVER_MODULE(nexus_fdt, root, nexus_fdt_driver, nexus_fdt_devclass, + 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_FIRST); static int nexus_fdt_probe(device_t dev) @@ -433,7 +432,8 @@ DEFINE_CLASS_1(nexus, nexus_acpi_driver, nexus_acpi_methods, 1, #undef nexus_baseclasses static devclass_t nexus_acpi_devclass; -DRIVER_MODULE(nexus_acpi, root, nexus_acpi_driver, nexus_acpi_devclass, 0, 0); +EARLY_DRIVER_MODULE(nexus_acpi, root, nexus_acpi_driver, nexus_acpi_devclass, + 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_FIRST); static int nexus_acpi_probe(device_t dev) diff --git a/sys/arm64/conf/GENERIC b/sys/arm64/conf/GENERIC index 87f788403ba9..72c5206e671f 100644 --- a/sys/arm64/conf/GENERIC +++ b/sys/arm64/conf/GENERIC @@ -101,6 +101,7 @@ device pci # Ethernet NICs device vnic # Cavium ThunderX NIC device em # Intel PRO/1000 Gigabit Ethernet Family +device igb # Intel PRO/1000 PCIE Server Gigabit Family device mii device miibus # MII bus support diff --git a/sys/boot/fdt/dts/arm/bcm2835.dtsi b/sys/boot/fdt/dts/arm/bcm2835.dtsi index 6ff1944b1c09..0b73401e4a03 100644 --- a/sys/boot/fdt/dts/arm/bcm2835.dtsi +++ b/sys/boot/fdt/dts/arm/bcm2835.dtsi @@ -474,11 +474,12 @@ reg-shift = <2>; }; - vchiq { + vchiq: vchiq { compatible = "broadcom,bcm2835-vchiq"; reg = <0xB800 0x50>; interrupts = <2>; interrupt-parent = <&intc>; + cache-line-size = <32>; }; usb { diff --git a/sys/boot/fdt/dts/arm/bcm2836.dtsi b/sys/boot/fdt/dts/arm/bcm2836.dtsi index c1caac34c702..ce967df7ea87 100644 --- a/sys/boot/fdt/dts/arm/bcm2836.dtsi +++ b/sys/boot/fdt/dts/arm/bcm2836.dtsi @@ -456,11 +456,12 @@ reg-shift = <2>; }; - vchiq { + vchiq: vchiq { compatible = "broadcom,bcm2835-vchiq"; reg = <0xB800 0x50>; interrupts = <2>; interrupt-parent = <&intc>; + cache-line-size = <32>; }; usb { diff --git a/sys/boot/fdt/dts/arm/rpi.dts b/sys/boot/fdt/dts/arm/rpi.dts index 08d9d24bb4e8..548f888b2bb8 100644 --- a/sys/boot/fdt/dts/arm/rpi.dts +++ b/sys/boot/fdt/dts/arm/rpi.dts @@ -389,4 +389,7 @@ stdout = "uart0"; }; + __overrides__ { + cache_line_size = <&vchiq>, "cache-line-size:0"; + }; }; diff --git a/sys/boot/fdt/dts/arm/rpi2.dts b/sys/boot/fdt/dts/arm/rpi2.dts index e32cfb00ea39..951bca3b4737 100644 --- a/sys/boot/fdt/dts/arm/rpi2.dts +++ b/sys/boot/fdt/dts/arm/rpi2.dts @@ -400,4 +400,7 @@ stdout = "uart0"; }; + __overrides__ { + cache_line_size = <&vchiq>, "cache-line-size:0"; + }; }; diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c index 1ecc7fd7b0b8..db28518b97a4 100644 --- a/sys/cam/ata/ata_da.c +++ b/sys/cam/ata/ata_da.c @@ -631,8 +631,6 @@ static struct periph_driver adadriver = PERIPHDRIVER_DECLARE(ada, adadriver); -static MALLOC_DEFINE(M_ATADA, "ata_da", "ata_da buffers"); - static int adaopen(struct disk *dp) { diff --git a/sys/cam/ata/ata_pmp.c b/sys/cam/ata/ata_pmp.c index fab0e6f1f574..aa37de2270f9 100644 --- a/sys/cam/ata/ata_pmp.c +++ b/sys/cam/ata/ata_pmp.c @@ -155,8 +155,6 @@ static struct periph_driver pmpdriver = PERIPHDRIVER_DECLARE(pmp, pmpdriver); -static MALLOC_DEFINE(M_ATPMP, "ata_pmp", "ata_pmp buffers"); - static void pmpinit(void) { diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 0d10721bbf7c..47e10c37faa0 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -11042,7 +11042,15 @@ ctl_check_for_blockage(struct ctl_lun *lun, union ctl_io *pending_io, return (CTL_ACTION_BLOCK); pending_entry = ctl_get_cmd_entry(&pending_io->scsiio, NULL); + KASSERT(pending_entry->seridx < CTL_SERIDX_COUNT, + ("%s: Invalid seridx %d for pending CDB %02x %02x @ %p", + __func__, pending_entry->seridx, pending_io->scsiio.cdb[0], + pending_io->scsiio.cdb[1], pending_io)); ooa_entry = ctl_get_cmd_entry(&ooa_io->scsiio, NULL); + KASSERT(ooa_entry->seridx < CTL_SERIDX_COUNT, + ("%s: Invalid seridx %d for ooa CDB %02x %02x @ %p", + __func__, ooa_entry->seridx, ooa_io->scsiio.cdb[0], + ooa_io->scsiio.cdb[1], ooa_io)); serialize_row = ctl_serialize_table[ooa_entry->seridx]; diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index 2dc2a474bc75..f870288f7044 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -368,7 +368,7 @@ static struct da_quirk_entry da_quirk_table[] = * VMware returns BUSY status when storage has transient * connectivity problems, so better wait. */ - {T_DIRECT, SIP_MEDIA_FIXED, "VMware", "Virtual disk", "*"}, + {T_DIRECT, SIP_MEDIA_FIXED, "VMware*", "*", "*"}, /*quirks*/ DA_Q_RETRY_BUSY }, /* USB mass storage devices supported by umass(4) */ diff --git a/sys/cddl/contrib/opensolaris/common/atomic/aarch64/opensolaris_atomic.S b/sys/cddl/contrib/opensolaris/common/atomic/aarch64/opensolaris_atomic.S new file mode 100644 index 000000000000..0321c7d74e12 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/common/atomic/aarch64/opensolaris_atomic.S @@ -0,0 +1,87 @@ +/*- + * Copyright (C) 2015 Andrew Turner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include + +/* + * uint64_t atomic_add_64_nv(volatile uint64_t *target, int64_t delta) + */ +ENTRY(atomic_add_64_nv) +1: ldxr x2, [x0] /* Load *target */ + add x2, x2, x1 /* x2 = x2 + delta */ + stxr w3, x2, [x0] /* Store *target */ + cbnz w3, 1b /* Check if the store succeeded */ + mov x0, x2 /* Return the new value */ + ret +END(atomic_add_64_nv) + +/* + * uint32_t + * atomic_cas_32(volatile uint32_t *target, uint32_t cmp, uint32_t newval) + */ +ENTRY(atomic_cas_32) +1: ldxr w3, [x0] /* Load *target */ + cmp w3, w1 /* Does *targe == cmp? */ + b.ne 2f /* If not exit */ + stxr w4, w2, [x0] /* Store newval to *target */ + cbnz w4, 1b /* Check if the store succeeded */ +2: mov w0, w3 /* Return the old value */ + ret +END(atomic_cas_32) + +/* + * uint64_t + * atomic_cas_64(volatile uint64_t *target, uint64_t cmp, uint64_t newval) + */ +ENTRY(atomic_cas_64) +1: ldxr x3, [x0] /* Load *target */ + cmp x3, x1 /* Does *targe == cmp? */ + b.ne 2f /* If not exit */ + stxr w4, x2, [x0] /* Store newval to *target */ + cbnz w4, 1b /* Check if the store succeeded */ +2: mov x0, x3 /* Return the old value */ + ret +END(atomic_cas_64) + +/* + * uint8_t atomic_or_8_nv(volatile uint8_t *target, uint8_t value) + */ +ENTRY(atomic_or_8_nv) +1: ldxrb w2, [x0] /* Load *target */ + orr w2, w2, w1 /* x2 = x2 | delta */ + stxrb w3, w2, [x0] /* Store *target */ + cbnz w3, 1b /* Check if the store succeeded */ + mov w0, w2 /* Return the new value */ + ret +END(atomic_or_8_nv) + +ENTRY(membar_producer) + dmb ish + ret +END(membar_producer) + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c index 30c71a63ddcd..1aa566c7d036 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c @@ -255,7 +255,7 @@ int zfs_flags = 0; */ boolean_t zfs_recover = B_FALSE; SYSCTL_DECL(_vfs_zfs); -SYSCTL_INT(_vfs_zfs, OID_AUTO, recover, CTLFLAG_RDTUN, &zfs_recover, 0, +SYSCTL_INT(_vfs_zfs, OID_AUTO, recover, CTLFLAG_RWTUN, &zfs_recover, 0, "Try to recover from otherwise-fatal errors."); static int @@ -1835,7 +1835,13 @@ dva_get_dsize_sync(spa_t *spa, const dva_t *dva) ASSERT(spa_config_held(spa, SCL_ALL, RW_READER) != 0); if (asize != 0 && spa->spa_deflate) { - vdev_t *vd = vdev_lookup_top(spa, DVA_GET_VDEV(dva)); + uint64_t vdev = DVA_GET_VDEV(dva); + vdev_t *vd = vdev_lookup_top(spa, vdev); + if (vd == NULL) { + panic( + "dva_get_dsize_sync(): bad DVA %llu:%llu", + (u_longlong_t)vdev, (u_longlong_t)asize); + } dsize = (asize >> SPA_MINBLOCKSHIFT) * vd->vdev_deflate_ratio; } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c index e2a3bff64577..cf42ff6c7cb3 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c @@ -222,7 +222,7 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, mutex_enter(&dzp->z_lock); for (;;) { - if (dzp->z_unlinked) { + if (dzp->z_unlinked && !(flag & ZXATTR)) { mutex_exit(&dzp->z_lock); if (!(flag & ZHAVELOCK)) rw_exit(&dzp->z_name_lock); diff --git a/sys/compat/linuxkpi/common/include/asm/byteorder.h b/sys/compat/linuxkpi/common/include/asm/byteorder.h index 7168e49b951a..21cc494d3088 100644 --- a/sys/compat/linuxkpi/common/include/asm/byteorder.h +++ b/sys/compat/linuxkpi/common/include/asm/byteorder.h @@ -86,7 +86,7 @@ #define swab64 bswap64 static inline void -be16_add_cpu(u16 *var, u16 val) +be16_add_cpu(uint16_t *var, uint16_t val) { *var = cpu_to_be16(be16_to_cpu(*var) + val); } diff --git a/sys/compat/linuxkpi/common/include/asm/types.h b/sys/compat/linuxkpi/common/include/asm/types.h index fb2fd568c067..63e1ac6aca8c 100644 --- a/sys/compat/linuxkpi/common/include/asm/types.h +++ b/sys/compat/linuxkpi/common/include/asm/types.h @@ -33,6 +33,8 @@ #ifdef _KERNEL +#include + typedef uint8_t u8; typedef uint8_t __u8; typedef uint16_t u16; diff --git a/sys/compat/linuxkpi/common/include/linux/bitops.h b/sys/compat/linuxkpi/common/include/linux/bitops.h index 8b985a92c475..2f402e86bf78 100644 --- a/sys/compat/linuxkpi/common/include/linux/bitops.h +++ b/sys/compat/linuxkpi/common/include/linux/bitops.h @@ -33,6 +33,7 @@ #include #include +#include #define BIT(nr) (1UL << (nr)) #ifdef __LP64__ diff --git a/sys/compat/linuxkpi/common/include/linux/cdev.h b/sys/compat/linuxkpi/common/include/linux/cdev.h index 9d5b3fb0f240..5d8962f46355 100644 --- a/sys/compat/linuxkpi/common/include/linux/cdev.h +++ b/sys/compat/linuxkpi/common/include/linux/cdev.h @@ -32,6 +32,7 @@ #define _LINUX_CDEV_H_ #include +#include #include #include diff --git a/sys/compat/linuxkpi/common/include/linux/clocksource.h b/sys/compat/linuxkpi/common/include/linux/clocksource.h index 7a4835c9bea3..f4d17f188796 100644 --- a/sys/compat/linuxkpi/common/include/linux/clocksource.h +++ b/sys/compat/linuxkpi/common/include/linux/clocksource.h @@ -31,6 +31,8 @@ #ifndef _LINUX_CLOCKSOURCE_H #define _LINUX_CLOCKSOURCE_H +#include + /* clocksource cycle base type */ typedef u64 cycle_t; diff --git a/sys/compat/linuxkpi/common/include/linux/device.h b/sys/compat/linuxkpi/common/include/linux/device.h index 3459a5c4b68d..02b2064587d5 100644 --- a/sys/compat/linuxkpi/common/include/linux/device.h +++ b/sys/compat/linuxkpi/common/include/linux/device.h @@ -33,6 +33,7 @@ #include #include +#include #include #include #include diff --git a/sys/compat/linuxkpi/common/include/linux/idr.h b/sys/compat/linuxkpi/common/include/linux/idr.h index 9beec6898838..fc377d40a05d 100644 --- a/sys/compat/linuxkpi/common/include/linux/idr.h +++ b/sys/compat/linuxkpi/common/include/linux/idr.h @@ -31,7 +31,11 @@ #ifndef _LINUX_IDR_H_ #define _LINUX_IDR_H_ -#include +#include +#include +#include + +#include #define IDR_BITS 5 #define IDR_SIZE (1 << IDR_BITS) diff --git a/sys/compat/linuxkpi/common/include/linux/if_arp.h b/sys/compat/linuxkpi/common/include/linux/if_arp.h index 6233aac6fa67..9235e2dff9cf 100644 --- a/sys/compat/linuxkpi/common/include/linux/if_arp.h +++ b/sys/compat/linuxkpi/common/include/linux/if_arp.h @@ -30,6 +30,8 @@ */ #ifndef _LINUX_IF_ARP_H_ #define _LINUX_IF_ARP_H_ +#include +#include #include #include #endif /* _LINUX_IF_ARP_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/if_vlan.h b/sys/compat/linuxkpi/common/include/linux/if_vlan.h index 4a8808fb335c..cd65183250d1 100644 --- a/sys/compat/linuxkpi/common/include/linux/if_vlan.h +++ b/sys/compat/linuxkpi/common/include/linux/if_vlan.h @@ -31,6 +31,7 @@ #ifndef _LINUX_IF_VLAN_H_ #define _LINUX_IF_VLAN_H_ +#include #include #include #include diff --git a/sys/compat/linuxkpi/common/include/linux/interrupt.h b/sys/compat/linuxkpi/common/include/linux/interrupt.h index 4c0ad8087582..d33a3b02bbb7 100644 --- a/sys/compat/linuxkpi/common/include/linux/interrupt.h +++ b/sys/compat/linuxkpi/common/include/linux/interrupt.h @@ -61,7 +61,7 @@ _irq_rid(struct device *dev, int irq) return irq - dev->msix + 1; } -static void +static inline void _irq_handler(void *ent) { struct irq_ent *irqe; diff --git a/sys/compat/linuxkpi/common/include/linux/io.h b/sys/compat/linuxkpi/common/include/linux/io.h index 16543ff11573..f3a1e686963a 100644 --- a/sys/compat/linuxkpi/common/include/linux/io.h +++ b/sys/compat/linuxkpi/common/include/linux/io.h @@ -33,6 +33,7 @@ #include #include +#include static inline uint32_t __raw_readl(const volatile void *addr) diff --git a/sys/compat/linuxkpi/common/include/linux/jhash.h b/sys/compat/linuxkpi/common/include/linux/jhash.h index f31829e846b2..c3904e276778 100644 --- a/sys/compat/linuxkpi/common/include/linux/jhash.h +++ b/sys/compat/linuxkpi/common/include/linux/jhash.h @@ -1,6 +1,8 @@ #ifndef _LINUX_JHASH_H_ #define _LINUX_JHASH_H_ +#include + /* jhash.h: Jenkins hash support. * * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net) diff --git a/sys/compat/linuxkpi/common/include/linux/kobject.h b/sys/compat/linuxkpi/common/include/linux/kobject.h index 63fbc56b48bc..0e9480964d3d 100644 --- a/sys/compat/linuxkpi/common/include/linux/kobject.h +++ b/sys/compat/linuxkpi/common/include/linux/kobject.h @@ -59,6 +59,20 @@ struct kobject { extern struct kobject *mm_kobj; +struct attribute { + const char *name; + struct module *owner; + mode_t mode; +}; + +struct kobj_attribute { + struct attribute attr; + ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, + char *buf); + ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count); +}; + static inline void kobject_init(struct kobject *kobj, struct kobj_type *ktype) { @@ -155,17 +169,4 @@ int kobject_set_name(struct kobject *kobj, const char *fmt, ...); int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype, struct kobject *parent, const char *fmt, ...); -/* sysfs.h calles for 'kobject' which is defined here, - * so we need to add the include only after the 'kobject' def. - */ -#include - -struct kobj_attribute { - struct attribute attr; - ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, - char *buf); - ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t count); -}; - #endif /* _LINUX_KOBJECT_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/kref.h b/sys/compat/linuxkpi/common/include/linux/kref.h index de5ddaa4b886..584de8db7f4f 100644 --- a/sys/compat/linuxkpi/common/include/linux/kref.h +++ b/sys/compat/linuxkpi/common/include/linux/kref.h @@ -35,6 +35,7 @@ #include #include +#include #include struct kref { diff --git a/sys/compat/linuxkpi/common/include/linux/module.h b/sys/compat/linuxkpi/common/include/linux/module.h index 0caa2b00695b..7db9f08c84bc 100644 --- a/sys/compat/linuxkpi/common/include/linux/module.h +++ b/sys/compat/linuxkpi/common/include/linux/module.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #include diff --git a/sys/compat/linuxkpi/common/include/linux/net.h b/sys/compat/linuxkpi/common/include/linux/net.h index 166b7503f273..282a45d2db32 100644 --- a/sys/compat/linuxkpi/common/include/linux/net.h +++ b/sys/compat/linuxkpi/common/include/linux/net.h @@ -31,9 +31,13 @@ #ifndef _LINUX_NET_H_ #define _LINUX_NET_H_ +#include +#include +#include #include #include #include +#include static inline int sock_create_kern(int family, int type, int proto, struct socket **res) diff --git a/sys/compat/linuxkpi/common/include/linux/notifier.h b/sys/compat/linuxkpi/common/include/linux/notifier.h index ca750e04a37d..472236853dcf 100644 --- a/sys/compat/linuxkpi/common/include/linux/notifier.h +++ b/sys/compat/linuxkpi/common/include/linux/notifier.h @@ -31,6 +31,7 @@ #ifndef _LINUX_NOTIFIER_H_ #define _LINUX_NOTIFIER_H_ +#include #include /* diff --git a/sys/compat/linuxkpi/common/include/linux/poll.h b/sys/compat/linuxkpi/common/include/linux/poll.h index e4f7417caef9..bdcfd293396b 100644 --- a/sys/compat/linuxkpi/common/include/linux/poll.h +++ b/sys/compat/linuxkpi/common/include/linux/poll.h @@ -34,11 +34,14 @@ #include #include +#include +#include + typedef struct poll_table_struct { } poll_table; static inline void -poll_wait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p) +poll_wait(struct linux_file *filp, wait_queue_head_t *wait_address, poll_table *p) { selrecord(curthread, &filp->f_selinfo); } diff --git a/sys/compat/linuxkpi/common/include/linux/radix-tree.h b/sys/compat/linuxkpi/common/include/linux/radix-tree.h index 838b81cfdf73..0edf04ee0ca5 100644 --- a/sys/compat/linuxkpi/common/include/linux/radix-tree.h +++ b/sys/compat/linuxkpi/common/include/linux/radix-tree.h @@ -31,6 +31,8 @@ #ifndef _LINUX_RADIX_TREE_H_ #define _LINUX_RADIX_TREE_H_ +#include + #define RADIX_TREE_MAP_SHIFT 6 #define RADIX_TREE_MAP_SIZE (1 << RADIX_TREE_MAP_SHIFT) #define RADIX_TREE_MAP_MASK (RADIX_TREE_MAP_SIZE - 1) diff --git a/sys/compat/linuxkpi/common/include/linux/rwlock.h b/sys/compat/linuxkpi/common/include/linux/rwlock.h index e7c6301f9587..54c53dc94988 100644 --- a/sys/compat/linuxkpi/common/include/linux/rwlock.h +++ b/sys/compat/linuxkpi/common/include/linux/rwlock.h @@ -31,6 +31,7 @@ #ifndef _LINUX_RWLOCK_H_ #define _LINUX_RWLOCK_H_ +#include #include #include diff --git a/sys/compat/linuxkpi/common/include/linux/sysfs.h b/sys/compat/linuxkpi/common/include/linux/sysfs.h index e565e43699d6..a102d4391ff8 100644 --- a/sys/compat/linuxkpi/common/include/linux/sysfs.h +++ b/sys/compat/linuxkpi/common/include/linux/sysfs.h @@ -31,13 +31,11 @@ #ifndef _LINUX_SYSFS_H_ #define _LINUX_SYSFS_H_ +#include #include +#include -struct attribute { - const char *name; - struct module *owner; - mode_t mode; -}; +#include struct sysfs_ops { ssize_t (*show)(struct kobject *, struct attribute *, char *); diff --git a/sys/compat/linuxkpi/common/include/linux/usb.h b/sys/compat/linuxkpi/common/include/linux/usb.h index 1f00d4b4addc..1954a7014a82 100644 --- a/sys/compat/linuxkpi/common/include/linux/usb.h +++ b/sys/compat/linuxkpi/common/include/linux/usb.h @@ -28,6 +28,15 @@ #ifndef _USB_COMPAT_LINUX_H #define _USB_COMPAT_LINUX_H +#include +#include +#include +#include + +#include +#include +#include + struct usb_device; struct usb_interface; struct usb_driver; diff --git a/sys/compat/linuxkpi/common/include/net/if_inet6.h b/sys/compat/linuxkpi/common/include/net/if_inet6.h index df853fd36cce..6fd92209523e 100644 --- a/sys/compat/linuxkpi/common/include/net/if_inet6.h +++ b/sys/compat/linuxkpi/common/include/net/if_inet6.h @@ -31,6 +31,11 @@ #ifndef _NET_IF_INET6_H_ #define _NET_IF_INET6_H_ +#include +#include + +#include + static inline void ipv6_eth_mc_map(const struct in6_addr *addr, char *buf) { /* diff --git a/sys/compat/linuxkpi/common/include/net/ipv6.h b/sys/compat/linuxkpi/common/include/net/ipv6.h index 1244706e14c4..7e078f378cdb 100644 --- a/sys/compat/linuxkpi/common/include/net/ipv6.h +++ b/sys/compat/linuxkpi/common/include/net/ipv6.h @@ -31,13 +31,14 @@ #ifndef _LINUX_NET_IPV6_H_ #define _LINUX_NET_IPV6_H_ -#include "opt_inet6.h" +#include +#include +#include #define ipv6_addr_loopback IN6_IS_ADDR_LOOPBACK #define ipv6_addr_copy(dst, src) \ memcpy((dst), (src), sizeof(struct in6_addr)) -#ifdef INET6 static inline void ipv6_ib_mc_map(const struct in6_addr *addr, const unsigned char *broadcast, char *buf) @@ -57,7 +58,6 @@ ipv6_ib_mc_map(const struct in6_addr *addr, const unsigned char *broadcast, buf[9] = broadcast[9]; memcpy(&buf[10], &addr->s6_addr[6], 10); } -#endif static inline void __ipv6_addr_set_half(__be32 *addr, __be32 wh, __be32 wl) diff --git a/sys/compat/linuxkpi/common/include/net/netevent.h b/sys/compat/linuxkpi/common/include/net/netevent.h index d2d37c0a1ed5..ffd3419f673b 100644 --- a/sys/compat/linuxkpi/common/include/net/netevent.h +++ b/sys/compat/linuxkpi/common/include/net/netevent.h @@ -31,7 +31,10 @@ #ifndef _LINUX_NET_NETEVENT_H_ #define _LINUX_NET_NETEVENT_H_ -#include +#include +#include + +#include enum netevent_notif_type { NETEVENT_NEIGH_UPDATE = 0, diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 3a9a651d61c3..303b084150b6 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -88,7 +88,7 @@ libkern/flsl.c standard libkern/flsll.c standard libkern/memmove.c standard libkern/memset.c standard -cddl/compat/opensolaris/kern/opensolaris_atomic.c optional zfs | dtrace compile-with "${CDDL_C}" +cddl/contrib/opensolaris/common/atomic/aarch64/opensolaris_atomic.S optional zfs | dtrace compile-with "${CDDL_C}" cddl/dev/dtrace/aarch64/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}" cddl/dev/dtrace/aarch64/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}" cddl/dev/fbt/aarch64/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" diff --git a/sys/conf/kern.opts.mk b/sys/conf/kern.opts.mk index f94ffb7595e4..2e77c4fbcf31 100644 --- a/sys/conf/kern.opts.mk +++ b/sys/conf/kern.opts.mk @@ -45,6 +45,7 @@ __DEFAULT_YES_OPTIONS = \ __DEFAULT_NO_OPTIONS = \ EISA \ + FAST_DEPEND \ NAND \ OFED diff --git a/sys/conf/kern.post.mk b/sys/conf/kern.post.mk index ddf828ed3177..bf24d17daab3 100644 --- a/sys/conf/kern.post.mk +++ b/sys/conf/kern.post.mk @@ -198,18 +198,37 @@ kernel-depend: .depend SRCS= assym.s vnode_if.h ${BEFORE_DEPEND} ${CFILES} \ ${SYSTEM_CFILES} ${GEN_CFILES} ${SFILES} \ ${MFILES:T:S/.m$/.h/} +DEPENDFILES= .depend +.if ${MK_FAST_DEPEND} == "yes" +DEPENDFILES+= .depend.* +DEPEND_CFLAGS+= -MD -MP -MF.depend.${.TARGET} +DEPEND_CFLAGS+= -MT${.TARGET} +CFLAGS+= ${DEPEND_CFLAGS} +DEPENDOBJS+= ${SYSTEM_OBJS} +.for __obj in ${DEPENDOBJS:O:u} +.sinclude ".depend.${__obj}" +DEPENDFILES_OBJS+= .depend.${__obj} +.endfor +.endif # ${MK_FAST_DEPEND} == "yes" + +.NOPATH: .depend ${DEPENDFILES_OBJS} + .depend: .PRECIOUS ${SRCS} - rm -f .newdep +.if ${MK_FAST_DEPEND} == "no" + rm -f ${.TARGET}.tmp ${MAKE} -V CFILES_NOCDDL -V SYSTEM_CFILES -V GEN_CFILES | \ - MKDEP_CPP="${CC} -E" CC="${CC}" xargs mkdep -a -f .newdep ${CFLAGS} + CC="${CC}" xargs mkdep -a -f ${.TARGET}.tmp ${CFLAGS} ${MAKE} -V CFILES_CDDL | \ - MKDEP_CPP="${CC} -E" CC="${CC}" xargs mkdep -a -f .newdep ${ZFS_CFLAGS} ${FBT_CFLAGS} ${DTRACE_CFLAGS} + CC="${CC}" xargs mkdep -a -f ${.TARGET}.tmp ${ZFS_CFLAGS} \ + ${FBT_CFLAGS} ${DTRACE_CFLAGS} ${MAKE} -V SFILES_NOCDDL | \ - MKDEP_CPP="${CC} -E" xargs mkdep -a -f .newdep ${ASM_CFLAGS} + CC="${CC}" xargs mkdep -a -f ${.TARGET}.tmp ${ASM_CFLAGS} ${MAKE} -V SFILES_CDDL | \ - MKDEP_CPP="${CC} -E" xargs mkdep -a -f .newdep ${ZFS_ASM_CFLAGS} - rm -f .depend - mv .newdep .depend + CC="${CC}" xargs mkdep -a -f ${.TARGET}.tmp ${ZFS_ASM_CFLAGS} + mv ${.TARGET}.tmp ${.TARGET} +.else + : > ${.TARGET} +.endif _ILINKS= machine .if ${MACHINE} != ${MACHINE_CPUARCH} && ${MACHINE} != "arm64" @@ -237,8 +256,8 @@ ${_ILINKS}: ln -s $$path ${.TARGET} # .depend needs include links so we remove them only together. -kernel-cleandepend: - rm -f .depend ${_ILINKS} +kernel-cleandepend: .PHONY + rm -f ${DEPENDFILES} ${_ILINKS} kernel-tags: @[ -f .depend ] || { echo "you must make depend first"; exit 1; } diff --git a/sys/contrib/vchiq/interface/vchi/vchi.h b/sys/contrib/vchiq/interface/vchi/vchi.h index f1b9d1c2bb5a..c80b25510728 100644 --- a/sys/contrib/vchiq/interface/vchi/vchi.h +++ b/sys/contrib/vchiq/interface/vchi/vchi.h @@ -220,7 +220,12 @@ extern int32_t vchi_service_use( const VCHI_SERVICE_HANDLE_T handle ); // Routine to decrement ref count on a named service extern int32_t vchi_service_release( const VCHI_SERVICE_HANDLE_T handle ); -// Routine to send a message accross a service +// Routine to set a control option for a named service +extern int32_t vchi_service_set_option( const VCHI_SERVICE_HANDLE_T handle, + VCHI_SERVICE_OPTION_T option, + int value); + +// Routine to send a message across a service extern int32_t vchi_msg_queue( VCHI_SERVICE_HANDLE_T handle, const void *data, uint32_t data_size, diff --git a/sys/contrib/vchiq/interface/vchi/vchi_common.h b/sys/contrib/vchiq/interface/vchi/vchi_common.h index 9e6c00e82324..d535a72970d3 100644 --- a/sys/contrib/vchiq/interface/vchi/vchi_common.h +++ b/sys/contrib/vchiq/interface/vchi/vchi_common.h @@ -110,7 +110,19 @@ typedef enum VCHI_CALLBACK_REASON_MAX } VCHI_CALLBACK_REASON_T; -//Calback used by all services / bulk transfers +// service control options +typedef enum +{ + VCHI_SERVICE_OPTION_MIN, + + VCHI_SERVICE_OPTION_TRACE, + VCHI_SERVICE_OPTION_SYNCHRONOUS, + + VCHI_SERVICE_OPTION_MAX +} VCHI_SERVICE_OPTION_T; + + +//Callback used by all services / bulk transfers typedef void (*VCHI_CALLBACK_T)( void *callback_param, //my service local param VCHI_CALLBACK_REASON_T reason, void *handle ); //for transmitting msg's only diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq.h b/sys/contrib/vchiq/interface/vchiq_arm/vchiq.h index f87dcbdaaffc..ad398bae6ee4 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq.h +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq.h @@ -38,4 +38,3 @@ #include "vchiq_util.h" #endif - diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c index 2f8ed436a1d5..9b97615141d1 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c @@ -61,9 +61,13 @@ MALLOC_DEFINE(M_VCPAGELIST, "vcpagelist", "VideoCore pagelist memory"); #include "vchiq_arm.h" #include "vchiq_2835.h" #include "vchiq_connected.h" +#include "vchiq_killable.h" #define MAX_FRAGMENTS (VCHIQ_NUM_CURRENT_BULKS * 2) +int g_cache_line_size = 32; +static int g_fragment_size; + typedef struct vchiq_2835_state_struct { int inited; VCHIQ_ARM_STATE_T arm_state; @@ -76,8 +80,8 @@ vm_paddr_t g_slot_phys; bus_dma_tag_t bcm_slots_dma_tag; bus_dmamap_t bcm_slots_dma_map; -static FRAGMENTS_T *g_fragments_base; -static FRAGMENTS_T *g_free_fragments; +static char *g_fragments_base; +static char *g_free_fragments; struct semaphore g_free_fragments_sema; static DEFINE_SEMAPHORE(g_free_fragments_mutex); @@ -114,13 +118,13 @@ copyout_page(vm_page_t p, size_t offset, void *kaddr, size_t size) { uint8_t *dst; - dst = pmap_mapdev(VM_PAGE_TO_PHYS(p), PAGE_SIZE); + dst = (uint8_t*)pmap_quick_enter_page(p); if (!dst) return ENOMEM; memcpy(dst + offset, kaddr, size); - pmap_unmapdev((vm_offset_t)dst, PAGE_SIZE); + pmap_quick_remove_page((vm_offset_t)dst); return 0; } @@ -135,7 +139,8 @@ vchiq_platform_init(VCHIQ_STATE_T *state) /* Allocate space for the channels in coherent memory */ g_slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); - frag_mem_size = PAGE_ALIGN(sizeof(FRAGMENTS_T) * MAX_FRAGMENTS); + g_fragment_size = 2*g_cache_line_size; + frag_mem_size = PAGE_ALIGN(g_fragment_size * MAX_FRAGMENTS); err = bus_dma_tag_create( NULL, @@ -179,15 +184,15 @@ vchiq_platform_init(VCHIQ_STATE_T *state) vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] = MAX_FRAGMENTS; - g_fragments_base = (FRAGMENTS_T *)(g_slot_mem + g_slot_mem_size); + g_fragments_base = (char *)(g_slot_mem + g_slot_mem_size); g_slot_mem_size += frag_mem_size; g_free_fragments = g_fragments_base; for (i = 0; i < (MAX_FRAGMENTS - 1); i++) { - *(FRAGMENTS_T **)&g_fragments_base[i] = - &g_fragments_base[i + 1]; + *(char **)&g_fragments_base[i*g_fragment_size] = + &g_fragments_base[(i + 1)*g_fragment_size]; } - *(FRAGMENTS_T **)&g_fragments_base[i] = NULL; + *(char **)&g_fragments_base[i*g_fragment_size] = NULL; _sema_init(&g_free_fragments_sema, MAX_FRAGMENTS); if (vchiq_init_state(state, vchiq_slot_zero, 0/*slave*/) != @@ -451,7 +456,8 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, } vchiq_log_trace(vchiq_arm_log_level, - "create_pagelist - %x", (unsigned int)pagelist); + "create_pagelist - %x (%d bytes @%p)", (unsigned int)pagelist, count, buf); + if (!pagelist) return -ENOMEM; @@ -505,10 +511,10 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, /* Partial cache lines (fragments) require special measures */ if ((type == PAGELIST_READ) && - ((pagelist->offset & (CACHE_LINE_SIZE - 1)) || + ((pagelist->offset & (g_cache_line_size - 1)) || ((pagelist->offset + pagelist->length) & - (CACHE_LINE_SIZE - 1)))) { - FRAGMENTS_T *fragments; + (g_cache_line_size - 1)))) { + char *fragments; if (down_interruptible(&g_free_fragments_sema) != 0) { free(pagelist, M_VCPAGELIST); @@ -518,13 +524,13 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, WARN_ON(g_free_fragments == NULL); down(&g_free_fragments_mutex); - fragments = (FRAGMENTS_T *) g_free_fragments; + fragments = g_free_fragments; WARN_ON(fragments == NULL); - g_free_fragments = *(FRAGMENTS_T **) g_free_fragments; + g_free_fragments = *(char **) g_free_fragments; up(&g_free_fragments_mutex); pagelist->type = - PAGELIST_READ_WITH_FRAGMENTS + (fragments - - g_fragments_base); + PAGELIST_READ_WITH_FRAGMENTS + + (fragments - g_fragments_base)/g_fragment_size; } cpu_dcache_wbinv_range((vm_offset_t)buf, count); @@ -554,7 +560,7 @@ free_pagelist(BULKINFO_T *bi, int actual) pagelist = bi->pagelist; vchiq_log_trace(vchiq_arm_log_level, - "free_pagelist - %x, %d", (unsigned int)pagelist, actual); + "free_pagelist - %x, %d (%lu bytes @%p)", (unsigned int)pagelist, actual, pagelist->length, bi->buf); num_pages = (pagelist->length + pagelist->offset + PAGE_SIZE - 1) / @@ -564,13 +570,13 @@ free_pagelist(BULKINFO_T *bi, int actual) /* Deal with any partial cache lines (fragments) */ if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS) { - FRAGMENTS_T *fragments = g_fragments_base + - (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS); + char *fragments = g_fragments_base + + (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS)*g_fragment_size; int head_bytes, tail_bytes; - head_bytes = (CACHE_LINE_SIZE - pagelist->offset) & - (CACHE_LINE_SIZE - 1); + head_bytes = (g_cache_line_size - pagelist->offset) & + (g_cache_line_size - 1); tail_bytes = (pagelist->offset + actual) & - (CACHE_LINE_SIZE - 1); + (g_cache_line_size - 1); if ((actual >= 0) && (head_bytes != 0)) { if (head_bytes > actual) @@ -578,7 +584,7 @@ free_pagelist(BULKINFO_T *bi, int actual) copyout_page(pages[0], pagelist->offset, - fragments->headbuf, + fragments, head_bytes); } @@ -587,12 +593,12 @@ free_pagelist(BULKINFO_T *bi, int actual) copyout_page(pages[num_pages-1], (((vm_offset_t)bi->buf + actual) % PAGE_SIZE) - tail_bytes, - fragments->tailbuf, + fragments + g_cache_line_size, tail_bytes); } down(&g_free_fragments_mutex); - *(FRAGMENTS_T **) fragments = g_free_fragments; + *(char **) fragments = g_free_fragments; g_free_fragments = fragments; up(&g_free_fragments_mutex); up(&g_free_fragments_sema); diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.c index d534a7fa755f..556ddf619778 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.c @@ -1,4 +1,5 @@ /** + * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved. * Copyright (c) 2010-2012 Broadcom. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -102,13 +103,15 @@ typedef struct user_service_struct { VCHIQ_SERVICE_T *service; void *userdata; VCHIQ_INSTANCE_T instance; - int is_vchi; - int dequeue_pending; + char is_vchi; + char dequeue_pending; + char close_pending; int message_available_pos; int msg_insert; int msg_remove; struct semaphore insert_event; struct semaphore remove_event; + struct semaphore close_event; VCHIQ_HEADER_T * msg_queue[MSG_QUEUE_SIZE]; } USER_SERVICE_T; @@ -131,11 +134,15 @@ struct vchiq_instance_struct { int closing; int pid; int mark; + int use_close_delivered; + int trace; struct list_head bulk_waiter_list; struct mutex bulk_waiter_list_mutex; - struct proc_dir_entry *proc_entry; +#ifdef notyet + VCHIQ_DEBUGFS_NODE_T proc_entry; +#endif }; typedef struct dump_context_struct { @@ -165,7 +172,9 @@ static const char *const ioctl_names[] = { "USE_SERVICE", "RELEASE_SERVICE", "SET_SERVICE_OPTION", - "DUMP_PHYS_MEM" + "DUMP_PHYS_MEM", + "LIB_VERSION", + "CLOSE_DELIVERED" }; vchiq_static_assert((sizeof(ioctl_names)/sizeof(ioctl_names[0])) == @@ -232,10 +241,13 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, completion->service_userdata = user_service->service; completion->bulk_userdata = bulk_userdata; - if (reason == VCHIQ_SERVICE_CLOSED) + if (reason == VCHIQ_SERVICE_CLOSED) { /* Take an extra reference, to be held until this CLOSED notification is delivered. */ lock_service(user_service->service); + if (instance->use_close_delivered) + user_service->close_pending = 1; + } /* A write barrier is needed here to ensure that the entire completion record is written out before the insert point. */ @@ -282,10 +294,10 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header, return VCHIQ_SUCCESS; vchiq_log_trace(vchiq_arm_log_level, - "service_callback - service %lx(%d), handle %x, reason %d, header %lx, " + "service_callback - service %lx(%d,%p), reason %d, header %lx, " "instance %lx, bulk_userdata %lx", (unsigned long)user_service, - service->localport, service->handle, + service->localport, user_service->userdata, reason, (unsigned long)header, (unsigned long)instance, (unsigned long)bulk_userdata); @@ -375,6 +387,28 @@ user_service_free(void *userdata) kfree(user_service); } +/**************************************************************************** +* +* close_delivered +* +***************************************************************************/ +static void close_delivered(USER_SERVICE_T *user_service) +{ + vchiq_log_info(vchiq_arm_log_level, + "close_delivered(handle=%x)", + user_service->service->handle); + + if (user_service->close_pending) { + /* Allow the underlying service to be culled */ + unlock_service(user_service->service); + + /* Wake the user-thread blocked in close_ or remove_service */ + up(&user_service->close_event); + + user_service->close_pending = 0; + } +} + /**************************************************************************** * * vchiq_ioctl @@ -496,14 +530,16 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, user_service->service = service; user_service->userdata = userdata; user_service->instance = instance; - user_service->is_vchi = args.is_vchi; + user_service->is_vchi = (args.is_vchi != 0); user_service->dequeue_pending = 0; + user_service->close_pending = 0; user_service->message_available_pos = instance->completion_remove - 1; user_service->msg_insert = 0; user_service->msg_remove = 0; _sema_init(&user_service->insert_event, 0); _sema_init(&user_service->remove_event, 0); + _sema_init(&user_service->close_event, 0); if (args.is_open) { status = vchiq_open_service_internal @@ -543,8 +579,24 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, #endif service = find_service_for_instance(instance, handle); - if (service != NULL) - status = vchiq_close_service(service->handle); + if (service != NULL) { + USER_SERVICE_T *user_service = + (USER_SERVICE_T *)service->base.userdata; + /* close_pending is false on first entry, and when the + wait in vchiq_close_service has been interrupted. */ + if (!user_service->close_pending) { + status = vchiq_close_service(service->handle); + if (status != VCHIQ_SUCCESS) + break; + } + + /* close_pending is true once the underlying service + has been closed until the client library calls the + CLOSE_DELIVERED ioctl, signalling close_event. */ + if (user_service->close_pending && + down_interruptible(&user_service->close_event)) + status = VCHIQ_RETRY; + } else ret = -EINVAL; } break; @@ -559,8 +611,24 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, #endif service = find_service_for_instance(instance, handle); - if (service != NULL) - status = vchiq_remove_service(service->handle); + if (service != NULL) { + USER_SERVICE_T *user_service = + (USER_SERVICE_T *)service->base.userdata; + /* close_pending is false on first entry, and when the + wait in vchiq_close_service has been interrupted. */ + if (!user_service->close_pending) { + status = vchiq_remove_service(service->handle); + if (status != VCHIQ_SUCCESS) + break; + } + + /* close_pending is true once the underlying service + has been closed until the client library calls the + CLOSE_DELIVERED ioctl, signalling close_event. */ + if (user_service->close_pending && + down_interruptible(&user_service->close_event)) + status = VCHIQ_RETRY; + } else ret = -EINVAL; } break; @@ -824,8 +892,9 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, completion->header = msgbuf; } - if (completion->reason == - VCHIQ_SERVICE_CLOSED) + if ((completion->reason == + VCHIQ_SERVICE_CLOSED) && + !instance->use_close_delivered) unlock_service(service1); if (copy_to_user((void __user *)( @@ -1007,6 +1076,29 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, #endif } break; + case VCHIQ_IOC_LIB_VERSION: { + unsigned int lib_version = (unsigned int)arg; + + if (lib_version < VCHIQ_VERSION_MIN) + ret = -EINVAL; + else if (lib_version >= VCHIQ_VERSION_CLOSE_DELIVERED) + instance->use_close_delivered = 1; + } break; + + case VCHIQ_IOC_CLOSE_DELIVERED: { + VCHIQ_SERVICE_HANDLE_T handle; + memcpy(&handle, (const void*)arg, sizeof(handle)); + + service = find_closed_service_for_instance(instance, handle); + if (service != NULL) { + USER_SERVICE_T *user_service = + (USER_SERVICE_T *)service->base.userdata; + close_delivered(user_service); + } + else + ret = -EINVAL; + } break; + default: ret = -ENOTTY; break; @@ -1209,7 +1301,15 @@ vchiq_close(struct cdev *dev, int flags __unused, int fmt __unused, (MAX_COMPLETIONS - 1)]; service1 = completion->service_userdata; if (completion->reason == VCHIQ_SERVICE_CLOSED) + { + USER_SERVICE_T *user_service = + service->base.userdata; + + /* Wake any blocked user-thread */ + if (instance->use_close_delivered) + up(&user_service->close_event); unlock_service(service1); + } instance->completion_remove++; } @@ -1704,7 +1804,7 @@ vchiq_arm_init_state(VCHIQ_STATE_T *state, VCHIQ_ARM_STATE_T *arm_state) ** VC_RESUME_FAILED - Currently unused - no mechanism to fail resume exists. */ -inline void +void set_suspend_state(VCHIQ_ARM_STATE_T *arm_state, enum vc_suspend_status new_state) { @@ -1725,6 +1825,7 @@ set_suspend_state(VCHIQ_ARM_STATE_T *arm_state, complete_all(&arm_state->vc_resume_complete); break; case VC_SUSPEND_IDLE: + /* TODO: reinit_completion */ INIT_COMPLETION(arm_state->vc_suspend_complete); break; case VC_SUSPEND_REQUESTED: @@ -1741,7 +1842,7 @@ set_suspend_state(VCHIQ_ARM_STATE_T *arm_state, } } -inline void +void set_resume_state(VCHIQ_ARM_STATE_T *arm_state, enum vc_resume_status new_state) { @@ -1753,6 +1854,7 @@ set_resume_state(VCHIQ_ARM_STATE_T *arm_state, case VC_RESUME_FAILED: break; case VC_RESUME_IDLE: + /* TODO: reinit_completion */ INIT_COMPLETION(arm_state->vc_resume_complete); break; case VC_RESUME_REQUESTED: @@ -1815,6 +1917,7 @@ block_resume(VCHIQ_ARM_STATE_T *arm_state) * (which only happens when blocked_count hits 0) then those threads * will have to wait until next time around */ if (arm_state->blocked_count) { + /* TODO: reinit_completion */ INIT_COMPLETION(arm_state->blocked_blocker); write_unlock_bh(&arm_state->susp_res_lock); vchiq_log_info(vchiq_susp_log_level, "%s wait for previously " @@ -1860,6 +1963,7 @@ block_resume(VCHIQ_ARM_STATE_T *arm_state) write_lock_bh(&arm_state->susp_res_lock); resume_count++; } + /* TODO: reinit_completion */ INIT_COMPLETION(arm_state->resume_blocker); arm_state->resume_blocked = 1; diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.h b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.h index e514a7f6119b..c7e9ae72dfbe 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.h +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.h @@ -1,4 +1,5 @@ /** + * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved. * Copyright (c) 2010-2012 Broadcom. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -153,6 +154,9 @@ vchiq_check_resume(VCHIQ_STATE_T *state); extern void vchiq_check_suspend(VCHIQ_STATE_T *state); +VCHIQ_STATUS_T +vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle); + extern VCHIQ_STATUS_T vchiq_platform_suspend(VCHIQ_STATE_T *state); @@ -180,21 +184,32 @@ vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, extern VCHIQ_STATUS_T vchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service); -void +#ifdef notyet +extern VCHIQ_DEBUGFS_NODE_T * +vchiq_instance_get_debugfs_node(VCHIQ_INSTANCE_T instance); +#endif + +extern int +vchiq_instance_get_use_count(VCHIQ_INSTANCE_T instance); + +extern int +vchiq_instance_get_pid(VCHIQ_INSTANCE_T instance); + +extern int +vchiq_instance_get_trace(VCHIQ_INSTANCE_T instance); + +extern void +vchiq_instance_set_trace(VCHIQ_INSTANCE_T instance, int trace); + +extern void set_suspend_state(VCHIQ_ARM_STATE_T *arm_state, enum vc_suspend_status new_state); -void +extern void set_resume_state(VCHIQ_ARM_STATE_T *arm_state, enum vc_resume_status new_state); -void +extern void start_suspend_timer(VCHIQ_ARM_STATE_T *arm_state); -extern int vchiq_proc_init(void); -extern void vchiq_proc_deinit(void); -extern struct proc_dir_entry *vchiq_proc_top(void); -extern struct proc_dir_entry *vchiq_clients_top(void); - - #endif /* VCHIQ_ARM_H */ diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_cfg.h b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_cfg.h index 493c86c34957..d2797db702f9 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_cfg.h +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_cfg.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2012 Broadcom. All rights reserved. + * Copyright (c) 2010-2014 Broadcom. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -36,11 +36,20 @@ #define VCHIQ_MAGIC VCHIQ_MAKE_FOURCC('V', 'C', 'H', 'I') /* The version of VCHIQ - change with any non-trivial change */ -#define VCHIQ_VERSION 6 +#define VCHIQ_VERSION 8 /* The minimum compatible version - update to match VCHIQ_VERSION with any ** incompatible change */ #define VCHIQ_VERSION_MIN 3 +/* The version that introduced the VCHIQ_IOC_LIB_VERSION ioctl */ +#define VCHIQ_VERSION_LIB_VERSION 7 + +/* The version that introduced the VCHIQ_IOC_CLOSE_DELIVERED ioctl */ +#define VCHIQ_VERSION_CLOSE_DELIVERED 7 + +/* The version that made it safe to use SYNCHRONOUS mode */ +#define VCHIQ_VERSION_SYNCHRONOUS_MODE 8 + #define VCHIQ_MAX_STATES 1 #define VCHIQ_MAX_SERVICES 4096 #define VCHIQ_MAX_SLOTS 128 diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_connected.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_connected.c index 0bc6c587754f..928e454031da 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_connected.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_connected.c @@ -33,6 +33,7 @@ #include "vchiq_connected.h" #include "vchiq_core.h" +#include "vchiq_killable.h" #define MAX_CALLBACKS 10 diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_connected.h b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_connected.h index e4cfdcc8aab2..863b3e335c1a 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_connected.h +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_connected.h @@ -48,4 +48,3 @@ void vchiq_add_connected_callback(VCHIQ_CONNECTED_CALLBACK_T callback); void vchiq_call_connected_callbacks(void); #endif /* VCHIQ_CONNECTED_H */ - diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.c index 633fd869b5cc..2ded208bae35 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.c @@ -32,6 +32,7 @@ */ #include "vchiq_core.h" +#include "vchiq_killable.h" #define VCHIQ_SLOT_HANDLER_STACK 8192 @@ -47,9 +48,12 @@ #define SLOT_QUEUE_INDEX_FROM_POS(pos) \ ((int)((unsigned int)(pos) / VCHIQ_SLOT_SIZE)) - #define BULK_INDEX(x) (x & (VCHIQ_NUM_SERVICE_BULKS - 1)) +#define SRVTRACE_LEVEL(srv) \ + (((srv) && (srv)->trace) ? VCHIQ_LOG_TRACE : vchiq_core_msg_log_level) +#define SRVTRACE_ENABLED(srv, lev) \ + (((srv) && (srv)->trace) || (vchiq_core_msg_log_level >= (lev))) struct vchiq_open_payload { int fourcc; @@ -62,6 +66,13 @@ struct vchiq_openack_payload { short version; }; +enum +{ + QMFLAGS_IS_BLOCKING = (1 << 0), + QMFLAGS_NO_MUTEX_LOCK = (1 << 1), + QMFLAGS_NO_MUTEX_UNLOCK = (1 << 2) +}; + /* we require this for consistency between endpoints */ vchiq_static_assert(sizeof(VCHIQ_HEADER_T) == 8); vchiq_static_assert(IS_POW2(sizeof(VCHIQ_HEADER_T))); @@ -230,6 +241,31 @@ find_service_for_instance(VCHIQ_INSTANCE_T instance, return service; } +VCHIQ_SERVICE_T * +find_closed_service_for_instance(VCHIQ_INSTANCE_T instance, + VCHIQ_SERVICE_HANDLE_T handle) { + VCHIQ_SERVICE_T *service; + + spin_lock(&service_spinlock); + service = handle_to_service(handle); + if (service && + ((service->srvstate == VCHIQ_SRVSTATE_FREE) || + (service->srvstate == VCHIQ_SRVSTATE_CLOSED)) && + (service->handle == handle) && + (service->instance == instance)) { + BUG_ON(service->ref_count == 0); + service->ref_count++; + } else + service = NULL; + spin_unlock(&service_spinlock); + + if (!service) + vchiq_log_info(vchiq_core_log_level, + "Invalid service handle 0x%x", handle); + + return service; +} + VCHIQ_SERVICE_T * next_service_by_instance(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance, int *pidx) @@ -726,7 +762,7 @@ process_free_queue(VCHIQ_STATE_T *state) static VCHIQ_STATUS_T queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, int msgid, const VCHIQ_ELEMENT_T *elements, - int count, int size, int is_blocking) + int count, int size, int flags) { VCHIQ_SHARED_STATE_T *local; VCHIQ_SERVICE_QUOTA_T *service_quota = NULL; @@ -741,7 +777,7 @@ queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, WARN_ON(!(stride <= VCHIQ_SLOT_SIZE)); - if ((type != VCHIQ_MSG_RESUME) && + if (!(flags & QMFLAGS_NO_MUTEX_LOCK) && (lmutex_lock_interruptible(&state->slot_mutex) != 0)) return VCHIQ_RETRY; @@ -749,6 +785,8 @@ queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, int tx_end_index; BUG_ON(!service); + BUG_ON((flags & (QMFLAGS_NO_MUTEX_LOCK | + QMFLAGS_NO_MUTEX_UNLOCK)) != 0); if (service->closing) { /* The service has been closed */ @@ -824,12 +862,16 @@ queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, spin_unlock("a_spinlock); } - header = reserve_space(state, stride, is_blocking); + header = reserve_space(state, stride, flags & QMFLAGS_IS_BLOCKING); if (!header) { if (service) VCHIQ_SERVICE_STATS_INC(service, slot_stalls); - lmutex_unlock(&state->slot_mutex); + /* In the event of a failure, return the mutex to the + state it was in */ + if (!(flags & QMFLAGS_NO_MUTEX_LOCK)) + lmutex_unlock(&state->slot_mutex); + return VCHIQ_RETRY; } @@ -847,6 +889,8 @@ queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, VCHIQ_MSG_DSTPORT(msgid)); BUG_ON(!service); + BUG_ON((flags & (QMFLAGS_NO_MUTEX_LOCK | + QMFLAGS_NO_MUTEX_UNLOCK)) != 0); for (i = 0, pos = 0; i < (unsigned int)count; pos += elements[i++].size) @@ -861,11 +905,11 @@ queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, return VCHIQ_ERROR; } if (i == 0) { - if (vchiq_core_msg_log_level >= - VCHIQ_LOG_INFO) + if (SRVTRACE_ENABLED(service, + VCHIQ_LOG_INFO)) vchiq_log_dump_mem("Sent", 0, header->data + pos, - min(64, + min(64u, elements[0].size)); } } @@ -928,7 +972,7 @@ queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, ? service->base.fourcc : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); - vchiq_log_info(vchiq_core_msg_log_level, + vchiq_log_info(SRVTRACE_LEVEL(service), "Sent Msg %s(%u) to %c%c%c%c s:%u d:%d len:%d", msg_type_str(VCHIQ_MSG_TYPE(msgid)), VCHIQ_MSG_TYPE(msgid), @@ -948,7 +992,7 @@ queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, if (service && (type == VCHIQ_MSG_CLOSE)) vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSESENT); - if (VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_PAUSE) + if (!(flags & QMFLAGS_NO_MUTEX_UNLOCK)) lmutex_unlock(&state->slot_mutex); remote_event_signal(&state->remote->trigger); @@ -1013,7 +1057,7 @@ queue_message_sync(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, VCHIQ_LOG_TRACE) vchiq_log_dump_mem("Sent Sync", 0, header->data + pos, - min(64, + min(64u, elements[0].size)); } } @@ -1320,11 +1364,11 @@ resolve_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue) vchiq_transfer_bulk(bulk); lmutex_unlock(&state->bulk_transfer_mutex); - if (vchiq_core_msg_log_level >= VCHIQ_LOG_INFO) { + if (SRVTRACE_ENABLED(service, VCHIQ_LOG_INFO)) { const char *header = (queue == &service->bulk_tx) ? "Send Bulk to" : "Recv Bulk from"; if (bulk->actual != VCHIQ_BULK_ACTUAL_ABORTED) - vchiq_log_info(vchiq_core_msg_log_level, + vchiq_log_info(SRVTRACE_LEVEL(service), "%s %c%c%c%c d:%d len:%d %x<->%x", header, VCHIQ_FOURCC_AS_4CHARS( @@ -1334,7 +1378,7 @@ resolve_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue) (unsigned int)bulk->data, (unsigned int)bulk->remote_data); else - vchiq_log_info(vchiq_core_msg_log_level, + vchiq_log_info(SRVTRACE_LEVEL(service), "%s %c%c%c%c d:%d ABORTED - tx len:%d," " rx len:%d %x<->%x", header, @@ -1381,7 +1425,7 @@ abort_outstanding_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue) if (queue->process != queue->local_insert) { vchiq_complete_bulk(bulk); - vchiq_log_info(vchiq_core_msg_log_level, + vchiq_log_info(SRVTRACE_LEVEL(service), "%s %c%c%c%c d:%d ABORTED - tx len:%d, " "rx len:%d", is_tx ? "Send Bulk to" : "Recv Bulk from", @@ -1488,10 +1532,10 @@ parse_open(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header) if (service) { /* A matching service exists */ - short v = payload->version; + short version = payload->version; short version_min = payload->version_min; if ((service->version < version_min) || - (v < service->version_min)) { + (version < service->version_min)) { /* Version mismatch */ vchiq_loud_error_header(); vchiq_loud_error("%d: service %d (%c%c%c%c) " @@ -1500,12 +1544,13 @@ parse_open(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header) state->id, service->localport, VCHIQ_FOURCC_AS_4CHARS(fourcc), service->version, service->version_min, - v, version_min); + version, version_min); vchiq_loud_error_footer(); unlock_service(service); + service = NULL; goto fail_open; } - service->peer_version = v; + service->peer_version = version; if (service->srvstate == VCHIQ_SRVSTATE_LISTENING) { struct vchiq_openack_payload ack_payload = { @@ -1516,8 +1561,14 @@ parse_open(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header) sizeof(ack_payload) }; + if (state->version_common < + VCHIQ_VERSION_SYNCHRONOUS_MODE) + service->sync = 0; + /* Acknowledge the OPEN */ - if (service->sync) { + if (service->sync && + (state->version_common >= + VCHIQ_VERSION_SYNCHRONOUS_MODE)) { if (queue_message_sync(state, NULL, VCHIQ_MAKE_MSG( VCHIQ_MSG_OPENACK, @@ -1631,9 +1682,11 @@ parse_rx_slots(VCHIQ_STATE_T *state) case VCHIQ_MSG_BULK_RX_DONE: case VCHIQ_MSG_BULK_TX_DONE: service = find_service_by_port(state, localport); - if ((!service || service->remoteport != remoteport) && - (localport == 0) && - (type == VCHIQ_MSG_CLOSE)) { + if ((!service || + ((service->remoteport != remoteport) && + (service->remoteport != VCHIQ_PORT_FREE))) && + (localport == 0) && + (type == VCHIQ_MSG_CLOSE)) { /* This could be a CLOSE from a client which hadn't yet received the OPENACK - look for the connected service */ @@ -1665,13 +1718,13 @@ parse_rx_slots(VCHIQ_STATE_T *state) break; } - if (vchiq_core_msg_log_level >= VCHIQ_LOG_INFO) { + if (SRVTRACE_ENABLED(service, VCHIQ_LOG_INFO)) { int svc_fourcc; svc_fourcc = service ? service->base.fourcc : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); - vchiq_log_info(vchiq_core_msg_log_level, + vchiq_log_info(SRVTRACE_LEVEL(service), "Rcvd Msg %s(%u) from %c%c%c%c s:%d d:%d " "len:%d", msg_type_str(type), type, @@ -1741,7 +1794,7 @@ parse_rx_slots(VCHIQ_STATE_T *state) service->remoteport); break; case VCHIQ_MSG_DATA: - vchiq_log_trace(vchiq_core_log_level, + vchiq_log_info(vchiq_core_log_level, "%d: prs DATA@%x,%x (%d->%d)", state->id, (unsigned int)header, size, remoteport, localport); @@ -1769,6 +1822,8 @@ parse_rx_slots(VCHIQ_STATE_T *state) vchiq_log_info(vchiq_core_log_level, "%d: prs CONNECT@%x", state->id, (unsigned int)header); + state->version_common = ((VCHIQ_SLOT_ZERO_T *) + state->slot_data)->version; up(&state->connect); break; case VCHIQ_MSG_BULK_RX: @@ -1922,7 +1977,8 @@ parse_rx_slots(VCHIQ_STATE_T *state) /* Send a PAUSE in response */ if (queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0), - NULL, 0, 0, 0) == VCHIQ_RETRY) + NULL, 0, 0, QMFLAGS_NO_MUTEX_UNLOCK) + == VCHIQ_RETRY) goto bail_not_ready; if (state->is_master) pause_bulks(state); @@ -2021,7 +2077,9 @@ slot_handler_func(void *v) pause_bulks(state); if (queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0), - NULL, 0, 0, 0) != VCHIQ_RETRY) { + NULL, 0, 0, + QMFLAGS_NO_MUTEX_UNLOCK) + != VCHIQ_RETRY) { vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSE_SENT); } else { @@ -2039,7 +2097,8 @@ slot_handler_func(void *v) case VCHIQ_CONNSTATE_RESUMING: if (queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_RESUME, 0, 0), - NULL, 0, 0, 0) != VCHIQ_RETRY) { + NULL, 0, 0, QMFLAGS_NO_MUTEX_LOCK) + != VCHIQ_RETRY) { if (state->is_master) resume_bulks(state); vchiq_set_conn_state(state, @@ -2162,6 +2221,7 @@ sync_func(void *v) service->remoteport = remoteport; vchiq_set_service_state(service, VCHIQ_SRVSTATE_OPENSYNC); + service->sync = 1; up(&service->remove_event); } release_message_sync(state, header); @@ -2341,6 +2401,9 @@ vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero, return VCHIQ_ERROR; } + if (VCHIQ_VERSION < slot_zero->version) + slot_zero->version = VCHIQ_VERSION; + if (is_master) { local = &slot_zero->master; remote = &slot_zero->slave; @@ -2517,6 +2580,7 @@ vchiq_add_service_internal(VCHIQ_STATE_T *state, service->auto_close = 1; service->sync = 0; service->closing = 0; + service->trace = 0; atomic_set(&service->poll_flags, 0); service->version = params->version; service->version_min = params->version_min; @@ -2647,8 +2711,9 @@ vchiq_open_service_internal(VCHIQ_SERVICE_T *service, int client_id) vchiq_use_service_internal(service); status = queue_message(service->state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_OPEN, service->localport, 0), - &body, 1, sizeof(payload), 1); + &body, 1, sizeof(payload), QMFLAGS_IS_BLOCKING); if (status == VCHIQ_SUCCESS) { + /* Wait for the ACK/NAK */ if (down_interruptible(&service->remove_event) != 0) { status = VCHIQ_RETRY; vchiq_release_service_internal(service); @@ -2675,7 +2740,18 @@ release_service_messages(VCHIQ_SERVICE_T *service) int slot_last = state->remote->slot_last; int i; - /* Release any claimed messages */ + /* Release any claimed messages aimed at this service */ + + if (service->sync) { + VCHIQ_HEADER_T *header = + (VCHIQ_HEADER_T *)SLOT_DATA_FROM_INDEX(state, + state->remote->slot_sync); + if (VCHIQ_MSG_DSTPORT(header->msgid) == service->localport) + release_message_sync(state, header); + + return; + } + for (i = state->remote->slot_first; i <= slot_last; i++) { VCHIQ_SLOT_INFO_T *slot_info = SLOT_INFO_FROM_INDEX(state, i); @@ -2873,17 +2949,31 @@ vchiq_close_service_internal(VCHIQ_SERVICE_T *service, int close_recvd) (VCHIQ_MSG_CLOSE, service->localport, VCHIQ_MSG_DSTPORT(service->remoteport)), - NULL, 0, 0, 0); + NULL, 0, 0, QMFLAGS_NO_MUTEX_UNLOCK); if (status == VCHIQ_SUCCESS) { - if (!close_recvd) + if (!close_recvd) { + /* Change the state while the mutex is + still held */ + vchiq_set_service_state(service, + VCHIQ_SRVSTATE_CLOSESENT); + lmutex_unlock(&state->slot_mutex); + if (service->sync) + lmutex_unlock(&state->sync_mutex); break; + } } else if (service->srvstate == VCHIQ_SRVSTATE_OPENSYNC) { lmutex_unlock(&state->sync_mutex); break; } else break; + /* Change the state while the mutex is still held */ + vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSERECVD); + lmutex_unlock(&state->slot_mutex); + if (service->sync) + lmutex_unlock(&state->sync_mutex); + status = close_service_complete(service, VCHIQ_SRVSTATE_CLOSERECVD); break; @@ -2990,7 +3080,7 @@ vchiq_connect_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance) if (state->conn_state == VCHIQ_CONNSTATE_DISCONNECTED) { if (queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_CONNECT, 0, 0), NULL, 0, - 0, 1) == VCHIQ_RETRY) + 0, QMFLAGS_IS_BLOCKING) == VCHIQ_RETRY) return VCHIQ_RETRY; vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTING); @@ -3276,6 +3366,16 @@ vchiq_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, service->localport, service->remoteport, dir_char, size, (unsigned int)bulk->data, (unsigned int)userdata); + /* The slot mutex must be held when the service is being closed, so + claim it here to ensure that isn't happening */ + if (lmutex_lock_interruptible(&state->slot_mutex) != 0) { + status = VCHIQ_RETRY; + goto cancel_bulk_error_exit; + } + + if (service->srvstate != VCHIQ_SRVSTATE_OPEN) + goto unlock_both_error_exit; + if (state->is_master) { queue->local_insert++; if (resolve_bulks(service, queue)) @@ -3289,14 +3389,17 @@ vchiq_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, status = queue_message(state, NULL, VCHIQ_MAKE_MSG(dir_msgtype, service->localport, service->remoteport), - &element, 1, sizeof(payload), 1); + &element, 1, sizeof(payload), + QMFLAGS_IS_BLOCKING | + QMFLAGS_NO_MUTEX_LOCK | + QMFLAGS_NO_MUTEX_UNLOCK); if (status != VCHIQ_SUCCESS) { - vchiq_complete_bulk(bulk); - goto unlock_error_exit; + goto unlock_both_error_exit; } queue->local_insert++; } + lmutex_unlock(&state->slot_mutex); lmutex_unlock(&service->bulk_mutex); vchiq_log_trace(vchiq_core_log_level, @@ -3320,6 +3423,10 @@ vchiq_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, return status; +unlock_both_error_exit: + lmutex_unlock(&state->slot_mutex); +cancel_bulk_error_exit: + vchiq_complete_bulk(bulk); unlock_error_exit: lmutex_unlock(&service->bulk_mutex); @@ -3530,6 +3637,11 @@ vchiq_set_service_option(VCHIQ_SERVICE_HANDLE_T handle, } break; + case VCHIQ_SERVICE_OPTION_TRACE: + service->trace = value; + status = VCHIQ_SUCCESS; + break; + default: break; } diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.h b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.h index fb50e85f2d88..754c9f669240 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.h +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.h @@ -295,6 +295,7 @@ typedef struct vchiq_service_struct { char auto_close; char sync; char closing; + char trace; atomic_t poll_flags; short version; short version_min; @@ -402,6 +403,7 @@ struct vchiq_state_struct { int initialised; VCHIQ_CONNSTATE_T conn_state; int is_master; + short version_common; VCHIQ_SHARED_STATE_T *local; VCHIQ_SHARED_STATE_T *remote; @@ -605,6 +607,10 @@ extern VCHIQ_SERVICE_T * find_service_for_instance(VCHIQ_INSTANCE_T instance, VCHIQ_SERVICE_HANDLE_T handle); +extern VCHIQ_SERVICE_T * +find_closed_service_for_instance(VCHIQ_INSTANCE_T instance, + VCHIQ_SERVICE_HANDLE_T handle); + extern VCHIQ_SERVICE_T * next_service_by_instance(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance, int *pidx); diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_debugfs.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_debugfs.c new file mode 100644 index 000000000000..7e032130d967 --- /dev/null +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_debugfs.c @@ -0,0 +1,383 @@ +/** + * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved. + * Copyright (c) 2010-2012 Broadcom. 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, + * without modification. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2, as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 +#include "vchiq_core.h" +#include "vchiq_arm.h" +#include "vchiq_debugfs.h" + +#ifdef CONFIG_DEBUG_FS + +/**************************************************************************** +* +* log category entries +* +***************************************************************************/ +#define DEBUGFS_WRITE_BUF_SIZE 256 + +#define VCHIQ_LOG_ERROR_STR "error" +#define VCHIQ_LOG_WARNING_STR "warning" +#define VCHIQ_LOG_INFO_STR "info" +#define VCHIQ_LOG_TRACE_STR "trace" + + +/* Top-level debug info */ +struct vchiq_debugfs_info { + /* Global 'vchiq' debugfs entry used by all instances */ + struct dentry *vchiq_cfg_dir; + + /* one entry per client process */ + struct dentry *clients; + + /* log categories */ + struct dentry *log_categories; +}; + +static struct vchiq_debugfs_info debugfs_info; + +/* Log category debugfs entries */ +struct vchiq_debugfs_log_entry { + const char *name; + int *plevel; + struct dentry *dir; +}; + +static struct vchiq_debugfs_log_entry vchiq_debugfs_log_entries[] = { + { "core", &vchiq_core_log_level }, + { "msg", &vchiq_core_msg_log_level }, + { "sync", &vchiq_sync_log_level }, + { "susp", &vchiq_susp_log_level }, + { "arm", &vchiq_arm_log_level }, +}; +static int n_log_entries = + sizeof(vchiq_debugfs_log_entries)/sizeof(vchiq_debugfs_log_entries[0]); + + +static struct dentry *vchiq_clients_top(void); +static struct dentry *vchiq_debugfs_top(void); + +static int debugfs_log_show(struct seq_file *f, void *offset) +{ + int *levp = f->private; + char *log_value = NULL; + + switch (*levp) { + case VCHIQ_LOG_ERROR: + log_value = VCHIQ_LOG_ERROR_STR; + break; + case VCHIQ_LOG_WARNING: + log_value = VCHIQ_LOG_WARNING_STR; + break; + case VCHIQ_LOG_INFO: + log_value = VCHIQ_LOG_INFO_STR; + break; + case VCHIQ_LOG_TRACE: + log_value = VCHIQ_LOG_TRACE_STR; + break; + default: + break; + } + + seq_printf(f, "%s\n", log_value ? log_value : "(null)"); + + return 0; +} + +static int debugfs_log_open(struct inode *inode, struct file *file) +{ + return single_open(file, debugfs_log_show, inode->i_private); +} + +static int debugfs_log_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct seq_file *f = (struct seq_file *)file->private_data; + int *levp = f->private; + char kbuf[DEBUGFS_WRITE_BUF_SIZE + 1]; + + memset(kbuf, 0, DEBUGFS_WRITE_BUF_SIZE + 1); + if (count >= DEBUGFS_WRITE_BUF_SIZE) + count = DEBUGFS_WRITE_BUF_SIZE; + + if (copy_from_user(kbuf, buffer, count) != 0) + return -EFAULT; + kbuf[count - 1] = 0; + + if (strncmp("error", kbuf, strlen("error")) == 0) + *levp = VCHIQ_LOG_ERROR; + else if (strncmp("warning", kbuf, strlen("warning")) == 0) + *levp = VCHIQ_LOG_WARNING; + else if (strncmp("info", kbuf, strlen("info")) == 0) + *levp = VCHIQ_LOG_INFO; + else if (strncmp("trace", kbuf, strlen("trace")) == 0) + *levp = VCHIQ_LOG_TRACE; + else + *levp = VCHIQ_LOG_DEFAULT; + + *ppos += count; + + return count; +} + +static const struct file_operations debugfs_log_fops = { + .owner = THIS_MODULE, + .open = debugfs_log_open, + .write = debugfs_log_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* create an entry under /vchiq/log for each log category */ +static int vchiq_debugfs_create_log_entries(struct dentry *top) +{ + struct dentry *dir; + size_t i; + int ret = 0; + dir = debugfs_create_dir("log", vchiq_debugfs_top()); + if (!dir) + return -ENOMEM; + debugfs_info.log_categories = dir; + + for (i = 0; i < n_log_entries; i++) { + void *levp = (void *)vchiq_debugfs_log_entries[i].plevel; + dir = debugfs_create_file(vchiq_debugfs_log_entries[i].name, + 0644, + debugfs_info.log_categories, + levp, + &debugfs_log_fops); + if (!dir) { + ret = -ENOMEM; + break; + } + + vchiq_debugfs_log_entries[i].dir = dir; + } + return ret; +} + +static int debugfs_usecount_show(struct seq_file *f, void *offset) +{ + VCHIQ_INSTANCE_T instance = f->private; + int use_count; + + use_count = vchiq_instance_get_use_count(instance); + seq_printf(f, "%d\n", use_count); + + return 0; +} + +static int debugfs_usecount_open(struct inode *inode, struct file *file) +{ + return single_open(file, debugfs_usecount_show, inode->i_private); +} + +static const struct file_operations debugfs_usecount_fops = { + .owner = THIS_MODULE, + .open = debugfs_usecount_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int debugfs_trace_show(struct seq_file *f, void *offset) +{ + VCHIQ_INSTANCE_T instance = f->private; + int trace; + + trace = vchiq_instance_get_trace(instance); + seq_printf(f, "%s\n", trace ? "Y" : "N"); + + return 0; +} + +static int debugfs_trace_open(struct inode *inode, struct file *file) +{ + return single_open(file, debugfs_trace_show, inode->i_private); +} + +static int debugfs_trace_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct seq_file *f = (struct seq_file *)file->private_data; + VCHIQ_INSTANCE_T instance = f->private; + char firstchar; + + if (copy_from_user(&firstchar, buffer, 1) != 0) + return -EFAULT; + + switch (firstchar) { + case 'Y': + case 'y': + case '1': + vchiq_instance_set_trace(instance, 1); + break; + case 'N': + case 'n': + case '0': + vchiq_instance_set_trace(instance, 0); + break; + default: + break; + } + + *ppos += count; + + return count; +} + +static const struct file_operations debugfs_trace_fops = { + .owner = THIS_MODULE, + .open = debugfs_trace_open, + .write = debugfs_trace_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* add an instance (process) to the debugfs entries */ +int vchiq_debugfs_add_instance(VCHIQ_INSTANCE_T instance) +{ + char pidstr[16]; + struct dentry *top, *use_count, *trace; + struct dentry *clients = vchiq_clients_top(); + + snprintf(pidstr, sizeof(pidstr), "%d", + vchiq_instance_get_pid(instance)); + + top = debugfs_create_dir(pidstr, clients); + if (!top) + goto fail_top; + + use_count = debugfs_create_file("use_count", + 0444, top, + instance, + &debugfs_usecount_fops); + if (!use_count) + goto fail_use_count; + + trace = debugfs_create_file("trace", + 0644, top, + instance, + &debugfs_trace_fops); + if (!trace) + goto fail_trace; + + vchiq_instance_get_debugfs_node(instance)->dentry = top; + + return 0; + +fail_trace: + debugfs_remove(use_count); +fail_use_count: + debugfs_remove(top); +fail_top: + return -ENOMEM; +} + +void vchiq_debugfs_remove_instance(VCHIQ_INSTANCE_T instance) +{ + VCHIQ_DEBUGFS_NODE_T *node = vchiq_instance_get_debugfs_node(instance); + debugfs_remove_recursive(node->dentry); +} + + +int vchiq_debugfs_init(void) +{ + BUG_ON(debugfs_info.vchiq_cfg_dir != NULL); + + debugfs_info.vchiq_cfg_dir = debugfs_create_dir("vchiq", NULL); + if (debugfs_info.vchiq_cfg_dir == NULL) + goto fail; + + debugfs_info.clients = debugfs_create_dir("clients", + vchiq_debugfs_top()); + if (!debugfs_info.clients) + goto fail; + + if (vchiq_debugfs_create_log_entries(vchiq_debugfs_top()) != 0) + goto fail; + + return 0; + +fail: + vchiq_debugfs_deinit(); + vchiq_log_error(vchiq_arm_log_level, + "%s: failed to create debugfs directory", + __func__); + + return -ENOMEM; +} + +/* remove all the debugfs entries */ +void vchiq_debugfs_deinit(void) +{ + debugfs_remove_recursive(vchiq_debugfs_top()); +} + +static struct dentry *vchiq_clients_top(void) +{ + return debugfs_info.clients; +} + +static struct dentry *vchiq_debugfs_top(void) +{ + BUG_ON(debugfs_info.vchiq_cfg_dir == NULL); + return debugfs_info.vchiq_cfg_dir; +} + +#else /* CONFIG_DEBUG_FS */ + +int vchiq_debugfs_init(void) +{ + return 0; +} + +void vchiq_debugfs_deinit(void) +{ +} + +int vchiq_debugfs_add_instance(VCHIQ_INSTANCE_T instance) +{ + return 0; +} + +void vchiq_debugfs_remove_instance(VCHIQ_INSTANCE_T instance) +{ +} + +#endif /* CONFIG_DEBUG_FS */ diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_debugfs.h b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_debugfs.h new file mode 100644 index 000000000000..4d6a3788e9c5 --- /dev/null +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_debugfs.h @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. 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, + * without modification. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2, as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +#ifndef VCHIQ_DEBUGFS_H +#define VCHIQ_DEBUGFS_H + +#include "vchiq_core.h" + +typedef struct vchiq_debugfs_node_struct +{ + struct dentry *dentry; +} VCHIQ_DEBUGFS_NODE_T; + +int vchiq_debugfs_init(void); + +void vchiq_debugfs_deinit(void); + +int vchiq_debugfs_add_instance(VCHIQ_INSTANCE_T instance); + +void vchiq_debugfs_remove_instance(VCHIQ_INSTANCE_T instance); + +#endif /* VCHIQ_DEBUGFS_H */ diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_if.h b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_if.h index 6a95a67a833a..a5fb12863c73 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_if.h +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_if.h @@ -74,7 +74,8 @@ typedef enum { VCHIQ_SERVICE_OPTION_AUTOCLOSE, VCHIQ_SERVICE_OPTION_SLOT_QUOTA, VCHIQ_SERVICE_OPTION_MESSAGE_QUOTA, - VCHIQ_SERVICE_OPTION_SYNCHRONOUS + VCHIQ_SERVICE_OPTION_SYNCHRONOUS, + VCHIQ_SERVICE_OPTION_TRACE } VCHIQ_SERVICE_OPTION_T; typedef struct vchiq_header_struct { diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_ioctl.h b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_ioctl.h index 13103c5c3632..617479eff136 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_ioctl.h +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_ioctl.h @@ -123,6 +123,8 @@ typedef struct { _IOW(VCHIQ_IOC_MAGIC, 14, VCHIQ_SET_SERVICE_OPTION_T) #define VCHIQ_IOC_DUMP_PHYS_MEM \ _IOW(VCHIQ_IOC_MAGIC, 15, VCHIQ_DUMP_MEM_T) -#define VCHIQ_IOC_MAX 15 +#define VCHIQ_IOC_LIB_VERSION _IO(VCHIQ_IOC_MAGIC, 16) +#define VCHIQ_IOC_CLOSE_DELIVERED _IO(VCHIQ_IOC_MAGIC, 17) +#define VCHIQ_IOC_MAX 17 #endif diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kern_lib.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kern_lib.c index 6edbb67d8e0a..1f849a09d854 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kern_lib.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kern_lib.c @@ -35,6 +35,7 @@ #include "vchiq_core.h" #include "vchiq_arm.h" +#include "vchiq_killable.h" /* ---- Public Variables ------------------------------------------------- */ diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_killable.h b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_killable.h new file mode 100644 index 000000000000..9385dbbfeedf --- /dev/null +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_killable.h @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2010-2012 Broadcom. 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, + * without modification. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2, as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +#ifndef VCHIQ_KILLABLE_H +#define VCHIQ_KILLABLE_H + +#ifdef notyet +#include +#include + +#define SHUTDOWN_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGTRAP) | sigmask(SIGSTOP) | sigmask(SIGCONT)) + +static inline int __must_check down_interruptible_killable(struct semaphore *sem) +{ + /* Allow interception of killable signals only. We don't want to be interrupted by harmless signals like SIGALRM */ + int ret; + sigset_t blocked, oldset; + siginitsetinv(&blocked, SHUTDOWN_SIGS); + sigprocmask(SIG_SETMASK, &blocked, &oldset); + ret = down_interruptible(sem); + sigprocmask(SIG_SETMASK, &oldset, NULL); + return ret; +} +#define down_interruptible down_interruptible_killable + + +static inline int __must_check mutex_lock_interruptible_killable(struct mutex *lock) +{ + /* Allow interception of killable signals only. We don't want to be interrupted by harmless signals like SIGALRM */ + int ret; + sigset_t blocked, oldset; + siginitsetinv(&blocked, SHUTDOWN_SIGS); + sigprocmask(SIG_SETMASK, &blocked, &oldset); + ret = mutex_lock_interruptible(lock); + sigprocmask(SIG_SETMASK, &oldset, NULL); + return ret; +} +#define mutex_lock_interruptible mutex_lock_interruptible_killable + +#endif + +#endif diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c index 9f282c7f77a2..04fc399de869 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c @@ -88,6 +88,7 @@ void vchiq_exit(void); int vchiq_init(void); extern VCHIQ_STATE_T g_state; +extern int g_cache_line_size; static void bcm_vchiq_intr(void *arg) @@ -133,6 +134,8 @@ static int bcm_vchiq_attach(device_t dev) { struct bcm_vchiq_softc *sc = device_get_softc(dev); + phandle_t node; + pcell_t cell; int rid = 0; if (bcm_vchiq_sc != NULL) @@ -154,6 +157,10 @@ bcm_vchiq_attach(device_t dev) return (ENXIO); } + node = ofw_bus_get_node(dev); + if ((OF_getencprop(node, "cache-line-size", &cell, sizeof(cell))) > 0) + g_cache_line_size = cell; + vchiq_core_initialize(); /* Setup and enable the timer */ diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_pagelist.h b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_pagelist.h index 07717d7bf358..72c362464cc2 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_pagelist.h +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_pagelist.h @@ -37,8 +37,6 @@ #ifndef PAGE_SIZE #define PAGE_SIZE 4096 #endif -#undef CACHE_LINE_SIZE -#define CACHE_LINE_SIZE 32 #define PAGELIST_WRITE 0 #define PAGELIST_READ 1 #define PAGELIST_READ_WITH_FRAGMENTS 2 @@ -51,9 +49,4 @@ typedef struct pagelist_struct { pages at consecutive addresses. */ } PAGELIST_T; -typedef struct fragments_struct { - char headbuf[CACHE_LINE_SIZE]; - char tailbuf[CACHE_LINE_SIZE]; -} FRAGMENTS_T; - #endif /* VCHIQ_PAGELIST_H */ diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_proc.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_proc.c deleted file mode 100644 index 863c285dd978..000000000000 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_proc.c +++ /dev/null @@ -1,240 +0,0 @@ -/** - * Copyright (c) 2010-2012 Broadcom. 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, - * without modification. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The names of the above-listed copyright holders may not be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2, as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 -#include "vchiq_core.h" -#include "vchiq_arm.h" - -struct vchiq_proc_info { - /* Global 'vc' proc entry used by all instances */ - struct proc_dir_entry *vc_cfg_dir; - - /* one entry per client process */ - struct proc_dir_entry *clients; - - /* log categories */ - struct proc_dir_entry *log_categories; -}; - -static struct vchiq_proc_info proc_info; - -struct proc_dir_entry *vchiq_proc_top(void) -{ - BUG_ON(proc_info.vc_cfg_dir == NULL); - return proc_info.vc_cfg_dir; -} - -/**************************************************************************** -* -* log category entries -* -***************************************************************************/ -#define PROC_WRITE_BUF_SIZE 256 - -#define VCHIQ_LOG_ERROR_STR "error" -#define VCHIQ_LOG_WARNING_STR "warning" -#define VCHIQ_LOG_INFO_STR "info" -#define VCHIQ_LOG_TRACE_STR "trace" - -static int log_cfg_read(char *buffer, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - int len = 0; - char *log_value = NULL; - - switch (*((int *)data)) { - case VCHIQ_LOG_ERROR: - log_value = VCHIQ_LOG_ERROR_STR; - break; - case VCHIQ_LOG_WARNING: - log_value = VCHIQ_LOG_WARNING_STR; - break; - case VCHIQ_LOG_INFO: - log_value = VCHIQ_LOG_INFO_STR; - break; - case VCHIQ_LOG_TRACE: - log_value = VCHIQ_LOG_TRACE_STR; - break; - default: - break; - } - - len += snprintf(buffer + len, count - len, - "%s\n", - log_value ? log_value : "(null)"); - - return len; -} - - -static int log_cfg_write(struct file *file, - const char __user *buffer, - unsigned long count, - void *data) -{ - int *log_module = data; - char kbuf[PROC_WRITE_BUF_SIZE + 1]; - - (void)file; - - memset(kbuf, 0, PROC_WRITE_BUF_SIZE + 1); - if (count >= PROC_WRITE_BUF_SIZE) - count = PROC_WRITE_BUF_SIZE; - - if (copy_from_user(kbuf, - buffer, - count) != 0) - return -EFAULT; - kbuf[count - 1] = 0; - - if (strncmp("error", kbuf, strlen("error")) == 0) - *log_module = VCHIQ_LOG_ERROR; - else if (strncmp("warning", kbuf, strlen("warning")) == 0) - *log_module = VCHIQ_LOG_WARNING; - else if (strncmp("info", kbuf, strlen("info")) == 0) - *log_module = VCHIQ_LOG_INFO; - else if (strncmp("trace", kbuf, strlen("trace")) == 0) - *log_module = VCHIQ_LOG_TRACE; - else - *log_module = VCHIQ_LOG_DEFAULT; - - return count; -} - -/* Log category proc entries */ -struct vchiq_proc_log_entry { - const char *name; - int *plevel; - struct proc_dir_entry *dir; -}; - -static struct vchiq_proc_log_entry vchiq_proc_log_entries[] = { - { "core", &vchiq_core_log_level }, - { "msg", &vchiq_core_msg_log_level }, - { "sync", &vchiq_sync_log_level }, - { "susp", &vchiq_susp_log_level }, - { "arm", &vchiq_arm_log_level }, -}; -static int n_log_entries = - sizeof(vchiq_proc_log_entries)/sizeof(vchiq_proc_log_entries[0]); - -/* create an entry under /proc/vc/log for each log category */ -static int vchiq_proc_create_log_entries(struct proc_dir_entry *top) -{ - struct proc_dir_entry *dir; - size_t i; - int ret = 0; - - dir = proc_mkdir("log", proc_info.vc_cfg_dir); - if (!dir) - return -ENOMEM; - proc_info.log_categories = dir; - - for (i = 0; i < n_log_entries; i++) { - dir = create_proc_entry(vchiq_proc_log_entries[i].name, - 0644, - proc_info.log_categories); - if (!dir) { - ret = -ENOMEM; - break; - } - - dir->read_proc = &log_cfg_read; - dir->write_proc = &log_cfg_write; - dir->data = (void *)vchiq_proc_log_entries[i].plevel; - - vchiq_proc_log_entries[i].dir = dir; - } - return ret; -} - - -int vchiq_proc_init(void) -{ - BUG_ON(proc_info.vc_cfg_dir != NULL); - - proc_info.vc_cfg_dir = proc_mkdir("vc", NULL); - if (proc_info.vc_cfg_dir == NULL) - goto fail; - - proc_info.clients = proc_mkdir("clients", - proc_info.vc_cfg_dir); - if (!proc_info.clients) - goto fail; - - if (vchiq_proc_create_log_entries(proc_info.vc_cfg_dir) != 0) - goto fail; - - return 0; - -fail: - vchiq_proc_deinit(); - vchiq_log_error(vchiq_arm_log_level, - "%s: failed to create proc directory", - __func__); - - return -ENOMEM; -} - -/* remove all the proc entries */ -void vchiq_proc_deinit(void) -{ - /* log category entries */ - if (proc_info.log_categories) { - size_t i; - for (i = 0; i < n_log_entries; i++) - if (vchiq_proc_log_entries[i].dir) - remove_proc_entry( - vchiq_proc_log_entries[i].name, - proc_info.log_categories); - - remove_proc_entry(proc_info.log_categories->name, - proc_info.vc_cfg_dir); - } - if (proc_info.clients) - remove_proc_entry(proc_info.clients->name, - proc_info.vc_cfg_dir); - if (proc_info.vc_cfg_dir) - remove_proc_entry(proc_info.vc_cfg_dir->name, NULL); -} - -struct proc_dir_entry *vchiq_clients_top(void) -{ - return proc_info.clients; -} - diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_shim.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_shim.c index 94ad46ea833f..cc8ef2e071f8 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_shim.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_shim.c @@ -403,6 +403,7 @@ int32_t vchi_held_msg_release(VCHI_HELD_MSG_T *message) return 0; } +EXPORT_SYMBOL(vchi_held_msg_release); /*********************************************************** * Name: vchi_msg_hold @@ -448,13 +449,12 @@ int32_t vchi_msg_hold(VCHI_SERVICE_HANDLE_T handle, return 0; } +EXPORT_SYMBOL(vchi_msg_hold); /*********************************************************** * Name: vchi_initialise * * Arguments: VCHI_INSTANCE_T *instance_handle - * VCHI_CONNECTION_T **connections - * const uint32_t num_connections * * Description: Initialises the hardware but does not transmit anything * When run as a Host App this will be called twice hence the need @@ -725,6 +725,36 @@ int32_t vchi_service_destroy(const VCHI_SERVICE_HANDLE_T handle) } EXPORT_SYMBOL(vchi_service_destroy); +int32_t vchi_service_set_option(const VCHI_SERVICE_HANDLE_T handle, + VCHI_SERVICE_OPTION_T option, + int value) +{ + int32_t ret = -1; + SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle; + VCHIQ_SERVICE_OPTION_T vchiq_option; + switch (option) { + case VCHI_SERVICE_OPTION_TRACE: + vchiq_option = VCHIQ_SERVICE_OPTION_TRACE; + break; + case VCHI_SERVICE_OPTION_SYNCHRONOUS: + vchiq_option = VCHIQ_SERVICE_OPTION_SYNCHRONOUS; + break; + default: + service = NULL; + break; + } + if (service) { + VCHIQ_STATUS_T status = + vchiq_set_service_option(service->handle, + vchiq_option, + value); + + ret = vchiq_status_to_vchi(status); + } + return ret; +} +EXPORT_SYMBOL(vchi_service_set_option); + int32_t vchi_get_peer_version( const VCHI_SERVICE_HANDLE_T handle, short *peer_version ) { int32_t ret = -1; diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_util.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_util.c index d972d3b791f4..67270b315727 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_util.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_util.c @@ -45,6 +45,7 @@ int vchiu_queue_init(VCHIU_QUEUE_T *queue, int size) queue->size = size; queue->read = 0; queue->write = 0; + queue->initialized = 1; _sema_init(&queue->pop, 0); _sema_init(&queue->push, 0); @@ -75,6 +76,9 @@ int vchiu_queue_is_full(VCHIU_QUEUE_T *queue) void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header) { + if (!queue->initialized) + return; + while (queue->write == queue->read + queue->size) { if (down_interruptible(&queue->pop) != 0) { flush_signals(current); diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_util.h b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_util.h index ce49037f9600..b63f1aa2b263 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_util.h +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_util.h @@ -44,6 +44,7 @@ typedef struct { int size; int read; int write; + int initialized; struct semaphore pop; struct semaphore push; @@ -63,4 +64,3 @@ extern VCHIQ_HEADER_T *vchiu_queue_peek(VCHIU_QUEUE_T *queue); extern VCHIQ_HEADER_T *vchiu_queue_pop(VCHIU_QUEUE_T *queue); #endif - diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 4166bb73d697..26b1060b5a18 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -3320,6 +3320,9 @@ ath_transmit(struct ieee80211com *ic, struct mbuf *m) * * Note: if this fails, then the mbufs are freed but * not the node reference. + * + * So, we now have to free the node reference ourselves here + * and return OK up to the stack. */ next = m->m_nextpkt; if (ath_tx_start(sc, ni, bf, m)) { @@ -3336,7 +3339,14 @@ ath_transmit(struct ieee80211com *ic, struct mbuf *m) */ ath_txfrag_cleanup(sc, &frags, ni); ATH_TXBUF_UNLOCK(sc); - retval = ENOBUFS; + + /* + * XXX: And free the node/return OK; ath_tx_start() may have + * modified the buffer. We currently have no way to + * signify that the mbuf was freed but there was an error. + */ + ieee80211_free_node(ni); + retval = 0; goto finish; } diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h index 1af99aa9c334..e3d414b3fd03 100644 --- a/sys/dev/ath/if_athvar.h +++ b/sys/dev/ath/if_athvar.h @@ -1035,8 +1035,8 @@ void ath_intr(void *); */ #define ath_hal_detach(_ah) \ ((*(_ah)->ah_detach)((_ah))) -#define ath_hal_reset(_ah, _opmode, _chan, _outdoor, _pstatus) \ - ((*(_ah)->ah_reset)((_ah), (_opmode), (_chan), (_outdoor), (_pstatus))) +#define ath_hal_reset(_ah, _opmode, _chan, _fullreset, _pstatus) \ + ((*(_ah)->ah_reset)((_ah), (_opmode), (_chan), (_fullreset), (_pstatus))) #define ath_hal_macversion(_ah) \ (((_ah)->ah_macVersion << 4) | ((_ah)->ah_macRev)) #define ath_hal_getratetable(_ah, _mode) \ diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index a5c7608310bd..473d5eb9fee1 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -573,6 +573,33 @@ t5_probe(device_t dev) return (ENXIO); } +static void +t5_attribute_workaround(device_t dev) +{ + device_t root_port; + uint32_t v; + + /* + * The T5 chips do not properly echo the No Snoop and Relaxed + * Ordering attributes when replying to a TLP from a Root + * Port. As a workaround, find the parent Root Port and + * disable No Snoop and Relaxed Ordering. Note that this + * affects all devices under this root port. + */ + root_port = pci_find_pcie_root_port(dev); + if (root_port == NULL) { + device_printf(dev, "Unable to find parent root port\n"); + return; + } + + v = pcie_adjust_config(root_port, PCIER_DEVICE_CTL, + PCIEM_CTL_RELAXED_ORD_ENABLE | PCIEM_CTL_NOSNOOP_ENABLE, 0, 2); + if ((v & (PCIEM_CTL_RELAXED_ORD_ENABLE | PCIEM_CTL_NOSNOOP_ENABLE)) != + 0) + device_printf(dev, "Disabled No Snoop/Relaxed Ordering on %s\n", + device_get_nameunit(root_port)); +} + static int t4_attach(device_t dev) { @@ -591,6 +618,8 @@ t4_attach(device_t dev) sc->dev = dev; TUNABLE_INT_FETCH("hw.cxgbe.debug_flags", &sc->debug_flags); + if ((pci_get_device(dev) & 0xff00) == 0x5400) + t5_attribute_workaround(dev); pci_enable_busmaster(dev); if (pci_find_cap(dev, PCIY_EXPRESS, &i) == 0) { uint32_t v; diff --git a/sys/dev/filemon/filemon.c b/sys/dev/filemon/filemon.c index ef6c98c7f18d..b302de9f6924 100644 --- a/sys/dev/filemon/filemon.c +++ b/sys/dev/filemon/filemon.c @@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include diff --git a/sys/dev/flash/mx25l.c b/sys/dev/flash/mx25l.c index 24c9323a9d33..d9aaa1c24935 100644 --- a/sys/dev/flash/mx25l.c +++ b/sys/dev/flash/mx25l.c @@ -107,6 +107,7 @@ struct mx25l_flash_ident flash_devices[] = { { "s25fl032", 0x01, 0x0215, 64 * 1024, 64, FL_NONE }, { "s25fl064", 0x01, 0x0216, 64 * 1024, 128, FL_NONE }, { "s25fl128", 0x01, 0x2018, 64 * 1024, 256, FL_NONE }, + { "s25fl256s", 0x01, 0x0219, 64 * 1024, 512, FL_NONE }, { "SST25VF032B", 0xbf, 0x254a, 64 * 1024, 64, FL_ERASE_4K | FL_ERASE_32K }, /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c index c45a37ffe55e..53141e1e4495 100644 --- a/sys/dev/iwi/if_iwi.c +++ b/sys/dev/iwi/if_iwi.c @@ -155,7 +155,6 @@ static void iwi_media_status(struct ifnet *, struct ifmediareq *); static int iwi_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void iwi_wme_init(struct iwi_softc *); static int iwi_wme_setparams(struct iwi_softc *); -static void iwi_update_wme(void *, int); static int iwi_wme_update(struct ieee80211com *); static uint16_t iwi_read_prom_word(struct iwi_softc *, uint8_t); static void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int, @@ -286,7 +285,6 @@ iwi_attach(device_t dev) TASK_INIT(&sc->sc_radiofftask, 0, iwi_radio_off, sc); TASK_INIT(&sc->sc_restarttask, 0, iwi_restart, sc); TASK_INIT(&sc->sc_disassoctask, 0, iwi_disassoc, sc); - TASK_INIT(&sc->sc_wmetask, 0, iwi_update_wme, sc); TASK_INIT(&sc->sc_monitortask, 0, iwi_monitor_scan, sc); callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0); @@ -1060,22 +1058,12 @@ iwi_wme_setparams(struct iwi_softc *sc) #undef IWI_USEC #undef IWI_EXP2 -static void -iwi_update_wme(void *arg, int npending) -{ - struct iwi_softc *sc = arg; - IWI_LOCK_DECL; - - IWI_LOCK(sc); - (void) iwi_wme_setparams(sc); - IWI_UNLOCK(sc); -} - static int iwi_wme_update(struct ieee80211com *ic) { struct iwi_softc *sc = ic->ic_softc; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + IWI_LOCK_DECL; /* * We may be called to update the WME parameters in @@ -1085,8 +1073,11 @@ iwi_wme_update(struct ieee80211com *ic) * to the adapter as part of the work iwi_auth_and_assoc * does. */ - if (vap->iv_state == IEEE80211_S_RUN) - ieee80211_runtask(ic, &sc->sc_wmetask); + if (vap->iv_state == IEEE80211_S_RUN) { + IWI_LOCK(sc); + iwi_wme_setparams(sc); + IWI_UNLOCK(sc); + } return (0); } diff --git a/sys/dev/iwi/if_iwivar.h b/sys/dev/iwi/if_iwivar.h index 47848e16c822..88138cf0ed67 100644 --- a/sys/dev/iwi/if_iwivar.h +++ b/sys/dev/iwi/if_iwivar.h @@ -192,7 +192,6 @@ struct iwi_softc { struct task sc_radiofftask; /* radio off processing */ struct task sc_restarttask; /* restart adapter processing */ struct task sc_disassoctask; - struct task sc_wmetask; /* set wme parameters */ struct task sc_monitortask; unsigned int sc_running : 1, /* initialized */ diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index 907755ba1b6f..2947db549c7a 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -4852,6 +4852,7 @@ iwn_xmit_task(void *arg0, int pending) if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); + m_freem(m); } } @@ -4872,16 +4873,13 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, DPRINTF(sc, IWN_DEBUG_XMIT | IWN_DEBUG_TRACE, "->%s begin\n", __func__); + IWN_LOCK(sc); if ((sc->sc_flags & IWN_FLAG_RUNNING) == 0) { m_freem(m); - return ENETDOWN; + IWN_UNLOCK(sc); + return (ENETDOWN); } - /* XXX? net80211 doesn't set this on xmit'ed raw frames? */ - m->m_pkthdr.rcvif = (void *) ni; - - IWN_LOCK(sc); - /* queue frame if we have to */ if (sc->sc_beacon_wait) { if (iwn_xmit_queue_enqueue(sc, m) != 0) { @@ -4909,12 +4907,14 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, } if (error == 0) sc->sc_tx_timer = 5; + else + m_freem(m); IWN_UNLOCK(sc); DPRINTF(sc, IWN_DEBUG_TRACE | IWN_DEBUG_XMIT, "->%s: end\n",__func__); - return error; + return (error); } /* diff --git a/sys/dev/ofw/ofw_iicbus.c b/sys/dev/ofw/ofw_iicbus.c index e7613fc9ddeb..badefed68477 100644 --- a/sys/dev/ofw/ofw_iicbus.c +++ b/sys/dev/ofw/ofw_iicbus.c @@ -148,10 +148,16 @@ ofw_iicbus_attach(device_t dev) if (dinfo == NULL) continue; /* - * OFW uses 7-bit I2C address format (see ePAPR), - * but system expect 8-bit. + * FreeBSD drivers expect I2C addresses to be expressed as + * 8-bit values. Apple OFW data contains 8-bit values, but + * Linux FDT data contains 7-bit values, so shift them up to + * 8-bit format. */ +#ifdef AIM + dinfo->opd_dinfo.addr = paddr; +#else dinfo->opd_dinfo.addr = paddr << 1; +#endif if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) != 0) { free(dinfo, M_DEVBUF); diff --git a/sys/dev/otus/if_otus.c b/sys/dev/otus/if_otus.c index a61e344e6deb..0d59278050e0 100644 --- a/sys/dev/otus/if_otus.c +++ b/sys/dev/otus/if_otus.c @@ -155,7 +155,6 @@ static void otus_free_txcmd(struct otus_softc *, struct otus_tx_cmd *); void otus_next_scan(void *, int); static void otus_tx_task(void *, int pending); -static void otus_wme_update_task(void *, int pending); void otus_do_async(struct otus_softc *, void (*)(struct otus_softc *, void *), void *, int); int otus_newstate(struct ieee80211vap *, enum ieee80211_state, @@ -177,8 +176,9 @@ static int otus_tx(struct otus_softc *, struct ieee80211_node *, const struct ieee80211_bpf_params *); int otus_ioctl(struct ifnet *, u_long, caddr_t); int otus_set_multi(struct otus_softc *); -static void otus_updateedca(struct otus_softc *sc); -static void otus_updateslot(struct otus_softc *sc); +static int otus_updateedca(struct ieee80211com *); +static void otus_updateedca_locked(struct otus_softc *); +static void otus_updateslot(struct otus_softc *); int otus_init_mac(struct otus_softc *); uint32_t otus_phy_get_def(struct otus_softc *, uint32_t); int otus_set_board_values(struct otus_softc *, @@ -300,7 +300,6 @@ otus_attach(device_t self) TIMEOUT_TASK_INIT(taskqueue_thread, &sc->scan_to, 0, otus_next_scan, sc); TIMEOUT_TASK_INIT(taskqueue_thread, &sc->calib_to, 0, otus_calibrate_to, sc); TASK_INIT(&sc->tx_task, 0, otus_tx_task, sc); - TASK_INIT(&sc->wme_update_task, 0, otus_wme_update_task, sc); mbufq_init(&sc->sc_snd, ifqmaxlen); iface_index = 0; @@ -345,7 +344,6 @@ otus_detach(device_t self) taskqueue_drain_timeout(taskqueue_thread, &sc->scan_to); taskqueue_drain_timeout(taskqueue_thread, &sc->calib_to); taskqueue_drain(taskqueue_thread, &sc->tx_task); - taskqueue_drain(taskqueue_thread, &sc->wme_update_task); otus_close_pipes(sc); #if 0 @@ -590,44 +588,6 @@ otus_set_channel(struct ieee80211com *ic) OTUS_UNLOCK(sc); } -static void -otus_wme_update_task(void *arg, int pending) -{ - struct otus_softc *sc = arg; - - OTUS_LOCK(sc); - /* - * XXX TODO: take temporary copy of EDCA information - * when scheduling this so we have a more time-correct view - * of things. - */ - otus_updateedca(sc); - OTUS_UNLOCK(sc); -} - -static void -otus_wme_schedule_update(struct otus_softc *sc) -{ - - taskqueue_enqueue(taskqueue_thread, &sc->wme_update_task); -} - -/* - * This is called by net80211 in RX packet context, so we - * can't sleep here. - * - * TODO: have net80211 schedule an update itself for its - * own internal taskqueue. - */ -static int -otus_wme_update(struct ieee80211com *ic) -{ - struct otus_softc *sc = ic->ic_softc; - - otus_wme_schedule_update(sc); - return (0); -} - static int otus_ampdu_enable(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap) { @@ -811,7 +771,7 @@ otus_attachhook(struct otus_softc *sc) ic->ic_transmit = otus_transmit; ic->ic_update_chw = otus_update_chw; ic->ic_ampdu_enable = otus_ampdu_enable; - ic->ic_wme.wme_update = otus_wme_update; + ic->ic_wme.wme_update = otus_updateedca; ic->ic_newassoc = otus_newassoc; ic->ic_node_alloc = otus_node_alloc; @@ -2383,8 +2343,25 @@ otus_set_multi(struct otus_softc *sc) return (r); } +static int +otus_updateedca(struct ieee80211com *ic) +{ + struct otus_softc *sc = ic->ic_softc; + + OTUS_LOCK(sc); + /* + * XXX TODO: take temporary copy of EDCA information + * when scheduling this so we have a more time-correct view + * of things. + * XXX TODO: this can be done on the net80211 level + */ + otus_updateedca_locked(sc); + OTUS_UNLOCK(sc); + return (0); +} + static void -otus_updateedca(struct otus_softc *sc) +otus_updateedca_locked(struct otus_softc *sc) { #define EXP2(val) ((1 << (val)) - 1) #define AIFS(val) ((val) * 9 + 10) @@ -2508,7 +2485,7 @@ otus_init_mac(struct otus_softc *sc) return error; /* Set default EDCA parameters. */ - otus_updateedca(sc); + otus_updateedca_locked(sc); return 0; } @@ -3185,7 +3162,6 @@ otus_stop(struct otus_softc *sc) taskqueue_drain_timeout(taskqueue_thread, &sc->scan_to); taskqueue_drain_timeout(taskqueue_thread, &sc->calib_to); taskqueue_drain(taskqueue_thread, &sc->tx_task); - taskqueue_drain(taskqueue_thread, &sc->wme_update_task); OTUS_LOCK(sc); sc->sc_running = 0; diff --git a/sys/dev/otus/if_otusreg.h b/sys/dev/otus/if_otusreg.h index 491e52972092..541d76731dbd 100644 --- a/sys/dev/otus/if_otusreg.h +++ b/sys/dev/otus/if_otusreg.h @@ -59,6 +59,8 @@ #define AR_MAC_REG_RX_PE_DELAY (AR_MAC_REG_BASE + 0x64c) #define AR_MAC_REG_DYNAMIC_SIFS_ACK (AR_MAC_REG_BASE + 0x658) #define AR_MAC_REG_SNIFFER (AR_MAC_REG_BASE + 0x674) +#define AR_MAC_SNIFFER_DEFAULTS 0x02000000 +#define AR_MAC_SNIFFER_ENABLE_PROMISC 0x1 #define AR_MAC_REG_ENCRYPTION (AR_MAC_REG_BASE + 0x678) #define AR_MAC_REG_MISC_680 (AR_MAC_REG_BASE + 0x680) #define AR_MAC_REG_FRAMETYPE_FILTER (AR_MAC_REG_BASE + 0x68c) @@ -69,6 +71,11 @@ #define AR_MAC_REG_BUSY_EXT (AR_MAC_REG_BASE + 0x6ec) #define AR_MAC_REG_SLOT_TIME (AR_MAC_REG_BASE + 0x6f0) #define AR_MAC_REG_CAM_MODE (AR_MAC_REG_BASE + 0x700) +#define AR_MAC_CAM_DEFAULTS (0xf << 24) +#define AR_MAC_CAM_IBSS 0xe0 +#define AR_MAC_CAM_AP 0xa1 +#define AR_MAC_CAM_STA 0x2 +#define AR_MAC_CAM_AP_WDS 0x3 #define AR_MAC_REG_AC0_CW (AR_MAC_REG_BASE + 0xb00) #define AR_MAC_REG_AC1_CW (AR_MAC_REG_BASE + 0xb04) #define AR_MAC_REG_AC2_CW (AR_MAC_REG_BASE + 0xb08) @@ -86,6 +93,12 @@ #define AR_MAC_REG_AMPDU_FACTOR (AR_MAC_REG_BASE + 0xb9c) #define AR_MAC_REG_FCS_SELECT (AR_MAC_REG_BASE + 0xbb0) #define AR_MAC_REG_RX_CONTROL (AR_MAC_REG_BASE + 0xc40) +#define AR_MAC_RX_CTRL_DEAGG 0x1 +#define AR_MAC_RX_CTRL_SHORT_FILTER 0x2 +#define AR_MAC_RX_CTRL_SA_DA_SEARCH 0x20 +#define AR_MAC_RX_CTRL_PASS_TO_HOST (1 << 28) +#define AR_MAC_RX_CTRL_ACK_IN_SNIFFER (1 << 30) + #define AR_MAC_REG_AMPDU_RX_THRESH (AR_MAC_REG_BASE + 0xc50) #define AR_MAC_REG_OFDM_PHY_ERRORS (AR_MAC_REG_BASE + 0xcb4) #define AR_MAC_REG_CCK_PHY_ERRORS (AR_MAC_REG_BASE + 0xcb8) @@ -1009,7 +1022,6 @@ struct otus_softc { struct ieee80211_channel *sc_curchan; struct task tx_task; - struct task wme_update_task; struct timeout_task scan_to; struct timeout_task calib_to; diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 39d311f65095..f5e8470de3ac 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -1917,6 +1917,63 @@ pci_set_max_read_req(device_t dev, int size) return (size); } +uint32_t +pcie_read_config(device_t dev, int reg, int width) +{ + struct pci_devinfo *dinfo = device_get_ivars(dev); + int cap; + + cap = dinfo->cfg.pcie.pcie_location; + if (cap == 0) { + if (width == 2) + return (0xffff); + return (0xffffffff); + } + + return (pci_read_config(dev, cap + reg, width)); +} + +void +pcie_write_config(device_t dev, int reg, uint32_t value, int width) +{ + struct pci_devinfo *dinfo = device_get_ivars(dev); + int cap; + + cap = dinfo->cfg.pcie.pcie_location; + if (cap == 0) + return; + pci_write_config(dev, cap + reg, value, width); +} + +/* + * Adjusts a PCI-e capability register by clearing the bits in mask + * and setting the bits in (value & mask). Bits not set in mask are + * not adjusted. + * + * Returns the old value on success or all ones on failure. + */ +uint32_t +pcie_adjust_config(device_t dev, int reg, uint32_t mask, uint32_t value, + int width) +{ + struct pci_devinfo *dinfo = device_get_ivars(dev); + uint32_t old, new; + int cap; + + cap = dinfo->cfg.pcie.pcie_location; + if (cap == 0) { + if (width == 2) + return (0xffff); + return (0xffffffff); + } + + old = pci_read_config(dev, cap + reg, width); + new = old & ~mask; + new |= (value & mask); + pci_write_config(dev, cap + reg, new, width); + return (old); +} + /* * Support for MSI message signalled interrupts. */ @@ -5374,3 +5431,44 @@ pci_get_rid_method(device_t dev, device_t child) return (PCIB_GET_RID(device_get_parent(dev), child)); } + +/* Find the upstream port of a given PCI device in a root complex. */ +device_t +pci_find_pcie_root_port(device_t dev) +{ + struct pci_devinfo *dinfo; + devclass_t pci_class; + device_t pcib, bus; + + pci_class = devclass_find("pci"); + KASSERT(device_get_devclass(device_get_parent(dev)) == pci_class, + ("%s: non-pci device %s", __func__, device_get_nameunit(dev))); + + /* + * Walk the bridge hierarchy until we find a PCI-e root + * port or a non-PCI device. + */ + for (;;) { + bus = device_get_parent(dev); + KASSERT(bus != NULL, ("%s: null parent of %s", __func__, + device_get_nameunit(dev))); + + pcib = device_get_parent(bus); + KASSERT(pcib != NULL, ("%s: null bridge of %s", __func__, + device_get_nameunit(bus))); + + /* + * pcib's parent must be a PCI bus for this to be a + * PCI-PCI bridge. + */ + if (device_get_devclass(device_get_parent(pcib)) != pci_class) + return (NULL); + + dinfo = device_get_ivars(pcib); + if (dinfo->cfg.pcie.pcie_location != 0 && + dinfo->cfg.pcie.pcie_type == PCIEM_TYPE_ROOT_PORT) + return (pcib); + + dev = pcib; + } +} diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index 7f2e95836a30..b8f64c2d9793 100644 --- a/sys/dev/pci/pcivar.h +++ b/sys/dev/pci/pcivar.h @@ -547,10 +547,15 @@ int pci_msix_device_blacklisted(device_t dev); void pci_ht_map_msi(device_t dev, uint64_t addr); +device_t pci_find_pcie_root_port(device_t dev); int pci_get_max_read_req(device_t dev); void pci_restore_state(device_t dev); void pci_save_state(device_t dev); int pci_set_max_read_req(device_t dev, int size); +uint32_t pcie_read_config(device_t dev, int reg, int width); +void pcie_write_config(device_t dev, int reg, uint32_t value, int width); +uint32_t pcie_adjust_config(device_t dev, int reg, uint32_t mask, + uint32_t value, int width); #ifdef BUS_SPACE_MAXADDR diff --git a/sys/dev/usb/net/if_cdce.c b/sys/dev/usb/net/if_cdce.c index 13fca9359f2b..397c4f6c779e 100644 --- a/sys/dev/usb/net/if_cdce.c +++ b/sys/dev/usb/net/if_cdce.c @@ -1535,6 +1535,7 @@ cdce_ncm_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) /* check if we have a buffer */ if (m) { + m->m_len = m->m_pkthdr.len = temp + ETHER_ALIGN; m_adj(m, ETHER_ALIGN); usbd_copy_out(pc, offset, m->m_data, temp); diff --git a/sys/dev/usb/net/if_urndis.c b/sys/dev/usb/net/if_urndis.c index 3c24dcf1d4d7..32fa53370946 100644 --- a/sys/dev/usb/net/if_urndis.c +++ b/sys/dev/usb/net/if_urndis.c @@ -884,7 +884,7 @@ urndis_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) DPRINTF("invalid ethernet size " "%u < %u\n", msg.rm_datalen, (unsigned)sizeof(struct ether_header)); goto tr_setup; - } else if (msg.rm_datalen > (uint32_t)MCLBYTES) { + } else if (msg.rm_datalen > (uint32_t)(MCLBYTES - ETHER_ALIGN)) { if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); DPRINTF("invalid ethernet size " "%u > %u\n", @@ -898,6 +898,7 @@ urndis_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) /* check if we have a buffer */ if (m != NULL) { + m->m_len = m->m_pkthdr.len = msg.rm_datalen + ETHER_ALIGN; m_adj(m, ETHER_ALIGN); usbd_copy_out(pc, offset + msg.rm_dataoffset + diff --git a/sys/dev/usb/usb_busdma.c b/sys/dev/usb/usb_busdma.c index 1c3628888ba8..d9c198774f7a 100644 --- a/sys/dev/usb/usb_busdma.c +++ b/sys/dev/usb/usb_busdma.c @@ -443,9 +443,13 @@ usb_pc_common_mem_cb(void *arg, bus_dma_segment_t *segs, pc->page_offset_buf = rem; pc->page_offset_end += rem; #ifdef USB_DEBUG - if (rem != (USB_P2U(pc->buffer) & (USB_PAGE_SIZE - 1))) { + if (nseg > 1 && + ((segs->ds_addr + segs->ds_len) & (USB_PAGE_SIZE - 1)) != + ((segs + 1)->ds_addr & (USB_PAGE_SIZE - 1))) { /* - * This check verifies that the physical address is correct: + * This check verifies there is no page offset hole + * between the first and second segment. See the + * BUS_DMA_KEEP_PG_OFFSET flag. */ DPRINTFN(0, "Page offset was not preserved\n"); error = 1; diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c index de7b8806e800..9d2203da5494 100644 --- a/sys/dev/usb/wlan/if_rum.c +++ b/sys/dev/usb/wlan/if_rum.c @@ -216,8 +216,6 @@ static void rum_get_tsf(struct rum_softc *, uint64_t *); static void rum_update_slot_cb(struct rum_softc *, union sec_param *, uint8_t); static void rum_update_slot(struct ieee80211com *); -static void rum_wme_update_cb(struct rum_softc *, - union sec_param *, uint8_t); static int rum_wme_update(struct ieee80211com *); static void rum_set_bssid(struct rum_softc *, const uint8_t *); static void rum_set_macaddr(struct rum_softc *, const uint8_t *); @@ -2083,14 +2081,15 @@ rum_update_slot(struct ieee80211com *ic) rum_cmd_sleepable(ic->ic_softc, NULL, 0, 0, rum_update_slot_cb); } -static void -rum_wme_update_cb(struct rum_softc *sc, union sec_param *data, uint8_t rvp_id) +static int +rum_wme_update(struct ieee80211com *ic) { - struct ieee80211com *ic = &sc->sc_ic; const struct wmeParams *chanp = ic->ic_wme.wme_chanParams.cap_wmeParams; + struct rum_softc *sc = ic->ic_softc; int error = 0; + RUM_LOCK(sc); error = rum_write(sc, RT2573_AIFSN_CSR, chanp[WME_AC_VO].wmep_aifsn << 12 | chanp[WME_AC_VI].wmep_aifsn << 8 | @@ -2125,21 +2124,14 @@ rum_wme_update_cb(struct rum_softc *sc, union sec_param *data, uint8_t rvp_id) memcpy(sc->wme_params, chanp, sizeof(*chanp) * WME_NUM_AC); - return; - print_err: - device_printf(sc->sc_dev, "%s: WME update failed, error %d\n", - __func__, error); -} + RUM_UNLOCK(sc); + if (error != 0) { + device_printf(sc->sc_dev, "%s: WME update failed, error %d\n", + __func__, error); + } -static int -rum_wme_update(struct ieee80211com *ic) -{ - struct rum_softc *sc = ic->ic_softc; - - rum_cmd_sleepable(sc, NULL, 0, 0, rum_wme_update_cb); - - return (0); + return (error); } static void diff --git a/sys/dev/usb/wlan/if_rumvar.h b/sys/dev/usb/wlan/if_rumvar.h index 9fa733e4c5f9..d4944680803d 100644 --- a/sys/dev/usb/wlan/if_rumvar.h +++ b/sys/dev/usb/wlan/if_rumvar.h @@ -73,7 +73,6 @@ typedef STAILQ_HEAD(, rum_tx_data) rum_txdhead; union sec_param { struct ieee80211_key key; - struct wmeParams wme_params[WME_NUM_AC]; uint8_t macaddr[IEEE80211_ADDR_LEN]; struct ieee80211vap *vap; }; diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c index d5b52887ba3f..bb52a09322cb 100644 --- a/sys/dev/usb/wlan/if_run.c +++ b/sys/dev/usb/wlan/if_run.c @@ -381,7 +381,6 @@ static struct ieee80211_node *run_node_alloc(struct ieee80211vap *, static int run_media_change(struct ifnet *); static int run_newstate(struct ieee80211vap *, enum ieee80211_state, int); static int run_wme_update(struct ieee80211com *); -static void run_wme_update_cb(void *); static void run_key_set_cb(void *); static int run_key_set(struct ieee80211vap *, struct ieee80211_key *); static void run_key_delete_cb(void *); @@ -2174,19 +2173,16 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) return(rvp->newstate(vap, nstate, arg)); } -/* ARGSUSED */ -static void -run_wme_update_cb(void *arg) +static int +run_wme_update(struct ieee80211com *ic) { - struct ieee80211com *ic = arg; struct run_softc *sc = ic->ic_softc; const struct wmeParams *ac = ic->ic_wme.wme_chanParams.cap_wmeParams; int aci, error = 0; - RUN_LOCK_ASSERT(sc, MA_OWNED); - /* update MAC TX configuration registers */ + RUN_LOCK(sc); for (aci = 0; aci < WME_NUM_AC; aci++) { error = run_write(sc, RT2860_EDCA_AC_CFG(aci), ac[aci].wmep_logcwmax << 16 | @@ -2224,33 +2220,11 @@ run_wme_update_cb(void *arg) ac[WME_AC_VI].wmep_txopLimit); err: + RUN_UNLOCK(sc); if (error) DPRINTF("WME update failed\n"); - return; -} - -static int -run_wme_update(struct ieee80211com *ic) -{ - struct run_softc *sc = ic->ic_softc; - - /* sometime called wothout lock */ - if (mtx_owned(&ic->ic_comlock.mtx)) { - uint32_t i = RUN_CMDQ_GET(&sc->cmdq_store); - DPRINTF("cmdq_store=%d\n", i); - sc->cmdq[i].func = run_wme_update_cb; - sc->cmdq[i].arg0 = ic; - ieee80211_runtask(ic, &sc->cmdq_task); - return (0); - } - - RUN_LOCK(sc); - run_wme_update_cb(ic); - RUN_UNLOCK(sc); - - /* return whatever, upper layer doesn't care anyway */ - return (0); + return (error); } static void diff --git a/sys/dev/usb/wlan/if_urtwn.c b/sys/dev/usb/wlan/if_urtwn.c index 0cd1cf342a50..9bc8911be95b 100644 --- a/sys/dev/usb/wlan/if_urtwn.c +++ b/sys/dev/usb/wlan/if_urtwn.c @@ -1473,32 +1473,11 @@ urtwn_ra_init(struct urtwn_softc *sc) return (0); } -void +static void urtwn_tsf_sync_enable(struct urtwn_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct ieee80211_node *ni = vap->iv_bss; - - uint64_t tsf; - - /* Enable TSF synchronization. */ urtwn_write_1(sc, R92C_BCN_CTRL, urtwn_read_1(sc, R92C_BCN_CTRL) & ~R92C_BCN_CTRL_DIS_TSF_UDT0); - - urtwn_write_1(sc, R92C_BCN_CTRL, - urtwn_read_1(sc, R92C_BCN_CTRL) & ~R92C_BCN_CTRL_EN_BCN); - - /* Set initial TSF. */ - memcpy(&tsf, ni->ni_tstamp.data, 8); - tsf = le64toh(tsf); - tsf = tsf - (tsf % (vap->iv_bss->ni_intval * IEEE80211_DUR_TU)); - tsf -= IEEE80211_DUR_TU; - urtwn_write_4(sc, R92C_TSFTR + 0, tsf); - urtwn_write_4(sc, R92C_TSFTR + 4, tsf >> 32); - - urtwn_write_1(sc, R92C_BCN_CTRL, - urtwn_read_1(sc, R92C_BCN_CTRL) | R92C_BCN_CTRL_EN_BCN); } static void diff --git a/sys/dev/vnic/thunder_mdio_fdt.c b/sys/dev/vnic/thunder_mdio_fdt.c index cd2d1cff9f09..b24be1dc3ee6 100644 --- a/sys/dev/vnic/thunder_mdio_fdt.c +++ b/sys/dev/vnic/thunder_mdio_fdt.c @@ -58,8 +58,8 @@ DEFINE_CLASS_1(thunder_mdio, thunder_mdio_fdt_driver, thunder_mdio_fdt_methods, static devclass_t thunder_mdio_fdt_devclass; -DRIVER_MODULE(thunder_mdio, ofwbus, thunder_mdio_fdt_driver, - thunder_mdio_fdt_devclass, 0, 0); +EARLY_DRIVER_MODULE(thunder_mdio, ofwbus, thunder_mdio_fdt_driver, + thunder_mdio_fdt_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); static int thunder_mdio_fdt_probe(device_t dev) diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c index dd1015d72d82..cef6370493c2 100644 --- a/sys/dev/xen/netfront/netfront.c +++ b/sys/dev/xen/netfront/netfront.c @@ -31,7 +31,6 @@ __FBSDID("$FreeBSD$"); #include "opt_inet6.h" #include -#include #include #include #include @@ -40,22 +39,17 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include -#include #include #include #include #include -#include #include #include #include -#include #include #include #include @@ -65,16 +59,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include /* for DELAY */ -#include -#include -#include -#include - #include -#include - -#include #include #include diff --git a/sys/geom/eli/g_eli.c b/sys/geom/eli/g_eli.c index 14fc17bc2323..57adc40addc8 100644 --- a/sys/geom/eli/g_eli.c +++ b/sys/geom/eli/g_eli.c @@ -195,7 +195,7 @@ g_eli_read_done(struct bio *bp) G_ELI_LOGREQ(2, bp, "Request done."); pbp = bp->bio_parent; - if (pbp->bio_error == 0) + if (pbp->bio_error == 0 && bp->bio_error != 0) pbp->bio_error = bp->bio_error; g_destroy_bio(bp); /* @@ -206,7 +206,8 @@ g_eli_read_done(struct bio *bp) return; sc = pbp->bio_to->geom->softc; if (pbp->bio_error != 0) { - G_ELI_LOGREQ(0, pbp, "%s() failed", __func__); + G_ELI_LOGREQ(0, pbp, "%s() failed (error=%d)", __func__, + pbp->bio_error); pbp->bio_completed = 0; if (pbp->bio_driver2 != NULL) { free(pbp->bio_driver2, M_ELI); @@ -235,10 +236,8 @@ g_eli_write_done(struct bio *bp) G_ELI_LOGREQ(2, bp, "Request done."); pbp = bp->bio_parent; - if (pbp->bio_error == 0) { - if (bp->bio_error != 0) - pbp->bio_error = bp->bio_error; - } + if (pbp->bio_error == 0 && bp->bio_error != 0) + pbp->bio_error = bp->bio_error; g_destroy_bio(bp); /* * Do we have all sectors already? @@ -249,14 +248,15 @@ g_eli_write_done(struct bio *bp) free(pbp->bio_driver2, M_ELI); pbp->bio_driver2 = NULL; if (pbp->bio_error != 0) { - G_ELI_LOGREQ(0, pbp, "Crypto WRITE request failed (error=%d).", + G_ELI_LOGREQ(0, pbp, "%s() failed (error=%d)", __func__, pbp->bio_error); pbp->bio_completed = 0; - } + } else + pbp->bio_completed = pbp->bio_length; + /* * Write is finished, send it up. */ - pbp->bio_completed = pbp->bio_length; sc = pbp->bio_to->geom->softc; g_io_deliver(pbp, pbp->bio_error); atomic_subtract_int(&sc->sc_inflight, 1); diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 94b25b8fe3b9..62c79419f83d 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -1270,9 +1270,11 @@ __elfN(coredump)(struct thread *td, struct vnode *vp, off_t limit, int flags) struct note_info *ninfo; void *hdr, *tmpbuf; size_t hdrsize, notesz, coresize; +#ifdef GZIO boolean_t compress; compress = (flags & IMGACT_CORE_COMPRESS) != 0; +#endif hdr = NULL; tmpbuf = NULL; TAILQ_INIT(¬elst); diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 23b7d5489e53..a74d27f62040 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -3157,6 +3157,30 @@ filedesc_to_leader_alloc(struct filedesc_to_leader *old, struct filedesc *fdp, s return (fdtol); } +static int +sysctl_kern_proc_nfds(SYSCTL_HANDLER_ARGS) +{ + struct filedesc *fdp; + int i, count, slots; + + if (*(int *)arg1 != 0) + return (EINVAL); + + fdp = curproc->p_fd; + count = 0; + FILEDESC_SLOCK(fdp); + slots = NDSLOTS(fdp->fd_lastfile + 1); + for (i = 0; i < slots; i++) + count += bitcountl(fdp->fd_map[i]); + FILEDESC_SUNLOCK(fdp); + + return (SYSCTL_OUT(req, &count, sizeof(count))); +} + +static SYSCTL_NODE(_kern_proc, KERN_PROC_NFDS, nfds, + CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc_nfds, + "Number of open file descriptors"); + /* * Get file structures globally. */ diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 0ee8a1a12bd5..243144eb67a1 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -643,7 +643,7 @@ sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, int recurse) */ struct sysctl_oid * sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent, - int number, const char *name, int kind, void *arg1, intptr_t arg2, + int number, const char *name, int kind, void *arg1, intmax_t arg2, int (*handler)(SYSCTL_HANDLER_ARGS), const char *fmt, const char *descr) { struct sysctl_oid *oidp; @@ -1191,6 +1191,38 @@ sysctl_handle_16(SYSCTL_HANDLER_ARGS) return (error); } +/* + * Handle an int32_t, signed or unsigned. + * Two cases: + * a variable: point arg1 at it. + * a constant: pass it in arg2. + */ + +int +sysctl_handle_32(SYSCTL_HANDLER_ARGS) +{ + int32_t tmpout; + int error = 0; + + /* + * Attempt to get a coherent snapshot by making a copy of the data. + */ + if (arg1) + tmpout = *(int32_t *)arg1; + else + tmpout = arg2; + error = SYSCTL_OUT(req, &tmpout, sizeof(tmpout)); + + if (error || !req->newptr) + return (error); + + if (!arg1) + error = EPERM; + else + error = SYSCTL_IN(req, arg1, sizeof(tmpout)); + return (error); +} + /* * Handle an int, signed or unsigned. * Two cases: diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index d4a1a536be8e..070a93a88a39 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -1702,13 +1702,16 @@ pps_event(struct pps_state *pps, int event) struct bintime bt; struct timespec ts, *tsp, *osp; u_int tcount, *pcount; - int foff, fhard; + int foff; pps_seq_t *pseq; #ifdef FFCLOCK struct timespec *tsp_ffc; pps_seq_t *pseq_ffc; ffcounter *ffcount; #endif +#ifdef PPS_SYNC + int fhard; +#endif KASSERT(pps != NULL, ("NULL pps pointer in pps_event")); /* Nothing to do if not currently set to capture this event type. */ @@ -1724,7 +1727,9 @@ pps_event(struct pps_state *pps, int event) tsp = &pps->ppsinfo.assert_timestamp; osp = &pps->ppsparam.assert_offset; foff = pps->ppsparam.mode & PPS_OFFSETASSERT; +#ifdef PPS_SYNC fhard = pps->kcmode & PPS_CAPTUREASSERT; +#endif pcount = &pps->ppscount[0]; pseq = &pps->ppsinfo.assert_sequence; #ifdef FFCLOCK @@ -1736,7 +1741,9 @@ pps_event(struct pps_state *pps, int event) tsp = &pps->ppsinfo.clear_timestamp; osp = &pps->ppsparam.clear_offset; foff = pps->ppsparam.mode & PPS_OFFSETCLEAR; +#ifdef PPS_SYNC fhard = pps->kcmode & PPS_CAPTURECLEAR; +#endif pcount = &pps->ppscount[1]; pseq = &pps->ppsinfo.clear_sequence; #ifdef FFCLOCK diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c index c931ae927495..d73c12dfb408 100644 --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -1594,6 +1594,10 @@ elf_lookup(linker_file_t lf, Elf_Size symidx, int deps, Elf_Addr *res) } addr = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps)); + if (addr == 0 && ELF_ST_BIND(sym->st_info) != STB_WEAK) { + *res = 0; + return (EINVAL); + } if (elf_set_find(&set_pcpu_list, addr, &start, &base)) addr = addr - start + base; diff --git a/sys/kern/subr_rman.c b/sys/kern/subr_rman.c index 61e951f4e5d7..310bd5e521ec 100644 --- a/sys/kern/subr_rman.c +++ b/sys/kern/subr_rman.c @@ -1051,7 +1051,8 @@ dump_rman(struct rman *rm) devname = "nomatch"; } else devname = NULL; - db_printf(" 0x%lx-0x%lx ", r->r_start, r->r_end); + db_printf(" 0x%lx-0x%lx (RID=%d) ", + r->r_start, r->r_end, r->r_rid); if (devname != NULL) db_printf("(%s)\n", devname); else diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 1e51db395433..6376cdf2e55a 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -3622,6 +3622,23 @@ getblk(struct vnode *vp, daddr_t blkno, int size, int slpflag, int slptimeo, if (bp == NULL) { if (slpflag || slptimeo) return NULL; + /* + * XXX This is here until the sleep path is diagnosed + * enough to work under very low memory conditions. + * + * There's an issue on low memory, 4BSD+non-preempt + * systems (eg MIPS routers with 32MB RAM) where buffer + * exhaustion occurs without sleeping for buffer + * reclaimation. This just sticks in a loop and + * constantly attempts to allocate a buffer, which + * hits exhaustion and tries to wakeup bufdaemon. + * This never happens because we never yield. + * + * The real solution is to identify and fix these cases + * so we aren't effectively busy-waiting in a loop + * until the reclaimation path has cycles to run. + */ + kern_yield(PRI_USER); goto loop; } diff --git a/sys/mips/atheros/files.ar71xx b/sys/mips/atheros/files.ar71xx index 712d03398d97..21ba8eb96ab0 100644 --- a/sys/mips/atheros/files.ar71xx +++ b/sys/mips/atheros/files.ar71xx @@ -31,5 +31,3 @@ mips/atheros/qca955x_chip.c standard mips/atheros/ar71xx_fixup.c optional ar71xx_ath_eeprom mips/atheros/qca955x_apb.c optional qca955x_apb mips/atheros/qca955x_pci.c optional qca955x_pci pci - -dev/hwpmc/hwpmc_mips24k.c optional hwpmc_mips24k diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index b1934638b2a3..9467679850c4 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -1660,11 +1660,25 @@ mips_unaligned_load_store(struct trapframe *frame, int mode, register_t addr, re } +/* + * XXX TODO: SMP? + */ +static struct timeval unaligned_lasterr; +static int unaligned_curerr; + +static int unaligned_pps_log_limit = 4; + +SYSCTL_INT(_machdep, OID_AUTO, unaligned_log_pps_limit, CTLFLAG_RWTUN, + &unaligned_pps_log_limit, 0, + "limit number of userland unaligned log messages per second"); + static int emulate_unaligned_access(struct trapframe *frame, int mode) { register_t pc; int access_type = 0; + struct thread *td = curthread; + struct proc *p = curproc; pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0); @@ -1691,9 +1705,19 @@ emulate_unaligned_access(struct trapframe *frame, int mode) else frame->pc += 4; - log(LOG_INFO, "Unaligned %s: pc=%#jx, badvaddr=%#jx\n", - access_name[access_type - 1], (intmax_t)pc, - (intmax_t)frame->badvaddr); + if (ppsratecheck(&unaligned_lasterr, + &unaligned_curerr, unaligned_pps_log_limit)) { + /* XXX TODO: keep global/tid/pid counters? */ + log(LOG_INFO, + "Unaligned %s: pid=%ld (%s), tid=%ld, " + "pc=%#jx, badvaddr=%#jx\n", + access_name[access_type - 1], + (long) p->p_pid, + p->p_comm, + (long) td->td_tid, + (intmax_t)pc, + (intmax_t)frame->badvaddr); + } } } return access_type; diff --git a/sys/modules/Makefile b/sys/modules/Makefile index dca94fec25c0..fadde8d46c4f 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -504,6 +504,11 @@ _cxgb= cxgb .endif .endif +.if ${MACHINE_CPUARCH} == "aarch64" +_em= em +_igb= igb +.endif + .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" _agp= agp _an= an diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c index 0d584fea3581..a16584356ee4 100644 --- a/sys/net/flowtable.c +++ b/sys/net/flowtable.c @@ -435,8 +435,7 @@ static int flow_stale(struct flowtable *ft, struct flentry *fle, int maxidle) { - if (((fle->f_rt->rt_flags & RTF_HOST) && - ((fle->f_rt->rt_flags & (RTF_UP)) != (RTF_UP))) || + if (((fle->f_rt->rt_flags & RTF_UP) == 0) || (fle->f_rt->rt_ifp == NULL) || !RT_LINK_IS_UP(fle->f_rt->rt_ifp) || (fle->f_lle->la_flags & LLE_VALID) == 0) @@ -477,7 +476,7 @@ flow_matches(struct flentry *fle, uint32_t *key, int keylen, uint32_t fibnum) CRITICAL_ASSERT(curthread); /* Microoptimization for IPv4: don't use bcmp(). */ - if (((keylen == sizeof(uint32_t) && (fle->f_key[0] != key[0])) || + if (((keylen == sizeof(uint32_t) && (fle->f_key[0] == key[0])) || (bcmp(fle->f_key, key, keylen) == 0)) && fibnum == fle->f_fibnum && #ifdef FLOWTABLE_HASH_ALL @@ -818,8 +817,6 @@ flowtable_free_stale(struct flowtable *ft, struct rtentry *rt, int maxidle) critical_exit(); bit_clear(tmpmask, curbit); - tmpmask += (curbit / 8); - tmpsize -= (curbit / 8) * 8; bit_ffs(tmpmask, tmpsize, &curbit); } diff --git a/sys/net/ieee8023ad_lacp.c b/sys/net/ieee8023ad_lacp.c index 1af4ffc91f20..4863ac98035b 100644 --- a/sys/net/ieee8023ad_lacp.c +++ b/sys/net/ieee8023ad_lacp.c @@ -196,6 +196,11 @@ SYSCTL_NODE(_net_link_lagg, OID_AUTO, lacp, CTLFLAG_RD, 0, "ieee802.3ad"); SYSCTL_INT(_net_link_lagg_lacp, OID_AUTO, debug, CTLFLAG_RWTUN | CTLFLAG_VNET, &VNET_NAME(lacp_debug), 0, "Enable LACP debug logging (1=debug, 2=trace)"); +static VNET_DEFINE(int, lacp_default_strict_mode) = 1; +SYSCTL_INT(_net_link_lagg_lacp, OID_AUTO, default_strict_mode, CTLFLAG_RWTUN, + &VNET_NAME(lacp_default_strict_mode), 0, + "LACP strict protocol compliance default"); + #define LACP_DPRINTF(a) if (V_lacp_debug & 0x01) { lacp_dprintf a ; } #define LACP_TRACE(a) if (V_lacp_debug & 0x02) { lacp_dprintf(a,"%s\n",__func__); } #define LACP_TPRINTF(a) if (V_lacp_debug & 0x04) { lacp_dprintf a ; } @@ -765,7 +770,7 @@ lacp_attach(struct lagg_softc *sc) lsc->lsc_hashkey = m_ether_tcpip_hash_init(); lsc->lsc_active_aggregator = NULL; - lsc->lsc_strict_mode = 1; + lsc->lsc_strict_mode = VNET(lacp_default_strict_mode); LACP_LOCK_INIT(lsc); TAILQ_INIT(&lsc->lsc_aggregators); LIST_INIT(&lsc->lsc_ports); @@ -1702,7 +1707,7 @@ lacp_sm_rx_record_default(struct lacp_port *lp) if (lp->lp_lsc->lsc_strict_mode) lp->lp_partner = lacp_partner_admin_strict; else - lp->lp_partner = lacp_partner_admin_optimistic;; + lp->lp_partner = lacp_partner_admin_optimistic; lp->lp_state |= LACP_STATE_DEFAULTED; lacp_sm_ptx_update_timeout(lp, oldpstate); } diff --git a/sys/net/if_arcsubr.c b/sys/net/if_arcsubr.c index d59c4a04a58f..4944e970e1cc 100644 --- a/sys/net/if_arcsubr.c +++ b/sys/net/if_arcsubr.c @@ -550,15 +550,11 @@ arc_input(struct ifnet *ifp, struct mbuf *m) #ifdef INET case ARCTYPE_IP: m_adj(m, ARC_HDRNEWLEN); - if ((m = ip_fastforward(m)) == NULL) - return; isr = NETISR_IP; break; case ARCTYPE_IP_OLD: m_adj(m, ARC_HDRLEN); - if ((m = ip_fastforward(m)) == NULL) - return; isr = NETISR_IP; break; diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 7bb3d990f69c..71e28ea00166 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -722,8 +722,6 @@ ether_demux(struct ifnet *ifp, struct mbuf *m) switch (ether_type) { #ifdef INET case ETHERTYPE_IP: - if ((m = ip_fastforward(m)) == NULL) - return; isr = NETISR_IP; break; diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c index 4a09fcd9bab8..81b65a634666 100644 --- a/sys/net/if_fddisubr.c +++ b/sys/net/if_fddisubr.c @@ -429,8 +429,6 @@ fddi_input(ifp, m) switch (type) { #ifdef INET case ETHERTYPE_IP: - if ((m = ip_fastforward(m)) == NULL) - return; isr = NETISR_IP; break; diff --git a/sys/net/if_fwsubr.c b/sys/net/if_fwsubr.c index f8ec120de815..626b1cb856fb 100644 --- a/sys/net/if_fwsubr.c +++ b/sys/net/if_fwsubr.c @@ -605,8 +605,6 @@ firewire_input(struct ifnet *ifp, struct mbuf *m, uint16_t src) switch (type) { #ifdef INET case ETHERTYPE_IP: - if ((m = ip_fastforward(m)) == NULL) - return; isr = NETISR_IP; break; diff --git a/sys/net/if_iso88025subr.c b/sys/net/if_iso88025subr.c index 976e41033157..7192998ac05e 100644 --- a/sys/net/if_iso88025subr.c +++ b/sys/net/if_iso88025subr.c @@ -519,8 +519,6 @@ iso88025_input(ifp, m) #ifdef INET case ETHERTYPE_IP: th->iso88025_shost[0] &= ~(TR_RII); - if ((m = ip_fastforward(m)) == NULL) - return; isr = NETISR_IP; break; diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h index e491ba4dd5a9..f21ddf43b4a6 100644 --- a/sys/netinet/in_var.h +++ b/sys/netinet/in_var.h @@ -380,7 +380,7 @@ int in_scrubprefix(struct in_ifaddr *, u_int); void ip_input(struct mbuf *); void ip_direct_input(struct mbuf *); void in_ifadown(struct ifaddr *ifa, int); -struct mbuf *ip_fastforward(struct mbuf *); +struct mbuf *ip_tryforward(struct mbuf *); void *in_domifattach(struct ifnet *); void in_domifdetach(struct ifnet *, void *); diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index 7e4506937680..c09d89550f60 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1769,6 +1769,13 @@ carp_ioctl(struct ifreq *ifr, u_long cmd, struct thread *td) } break; } + case SIOCSIFMTU: + if (ifr->ifr_mtu > ETHERMTU_JUMBO) { + error = EINVAL; + } else { + ifp->if_mtu = ifr->ifr_mtu; + } + break; default: error = EINVAL; } diff --git a/sys/netinet/ip_fastfwd.c b/sys/netinet/ip_fastfwd.c index 09ca4d70033d..22eb727620f6 100644 --- a/sys/netinet/ip_fastfwd.c +++ b/sys/netinet/ip_fastfwd.c @@ -108,12 +108,6 @@ __FBSDID("$FreeBSD$"); #include -static VNET_DEFINE(int, ipfastforward_active); -#define V_ipfastforward_active VNET(ipfastforward_active) - -SYSCTL_INT(_net_inet_ip, OID_AUTO, fastforwarding, CTLFLAG_VNET | CTLFLAG_RW, - &VNET_NAME(ipfastforward_active), 0, "Enable fast IP forwarding"); - static struct sockaddr_in * ip_findroute(struct route *ro, struct in_addr dest, struct mbuf *m) { @@ -158,7 +152,7 @@ ip_findroute(struct route *ro, struct in_addr dest, struct mbuf *m) * to ip_input for full processing. */ struct mbuf * -ip_fastforward(struct mbuf *m) +ip_tryforward(struct mbuf *m) { struct ip *ip; struct mbuf *m0 = NULL; @@ -166,119 +160,20 @@ ip_fastforward(struct mbuf *m) struct sockaddr_in *dst = NULL; struct ifnet *ifp; struct in_addr odest, dest; - uint16_t sum, ip_len, ip_off; + uint16_t ip_len, ip_off; int error = 0; - int hlen, mtu; + int mtu; struct m_tag *fwd_tag = NULL; /* * Are we active and forwarding packets? */ - if (!V_ipfastforward_active || !V_ipforwarding) - return m; M_ASSERTVALID(m); M_ASSERTPKTHDR(m); bzero(&ro, sizeof(ro)); - /* - * Step 1: check for packet drop conditions (and sanity checks) - */ - - /* - * Is entire packet big enough? - */ - if (m->m_pkthdr.len < sizeof(struct ip)) { - IPSTAT_INC(ips_tooshort); - goto drop; - } - - /* - * Is first mbuf large enough for ip header and is header present? - */ - if (m->m_len < sizeof (struct ip) && - (m = m_pullup(m, sizeof (struct ip))) == NULL) { - IPSTAT_INC(ips_toosmall); - return NULL; /* mbuf already free'd */ - } - - ip = mtod(m, struct ip *); - - /* - * Is it IPv4? - */ - if (ip->ip_v != IPVERSION) { - IPSTAT_INC(ips_badvers); - goto drop; - } - - /* - * Is IP header length correct and is it in first mbuf? - */ - hlen = ip->ip_hl << 2; - if (hlen < sizeof(struct ip)) { /* minimum header length */ - IPSTAT_INC(ips_badhlen); - goto drop; - } - if (hlen > m->m_len) { - if ((m = m_pullup(m, hlen)) == NULL) { - IPSTAT_INC(ips_badhlen); - return NULL; /* mbuf already free'd */ - } - ip = mtod(m, struct ip *); - } - - /* - * Checksum correct? - */ - if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) - sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID); - else { - if (hlen == sizeof(struct ip)) - sum = in_cksum_hdr(ip); - else - sum = in_cksum(m, hlen); - } - if (sum) { - IPSTAT_INC(ips_badsum); - goto drop; - } - - /* - * Remember that we have checked the IP header and found it valid. - */ - m->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED | CSUM_IP_VALID); - - ip_len = ntohs(ip->ip_len); - - /* - * Is IP length longer than packet we have got? - */ - if (m->m_pkthdr.len < ip_len) { - IPSTAT_INC(ips_tooshort); - goto drop; - } - - /* - * Is packet longer than IP header tells us? If yes, truncate packet. - */ - if (m->m_pkthdr.len > ip_len) { - if (m->m_len == m->m_pkthdr.len) { - m->m_len = ip_len; - m->m_pkthdr.len = ip_len; - } else - m_adj(m, ip_len - m->m_pkthdr.len); - } - - /* - * Is packet from or to 127/8? - */ - if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET || - (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) { - IPSTAT_INC(ips_badaddr); - goto drop; - } #ifdef ALTQ /* @@ -288,13 +183,11 @@ ip_fastforward(struct mbuf *m) goto drop; #endif - /* - * Step 2: fallback conditions to normal ip_input path processing - */ - /* * Only IP packets without options */ + ip = mtod(m, struct ip *); + if (ip->ip_hl != (sizeof(struct ip) >> 2)) { if (V_ip_doopts == 1) return m; diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h index d1764bbf5f1a..e52ff1a54cb3 100644 --- a/sys/netinet/ip_fw.h +++ b/sys/netinet/ip_fw.h @@ -107,6 +107,7 @@ typedef struct _ip_fw3_opheader { #define IP_FW_NAT44_XGETLOG 115 /* Get log from NAT44 instance */ #define IP_FW_DUMP_SOPTCODES 116 /* Dump available sopts/versions */ +#define IP_FW_DUMP_SRVOBJECTS 117 /* Dump existing named objects */ /* * The kernel representation of ipfw rules is made of a list of diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index a4060800194e..4998b146cb66 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -79,6 +79,8 @@ __FBSDID("$FreeBSD$"); #include #ifdef IPSEC #include +#include +#include #endif /* IPSEC */ #include @@ -500,12 +502,22 @@ ip_input(struct mbuf *m) m_adj(m, ip_len - m->m_pkthdr.len); } + /* Try to forward the packet, but if we fail continue */ #ifdef IPSEC + /* For now we do not handle IPSEC in tryforward. */ + if (!key_havesp(IPSEC_DIR_INBOUND) && !key_havesp(IPSEC_DIR_OUTBOUND) && + (V_ipforwarding == 1)) + if (ip_tryforward(m) == NULL) + return; /* * Bypass packet filtering for packets previously handled by IPsec. */ if (ip_ipsec_filtertunnel(m)) goto passin; +#else + if (V_ipforwarding == 1) + if (ip_tryforward(m) == NULL) + return; #endif /* IPSEC */ /* diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index 34f4bfd9d2dc..9c72d8bd124b 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -223,9 +223,9 @@ sctp_build_ctl_nchunk(struct sctp_inpcb *inp, struct sctp_sndrcvinfo *sinfo) } seinfo = (struct sctp_extrcvinfo *)sinfo; if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO) && - (seinfo->sreinfo_next_flags & SCTP_NEXT_MSG_AVAIL)) { + (seinfo->serinfo_next_flags & SCTP_NEXT_MSG_AVAIL)) { provide_nxt = 1; - len += CMSG_SPACE(sizeof(struct sctp_rcvinfo)); + len += CMSG_SPACE(sizeof(struct sctp_nxtinfo)); } else { provide_nxt = 0; } @@ -276,20 +276,20 @@ sctp_build_ctl_nchunk(struct sctp_inpcb *inp, struct sctp_sndrcvinfo *sinfo) cmh->cmsg_len = CMSG_LEN(sizeof(struct sctp_nxtinfo)); cmh->cmsg_type = SCTP_NXTINFO; nxtinfo = (struct sctp_nxtinfo *)CMSG_DATA(cmh); - nxtinfo->nxt_sid = seinfo->sreinfo_next_stream; + nxtinfo->nxt_sid = seinfo->serinfo_next_stream; nxtinfo->nxt_flags = 0; - if (seinfo->sreinfo_next_flags & SCTP_NEXT_MSG_IS_UNORDERED) { + if (seinfo->serinfo_next_flags & SCTP_NEXT_MSG_IS_UNORDERED) { nxtinfo->nxt_flags |= SCTP_UNORDERED; } - if (seinfo->sreinfo_next_flags & SCTP_NEXT_MSG_IS_NOTIFICATION) { + if (seinfo->serinfo_next_flags & SCTP_NEXT_MSG_IS_NOTIFICATION) { nxtinfo->nxt_flags |= SCTP_NOTIFICATION; } - if (seinfo->sreinfo_next_flags & SCTP_NEXT_MSG_ISCOMPLETE) { + if (seinfo->serinfo_next_flags & SCTP_NEXT_MSG_ISCOMPLETE) { nxtinfo->nxt_flags |= SCTP_COMPLETE; } - nxtinfo->nxt_ppid = seinfo->sreinfo_next_ppid; - nxtinfo->nxt_length = seinfo->sreinfo_next_length; - nxtinfo->nxt_assoc_id = seinfo->sreinfo_next_aid; + nxtinfo->nxt_ppid = seinfo->serinfo_next_ppid; + nxtinfo->nxt_length = seinfo->serinfo_next_length; + nxtinfo->nxt_assoc_id = seinfo->serinfo_next_aid; cmh = (struct cmsghdr *)((caddr_t)cmh + CMSG_SPACE(sizeof(struct sctp_nxtinfo))); SCTP_BUF_LEN(ret) += CMSG_SPACE(sizeof(struct sctp_nxtinfo)); } diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h index 619638331380..cfc79788adda 100644 --- a/sys/netinet/sctp_uio.h +++ b/sys/netinet/sctp_uio.h @@ -134,20 +134,27 @@ struct sctp_extrcvinfo { uint16_t sinfo_flags; uint32_t sinfo_ppid; uint32_t sinfo_context; - uint32_t sinfo_timetolive; + uint32_t sinfo_timetolive; /* should have been sinfo_pr_value */ uint32_t sinfo_tsn; uint32_t sinfo_cumtsn; sctp_assoc_t sinfo_assoc_id; - uint16_t sreinfo_next_flags; - uint16_t sreinfo_next_stream; - uint32_t sreinfo_next_aid; - uint32_t sreinfo_next_length; - uint32_t sreinfo_next_ppid; + uint16_t serinfo_next_flags; + uint16_t serinfo_next_stream; + uint32_t serinfo_next_aid; + uint32_t serinfo_next_length; + uint32_t serinfo_next_ppid; uint16_t sinfo_keynumber; uint16_t sinfo_keynumber_valid; uint8_t __reserve_pad[SCTP_ALIGN_RESV_PAD_SHORT]; }; +#define sinfo_pr_value sinfo_timetolive +#define sreinfo_next_flags serinfo_next_flags +#define sreinfo_next_stream serinfo_next_stream +#define sreinfo_next_aid serinfo_next_aid +#define sreinfo_next_length serinfo_next_length +#define sreinfo_next_ppid serinfo_next_ppid + struct sctp_sndinfo { uint16_t snd_sid; uint16_t snd_flags; diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index e451cb18d382..cae0e2645880 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -5654,20 +5654,20 @@ sctp_sorecvmsg(struct socket *so, s_extra = (struct sctp_extrcvinfo *)sinfo; if ((nxt) && (nxt->length)) { - s_extra->sreinfo_next_flags = SCTP_NEXT_MSG_AVAIL; + s_extra->serinfo_next_flags = SCTP_NEXT_MSG_AVAIL; if (nxt->sinfo_flags & SCTP_UNORDERED) { - s_extra->sreinfo_next_flags |= SCTP_NEXT_MSG_IS_UNORDERED; + s_extra->serinfo_next_flags |= SCTP_NEXT_MSG_IS_UNORDERED; } if (nxt->spec_flags & M_NOTIFICATION) { - s_extra->sreinfo_next_flags |= SCTP_NEXT_MSG_IS_NOTIFICATION; + s_extra->serinfo_next_flags |= SCTP_NEXT_MSG_IS_NOTIFICATION; } - s_extra->sreinfo_next_aid = nxt->sinfo_assoc_id; - s_extra->sreinfo_next_length = nxt->length; - s_extra->sreinfo_next_ppid = nxt->sinfo_ppid; - s_extra->sreinfo_next_stream = nxt->sinfo_stream; + s_extra->serinfo_next_aid = nxt->sinfo_assoc_id; + s_extra->serinfo_next_length = nxt->length; + s_extra->serinfo_next_ppid = nxt->sinfo_ppid; + s_extra->serinfo_next_stream = nxt->sinfo_stream; if (nxt->tail_mbuf != NULL) { if (nxt->end_added) { - s_extra->sreinfo_next_flags |= SCTP_NEXT_MSG_ISCOMPLETE; + s_extra->serinfo_next_flags |= SCTP_NEXT_MSG_ISCOMPLETE; } } } else { @@ -5678,11 +5678,11 @@ sctp_sorecvmsg(struct socket *so, * :-D */ nxt = NULL; - s_extra->sreinfo_next_flags = SCTP_NO_NEXT_MSG; - s_extra->sreinfo_next_aid = 0; - s_extra->sreinfo_next_length = 0; - s_extra->sreinfo_next_ppid = 0; - s_extra->sreinfo_next_stream = 0; + s_extra->serinfo_next_flags = SCTP_NO_NEXT_MSG; + s_extra->serinfo_next_aid = 0; + s_extra->serinfo_next_length = 0; + s_extra->serinfo_next_ppid = 0; + s_extra->serinfo_next_stream = 0; } } /* @@ -6165,7 +6165,7 @@ sctp_sorecvmsg(struct socket *so, struct sctp_extrcvinfo *s_extra; s_extra = (struct sctp_extrcvinfo *)sinfo; - s_extra->sreinfo_next_flags = SCTP_NO_NEXT_MSG; + s_extra->serinfo_next_flags = SCTP_NO_NEXT_MSG; } if (hold_rlock == 1) { SCTP_INP_READ_UNLOCK(inp); diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 10c3cdca9cdd..4caea80935bc 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -149,7 +149,7 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, drop_synfin, CTLFLAG_VNET | CTLFLAG_RW, "Drop TCP packets with SYN+FIN set"); VNET_DEFINE(int, tcp_do_rfc6675_pipe) = 0; -SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_pipe, CTLFLAG_VNET | CTLFLAG_RW, +SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc6675_pipe, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_rfc6675_pipe), 0, "Use calculated pipe/in-flight bytes per RFC 6675"); diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c index dba0cf30be67..2f2b86997ade 100644 --- a/sys/netinet6/frag6.c +++ b/sys/netinet6/frag6.c @@ -32,6 +32,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_rss.h" + #include #include #include @@ -46,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -159,6 +162,11 @@ frag6_input(struct mbuf **mp, int *offp, int proto) int fragoff, frgpartlen; /* must be larger than u_int16_t */ struct ifnet *dstifp; u_int8_t ecn, ecn0; +#ifdef RSS + struct m_tag *mtag; + struct ip6_direct_ctx *ip6dc; +#endif + #if 0 char ip6buf[INET6_ADDRSTRLEN]; #endif @@ -577,9 +585,31 @@ frag6_input(struct mbuf **mp, int *offp, int proto) m->m_pkthdr.len = plen; } +#ifdef RSS + mtag = m_tag_alloc(MTAG_ABI_IPV6, IPV6_TAG_DIRECT, sizeof(*ip6dc), + M_NOWAIT); + if (mtag == NULL) + goto dropfrag; + + ip6dc = (struct ip6_direct_ctx *)(mtag + 1); + ip6dc->ip6dc_nxt = nxt; + ip6dc->ip6dc_off = offset; + + m_tag_prepend(m, mtag); +#endif + + IP6Q_UNLOCK(); IP6STAT_INC(ip6s_reassembled); in6_ifstat_inc(dstifp, ifs6_reass_ok); +#ifdef RSS + /* + * Queue/dispatch for reprocessing. + */ + netisr_dispatch(NETISR_IPV6_DIRECT, m); + return IPPROTO_DONE; +#endif + /* * Tell launch routine the next header */ @@ -587,7 +617,6 @@ frag6_input(struct mbuf **mp, int *offp, int proto) *mp = m; *offp = offset; - IP6Q_UNLOCK(); return nxt; dropfrag: diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index 81d8d318cdc4..8f08c8f195fa 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -382,6 +382,11 @@ struct route_in6 { }; #endif +#ifdef _KERNEL +#define MTAG_ABI_IPV6 1444287380 /* IPv6 ABI */ +#define IPV6_TAG_DIRECT 0 /* direct-dispatch IPv6 */ +#endif /* _KERNEL */ + /* * Options for use with [gs]etsockopt at the IPV6 level. * First word of comment is data type; bool is stored in int. diff --git a/sys/netinet6/in6_rss.c b/sys/netinet6/in6_rss.c index 6fe56eb14e5f..72dd0a8831af 100644 --- a/sys/netinet6/in6_rss.c +++ b/sys/netinet6/in6_rss.c @@ -172,6 +172,7 @@ rss_mbuf_software_hash_v6(const struct mbuf *m, int dir, uint32_t *hashval, uint32_t *hashtype) { const struct ip6_hdr *ip6; + const struct ip6_frag *ip6f; const struct tcphdr *th; const struct udphdr *uh; uint32_t flowtype; @@ -221,6 +222,26 @@ rss_mbuf_software_hash_v6(const struct mbuf *m, int dir, uint32_t *hashval, proto = nxt; } + /* + * Ignore the fragment header if this is an "atomic" fragment + * (offset and m bit set to 0) + */ + if (proto == IPPROTO_FRAGMENT) { + if (m->m_len < off + sizeof(struct ip6_frag)) { + RSS_DEBUG("short fragment frame?\n"); + return (-1); + } + ip6f = (const struct ip6_frag *)((c_caddr_t)ip6 + off); + if ((ip6f->ip6f_offlg & ~IP6F_RESERVED_MASK) == 0) { + off = ip6_lasthdr(m, off, proto, &nxt); + if (off < 0) { + RSS_DEBUG("invalid extension header\n"); + return (-1); + } + proto = nxt; + } + } + /* * If the mbuf flowid/flowtype matches the packet type, * and we don't support the 4-tuple version of the given protocol, diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index fc3816806797..577dc48e7ece 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -144,6 +144,17 @@ static struct netisr_handler ip6_nh = { #endif }; +#ifdef RSS +static struct netisr_handler ip6_direct_nh = { + .nh_name = "ip6_direct", + .nh_handler = ip6_direct_input, + .nh_proto = NETISR_IPV6_DIRECT, + .nh_m2cpuid = rss_soft_m2cpuid_v6, + .nh_policy = NETISR_POLICY_CPU, + .nh_dispatch = NETISR_DISPATCH_HYBRID, +}; +#endif + VNET_DECLARE(struct callout, in6_tmpaddrtimer_ch); #define V_in6_tmpaddrtimer_ch VNET(in6_tmpaddrtimer_ch) @@ -222,6 +233,9 @@ ip6_init(void) } netisr_register(&ip6_nh); +#ifdef RSS + netisr_register(&ip6_direct_nh); +#endif } /* @@ -403,6 +417,66 @@ ip6_input_hbh(struct mbuf *m, uint32_t *plen, uint32_t *rtalert, int *off, return (1); } +#ifdef RSS +/* + * IPv6 direct input routine. + * + * This is called when reinjecting completed fragments where + * all of the previous checking and book-keeping has been done. + */ +void +ip6_direct_input(struct mbuf *m) +{ + int off, nxt; + int nest; + struct m_tag *mtag; + struct ip6_direct_ctx *ip6dc; + + mtag = m_tag_locate(m, MTAG_ABI_IPV6, IPV6_TAG_DIRECT, NULL); + KASSERT(mtag != NULL, ("Reinjected packet w/o direct ctx tag!")); + + ip6dc = (struct ip6_direct_ctx *)(mtag + 1); + nxt = ip6dc->ip6dc_nxt; + off = ip6dc->ip6dc_off; + + nest = 0; + + m_tag_delete(m, mtag); + + while (nxt != IPPROTO_DONE) { + if (V_ip6_hdrnestlimit && (++nest > V_ip6_hdrnestlimit)) { + IP6STAT_INC(ip6s_toomanyhdr); + goto bad; + } + + /* + * protection against faulty packet - there should be + * more sanity checks in header chain processing. + */ + if (m->m_pkthdr.len < off) { + IP6STAT_INC(ip6s_tooshort); + in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); + goto bad; + } + +#ifdef IPSEC + /* + * enforce IPsec policy checking if we are seeing last header. + * note that we do not visit this with protocols with pcb layer + * code - like udp/tcp/raw ip. + */ + if (ip6_ipsec_input(m, nxt)) + goto bad; +#endif /* IPSEC */ + + nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); + } + return; +bad: + m_freem(m); +} +#endif + void ip6_input(struct mbuf *m) { @@ -712,6 +786,13 @@ ip6_input(struct mbuf *m) } else nxt = ip6->ip6_nxt; + /* + * Use mbuf flags to propagate Router Alert option to + * ICMPv6 layer, as hop-by-hop options have been stripped. + */ + if (rtalert != ~0) + m->m_flags |= M_RTALERT_MLD; + /* * Check that the amount of data in the buffers * is as at least much as the IPv6 header would have us expect. @@ -809,13 +890,6 @@ ip6_input(struct mbuf *m) goto bad; #endif /* IPSEC */ - /* - * Use mbuf flags to propagate Router Alert option to - * ICMPv6 layer, as hop-by-hop options have been stripped. - */ - if (nxt == IPPROTO_ICMPV6 && rtalert != ~0) - m->m_flags |= M_RTALERT_MLD; - nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); } return; diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index d48951828887..2159f29536e7 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -98,6 +98,14 @@ struct ip6asfrag { #define IP6_REASS_MBUF(ip6af) (*(struct mbuf **)&((ip6af)->ip6af_m)) +/* + * IP6 reinjecting structure. + */ +struct ip6_direct_ctx { + uint32_t ip6dc_nxt; /* next header to process */ + uint32_t ip6dc_off; /* offset to next header */ +}; + /* * Structure attached to inpcb.in6p_moptions and * passed to ip6_output when IPv6 multicast options are in use. @@ -353,6 +361,7 @@ int ip6proto_register(short); int ip6proto_unregister(short); void ip6_input(struct mbuf *); +void ip6_direct_input(struct mbuf *); void ip6_freepcbopts(struct ip6_pktopts *); int ip6_unknown_opt(u_int8_t *, struct mbuf *, int); diff --git a/sys/netpfil/ipfw/ip_fw_private.h b/sys/netpfil/ipfw/ip_fw_private.h index e39b32ddc577..b36ca3f7c434 100644 --- a/sys/netpfil/ipfw/ip_fw_private.h +++ b/sys/netpfil/ipfw/ip_fw_private.h @@ -673,6 +673,7 @@ int ipfw_objhash_free_idx(struct namedobj_instance *ni, uint16_t idx); int ipfw_objhash_alloc_idx(void *n, uint16_t *pidx); void ipfw_objhash_set_funcs(struct namedobj_instance *ni, objhash_hash_f *hash_f, objhash_cmp_f *cmp_f); +void ipfw_export_obj_ntlv(struct named_object *no, ipfw_obj_ntlv *ntlv); void ipfw_init_obj_rewriter(void); void ipfw_destroy_obj_rewriter(void); void ipfw_add_obj_rewriter(struct opcode_obj_rewrite *rw, size_t count); @@ -692,6 +693,7 @@ void update_opcode_kidx(ipfw_insn *cmd, uint16_t idx); int classify_opcode_kidx(ipfw_insn *cmd, uint16_t *puidx); void ipfw_init_srv(struct ip_fw_chain *ch); void ipfw_destroy_srv(struct ip_fw_chain *ch); +int ipfw_check_object_name_generic(const char *name); /* In ip_fw_table.c */ struct table_info; diff --git a/sys/netpfil/ipfw/ip_fw_sockopt.c b/sys/netpfil/ipfw/ip_fw_sockopt.c index 7ed4c1d055c3..4ae896115037 100644 --- a/sys/netpfil/ipfw/ip_fw_sockopt.c +++ b/sys/netpfil/ipfw/ip_fw_sockopt.c @@ -119,6 +119,8 @@ static int manage_sets(struct ip_fw_chain *chain, ip_fw3_opheader *op3, struct sockopt_data *sd); static int dump_soptcodes(struct ip_fw_chain *chain, ip_fw3_opheader *op3, struct sockopt_data *sd); +static int dump_srvobjects(struct ip_fw_chain *chain, ip_fw3_opheader *op3, + struct sockopt_data *sd); /* ctl3 handler data */ struct mtx ctl3_lock; @@ -146,6 +148,7 @@ static struct ipfw_sopt_handler scodes[] = { { IP_FW_SET_MOVE, 0, HDIR_SET, manage_sets }, { IP_FW_SET_ENABLE, 0, HDIR_SET, manage_sets }, { IP_FW_DUMP_SOPTCODES, 0, HDIR_GET, dump_soptcodes }, + { IP_FW_DUMP_SRVOBJECTS,0, HDIR_GET, dump_srvobjects }, }; static int @@ -1602,10 +1605,9 @@ check_ipfw_rule_body(ipfw_insn *cmd, int cmd_len, struct rule_check_info *ci) case O_RECV: case O_XMIT: case O_VIA: - if (((ipfw_insn_if *)cmd)->name[0] == '\1') - ci->object_opcodes++; if (cmdlen != F_INSN_SIZE(ipfw_insn_if)) goto bad_size; + ci->object_opcodes++; break; case O_ALTQ: @@ -1876,6 +1878,16 @@ struct dump_args { int rcounters; /* counters */ }; +void +ipfw_export_obj_ntlv(struct named_object *no, ipfw_obj_ntlv *ntlv) +{ + + ntlv->head.type = no->etlv; + ntlv->head.length = sizeof(*ntlv); + ntlv->idx = no->kidx; + strlcpy(ntlv->name, no->name, sizeof(ntlv->name)); +} + /* * Export named object info in instance @ni, identified by @kidx * to ipfw_obj_ntlv. TLV is allocated from @sd space. @@ -1896,11 +1908,7 @@ export_objhash_ntlv(struct namedobj_instance *ni, uint16_t kidx, if (ntlv == NULL) return (ENOMEM); - ntlv->head.type = no->etlv; - ntlv->head.length = sizeof(*ntlv); - ntlv->idx = no->kidx; - strlcpy(ntlv->name, no->name, sizeof(ntlv->name)); - + ipfw_export_obj_ntlv(no, ntlv); return (0); } @@ -2147,19 +2155,16 @@ dump_config(struct ip_fw_chain *chain, ip_fw3_opheader *op3, return (error); } -static int -check_object_name(ipfw_obj_ntlv *ntlv) +int +ipfw_check_object_name_generic(const char *name) { - int error; - - switch (ntlv->head.type) { - case IPFW_TLV_TBL_NAME: - error = ipfw_check_table_name(ntlv->name); - break; - default: - error = ENOTSUP; - } + int nsize; + nsize = sizeof(((ipfw_obj_ntlv *)0)->name); + if (strnlen(name, nsize) == nsize) + return (EINVAL); + if (name[0] == '\0') + return (EINVAL); return (0); } @@ -2474,7 +2479,7 @@ add_rules(struct ip_fw_chain *chain, ip_fw3_opheader *op3, if (ntlv->head.length != sizeof(ipfw_obj_ntlv)) return (EINVAL); - error = check_object_name(ntlv); + error = ipfw_check_object_name_generic(ntlv->name); if (error != 0) return (error); @@ -2803,6 +2808,54 @@ ipfw_del_obj_rewriter(struct opcode_obj_rewrite *rw, size_t count) return (0); } +static void +export_objhash_ntlv_internal(struct namedobj_instance *ni, + struct named_object *no, void *arg) +{ + struct sockopt_data *sd; + ipfw_obj_ntlv *ntlv; + + sd = (struct sockopt_data *)arg; + ntlv = (ipfw_obj_ntlv *)ipfw_get_sopt_space(sd, sizeof(*ntlv)); + if (ntlv == NULL) + return; + ipfw_export_obj_ntlv(no, ntlv); +} + +/* + * Lists all service objects. + * Data layout (v0)(current): + * Request: [ ipfw_obj_lheader ] size = ipfw_cfg_lheader.size + * Reply: [ ipfw_obj_lheader [ ipfw_obj_ntlv x N ] (optional) ] + * Returns 0 on success + */ +static int +dump_srvobjects(struct ip_fw_chain *chain, ip_fw3_opheader *op3, + struct sockopt_data *sd) +{ + ipfw_obj_lheader *hdr; + int count; + + hdr = (ipfw_obj_lheader *)ipfw_get_sopt_header(sd, sizeof(*hdr)); + if (hdr == NULL) + return (EINVAL); + + IPFW_UH_RLOCK(chain); + count = ipfw_objhash_count(CHAIN_TO_SRV(chain)); + hdr->size = sizeof(ipfw_obj_lheader) + count * sizeof(ipfw_obj_ntlv); + if (sd->valsize < hdr->size) { + IPFW_UH_RUNLOCK(chain); + return (ENOMEM); + } + hdr->count = count; + hdr->objsize = sizeof(ipfw_obj_ntlv); + if (count > 0) + ipfw_objhash_foreach(CHAIN_TO_SRV(chain), + export_objhash_ntlv_internal, sd); + IPFW_UH_RUNLOCK(chain); + return (0); +} + /* * Compares two sopt handlers (code, version and handler ptr). * Used both as qsort() and bsearch(). diff --git a/sys/netpfil/ipfw/ip_fw_table.c b/sys/netpfil/ipfw/ip_fw_table.c index f9425415c3c4..71c96b278d3e 100644 --- a/sys/netpfil/ipfw/ip_fw_table.c +++ b/sys/netpfil/ipfw/ip_fw_table.c @@ -115,6 +115,7 @@ static int dump_table_xentry(void *e, void *arg); static int swap_tables(struct ip_fw_chain *ch, struct tid_info *a, struct tid_info *b); +static int check_table_name(const char *name); static int check_table_space(struct ip_fw_chain *ch, struct tableop_state *ts, struct table_config *tc, struct table_info *ti, uint32_t count); static int destroy_table(struct ip_fw_chain *ch, struct tid_info *ti); @@ -1794,7 +1795,7 @@ modify_table(struct ip_fw_chain *ch, ip_fw3_opheader *op3, * Check for null-terminated/zero-length strings/ */ tname = oh->ntlv.name; - if (ipfw_check_table_name(tname) != 0) + if (check_table_name(tname) != 0) return (EINVAL); objheader_to_ti(oh, &ti); @@ -1851,7 +1852,7 @@ create_table(struct ip_fw_chain *ch, ip_fw3_opheader *op3, */ tname = oh->ntlv.name; aname = i->algoname; - if (ipfw_check_table_name(tname) != 0 || + if (check_table_name(tname) != 0 || strnlen(aname, sizeof(i->algoname)) == sizeof(i->algoname)) return (EINVAL); @@ -2915,25 +2916,14 @@ static struct opcode_obj_rewrite opcodes[] = { * * Returns 0 if name is considered valid. */ -int -ipfw_check_table_name(char *name) +static int +check_table_name(const char *name) { - int nsize; - ipfw_obj_ntlv *ntlv = NULL; - - nsize = sizeof(ntlv->name); - - if (strnlen(name, nsize) == nsize) - return (EINVAL); - - if (name[0] == '\0') - return (EINVAL); /* * TODO: do some more complicated checks */ - - return (0); + return (ipfw_check_object_name_generic(name)); } /* @@ -2965,7 +2955,7 @@ find_name_tlv(void *tlvs, int len, uint16_t uidx) if (ntlv->idx != uidx) continue; - if (ipfw_check_table_name(ntlv->name) != 0) + if (check_table_name(ntlv->name) != 0) return (NULL); return (ntlv); @@ -3398,18 +3388,15 @@ ref_rule_objects(struct ip_fw_chain *ch, struct ip_fw *rule, IPFW_UH_WUNLOCK(ch); return (error); } - IPFW_UH_WUNLOCK(ch); - found = pidx - oib; - KASSERT(found == ci->object_opcodes, - ("refcount inconsistency: found: %d total: %d", - found, ci->object_opcodes)); - /* Perform auto-creation for non-existing objects */ if (numnew != 0) error = create_objects_compat(ch, rule->cmd, oib, pidx, ti); + /* Calculate real number of dynamic objects */ + ci->object_opcodes = (uint16_t)(pidx - oib); + return (error); } @@ -3441,7 +3428,6 @@ ipfw_rewrite_rule_uidx(struct ip_fw_chain *chain, pidx_first = malloc(ci->object_opcodes * sizeof(struct obj_idx), M_IPFW, M_WAITOK | M_ZERO); - pidx_last = pidx_first + ci->object_opcodes; error = 0; type = 0; memset(&ti, 0, sizeof(ti)); @@ -3460,9 +3446,14 @@ ipfw_rewrite_rule_uidx(struct ip_fw_chain *chain, error = ref_rule_objects(chain, ci->krule, ci, pidx_first, &ti); if (error != 0) goto free; + /* + * Note that ref_rule_objects() might have updated ci->object_opcodes + * to reflect actual number of object opcodes. + */ /* Perform rule rewrite */ p = pidx_first; + pidx_last = pidx_first + ci->object_opcodes; for (p = pidx_first; p < pidx_last; p++) { cmd = ci->krule->cmd + p->off; update_opcode_kidx(cmd, p->kidx); diff --git a/sys/netpfil/ipfw/ip_fw_table.h b/sys/netpfil/ipfw/ip_fw_table.h index ca49fd47b69e..d6578482fb33 100644 --- a/sys/netpfil/ipfw/ip_fw_table.h +++ b/sys/netpfil/ipfw/ip_fw_table.h @@ -187,7 +187,6 @@ void ipfw_unref_rule_tables(struct ip_fw_chain *chain, struct ip_fw *rule); struct namedobj_instance *ipfw_get_table_objhash(struct ip_fw_chain *ch); /* utility functions */ -int ipfw_check_table_name(char *name); int ipfw_move_tables_sets(struct ip_fw_chain *ch, ipfw_range_tlv *rt, uint32_t new_set); void ipfw_swap_tables_sets(struct ip_fw_chain *ch, uint32_t old_set, diff --git a/sys/powerpc/mpc85xx/pci_mpc85xx.c b/sys/powerpc/mpc85xx/pci_mpc85xx.c index c3610cd046dd..70bdb72e658b 100644 --- a/sys/powerpc/mpc85xx/pci_mpc85xx.c +++ b/sys/powerpc/mpc85xx/pci_mpc85xx.c @@ -129,11 +129,11 @@ static void fsl_pcib_cfgwrite(struct fsl_pcib_softc *, u_int, u_int, u_int, u_int, uint32_t, int); static int fsl_pcib_decode_win(phandle_t, struct fsl_pcib_softc *); static void fsl_pcib_err_init(device_t); -static void fsl_pcib_inbound(struct fsl_pcib_softc *, int, int, u_long, - u_long, u_long); +static void fsl_pcib_inbound(struct fsl_pcib_softc *, int, int, uint64_t, + uint64_t, uint64_t); static int fsl_pcib_init(struct fsl_pcib_softc *, int, int); -static void fsl_pcib_outbound(struct fsl_pcib_softc *, int, int, u_long, - u_long, u_long); +static void fsl_pcib_outbound(struct fsl_pcib_softc *, int, int, uint64_t, + uint64_t, uint64_t); /* Forward declerations. */ static int fsl_pcib_attach(device_t); @@ -645,8 +645,8 @@ fsl_pcib_init(struct fsl_pcib_softc *sc, int bus, int maxslot) } static void -fsl_pcib_inbound(struct fsl_pcib_softc *sc, int wnd, int tgt, u_long start, - u_long size, u_long pci_start) +fsl_pcib_inbound(struct fsl_pcib_softc *sc, int wnd, int tgt, uint64_t start, + uint64_t size, uint64_t pci_start) { uint32_t attr, bar, tar; @@ -671,8 +671,8 @@ fsl_pcib_inbound(struct fsl_pcib_softc *sc, int wnd, int tgt, u_long start, } static void -fsl_pcib_outbound(struct fsl_pcib_softc *sc, int wnd, int res, u_long start, - u_long size, u_long pci_start) +fsl_pcib_outbound(struct fsl_pcib_softc *sc, int wnd, int res, uint64_t start, + uint64_t size, uint64_t pci_start) { uint32_t attr, bar, tar; @@ -782,9 +782,9 @@ fsl_pcib_decode_win(phandle_t node, struct fsl_pcib_softc *sc) sc->pci_sc.sc_range[i].host, sc->pci_sc.sc_range[i].size, sc->pci_sc.sc_range[i].pci); - sc->sc_ioport_start = sc->pci_sc.sc_range[i].host; - sc->sc_ioport_end = sc->pci_sc.sc_range[i].host + - sc->pci_sc.sc_range[i].size; + sc->sc_ioport_start = sc->pci_sc.sc_range[i].pci; + sc->sc_ioport_end = sc->pci_sc.sc_range[i].pci + + sc->pci_sc.sc_range[i].size - 1; sc->sc_ioport_alloc = 0x1000 + sc->pci_sc.sc_range[i].pci; break; case OFW_PCI_PHYS_HI_SPACE_MEM32: @@ -794,9 +794,9 @@ fsl_pcib_decode_win(phandle_t node, struct fsl_pcib_softc *sc) sc->pci_sc.sc_range[i].host, sc->pci_sc.sc_range[i].size, sc->pci_sc.sc_range[i].pci); - sc->sc_iomem_start = sc->pci_sc.sc_range[i].host; - sc->sc_iomem_end = sc->pci_sc.sc_range[i].host + - sc->pci_sc.sc_range[i].size; + sc->sc_iomem_start = sc->pci_sc.sc_range[i].pci; + sc->sc_iomem_end = sc->pci_sc.sc_range[i].pci + + sc->pci_sc.sc_range[i].size - 1; sc->sc_iomem_alloc = sc->pci_sc.sc_range[i].pci; break; default: diff --git a/sys/powerpc/powerpc/busdma_machdep.c b/sys/powerpc/powerpc/busdma_machdep.c index 9ea51ced1de4..1e57d9272ba7 100644 --- a/sys/powerpc/powerpc/busdma_machdep.c +++ b/sys/powerpc/powerpc/busdma_machdep.c @@ -514,14 +514,14 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, /* * XXX: - * (dmat->alignment < dmat->maxsize) is just a quick hack; the exact + * (dmat->alignment <= dmat->maxsize) is just a quick hack; the exact * alignment guarantees of malloc need to be nailed down, and the * code below should be rewritten to take that into account. * * In the meantime, we'll warn the user if malloc gets it wrong. */ if ((dmat->maxsize <= PAGE_SIZE) && - (dmat->alignment < dmat->maxsize) && + (dmat->alignment <= dmat->maxsize) && dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem) && attr == VM_MEMATTR_DEFAULT) { *vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags); diff --git a/sys/powerpc/powerpc/db_interface.c b/sys/powerpc/powerpc/db_interface.c index f3d1f581bf08..d2c7b8b17658 100644 --- a/sys/powerpc/powerpc/db_interface.c +++ b/sys/powerpc/powerpc/db_interface.c @@ -67,8 +67,14 @@ db_write_bytes(vm_offset_t addr, size_t size, char *data) dst = (char *)addr; cnt = size; - while (cnt-- > 0) - *dst++ = *data++; + if (size == 4 && (addr & 3) == 0 && ((uintptr_t)data & 3) == 0) + *((int*)dst) = *((int*)data); + else + if (size == 2 && (addr & 1) == 0 && ((uintptr_t)data & 1) == 0) + *((short*)dst) = *((short*)data); + else + while (cnt-- > 0) + *dst++ = *data++; kdb_cpu_sync_icache((void *)addr, size); } (void)kdb_jmpbuf(prev_jb); diff --git a/sys/sparc64/sparc64/bus_machdep.c b/sys/sparc64/sparc64/bus_machdep.c index 19221a46cc31..873d30ed670d 100644 --- a/sys/sparc64/sparc64/bus_machdep.c +++ b/sys/sparc64/sparc64/bus_machdep.c @@ -518,14 +518,14 @@ nexus_dmamem_alloc(bus_dma_tag_t dmat, void **vaddr, int flags, /* * XXX: - * (dmat->dt_alignment < dmat->dt_maxsize) is just a quick hack; the + * (dmat->dt_alignment <= dmat->dt_maxsize) is just a quick hack; the * exact alignment guarantees of malloc need to be nailed down, and * the code below should be rewritten to take that into account. * * In the meantime, we'll warn the user if malloc gets it wrong. */ if (dmat->dt_maxsize <= PAGE_SIZE && - dmat->dt_alignment < dmat->dt_maxsize) + dmat->dt_alignment <= dmat->dt_maxsize) *vaddr = malloc(dmat->dt_maxsize, M_DEVBUF, mflags); else { /* diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h index 3eaf17bac2bf..59cc45f0e5fa 100644 --- a/sys/sys/cdefs.h +++ b/sys/sys/cdefs.h @@ -459,11 +459,11 @@ #endif #if __GNUC_PREREQ__(4, 0) -#define __sentinel __attribute__((__sentinel__)) +#define __null_sentinel __attribute__((__sentinel__)) #define __exported __attribute__((__visibility__("default"))) #define __hidden __attribute__((__visibility__("hidden"))) #else -#define __sentinel +#define __null_sentinel #define __exported #define __hidden #endif diff --git a/sys/sys/param.h b/sys/sys/param.h index 059c23453ee2..30c248bcc790 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1100085 /* Master, propagated to newvers */ +#define __FreeBSD_version 1100087 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index 4e6c556736d6..950e7127bfc0 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -75,6 +75,10 @@ struct ctlname { #define CTLTYPE_U64 9 /* name describes an unsigned 64-bit number */ #define CTLTYPE_U8 0xa /* name describes an unsigned 8-bit number */ #define CTLTYPE_U16 0xb /* name describes an unsigned 16-bit number */ +#define CTLTYPE_S8 0xc /* name describes a signed 8-bit number */ +#define CTLTYPE_S16 0xd /* name describes a signed 16-bit number */ +#define CTLTYPE_S32 0xe /* name describes a signed 32-bit number */ +#define CTLTYPE_U32 0xf /* name describes an unsigned 32-bit number */ #define CTLFLAG_RD 0x80000000 /* Allow reads of variable */ #define CTLFLAG_WR 0x40000000 /* Allow writes to the variable */ @@ -192,10 +196,11 @@ struct sysctl_oid { int sysctl_handle_8(SYSCTL_HANDLER_ARGS); int sysctl_handle_16(SYSCTL_HANDLER_ARGS); +int sysctl_handle_32(SYSCTL_HANDLER_ARGS); +int sysctl_handle_64(SYSCTL_HANDLER_ARGS); int sysctl_handle_int(SYSCTL_HANDLER_ARGS); int sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS); int sysctl_handle_long(SYSCTL_HANDLER_ARGS); -int sysctl_handle_64(SYSCTL_HANDLER_ARGS); int sysctl_handle_string(SYSCTL_HANDLER_ARGS); int sysctl_handle_opaque(SYSCTL_HANDLER_ARGS); int sysctl_handle_counter_u64(SYSCTL_HANDLER_ARGS); @@ -323,6 +328,26 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry); __arg, len, sysctl_handle_string, "A", __DESCR(descr)); \ }) +/* Oid for a signed 8-bit int. If ptr is NULL, val is returned. */ +#define SYSCTL_NULL_S8_PTR ((unsigned *)NULL) +#define SYSCTL_S8(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_S8 | CTLFLAG_MPSAFE | (access), \ + ptr, val, sysctl_handle_8, "C", descr); \ + CTASSERT((((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S8) && \ + sizeof(int8_t) == sizeof(*(ptr))) + +#define SYSCTL_ADD_S8(ctx, parent, nbr, name, access, ptr, val, descr) \ +({ \ + int8_t *__ptr = (ptr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S8); \ + sysctl_add_oid(ctx, parent, nbr, name, \ + CTLTYPE_S8 | CTLFLAG_MPSAFE | (access), \ + __ptr, val, sysctl_handle_8, "C", __DESCR(descr)); \ +}) + /* Oid for an unsigned 8-bit int. If ptr is NULL, val is returned. */ #define SYSCTL_NULL_U8_PTR ((unsigned *)NULL) #define SYSCTL_U8(parent, nbr, name, access, ptr, val, descr) \ @@ -343,6 +368,26 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry); __ptr, val, sysctl_handle_8, "CU", __DESCR(descr)); \ }) +/* Oid for a signed 16-bit int. If ptr is NULL, val is returned. */ +#define SYSCTL_NULL_S16_PTR ((unsigned *)NULL) +#define SYSCTL_S16(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_S16 | CTLFLAG_MPSAFE | (access), \ + ptr, val, sysctl_handle_16, "S", descr); \ + CTASSERT((((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S16) && \ + sizeof(int16_t) == sizeof(*(ptr))) + +#define SYSCTL_ADD_S16(ctx, parent, nbr, name, access, ptr, val, descr) \ +({ \ + int16_t *__ptr = (ptr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S16); \ + sysctl_add_oid(ctx, parent, nbr, name, \ + CTLTYPE_S16 | CTLFLAG_MPSAFE | (access), \ + __ptr, val, sysctl_handle_16, "S", __DESCR(descr)); \ +}) + /* Oid for an unsigned 16-bit int. If ptr is NULL, val is returned. */ #define SYSCTL_NULL_U16_PTR ((unsigned *)NULL) #define SYSCTL_U16(parent, nbr, name, access, ptr, val, descr) \ @@ -355,7 +400,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry); #define SYSCTL_ADD_U16(ctx, parent, nbr, name, access, ptr, val, descr) \ ({ \ - uint16_t *__ptr = (ptr); \ + uint16_t *__ptr = (ptr); \ CTASSERT(((access) & CTLTYPE) == 0 || \ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U16); \ sysctl_add_oid(ctx, parent, nbr, name, \ @@ -363,6 +408,86 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry); __ptr, val, sysctl_handle_16, "SU", __DESCR(descr)); \ }) +/* Oid for a signed 32-bit int. If ptr is NULL, val is returned. */ +#define SYSCTL_NULL_S32_PTR ((unsigned *)NULL) +#define SYSCTL_S32(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_S32 | CTLFLAG_MPSAFE | (access), \ + ptr, val, sysctl_handle_32, "I", descr); \ + CTASSERT((((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S32) && \ + sizeof(int32_t) == sizeof(*(ptr))) + +#define SYSCTL_ADD_S32(ctx, parent, nbr, name, access, ptr, val, descr) \ +({ \ + int32_t *__ptr = (ptr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S32); \ + sysctl_add_oid(ctx, parent, nbr, name, \ + CTLTYPE_S32 | CTLFLAG_MPSAFE | (access), \ + __ptr, val, sysctl_handle_32, "I", __DESCR(descr)); \ +}) + +/* Oid for an unsigned 32-bit int. If ptr is NULL, val is returned. */ +#define SYSCTL_NULL_U32_PTR ((unsigned *)NULL) +#define SYSCTL_U32(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_U32 | CTLFLAG_MPSAFE | (access), \ + ptr, val, sysctl_handle_32, "IU", descr); \ + CTASSERT((((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U32) && \ + sizeof(uint32_t) == sizeof(*(ptr))) + +#define SYSCTL_ADD_U32(ctx, parent, nbr, name, access, ptr, val, descr) \ +({ \ + uint32_t *__ptr = (ptr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U32); \ + sysctl_add_oid(ctx, parent, nbr, name, \ + CTLTYPE_U32 | CTLFLAG_MPSAFE | (access), \ + __ptr, val, sysctl_handle_32, "IU", __DESCR(descr)); \ +}) + +/* Oid for a signed 64-bit int. If ptr is NULL, val is returned. */ +#define SYSCTL_NULL_S64_PTR ((unsigned *)NULL) +#define SYSCTL_S64(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_S64 | CTLFLAG_MPSAFE | (access), \ + ptr, val, sysctl_handle_64, "Q", descr); \ + CTASSERT((((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S64) && \ + sizeof(int64_t) == sizeof(*(ptr))) + +#define SYSCTL_ADD_S64(ctx, parent, nbr, name, access, ptr, val, descr) \ +({ \ + int64_t *__ptr = (ptr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S64); \ + sysctl_add_oid(ctx, parent, nbr, name, \ + CTLTYPE_S64 | CTLFLAG_MPSAFE | (access), \ + __ptr, val, sysctl_handle_64, "Q", __DESCR(descr)); \ +}) + +/* Oid for an unsigned 64-bit int. If ptr is NULL, val is returned. */ +#define SYSCTL_NULL_U64_PTR ((unsigned *)NULL) +#define SYSCTL_U64(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_U64 | CTLFLAG_MPSAFE | (access), \ + ptr, val, sysctl_handle_64, "QU", descr); \ + CTASSERT((((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U64) && \ + sizeof(uint64_t) == sizeof(*(ptr))) + +#define SYSCTL_ADD_U64(ctx, parent, nbr, name, access, ptr, val, descr) \ +({ \ + uint64_t *__ptr = (ptr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U64); \ + sysctl_add_oid(ctx, parent, nbr, name, \ + CTLTYPE_U64 | CTLFLAG_MPSAFE | (access), \ + __ptr, val, sysctl_handle_64, "QU", __DESCR(descr)); \ +}) + /* Oid for an int. If ptr is SYSCTL_NULL_INT_PTR, val is returned. */ #define SYSCTL_NULL_INT_PTR ((int *)NULL) #define SYSCTL_INT(parent, nbr, name, access, ptr, val, descr) \ @@ -703,6 +828,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry); #define KERN_PROC_OSREL 40 /* osreldate for process binary */ #define KERN_PROC_SIGTRAMP 41 /* signal trampoline location */ #define KERN_PROC_CWD 42 /* process current working directory */ +#define KERN_PROC_NFDS 43 /* number of open file descriptors */ /* * KERN_IPC identifiers diff --git a/sys/x86/x86/busdma_bounce.c b/sys/x86/x86/busdma_bounce.c index ebd6238ef820..5865ca481b59 100644 --- a/sys/x86/x86/busdma_bounce.c +++ b/sys/x86/x86/busdma_bounce.c @@ -398,14 +398,14 @@ bounce_bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, /* * XXX: - * (dmat->alignment < dmat->maxsize) is just a quick hack; the exact + * (dmat->alignment <= dmat->maxsize) is just a quick hack; the exact * alignment guarantees of malloc need to be nailed down, and the * code below should be rewritten to take that into account. * * In the meantime, we'll warn the user if malloc gets it wrong. */ if ((dmat->common.maxsize <= PAGE_SIZE) && - (dmat->common.alignment < dmat->common.maxsize) && + (dmat->common.alignment <= dmat->common.maxsize) && dmat->common.lowaddr >= ptoa((vm_paddr_t)Maxmem) && attr == VM_MEMATTR_DEFAULT) { *vaddr = malloc(dmat->common.maxsize, M_DEVBUF, mflags); diff --git a/sys/x86/xen/xen_intr.c b/sys/x86/xen/xen_intr.c index 5fd50d836929..1c0ae3ae0f3c 100644 --- a/sys/x86/xen/xen_intr.c +++ b/sys/x86/xen/xen_intr.c @@ -71,9 +71,6 @@ __FBSDID("$FreeBSD$"); static MALLOC_DEFINE(M_XENINTR, "xen_intr", "Xen Interrupt Services"); -#define ENABLED_SETSIZE (sizeof(u_long) * 8) -BITSET_DEFINE(enabledbits, ENABLED_SETSIZE); - /** * Per-cpu event channel processing state. */ @@ -98,7 +95,7 @@ struct xen_intr_pcpu_data { * A bitmap of ports that can be serviced from this CPU. * A set bit means interrupt handling is enabled. */ - struct enabledbits evtchn_enabled; + u_long evtchn_enabled[sizeof(u_long) * 8]; }; /* @@ -215,7 +212,7 @@ evtchn_cpu_mask_port(u_int cpu, evtchn_port_t port) struct xen_intr_pcpu_data *pcpu; pcpu = DPCPU_ID_PTR(cpu, xen_intr_pcpu); - BIT_CLR_ATOMIC(ENABLED_SETSIZE, port, &pcpu->evtchn_enabled); + xen_clear_bit(port, pcpu->evtchn_enabled); } /** @@ -237,7 +234,7 @@ evtchn_cpu_unmask_port(u_int cpu, evtchn_port_t port) struct xen_intr_pcpu_data *pcpu; pcpu = DPCPU_ID_PTR(cpu, xen_intr_pcpu); - BIT_SET_ATOMIC(ENABLED_SETSIZE, port, &pcpu->evtchn_enabled); + xen_set_bit(port, pcpu->evtchn_enabled); } /** @@ -499,9 +496,14 @@ static inline u_long xen_intr_active_ports(struct xen_intr_pcpu_data *pcpu, shared_info_t *sh, u_int idx) { + + CTASSERT(sizeof(sh->evtchn_mask[0]) == sizeof(sh->evtchn_pending[0])); + CTASSERT(sizeof(sh->evtchn_mask[0]) == sizeof(pcpu->evtchn_enabled[0])); + CTASSERT(sizeof(sh->evtchn_mask) == sizeof(sh->evtchn_pending)); + CTASSERT(sizeof(sh->evtchn_mask) == sizeof(pcpu->evtchn_enabled)); return (sh->evtchn_pending[idx] & ~sh->evtchn_mask[idx] - & pcpu->evtchn_enabled.__bits[idx]); + & pcpu->evtchn_enabled[idx]); } /** @@ -637,10 +639,8 @@ xen_intr_init(void *dummy __unused) */ CPU_FOREACH(i) { pcpu = DPCPU_ID_PTR(i, xen_intr_pcpu); - if (i == 0) - BIT_FILL(ENABLED_SETSIZE, &pcpu->evtchn_enabled); - else - BIT_ZERO(ENABLED_SETSIZE, &pcpu->evtchn_enabled); + memset(pcpu->evtchn_enabled, i == 0 ? ~0 : 0, + sizeof(pcpu->evtchn_enabled)); xen_intr_intrcnt_add(i); } @@ -753,11 +753,8 @@ xen_intr_resume(struct pic *unused, bool suspend_cancelled) struct xen_intr_pcpu_data *pcpu; pcpu = DPCPU_ID_PTR(i, xen_intr_pcpu); - - if (i == 0) - BIT_FILL(ENABLED_SETSIZE, &pcpu->evtchn_enabled); - else - BIT_ZERO(ENABLED_SETSIZE, &pcpu->evtchn_enabled); + memset(pcpu->evtchn_enabled, i == 0 ? ~0 : 0, + sizeof(pcpu->evtchn_enabled)); } /* Mask all event channels. */ @@ -1612,8 +1609,7 @@ xen_intr_dump_port(struct xenisrc *isrc) CPU_FOREACH(i) { pcpu = DPCPU_ID_PTR(i, xen_intr_pcpu); db_printf("cpu#%d: %d ", i, - BIT_ISSET(ENABLED_SETSIZE, isrc->xi_port, - &pcpu->evtchn_enabled)); + !!xen_test_bit(isrc->xi_port, pcpu->evtchn_enabled)); } db_printf("\n"); } diff --git a/sys/xen/xen-os.h b/sys/xen/xen-os.h index eec8244f2d3e..0aa3bb50c06b 100644 --- a/sys/xen/xen-os.h +++ b/sys/xen/xen-os.h @@ -112,6 +112,12 @@ xen_set_bit(int bit, volatile long *addr) atomic_set_long(&addr[bit / NBPL], 1UL << (bit % NBPL)); } +static inline void +xen_clear_bit(int bit, volatile long *addr) +{ + atomic_clear_long(&addr[bit / NBPL], 1UL << (bit % NBPL)); +} + #undef NPBL /* diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index 7f5534704722..aba1885be61b 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -6827,8 +6827,7 @@ OLD_FILES+=usr/share/man/man8/repquota.8.gz .if ${MK_RCMDS} == no OLD_FILES+=bin/rcp OLD_FILES+=etc/rc.d/rwho -OLD_FILES+=etc/periodic/daily/140.clean-rwho -OLD_FILES+=etc/periodic/daily/430.status-rwho +OLD_FILES+=etc/periodic/daily/140.clean-rwho OLD_FILES+=rescue/rcp OLD_FILES+=usr/bin/rlogin OLD_FILES+=usr/bin/rsh @@ -8339,6 +8338,12 @@ OLD_FILES+=usr/share/man/man3/usb_set_configuration.3.gz OLD_FILES+=usr/share/man/man3/usb_set_debug.3.gz OLD_FILES+=usr/share/man/man3/usb_strerror.3.gz OLD_FILES+=usr/share/man/man3/usbhid.3.gz +OLD_FILES+=usr/share/man/man4/if_otus.4.gz +OLD_FILES+=usr/share/man/man4/if_rsu.4.gz +OLD_FILES+=usr/share/man/man4/otus.4.gz +OLD_FILES+=usr/share/man/man4/otusfw.4.gz +OLD_FILES+=usr/share/man/man4/rsu.4.gz +OLD_FILES+=usr/share/man/man4/rsufw.4.gz OLD_FILES+=usr/share/man/man4/u3g.4.gz OLD_FILES+=usr/share/man/man4/u3gstub.4.gz OLD_FILES+=usr/share/man/man4/uark.4.gz diff --git a/tools/build/options/WITH_FAST_DEPEND b/tools/build/options/WITH_FAST_DEPEND new file mode 100644 index 000000000000..2597a3622941 --- /dev/null +++ b/tools/build/options/WITH_FAST_DEPEND @@ -0,0 +1,7 @@ +.\" $FreeBSD$ +Set to generate +.Sy .depend +files in the build during compilation instead of the +historial +.Xr mkdep 1 +call during the "make depend" phase. diff --git a/tools/build/options/makeman b/tools/build/options/makeman index 1595499ca80c..c0c12b1bdb76 100755 --- a/tools/build/options/makeman +++ b/tools/build/options/makeman @@ -33,7 +33,7 @@ show_options() ALL_TARGETS=$(echo $(${make} targets | tail -n +2)) rm -f $t/settings for target in ${ALL_TARGETS} ; do - ${make} showconfig \ + env -i ${make} showconfig \ SRC_ENV_CONF=/dev/null SRCCONF=/dev/null \ __MAKE_CONF=/dev/null \ TARGET_ARCH=${target#*/} TARGET=${target%/*} | @@ -97,7 +97,7 @@ show() exit 1 ;; esac - ${make} .MAKE.MODE=normal "$@" showconfig __MAKE_CONF=/dev/null \ + env -i ${make} .MAKE.MODE=normal "$@" showconfig __MAKE_CONF=/dev/null \ SRCCONF=/dev/null | while read var _ val ; do opt=${var#MK_} diff --git a/tools/regression/security/open_to_operation/open_to_operation.c b/tools/regression/security/open_to_operation/open_to_operation.c index 0c65019a629a..c8c816becab9 100644 --- a/tools/regression/security/open_to_operation/open_to_operation.c +++ b/tools/regression/security/open_to_operation/open_to_operation.c @@ -119,10 +119,10 @@ __FBSDID("$FreeBSD$"); */ static const int file_modes[] = { O_RDONLY, O_WRONLY, O_RDWR, O_RDONLY | O_TRUNC, O_WRONLY | O_TRUNC, O_RDWR | O_TRUNC }; -static const int file_modes_count = sizeof(file_modes) / sizeof(int); +static const int file_modes_count = nitems(file_modes); static const int dir_modes[] = { O_RDONLY }; -static const int dir_modes_count = sizeof(dir_modes) / sizeof(int); +static const int dir_modes_count = nitems(dir_modes); static int testnum; static int aio_present; diff --git a/tools/tools/zfsboottest/Makefile b/tools/tools/zfsboottest/Makefile index 145e166a40ab..73620735d0a0 100644 --- a/tools/tools/zfsboottest/Makefile +++ b/tools/tools/zfsboottest/Makefile @@ -16,6 +16,7 @@ CFLAGS= -O1 \ -I. \ -fdiagnostics-show-option \ -W -Wextra -Wno-sign-compare -Wno-unused-parameter +CFLAGS+=-m32 LDADD+= -lmd .if ${MACHINE_CPUARCH} == "amd64" diff --git a/tools/tools/zfsboottest/zfsboottest.c b/tools/tools/zfsboottest/zfsboottest.c index 29e9a485ba20..45715d9624cd 100644 --- a/tools/tools/zfsboottest/zfsboottest.c +++ b/tools/tools/zfsboottest/zfsboottest.c @@ -136,19 +136,21 @@ main(int argc, char** argv) } } + STAILQ_FOREACH(spa, &zfs_pools, spa_link) { + if (zfs_spa_init(spa)) { + fprintf(stderr, "can't init pool %s\n", spa->spa_name); + exit(1); + } + } + + spa_all_status(); + spa = STAILQ_FIRST(&zfs_pools); if (spa == NULL) { fprintf(stderr, "no pools\n"); exit(1); } - if (zfs_spa_init(spa)) { - fprintf(stderr, "can't init pool\n"); - exit(1); - } - - spa_all_status(); - #if 0 uint64_t rootobj; if (zfs_get_root(spa, &rootobj)) { diff --git a/usr.bin/bsdiff/bsdiff/bsdiff.c b/usr.bin/bsdiff/bsdiff/bsdiff.c index d46eed983a81..7e39275a0a46 100644 --- a/usr.bin/bsdiff/bsdiff/bsdiff.c +++ b/usr.bin/bsdiff/bsdiff/bsdiff.c @@ -31,7 +31,10 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include +#include +#include #include #include #include @@ -230,8 +233,17 @@ int main(int argc,char *argv[]) /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure that we never try to malloc(0) and get a NULL pointer */ if(((fd=open(argv[1],O_RDONLY|O_BINARY,0))<0) || - ((oldsize=lseek(fd,0,SEEK_END))==-1) || - ((old=malloc(oldsize+1))==NULL) || + ((oldsize=lseek(fd,0,SEEK_END))==-1)) + err(1, "%s", argv[1]); + + if (oldsize > SSIZE_MAX || + (uintmax_t)oldsize >= SIZE_T_MAX / sizeof(off_t) || + oldsize == OFF_MAX) { + errno = EFBIG; + err(1, "%s", argv[1]); + } + + if (((old=malloc(oldsize+1))==NULL) || (lseek(fd,0,SEEK_SET)!=0) || (read(fd,old,oldsize)!=oldsize) || (close(fd)==-1)) err(1,"%s",argv[1]); @@ -246,8 +258,16 @@ int main(int argc,char *argv[]) /* Allocate newsize+1 bytes instead of newsize bytes to ensure that we never try to malloc(0) and get a NULL pointer */ if(((fd=open(argv[2],O_RDONLY|O_BINARY,0))<0) || - ((newsize=lseek(fd,0,SEEK_END))==-1) || - ((new=malloc(newsize+1))==NULL) || + ((newsize=lseek(fd,0,SEEK_END))==-1)) + err(1, "%s", argv[2]); + + if (newsize > SSIZE_MAX || (uintmax_t)newsize >= SIZE_T_MAX || + newsize == OFF_MAX) { + errno = EFBIG; + err(1, "%s", argv[2]); + } + + if (((new=malloc(newsize+1))==NULL) || (lseek(fd,0,SEEK_SET)!=0) || (read(fd,new,newsize)!=newsize) || (close(fd)==-1)) err(1,"%s",argv[2]); diff --git a/usr.bin/m4/Makefile b/usr.bin/m4/Makefile index d9550758f9b9..55118773b579 100644 --- a/usr.bin/m4/Makefile +++ b/usr.bin/m4/Makefile @@ -7,8 +7,8 @@ .include PROG= m4 -CFLAGS+=-DEXTENDED -I${.CURDIR} -I${.CURDIR}/../../lib/libohash -LIBADD= y l m ohash +CFLAGS+=-DEXTENDED -I${.CURDIR} -I${.CURDIR}/../../lib/libopenbsd +LIBADD= y l m openbsd NO_WMISSING_VARIABLE_DECLARATIONS= diff --git a/usr.bin/m4/Makefile.depend b/usr.bin/m4/Makefile.depend index f5fa771b92e1..8ccf846f0ced 100644 --- a/usr.bin/m4/Makefile.depend +++ b/usr.bin/m4/Makefile.depend @@ -9,7 +9,7 @@ DIRDEPS = \ lib/${CSU_DIR} \ lib/libc \ lib/libcompiler_rt \ - lib/libohash \ + lib/libopenbsd \ lib/liby \ lib/msun \ usr.bin/lex/lib \ diff --git a/usr.bin/mandoc/Makefile b/usr.bin/mandoc/Makefile index faa46ed3bdc8..9160dc0b58f8 100644 --- a/usr.bin/mandoc/Makefile +++ b/usr.bin/mandoc/Makefile @@ -82,8 +82,8 @@ SRCS+= ${DB_SRCS} WARNS?= 2 CFLAGS+= -DHAVE_CONFIG_H \ - -I${.CURDIR}/../../lib/libohash/ \ + -I${.CURDIR}/../../lib/libopenbsd/ \ -I${.CURDIR}/../../contrib/sqlite3 -LIBADD= ohash sqlite3 z +LIBADD= openbsd sqlite3 z .include diff --git a/usr.bin/mandoc/Makefile.depend b/usr.bin/mandoc/Makefile.depend index e3848e3fa54f..7c705f5b3c99 100644 --- a/usr.bin/mandoc/Makefile.depend +++ b/usr.bin/mandoc/Makefile.depend @@ -9,7 +9,7 @@ DIRDEPS = \ lib/${CSU_DIR} \ lib/libc \ lib/libcompiler_rt \ - lib/libohash \ + lib/libopenbsd \ lib/libsqlite3 \ lib/libthr \ lib/libz \ diff --git a/usr.bin/netstat/if.c b/usr.bin/netstat/if.c index 96606c436057..f2f689d673cc 100644 --- a/usr.bin/netstat/if.c +++ b/usr.bin/netstat/if.c @@ -37,7 +37,7 @@ static char sccsid[] = "@(#)if.c 8.3 (Berkeley) 4/28/95"; #include __FBSDID("$FreeBSD$"); -#include +#include #include #include #include @@ -271,7 +271,9 @@ intpr(void (*pfunc)(char *), int af) { struct ifaddrs *ifap, *ifa; struct ifmaddrs *ifmap, *ifma; - + u_int ifn_len_max = 5, ifn_len; + u_int has_ipv6 = 0, net_len = 13, addr_len = 17; + if (interval) return sidewaysintpr(); @@ -280,15 +282,34 @@ intpr(void (*pfunc)(char *), int af) if (aflag && getifmaddrs(&ifmap) != 0) err(EX_OSERR, "getifmaddrs"); + if (Wflag) { + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (interface != NULL && + strcmp(ifa->ifa_name, interface) != 0) + continue; + if (af != AF_UNSPEC && ifa->ifa_addr->sa_family != af) + continue; + ifn_len = strlen(ifa->ifa_name); + if ((ifa->ifa_flags & IFF_UP) == 0) + ++ifn_len; + ifn_len_max = MAX(ifn_len_max, ifn_len); + if (ifa->ifa_addr->sa_family == AF_INET6) + has_ipv6 = 1; + } + if (has_ipv6) { + net_len = 24; + addr_len = 39; + } else + net_len = 18; + } + xo_open_list("interface"); if (!pfunc) { - if (Wflag) - xo_emit("{T:/%-7.7s}", "Name"); - else - xo_emit("{T:/%-5.5s}", "Name"); - xo_emit(" {T:/%5.5s} {T:/%-13.13s} {T:/%-17.17s} {T:/%8.8s} " + xo_emit("{T:/%-*.*s}", ifn_len_max, ifn_len_max, "Name"); + xo_emit(" {T:/%5.5s} {T:/%-*.*s} {T:/%-*.*s} {T:/%8.8s} " "{T:/%5.5s} {T:/%5.5s}", - "Mtu", "Network", "Address", "Ipkts", "Ierrs", "Idrop"); + "Mtu", net_len, net_len, "Network", addr_len, addr_len, + "Address", "Ipkts", "Ierrs", "Idrop"); if (bflag) xo_emit(" {T:/%10.10s}","Ibytes"); xo_emit(" {T:/%8.8s} {T:/%5.5s}", "Opkts", "Oerrs"); @@ -296,13 +317,14 @@ intpr(void (*pfunc)(char *), int af) xo_emit(" {T:/%10.10s}","Obytes"); xo_emit(" {T:/%5s}", "Coll"); if (dflag) - xo_emit(" {T:/%s}", "Drop"); + xo_emit(" {T:/%5.5s}", "Drop"); xo_emit("\n"); } for (ifa = ifap; ifa; ifa = ifa->ifa_next) { bool network = false, link = false; char *name, *xname, buf[IFNAMSIZ+1]; + const char *nn, *rn; if (interface != NULL && strcmp(ifa->ifa_name, interface) != 0) continue; @@ -336,12 +358,8 @@ intpr(void (*pfunc)(char *), int af) } else xname = name; - if (Wflag) - xo_emit("{etk:name/%s}{e:flags/0x%x}{d:/%7.7s}", - name, ifa->ifa_flags, xname); - else - xo_emit("{etk:name/%s}{e:flags/0x%x}{d:/%5.5s}", - name, ifa->ifa_flags, xname); + xo_emit("{etk:name/%s}{e:flags/0x%x}{d:/%-*.*s}", + name, ifa->ifa_flags, ifn_len_max, ifn_len_max, xname); #define IFA_MTU(ifa) (((struct if_data *)(ifa)->ifa_data)->ifi_mtu) show_stat("lu", 6, "mtu", IFA_MTU(ifa), IFA_MTU(ifa), 0); @@ -349,41 +367,31 @@ intpr(void (*pfunc)(char *), int af) switch (ifa->ifa_addr->sa_family) { case AF_UNSPEC: - xo_emit("{:network/%-13.13s} ", "none"); - xo_emit("{:address/%-15.15s} ", "none"); + xo_emit("{:network/%-*.*s} ", net_len, net_len, + "none"); + xo_emit("{:address/%-*.*s} ", addr_len, addr_len, + "none"); break; case AF_INET: - if (Wflag) { - xo_emit("{t:network/%-13s} ", - netname(ifa->ifa_addr, ifa->ifa_netmask)); - xo_emit("{t:address/%-17s} ", - routename(ifa->ifa_addr, numeric_addr)); - } else { - xo_emit("{t:network/%-13.13s} ", - netname(ifa->ifa_addr, ifa->ifa_netmask)); - xo_emit("{t:address/%-17.17s} ", - routename(ifa->ifa_addr, numeric_addr)); - } - - network = true; - break; #ifdef INET6 case AF_INET6: +#endif /* INET6 */ + nn = netname(ifa->ifa_addr, ifa->ifa_netmask); + rn = routename(ifa->ifa_addr, numeric_addr); if (Wflag) { - xo_emit("{t:network/%-13s} ", - netname(ifa->ifa_addr, ifa->ifa_netmask)); - xo_emit("{t:address/%-17s} ", - routename(ifa->ifa_addr, numeric_addr)); + xo_emit("{et:network/%s}{d:/%-*s} ", + nn, net_len, nn); + xo_emit("{et:address/%s}{d:/%-*s} ", + rn, addr_len, rn); } else { - xo_emit("{t:network/%-13.13s} ", - netname(ifa->ifa_addr, ifa->ifa_netmask)); - xo_emit("{t:address/%-17.17s} ", - routename(ifa->ifa_addr, numeric_addr)); + xo_emit("{et:network/%s}{d:/%-*.*s} ", + nn, net_len, net_len, nn); + xo_emit("{et:address/%s}{d:/%-*.*s} ", + rn, addr_len, addr_len, rn); } network = true; break; -#endif /* INET6 */ case AF_LINK: { struct sockaddr_dl *sdl; @@ -391,15 +399,15 @@ intpr(void (*pfunc)(char *), int af) sdl = (struct sockaddr_dl *)ifa->ifa_addr; sprintf(linknum, "", sdl->sdl_index); - xo_emit("{t:network/%-13.13s} ", linknum); + xo_emit("{t:network/%-*.*s} ", net_len, net_len, + linknum); if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 && sdl->sdl_slen == 0) - xo_emit("{P: }"); + xo_emit("{P:/%*s} ", addr_len, ""); else - xo_emit("{:address/%*s}", - 32 - 3 * sdl->sdl_alen, - routename(ifa->ifa_addr, 1)); + xo_emit("{t:address/%-*.*s} ", addr_len, + addr_len, routename(ifa->ifa_addr, 1)); link = true; break; } diff --git a/usr.bin/netstat/route.c b/usr.bin/netstat/route.c index 7cb777bdd245..3f6918cc160a 100644 --- a/usr.bin/netstat/route.c +++ b/usr.bin/netstat/route.c @@ -637,14 +637,13 @@ netname4(in_addr_t in, in_addr_t mask) trimdomain(cp, strlen(cp)); } } - inet_ntop(AF_INET, &in, nline, sizeof(line)); - if (cp != NULL) { - if (strcpy(cp, nline) != 0) - return (line); + if (cp != NULL) strlcpy(line, cp, sizeof(line)); - } else + else { + inet_ntop(AF_INET, &in, nline, sizeof(nline)); strlcpy(line, nline, sizeof(line)); - domask(line + strlen(line), i, ntohl(mask)); + domask(line + strlen(line), i, ntohl(mask)); + } return (line); } @@ -688,9 +687,10 @@ static const char * netname6(struct sockaddr_in6 *sa6, struct sockaddr_in6 *mask) { static char line[NI_MAXHOST + sizeof("/xxx") - 1]; + struct sockaddr_in6 addr; char nline[NI_MAXHOST]; u_char *p, *lim; - int masklen, illegal = 0; + int masklen, illegal = 0, i; if (mask) { p = (u_char *)&mask->sin6_addr; @@ -703,6 +703,12 @@ netname6(struct sockaddr_in6 *sa6, struct sockaddr_in6 *mask) } if (illegal) xo_error("illegal prefixlen\n"); + + memcpy(&addr, sa6, sizeof(addr)); + for (i = 0; i < 16; ++i) + addr.sin6_addr.s6_addr[i] &= + mask->sin6_addr.s6_addr[i]; + sa6 = &addr; } else masklen = 128; diff --git a/usr.bin/rctl/rctl.8 b/usr.bin/rctl/rctl.8 index 9fc1c1ce79c1..c9aa6f430a70 100644 --- a/usr.bin/rctl/rctl.8 +++ b/usr.bin/rctl/rctl.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 14, 2015 +.Dd November 5, 2015 .Dt RCTL 8 .Os .Sh NAME @@ -38,19 +38,19 @@ .Op Ar filter .Nm .Fl a -.Op Ar rule +.Ar rule .Nm .Fl l .Op Fl h .Op Fl n -.Op Ar filter +.Ar filter .Nm .Fl r -.Op Ar filter +.Ar filter .Nm .Fl u .Op Fl h -.Op Ar filter +.Ar filter .Pp .Nm requires the kernel to be compiled with: diff --git a/usr.bin/rctl/rctl.c b/usr.bin/rctl/rctl.c index b5342583958d..915303612971 100644 --- a/usr.bin/rctl/rctl.c +++ b/usr.bin/rctl/rctl.c @@ -48,7 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include -#define RCTL_DEFAULT_BUFSIZE 4096 +#define RCTL_DEFAULT_BUFSIZE 128 * 1024 static id_t parse_user(const char *s) diff --git a/usr.bin/soelim/soelim.1 b/usr.bin/soelim/soelim.1 index 57e86141c001..1f4e5a833516 100644 --- a/usr.bin/soelim/soelim.1 +++ b/usr.bin/soelim/soelim.1 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 1, 2015 +.Dd November 7, 2015 .Dt SOELIM 1 .Os .Sh NAME @@ -34,43 +34,48 @@ .Nm .Op Fl Crtv .Op Fl I Ar dir -.Op Ar files ... +.Op Ar .Sh DESCRIPTION +The .Nm -reads -.Ar files -lines by lines. +utility +reads the specified files or the standard input and performs the textual +inclusion implied by the +.Xr nroff 1 +directives of the form: .Pp -If a line starts by: +.Dl \&.so anotherfile +.Pp +If a line starts with: .Dq .so anotherfile -it replace the line by processing +it replaces the line by processing .Dq anotherfile . Otherwise the line is printed to stdout. .Bl -tag -width "-I dir" .It Fl C Recognise .Em .so -when not followed by a space character. +when it is not followed by a space character. .It Fl r -Compatibility with GNU groff's +Compatibility with groff's .Xr soelim 1 (does nothing). .It Fl t -Compatibility with GNU groff's +Compatibility with groff's .Xr soelim 1 (does nothing). .It Fl v -Compatibility with GNU groff's +Compatibility with groff's .Xr soelim 1 (does nothing). .It Fl I Ar dir -This option specify directories where +This option specifies directories where .Nm searches for files (both those on the command line and those named in .Dq .so directive.) -This options may be specified multiple times. The directories will be searched -in the order specified. +This option may be specified multiple times. +The directories will be searched in the order specified. .El .Pp The files are always searched first in the current directory. diff --git a/usr.bin/svn/lib/Makefile b/usr.bin/svn/lib/Makefile index ff8309b2f676..fd3ad856b104 100644 --- a/usr.bin/svn/lib/Makefile +++ b/usr.bin/svn/lib/Makefile @@ -4,5 +4,6 @@ SUBDIR= libapr libapr_util libserf \ libsvn_client libsvn_delta libsvn_diff libsvn_fs libsvn_fs_fs \ libsvn_fs_util libsvn_fs_x libsvn_ra libsvn_ra_local libsvn_ra_serf \ libsvn_ra_svn libsvn_repos libsvn_subr libsvn_wc +SUBDIR_PARALLEL= .include diff --git a/usr.sbin/bsdinstall/distfetch/distfetch.c b/usr.sbin/bsdinstall/distfetch/distfetch.c index 4e870c8bbdbf..219847db6423 100644 --- a/usr.sbin/bsdinstall/distfetch/distfetch.c +++ b/usr.sbin/bsdinstall/distfetch/distfetch.c @@ -78,7 +78,7 @@ main(void) if (chdir(getenv("BSDINSTALL_DISTDIR")) != 0) { snprintf(error, sizeof(error), - "Could could change to directory %s: %s\n", + "Could not change to directory %s: %s\n", getenv("BSDINSTALL_DISTDIR"), strerror(errno)); dialog_msgbox("Error", error, 0, 0, TRUE); end_dialog(); diff --git a/usr.sbin/makefs/cd9660.c b/usr.sbin/makefs/cd9660.c index b5be46906b09..e05e52ac32c9 100644 --- a/usr.sbin/makefs/cd9660.c +++ b/usr.sbin/makefs/cd9660.c @@ -296,8 +296,8 @@ cd9660_parse_opts(const char *option, fsinfo_t *fsopts) int rv; /* Set up allowed options - integer options ONLY */ option_t cd9660_options[] = { - { "l", &diskStructure.isoLevel, 1, 3, "ISO Level" }, - { "isolevel", &diskStructure.isoLevel, 1, 3, "ISO Level" }, + { "l", &diskStructure.isoLevel, 1, 2, "ISO Level" }, + { "isolevel", &diskStructure.isoLevel, 1, 2, "ISO Level" }, { "verbose", &diskStructure.verbose_level, 0, 2, "Turns on verbose output" }, { "v", &diskStructure.verbose_level, 0 , 2, @@ -1055,6 +1055,7 @@ cd9660_rename_filename(cd9660node *iter, int num, int delete_chars) if (diskStructure.verbose_level > 0) printf("Rename_filename called\n"); + assert(1 <= diskStructure.isoLevel && diskStructure.isoLevel <= 2); /* TODO : A LOT of chanes regarding 8.3 filenames */ if (diskStructure.isoLevel == 1) maxlength = 8; @@ -1730,6 +1731,7 @@ cd9660_joliet_convert_filename(const char *oldname, char *newname, int is_file) static int cd9660_convert_filename(const char *oldname, char *newname, int is_file) { + assert(1 <= diskStructure.isoLevel && diskStructure.isoLevel <= 2); /* NEW */ cd9660_filename_conversion_functor conversion_function = 0; if (diskStructure.isoLevel == 1) diff --git a/usr.sbin/makefs/ffs/ffs_bswap.c b/usr.sbin/makefs/ffs/ffs_bswap.c index a1a1c46c5360..e62eb1957b9e 100644 --- a/usr.sbin/makefs/ffs/ffs_bswap.c +++ b/usr.sbin/makefs/ffs/ffs_bswap.c @@ -67,7 +67,7 @@ void ffs_csumtotal_swap(struct csum_total *o, struct csum_total *n); void ffs_sb_swap(struct fs *o, struct fs *n) { - int i; + size_t i; u_int32_t *o32, *n32; /* @@ -97,7 +97,7 @@ ffs_sb_swap(struct fs *o, struct fs *n) n->fs_csaddr = bswap64(o->fs_csaddr); n->fs_pendingblocks = bswap64(o->fs_pendingblocks); n->fs_pendinginodes = bswap32(o->fs_pendinginodes); - + /* These fields overlap with the second half of the * historic FS_42POSTBLFMT postbl table */ @@ -171,9 +171,9 @@ ffs_dinode2_swap(struct ufs2_dinode *o, struct ufs2_dinode *n) void ffs_csum_swap(struct csum *o, struct csum *n, int size) { - int i; + size_t i; u_int32_t *oint, *nint; - + oint = (u_int32_t*)o; nint = (u_int32_t*)n; diff --git a/usr.sbin/makefs/makefs.8 b/usr.sbin/makefs/makefs.8 index edecd4a63890..c9d6c0761a21 100644 --- a/usr.sbin/makefs/makefs.8 +++ b/usr.sbin/makefs/makefs.8 @@ -35,7 +35,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 29, 2015 +.Dd November 1, 2015 .Dt MAKEFS 8 .Os .Sh NAME @@ -44,10 +44,10 @@ .Sh SYNOPSIS .Nm .Op Fl DxZ -.Op Fl B Ar byte-order +.Op Fl B Ar endian .Op Fl b Ar free-blocks .Op Fl d Ar debug-mask -.Op Fl F Ar specfile +.Op Fl F Ar mtree-specfile .Op Fl f Ar free-files .Op Fl M Ar minimum-size .Op Fl m Ar maximum-size @@ -69,9 +69,9 @@ from the directory tree .Ar directory or from the mtree manifest .Ar manifest . -If optional directory tree +If any optional directory trees are passed in the .Ar extra-directory -is passed, then the directory tree of each argument will be merged +arguments, then the directory tree of each argument will be merged into the .Ar directory or @@ -82,9 +82,9 @@ No special devices or privileges are required to perform this task. .Pp The options are as follows: .Bl -tag -width flag -.It Fl B Ar byte-order +.It Fl B Ar endian Set the byte order of the image to -.Ar byte-order . +.Ar endian . Valid byte orders are .Ql 4321 , .Ql big , @@ -114,9 +114,9 @@ Enable various levels of debugging, depending upon which bits are set in .Ar debug-mask . XXX: document these -.It Fl F Ar specfile +.It Fl F Ar mtree-specfile Use -.Ar specfile +.Ar mtree-specfile as an .Xr mtree 8 .Sq specfile @@ -174,13 +174,13 @@ Set the maximum size of the file system image to .Ar maximum-size . An error will be raised if the target file system needs to be larger than this to accommodate the provided directory tree. -.It Fl N Ar dbdir +.It Fl N Ar userdb-dir Use the user database text file .Pa master.passwd and group database text file .Pa group from -.Ar dbdir , +.Ar userdb-dir , rather than using the results from the system's .Xr getpwnam 3 and @@ -226,7 +226,9 @@ ISO 9660 file system. .It Fl x Exclude file system nodes not explicitly listed in the specfile. .It Fl Z -Create the image as a sparse file. +Create a sparse file for +.Sy ffs . +This is useful for virtual machine images. .El .Pp Where sizes are specified, a decimal number of bytes is expected. @@ -301,10 +303,10 @@ The following keywords are supported: .It Sy allow-deep-trees Allow the directory structure to exceed the maximum specified in the spec. -.\" .It Sy allow-illegal-chars -.\" Unknown -.\" .It Sy allow-lowercase -.\" Unknown +.It Sy allow-illegal-chars +Allow illegal characters in filenames. This option is not implemented. +.It Sy allow-lowercase +Allow lowercase characters in filenames. This option is not implemented. .It Sy allow-max-name Allow 37 instead of 33 characters for filenames by omitting the version id. @@ -318,6 +320,8 @@ Use the extension to encode .Tn RISC OS metadata. +.It Sy bootimagedir +Boot image directory. This option is not implemented. .It Sy chrp-boot Write an MBR partition table to the image to allow older CHRP hardware to boot. @@ -338,8 +342,18 @@ or Load a generic boot image into the first 32K of the cd9660 image. .It Sy hard-disk-boot Boot image is a hard disk image. +.It Sy isolevel +An integer representing the ISO 9660 interchange level where +.Dq level +is either +.Ql 1 +or +.Ql 2 . +.Dq level +.Ql 3 +is not implemented. .It Sy keep-bad-images -Do not throw away images whose write was aborted due to an error. +Don't throw away images whose write was aborted due to an error. For debugging purposes. .It Sy label Label name of the image. @@ -351,14 +365,16 @@ Boot image is a ElTorito image. .It Sy no-trailing-padding Do not pad the image (apparently Linux needs the padding). -.\" .It Sy omit-trailing-period -.\" Unknown +.It Sy omit-trailing-period +Omit trailing periods in filenames. .It Sy preparer Preparer ID of the image. .It Sy publisher Publisher ID of the image. .It Sy rockridge Use RockRidge extensions (for longer filenames, etc.). +.It Sy verbose +Turns on verbose output. .It Sy volumeid Volume set identifier of the image. .El @@ -372,11 +388,12 @@ The utility appeared in .Nx 1.6 . .Sh AUTHORS -.An Luke Mewburn Aq Mt lukem@NetBSD.org -(original program) -.An Daniel Watt -.An Walter Deignan -.An Ryan Gabrys -.An Alan Perez-Rathke +.An Luke Mewburn +.Aq lukem@NetBSD.org +(original program), +.An Daniel Watt , +.An Walter Deignan , +.An Ryan Gabrys , +.An Alan Perez-Rathke , .An Ram Vedam (cd9660 support) diff --git a/usr.sbin/makefs/tests/makefs_cd9660_tests.sh b/usr.sbin/makefs/tests/makefs_cd9660_tests.sh index e476cf1bf8dd..161b56b12e7a 100755 --- a/usr.sbin/makefs/tests/makefs_cd9660_tests.sh +++ b/usr.sbin/makefs/tests/makefs_cd9660_tests.sh @@ -113,7 +113,7 @@ from_mtree_spec_file_body() create_test_inputs atf_check -e empty -o save:$TEST_SPEC_FILE -s exit:0 \ - mtree -c -k type,link,size -p $TEST_INPUTS_DIR + mtree -c -k "$DEFAULT_MTREE_KEYWORDS" -p $TEST_INPUTS_DIR cd $TEST_INPUTS_DIR atf_check -e empty -o empty -s exit:0 \ $MAKEFS $TEST_IMAGE $TEST_SPEC_FILE @@ -208,6 +208,61 @@ o_flag_allow_max_name_cleanup() common_cleanup } +atf_test_case o_flag_isolevel_1 cleanup +o_flag_isolevel_1_body() +{ + atf_expect_fail "this testcase needs work; the filenames generated seem incorrect/corrupt" + + create_test_inputs + + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS -o isolevel=1 $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + check_base_iso9660_image_contents +} +o_flag_isolevel_1_cleanup() +{ + common_cleanup +} + +atf_test_case o_flag_isolevel_2 cleanup +o_flag_isolevel_2_body() +{ + create_test_inputs + + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS -o isolevel=2 $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + check_base_iso9660_image_contents +} +o_flag_isolevel_2_cleanup() +{ + common_cleanup +} + +atf_test_case o_flag_isolevel_3 cleanup +o_flag_isolevel_3_body() +{ + create_test_inputs + + # XXX: isolevel=3 isn't implemented yet. See FreeBSD bug # 203645 + if true; then + atf_check -e match:'makefs: ISO Level 3 is greater than 2\.' -o empty -s not-exit:0 \ + $MAKEFS -o isolevel=3 $TEST_IMAGE $TEST_INPUTS_DIR + else + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS -o isolevel=3 $TEST_IMAGE $TEST_INPUTS_DIR + mount_image + check_base_iso9660_image_contents + fi +} +o_flag_isolevel_3_cleanup() +{ + common_cleanup +} + atf_test_case o_flag_preparer o_flag_preparer_body() { @@ -308,6 +363,9 @@ atf_init_test_cases() atf_add_test_case o_flag_allow_deep_trees atf_add_test_case o_flag_allow_max_name + atf_add_test_case o_flag_isolevel_1 + atf_add_test_case o_flag_isolevel_2 + atf_add_test_case o_flag_isolevel_3 atf_add_test_case o_flag_preparer atf_add_test_case o_flag_publisher atf_add_test_case o_flag_rockridge diff --git a/usr.sbin/makefs/tests/makefs_ffs_tests.sh b/usr.sbin/makefs/tests/makefs_ffs_tests.sh index 4bc3f5c25892..121c2a2d9eb8 100755 --- a/usr.sbin/makefs/tests/makefs_ffs_tests.sh +++ b/usr.sbin/makefs/tests/makefs_ffs_tests.sh @@ -105,7 +105,7 @@ from_mtree_spec_file_body() create_test_inputs atf_check -e empty -o save:$TEST_SPEC_FILE -s exit:0 \ - mtree -c -k type,link,size -p $TEST_INPUTS_DIR + mtree -c -k "$DEFAULT_MTREE_KEYWORDS" -p $TEST_INPUTS_DIR cd $TEST_INPUTS_DIR atf_check -e empty -o not-empty -s exit:0 \ @@ -158,6 +158,70 @@ from_single_dir_cleanup() common_cleanup } +atf_test_case o_flag_version_1 cleanup +o_flag_version_1_body() +{ + ffs_version=1 + + platform=$(uname) + case "$platform" in + FreeBSD) + ffs_label=UFS${ffs_version} + ;; + NetBSD) + ffs_label=FFSv${ffs_version} + ;; + *) + atf_skip "Unsupported platform" + ;; + esac + + create_test_inputs + + atf_check -e empty -o not-empty -s exit:0 \ + $MAKEFS -M 1m -o version=$ffs_version $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + atf_check -e empty -o match:"$ffs_label" dumpfs $TEST_MOUNT_DIR + check_ffs_image_contents +} +o_flag_version_1_cleanup() +{ + common_cleanup +} + +atf_test_case o_flag_version_2 cleanup +o_flag_version_2_body() +{ + ffs_version=2 + + platform=$(uname) + case "$platform" in + FreeBSD) + ffs_label=UFS${ffs_version} + ;; + NetBSD) + ffs_label=FFSv${ffs_version} + ;; + *) + atf_skip "Unsupported platform" + ;; + esac + + create_test_inputs + + atf_check -e empty -o not-empty -s exit:0 \ + $MAKEFS -M 1m -o version=$ffs_version $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + atf_check -e empty -o match:"$ffs_label" dumpfs $TEST_MOUNT_DIR + check_ffs_image_contents +} +o_flag_version_2_cleanup() +{ + common_cleanup +} + atf_init_test_cases() { @@ -168,5 +232,6 @@ atf_init_test_cases() atf_add_test_case from_multiple_dirs atf_add_test_case from_single_dir - + atf_add_test_case o_flag_version_1 + atf_add_test_case o_flag_version_2 } diff --git a/usr.sbin/makefs/tests/makefs_tests_common.sh b/usr.sbin/makefs/tests/makefs_tests_common.sh index d0099fd9c183..add0b88728e2 100755 --- a/usr.sbin/makefs/tests/makefs_tests_common.sh +++ b/usr.sbin/makefs/tests/makefs_tests_common.sh @@ -29,6 +29,13 @@ KB=1024 : ${TMPDIR=/tmp} +# TODO: add mtree `time` support; get a lot of errors like this right now when +# passing generating disk images with keyword mtree support, like: +# +# `[...]/mtree.spec:8: error: time: invalid value '1446458503'` +# +#DEFAULT_MTREE_KEYWORDS="type,mode,gid,uid,size,link,time" +DEFAULT_MTREE_KEYWORDS="type,mode,gid,uid,size,link" TEST_IMAGE="$TMPDIR/test.img" TEST_INPUTS_DIR="$TMPDIR/inputs" TEST_MD_DEVICE_FILE="$TMPDIR/md.output" @@ -39,7 +46,7 @@ check_image_contents() { local directories=$TEST_INPUTS_DIR local excludes mtree_excludes_arg mtree_file - local mtree_keywords="type,link,size" + local mtree_keywords="$DEFAULT_MTREE_KEYWORDS" while getopts "d:f:m:X:" flag; do case "$flag" in diff --git a/usr.sbin/pciconf/cap.c b/usr.sbin/pciconf/cap.c index 2e2e359fb825..9ab6dd17ddbd 100644 --- a/usr.sbin/pciconf/cap.c +++ b/usr.sbin/pciconf/cap.c @@ -460,6 +460,10 @@ cap_express(int fd, struct pci_conf *p, uint8_t ptr) MAX_PAYLOAD(cap & PCIEM_CAP_MAX_PAYLOAD)); if ((cap & PCIEM_CAP_FLR) != 0) printf(" FLR"); + if (ctl & PCIEM_CTL_RELAXED_ORD_ENABLE) + printf(" RO"); + if (ctl & PCIEM_CTL_NOSNOOP_ENABLE) + printf(" NS"); cap = read_config(fd, &p->pc_sel, ptr + PCIER_LINK_CAP, 4); sta = read_config(fd, &p->pc_sel, ptr + PCIER_LINK_STA, 2); printf(" link x%d(x%d)", (sta & PCIEM_LINK_STA_WIDTH) >> 4, diff --git a/usr.sbin/sysrc/sysrc b/usr.sbin/sysrc/sysrc index 2a245510ef64..e384dff93f6c 100644 --- a/usr.sbin/sysrc/sysrc +++ b/usr.sbin/sysrc/sysrc @@ -40,18 +40,23 @@ BSDCFG_SHARE="/usr/share/bsdconfig" # # Version information # -SYSRC_VERSION="6.5 Sep-1,2015" +SYSRC_VERSION="7.0 Sep-13,2015" # # Options # CHECK_ONLY= +DEFAULT= DELETE= DESCRIBE= +EXISTING_ONLY= IGNORE_UNKNOWNS= JAIL= +LIST_SERVICE_CONFS= +LIST_CONFS= QUIET= ROOTDIR= +SERVICE= SHOW_ALL= SHOW_EQUALS= SHOW_FILE= @@ -80,7 +85,8 @@ die() # usage() { - f_err "Usage: %s [OPTIONS] name[[+|-]=value] ...\n" "$pgm" + f_err "Usage: %s [OPTIONS] %s\n" "$pgm" \ + "{name[[+|-]=value] ... | -a | -A | -l | -L [name ...]}" f_err "Try \`%s --help' for more information.\n" "$pgm" die } @@ -95,6 +101,8 @@ help() local envfmt="\t%-17s%s\n" f_err "Usage: %s [OPTIONS] name[[+|-]=value] ...\n" "$pgm" + f_err "Usage: %s [OPTIONS] -a | -A\n" "$pgm" + f_err "Usage: %s [OPTIONS] -l | -L [name ...]\n" "$pgm" f_err "OPTIONS:\n" f_err "$optfmt" "-a" \ @@ -113,6 +121,8 @@ help() "Print query results as \`var=value' (useful for producing" f_err "$optfmt" "" \ "output to be fed back in). Ignored if \`-n' is specified." + f_err "$optfmt" "-E" \ + "Existing files only with \`-[lL]' or when changing a setting." f_err "$optfmt" "-f file" \ "Operate on the specified file(s) instead of rc_conf_files." f_err "$optfmt" "" \ @@ -129,12 +139,20 @@ help() "The jid or name of the jail to operate within (overrides" f_err "$optfmt" "" \ "\`-R dir'; requires jexec(8))." + f_err "$optfmt" "-l" \ + "List configuration files used at startup on stdout and exit." + f_err "$optfmt" "-L" \ + "List all configuration files including rc.conf.d entries." f_err "$optfmt" "-n" \ "Show only variable values, not their names." f_err "$optfmt" "-N" \ "Show only variable names, not their values." f_err "$optfmt" "-q" \ "Quiet. Disable verbose and hide certain errors." + f_err "$optfmt" "-s name" \ + "Process additional \`rc.conf.d' entries for service name." + f_err "$optfmt" "" \ + "Ignored if \`-f file' is given." f_err "$optfmt" "-R dir" \ "Operate within the root directory \`dir' rather than \`/'." f_err "$optfmt" "-v" \ @@ -245,27 +263,33 @@ unset arg # # Process command-line flags # -while getopts aAcdDef:Fhij:nNqR:vxX flag; do +while getopts aAcdDeEf:Fhij:lLnNqR:s:vxX flag; do case "$flag" in a) SHOW_ALL=${SHOW_ALL:-1} ;; A) SHOW_ALL=2 ;; c) CHECK_ONLY=1 ;; d) DESCRIBE=1 ;; - D) RC_CONFS= ;; + D) DEFAULT=1 RC_CONFS= ;; e) SHOW_EQUALS=1 ;; - f) RC_CONFS="$RC_CONFS${RC_CONFS:+ }$OPTARG" ;; + E) EXISTING_ONLY=1 ;; + f) DEFAULT= RC_CONFS="$RC_CONFS${RC_CONFS:+ }$OPTARG" ;; F) SHOW_FILE=1 ;; h) usage ;; # NOTREACHED i) IGNORE_UNKNOWNS=1 ;; j) [ "$OPTARG" ] || die "%s: Missing or null argument to \`-j' flag" "$pgm" JAIL="$OPTARG" ;; + l) LIST_CONFS=1 ;; + L) LIST_SERVICE_CONFS=1 ;; n) SHOW_NAME= ;; N) SHOW_VALUE= ;; q) QUIET=1 VERBOSE= ;; R) [ "$OPTARG" ] || die "%s: Missing or null argument to \`-R' flag" "$pgm" ROOTDIR="$OPTARG" ;; + s) [ "$OPTARG" ] || + die "%s: Missing or null argument to \`-s' flag" "$pgm" + SERVICE="$OPTARG" ;; v) VERBOSE=1 QUIET= ;; x) DELETE=${DELETE:-1} ;; X) DELETE=2 ;; @@ -274,6 +298,129 @@ while getopts aAcdDef:Fhij:nNqR:vxX flag; do done shift $(( $OPTIND - 1 )) +# +# Process `-L' flag +# +if [ "$LIST_SERVICE_CONFS" ]; then + list= + + # + # List rc_conf_files if no service names given + # + files= + [ $# -eq 0 ] && files=$( f_sysrc_get rc_conf_files ) + for file in $files; do + if [ "$EXISTING_ONLY" ]; then + [ -e "$file" -a ! -d "$file" ] || continue + fi + case "$list" in + "$file"|*" $file"|"$file "*|*" $file "*) continue ;; + esac + list="$list $file" + done + list="${list# }" + if [ $# -eq 0 ]; then + if [ "$VERBOSE" ]; then + echo rc_conf_files: $list + elif [ "$SHOW_EQUALS" ]; then + echo "rc_conf_files=\"$list\"" + fi + fi + + # + # List rc.conf.d entries + # + retval=$SUCCESS + for service in ${*:-$( service -l )}; do + slist= + f_sysrc_service_configs $service files || retval=$? continue + for file in $files; do + if [ "$EXISTING_ONLY" ]; then + [ -e "$file" -a ! -d "$file" ] || continue + fi + if [ ! "$VERBOSE" -a ! "$SHOW_EQUALS" ]; then + case "$list" in + "$file"|*" $file"|"$file "*|*" $file "*) + continue ;; + esac + fi + slist="$slist $file" + done + slist="${slist# }" + if [ $# -gt 0 ]; then + [ "$slist" ] || retval=$? + fi + if [ "$VERBOSE" ]; then + [ "$slist" ] && echo "$service: $slist" + continue + elif [ "$SHOW_EQUALS" ]; then + [ "$slist" ] && echo "$service=\"$slist\"" + continue + fi + list="$list${slist:+ }$slist" + done + if [ ! "$VERBOSE" -a ! "$SHOW_EQUALS" ]; then + if [ $# -eq 0 -o ! "$QUIET" ]; then + list="${list# }" + [ "$list" ] && echo $list + fi + fi + + exit $retval +fi + +# +# Process `-s name' argument +# +if [ "$SERVICE" -a ! "${RC_CONFS+set}" ]; then + if f_sysrc_service_configs "$SERVICE" RC_CONFS; then + rc_conf_files=$( f_sysrc_get rc_conf_files ) + RC_CONFS="$rc_conf_files${RC_CONFS:+ }$RC_CONFS" + unset rc_conf_files + else + unset RC_CONFS + fi +fi + +# +# Process `-E' option flag +# +if [ "$EXISTING_ONLY" ]; then + # + # To get f_sysrc_*() to ignore missing rc_conf_files, we have to use + # RC_CONFS to override the unpreened value. If RC_CONFS already has a + # value (`-D', `-f file', `-s name', or inherited from parent), use it. + # Otherwise, include filtered contents of rc_conf_files. + # + RC_CONFS=$( + if [ "${RC_CONFS+set}" ]; then + set -- $RC_CONFS + else + set -- $( f_sysrc_get rc_conf_files ) + fi + while [ $# -gt 0 ]; do + [ -f "$1" ] && echo -n " $1" + shift + done + ) + RC_CONFS="${RC_CONFS# }" +fi + +# +# Process `-l' option flag +# +if [ "$LIST_CONFS" ]; then + [ $# -eq 0 ] || usage + if [ "$DEFAULT" ]; then + echo "$RC_DEFAULTS" + elif [ "${RC_CONFS+set}" ]; then + echo "$RC_CONFS" + else + f_sysrc_get rc_conf_files + fi + exit $SUCCESS +fi + # # [More] Sanity checks (e.g., "sysrc --") # @@ -344,6 +491,10 @@ if [ "$JAIL" -o "$ROOTDIR" ]; then $( [ "$SHOW_ALL" = "1" ] && echo \ -a ) $( [ "$SHOW_ALL" = "2" ] && echo \ -A ) ${CHECK_ONLY:+-c} + ${DEFAULT:+-D} + ${EXISTING_ONLY:+-E} + ${LIST_CONFS:+-l} + ${LIST_SERVICE_CONFS:+-L} ${DESCRIBE:+-d} ${SHOW_EQUALS:+-e} ${IGNORE_UNKNOWNS:+-i} @@ -351,6 +502,11 @@ if [ "$JAIL" -o "$ROOTDIR" ]; then $( [ "$SHOW_VALUE" ] || echo \ -N ) $( [ "$SHOW_FILE" ] && echo \ -F ) " + if [ "$SERVICE" ]; then + escape "$SERVICE" _SERVICE + args="$args -s '$_SERVICE'" + unset _SERVICE + fi if [ "${RC_CONFS+set}" ]; then escape "$RC_CONFS" _RC_CONFS args="$args -f '$_RC_CONFS'" @@ -454,9 +610,10 @@ if [ "$SHOW_ALL" ]; then # IFS="$IFS|" EXCEPT="IFS|EXCEPT|PATH|RC_DEFAULTS|OPTIND|DESCRIBE|SEP" - EXCEPT="$EXCEPT|DELETE|SHOW_ALL|SHOW_EQUALS|SHOW_NAME" - EXCEPT="$EXCEPT|SHOW_VALUE|SHOW_FILE|VERBOSE|RC_CONFS" - EXCEPT="$EXCEPT|pgm|SUCCESS|FAILURE|CHECK_ONLY" + EXCEPT="$EXCEPT|DELETE|SHOW_ALL|SHOW_EQUALS|SHOW_NAME|DEFAULT" + EXCEPT="$EXCEPT|SHOW_VALUE|SHOW_FILE|VERBOSE|RC_CONFS|SERVICE" + EXCEPT="$EXCEPT|pgm|SUCCESS|FAILURE|CHECK_ONLY|EXISTING_ONLY" + EXCEPT="$EXCEPT|LIST_CONFS|LIST_SERVICE_CONFS" EXCEPT="$EXCEPT|f_sysrc_desc_awk|f_sysrc_delete_awk" # @@ -479,7 +636,13 @@ if [ "$SHOW_ALL" ]; then # explicit value, modifying the default behavior of # source_rc_confs(). # - [ "${RC_CONFS+set}" ] && rc_conf_files="$RC_CONFS" + if [ "${RC_CONFS+set}" ]; then + [ "$SHOW_ALL" = "1" -a "$SERVICE" -a \ + ! "$DEFAULT" ] || rc_conf_files= + rc_conf_files="$rc_conf_files $RC_CONFS" + rc_conf_files="${rc_conf_files# }" + rc_conf_files="${rc_conf_files% }" + fi source_rc_confs diff --git a/usr.sbin/sysrc/sysrc.8 b/usr.sbin/sysrc/sysrc.8 index b1767b856d4a..dbd0e4b3c326 100644 --- a/usr.sbin/sysrc/sysrc.8 +++ b/usr.sbin/sysrc/sysrc.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 2, 2015 +.Dd September 12, 2015 .Dt SYSRC 8 .Os .Sh NAME @@ -32,16 +32,27 @@ .Nd safely edit system rc files .Sh SYNOPSIS .Nm -.Op Fl cdDeFhinNqvx +.Op Fl cdDeEFhinNqvx +.Op Fl s Ar name .Op Fl f Ar file .Op Fl j Ar jail | Fl R Ar dir .Ar name Ns Op Ns Oo +|- Oc Ns = Ns Ar value .Ar ... .Nm -.Op Fl cdDeFhinNqvx +.Op Fl cdDeEFhinNqvx +.Op Fl s Ar name .Op Fl f Ar file .Op Fl j Ar jail | Fl R Ar dir .Fl a | A +.Nm +.Op Fl E +.Op Fl s Ar name +.Op Fl f Ar file +.Fl l +.Nm +.Op Fl eEqv +.Fl L +.Op Ar name ... .Sh DESCRIPTION The .Nm @@ -81,6 +92,13 @@ Ignored if either or .Ql Fl F is specified. +.It Fl E +When given +.Sq Fl l +or +.Sq Fl L +to list configuration files, only list those that exist. +When changing a setting, prefer to modify existing files. .It Fl f Ar file Operate on the specified file(s) instead of the files obtained by reading the .Sq rc_conf_files @@ -105,6 +123,17 @@ or name of the .Ar jail to operate within .Pq overrides So Fl R Ar dir Sc ; requires Xr jexec 8 . +.It Fl l +List configuration files used at startup on stdout and exit. +.It Fl L +List all configuration files including rc.conf.d entries on stdout and exit. +Can be combined with +.Sq Fl v +or +.Sq Fl e +to show service names. +.Nm +exits with success if all named services are installed, failure otherwise. .It Fl n Show only variable values, not their names. .It Fl N @@ -112,11 +141,40 @@ Show only variable names, not their values. .It Fl q Quiet. Disable verbose and hide certain errors. +When combined with +.Sq Fl L +and one or more +.Li Ar name +arguments, provide only exit status and no output. .It Fl R Ar dir Operate within the root directory .Sq Ar dir rather than .Sq / . +.It Fl s Ar name +If an +.Li rc.d +script of +.Ar name +exists +.Po +in +.Dq /etc/rc.d +or +.Li local_startup +directories +.Pc , +process its +.Dq rc.conf.d +entries as potential overrides to +.Sq rc_conf_files . +See +.Xr rc.subr 8 +for additional information on +.Dq rc.conf.d . +Can be combined with +.Sq Fl l +to list configuration files used by service at startup. .It Fl v Verbose. Print the pathname of the specific @@ -336,6 +394,10 @@ and .It Pa /etc/defaults/rc.conf .It Pa /etc/rc.conf .It Pa /etc/rc.conf.local +.It Pa /etc/rc.conf.d/name +.It Pa /etc/rc.conf.d/name/* +.It Pa /usr/local/etc/rc.conf.d/name +.It Pa /usr/local/etc/rc.conf.d/name/* .El .Sh EXAMPLES Below are some simple examples of how @@ -397,6 +459,7 @@ cloned_interfaces+"alternate" .Sh SEE ALSO .Xr jls 1 , .Xr rc.conf 5 , +.Xr rc.subr 8 , .Xr jail 8 , .Xr jexec 8 , .Xr rc 8 ,