diff options
author | dim <dim@FreeBSD.org> | 2015-10-01 19:02:45 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-10-01 19:02:45 +0000 |
commit | c88ca1c4064bdfc5aa9a040453a2bedcab5563cf (patch) | |
tree | 65e063ba4063b01c208d44deddda2fe59ac5f224 | |
parent | d3edc9664e05776279ed8ad8a20ad14cdd579030 (diff) | |
parent | e6448d3ce04113fa55305f4d9b53a92f11189be6 (diff) | |
download | FreeBSD-src-c88ca1c4064bdfc5aa9a040453a2bedcab5563cf.zip FreeBSD-src-c88ca1c4064bdfc5aa9a040453a2bedcab5563cf.tar.gz |
Merge ^/head r288197 through r288456.
560 files changed, 11055 insertions, 11809 deletions
@@ -243,9 +243,9 @@ cleanworld: # Handle the user-driven targets, using the source relative mk files. # -.if empty(.MAKEFLAGS:M-n) +.if !(!empty(.MAKEFLAGS:M-n) && ${.MAKEFLAGS:M-n} == "-n") # skip this for -n to avoid changing previous behavior of -# 'make -n buildworld' etc. +# 'make -n buildworld' etc. Using -n -n will run it. ${TGTS}: .MAKE tinderbox toolchains kernel-toolchains: .MAKE .endif diff --git a/Makefile.inc1 b/Makefile.inc1 index e11b54d..24f466c 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -257,9 +257,8 @@ BMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \ WORLDTMP=${WORLDTMP} \ VERSION="${VERSION}" \ MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" -BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \ - ${BMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \ - DESTDIR= \ +# need to keep this in sync with targets/pseudo/bootstrap-tools/Makefile +BSARGS= DESTDIR= \ BOOTSTRAPPING=${OSRELDATE} \ SSP_CFLAGS= \ MK_HTML=no NO_LINT=yes MK_MAN=no \ @@ -267,7 +266,11 @@ BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \ -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \ MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \ MK_LLDB=no MK_TESTS=no \ - MK_INCLUDES=yes + MK_INCLUDES=yes + +BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \ + ${BMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \ + ${BSARGS} # build-tools stage TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \ @@ -1255,7 +1258,7 @@ update: # ELF Tool Chain libraries are needed for ELF tools and dtrace tools. .if ${BOOTSTRAPPING} < 1100006 -_elftoolchain_libs= lib/libelf lib/libdwarf +_elftoolchain_libs= lib/libelf lib/libdwarf .endif legacy: @@ -1279,7 +1282,7 @@ legacy: # binaries is usually quite narrow. Bootstrap tools use the host's compiler and # libraries, augmented by -legacy. # -_bt= _bootstrap-tools +_bt= _bootstrap-tools .if ${MK_GAMES} != "no" _strfile= games/fortune/strfile @@ -1494,7 +1497,7 @@ _btxld= usr.sbin/btxld # Rebuild ctfconvert and ctfmerge to avoid difficult-to-diagnose failures # resulting from missing bug fixes or ELF Toolchain updates. .if ${MK_CDDL} != "no" -_dtrace_tools= cddl/usr.bin/sgsmsg cddl/lib/libctf cddl/usr.bin/ctfconvert \ +_dtrace_tools= cddl/lib/libctf cddl/usr.bin/ctfconvert \ cddl/usr.bin/ctfmerge .endif diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 372c3ff..8e4483f 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -101,6 +101,14 @@ OLD_FILES+=usr/lib/clang/3.6.1/lib/freebsd/libclang_rt.ubsan_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/3.6.1/lib/freebsd OLD_DIRS+=usr/lib/clang/3.6.1/lib OLD_DIRS+=usr/lib/clang/3.6.1 +# 20150928: unused sgsmsg utility is removed +OLD_FILES+=usr/bin/sgsmsg +# 20150926: remove links to removed/unimplemented mbuf(9) macros +OLD_FILES+=usr/share/man/man9/MEXT_ADD_REF.9.gz +OLD_FILES+=usr/share/man/man9/MEXTFREE.9.gz +OLD_FILES+=usr/share/man/man9/MEXT_IS_REF.9.gz +OLD_FILES+=usr/share/man/man9/MEXT_REM_REF.9.gz +OLD_FILES+=usr/share/man/man9/MFREE.9.gz # 20150818: *allocm() are gone in jemalloc 4.0.0 OLD_FILES+=usr/share/man/man3/allocm.3.gz OLD_FILES+=usr/share/man/man3/dallocm.3.gz diff --git a/bin/ls/Makefile b/bin/ls/Makefile index a9431f1..e57bf35 100644 --- a/bin/ls/Makefile +++ b/bin/ls/Makefile @@ -13,4 +13,8 @@ CFLAGS+= -DCOLORLS LIBADD+= termcapw .endif +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + .include <bsd.prog.mk> diff --git a/bin/ls/ls.1 b/bin/ls/ls.1 index 3e02229..6bca9aa 100644 --- a/bin/ls/ls.1 +++ b/bin/ls/ls.1 @@ -32,7 +32,7 @@ .\" @(#)ls.1 8.7 (Berkeley) 7/29/94 .\" $FreeBSD$ .\" -.Dd June 8, 2015 +.Dd September 27, 2015 .Dt LS 1 .Os .Sh NAME @@ -296,9 +296,9 @@ subsection below, except (if the long format is not also requested) the directory totals are not output when the output is in a single column, even if multi-column output is requested. .It Fl t -Sort by descending time modified (most recently modified first). If two files -have the same modification timestamp, sort their names in ascending -lexicographical order. +Sort by descending time modified (most recently modified first). +If two files have the same modification timestamp, sort their names +in ascending lexicographical order. The .Fl r option reverses both of these sort orders. @@ -320,7 +320,7 @@ or use the option. This causes .Nm -to reverse the lexicographal sort order when sorting files with the +to reverse the lexicographical sort order when sorting files with the same modification timestamp. .It Fl u Use time of last access, diff --git a/bin/ls/tests/Makefile b/bin/ls/tests/Makefile new file mode 100644 index 0000000..38770e3 --- /dev/null +++ b/bin/ls/tests/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/bin/ls + +ATF_TESTS_SH+= ls_tests +# This seems like overkill, but the idea in mind is that all of the testcases +# should be runnable as !root +TEST_METADATA.ls_tests+= required_user="unprivileged" +TEST_METADATA.ls_tests+= required_files="/usr/bin/nc" + +.include <bsd.test.mk> diff --git a/bin/ls/tests/ls_tests.sh b/bin/ls/tests/ls_tests.sh new file mode 100755 index 0000000..6e6ebb7 --- /dev/null +++ b/bin/ls/tests/ls_tests.sh @@ -0,0 +1,359 @@ +# +# Copyright 2015 EMC Corp. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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 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. +# +# $FreeBSD$ +# + +create_test_dir() +{ + [ -z "$ATF_TMPDIR" ] || return 0 + + export ATF_TMPDIR=$(pwd) + + # XXX: need to nest this because of how kyua creates $TMPDIR; otherwise + # it will run into EPERM issues later + TEST_INPUTS_DIR="${ATF_TMPDIR}/test/inputs" + + atf_check -e empty -s exit:0 mkdir -m 0777 -p $TEST_INPUTS_DIR + cd $TEST_INPUTS_DIR +} + +create_test_inputs() +{ + create_test_dir + + atf_check -e empty -s exit:0 mkdir -m 0755 -p a/b + atf_check -e empty -s exit:0 ln -s a/b c + atf_check -e empty -s exit:0 touch d + atf_check -e empty -s exit:0 ln d e + atf_check -e empty -s exit:0 touch .f + atf_check -e empty -s exit:0 mkdir .g + atf_check -e empty -s exit:0 mkfifo h + atf_check -e ignore -s exit:0 dd if=/dev/zero of=i count=1000 bs=1 + atf_check -e empty -s exit:0 \ + sh -c "pid=${ATF_TMPDIR}/nc.pid; daemon -p \$pid nc -lU j; sleep 2; pkill -F \$pid" + atf_check -e empty -s exit:0 touch klmn + atf_check -e empty -s exit:0 touch opqr + atf_check -e empty -s exit:0 touch stuv + atf_check -e empty -s exit:0 touch wxyz + atf_check -e empty -s exit:0 touch 0b00000001 + atf_check -e empty -s exit:0 touch 0b00000010 + atf_check -e empty -s exit:0 touch 0b00000011 + atf_check -e empty -s exit:0 touch 0b00000100 + atf_check -e empty -s exit:0 touch 0b00000101 + atf_check -e empty -s exit:0 touch 0b00000110 + atf_check -e empty -s exit:0 touch 0b00000111 + atf_check -e empty -s exit:0 touch 0b00001000 + atf_check -e empty -s exit:0 touch 0b00001001 + atf_check -e empty -s exit:0 touch 0b00001010 + atf_check -e empty -s exit:0 touch 0b00001011 + atf_check -e empty -s exit:0 touch 0b00001100 + atf_check -e empty -s exit:0 touch 0b00001101 + atf_check -e empty -s exit:0 touch 0b00001110 + atf_check -e empty -s exit:0 touch 0b00001111 +} + +atf_test_case a_flag +a_flag_head() +{ + atf_set "descr" "Verify -a support" +} + +a_flag_body() +{ + create_test_dir + + # Make sure "." and ".." show up with -a + atf_check -e empty -o match:'\.[[:space:]]+\.\.' -s exit:0 ls -ax + + create_test_inputs + + WITH_a=$PWD/../with_a.out + WITHOUT_a=$PWD/../without_a.out + + atf_check -e empty -o save:$WITH_a -s exit:0 ls -A + atf_check -e empty -o save:$WITHOUT_a -s exit:0 ls + + echo "-A usage" + cat $WITH_a + echo "No -A usage" + cat $WITHOUT_a + + for dot_path in '\.f' '\.g'; do + atf_check -e empty -o not-empty -s exit:0 grep "${dot_path}" \ + $WITH_a + atf_check -e empty -o empty -s not-exit:0 grep "${dot_path}" \ + $WITHOUT_a + done +} + +atf_test_case A_flag +A_flag_head() +{ + atf_set "descr" "Verify -A support with unprivileged users" +} + +A_flag_body() +{ + create_test_dir + + atf_check -e empty -o empty -s exit:0 ls -A + + create_test_inputs + + WITH_A=$PWD/../with_A.out + WITHOUT_A=$PWD/../without_A.out + + atf_check -e empty -o save:$WITH_A -s exit:0 ls -A + atf_check -e empty -o save:$WITHOUT_A -s exit:0 ls + + echo "-A usage" + cat $WITH_A + echo "No -A usage" + cat $WITHOUT_A + + for dot_path in '\.f' '\.g'; do + atf_check -e empty -o not-empty -s exit:0 grep "${dot_path}" \ + $WITH_A + atf_check -e empty -o empty -s not-exit:0 grep "${dot_path}" \ + $WITHOUT_A + done +} + +atf_test_case A_flag_implied_when_root +A_flag_implied_when_root_head() +{ + atf_set "descr" "Verify that -A is implied for root" + atf_set "require.user" "root" +} + +A_flag_implied_when_root_body() +{ + create_test_dir + + atf_check -e empty -o empty -s exit:0 ls -A + + create_test_inputs + + WITH_EXPLICIT=$PWD/../with_explicit_A.out + WITH_IMPLIED=$PWD/../with_implied_A.out + + atf_check -e empty -o save:$WITH_EXPLICIT -s exit:0 ls -A + atf_check -e empty -o save:$WITH_IMPLIED -s exit:0 ls + + echo "Explicit -A usage" + cat $WITH_EXPLICIT + echo "Implicit -A usage" + cat $WITH_IMPLIED + + atf_check_equal "$(cat $WITH_EXPLICIT)" "$(cat $WITH_IMPLIED)" +} + +atf_test_case B_flag +B_flag_head() +{ + atf_set "descr" "Verify that the output from ls -B prints out non-printable characters" +} + +B_flag_body() +{ + atf_skip "kyua report-jenkins doesn't properly escape non-printable chars: https://github.com/jmmv/kyua/issues/136" + + atf_check -e empty -o empty -s exit:0 touch "$(printf "y\013z")" + atf_check -e empty -o match:'y\\013z' -s exit:0 ls -B +} + +atf_test_case C_flag +C_flag_head() +{ + atf_set "descr" "Verify that the output from ls -C is multi-column, sorted down" +} + +C_flag_body() +{ + create_test_inputs + + WITH_C=$PWD/../with_C.out + + atf_check -e empty -o save:$WITH_C -s exit:0 ls -C + + echo "With -C usage" + cat $WITH_C + + atf_check -e ignore -o not-empty -s exit:0 \ + egrep "0b00000001[[:space:]]+0b00000111[[:space:]]+0b00001101[[:space:]]+e[[:space:]]+stuv" $WITH_C + atf_check -e ignore -o not-empty -s exit:0 \ + egrep "0b00000010[[:space:]]+0b00001000[[:space:]]+0b00001110[[:space:]]+h[[:space:]]+wxyz" $WITH_C +} + +atf_test_case I_flag +I_flag_head() +{ + atf_set "descr" "Verify that the output from ls -I is the same as ls for an unprivileged user" +} + +I_flag_body() +{ + create_test_inputs + + WITH_I=$PWD/../with_I.out + WITHOUT_I=$PWD/../without_I.out + + atf_check -e empty -o save:$WITH_I -s exit:0 ls -I + atf_check -e empty -o save:$WITHOUT_I -s exit:0 ls + + echo "Explicit -I usage" + cat $WITH_I + echo "No -I usage" + cat $WITHOUT_I + + atf_check_equal "$(cat $WITH_I)" "$(cat $WITHOUT_I)" +} + +atf_test_case I_flag_voids_implied_A_flag_when_root +I_flag_voids_implied_A_flag_when_root_head() +{ + atf_set "descr" "Verify that -I voids out implied -A for root" + atf_set "require.user" "root" +} + +I_flag_voids_implied_A_flag_when_root_body() +{ + create_test_inputs + + atf_check -o not-match:'\.f' -s exit:0 ls -I + atf_check -o not-match:'\.g' -s exit:0 ls -I + + atf_check -o match:'\.f' -s exit:0 ls -A -I + atf_check -o match:'\.g' -s exit:0 ls -A -I +} + +lcomma_flag_head() +{ + atf_set "descr" "Verify that -l, prints out the size with , delimiters" +} + +lcomma_flag_body() +{ + create_test_inputs + + atf_check \ + -o match:'\-rw\-r\-\-r\-\-[[:space:]]+.+[[:space:]]+1,000[[:space:]]+.+i' \ + env LC_ALL=en_US.ISO8859-1 ls -l, i +} + +x_flag_head() +{ + atf_set "descr" "Verify that -x prints out one item per line" +} + +x_flag_body() +{ + create_test_inputs + + WITH_x=$PWD/../with_x.out + + atf_check -e empty -o save:$WITH_x -s exit:0 ls -x + + echo "With -x usage" + cat $WITH_x + + atf_check -e ignore -o not-empty -s exit:0 \ + egrep "a[[:space:]]+c[[:space:]]+d[[:space:]]+e[[:space:]]+h" $WITH_x + atf_check -e ignore -o not-empty -s exit:0 \ + egrep "i[[:space:]]+j[[:space:]]+klmn[[:space:]]+opqr[[:space:]]+stuv" $WITH_x +} + +1_flag_head() +{ + atf_set "descr" "Verify that -1 prints out one item per line" +} + +1_flag_body() +{ + create_test_inputs + + WITH_1=$PWD/../with_1.out + WITHOUT_1=$PWD/../without_1.out + + atf_check -e empty -o save:$WITH_1 -s exit:0 ls -1 + atf_check -e empty -o save:$WITHOUT_1 -s exit:0 \ + sh -c 'for i in $(ls); do echo $i; done' + + echo "Explicit -1 usage" + cat $WITH_1 + echo "No -1 usage" + cat $WITHOUT_1 + + atf_check_equal "$(cat $WITH_1)" "$(cat $WITHOUT_1)" +} + +atf_init_test_cases() +{ + + atf_add_test_case A_flag + atf_add_test_case A_flag_implied_when_root + atf_add_test_case B_flag + atf_add_test_case C_flag + #atf_add_test_case D_flag + #atf_add_test_case F_flag + #atf_add_test_case G_flag + #atf_add_test_case H_flag + atf_add_test_case I_flag + atf_add_test_case I_flag_voids_implied_A_flag_when_root + #atf_add_test_case L_flag + #atf_add_test_case P_flag + #atf_add_test_case R_flag + #atf_add_test_case S_flag + #atf_add_test_case T_flag + #atf_add_test_case U_flag + #atf_add_test_case W_flag + #atf_add_test_case Z_flag + atf_add_test_case a_flag + #atf_add_test_case b_flag + #atf_add_test_case c_flag + #atf_add_test_case d_flag + #atf_add_test_case f_flag + #atf_add_test_case g_flag + #atf_add_test_case h_flag + #atf_add_test_case i_flag + #atf_add_test_case k_flag + #atf_add_test_case l_flag + atf_add_test_case lcomma_flag + #atf_add_test_case m_flag + #atf_add_test_case n_flag + #atf_add_test_case o_flag + #atf_add_test_case p_flag + #atf_add_test_case q_flag + #atf_add_test_case r_flag + #atf_add_test_case s_flag + #atf_add_test_case t_flag + #atf_add_test_case u_flag + #atf_add_test_case w_flag + atf_add_test_case x_flag + #atf_add_test_case y_flag + atf_add_test_case 1_flag +} diff --git a/bin/sh/builtins.def b/bin/sh/builtins.def index 1cbeea9..8807347 100644 --- a/bin/sh/builtins.def +++ b/bin/sh/builtins.def @@ -65,6 +65,7 @@ exportcmd -s export -s readonly #exprcmd expr falsecmd false fgcmd -j fg +freebsd_wordexpcmd freebsd_wordexp getoptscmd getopts hashcmd hash histcmd -h fc diff --git a/bin/sh/expand.c b/bin/sh/expand.c index 7411f1c..88d80ea 100644 --- a/bin/sh/expand.c +++ b/bin/sh/expand.c @@ -1656,3 +1656,57 @@ wordexpcmd(int argc, char **argv) outbin(argv[i], strlen(argv[i]) + 1, out1); return (0); } + +/* + * Do most of the work for wordexp(3), new version. + */ + +int +freebsd_wordexpcmd(int argc __unused, char **argv __unused) +{ + struct arglist arglist; + union node *args, *n; + struct strlist *sp; + size_t count, len; + int ch; + int protected = 0; + int fd = -1; + + while ((ch = nextopt("f:p")) != '\0') { + switch (ch) { + case 'f': + fd = number(shoptarg); + break; + case 'p': + protected = 1; + break; + } + } + if (*argptr != NULL) + error("wrong number of arguments"); + if (fd < 0) + error("missing fd"); + INTOFF; + setinputfd(fd, 1); + INTON; + args = parsewordexp(); + popfile(); /* will also close fd */ + if (protected) + for (n = args; n != NULL; n = n->narg.next) { + if (n->narg.backquote != NULL) { + outcslow('C', out1); + error("command substitution disabled"); + } + } + outcslow(' ', out1); + arglist.lastp = &arglist.list; + for (n = args; n != NULL; n = n->narg.next) + expandarg(n, &arglist, EXP_FULL | EXP_TILDE); + *arglist.lastp = NULL; + for (sp = arglist.list, count = len = 0; sp; sp = sp->next) + count++, len += strlen(sp->text); + out1fmt("%016zx %016zx", count, len); + for (sp = arglist.list; sp; sp = sp->next) + outbin(sp->text, strlen(sp->text) + 1, out1); + return (0); +} diff --git a/bin/sh/parser.c b/bin/sh/parser.c index 302d179..53d7923 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -231,6 +231,39 @@ parsecmd(int interact) } +/* + * Read and parse words for wordexp. + * Returns a list of NARG nodes; NULL if there are no words. + */ +union node * +parsewordexp(void) +{ + union node *n, *first = NULL, **pnext; + int t; + + /* This assumes the parser is not re-entered, + * which could happen if we add command substitution on PS1/PS2. + */ + parser_temp_free_all(); + heredoclist = NULL; + + tokpushback = 0; + checkkwd = 0; + doprompt = 0; + setprompt(0); + needprompt = 0; + pnext = &first; + while ((t = readtoken()) != TEOF) { + if (t != TWORD) + synexpect(TWORD); + n = makename(); + *pnext = n; + pnext = &n->narg.next; + } + return first; +} + + static union node * list(int nlflag) { diff --git a/bin/sh/parser.h b/bin/sh/parser.h index 5982594..0c3cd88 100644 --- a/bin/sh/parser.h +++ b/bin/sh/parser.h @@ -76,6 +76,7 @@ extern const char *const parsekwd[]; union node *parsecmd(int); +union node *parsewordexp(void); void forcealias(void); void fixredir(union node *, const char *, int); int goodname(const char *); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.kpriv.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.kpriv.ksh new file mode 100644 index 0000000..da776d0 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.kpriv.ksh @@ -0,0 +1,112 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2015, Joyent, Inc. All rights reserved. +# + +err=/tmp/err.$$ + +ppriv -s A=basic,dtrace_user $$ + +# +# When we lack dtrace_kernel, we expect to not be able to get at kernel memory +# via any subroutine or other vector. +# +# trace(func((void *)&\`utsname)); } +/usr/sbin/dtrace -wq -Cs /dev/stdin 2> $err <<EOF + +#define FAIL \ + printf("able to read kernel memory via %s!\n", badsubr); \ + exit(2); + +#define CANTREAD1(func) \ + BEGIN { badsubr = "func()"; func((void *)&\`utsname); FAIL } + +#define CANTREAD2(func, arg1) \ + BEGIN { badsubr = "func()"; func((void *)&\`utsname, arg1); FAIL } + +#define CANTREAD2ARG1(func, arg0) \ + BEGIN { badsubr = "func() (arg1)"; func(arg0, (void *)&\`utsname); FAIL } + +#define CANTREAD3(func, arg1, arg2) \ + BEGIN { badsubr = "func()"; func((void *)&\`utsname, arg1, arg2); FAIL } + +CANTREAD1(mutex_owned) +CANTREAD1(mutex_owner) +CANTREAD1(mutex_type_adaptive) +CANTREAD1(mutex_type_spin) +CANTREAD1(rw_read_held) +CANTREAD1(rw_write_held) +CANTREAD1(rw_iswriter) +CANTREAD3(bcopy, alloca(1), 1) +CANTREAD1(msgsize) +CANTREAD1(msgdsize) +CANTREAD1(strlen) +CANTREAD2(strchr, '!') +CANTREAD2(strrchr, '!') +CANTREAD2(strstr, "doogle") +CANTREAD2ARG1(strstr, "doogle") +CANTREAD2(index, "bagnoogle") +CANTREAD2ARG1(index, "bagnoogle") +CANTREAD2(rindex, "bagnoogle") +CANTREAD2ARG1(rindex, "bagnoogle") +CANTREAD2(strtok, "doogle") +CANTREAD2ARG1(strtok, "doogle") +CANTREAD2(json, "doogle") +CANTREAD2ARG1(json, "doogle") +CANTREAD1(toupper) +CANTREAD1(tolower) +CANTREAD2(ddi_pathname, 1) +CANTREAD2(strjoin, "doogle") +CANTREAD2ARG1(strjoin, "doogle") +CANTREAD1(strtoll) +CANTREAD1(dirname) +CANTREAD1(basename) +CANTREAD1(cleanpath) + +#if defined(__amd64) +CANTREAD3(copyout, uregs[R_R9], 1) +CANTREAD3(copyoutstr, uregs[R_R9], 1) +#else +#if defined(__i386) +CANTREAD3(copyout, uregs[R_ESP], 1) +CANTREAD3(copyoutstr, uregs[R_ESP], 1) +#endif +#endif + +BEGIN +{ + exit(0); +} + +ERROR +/arg4 != DTRACEFLT_KPRIV/ +{ + printf("bad error code via %s (expected %d, found %d)\n", + badsubr, DTRACEFLT_KPRIV, arg4); + exit(3); +} + +ERROR +/arg4 == DTRACEFLT_KPRIV/ +{ + printf("illegal kernel access properly prevented from %s\n", badsubr); +} +EOF + +status=$? + +if [[ $status -eq 1 ]]; then + cat $err +fi + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.bigglobal.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.bigglobal.d new file mode 100644 index 0000000..a50a759 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.bigglobal.d @@ -0,0 +1,26 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2015, Joyent, Inc. All rights reserved. + */ + +struct mrbig { + char toomany[100000]; +}; + +struct mrbig mrbig; + +BEGIN +{ + mrbig.toomany[0] = '!'; + exit(0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.biglocal.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.biglocal.d new file mode 100644 index 0000000..08a2a4c --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.biglocal.d @@ -0,0 +1,26 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2015, Joyent, Inc. All rights reserved. + */ + +struct mrbig { + char toomany[100000]; +}; + +this struct mrbig mrbig; + +BEGIN +{ + this->mrbig.toomany[0] = '!'; + exit(0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh index 696088c..f1887ea 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh @@ -69,7 +69,7 @@ prov.h: prov.d $dtrace -h -s prov.d prov.o: prov.d main.o - $dtrace -G -32 -s prov.d main.o + $dtrace -G -s prov.d main.o EOF cat > prov.d <<EOF diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh index 96b05d5..7dcfd41 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh @@ -77,7 +77,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh index d0ac186..2a1f9b6 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh @@ -66,7 +66,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh index d40036d..662076a 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh @@ -82,7 +82,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh index 51afe96..43726a2 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh @@ -75,7 +75,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh index 3ee9e9f..72304cb 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh @@ -76,7 +76,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.header.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.header.ksh index 37ad97c..ef07525 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.header.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.header.ksh @@ -70,7 +70,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh index a1ef9d8..4aa3f59 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh @@ -67,7 +67,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh index ffc5107..01d127f 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh @@ -69,7 +69,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh index 3f545a7..b517e88 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh @@ -70,7 +70,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiprov.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiprov.ksh index bf267c7..9620b97 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiprov.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiprov.ksh @@ -71,7 +71,7 @@ EOF exit 1 fi - $dtrace -G -32 -s $oogle.d $oogle.o -o $oogle.d.o + $dtrace -G -s $oogle.d $oogle.o -o $oogle.d.o if [ $? -ne 0 ]; then print -u2 "failed to process $oogle.d" diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noprobes.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noprobes.ksh index 2c1aedc..4f3264f 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noprobes.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noprobes.ksh @@ -47,7 +47,7 @@ provider doogle { EOF cc -c test.c -$dtrace -G -32 -s doogle.d test.o -o doogle.d.o +$dtrace -G -s doogle.d test.o -o doogle.d.o if [ $? -eq 0 ]; then print -u2 "dtrace succeeded despite having no probe sites" diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh index 905fb55..a2837d8 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh @@ -56,7 +56,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh index 2afd781..16ff34a 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh @@ -56,7 +56,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh index 9def3c0..db2771a 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh @@ -67,7 +67,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh index 4f6c0ac..8ce1dc0 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh @@ -56,7 +56,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh index 4ea33f7..2c6c7bc 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh @@ -57,7 +57,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh index 0cddf0d..8a19c77 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh @@ -68,7 +68,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh index 8385b27..a6ddfe8 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh @@ -72,13 +72,13 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create initial DOF" exit 1 fi rm -f prov.o -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create final DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh index 89ceb4a..3c22958 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh @@ -67,7 +67,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 fi -$dtrace -G -32 -s prov.d test.o +$dtrace -G -s prov.d test.o if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 diff --git a/cddl/contrib/opensolaris/cmd/lockstat/lockstat.1 b/cddl/contrib/opensolaris/cmd/lockstat/lockstat.1 index 1aa73cc..5524968 100644 --- a/cddl/contrib/opensolaris/cmd/lockstat/lockstat.1 +++ b/cddl/contrib/opensolaris/cmd/lockstat/lockstat.1 @@ -21,7 +21,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 24, 2015 +.Dd September 29, 2015 .Dt LOCKSTAT 1 .Os .Sh NAME @@ -38,7 +38,7 @@ .Op Fl d Ar duration .Op Fl f Ar function Oo Ns , Ns Ar size Oc .Op Fl T -.Op Fl ckgwWRpP +.Op Fl kgwWRpP .Op Fl D Ar count .Op Fl o filename .Op Fl x Ar opt Oo Ns = Ns Ar val Oc @@ -172,8 +172,6 @@ This is off by default. .El .Ss Data Reporting .Bl -tag -width indent -.It Fl c -Coalesce lock data for lock arrays. .It Fl D Ar count Only display the top .Ar count diff --git a/cddl/contrib/opensolaris/cmd/lockstat/lockstat.c b/cddl/contrib/opensolaris/cmd/lockstat/lockstat.c index b59bee7..38bf681 100644 --- a/cddl/contrib/opensolaris/cmd/lockstat/lockstat.c +++ b/cddl/contrib/opensolaris/cmd/lockstat/lockstat.c @@ -65,7 +65,11 @@ typedef uintptr_t pc_t; typedef struct lsrec { struct lsrec *ls_next; /* next in hash chain */ +#ifdef illumos uintptr_t ls_lock; /* lock address */ +#else + char *ls_lock; /* lock name */ +#endif uintptr_t ls_caller; /* caller address */ uint32_t ls_count; /* cumulative event count */ uint32_t ls_event; /* type of event */ @@ -338,7 +342,9 @@ usage(void) " -d duration only watch events longer than <duration>\n" " -T trace (rather than sample) events\n" "\nData reporting options:\n\n" +#ifdef illumos " -c coalesce lock data for arrays like pse_mutex[]\n" +#endif " -k coalesce PCs within functions\n" " -g show total events generated by function\n" " -w wherever: don't distinguish events by caller\n" @@ -381,12 +387,16 @@ lockcmp(lsrec_t *a, lsrec_t *b) if (a->ls_caller > b->ls_caller) return (1); +#ifdef illumos if (a->ls_lock < b->ls_lock) return (-1); if (a->ls_lock > b->ls_lock) return (1); return (0); +#else + return (strcmp(a->ls_lock, b->ls_lock)); +#endif } static int @@ -424,26 +434,40 @@ lockcmp_anywhere(lsrec_t *a, lsrec_t *b) if (a->ls_event > b->ls_event) return (1); +#ifdef illumos if (a->ls_lock < b->ls_lock) return (-1); if (a->ls_lock > b->ls_lock) return (1); return (0); +#else + return (strcmp(a->ls_lock, b->ls_lock)); +#endif } static int lock_and_count_cmp_anywhere(lsrec_t *a, lsrec_t *b) { +#ifndef illumos + int cmp; +#endif + if (a->ls_event < b->ls_event) return (-1); if (a->ls_event > b->ls_event) return (1); +#ifdef illumos if (a->ls_lock < b->ls_lock) return (-1); if (a->ls_lock > b->ls_lock) return (1); +#else + cmp = strcmp(a->ls_lock, b->ls_lock); + if (cmp != 0) + return (cmp); +#endif return (b->ls_count - a->ls_count); } @@ -698,7 +722,11 @@ dprog_addevent(int event) caller = "(uintptr_t)arg0"; arg1 = "arg2"; } else { +#ifdef illumos arg0 = "(uintptr_t)arg0"; +#else + arg0 = "stringof(args[0]->lock_object.lo_name)"; +#endif caller = "caller"; } @@ -912,12 +940,17 @@ lsrec_fill(lsrec_t *lsrec, const dtrace_recdesc_t *rec, int nrecs, caddr_t data) lsrec->ls_event = (uint32_t)*((uint64_t *)(data + rec->dtrd_offset)); rec++; +#ifdef illumos if (rec->dtrd_size != sizeof (uintptr_t)) fail(0, "bad lock address size in second record"); /* LINTED - alignment */ lsrec->ls_lock = *((uintptr_t *)(data + rec->dtrd_offset)); rec++; +#else + lsrec->ls_lock = strdup((const char *)(data + rec->dtrd_offset)); + rec++; +#endif if (rec->dtrd_size != sizeof (uintptr_t)) fail(0, "bad caller size in third record"); @@ -1224,9 +1257,11 @@ main(int argc, char **argv) events_specified = 1; break; +#ifdef illumos case 'c': g_cflag = 1; break; +#endif case 'k': g_kflag = 1; @@ -1539,6 +1574,9 @@ main(int argc, char **argv) caller_in_stack = 1; bcopy(oldlsp, lsp, LS_TIME); lsp->ls_caller = oldlsp->ls_stack[fr]; +#ifndef illumos + lsp->ls_lock = strdup(oldlsp->ls_lock); +#endif /* LINTED - alignment */ lsp = (lsrec_t *)((char *)lsp + LS_TIME); } @@ -1547,6 +1585,9 @@ main(int argc, char **argv) /* LINTED - alignment */ lsp = (lsrec_t *)((char *)lsp + LS_TIME); } +#ifndef illumos + free(oldlsp->ls_lock); +#endif } g_nrecs = g_nrecs_used = ((uintptr_t)lsp - (uintptr_t)newlsp) / LS_TIME; @@ -1604,8 +1645,10 @@ main(int argc, char **argv) for (i = 0; i < g_nrecs_used; i++) { int fr; lsp = sort_buf[i]; +#ifdef illumos if (g_cflag) coalesce_symbol(&lsp->ls_lock); +#endif if (g_kflag) { for (fr = 0; fr < g_stkdepth; fr++) coalesce_symbol(&lsp->ls_stack[fr]); @@ -1659,6 +1702,15 @@ main(int argc, char **argv) first = current; } +#ifndef illumos + /* + * Free lock name buffers + */ + for (i = 0, lsp = (lsrec_t *)data_buf; i < g_nrecs_used; i++, + lsp = (lsrec_t *)((char *)lsp + g_recsize)) + free(lsp->ls_lock); +#endif + return (0); } @@ -1748,8 +1800,12 @@ report_stats(FILE *out, lsrec_t **sort_buf, size_t nrecs, uint64_t total_count, (void) fprintf(out, "%u %u", lsp->ls_event, lsp->ls_count); +#ifdef illumos (void) fprintf(out, " %s", format_symbol(buf, lsp->ls_lock, g_cflag)); +#else + (void) fprintf(out, " %s", lsp->ls_lock); +#endif (void) fprintf(out, " %s", format_symbol(buf, lsp->ls_caller, 0)); (void) fprintf(out, " %f", @@ -1811,8 +1867,12 @@ report_stats(FILE *out, lsrec_t **sort_buf, size_t nrecs, uint64_t total_count, (void) fprintf(out, "%4.2f %8s ", (double)lsp->ls_refcnt / lsp->ls_count, buf); +#ifdef illumos (void) fprintf(out, "%-22s ", format_symbol(buf, lsp->ls_lock, g_cflag)); +#else + (void) fprintf(out, "%-22s ", lsp->ls_lock); +#endif (void) fprintf(out, "%-24s\n", format_symbol(buf, lsp->ls_caller, 0)); @@ -1908,7 +1968,11 @@ report_trace(FILE *out, lsrec_t **sort_buf) (void) fprintf(out, "%2d %10llu %11p %-24s %-24s\n", lsp->ls_event, (unsigned long long)lsp->ls_time, (void *)lsp->ls_next, +#ifdef illumos format_symbol(buf, lsp->ls_lock, 0), +#else + lsp->ls_lock, +#endif format_symbol(buf2, lsp->ls_caller, 0)); if (rectype <= LS_STACK(0)) diff --git a/cddl/contrib/opensolaris/cmd/sgs/include/_string_table.h b/cddl/contrib/opensolaris/cmd/sgs/include/_string_table.h deleted file mode 100644 index 2d2963f..0000000 --- a/cddl/contrib/opensolaris/cmd/sgs/include/_string_table.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef __STRING_TABLE_DOT_H -#define __STRING_TABLE_DOT_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> -#include <sys/avl.h> -#include <string_table.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * A string is represented in a string table using two values: length, and - * value. Grouping all the strings of a given length together allows for - * efficient matching of tail strings, as each input string value is hashed. - * Each string table uses a 2-level AVL tree of AVL trees to represent this - * organization. - * - * The outer (main) AVL tree contains LenNode structures. The search key for - * nodes on this main tree is the string length. Each such node represents - * all strings of a given length, and all strings of that length are found - * within. - * - * The strings within each LenNode are maintained using a secondary AVL tree - * of StrNode structures. The search key for this inner tree is the string - * itself. The strings are maintained in lexical order. - */ -typedef struct { - avl_node_t sn_avlnode; /* AVL book-keeping */ - const char *sn_str; /* string */ - size_t sn_refcnt; /* reference count */ -} StrNode; - -typedef struct { - avl_node_t ln_avlnode; /* AVL book-keeping */ - avl_tree_t *ln_strtree; /* AVL tree of associated strings */ - size_t ln_strlen; /* length of associated strings */ -} LenNode; - -/* - * Define a master string data item. Other strings may be suffixes of this - * string. The final string table will consist of the master string values, - * laid end to end, with the other strings referencing their tails. - */ -typedef struct str_master Str_master; - -struct str_master { - const char *sm_str; /* pointer to master string */ - Str_master *sm_next; /* used for tracking master strings */ - size_t sm_strlen; /* length of master string */ - uint_t sm_hashval; /* hashval of master string */ - size_t sm_stroff; /* offset into destination strtab */ -}; - -/* - * Define a hash data item. This item represents an individual string that has - * been input into the String hash table. The string may either be a suffix of - * another string, or a master string. - */ -typedef struct str_hash Str_hash; - -struct str_hash { - size_t hi_strlen; /* string length */ - size_t hi_refcnt; /* number of references to str */ - uint_t hi_hashval; /* hash for string */ - Str_master *hi_mstr; /* pointer to master string */ - Str_hash *hi_next; /* next entry in hash bucket */ -}; - -/* - * Controlling data structure for a String Table. - */ -struct str_tbl { - avl_tree_t *st_lentree; /* AVL tree of string lengths */ - char *st_strbuf; /* string buffer */ - Str_hash **st_hashbcks; /* hash buckets */ - Str_master *st_mstrlist; /* list of all master strings */ - size_t st_fullstrsize; /* uncompressed table size */ - size_t st_nextoff; /* next available string */ - size_t st_strsize; /* compressed size */ - size_t st_strcnt; /* number of strings */ - uint_t st_hbckcnt; /* number of buckets in */ - /* hashlist */ - uint_t st_flags; -}; - -#define FLG_STTAB_COMPRESS 0x01 /* compressed string table */ -#define FLG_STTAB_COOKED 0x02 /* offset has been assigned */ - -/* - * Starting value for use with string hashing functions inside of string_table.c - */ -#define HASHSEED 5381 - -#ifdef __cplusplus -} -#endif - -#endif /* __STRING_TABLE_DOT_H */ diff --git a/cddl/contrib/opensolaris/cmd/sgs/include/alist.h b/cddl/contrib/opensolaris/cmd/sgs/include/alist.h deleted file mode 100644 index 2b790b71..0000000 --- a/cddl/contrib/opensolaris/cmd/sgs/include/alist.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - * Define an Alist, a list maintained as a reallocable array, and a for() loop - * macro to generalize its traversal. Note that the array can be reallocated - * as it is being traversed, thus the offset of each element is recomputed from - * the start of the structure. - */ - -#ifndef _ALIST_H -#define _ALIST_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> -#ifdef illumos -#include <sys/machelf.h> -#else -#include <sys/elf.h> -#endif - -/* - * An Alist implements array lists. The functionality is similar to - * that of a linked list. However, an Alist is represented by a single - * contigious allocation of memory. The head of the memory is a header - * that contains control information for the list. Following the header - * is an array used to hold the user data. In the type definitions that - * follow, we define these as an array with a single element, but when - * we allocate the memory, we actually allocate the amount of memory needed. - * - * There are two "flavors" of array list: - * - * Alist - Contain arbitrary data, usually structs. - * APlist - Contain pointers to data allocated elsewhere. - * - * This differentiation is useful, because pointer lists are heavily - * used, and support a slightly different set of operations that are - * unique to their purpose. - * - * Array lists are initially represented by a NULL pointer. The memory - * for the list is only allocated if an item is inserted. This is very - * efficient for data structures that may or may not be needed for a - * given linker operation --- you only pay for what you use. In addition: - * - * - Array lists grow as needed (memory is reallocated as necessary) - * - Data is kept contiguously (no unused holes in between elements) - * at the beginning of the data area. This locality has - * good cache behavior, as access to adjacent items are - * highly likely to be in the same page of memory. - * - Insert/Delete operations at the end of the list are very - * efficient. However, insert/delete operations elsewhere - * will cause a relatively expensive overlapped memory - * copy of the data following the insert/delete location. - * - As with any generic memory alloctor (i.e. malloc()/free()), - * array lists are not type safe for the data they contain. - * Data is managed as (void *) pointers to data of a given - * length, so the Alist module cannot prevent the caller from - * inserting/extracting the wrong type of data. The caller - * must guard against this. - * - To free an array list, simply call the standard free() function - * on the list pointer. - */ - - - -/* - * Aliste is used to represent list indexes, offsets, and sizes. - */ -typedef size_t Aliste; - - - -/* - * Alist is used to hold non-pointer items --- usually structs: - * - There must be an even number of Aliste fields before the - * al_data field. This ensures that al_data will have - * an alignment of 8, no matter whether sizeof(Aliste) - * is 4 or 8. That means that al_data will have sufficient - * alignment for any use, just like memory allocated via - * malloc(). - * - al_nitems and al_next are redundant, in that they are - * directly related: - * al_next = al_nitems * al_size - * We do this to make ALIST_TRAVERSE_BYOFFSET maximally - * efficient. This doesn't waste space, because of the - * requirement to have an even # of Alist fields (above). - * - * Note that Alists allow the data to be referenced by 0 based array - * index, or by their byte offset from the start of the Alist memory - * allocation. The index form is preferred for most use, as it is simpler. - * However, by-offset access is used by rtld link maps, and this ability - * is convenient in that case. - */ -typedef struct { - Aliste al_arritems; /* # of items in al_data allocation */ - Aliste al_nitems; /* # items (index of next avail item) */ - Aliste al_next; /* offset of next available al_data[] */ - Aliste al_size; /* size of each al_data[] item */ - void *al_data[1]; /* data (can grow) */ -} Alist; - -/* - * APlist is a variant of Alist that contains pointers. There are several - * benefits to this special type: - * - API is simpler - * - Pointers are used directly, instead of requiring a - * pointer-to-pointer double indirection. - * - The implementation is slightly more efficient. - * - Operations that make particular sense for pointers - * can be supported without confusing the API for the - * regular Alists. - */ -typedef struct { - Aliste apl_arritems; /* # of items in apl_data allocation */ - Aliste apl_nitems; /* # items (index of next avail item) */ - void *apl_data[1]; /* data area: (arrcnt * size) bytes */ -} APlist; - - -/* - * The ALIST_OFF_DATA and APLIST_OFF_DATA macros give the byte offset - * from the start of an array list to the first byte of the data area - * used to hold user data. The same trick used by the standard offsetof() - * macro is used. - */ -#define ALIST_OFF_DATA ((size_t)(((Alist *)0)->al_data)) -#define APLIST_OFF_DATA ((size_t)(((APlist *)0)->apl_data)) - - -/* - * The TRAVERSE macros are intended to be used within a for(), and - * cause the resulting loop to iterate over each item in the loop, - * in order. - * ALIST_TRAVERSE: Traverse over the items in an Alist, - * using the zero based item array index to refer to - * each item. - * ALIST_TRAVERSE_BY_OFFSET: Traverse over the items in an - * Alist using the byte offset from the head of the - * Alist pointer to refer to each item. It should be noted - * that the first such offset is given by ALIST_OFF_DATA, - * and as such, there will never be a 0 offset. Some code - * uses this fact to treat 0 as a reserved value with - * special meaning. - * - * By-offset access is convenient for some parts of - * rtld, where a value of 0 is used to indicate an - * uninitialized link map control. - * - * APLIST_TRAVERSE: Traverse over the pointers in an APlist, using - * the zero based item array index to refer to each pointer. - */ - -/* - * Within the loop: - * - * LIST - Pointer to Alist structure for list - * IDX - The current item index - * OFF - The current item offset - * DATA - Pointer to item - */ -#define ALIST_TRAVERSE(LIST, IDX, DATA) \ - (IDX) = 0, \ - ((LIST) != NULL) && ((DATA) = (void *)(LIST)->al_data); \ - \ - ((LIST) != NULL) && ((IDX) < (LIST)->al_nitems); \ - \ - (IDX)++, \ - (DATA) = (void *) (((LIST)->al_size * (IDX)) + (char *)(LIST)->al_data) - -#define ALIST_TRAVERSE_BY_OFFSET(LIST, OFF, DATA) \ - (((LIST) != NULL) && ((OFF) = ALIST_OFF_DATA) && \ - (((DATA) = (void *)((char *)(LIST) + (OFF))))); \ - \ - (((LIST) != NULL) && ((OFF) < (LIST)->al_next)); \ - \ - (((OFF) += ((LIST)->al_size)), \ - ((DATA) = (void *)((char *)(LIST) + (OFF)))) - -/* - * Within the loop: - * - * LIST - Pointer to APlist structure for list - * IDX - The current item index - * PTR - item value - * - * Note that this macro is designed to ensure that PTR retains the - * value of the final pointer in the list after exiting the for loop, - * and to avoid dereferencing an out of range address. This is done by - * doing the dereference in the middle expression, using the comma - * operator to ensure that a NULL pointer won't stop the loop. - */ -#define APLIST_TRAVERSE(LIST, IDX, PTR) \ - (IDX) = 0; \ - \ - ((LIST) != NULL) && ((IDX) < (LIST)->apl_nitems) && \ - (((PTR) = ((LIST)->apl_data)[IDX]), 1); \ - \ - (IDX)++ - - -/* - * Possible values returned by aplist_test() - */ -typedef enum { - ALE_ALLOCFAIL = 0, /* Memory allocation error */ - ALE_EXISTS = 1, /* alist entry already exists */ - ALE_NOTFND = 2, /* item not found and insert not required */ - ALE_CREATE = 3 /* alist entry created */ -} aplist_test_t; - - -/* - * Access to an Alist item by index or offset. This is needed because the - * size of an item in an Alist is not known by the C compiler, and we - * have to do the indexing arithmetic explicitly. - * - * For an APlist, index the apl_data field directly --- No macro is needed. - */ -#define alist_item(_lp, _idx) \ - ((void *)(ALIST_OFF_DATA + ((_idx) * (_lp)->al_size) + (char *)(_lp))) -#define alist_item_by_offset(_lp, _off) \ - ((void *)((_off) + (char *)(_lp))) - -/* - * # of items currently found in a list. These macros handle the case - * where the list has not been allocated yet. - */ -#define alist_nitems(_lp) (((_lp) == NULL) ? 0 : (_lp)->al_nitems) -#define aplist_nitems(_lp) (((_lp) == NULL) ? 0 : (_lp)->apl_nitems) - - -extern void *alist_append(Alist **, const void *, size_t, Aliste); -extern void alist_delete(Alist *, Aliste *); -extern void alist_delete_by_offset(Alist *, Aliste *); -extern void *alist_insert(Alist **, const void *, size_t, - Aliste, Aliste); -extern void *alist_insert_by_offset(Alist **, const void *, size_t, - Aliste, Aliste); -extern void alist_reset(Alist *); - - -extern void *aplist_append(APlist **, const void *, Aliste); -extern void aplist_delete(APlist *, Aliste *); -extern int aplist_delete_value(APlist *, const void *); -extern void *aplist_insert(APlist **, const void *, - Aliste, Aliste idx); -extern void aplist_reset(APlist *); -extern aplist_test_t aplist_test(APlist **, const void *, Aliste); - -#ifdef __cplusplus -} -#endif - -#endif /* _ALIST_H */ diff --git a/cddl/contrib/opensolaris/cmd/sgs/include/debug.h b/cddl/contrib/opensolaris/cmd/sgs/include/debug.h deleted file mode 100644 index 0a42f8d..0000000 --- a/cddl/contrib/opensolaris/cmd/sgs/include/debug.h +++ /dev/null @@ -1,1017 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _DEBUG_H -#define _DEBUG_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Global include file for lddbg debugging. - * - * ld(1) and ld.so.1(1) carry out all diagnostic debugging calls via lazy - * loading the library liblddbg.so. Thus debugging is always enabled. The - * utility elfdump(1) is explicitly dependent upon this library. There are two - * categories of routines defined in this library: - * - * o Debugging routines that have specific linker knowledge, and test the - * class of debugging allowable before proceeding, start with the `Dbg_' - * prefix. - * - * o Lower level routines that provide generic ELF structure interpretation - * start with the `Elf_' prefix. These latter routines are the only - * routines used by the elfdump(1) utility. - */ -#include <sgs.h> -#include <libld.h> -#include <rtld.h> -#include <gelf.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Define Dbg_*() interface flags. These flags direct the debugging routine to - * generate different diagnostics, thus the strings themselves are maintained - * in the debugging library. - */ -#define DBG_SUP_ENVIRON 1 -#define DBG_SUP_CMDLINE 2 -#define DBG_SUP_DEFAULT 3 - -#define DBG_CONF_IGNORE 1 /* configuration processing errors */ -#define DBG_CONF_VERSION 2 -#define DBG_CONF_PRCFAIL 3 -#define DBG_CONF_CORRUPT 4 -#define DBG_CONF_ABIMISMATCH 5 - -#define DBG_ORDER_INFO_RANGE 1 /* sh_link out of range */ -#define DBG_ORDER_INFO_ORDER 2 /* sh_info also ordered */ -#define DBG_ORDER_LINK_OUTRANGE 3 /* sh_link out of range */ -#define DBG_ORDER_FLAGS 4 /* sh_flags do not match */ -#define DBG_ORDER_CYCLIC 5 /* sh_link cyclic */ -#define DBG_ORDER_LINK_ERROR 6 /* sh_link (one) has an error */ - -#define DBG_INIT_SORT 1 /* calling init from sorted order */ -#define DBG_INIT_PEND 2 /* calling pending init */ -#define DBG_INIT_DYN 3 /* dynamically triggered init */ -#define DBG_INIT_DONE 4 /* init completed */ - -#define DBG_DLSYM_DEF 0 -#define DBG_DLSYM_NEXT 1 -#define DBG_DLSYM_DEFAULT 2 -#define DBG_DLSYM_SELF 3 -#define DBG_DLSYM_PROBE 4 -#define DBG_DLSYM_SINGLETON 5 - -#define DBG_DLCLOSE_NULL 0 -#define DBG_DLCLOSE_IGNORE 1 -#define DBG_DLCLOSE_RESCAN 2 - -#define DBG_WAIT_INIT 1 -#define DBG_WAIT_FINI 2 -#define DBG_WAIT_SYMBOL 3 - -#define DBG_SYM_REDUCE_GLOBAL 1 /* reporting global symbols to local */ -#define DBG_SYM_REDUCE_RETAIN 2 /* reporting non reduced local syms */ - -/* - * Group handle operations - passed to Dbg_file_hdl_title(). Indicate why - * handle dependencies are being manipulated. - */ -#define DBG_HDL_CREATE 0 /* handle creation */ -#define DBG_HDL_ADD 1 /* addition to existing handle */ -#define DBG_HDL_DELETE 2 /* deletion from a handle */ -#define DBG_HDL_ORPHAN 3 /* handle being moved to orphan list */ -#define DBG_HDL_REINST 4 /* handle reinstated from orphan list */ - -/* - * Group handle dependency operations - passed to Dbg_file_hdl_action(). - * Identify the dependencies that are associated with a handle. - */ -#define DBG_DEP_ADD 0 /* dependency added */ -#define DBG_DEP_UPDATE 1 /* dependency updated */ -#define DBG_DEP_DELETE 2 /* dependency deleted */ -#define DBG_DEP_REMOVE 3 /* dependency removed from handle */ -#define DBG_DEP_REMAIN 4 /* dependency must remain on handle */ -#define DBG_DEP_ORPHAN 5 /* dependency must remain an orphan */ -#define DBG_DEP_REINST 6 /* dependency reinstated from orphan */ - -/* - * Binding information, indicating the result of a symbol binding. Can also - * indicate the reference as being EXTERN or PARENT. Binding information is - * used to augment diagnostic binding information (which in turn can be used by - * lari(1)), and to enable ldd(1) -p processing. - */ -#define DBG_BINFO_FOUND 0x0001 /* information regarding binding */ -#define DBG_BINFO_DIRECT 0x0002 /* bound directly */ -#define DBG_BINFO_COPYREF 0x0004 /* bound to copy relocated reference */ -#define DBG_BINFO_FILTEE 0x0008 /* bound to filtee */ -#define DBG_BINFO_INTERPOSE 0x0010 /* bound to an identified interposer */ -#define DBG_BINFO_PLTADDR 0x0020 /* bound to executables undefined plt */ -#define DBG_BINFO_MSK 0x0fff - -#define DBG_BINFO_REF_EXTERN 0x1000 /* reference to EXTERN */ -#define DBG_BINFO_REF_PARENT 0x2000 /* reference to PARENT */ -#define DBG_BINFO_REF_MSK 0xf000 - - -#define DBG_CAP_INITIAL 0 -#define DBG_CAP_IGNORE 1 -#define DBG_CAP_OLD 2 -#define DBG_CAP_NEW 3 -#define DBG_CAP_RESOLVED 4 - -#define DBG_REL_START 1 -#define DBG_REL_FINISH 2 -#define DBG_REL_NONE 3 - -#define DBG_NL_STD 0 /* newline controllers - standard and */ -#define DBG_NL_FRC 2 /* forced. */ - -#define DBG_BNDREJ_NODIR 0 /* bind rejected, direct to nodirect */ -#define DBG_BNDREJ_SINGLE 1 /* bind rejected, singleton without */ - /* default search model */ -#define DBG_BNDREJ_NUM DBG_BNDREJ_SINGLE - -/* - * Define a debug descriptor, and a user macro that inspects the descriptor as - * a means of triggering a class of diagnostic output. - */ -typedef struct { - uint_t d_class; /* debugging classes */ - uint_t d_extra; /* extra information for classes */ - APlist *d_list; /* associated strings */ -} Dbg_desc; - -extern Dbg_desc *dbg_desc; - -#define DBG_ENABLED (dbg_desc->d_class) -#define DBG_CALL(func) if (DBG_ENABLED) func - -/* - * Most debugging tokens are interpreted within liblddbg, and thus any flags - * within d_class are only meaningful to this library. The following flags - * extend the d_class diagnostic, and are maintained in d_extra. These flags - * may be interpreted by the debugging library itself or from the callers - * dbg_print() routine. - */ -#define DBG_E_DETAIL 0x0001 /* add detail to a class */ -#define DBG_E_LONG 0x0002 /* use long names (ie. no truncation) */ - -#define DBG_E_STDNL 0x0010 /* standard newline indicator */ - -#define DBG_E_SNAME 0x0100 /* prepend simple name (ld only) */ -#define DBG_E_FNAME 0x0200 /* prepend full name (ld only) */ -#define DBG_E_CLASS 0x0400 /* prepend ELF class (ld only) */ -#define DBG_E_LMID 0x0800 /* prepend link-map id (ld.so.1 only) */ -#define DBG_E_DEMANGLE 0x1000 /* demangle symbol names */ - -#define DBG_NOTDETAIL() !(dbg_desc->d_extra & DBG_E_DETAIL) -#define DBG_NOTLONG() !(dbg_desc->d_extra & DBG_E_LONG) - -#define DBG_ISSNAME() (dbg_desc->d_extra & DBG_E_SNAME) -#define DBG_ISFNAME() (dbg_desc->d_extra & DBG_E_FNAME) -#define DBG_ISCLASS() (dbg_desc->d_extra & DBG_E_CLASS) -#define DBG_ISLMID() (dbg_desc->d_extra & DBG_E_LMID) -#define DBG_ISDEMANGLE() \ - (dbg_desc->d_extra & DBG_E_DEMANGLE) - -/* - * Print routine, this must be supplied by the application. The initial - * argument may provide a link-map list to associate with the format statement - * that follows. - */ -/* PRINTFLIKE2 */ -extern void dbg_print(Lm_list *, const char *, ...); - -extern uintptr_t Dbg_setup(const char *, Dbg_desc *); - -/* - * Establish ELF32 and ELF64 class Dbg_*() interfaces. - */ -#if defined(_ELF64) - -#define Dbg_demangle_name Dbg64_demangle_name - -#define Dbg_bind_global Dbg64_bind_global -#define Dbg_bind_plt_summary Dbg64_bind_plt_summary -#define Dbg_bind_pltpad_from Dbg64_bind_pltpad_from -#define Dbg_bind_pltpad_to Dbg64_bind_pltpad_to -#define Dbg_bind_reject Dbg64_bind_reject -#define Dbg_bind_weak Dbg64_bind_weak - -#define Dbg_cap_val_hw1 Dbg64_cap_val_hw1 -#define Dbg_cap_hw_candidate Dbg64_cap_hw_candidate -#define Dbg_cap_hw_filter Dbg64_cap_hw_filter -#define Dbg_cap_mapfile Dbg64_cap_mapfile -#define Dbg_cap_sec_entry Dbg64_cap_sec_entry -#define Dbg_cap_sec_title Dbg64_cap_sec_title - -#define Dbg_ent_entry Dbg64_ent_entry -#define Dbg_ent_print Dbg64_ent_print - -#define Dbg_file_analyze Dbg64_file_analyze -#define Dbg_file_aout Dbg64_file_aout -#define Dbg_file_ar Dbg64_file_ar -#define Dbg_file_ar_rescan Dbg64_file_ar_rescan -#define Dbg_file_bind_entry Dbg64_file_bind_entry -#define Dbg_file_bindings Dbg64_file_bindings -#define Dbg_file_cleanup Dbg64_file_cleanup -#define Dbg_file_cntl Dbg64_file_cntl -#define Dbg_file_config_dis Dbg64_file_config_dis -#define Dbg_file_config_obj Dbg64_file_config_obj -#define Dbg_file_del_rescan Dbg64_file_del_rescan -#define Dbg_file_delete Dbg64_file_delete -#define Dbg_file_dlclose Dbg64_file_dlclose -#define Dbg_file_dldump Dbg64_file_dldump -#define Dbg_file_dlopen Dbg64_file_dlopen -#define Dbg_file_elf Dbg64_file_elf -#define Dbg_file_filtee Dbg64_file_filtee -#define Dbg_file_filter Dbg64_file_filter -#define Dbg_file_fixname Dbg64_file_fixname -#define Dbg_file_generic Dbg64_file_generic -#define Dbg_file_hdl_action Dbg64_file_hdl_action -#define Dbg_file_hdl_collect Dbg64_file_hdl_collect -#define Dbg_file_hdl_title Dbg64_file_hdl_title -#define Dbg_file_lazyload Dbg64_file_lazyload -#define Dbg_file_ldso Dbg64_file_ldso -#define Dbg_file_mode_promote Dbg64_file_mode_promote -#define Dbg_file_modified Dbg64_file_modified -#define Dbg_file_needed Dbg64_file_needed -#define Dbg_file_output Dbg64_file_output -#define Dbg_file_preload Dbg64_file_preload -#define Dbg_file_prot Dbg64_file_prot -#define Dbg_file_rejected Dbg64_file_rejected -#define Dbg_file_reuse Dbg64_file_reuse -#define Dbg_file_skip Dbg64_file_skip - -#define Dbg_got_display Dbg64_got_display - -#define Dbg_libs_audit Dbg64_libs_audit -#define Dbg_libs_find Dbg64_libs_find -#define Dbg_libs_found Dbg64_libs_found -#define Dbg_libs_ignore Dbg64_libs_ignore -#define Dbg_libs_init Dbg64_libs_init -#define Dbg_libs_l Dbg64_libs_l -#define Dbg_libs_path Dbg64_libs_path -#define Dbg_libs_req Dbg64_libs_req -#define Dbg_libs_update Dbg64_libs_update -#define Dbg_libs_yp Dbg64_libs_yp -#define Dbg_libs_ylu Dbg64_libs_ylu - -#define Dbg_map_dash Dbg64_map_dash -#define Dbg_map_ent Dbg64_map_ent -#define Dbg_map_parse Dbg64_map_parse -#define Dbg_map_pipe Dbg64_map_pipe -#define Dbg_map_seg Dbg64_map_seg -#define Dbg_map_set_atsign Dbg64_map_set_atsign -#define Dbg_map_set_equal Dbg64_map_set_equal -#define Dbg_map_size_new Dbg64_map_size_new -#define Dbg_map_size_old Dbg64_map_size_old -#define Dbg_map_sort_fini Dbg64_map_sort_fini -#define Dbg_map_sort_orig Dbg64_map_sort_orig -#define Dbg_map_symbol Dbg64_map_symbol -#define Dbg_map_version Dbg64_map_version - -#define Dbg_move_adjexpandreloc Dbg64_move_adjexpandreloc -#define Dbg_move_adjmovereloc Dbg64_move_adjmovereloc -#define Dbg_move_data Dbg64_move_data -#define Dbg_move_entry1 Dbg64_move_entry1 -#define Dbg_move_entry2 Dbg64_move_entry2 -#define Dbg_move_expand Dbg64_move_expand -#define Dbg_move_input Dbg64_move_input -#define Dbg_move_outmove Dbg64_move_outmove -#define Dbg_move_outsctadj Dbg64_move_outsctadj -#define Dbg_move_parexpn Dbg64_move_parexpn - -#define Dbg_reloc_apply_reg Dbg64_reloc_apply_reg -#define Dbg_reloc_apply_val Dbg64_reloc_apply_val -#define Dbg_reloc_ars_entry Dbg64_reloc_ars_entry -#define Dbg_reloc_copy Dbg64_reloc_copy -#define Dbg_reloc_discard Dbg64_reloc_discard -#define Dbg_reloc_doact Dbg64_reloc_doact -#define Dbg_reloc_doact_title Dbg64_reloc_doact_title -#define Dbg_reloc_dooutrel Dbg64_reloc_dooutrel -#define Dbg_reloc_entry Dbg64_reloc_entry -#define Dbg_reloc_error Dbg64_reloc_error -#define Dbg_reloc_generate Dbg64_reloc_generate -#define Dbg_reloc_in Dbg64_reloc_in -#define Dbg_reloc_ors_entry Dbg64_reloc_ors_entry -#define Dbg_reloc_out Dbg64_reloc_out -#define Dbg_reloc_proc Dbg64_reloc_proc -#define Dbg_reloc_run Dbg64_reloc_run -#define Dbg_reloc_transition Dbg64_reloc_transition -#define Dbg_reloc_sloppycomdat Dbg64_reloc_sloppycomdat - -#define Dbg_sec_added Dbg64_sec_added -#define Dbg_sec_created Dbg64_sec_created -#define Dbg_sec_discarded Dbg64_sec_discarded -#define Dbg_sec_genstr_compress Dbg64_sec_genstr_compress -#define Dbg_sec_group Dbg64_sec_group -#define Dbg_sec_in Dbg64_sec_in -#define Dbg_sec_order_error Dbg64_sec_order_error -#define Dbg_sec_order_list Dbg64_sec_order_list -#define Dbg_sec_strtab Dbg64_sec_strtab -#define Dbg_sec_unsup_strmerge Dbg64_sec_unsup_strmerge - -#define Dbg_seg_desc_entry Dbg64_seg_desc_entry -#define Dbg_seg_entry Dbg64_seg_entry -#define Dbg_seg_list Dbg64_seg_list -#define Dbg_seg_os Dbg64_seg_os -#define Dbg_seg_title Dbg64_seg_title - -#define Dbg_shdr_modified Dbg64_shdr_modified - -#define Dbg_statistics_ar Dbg64_statistics_ar -#define Dbg_statistics_ld Dbg64_statistics_ld - -#define Dbg_support_action Dbg64_support_action -#define Dbg_support_load Dbg64_support_load -#define Dbg_support_req Dbg64_support_req - -#define Dbg_syminfo_entry Dbg64_syminfo_entry -#define Dbg_syminfo_title Dbg64_syminfo_title - -#define Dbg_syms_ar_checking Dbg64_syms_ar_checking -#define Dbg_syms_ar_entry Dbg64_syms_ar_entry -#define Dbg_syms_ar_resolve Dbg64_syms_ar_resolve -#define Dbg_syms_ar_title Dbg64_syms_ar_title -#define Dbg_syms_created Dbg64_syms_created -#define Dbg_syms_discarded Dbg64_syms_discarded -#define Dbg_syms_dlsym Dbg64_syms_dlsym -#define Dbg_syms_dup_sort_addr Dbg64_syms_dup_sort_addr -#define Dbg_syms_entered Dbg64_syms_entered -#define Dbg_syms_entry Dbg64_syms_entry -#define Dbg_syms_global Dbg64_syms_global -#define Dbg_syms_ignore Dbg64_syms_ignore -#define Dbg_syms_ignore_gnuver Dbg64_syms_ignore_gnuver -#define Dbg_syms_lazy_rescan Dbg64_syms_lazy_rescan -#define Dbg_syms_lookup Dbg64_syms_lookup -#define Dbg_syms_new Dbg64_syms_new -#define Dbg_syms_old Dbg64_syms_old -#define Dbg_syms_process Dbg64_syms_process -#define Dbg_syms_reduce Dbg64_syms_reduce -#define Dbg_syms_reloc Dbg64_syms_reloc -#define Dbg_syms_resolved Dbg64_syms_resolved -#define Dbg_syms_resolving Dbg64_syms_resolving -#define Dbg_syms_sec_entry Dbg64_syms_sec_entry -#define Dbg_syms_sec_title Dbg64_syms_sec_title -#define Dbg_syms_spec_title Dbg64_syms_spec_title -#define Dbg_syms_updated Dbg64_syms_updated -#define Dbg_syms_up_title Dbg64_syms_up_title - -#define Dbg_util_broadcast Dbg64_util_broadcast -#define Dbg_util_call_array Dbg64_util_call_array -#define Dbg_util_call_fini Dbg64_util_call_fini -#define Dbg_util_call_init Dbg64_util_call_init -#define Dbg_util_call_main Dbg64_util_call_main -#define Dbg_util_collect Dbg64_util_collect -#define Dbg_util_dbnotify Dbg64_util_dbnotify -#define Dbg_util_edge_in Dbg64_util_edge_in -#define Dbg_util_edge_out Dbg64_util_edge_out -#define Dbg_util_intoolate Dbg64_util_intoolate -#define Dbg_util_lcinterface Dbg64_util_lcinterface -#define Dbg_util_nl Dbg64_util_nl -#define Dbg_util_no_init Dbg64_util_no_init -#define Dbg_util_scc_entry Dbg64_util_scc_entry -#define Dbg_util_scc_title Dbg64_util_scc_title -#define Dbg_util_str Dbg64_util_str -#define Dbg_util_wait Dbg64_util_wait - -#define Dbg_unused_file Dbg64_unused_file -#define Dbg_unused_lcinterface Dbg64_unused_lcinterface -#define Dbg_unused_path Dbg64_unused_path -#define Dbg_unused_sec Dbg64_unused_sec -#define Dbg_unused_unref Dbg64_unused_unref - -#define Dbg_ver_avail_entry Dbg64_ver_avail_entry -#define Dbg_ver_avail_title Dbg64_ver_avail_title -#define Dbg_ver_def_title Dbg64_ver_def_title -#define Dbg_ver_desc_entry Dbg64_ver_desc_entry -#define Dbg_ver_need_entry Dbg64_ver_need_entry -#define Dbg_ver_need_title Dbg64_ver_need_title -#define Dbg_ver_nointerface Dbg64_ver_nointerface -#define Dbg_ver_symbol Dbg64_ver_symbol - -#else - -#define Dbg_demangle_name Dbg32_demangle_name - -#define Dbg_bind_global Dbg32_bind_global -#define Dbg_bind_plt_summary Dbg32_bind_plt_summary -#define Dbg_bind_reject Dbg32_bind_reject -#define Dbg_bind_weak Dbg32_bind_weak - -#define Dbg_cap_val_hw1 Dbg32_cap_val_hw1 -#define Dbg_cap_hw_candidate Dbg32_cap_hw_candidate -#define Dbg_cap_hw_filter Dbg32_cap_hw_filter -#define Dbg_cap_mapfile Dbg32_cap_mapfile -#define Dbg_cap_sec_entry Dbg32_cap_sec_entry -#define Dbg_cap_sec_title Dbg32_cap_sec_title - -#define Dbg_ent_entry Dbg32_ent_entry -#define Dbg_ent_print Dbg32_ent_print - -#define Dbg_file_analyze Dbg32_file_analyze -#define Dbg_file_aout Dbg32_file_aout -#define Dbg_file_ar Dbg32_file_ar -#define Dbg_file_ar_rescan Dbg32_file_ar_rescan -#define Dbg_file_bind_entry Dbg32_file_bind_entry -#define Dbg_file_bindings Dbg32_file_bindings -#define Dbg_file_cleanup Dbg32_file_cleanup -#define Dbg_file_cntl Dbg32_file_cntl -#define Dbg_file_config_dis Dbg32_file_config_dis -#define Dbg_file_config_obj Dbg32_file_config_obj -#define Dbg_file_del_rescan Dbg32_file_del_rescan -#define Dbg_file_delete Dbg32_file_delete -#define Dbg_file_dlclose Dbg32_file_dlclose -#define Dbg_file_dldump Dbg32_file_dldump -#define Dbg_file_dlopen Dbg32_file_dlopen -#define Dbg_file_elf Dbg32_file_elf -#define Dbg_file_filtee Dbg32_file_filtee -#define Dbg_file_filter Dbg32_file_filter -#define Dbg_file_fixname Dbg32_file_fixname -#define Dbg_file_generic Dbg32_file_generic -#define Dbg_file_hdl_action Dbg32_file_hdl_action -#define Dbg_file_hdl_collect Dbg32_file_hdl_collect -#define Dbg_file_hdl_title Dbg32_file_hdl_title -#define Dbg_file_lazyload Dbg32_file_lazyload -#define Dbg_file_ldso Dbg32_file_ldso -#define Dbg_file_mode_promote Dbg32_file_mode_promote -#define Dbg_file_modified Dbg32_file_modified -#define Dbg_file_needed Dbg32_file_needed -#define Dbg_file_output Dbg32_file_output -#define Dbg_file_preload Dbg32_file_preload -#define Dbg_file_prot Dbg32_file_prot -#define Dbg_file_rejected Dbg32_file_rejected -#define Dbg_file_reuse Dbg32_file_reuse -#define Dbg_file_skip Dbg32_file_skip - -#define Dbg_got_display Dbg32_got_display - -#define Dbg_libs_audit Dbg32_libs_audit -#define Dbg_libs_find Dbg32_libs_find -#define Dbg_libs_found Dbg32_libs_found -#define Dbg_libs_ignore Dbg32_libs_ignore -#define Dbg_libs_init Dbg32_libs_init -#define Dbg_libs_l Dbg32_libs_l -#define Dbg_libs_path Dbg32_libs_path -#define Dbg_libs_req Dbg32_libs_req -#define Dbg_libs_update Dbg32_libs_update -#define Dbg_libs_yp Dbg32_libs_yp -#define Dbg_libs_ylu Dbg32_libs_ylu - -#define Dbg_map_dash Dbg32_map_dash -#define Dbg_map_ent Dbg32_map_ent -#define Dbg_map_parse Dbg32_map_parse -#define Dbg_map_pipe Dbg32_map_pipe -#define Dbg_map_seg Dbg32_map_seg -#define Dbg_map_set_atsign Dbg32_map_set_atsign -#define Dbg_map_set_equal Dbg32_map_set_equal -#define Dbg_map_size_new Dbg32_map_size_new -#define Dbg_map_size_old Dbg32_map_size_old -#define Dbg_map_sort_fini Dbg32_map_sort_fini -#define Dbg_map_sort_orig Dbg32_map_sort_orig -#define Dbg_map_symbol Dbg32_map_symbol -#define Dbg_map_version Dbg32_map_version - -#define Dbg_move_adjexpandreloc Dbg32_move_adjexpandreloc -#define Dbg_move_adjmovereloc Dbg32_move_adjmovereloc -#define Dbg_move_data Dbg32_move_data -#define Dbg_move_entry1 Dbg32_move_entry1 -#define Dbg_move_entry2 Dbg32_move_entry2 -#define Dbg_move_expand Dbg32_move_expand -#define Dbg_move_input Dbg32_move_input -#define Dbg_move_outmove Dbg32_move_outmove -#define Dbg_move_outsctadj Dbg32_move_outsctadj -#define Dbg_move_parexpn Dbg32_move_parexpn - -#define Dbg_reloc_apply_reg Dbg32_reloc_apply_reg -#define Dbg_reloc_apply_val Dbg32_reloc_apply_val -#define Dbg_reloc_ars_entry Dbg32_reloc_ars_entry -#define Dbg_reloc_copy Dbg32_reloc_copy -#define Dbg_reloc_discard Dbg32_reloc_discard -#define Dbg_reloc_doact Dbg32_reloc_doact -#define Dbg_reloc_doact_title Dbg32_reloc_doact_title -#define Dbg_reloc_dooutrel Dbg32_reloc_dooutrel -#define Dbg_reloc_entry Dbg32_reloc_entry -#define Dbg_reloc_error Dbg32_reloc_error -#define Dbg_reloc_generate Dbg32_reloc_generate -#define Dbg_reloc_in Dbg32_reloc_in -#define Dbg_reloc_ors_entry Dbg32_reloc_ors_entry -#define Dbg_reloc_out Dbg32_reloc_out -#define Dbg_reloc_proc Dbg32_reloc_proc -#define Dbg_reloc_run Dbg32_reloc_run -#define Dbg_reloc_transition Dbg32_reloc_transition -#define Dbg_reloc_sloppycomdat Dbg32_reloc_sloppycomdat - -#define Dbg_sec_added Dbg32_sec_added -#define Dbg_sec_created Dbg32_sec_created -#define Dbg_sec_discarded Dbg32_sec_discarded -#define Dbg_sec_genstr_compress Dbg32_sec_genstr_compress -#define Dbg_sec_group Dbg32_sec_group -#define Dbg_sec_in Dbg32_sec_in -#define Dbg_sec_order_error Dbg32_sec_order_error -#define Dbg_sec_order_list Dbg32_sec_order_list -#define Dbg_sec_strtab Dbg32_sec_strtab -#define Dbg_sec_unsup_strmerge Dbg32_sec_unsup_strmerge - -#define Dbg_seg_desc_entry Dbg32_seg_desc_entry -#define Dbg_seg_entry Dbg32_seg_entry -#define Dbg_seg_list Dbg32_seg_list -#define Dbg_seg_os Dbg32_seg_os -#define Dbg_seg_title Dbg32_seg_title - -#define Dbg_shdr_modified Dbg32_shdr_modified - -#define Dbg_statistics_ar Dbg32_statistics_ar -#define Dbg_statistics_ld Dbg32_statistics_ld - -#define Dbg_support_action Dbg32_support_action -#define Dbg_support_load Dbg32_support_load -#define Dbg_support_req Dbg32_support_req - -#define Dbg_syminfo_entry Dbg32_syminfo_entry -#define Dbg_syminfo_title Dbg32_syminfo_title - -#define Dbg_syms_ar_checking Dbg32_syms_ar_checking -#define Dbg_syms_ar_entry Dbg32_syms_ar_entry -#define Dbg_syms_ar_resolve Dbg32_syms_ar_resolve -#define Dbg_syms_ar_title Dbg32_syms_ar_title -#define Dbg_syms_created Dbg32_syms_created -#define Dbg_syms_discarded Dbg32_syms_discarded -#define Dbg_syms_dlsym Dbg32_syms_dlsym -#define Dbg_syms_dup_sort_addr Dbg32_syms_dup_sort_addr -#define Dbg_syms_entered Dbg32_syms_entered -#define Dbg_syms_entry Dbg32_syms_entry -#define Dbg_syms_global Dbg32_syms_global -#define Dbg_syms_ignore Dbg32_syms_ignore -#define Dbg_syms_ignore_gnuver Dbg32_syms_ignore_gnuver -#define Dbg_syms_lazy_rescan Dbg32_syms_lazy_rescan -#define Dbg_syms_lookup Dbg32_syms_lookup -#define Dbg_syms_lookup_aout Dbg32_syms_lookup_aout -#define Dbg_syms_new Dbg32_syms_new -#define Dbg_syms_old Dbg32_syms_old -#define Dbg_syms_process Dbg32_syms_process -#define Dbg_syms_reduce Dbg32_syms_reduce -#define Dbg_syms_reloc Dbg32_syms_reloc -#define Dbg_syms_resolved Dbg32_syms_resolved -#define Dbg_syms_resolving Dbg32_syms_resolving -#define Dbg_syms_sec_entry Dbg32_syms_sec_entry -#define Dbg_syms_sec_title Dbg32_syms_sec_title -#define Dbg_syms_spec_title Dbg32_syms_spec_title -#define Dbg_syms_updated Dbg32_syms_updated -#define Dbg_syms_up_title Dbg32_syms_up_title - -#define Dbg_util_broadcast Dbg32_util_broadcast -#define Dbg_util_call_array Dbg32_util_call_array -#define Dbg_util_call_fini Dbg32_util_call_fini -#define Dbg_util_call_init Dbg32_util_call_init -#define Dbg_util_call_main Dbg32_util_call_main -#define Dbg_util_collect Dbg32_util_collect -#define Dbg_util_dbnotify Dbg32_util_dbnotify -#define Dbg_util_edge_in Dbg32_util_edge_in -#define Dbg_util_edge_out Dbg32_util_edge_out -#define Dbg_util_intoolate Dbg32_util_intoolate -#define Dbg_util_lcinterface Dbg32_util_lcinterface -#define Dbg_util_nl Dbg32_util_nl -#define Dbg_util_no_init Dbg32_util_no_init -#define Dbg_util_scc_entry Dbg32_util_scc_entry -#define Dbg_util_scc_title Dbg32_util_scc_title -#define Dbg_util_str Dbg32_util_str -#define Dbg_util_wait Dbg32_util_wait - -#define Dbg_unused_file Dbg32_unused_file -#define Dbg_unused_lcinterface Dbg32_unused_lcinterface -#define Dbg_unused_path Dbg32_unused_path -#define Dbg_unused_sec Dbg32_unused_sec -#define Dbg_unused_unref Dbg32_unused_unref - -#define Dbg_ver_avail_entry Dbg32_ver_avail_entry -#define Dbg_ver_avail_title Dbg32_ver_avail_title -#define Dbg_ver_def_title Dbg32_ver_def_title -#define Dbg_ver_desc_entry Dbg32_ver_desc_entry -#define Dbg_ver_need_entry Dbg32_ver_need_entry -#define Dbg_ver_need_title Dbg32_ver_need_title -#define Dbg_ver_nointerface Dbg32_ver_nointerface -#define Dbg_ver_symbol Dbg32_ver_symbol - -#endif - -/* - * External Dbg_*() interface routines. - */ -extern void Dbg_args_files(Lm_list *, int, char *); -extern void Dbg_args_flags(Lm_list *, int, int); -extern void Dbg_audit_ignore(Rt_map *); -extern void Dbg_audit_interface(Lm_list *, const char *, const char *); -extern void Dbg_audit_lib(Lm_list *, const char *); -extern void Dbg_audit_object(Lm_list *, const char *, const char *); -extern void Dbg_audit_symval(Lm_list *, const char *, const char *, - const char *, Addr, Addr); -extern void Dbg_audit_skip(Lm_list *, const char *, const char *); -extern void Dbg_audit_terminate(Lm_list *, const char *); -extern void Dbg_audit_version(Lm_list *, const char *, ulong_t); - -extern void Dbg_bind_global(Rt_map *, Addr, Off, Xword, Pltbindtype, - Rt_map *, Addr, Off, const char *, uint_t); -extern void Dbg_bind_plt_summary(Lm_list *, Half, Word, Word, Word, Word, - Word, Word); -#if defined(_ELF64) -extern void Dbg_bind_pltpad_from(Rt_map *, Addr, const char *); -extern void Dbg_bind_pltpad_to(Rt_map *, Addr, const char *, const char *); -#endif -extern void Dbg_bind_reject(Rt_map *, Rt_map *, const char *, int); -extern void Dbg_bind_weak(Rt_map *, Addr, Addr, const char *); - -extern void Dbg_cap_hw_candidate(Lm_list *, const char *); -extern void Dbg_cap_hw_filter(Lm_list *, const char *, Rt_map *); -extern void Dbg_cap_mapfile(Lm_list *, Xword, Xword, Half); -extern void Dbg_cap_sec_entry(Lm_list *, uint_t, Xword, Xword, Half); -extern void Dbg_cap_sec_title(Ofl_desc *); -extern void Dbg_cap_val_hw1(Lm_list *, Xword, Half); - -extern const char * - Dbg_demangle_name(const char *); - -extern void Dbg_ent_entry(Lm_list *, Half, Ent_desc *); -extern void Dbg_ent_print(Lm_list *, Half, List *, Boolean); - -extern void Dbg_file_analyze(Rt_map *); -extern void Dbg_file_aout(Lm_list *, const char *, ulong_t, ulong_t, - ulong_t, const char *, Aliste); -extern void Dbg_file_ar(Lm_list *, const char *, int); -extern void Dbg_file_ar_rescan(Lm_list *); -extern void Dbg_file_bind_entry(Lm_list *, Bnd_desc *); -extern void Dbg_file_bindings(Rt_map *, int); -extern void Dbg_file_cleanup(Lm_list *, const char *, Aliste); -extern void Dbg_file_cntl(Lm_list *, Aliste, Aliste); -extern void Dbg_file_config_dis(Lm_list *, const char *, int); -extern void Dbg_file_config_obj(Lm_list *, const char *, const char *, - const char *); -extern void Dbg_file_del_rescan(Lm_list *); -extern void Dbg_file_delete(Rt_map *); -extern void Dbg_file_dlclose(Lm_list *, const char *, int); -extern void Dbg_file_dldump(Rt_map *, const char *, int); -extern void Dbg_file_dlopen(Rt_map *, const char *, int *, int); -extern void Dbg_file_elf(Lm_list *, const char *, ulong_t, ulong_t, - ulong_t, ulong_t, const char *, Aliste); -extern void Dbg_file_filtee(Lm_list *, const char *, const char *, int); -extern void Dbg_file_filter(Lm_list *, const char *, const char *, int); -extern void Dbg_file_fixname(Lm_list *, const char *, const char *); -extern void Dbg_file_generic(Lm_list *, Ifl_desc *); -extern void Dbg_file_hdl_action(Grp_hdl *, Rt_map *, int, uint_t); -extern void Dbg_file_hdl_collect(Grp_hdl *, const char *); -extern void Dbg_file_hdl_title(int); -extern void Dbg_file_lazyload(Rt_map *, const char *, const char *); -extern void Dbg_file_ldso(Rt_map *, char **, auxv_t *, const char *, - Aliste); -extern void Dbg_file_mode_promote(Rt_map *, int); -extern void Dbg_file_modified(Lm_list *, const char *, const char *, - const char *, int, int, Elf *, Elf *); -extern void Dbg_file_needed(Rt_map *, const char *); -extern void Dbg_file_output(Ofl_desc *); -extern void Dbg_file_preload(Lm_list *, const char *); -extern void Dbg_file_prot(Rt_map *, int); -extern void Dbg_file_rejected(Lm_list *, Rej_desc *, Half mach); -extern void Dbg_file_reuse(Lm_list *, const char *, const char *); -extern void Dbg_file_skip(Lm_list *, const char *, const char *); - -extern void Dbg_got_display(Ofl_desc *, Off, int, Word, size_t); - -extern void Dbg_libs_audit(Lm_list *, const char *, const char *); -extern void Dbg_libs_find(Lm_list *, const char *); -extern void Dbg_libs_found(Lm_list *, const char *, int); -extern void Dbg_libs_ignore(Lm_list *, const char *); -extern void Dbg_libs_init(Lm_list *, List *, List *); -extern void Dbg_libs_l(Lm_list *, const char *, const char *); -extern void Dbg_libs_path(Lm_list *, const char *, uint_t, const char *); -extern void Dbg_libs_req(Lm_list *, const char *, const char *, - const char *); -extern void Dbg_libs_update(Lm_list *, List *, List *); -extern void Dbg_libs_yp(Lm_list *, const char *); -extern void Dbg_libs_ylu(Lm_list *, const char *, const char *, int); - -extern void Dbg_map_dash(Lm_list *, const char *, Sdf_desc *); -extern void Dbg_map_ent(Lm_list *, Boolean, Ent_desc *, Ofl_desc *); -extern void Dbg_map_parse(Lm_list *, const char *); -extern void Dbg_map_pipe(Lm_list *, Sg_desc *, const char *, const Word); -extern void Dbg_map_seg(Ofl_desc *, int, Sg_desc *); -extern void Dbg_map_set_atsign(Boolean); -extern void Dbg_map_set_equal(Boolean); -extern void Dbg_map_size_new(Lm_list *, const char *); -extern void Dbg_map_size_old(Ofl_desc *, Sym_desc *); -extern void Dbg_map_sort_fini(Lm_list *, Sg_desc *); -extern void Dbg_map_sort_orig(Lm_list *, Sg_desc *); -extern void Dbg_map_symbol(Ofl_desc *, Sym_desc *); -extern void Dbg_map_version(Lm_list *, const char *, const char *, int); - -extern void Dbg_move_adjexpandreloc(Lm_list *, Xword, const char *); -extern void Dbg_move_adjmovereloc(Lm_list *, Xword, Xword, const char *); -extern void Dbg_move_data(Rt_map *); -extern void Dbg_move_entry1(Lm_list *, int, Move *, Sym_desc *); -extern void Dbg_move_entry2(Lm_list *, Move *, Word, const char *); -extern void Dbg_move_expand(Lm_list *, Move *, Addr); -extern void Dbg_move_input(Lm_list *, const char *); -extern void Dbg_move_outmove(Lm_list *, const char *); -extern void Dbg_move_outsctadj(Lm_list *, Sym_desc *); -extern void Dbg_move_parexpn(Lm_list *, const char *, const char *); - -extern void Dbg_reloc_apply_reg(Lm_list *, int, Half, Xword, Xword); -extern void Dbg_reloc_apply_val(Lm_list *, int, Xword, Xword); -extern void Dbg_reloc_ars_entry(Lm_list *, int, Word, Half, Rel_desc *); -extern void Dbg_reloc_copy(Rt_map *, Rt_map *, const char *, int); -extern void Dbg_reloc_discard(Lm_list *, Half, Rel_desc *); -extern void Dbg_reloc_doact(Lm_list *, int, Half, Word, Word, Xword, Xword, - const char *, Os_desc *); -extern void Dbg_reloc_doact_title(Lm_list *); -extern void Dbg_reloc_dooutrel(Lm_list *, Word); -extern void Dbg_reloc_entry(Lm_list *, const char *, Half, Word, void *, - const char *, const char *, const char *); -extern void Dbg_reloc_error(Lm_list *, int, Half, Word, void *, - const char *); -extern void Dbg_reloc_generate(Lm_list *, Os_desc *, Word); -extern void Dbg_reloc_in(Lm_list *, int, Half, Word, void *, const char *, - const char *); -extern void Dbg_reloc_ors_entry(Lm_list *, int, Word, Half, Rel_desc *); -extern void Dbg_reloc_out(Ofl_desc *, int, Word, void *, const char *, - const char *); -extern void Dbg_reloc_proc(Lm_list *, Os_desc *, Is_desc *, Is_desc *); -extern void Dbg_reloc_run(Rt_map *, uint_t, int, int); -extern void Dbg_reloc_transition(Lm_list *, Half, Word, Rel_desc *); -extern void Dbg_reloc_sloppycomdat(Lm_list *, const char *, Sym_desc *); - -extern void Dbg_sec_added(Lm_list *, Os_desc *, Sg_desc *); -extern void Dbg_sec_created(Lm_list *, Os_desc *, Sg_desc *); -extern void Dbg_sec_discarded(Lm_list *, Is_desc *, Is_desc *); -extern void Dbg_sec_genstr_compress(Lm_list *, const char *, - Xword, Xword); -extern void Dbg_sec_group(Lm_list *, Is_desc *, Group_desc *); -extern void Dbg_sec_in(Lm_list *, Is_desc *); -extern void Dbg_sec_order_error(Lm_list *, Ifl_desc *, Word, int); -extern void Dbg_sec_order_list(Ofl_desc *, int); -extern void Dbg_sec_strtab(Lm_list *, Os_desc *, Str_tbl *); -extern void Dbg_sec_unsup_strmerge(Lm_list *, Is_desc *); - -extern void Dbg_seg_desc_entry(Lm_list *, Half, int, Sg_desc *); -extern void Dbg_seg_entry(Ofl_desc *, int, Sg_desc *); -extern void Dbg_seg_list(Lm_list *, Half, List *); -extern void Dbg_seg_os(Ofl_desc *, Os_desc *, int); -extern void Dbg_seg_title(Lm_list *); - -extern void Dbg_shdr_modified(Lm_list *, const char *, Half, Shdr *, Shdr *, - const char *); - -extern void Dbg_statistics_ar(Ofl_desc *); -extern void Dbg_statistics_ld(Ofl_desc *); - -extern void Dbg_support_action(Lm_list *, const char *, const char *, - Support_ndx, const char *); -extern void Dbg_support_load(Lm_list *, const char *, const char *); -extern void Dbg_support_req(Lm_list *, const char *, int); - -extern void Dbg_syminfo_entry(Lm_list *, Word, Syminfo *, Sym *, - const char *, Dyn *); -extern void Dbg_syminfo_title(Lm_list *); - -extern void Dbg_syms_ar_checking(Lm_list *, Xword, Elf_Arsym *, - const char *); -extern void Dbg_syms_ar_entry(Lm_list *, Xword, Elf_Arsym *); -extern void Dbg_syms_ar_resolve(Lm_list *, Xword, Elf_Arsym *, - const char *, int); -extern void Dbg_syms_ar_title(Lm_list *, const char *, int); -extern void Dbg_syms_created(Lm_list *, const char *); -extern void Dbg_syms_discarded(Lm_list *, Sym_desc *); -extern void Dbg_syms_dlsym(Rt_map *, const char *, int *, const char *, - int); -extern void Dbg_syms_dup_sort_addr(Lm_list *, const char *, const char *, - const char *, Addr); -extern void Dbg_syms_entered(Ofl_desc *, Sym *, Sym_desc *); -extern void Dbg_syms_entry(Lm_list *, Word, Sym_desc *); -extern void Dbg_syms_global(Lm_list *, Word, const char *); -extern void Dbg_syms_ignore(Ofl_desc *, Sym_desc *); -extern void Dbg_syms_ignore_gnuver(Rt_map *, const char *, Word, Versym); -extern void Dbg_syms_lazy_rescan(Lm_list *, const char *); -extern void Dbg_syms_lookup(Rt_map *, const char *, const char *); -#if !(defined(_ELF64)) -extern void Dbg_syms_lookup_aout(Lm_list *, const char *); -#endif -extern void Dbg_syms_new(Ofl_desc *, Sym *, Sym_desc *); -extern void Dbg_syms_old(Ofl_desc *, Sym_desc *); -extern void Dbg_syms_process(Lm_list *, Ifl_desc *); -extern void Dbg_syms_reduce(Ofl_desc *, int, Sym_desc *, int, - const char *); -extern void Dbg_syms_reloc(Ofl_desc *, Sym_desc *); -extern void Dbg_syms_resolved(Ofl_desc *, Sym_desc *); -extern void Dbg_syms_resolving(Ofl_desc *, Word, const char *, int, int, - Sym *, Sym *, Sym_desc *, Ifl_desc *); -extern void Dbg_syms_sec_entry(Lm_list *, Word, Sg_desc *, Os_desc *); -extern void Dbg_syms_sec_title(Lm_list *); -extern void Dbg_syms_spec_title(Lm_list *); -extern void Dbg_syms_updated(Ofl_desc *, Sym_desc *, const char *); -extern void Dbg_syms_up_title(Lm_list *); - -extern void Dbg_tls_modactivity(Lm_list *, void *, uint_t); -extern void Dbg_tls_static_block(Lm_list *, void *, ulong_t, ulong_t); -extern void Dbg_tls_static_resv(Rt_map *, ulong_t, ulong_t); - -extern void Dbg_util_broadcast(Rt_map *); -extern void Dbg_util_call_array(Rt_map *, void *, int, Word); -extern void Dbg_util_call_fini(Rt_map *); -extern void Dbg_util_call_init(Rt_map *, int); -extern void Dbg_util_call_main(Rt_map *); -extern void Dbg_util_collect(Rt_map *, int, int); -extern void Dbg_util_dbnotify(Lm_list *, rd_event_e, r_state_e); -extern void Dbg_util_edge_in(Lm_list *, Rt_map *, uint_t, Rt_map *, - int, int); -extern void Dbg_util_edge_out(Rt_map *, Rt_map *); -extern void Dbg_util_intoolate(Rt_map *); -extern void Dbg_util_lcinterface(Rt_map *, int, char *); -extern void Dbg_util_nl(Lm_list *, int); -extern void Dbg_util_no_init(Rt_map *); -extern void Dbg_util_str(Lm_list *, const char *); -extern void Dbg_util_scc_entry(Rt_map *, uint_t); -extern void Dbg_util_scc_title(Lm_list *, int); -extern void Dbg_util_wait(Rt_map *, Rt_map *, int); - -extern void Dbg_unused_file(Lm_list *, const char *, int, uint_t); -extern void Dbg_unused_lcinterface(Rt_map *, Rt_map *, int); -extern void Dbg_unused_path(Lm_list *, const char *, uint_t, uint_t, - const char *); -extern void Dbg_unused_sec(Lm_list *, Is_desc *); -extern void Dbg_unused_unref(Rt_map *, const char *); - -extern void Dbg_ver_avail_entry(Lm_list *, Ver_index *, const char *); -extern void Dbg_ver_avail_title(Lm_list *, const char *); -extern void Dbg_ver_def_title(Lm_list *, const char *); -extern void Dbg_ver_desc_entry(Lm_list *, Ver_desc *); -extern void Dbg_ver_need_entry(Lm_list *, Half, const char *, - const char *); -extern void Dbg_ver_need_title(Lm_list *, const char *); -extern void Dbg_ver_nointerface(Lm_list *, const char *); -extern void Dbg_ver_symbol(Lm_list *, const char *); - -/* - * Define Elf_*() interface flags. - */ -#define ELF_DBG_ELFDUMP 1 -#define ELF_DBG_RTLD 2 -#define ELF_DBG_LD 3 - -/* - * Define generic Elf_*() interfaces. - */ -extern void Elf_syminfo_entry(Lm_list *, Word, Syminfo *, const char *, - const char *); -extern void Elf_syminfo_title(Lm_list *); - -/* - * Establish ELF32 and ELF64 class Elf_*() interfaces. - */ -#if defined(_ELF64) - -#define Elf_cap_entry Elf64_cap_entry -#define Elf_cap_title Elf64_cap_title - -#define Elf_demangle_name Elf64_demangle_name -#define Elf_dyn_entry Elf64_dyn_entry -#define Elf_dyn_null_entry Elf64_dyn_null_entry -#define Elf_dyn_title Elf64_dyn_title - -#define Elf_ehdr Elf64_ehdr - -#define Elf_got_entry Elf64_got_entry -#define Elf_got_title Elf64_got_title - -#define Elf_reloc_apply_reg Elf64_reloc_apply_reg -#define Elf_reloc_apply_val Elf64_reloc_apply_val -#define Elf_reloc_entry_1 Elf64_reloc_entry_1 -#define Elf_reloc_entry_2 Elf64_reloc_entry_2 -#define Elf_reloc_title Elf64_reloc_title - -#define Elf_phdr Elf64_phdr - -#define Elf_shdr Elf64_shdr - -#define Elf_syms_table_entry Elf64_syms_table_entry -#define Elf_syms_table_title Elf64_syms_table_title - -#define Elf_ver_def_title Elf64_ver_def_title -#define Elf_ver_line_1 Elf64_ver_line_1 -#define Elf_ver_line_2 Elf64_ver_line_2 -#define Elf_ver_line_3 Elf64_ver_line_3 -#define Elf_ver_line_4 Elf64_ver_line_4 -#define Elf_ver_line_5 Elf64_ver_line_5 -#define Elf_ver_need_title Elf64_ver_need_title - -#else - -#define Elf_cap_entry Elf32_cap_entry -#define Elf_cap_title Elf32_cap_title - -#define Elf_demangle_name Elf32_demangle_name -#define Elf_dyn_entry Elf32_dyn_entry -#define Elf_dyn_null_entry Elf32_dyn_null_entry -#define Elf_dyn_title Elf32_dyn_title - -#define Elf_ehdr Elf32_ehdr - -#define Elf_got_entry Elf32_got_entry -#define Elf_got_title Elf32_got_title - -#define Elf_reloc_apply_reg Elf32_reloc_apply_reg -#define Elf_reloc_apply_val Elf32_reloc_apply_val -#define Elf_reloc_entry_1 Elf32_reloc_entry_1 -#define Elf_reloc_entry_2 Elf32_reloc_entry_2 -#define Elf_reloc_title Elf32_reloc_title - -#define Elf_phdr Elf32_phdr - -#define Elf_shdr Elf32_shdr - -#define Elf_syms_table_entry Elf32_syms_table_entry -#define Elf_syms_table_title Elf32_syms_table_title - -#define Elf_ver_def_title Elf32_ver_def_title -#define Elf_ver_line_1 Elf32_ver_line_1 -#define Elf_ver_line_2 Elf32_ver_line_2 -#define Elf_ver_line_3 Elf32_ver_line_3 -#define Elf_ver_line_4 Elf32_ver_line_4 -#define Elf_ver_line_5 Elf32_ver_line_5 -#define Elf_ver_need_title Elf32_ver_need_title - -#endif - -extern void Elf_cap_entry(Lm_list *, Cap *, int, Half); -extern void Elf_cap_title(Lm_list *); - -extern const char \ - *Elf_demangle_name(const char *); -extern void Elf_dyn_entry(Lm_list *, Dyn *, int, const char *, Half); -extern void Elf_dyn_null_entry(Lm_list *, Dyn *, int, int); -extern void Elf_dyn_title(Lm_list *); - -extern void Elf_ehdr(Lm_list *, Ehdr *, Shdr *); - -extern void Elf_got_entry(Lm_list *, Sword, Addr, Xword, Half, - uchar_t, uchar_t, Word, void *, const char *); -extern void Elf_got_title(Lm_list *); - -extern void Elf_phdr(Lm_list *, Half, Phdr *); - -extern void Elf_reloc_apply_val(Lm_list *, int, Xword, Xword); -extern void Elf_reloc_apply_reg(Lm_list *, int, Half, Xword, Xword); -extern void Elf_reloc_entry_1(Lm_list *, int, const char *, Half, Word, - void *, const char *, const char *, const char *); -extern void Elf_reloc_entry_2(Lm_list *, int, const char *, Word, - const char *, Off, Sxword, const char *, const char *, - const char *); -extern void Elf_reloc_title(Lm_list *, int, Word); - -extern void Elf_shdr(Lm_list *, Half, Shdr *); - -extern void Elf_syms_table_entry(Lm_list *, int, const char *, Half, Sym *, - Versym, int, const char *, const char *); -extern void Elf_syms_table_title(Lm_list *, int); - -extern void Elf_ver_def_title(Lm_list *); -extern void Elf_ver_line_1(Lm_list *, const char *, const char *, - const char *, const char *); -extern void Elf_ver_line_2(Lm_list *, const char *, const char *); -extern void Elf_ver_line_3(Lm_list *, const char *, const char *, - const char *); -extern void Elf_ver_line_4(Lm_list *, const char *); -extern void Elf_ver_line_5(Lm_list *, const char *, const char *); -extern void Elf_ver_need_title(Lm_list *, int); - - -#ifdef __cplusplus -} -#endif - -#endif /* _DEBUG_H */ diff --git a/cddl/contrib/opensolaris/cmd/sgs/include/sgs.h b/cddl/contrib/opensolaris/cmd/sgs/include/sgs.h deleted file mode 100644 index adfe5be..0000000 --- a/cddl/contrib/opensolaris/cmd/sgs/include/sgs.h +++ /dev/null @@ -1,296 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 1988 AT&T - * All Rights Reserved - * - * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - * Global include file for all sgs. - */ - -#ifndef _SGS_H -#define _SGS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* <assert.h> keys off of NDEBUG */ -#ifdef DEBUG -#undef NDEBUG -#else -#define NDEBUG -#endif - -#ifndef _ASM -#include <sys/types.h> -#ifdef illumos -#include <sys/machelf.h> -#else -#include <elf.h> -#endif -#include <stdlib.h> -#include <libelf.h> -#include <assert.h> -#include <alist.h> -#endif /* _ASM */ - -/* - * Software identification. - */ -#define SGS "" -#define SGU_PKG "Software Generation Utilities" -#define SGU_REL "(SGU) Solaris-ELF (4.0)" - - -#ifndef _ASM - -/* - * link_ver_string[] contains a version string for use by the link-editor - * and all other linker components. It is found in libconv, and is - * generated by sgs/libconv/common/bld_vernote.ksh. That script produces - * libconv/{plat}/vernote.s, which is in turn assembled/linked into - * libconv. - */ -extern const char link_ver_string[]; -/* - * Macro to round to next double word boundary. - */ -#define S_DROUND(x) (((x) + sizeof (double) - 1) & ~(sizeof (double) - 1)) - -/* - * General align and round macros. - */ -#define S_ALIGN(x, a) ((x) & ~(((a) ? (a) : 1) - 1)) -#define S_ROUND(x, a) ((x) + (((a) ? (a) : 1) - 1) & ~(((a) ? (a) : 1) - 1)) - -/* - * Bit manipulation macros; generic bit mask and is `v' in the range - * supportable in `n' bits? - */ -#define S_MASK(n) ((1 << (n)) -1) -#define S_INRANGE(v, n) (((-(1 << (n)) - 1) < (v)) && ((v) < (1 << (n)))) - - -/* - * Yet another definition of the OFFSETOF macro, used with the AVL routines. - */ -#define SGSOFFSETOF(s, m) ((size_t)(&(((s *)0)->m))) - -/* - * When casting between integer and pointer types, gcc will complain - * if the integer type used is not large enough to hold the pointer - * value without loss. Although a dubious practice in general, this - * is sometimes done by design. In those cases, the general solution - * is to introduce an intermediate cast to widen the integer value. The - * CAST_PTRINT macro does this, and its use documents the fact that - * the programmer is doing that sort of cast. - */ -#ifdef __GNUC__ -#define CAST_PTRINT(cast, value) ((cast)(uintptr_t)value) -#else -#define CAST_PTRINT(cast, value) ((cast)value) -#endif - -/* - * General typedefs. - */ -typedef enum { - FALSE = 0, - TRUE = 1 -} Boolean; - -/* - * Types of errors (used by eprintf()), together with a generic error return - * value. - */ -typedef enum { - ERR_NONE, - ERR_WARNING, - ERR_FATAL, - ERR_ELF, - ERR_NUM /* Must be last */ -} Error; - -#if defined(_LP64) && !defined(_ELF64) -#define S_ERROR (~(uint_t)0) -#else -#define S_ERROR (~(uintptr_t)0) -#endif - -/* - * LIST_TRAVERSE() is used as the only "argument" of a "for" loop to - * traverse a linked list. The node pointer `node' is set to each node in - * turn and the corresponding data pointer is copied to `data'. The macro - * is used as in - * for (LIST_TRAVERSE(List *list, Listnode *node, void *data)) { - * process(data); - * } - */ -#define LIST_TRAVERSE(L, N, D) \ - (void) (((N) = (L)->head) != NULL && ((D) = (N)->data) != NULL); \ - (N) != NULL; \ - (void) (((N) = (N)->next) != NULL && ((D) = (N)->data) != NULL) - -typedef struct listnode Listnode; -typedef struct list List; - -struct listnode { /* a node on a linked list */ - void *data; /* the data item */ - Listnode *next; /* the next element */ -}; - -struct list { /* a linked list */ - Listnode *head; /* the first element */ - Listnode *tail; /* the last element */ -}; - - -#ifdef _SYSCALL32 -typedef struct listnode32 Listnode32; -typedef struct list32 List32; - -struct listnode32 { /* a node on a linked list */ - Elf32_Addr data; /* the data item */ - Elf32_Addr next; /* the next element */ -}; - -struct list32 { /* a linked list */ - Elf32_Addr head; /* the first element */ - Elf32_Addr tail; /* the last element */ -}; -#endif /* _SYSCALL32 */ - - -/* - * Structure to maintain rejected files elf information. Files that are not - * applicable to the present link-edit are rejected and a search for an - * appropriate file may be resumed. The first rejected files information is - * retained so that a better error diagnostic can be given should an appropriate - * file not be located. - */ -typedef struct { - ushort_t rej_type; /* SGS_REJ_ value */ - ushort_t rej_flag; /* additional information */ - uint_t rej_info; /* numeric and string information */ - const char *rej_str; /* associated with error */ - const char *rej_name; /* object name - expanded library */ - /* name and archive members */ -} Rej_desc; - -#define SGS_REJ_NONE 0 -#define SGS_REJ_MACH 1 /* wrong ELF machine type */ -#define SGS_REJ_CLASS 2 /* wrong ELF class (32-bit/64-bit) */ -#define SGS_REJ_DATA 3 /* wrong ELF data format (MSG/LSB) */ -#define SGS_REJ_TYPE 4 /* bad ELF type */ -#define SGS_REJ_BADFLAG 5 /* bad ELF flags value */ -#define SGS_REJ_MISFLAG 6 /* mismatched ELF flags value */ -#define SGS_REJ_VERSION 7 /* mismatched ELF/lib version */ -#define SGS_REJ_HAL 8 /* HAL R1 extensions required */ -#define SGS_REJ_US3 9 /* Sun UltraSPARC III extensions */ - /* required */ -#define SGS_REJ_STR 10 /* generic error - info is a string */ -#define SGS_REJ_UNKFILE 11 /* unknown file type */ -#define SGS_REJ_HWCAP_1 12 /* hardware capabilities mismatch */ - -/* - * For those source files used both inside and outside of the - * libld source base (tools/common/string_table.c) we can - * automatically switch between the allocation models - * based off of the 'cc -DUSE_LIBLD_MALLOC' flag. - */ -#ifdef USE_LIBLD_MALLOC -#define calloc(x, a) libld_malloc(((size_t)x) * ((size_t)a)) -#define free libld_free -#define malloc libld_malloc -#define realloc libld_realloc - -#define libld_calloc(x, a) libld_malloc(((size_t)x) * ((size_t)a)) -extern void libld_free(void *); -extern void *libld_malloc(size_t); -extern void *libld_realloc(void *, size_t); -#endif - - -/* - * Data structures (defined in libld.h). - */ -typedef struct ent_desc Ent_desc; -typedef struct group_desc Group_desc; -typedef struct ifl_desc Ifl_desc; -typedef struct is_desc Is_desc; -typedef struct isa_desc Isa_desc; -typedef struct isa_opt Isa_opt; -typedef struct mv_desc Mv_desc; -typedef struct ofl_desc Ofl_desc; -typedef struct os_desc Os_desc; -typedef struct rel_cache Rel_cache; -typedef struct sdf_desc Sdf_desc; -typedef struct sdv_desc Sdv_desc; -typedef struct sg_desc Sg_desc; -typedef struct sort_desc Sort_desc; -typedef struct sec_order Sec_order; -typedef struct sym_desc Sym_desc; -typedef struct sym_aux Sym_aux; -typedef struct sym_avlnode Sym_avlnode; -typedef struct uts_desc Uts_desc; -typedef struct ver_desc Ver_desc; -typedef struct ver_index Ver_index; -typedef struct audit_desc Audit_desc; -typedef struct audit_info Audit_info; -typedef struct audit_list Audit_list; - -/* - * Data structures defined in machrel.h. - */ -typedef struct rel_desc Rel_desc; - -/* - * Data structures defined in rtld.h. - */ -typedef struct lm_list Lm_list; -#ifdef _SYSCALL32 -typedef struct lm_list32 Lm_list32; -#endif /* _SYSCALL32 */ - -/* - * For the various utilities that include sgs.h - */ -extern int assfail(const char *, const char *, int); -extern void eprintf(Lm_list *, Error, const char *, ...); -extern char *sgs_demangle(char *); -extern uint_t sgs_str_hash(const char *); -extern uint_t findprime(uint_t); - -#endif /* _ASM */ - -#ifdef __cplusplus -} -#endif - - -#endif /* _SGS_H */ diff --git a/cddl/contrib/opensolaris/cmd/sgs/include/string_table.h b/cddl/contrib/opensolaris/cmd/sgs/include/string_table.h deleted file mode 100644 index e42f817..0000000 --- a/cddl/contrib/opensolaris/cmd/sgs/include/string_table.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _STRING_TABLE_DOT_H -#define _STRING_TABLE_DOT_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Exported, opaque string table handle. - */ -typedef struct str_tbl Str_tbl; - -/* - * Exported string table functions. - */ -extern int st_delstring(Str_tbl *, const char *); -extern void st_destroy(Str_tbl *); -extern size_t st_getstrtab_sz(Str_tbl *); -extern const char *st_getstrbuf(Str_tbl *); -extern int st_insert(Str_tbl *, const char *); -extern Str_tbl *st_new(uint_t); -extern int st_setstrbuf(Str_tbl *, char *, size_t); -extern int st_setstring(Str_tbl *, const char *, size_t *); - -/* - * Exported flags values for st_new(). - */ -#define FLG_STNEW_COMPRESS 0x01 /* compressed string table */ - -#ifdef __cplusplus -} -#endif - -#endif /* _STRING_TABLE_DOT_H */ diff --git a/cddl/contrib/opensolaris/cmd/sgs/messages/sgs.ident b/cddl/contrib/opensolaris/cmd/sgs/messages/sgs.ident deleted file mode 100644 index 6afbf5f..0000000 --- a/cddl/contrib/opensolaris/cmd/sgs/messages/sgs.ident +++ /dev/null @@ -1,62 +0,0 @@ -# -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# ident "%Z%%M% %I% %E% SMI" -# -# -# Global message identifiers for the sgs utilities. This information is read -# by sgsmsg(1l) using the -i option. -# Each utilities message file references one of the `MSGID' identifiers. Its -# associated numeric setid is used when creating catgets(3c) messages, the -# string domain is used when creating gettext(3i) messages. -# - -mesgid setid domain - -MSG_ID_RTLD 1 SUNW_OST_SGS /* sgs/rtld */ -MSG_ID_LIBRTLD 2 SUNW_OST_SGS /* sgs/librtld */ -MSG_ID_LIBLD 3 SUNW_OST_SGS /* sgs/libld */ -MSG_ID_LIBLDDBG 4 SUNW_OST_SGS /* sgs/liblddbg */ -MSG_ID_LIBLDSTAB 5 SUNW_OST_SGS /* sgs/libldstab */ -MSG_ID_LIBRTLD_DB 6 SUNW_OST_SGS /* sgs/librtld_db */ -MSG_ID_LIBPROF 7 SUNW_OST_SGS /* sgs/libprof */ -MSG_ID_LIBCRLE 8 SUNW_OST_SGS /* sgs/libcrle */ - -MSG_ID_LIBELF 10 SUNW_OST_SGS /* sgs/libelf */ - -MSG_ID_LD 20 SUNW_OST_SGS /* sgs/ld */ -MSG_ID_LDD 21 SUNW_OST_SGS /* sgs/ldd */ -MSG_ID_PVS 22 SUNW_OST_SGS /* sgs/pvs */ -MSG_ID_CRLE 23 SUNW_OST_SGS /* sgs/crle */ -MSG_ID_ELFDUMP 24 SUNW_OST_SGS /* sgs/elfdump */ -MSG_ID_MOE 25 SUNW_OST_SGS /* sgs/moe */ -MSG_ID_ELFEDIT 26 SUNW_OST_SGS /* sgs/elfedit */ -MSG_ID_ELFEDIT_CAP 27 SUNW_OST_SGS /* cap: */ -MSG_ID_ELFEDIT_DYN 27 SUNW_OST_SGS /* dyn: */ -MSG_ID_ELFEDIT_EHDR 27 SUNW_OST_SGS /* ehdr: */ -MSG_ID_ELFEDIT_PHDR 27 SUNW_OST_SGS /* phdr: */ -MSG_ID_ELFEDIT_SHDR 27 SUNW_OST_SGS /* shdr: */ -MSG_ID_ELFEDIT_STR 27 SUNW_OST_SGS /* str: */ -MSG_ID_ELFEDIT_SYM 27 SUNW_OST_SGS /* sym: */ -MSG_ID_ELFEDIT_SYMINFO 27 SUNW_OST_SGS /* syminfo: */ -MSG_ID_ELFWRAP 28 SUNW_OST_SGS /* sgs/elfwrap */ diff --git a/cddl/contrib/opensolaris/cmd/sgs/tools/common/findprime.c b/cddl/contrib/opensolaris/cmd/sgs/tools/common/findprime.c deleted file mode 100644 index 299fa21..0000000 --- a/cddl/contrib/opensolaris/cmd/sgs/tools/common/findprime.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> -#include <sgs.h> - -/* - * function that will find a prime'ish number. Usefull for - * hashbuckets and related things. - */ -uint_t -findprime(uint_t count) -{ - uint_t h, f; - - if (count <= 3) - return (3); - - - /* - * Check to see if divisible by two, if so - * increment. - */ - if ((count & 0x1) == 0) - count++; - - for (h = count, f = 2; f * f <= h; f++) - if ((h % f) == 0) - h += f = 1; - return (h); -} diff --git a/cddl/contrib/opensolaris/cmd/sgs/tools/common/sgsmsg.c b/cddl/contrib/opensolaris/cmd/sgs/tools/common/sgsmsg.c deleted file mode 100644 index 9432161..0000000 --- a/cddl/contrib/opensolaris/cmd/sgs/tools/common/sgsmsg.c +++ /dev/null @@ -1,1212 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - * sgsmsg generates several message files from an input template file. Messages - * are constructed for use with gettext(3i) - the default - or catgets(3c). The - * files generate are: - * - * msg.h a header file containing definitions for each message. The -h - * option triggers the creation of these definitions and specifies - * the name to use. - * - * msg.c a data array of message strings. The msg.h definitions are - * offsets into this array. The -d option triggers the creation of - * these definitions and specifies the name to use. - * - * messages a message file suitable for catgets(3c) or gettext(3i) use. The - * -m option triggers this output and specifies the filename to be - * used. - * - * The template file is processed based on the first character of each line: - * - * # or $ entries are copied (as is) to the message file (messages). - * - * @ token(s) entries are translated. Two translations are possible dependent - * on whether one or more tokens are supplied: - * - * A single token is interpreted as one of two reserved message - * output indicators, or a message identifier. The reserved output - * indicator _START_ enables output to the message file - Note that - * the occurance of any other @ token will also enable message - * output. The reserved output indicator _END_ disables output to - * the message file. The use of these two indicators provides for - * only those message strings that require translation to be output - * to the message file. - * - * Besides the reserved output indicators, a single token is taken - * to be a message identifier which will be subsituted for a - * `setid' for catgets(3c) output, or a `domain' name for - * gettext(3i) output. This value is determine by substituting the - * token for the associated definition found in the message - * identifier file (specified with the -i option). - * - * Multiple tokens are taken to be a message definition followed by - * the associated message string. The message string is copied to - * the data array being built in msg.c. The index into this array - * becomes the `message' identifier created in the msg.h file. - */ -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <limits.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> -#include <sys/param.h> - -#include <sgs.h> -#include <_string_table.h> - -/* - * Define any error message strings. - */ -static const char - * Errmsg_malt = "sgsmsg: file %s: line %d: malformed input " - "at line\n", - * Errmsg_nmem = "sgsmsg: memory allocation failed: %s\n", - * Errmsg_opne = "sgsmsg: file %s: open failed: %s\n", - * Errmsg_wrte = "sgsmsg: file %s: write failed: %s\n", - * Errmsg_read = "sgsmsg: file %s: read failed %s\n", - * Errmsg_stnw = "sgsmsg: st_new(): failed: %s\n", - * Errmsg_stin = "sgsmsg: Str_tbl insert failed: %s\n", - * Errmsg_mnfn = "sgsmsg: message not found in Str_tbl: %s\n", - * Errmsg_use = "usage: sgsmsg [-clv] [-d mesgdata] [-h mesgdefs] " - "[-m messages] [-n name] [-i mesgident] file ...\n"; - -/* - * Define all output filenames and associated descriptors. - */ -static FILE *fddefs, *fddata, *fdmsgs, *fdmids, *fddesc; -static char *fldefs, *fldata, *flmsgs, *flmids, *fldesc; -static FILE *fdlint; -static char fllint[MAXPATHLEN]; - -static uint_t vflag; /* verbose flag */ -static Str_tbl *stp; /* string table */ - -/* - * Define any default strings. - */ -static const char - *nmlint = "/tmp/sgsmsg.lint", - *interface = "sgs_msg", - *start = "_START_", - *end = "_END_"; - -/* - * Define any default flags and data items. - */ -static int cflag = 0, lflag = 0, prtmsgs = 0, line, ptr = 1, msgid = 0; -static char *mesgid = 0, *setid = 0, *domain = 0; - -typedef struct msg_string { - char *ms_defn; - char *ms_message; - struct msg_string *ms_next; -} msg_string; - -static msg_string *msg_head; -static msg_string *msg_tail; - -int aok; - -/* - * message_append() is responsible for both inserting strings into - * the master Str_tbl as well as maintaining a list of the - * DEFINITIONS associated with each string. - * - * The list of strings is traversed at the end once the full - * Str_tbl has been constructed - and string offsets can be - * assigned. - */ -static void -message_append(const char *defn, const char *message) -{ - msg_string *msg; - if ((msg = calloc(sizeof (msg_string), 1)) == 0) { - (void) fprintf(stderr, Errmsg_nmem, strerror(errno)); - exit(1); - } - - /* - * Initialize the string table. - */ - if ((stp == 0) && ((stp = st_new(FLG_STNEW_COMPRESS)) == NULL)) { - (void) fprintf(stderr, Errmsg_stnw, strerror(errno)); - exit(1); - } - - - if ((msg->ms_defn = strdup(defn)) == 0) { - (void) fprintf(stderr, Errmsg_nmem, strerror(errno)); - exit(1); - } - if ((msg->ms_message = strdup(message)) == 0) { - (void) fprintf(stderr, Errmsg_nmem, strerror(errno)); - exit(1); - } - - if (st_insert(stp, msg->ms_message) == -1) { - (void) fprintf(stderr, Errmsg_stin, - message); - exit(1); - } - - if (msg_head == 0) { - msg_head = msg_tail = msg; - return; - } - msg_tail->ms_next = msg; - msg_tail = msg; -} - -/* - * Initialize a setid value. Given a setid definition determine its numeric - * value from the specified message identifier file (specified with the -i - * option). Return a pointer to the numeric string. - */ -static int -getmesgid(char *id) -{ - char *buffer, *token, *_mesgid = 0, *_setid = 0, *_domain = 0; - - /* - * If we're being asked to interpret a message id but the user didn't - * provide the required message identifier file (-i option) we're in - * trouble. - */ - if (flmids == 0) { - (void) fprintf(stderr, "sgsmsg: file %s: line %d: mesgid %s: " - "unable to process mesgid\n\t" - "no message identifier file specified " - "(see -i option)\n", fldesc, line, id); - return (1); - } - - if ((buffer = malloc(LINE_MAX)) == 0) { - (void) fprintf(stderr, Errmsg_nmem, strerror(errno)); - return (1); - } - - /* - * Read the message identifier file and locate the required mesgid. - */ - rewind(fdmids); - while (fgets(buffer, LINE_MAX, fdmids) != NULL) { - if ((token = strstr(buffer, id)) == NULL) - continue; - - /* - * Establish individual strings for the mesgid, setid and domain - * values. - */ - _mesgid = token; - while (!(isspace(*token))) - token++; - *token++ = 0; - - while (isspace(*token)) - token++; - _setid = token; - while (!(isspace(*token))) - token++; - *token++ = 0; - - while (isspace(*token)) - token++; - _domain = token; - while (!(isspace(*token))) - token++; - *token = 0; - break; - } - - /* - * Did we find a match? - */ - if ((_mesgid == 0) || (_setid == 0) || (_domain == 0)) { - (void) fprintf(stderr, "sgsmsg: file %s: line %d: mesgid %s: " - "unable to process mesgid\n\t" - "identifier does not exist in file %s\n", - fldesc, line, id, flmids); - return (1); - } - - /* - * Have we been here before? - */ - if (mesgid) { - if (cflag == 1) { - /* - * If we're being asked to process more than one mesgid - * warn the user that only one mesgid can be used for - * the catgets(3c) call. - */ - (void) fprintf(stderr, "sgsmsg: file %s: line %d: " - "setid %s: warning: multiple mesgids " - "encountered\n\t" - "last setting used in messaging code\n", - fldesc, line, id); - } - } - - mesgid = _mesgid; - setid = _setid; - domain = _domain; - - /* - * Generate the message file output (insure output flag is enabled). - */ - if (prtmsgs != -1) - prtmsgs = 1; - if (fdmsgs && (prtmsgs == 1)) { - if (cflag == 1) { - if (fprintf(fdmsgs, "$quote \"\n$set %s\n", - setid) < 0) { - (void) fprintf(stderr, Errmsg_wrte, flmsgs, - strerror(errno)); - return (1); - } - } else { - if (fprintf(fdmsgs, "domain\t\"%s\"\n", domain) < 0) { - (void) fprintf(stderr, Errmsg_wrte, flmsgs, - strerror(errno)); - return (1); - } - } - } - - /* - * For catgets(3c) output generate a setid definition in the message - * definition file. - */ - if (fddefs && (cflag == 1) && - (fprintf(fddefs, "#define\t%s\t%s\n\n", mesgid, setid) < 0)) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno)); - return (1); - } - - return (0); -} - -/* - * Dump contents of String Table to standard out - */ -static void -dump_stringtab(Str_tbl *stp) -{ - uint_t cnt; - - if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0) { - (void) printf("string table full size: %ld: uncompressed\n", - stp->st_fullstrsize); - return; - } - - (void) printf("string table full size: %ld compressed down to: %ld\n\n", - stp->st_fullstrsize, stp->st_strsize); - (void) printf("string table compression information [%d buckets]:\n", - stp->st_hbckcnt); - - for (cnt = 0; cnt < stp->st_hbckcnt; cnt++) { - Str_hash *sthash = stp->st_hashbcks[cnt]; - - if (sthash == 0) - continue; - - (void) printf(" bucket: [%d]\n", cnt); - - while (sthash) { - size_t stroff = sthash->hi_mstr->sm_strlen - - sthash->hi_strlen; - - if (stroff == 0) { - (void) printf(" [%ld]: '%s' <master>\n", - sthash->hi_refcnt, sthash->hi_mstr->sm_str); - } else { - (void) printf(" [%ld]: '%s' <suffix of: " - "'%s'>\n", sthash->hi_refcnt, - &sthash->hi_mstr->sm_str[stroff], - sthash->hi_mstr->sm_str); - } - sthash = sthash->hi_next; - } - } -} - -/* - * Initialize the message definition header file stream. - */ -static int -init_defs(void) -{ - static char guard[FILENAME_MAX + 6]; - char *optr; - const char *iptr, *_ptr; - - /* - * Establish a header guard name using the files basename. - */ - for (iptr = 0, _ptr = fldefs; _ptr && (*_ptr != '\0'); _ptr++) { - if (*_ptr == '/') - iptr = _ptr + 1; - } - if (iptr == 0) - iptr = fldefs; - - optr = guard; - for (*optr++ = '_'; iptr && (*iptr != '\0'); iptr++, optr++) { - if (*iptr == '.') { - *optr++ = '_'; - *optr++ = 'D'; - *optr++ = 'O'; - *optr++ = 'T'; - *optr = '_'; - } else - *optr = toupper(*iptr); - } - - if (fprintf(fddefs, "#ifndef\t%s\n#define\t%s\n\n", guard, guard) < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno)); - return (1); - } - - if (fprintf(fddefs, "#ifndef\t__lint\n\n") < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno)); - return (1); - } - - /* - * add "typedef int Msg;" - */ - if (fprintf(fddefs, "typedef int\tMsg;\n\n") < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno)); - return (1); - } - - /* - * If the associated data array is global define a prototype. - * Define a macro to access the array elements. - */ - if (lflag == 0) { - if (fprintf(fddefs, "extern\tconst char\t__%s[];\n\n", - interface) < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, - strerror(errno)); - return (1); - } - } - if (fprintf(fddefs, "#define\tMSG_ORIG(x)\t&__%s[x]\n\n", - interface) < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno)); - return (1); - } - - /* - * Generate a prototype to access the associated data array. - */ - if (fprintf(fddefs, "extern\tconst char *\t_%s(Msg);\n\n", - interface) < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno)); - return (1); - } - if (fprintf(fddefs, "#define\tMSG_INTL(x)\t_%s(x)\n\n", - interface) < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno)); - return (1); - } - - return (0); -} - - -/* - * Finish the message definition header file. - */ -static int -fini_defs(void) -{ - if (fprintf(fddefs, "\n#else\t/* __lint */\n\n") < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno)); - return (1); - } - - /* - * When __lint is defined, Msg is a char *. This allows lint to - * check our format strings against it's arguments. - */ - if (fprintf(fddefs, "\ntypedef char *\tMsg;\n\n") < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno)); - return (1); - } - - if (fprintf(fddefs, "extern\tconst char *\t_%s(Msg);\n\n", - interface) < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno)); - return (1); - } - - if (lflag == 0) { - if (fprintf(fddefs, "extern\tconst char\t__%s[];\n\n", - interface) < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, - strerror(errno)); - return (1); - } - } - - if (fprintf(fddefs, - "#define MSG_ORIG(x)\tx\n#define MSG_INTL(x)\tx\n") < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno)); - return (1); - } - - /* - * Copy the temporary lint defs file into the new header. - */ - if (fdlint) { - long size; - char *buf; - - size = ftell(fdlint); - (void) rewind(fdlint); - - if ((buf = malloc(size)) == 0) { - (void) fprintf(stderr, Errmsg_nmem, strerror(errno)); - return (1); - } - if (fread(buf, size, 1, fdlint) == 0) { - (void) fprintf(stderr, Errmsg_read, fllint, - strerror(errno)); - return (1); - } - if (fwrite(buf, size, 1, fddefs) == 0) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, - strerror(errno)); - return (1); - } - (void) free(buf); - } - - if (fprintf(fddefs, "\n#endif\t/* __lint */\n") < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno)); - return (1); - } - - if (fprintf(fddefs, "\n#endif\n") < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno)); - return (1); - } - - return (0); -} - -/* - * The entire messaging file has been scanned - and all strings have been - * inserted into the string_table. We can now walk the message queue - * and create the '#define <DEFN>' for each string - with the strings - * assigned offset into the string_table. - */ -static int -output_defs(void) -{ - msg_string *msg; - size_t stbufsize; - char *stbuf; - - stbufsize = st_getstrtab_sz(stp); - if ((stbuf = malloc(stbufsize)) == 0) { - (void) fprintf(stderr, Errmsg_nmem, strerror(errno)); - exit(1); - } - (void) st_setstrbuf(stp, stbuf, stbufsize); - for (msg = msg_head; msg; msg = msg->ms_next) { - size_t stoff; - if ((st_setstring(stp, msg->ms_message, &stoff)) == -1) { - (void) fprintf(stderr, Errmsg_mnfn, msg->ms_message); - return (1); - } - if (fprintf(fddefs, "\n#define\t%s\t%ld\n", - msg->ms_defn, stoff) < 0) { - (void) fprintf(stderr, Errmsg_wrte, - fldefs, strerror(errno)); - return (1); - } - if (fddefs && fprintf(fddefs, "#define\t%s_SIZE\t%d\n", - msg->ms_defn, strlen(msg->ms_message)) < 0) { - (void) fprintf(stderr, Errmsg_wrte, - fldefs, strerror(errno)); - return (1); - } - } - return (0); -} - - -/* - * Finish off the data structure definition. - */ -static int -output_data(void) -{ - size_t stbufsize; - size_t ndx; - size_t column = 1; - const char *stbuf; - const char *fmtstr; - - stbufsize = st_getstrtab_sz(stp); - stbuf = st_getstrbuf(stp); - - assert(stbuf); - - /* - * Determine from the local flag whether the data declaration should - * be static. - */ - if (lflag) - fmtstr = (const char *)"static const"; - else - fmtstr = (const char *)"const"; - - if (fprintf(fddata, "\n%s char __%s[%ld] = { ", - fmtstr, interface, stbufsize) < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldata, strerror(errno)); - return (1); - } - - for (ndx = 0; ndx < (stbufsize - 1); ndx++) { - if (column == 1) { - if (fddata && fprintf(fddata, - "\n/* %4ld */ 0x%.2x,", ndx, - (unsigned char)stbuf[ndx]) < 0) { - (void) fprintf(stderr, Errmsg_wrte, - fldata, strerror(errno)); - return (1); - } - } else { - if (fddata && fprintf(fddata, " 0x%.2x,", - (unsigned char)stbuf[ndx]) < 0) { - (void) fprintf(stderr, Errmsg_wrte, - fldata, strerror(errno)); - return (1); - } - } - - if (column++ == 10) - column = 1; - } - - if (column == 1) - fmtstr = "\n\t0x%.2x };\n"; - else - fmtstr = " 0x%.2x };\n"; - - if (fprintf(fddata, fmtstr, (unsigned char)stbuf[stbufsize - 1]) < 0) { - (void) fprintf(stderr, Errmsg_wrte, fldata, strerror(errno)); - return (1); - } - - return (0); -} - -static int -file() -{ - char buffer[LINE_MAX], * token; - uint_t bufsize; - char *token_buffer; - int escape = 0; - - if ((token_buffer = malloc(LINE_MAX)) == 0) { - (void) fprintf(stderr, Errmsg_nmem, strerror(errno)); - return (1); - } - bufsize = LINE_MAX; - - line = 1; - - while ((token = fgets(buffer, LINE_MAX, fddesc)) != NULL) { - char defn[PATH_MAX], * _defn, * str; - int len; - - switch (*token) { - case '#': - case '$': - if (escape) { - (void) fprintf(stderr, Errmsg_malt, fldesc, - line); - return (1); - } - - /* - * If a msgid has been output a msgstr must follow - * before we digest the new token. A msgid is only set - * if fdmsgs is in use. - */ - if (msgid) { - msgid = 0; - if (fprintf(fdmsgs, "msgstr\t\"\"\n") < 0) { - (void) fprintf(stderr, Errmsg_wrte, - flmsgs, strerror(errno)); - return (1); - } - } - - /* - * Pass lines directly through to the output message - * file. - */ - if (fdmsgs && (prtmsgs == 1)) { - char comment; - - if (cflag == 0) - comment = '#'; - else - comment = '$'; - - if (fprintf(fdmsgs, "%c%s", comment, - ++token) < 0) { - (void) fprintf(stderr, Errmsg_wrte, - flmsgs, strerror(errno)); - return (1); - } - } - break; - - case '@': - if (escape) { - (void) fprintf(stderr, Errmsg_malt, fldesc, - line); - return (1); - } - - /* - * If a msgid has been output a msgstr must follow - * before we digest the new token. - */ - if (msgid) { - msgid = 0; - if (fprintf(fdmsgs, "msgstr\t\"\"\n") < 0) { - (void) fprintf(stderr, Errmsg_wrte, - flmsgs, strerror(errno)); - return (1); - } - } - - /* - * Determine whether we have one or more tokens. - */ - token++; - while (isspace(*token)) /* rid any whitespace */ - token++; - _defn = token; /* definition start */ - while (!(isspace(*token))) - token++; - *token++ = 0; - - while (isspace(*token)) /* rid any whitespace */ - token++; - - /* - * Determine whether the single token is one of the - * reserved message output delimiters otherwise - * translate it as a message identifier. - */ - if (*token == 0) { - if (strcmp(_defn, start) == 0) - prtmsgs = 1; - else if (strcmp(_defn, end) == 0) - prtmsgs = -1; - else if (getmesgid(_defn) == 1) - return (1); - break; - } - - /* - * Multiple tokens are translated by taking the first - * token as the message definition, and the rest of the - * line as the message itself. A message line ending - * with an escape ('\') is expected to be continued on - * the next line. - */ - if (prtmsgs != -1) - prtmsgs = 1; - if (fdmsgs && (prtmsgs == 1)) { - /* - * For catgets(3c) make sure a message - * identifier has been established (this is - * normally a domain for gettext(3i), but for - * sgsmsg use this could be argued as being - * redundent). Also make sure that the message - * definitions haven't exceeeded the maximum - * value allowed by gencat(1) before generating - * any message file entries. - */ - if (cflag == 1) { - if (setid == 0) { - (void) fprintf(stderr, "file " - "%s: no message identifier " - "has been established\n", - fldesc); - return (1); - } - if (ptr > NL_MSGMAX) { - (void) fprintf(stderr, "file " - "%s: message definition " - "(%d) exceeds allowable " - "limit (NL_MSGMAX)\n", - fldesc, ptr); - return (1); - } - } - - /* - * For catgets(3c) write the definition and the - * message string to the message file. For - * gettext(3i) write the message string as a - * mesgid - indicate a mesgid has been output - * so that a msgstr can follow. - */ - if (cflag == 1) { - if (fprintf(fdmsgs, "%d\t%s", ptr, - token) < 0) { - (void) fprintf(stderr, - Errmsg_wrte, flmsgs, - strerror(errno)); - return (1); - } - } else { - if (fprintf(fdmsgs, "msgid\t\"") < 0) { - (void) fprintf(stderr, - Errmsg_wrte, flmsgs, - strerror(errno)); - return (1); - } - msgid = 1; - } - } - - /* - * The message itself is a quoted string as this makes - * embedding spaces at the start (or the end) of the - * string very easy. - */ - if (*token != '"') { - (void) fprintf(stderr, Errmsg_malt, fldesc, - line); - return (1); - } - - (void) strcpy(defn, _defn); - - /* - * Write the tag to the lint definitions. - */ - if (fdlint) { - if (fprintf(fdlint, "\n#define\t%s\t", - _defn) < 0) { - (void) fprintf(stderr, Errmsg_wrte, - fllint, strerror(errno)); - return (1); - } - } - - len = 0; - - /* - * Write each character of the message string to the - * data array. Translate any escaped characters - use - * the same specially recognized characters as defined - * by gencat(1). - */ -message: - if (*token == '"') { - if (fdlint && - (fprintf(fdlint, "%c", *token) < 0)) { - (void) fprintf(stderr, Errmsg_wrte, - fllint, strerror(errno)); - return (1); - } - token++; - } - while (*token) { - char _token; - - if ((*token == '\\') && (escape == 0)) { - escape = 1; - if (fdlint && (*(token + 1) != '\n') && - fprintf(fdlint, "%c", *token) < 0) { - (void) fprintf(stderr, - Errmsg_wrte, fllint, - strerror(errno)); - return (1); - } - token++; - continue; - } - if (escape) { - if (*token == 'n') - _token = '\n'; - else if (*token == 't') - _token = '\t'; - else if (*token == 'v') - _token = '\v'; - else if (*token == 'b') - _token = '\b'; - else if (*token == 'f') - _token = '\f'; - else if (*token == '\\') - _token = '\\'; - else if (*token == '"') - _token = '"'; - else if (*token == '\n') - break; - else - _token = *token; - - if (fdmsgs && (prtmsgs == 1) && - (fprintf(fdmsgs, "\\") < 0)) { - (void) fprintf(stderr, - Errmsg_wrte, flmsgs, - strerror(errno)); - return (1); - } - } else { - /* - * If this is the trailing quote then - * thats the last of the message string. - * Eat up any remaining white space and - * unless an escape character is found - * terminate the data string with a 0. - */ - /* BEGIN CSTYLED */ - if (*token == '"') { - if (fdlint && (fprintf(fdlint, - "%c", *token) < 0)) { - (void) fprintf(stderr, - Errmsg_wrte, fllint, - strerror(errno)); - return (1); - } - - if (fdmsgs && (prtmsgs == 1) && - (fprintf(fdmsgs, "%c", - *token) < 0)) { - (void) fprintf(stderr, - Errmsg_wrte, flmsgs, - strerror(errno)); - return (1); - } - - while (*++token) { - if (*token == '\n') - break; - } - _token = '\0'; - } else - _token = *token; - /* END CSTYLED */ - } - - if (fdmsgs && (prtmsgs == 1) && - (fprintf(fdmsgs, "%c", *token) < 0)) { - (void) fprintf(stderr, Errmsg_wrte, - flmsgs, strerror(errno)); - return (1); - } - - if (fdlint && fprintf(fdlint, - "%c", *token) < 0) { - (void) fprintf(stderr, Errmsg_wrte, - fllint, strerror(errno)); - return (1); - } - - if (len >= bufsize) { - bufsize += LINE_MAX; - if ((token_buffer = realloc( - token_buffer, bufsize)) == 0) { - (void) fprintf(stderr, - Errmsg_nmem, - strerror(errno)); - return (1); - } - } - token_buffer[len] = _token; - ptr++, token++, len++; - escape = 0; - - if (_token == '\0') - break; - } - - /* - * After the complete message string has been processed - * (including its continuation beyond one line), create - * a string size definition. - */ - if (escape == 0) { - const char *form = "#define\t%s_SIZE\t%d\n"; - - token_buffer[len] = '\0'; - - message_append(defn, token_buffer); - - if (fdlint && fprintf(fdlint, form, defn, - (len - 1)) < 0) { - (void) fprintf(stderr, Errmsg_wrte, - fllint, strerror(errno)); - return (1); - } - } - break; - - default: - /* - * Empty lines are passed through to the message file. - */ - while (isspace(*token)) - token++; - - if (*token == 0) { - if (msgid || (fdmsgs && (prtmsgs == 1))) { - /* - * If a msgid has been output a msgstr - * must follow before we digest the new - * token. - */ - if (msgid) { - msgid = 0; - str = "msgstr\t\"\"\n\n"; - } else - str = "\n"; - - if (fprintf(fdmsgs, str) < 0) { - (void) fprintf(stderr, - Errmsg_wrte, flmsgs, - strerror(errno)); - return (1); - } - } - break; - } - - /* - * If an escape is in effect then any tokens are taken - * to be message continuations. - */ - if (escape) { - escape = 0; - goto message; - } - - (void) fprintf(stderr, "file %s: line %d: invalid " - "input does not start with #, $ or @\n", fldesc, - line); - return (1); - } - line++; - } - - free(token_buffer); - - return (0); -} - -int -main(int argc, char ** argv) -{ - opterr = 0; - while ((line = getopt(argc, argv, "cd:h:lm:n:i:v")) != EOF) { - switch (line) { - case 'c': /* catgets instead of gettext */ - cflag = 1; - break; - case 'd': /* new message data filename */ - fldata = optarg; /* (msg.c is default) */ - break; - case 'h': /* new message defs filename */ - fldefs = optarg; /* (msg.h is default) */ - break; - case 'i': /* input message ids from */ - flmids = optarg; /* from this file */ - break; - case 'l': /* define message data arrays */ - lflag = 1; /* to be local (static) */ - break; - case 'm': /* generate message database */ - flmsgs = optarg; /* to this file */ - break; - case 'n': /* new data array and func */ - interface = optarg; /* name (msg is default) */ - break; - case 'v': - vflag = 1; /* set verbose flag */ - break; - case '?': - (void) fprintf(stderr, Errmsg_use, argv[0]); - exit(1); - default: - break; - } - } - - /* - * Validate the we have been given at least one input file. - */ - if ((argc - optind) < 1) { - (void) fprintf(stderr, Errmsg_use); - exit(1); - } - - /* - * Open all the required output files. - */ - if (fldefs) { - if ((fddefs = fopen(fldefs, "w+")) == NULL) { - (void) fprintf(stderr, Errmsg_opne, fldefs, - strerror(errno)); - return (1); - } - } - if (fldata) { - if (fldefs && (strcmp(fldefs, fldata) == 0)) - fddata = fddefs; - else if ((fddata = fopen(fldata, "w+")) == NULL) { - (void) fprintf(stderr, Errmsg_opne, fldata, - strerror(errno)); - return (1); - } - } - if (fddefs && fddata) { - (void) sprintf(fllint, "%s.%d", nmlint, (int)getpid()); - if ((fdlint = fopen(fllint, "w+")) == NULL) { - (void) fprintf(stderr, Errmsg_opne, fllint, - strerror(errno)); - return (1); - } - } - if (flmsgs) { - if ((fdmsgs = fopen(flmsgs, "w+")) == NULL) { - (void) fprintf(stderr, Errmsg_opne, flmsgs, - strerror(errno)); - return (1); - } - } - if (flmids) { - if ((fdmids = fopen(flmids, "r")) == NULL) { - (void) fprintf(stderr, Errmsg_opne, flmids, - strerror(errno)); - return (1); - } - } - - - /* - * Initialize the message definition and message data streams. - */ - if (fddefs) { - if (init_defs()) - return (1); - } - - /* - * Read the input message file, and for each line process accordingly. - */ - for (; optind < argc; optind++) { - int err; - - fldesc = argv[optind]; - - if ((fddesc = fopen(fldesc, "r")) == NULL) { - (void) fprintf(stderr, Errmsg_opne, fldesc, - strerror(errno)); - return (1); - } - err = file(); - (void) fclose(fddesc); - - if (err != 0) - return (1); - } - - /* - * If a msgid has been output a msgstr must follow before we end the - * file. - */ - if (msgid) { - msgid = 0; - if (fprintf(fdmsgs, "msgstr\t\"\"\n") < 0) { - (void) fprintf(stderr, Errmsg_wrte, flmsgs, - strerror(errno)); - return (1); - } - } - - if (fdmids) - (void) fclose(fdmids); - if (fdmsgs) - (void) fclose(fdmsgs); - - if (fddefs) { - if (output_defs()) - return (1); - } - - /* - * Finish off any generated data and header file. - */ - if (fldata) { - if (output_data()) - return (1); - } - if (fddefs) { - if (fini_defs()) - return (1); - } - - if (vflag) - dump_stringtab(stp); - - /* - * Close up everything and go home. - */ - if (fddata) - (void) fclose(fddata); - if (fddefs && (fddefs != fddata)) - (void) fclose(fddefs); - if (fddefs && fddata) { - (void) fclose(fdlint); - (void) unlink(fllint); - } - - if (stp) - st_destroy(stp); - - return (0); -} diff --git a/cddl/contrib/opensolaris/cmd/sgs/tools/common/string_table.c b/cddl/contrib/opensolaris/cmd/sgs/tools/common/string_table.c deleted file mode 100644 index e174aca..0000000 --- a/cddl/contrib/opensolaris/cmd/sgs/tools/common/string_table.c +++ /dev/null @@ -1,685 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <_string_table.h> -#include <strings.h> -#include <sgs.h> -#include <stdio.h> - -/* - * This file provides the interfaces to build a Str_tbl suitable for use by - * either the sgsmsg message system, or a standard ELF string table (SHT_STRTAB) - * as created by ld(1). - * - * There are two modes which can be used when constructing a string table: - * - * st_new(0) - * standard string table - no compression. This is the - * traditional, fast method. - * - * st_new(FLG_STTAB_COMPRESS) - * builds a compressed string table which both eliminates - * duplicate strings, and permits strings with common suffixes - * (atexit vs. exit) to overlap in the table. This provides space - * savings for many string tables. Although more work than the - * traditional method, the algorithms used are designed to scale - * and keep any overhead at a minimum. - * - * These string tables are built with a common interface in a two-pass manner. - * The first pass finds all of the strings required for the string-table and - * calculates the size required for the final string table. - * - * The second pass allocates the string table, populates the strings into the - * table and returns the offsets the strings have been assigned. - * - * The calling sequence to build and populate a string table is: - * - * st_new(); // initialize strtab - * - * st_insert(st1); // first pass of strings ... - * // calculates size required for - * // string table - * - * st_delstring(st?); // remove string previously - * // inserted - * st_insert(stN); - * - * st_getstrtab_sz(); // freezes strtab and computes - * // size of table. - * - * st_setstrbuf(); // associates a final destination - * // for the string table - * - * st_setstring(st1); // populate the string table - * ... // offsets are based off of second - * // pass through the string table - * st_setstring(stN); - * - * st_destroy(); // tear down string table - * // structures. - * - * String Suffix Compression Algorithm: - * - * Here's a quick high level overview of the Suffix String - * compression algorithm used. First - the heart of the algorithm - * is a Hash table list which represents a dictionary of all unique - * strings inserted into the string table. The hash function for - * this table is a standard string hash except that the hash starts - * at the last character in the string (&str[n - 1]) and works towards - * the first character in the function (&str[0]). As we compute the - * HASH value for a given string, we also compute the hash values - * for all of the possible suffix strings for that string. - * - * As we compute the hash - at each character see if the current - * suffix string for that hash is already present in the table. If - * it is, and the string is a master string. Then change that - * string to a suffix string of the new string being inserted. - * - * When the final hash value is found (hash for str[0...n]), check - * to see if it is in the hash table - if so increment the reference - * count for the string. If it is not yet in the table, insert a - * new hash table entry for a master string. - * - * The above method will find all suffixes of a given string given - * that the strings are inserted from shortest to longest. That is - * why this is a two phase method, we first collect all of the - * strings and store them based off of their length in an AVL tree. - * Once all of the strings have been submitted we then start the - * hash table build by traversing the AVL tree in order and - * inserting the strings from shortest to longest as described - * above. - */ - -/* LINTLIBRARY */ - -static int -avl_len_compare(const void *n1, const void *n2) -{ - size_t len1, len2; - - len1 = ((LenNode *)n1)->ln_strlen; - len2 = ((LenNode *)n2)->ln_strlen; - - if (len1 == len2) - return (0); - if (len2 < len1) - return (1); - return (-1); -} - -static int -avl_str_compare(const void *n1, const void *n2) -{ - const char *str1, *str2; - int rc; - - str1 = ((StrNode *)n1)->sn_str; - str2 = ((StrNode *)n2)->sn_str; - - rc = strcmp(str1, str2); - if (rc > 0) - return (1); - if (rc < 0) - return (-1); - return (0); -} - -/* - * Return an initialized Str_tbl - returns NULL on failure. - * - * flags: - * FLG_STTAB_COMPRESS - build a compressed string table - */ -Str_tbl * -st_new(uint_t flags) -{ - Str_tbl *stp; - - if ((stp = calloc(sizeof (Str_tbl), 1)) == NULL) - return (NULL); - - /* - * Start with a leading '\0' - it's tradition. - */ - stp->st_strsize = stp->st_fullstrsize = stp->st_nextoff = 1; - - /* - * Do we compress this string table? - */ - stp->st_flags = flags; - if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0) - return (stp); - - if ((stp->st_lentree = calloc(sizeof (avl_tree_t), 1)) == NULL) - return (NULL); - - avl_create(stp->st_lentree, &avl_len_compare, sizeof (LenNode), - SGSOFFSETOF(LenNode, ln_avlnode)); - - return (stp); -} - -/* - * Insert a new string into the Str_tbl. There are two AVL trees used. - * - * . The first LenNode AVL tree maintains a tree of nodes based on string - * sizes. - * . Each LenNode maintains a StrNode AVL tree for each string. Large - * applications have been known to contribute thousands of strings of - * the same size. Should strings need to be removed (-z ignore), then - * the string AVL tree makes this removal efficient and scalable. - */ -int -st_insert(Str_tbl *stp, const char *str) -{ - size_t len; - StrNode *snp, sn = { 0 }; - LenNode *lnp, ln = { 0 }; - avl_index_t where; - - /* - * String table can't have been cooked - */ - assert((stp->st_flags & FLG_STTAB_COOKED) == 0); - - /* - * Null strings always point to the head of the string - * table - no reason to keep searching. - */ - if ((len = strlen(str)) == 0) - return (0); - - stp->st_fullstrsize += len + 1; - stp->st_strcnt++; - - if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0) - return (0); - - /* - * From the controlling string table, determine which LenNode AVL node - * provides for this string length. If the node doesn't exist, insert - * a new node to represent this string length. - */ - ln.ln_strlen = len; - if ((lnp = avl_find(stp->st_lentree, &ln, &where)) == NULL) { - if ((lnp = calloc(sizeof (LenNode), 1)) == NULL) - return (-1); - lnp->ln_strlen = len; - avl_insert(stp->st_lentree, lnp, where); - - if ((lnp->ln_strtree = calloc(sizeof (avl_tree_t), 1)) == NULL) - return (0); - - avl_create(lnp->ln_strtree, &avl_str_compare, sizeof (StrNode), - SGSOFFSETOF(StrNode, sn_avlnode)); - } - - /* - * From the string length AVL node determine whether a StrNode AVL node - * provides this string. If the node doesn't exist, insert a new node - * to represent this string. - */ - sn.sn_str = str; - if ((snp = avl_find(lnp->ln_strtree, &sn, &where)) == NULL) { - if ((snp = calloc(sizeof (StrNode), 1)) == NULL) - return (-1); - snp->sn_str = str; - avl_insert(lnp->ln_strtree, snp, where); - } - snp->sn_refcnt++; - - return (0); -} - -/* - * Remove a previously inserted string from the Str_tbl. - */ -int -st_delstring(Str_tbl *stp, const char *str) -{ - size_t len; - LenNode *lnp, ln = { 0 }; - StrNode *snp, sn = { 0 }; - - /* - * String table can't have been cooked - */ - assert((stp->st_flags & FLG_STTAB_COOKED) == 0); - - len = strlen(str); - stp->st_fullstrsize -= len + 1; - - if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0) - return (0); - - /* - * Determine which LenNode AVL node provides for this string length. - */ - ln.ln_strlen = len; - if ((lnp = avl_find(stp->st_lentree, &ln, 0)) != NULL) { - sn.sn_str = str; - if ((snp = avl_find(lnp->ln_strtree, &sn, 0)) != NULL) { - /* - * Reduce the reference count, and if zero remove the - * node. - */ - if (--snp->sn_refcnt == 0) - avl_remove(lnp->ln_strtree, snp); - return (0); - } - } - - /* - * No strings of this length, or no string itself - someone goofed. - */ - return (-1); -} - -/* - * Tear down a String_Table structure. - */ -void -st_destroy(Str_tbl *stp) -{ - Str_hash *sthash, *psthash; - Str_master *mstr, *pmstr; - uint_t i; - - /* - * cleanup the master strings - */ - for (mstr = stp->st_mstrlist, pmstr = 0; mstr; - mstr = mstr->sm_next) { - if (pmstr) - free(pmstr); - pmstr = mstr; - } - if (pmstr) - free(pmstr); - - if (stp->st_hashbcks) { - for (i = 0; i < stp->st_hbckcnt; i++) { - for (sthash = stp->st_hashbcks[i], psthash = 0; - sthash; sthash = sthash->hi_next) { - if (psthash) - free(psthash); - psthash = sthash; - } - if (psthash) - free(psthash); - } - free(stp->st_hashbcks); - } - free(stp); -} - - -/* - * For a given string - copy it into the buffer associated with - * the string table - and return the offset it has been assigned. - * - * If a value of '-1' is returned - the string was not found in - * the Str_tbl. - */ -int -st_setstring(Str_tbl *stp, const char *str, size_t *stoff) -{ - size_t stlen; - uint_t hashval; - Str_hash *sthash; - Str_master *mstr; - int i; - - /* - * String table *must* have been previously cooked - */ - assert(stp->st_strbuf); - - assert(stp->st_flags & FLG_STTAB_COOKED); - stlen = strlen(str); - /* - * Null string always points to head of string table - */ - if (stlen == 0) { - *stoff = 0; - return (0); - } - - if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0) { - size_t _stoff; - - stlen++; /* count for trailing '\0' */ - _stoff = stp->st_nextoff; - /* - * Have we overflowed our assigned buffer? - */ - if ((_stoff + stlen) > stp->st_fullstrsize) - return (-1); - memcpy(stp->st_strbuf + _stoff, str, stlen); - *stoff = _stoff; - stp->st_nextoff += stlen; - return (0); - } - - /* - * Calculate reverse hash for string. - */ - hashval = HASHSEED; - for (i = stlen; i >= 0; i--) { - hashval = ((hashval << 5) + hashval) + - str[i]; /* h = ((h * 33) + c) */ - } - - for (sthash = stp->st_hashbcks[hashval % stp->st_hbckcnt]; sthash; - sthash = sthash->hi_next) { - const char *hstr; - - if (sthash->hi_hashval != hashval) - continue; - - hstr = &sthash->hi_mstr->sm_str[sthash->hi_mstr->sm_strlen - - sthash->hi_strlen]; - if (strcmp(str, hstr) == 0) - break; - } - - /* - * Did we find the string? - */ - if (sthash == 0) - return (-1); - - /* - * Has this string been copied into the string table? - */ - mstr = sthash->hi_mstr; - if (mstr->sm_stroff == 0) { - size_t mstrlen = mstr->sm_strlen + 1; - - mstr->sm_stroff = stp->st_nextoff; - - /* - * Have we overflowed our assigned buffer? - */ - if ((mstr->sm_stroff + mstrlen) > stp->st_fullstrsize) - return (-1); - - (void) memcpy(stp->st_strbuf + mstr->sm_stroff, - mstr->sm_str, mstrlen); - stp->st_nextoff += mstrlen; - } - - /* - * Calculate offset of (sub)string. - */ - *stoff = mstr->sm_stroff + mstr->sm_strlen - sthash->hi_strlen; - - return (0); -} - - -static int -st_hash_insert(Str_tbl *stp, const char *str, size_t len) -{ - int i; - uint_t hashval = HASHSEED; - uint_t bckcnt = stp->st_hbckcnt; - Str_hash **hashbcks = stp->st_hashbcks; - Str_hash *sthash; - Str_master *mstr = 0; - - /* - * We use a classic 'Bernstein k=33' hash function. But - * instead of hashing from the start of the string to the - * end, we do it in reverse. - * - * This way - we are essentially building all of the - * suffix hashvalues as we go. We can check to see if - * any suffixes already exist in the tree as we generate - * the hash. - */ - for (i = len; i >= 0; i--) { - hashval = ((hashval << 5) + hashval) + - str[i]; /* h = ((h * 33) + c) */ - - for (sthash = hashbcks[hashval % bckcnt]; - sthash; sthash = sthash->hi_next) { - const char *hstr; - Str_master *_mstr; - - if (sthash->hi_hashval != hashval) - continue; - - _mstr = sthash->hi_mstr; - hstr = &_mstr->sm_str[_mstr->sm_strlen - - sthash->hi_strlen]; - - if (strcmp(&str[i], hstr)) - continue; - - if (i == 0) { - /* - * Entry already in table, increment refcnt and - * get out. - */ - sthash->hi_refcnt++; - return (0); - } else { - /* - * If this 'suffix' is presently a 'master - * string, then take over it's record. - */ - if (sthash->hi_strlen == _mstr->sm_strlen) { - /* - * we should only do this once. - */ - assert(mstr == 0); - mstr = _mstr; - } - } - } - } - - /* - * Do we need a new master string, or can we take over - * one we already found in the table? - */ - if (mstr == 0) { - /* - * allocate a new master string - */ - if ((mstr = calloc(sizeof (Str_hash), 1)) == 0) - return (-1); - mstr->sm_next = stp->st_mstrlist; - stp->st_mstrlist = mstr; - stp->st_strsize += len + 1; - } else { - /* - * We are taking over a existing master string, the string size - * only increments by the difference between the current string - * and the previous master. - */ - assert(len > mstr->sm_strlen); - stp->st_strsize += len - mstr->sm_strlen; - } - - if ((sthash = calloc(sizeof (Str_hash), 1)) == 0) - return (-1); - - mstr->sm_hashval = sthash->hi_hashval = hashval; - mstr->sm_strlen = sthash->hi_strlen = len; - mstr->sm_str = str; - sthash->hi_refcnt = 1; - sthash->hi_mstr = mstr; - - /* - * Insert string element into head of hash list - */ - hashval = hashval % bckcnt; - sthash->hi_next = hashbcks[hashval]; - hashbcks[hashval] = sthash; - return (0); -} - -/* - * Return amount of space required for the string table. - */ -size_t -st_getstrtab_sz(Str_tbl *stp) -{ - assert(stp->st_fullstrsize > 0); - - if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0) { - stp->st_flags |= FLG_STTAB_COOKED; - return (stp->st_fullstrsize); - } - - if ((stp->st_flags & FLG_STTAB_COOKED) == 0) { - LenNode *lnp; - void *cookie; - - stp->st_flags |= FLG_STTAB_COOKED; - /* - * allocate a hash table about the size of # of - * strings input. - */ - stp->st_hbckcnt = findprime(stp->st_strcnt); - if ((stp->st_hashbcks = - calloc(sizeof (Str_hash), stp->st_hbckcnt)) == NULL) - return (0); - - /* - * We now walk all of the strings in the list, from shortest to - * longest, and insert them into the hashtable. - */ - if ((lnp = avl_first(stp->st_lentree)) == NULL) { - /* - * Is it possible we have an empty string table, if so, - * the table still contains '\0', so return the size. - */ - if (avl_numnodes(stp->st_lentree) == 0) { - assert(stp->st_strsize == 1); - return (stp->st_strsize); - } - return (0); - } - - while (lnp) { - StrNode *snp; - - /* - * Walk the string lists and insert them into the hash - * list. Once a string is inserted we no longer need - * it's entry, so the string can be freed. - */ - for (snp = avl_first(lnp->ln_strtree); snp; - snp = AVL_NEXT(lnp->ln_strtree, snp)) { - if (st_hash_insert(stp, snp->sn_str, - lnp->ln_strlen) == -1) - return (0); - } - - /* - * Now that the strings have been copied, walk the - * StrNode tree and free all the AVL nodes. Note, - * avl_destroy_nodes() beats avl_remove() as the - * latter balances the nodes as they are removed. - * We just want to tear the whole thing down fast. - */ - cookie = NULL; - while ((snp = avl_destroy_nodes(lnp->ln_strtree, - &cookie)) != NULL) - free(snp); - avl_destroy(lnp->ln_strtree); - free(lnp->ln_strtree); - lnp->ln_strtree = NULL; - - /* - * Move on to the next LenNode. - */ - lnp = AVL_NEXT(stp->st_lentree, lnp); - } - - /* - * Now that all of the strings have been freed, walk the - * LenNode tree and free all of the AVL nodes. Note, - * avl_destroy_nodes() beats avl_remove() as the latter - * balances the nodes as they are removed. We just want to - * tear the whole thing down fast. - */ - cookie = NULL; - while ((lnp = avl_destroy_nodes(stp->st_lentree, - &cookie)) != NULL) - free(lnp); - avl_destroy(stp->st_lentree); - free(stp->st_lentree); - stp->st_lentree = 0; - } - - assert(stp->st_strsize > 0); - assert(stp->st_fullstrsize >= stp->st_strsize); - - return (stp->st_strsize); -} - -/* - * Associate a buffer with a string table. - */ -const char * -st_getstrbuf(Str_tbl *stp) -{ - return (stp->st_strbuf); -} - -int -st_setstrbuf(Str_tbl *stp, char *stbuf, size_t bufsize) -{ - assert(stp->st_flags & FLG_STTAB_COOKED); - - if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0) { - if (bufsize < stp->st_fullstrsize) - return (-1); - } else { - if (bufsize < stp->st_strsize) - return (-1); - } - - stp->st_strbuf = stbuf; -#ifdef DEBUG - /* - * for debug builds - start with a stringtable filled in - * with '0xff'. This makes it very easy to find wholes - * which we failed to fill in - in the strtab. - */ - memset(stbuf, 0xff, bufsize); - stbuf[0] = '\0'; -#else - memset(stbuf, 0x0, bufsize); -#endif - return (0); -} diff --git a/cddl/contrib/opensolaris/common/avl/avl.c b/cddl/contrib/opensolaris/common/avl/avl.c deleted file mode 100644 index 4223da4..0000000 --- a/cddl/contrib/opensolaris/common/avl/avl.c +++ /dev/null @@ -1,1059 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * Copyright (c) 2014 by Delphix. All rights reserved. - */ - -/* - * AVL - generic AVL tree implementation for kernel use - * - * A complete description of AVL trees can be found in many CS textbooks. - * - * Here is a very brief overview. An AVL tree is a binary search tree that is - * almost perfectly balanced. By "almost" perfectly balanced, we mean that at - * any given node, the left and right subtrees are allowed to differ in height - * by at most 1 level. - * - * This relaxation from a perfectly balanced binary tree allows doing - * insertion and deletion relatively efficiently. Searching the tree is - * still a fast operation, roughly O(log(N)). - * - * The key to insertion and deletion is a set of tree manipulations called - * rotations, which bring unbalanced subtrees back into the semi-balanced state. - * - * This implementation of AVL trees has the following peculiarities: - * - * - The AVL specific data structures are physically embedded as fields - * in the "using" data structures. To maintain generality the code - * must constantly translate between "avl_node_t *" and containing - * data structure "void *"s by adding/subtracting the avl_offset. - * - * - Since the AVL data is always embedded in other structures, there is - * no locking or memory allocation in the AVL routines. This must be - * provided for by the enclosing data structure's semantics. Typically, - * avl_insert()/_add()/_remove()/avl_insert_here() require some kind of - * exclusive write lock. Other operations require a read lock. - * - * - The implementation uses iteration instead of explicit recursion, - * since it is intended to run on limited size kernel stacks. Since - * there is no recursion stack present to move "up" in the tree, - * there is an explicit "parent" link in the avl_node_t. - * - * - The left/right children pointers of a node are in an array. - * In the code, variables (instead of constants) are used to represent - * left and right indices. The implementation is written as if it only - * dealt with left handed manipulations. By changing the value assigned - * to "left", the code also works for right handed trees. The - * following variables/terms are frequently used: - * - * int left; // 0 when dealing with left children, - * // 1 for dealing with right children - * - * int left_heavy; // -1 when left subtree is taller at some node, - * // +1 when right subtree is taller - * - * int right; // will be the opposite of left (0 or 1) - * int right_heavy;// will be the opposite of left_heavy (-1 or 1) - * - * int direction; // 0 for "<" (ie. left child); 1 for ">" (right) - * - * Though it is a little more confusing to read the code, the approach - * allows using half as much code (and hence cache footprint) for tree - * manipulations and eliminates many conditional branches. - * - * - The avl_index_t is an opaque "cookie" used to find nodes at or - * adjacent to where a new value would be inserted in the tree. The value - * is a modified "avl_node_t *". The bottom bit (normally 0 for a - * pointer) is set to indicate if that the new node has a value greater - * than the value of the indicated "avl_node_t *". - * - * Note - in addition to userland (e.g. libavl and libutil) and the kernel - * (e.g. genunix), avl.c is compiled into ld.so and kmdb's genunix module, - * which each have their own compilation environments and subsequent - * requirements. Each of these environments must be considered when adding - * dependencies from avl.c. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/debug.h> -#include <sys/avl.h> -#include <sys/cmn_err.h> - -/* - * Small arrays to translate between balance (or diff) values and child indices. - * - * Code that deals with binary tree data structures will randomly use - * left and right children when examining a tree. C "if()" statements - * which evaluate randomly suffer from very poor hardware branch prediction. - * In this code we avoid some of the branch mispredictions by using the - * following translation arrays. They replace random branches with an - * additional memory reference. Since the translation arrays are both very - * small the data should remain efficiently in cache. - */ -static const int avl_child2balance[2] = {-1, 1}; -static const int avl_balance2child[] = {0, 0, 1}; - - -/* - * Walk from one node to the previous valued node (ie. an infix walk - * towards the left). At any given node we do one of 2 things: - * - * - If there is a left child, go to it, then to it's rightmost descendant. - * - * - otherwise we return through parent nodes until we've come from a right - * child. - * - * Return Value: - * NULL - if at the end of the nodes - * otherwise next node - */ -void * -avl_walk(avl_tree_t *tree, void *oldnode, int left) -{ - size_t off = tree->avl_offset; - avl_node_t *node = AVL_DATA2NODE(oldnode, off); - int right = 1 - left; - int was_child; - - - /* - * nowhere to walk to if tree is empty - */ - if (node == NULL) - return (NULL); - - /* - * Visit the previous valued node. There are two possibilities: - * - * If this node has a left child, go down one left, then all - * the way right. - */ - if (node->avl_child[left] != NULL) { - for (node = node->avl_child[left]; - node->avl_child[right] != NULL; - node = node->avl_child[right]) - ; - /* - * Otherwise, return thru left children as far as we can. - */ - } else { - for (;;) { - was_child = AVL_XCHILD(node); - node = AVL_XPARENT(node); - if (node == NULL) - return (NULL); - if (was_child == right) - break; - } - } - - return (AVL_NODE2DATA(node, off)); -} - -/* - * Return the lowest valued node in a tree or NULL. - * (leftmost child from root of tree) - */ -void * -avl_first(avl_tree_t *tree) -{ - avl_node_t *node; - avl_node_t *prev = NULL; - size_t off = tree->avl_offset; - - for (node = tree->avl_root; node != NULL; node = node->avl_child[0]) - prev = node; - - if (prev != NULL) - return (AVL_NODE2DATA(prev, off)); - return (NULL); -} - -/* - * Return the highest valued node in a tree or NULL. - * (rightmost child from root of tree) - */ -void * -avl_last(avl_tree_t *tree) -{ - avl_node_t *node; - avl_node_t *prev = NULL; - size_t off = tree->avl_offset; - - for (node = tree->avl_root; node != NULL; node = node->avl_child[1]) - prev = node; - - if (prev != NULL) - return (AVL_NODE2DATA(prev, off)); - return (NULL); -} - -/* - * Access the node immediately before or after an insertion point. - * - * "avl_index_t" is a (avl_node_t *) with the bottom bit indicating a child - * - * Return value: - * NULL: no node in the given direction - * "void *" of the found tree node - */ -void * -avl_nearest(avl_tree_t *tree, avl_index_t where, int direction) -{ - int child = AVL_INDEX2CHILD(where); - avl_node_t *node = AVL_INDEX2NODE(where); - void *data; - size_t off = tree->avl_offset; - - if (node == NULL) { - ASSERT(tree->avl_root == NULL); - return (NULL); - } - data = AVL_NODE2DATA(node, off); - if (child != direction) - return (data); - - return (avl_walk(tree, data, direction)); -} - - -/* - * Search for the node which contains "value". The algorithm is a - * simple binary tree search. - * - * return value: - * NULL: the value is not in the AVL tree - * *where (if not NULL) is set to indicate the insertion point - * "void *" of the found tree node - */ -void * -avl_find(avl_tree_t *tree, const void *value, avl_index_t *where) -{ - avl_node_t *node; - avl_node_t *prev = NULL; - int child = 0; - int diff; - size_t off = tree->avl_offset; - - for (node = tree->avl_root; node != NULL; - node = node->avl_child[child]) { - - prev = node; - - diff = tree->avl_compar(value, AVL_NODE2DATA(node, off)); - ASSERT(-1 <= diff && diff <= 1); - if (diff == 0) { -#ifdef DEBUG - if (where != NULL) - *where = 0; -#endif - return (AVL_NODE2DATA(node, off)); - } - child = avl_balance2child[1 + diff]; - - } - - if (where != NULL) - *where = AVL_MKINDEX(prev, child); - - return (NULL); -} - - -/* - * Perform a rotation to restore balance at the subtree given by depth. - * - * This routine is used by both insertion and deletion. The return value - * indicates: - * 0 : subtree did not change height - * !0 : subtree was reduced in height - * - * The code is written as if handling left rotations, right rotations are - * symmetric and handled by swapping values of variables right/left[_heavy] - * - * On input balance is the "new" balance at "node". This value is either - * -2 or +2. - */ -static int -avl_rotation(avl_tree_t *tree, avl_node_t *node, int balance) -{ - int left = !(balance < 0); /* when balance = -2, left will be 0 */ - int right = 1 - left; - int left_heavy = balance >> 1; - int right_heavy = -left_heavy; - avl_node_t *parent = AVL_XPARENT(node); - avl_node_t *child = node->avl_child[left]; - avl_node_t *cright; - avl_node_t *gchild; - avl_node_t *gright; - avl_node_t *gleft; - int which_child = AVL_XCHILD(node); - int child_bal = AVL_XBALANCE(child); - - /* BEGIN CSTYLED */ - /* - * case 1 : node is overly left heavy, the left child is balanced or - * also left heavy. This requires the following rotation. - * - * (node bal:-2) - * / \ - * / \ - * (child bal:0 or -1) - * / \ - * / \ - * cright - * - * becomes: - * - * (child bal:1 or 0) - * / \ - * / \ - * (node bal:-1 or 0) - * / \ - * / \ - * cright - * - * we detect this situation by noting that child's balance is not - * right_heavy. - */ - /* END CSTYLED */ - if (child_bal != right_heavy) { - - /* - * compute new balance of nodes - * - * If child used to be left heavy (now balanced) we reduced - * the height of this sub-tree -- used in "return...;" below - */ - child_bal += right_heavy; /* adjust towards right */ - - /* - * move "cright" to be node's left child - */ - cright = child->avl_child[right]; - node->avl_child[left] = cright; - if (cright != NULL) { - AVL_SETPARENT(cright, node); - AVL_SETCHILD(cright, left); - } - - /* - * move node to be child's right child - */ - child->avl_child[right] = node; - AVL_SETBALANCE(node, -child_bal); - AVL_SETCHILD(node, right); - AVL_SETPARENT(node, child); - - /* - * update the pointer into this subtree - */ - AVL_SETBALANCE(child, child_bal); - AVL_SETCHILD(child, which_child); - AVL_SETPARENT(child, parent); - if (parent != NULL) - parent->avl_child[which_child] = child; - else - tree->avl_root = child; - - return (child_bal == 0); - } - - /* BEGIN CSTYLED */ - /* - * case 2 : When node is left heavy, but child is right heavy we use - * a different rotation. - * - * (node b:-2) - * / \ - * / \ - * / \ - * (child b:+1) - * / \ - * / \ - * (gchild b: != 0) - * / \ - * / \ - * gleft gright - * - * becomes: - * - * (gchild b:0) - * / \ - * / \ - * / \ - * (child b:?) (node b:?) - * / \ / \ - * / \ / \ - * gleft gright - * - * computing the new balances is more complicated. As an example: - * if gchild was right_heavy, then child is now left heavy - * else it is balanced - */ - /* END CSTYLED */ - gchild = child->avl_child[right]; - gleft = gchild->avl_child[left]; - gright = gchild->avl_child[right]; - - /* - * move gright to left child of node and - * - * move gleft to right child of node - */ - node->avl_child[left] = gright; - if (gright != NULL) { - AVL_SETPARENT(gright, node); - AVL_SETCHILD(gright, left); - } - - child->avl_child[right] = gleft; - if (gleft != NULL) { - AVL_SETPARENT(gleft, child); - AVL_SETCHILD(gleft, right); - } - - /* - * move child to left child of gchild and - * - * move node to right child of gchild and - * - * fixup parent of all this to point to gchild - */ - balance = AVL_XBALANCE(gchild); - gchild->avl_child[left] = child; - AVL_SETBALANCE(child, (balance == right_heavy ? left_heavy : 0)); - AVL_SETPARENT(child, gchild); - AVL_SETCHILD(child, left); - - gchild->avl_child[right] = node; - AVL_SETBALANCE(node, (balance == left_heavy ? right_heavy : 0)); - AVL_SETPARENT(node, gchild); - AVL_SETCHILD(node, right); - - AVL_SETBALANCE(gchild, 0); - AVL_SETPARENT(gchild, parent); - AVL_SETCHILD(gchild, which_child); - if (parent != NULL) - parent->avl_child[which_child] = gchild; - else - tree->avl_root = gchild; - - return (1); /* the new tree is always shorter */ -} - - -/* - * Insert a new node into an AVL tree at the specified (from avl_find()) place. - * - * Newly inserted nodes are always leaf nodes in the tree, since avl_find() - * searches out to the leaf positions. The avl_index_t indicates the node - * which will be the parent of the new node. - * - * After the node is inserted, a single rotation further up the tree may - * be necessary to maintain an acceptable AVL balance. - */ -void -avl_insert(avl_tree_t *tree, void *new_data, avl_index_t where) -{ - avl_node_t *node; - avl_node_t *parent = AVL_INDEX2NODE(where); - int old_balance; - int new_balance; - int which_child = AVL_INDEX2CHILD(where); - size_t off = tree->avl_offset; - - ASSERT(tree); -#ifdef _LP64 - ASSERT(((uintptr_t)new_data & 0x7) == 0); -#endif - - node = AVL_DATA2NODE(new_data, off); - - /* - * First, add the node to the tree at the indicated position. - */ - ++tree->avl_numnodes; - - node->avl_child[0] = NULL; - node->avl_child[1] = NULL; - - AVL_SETCHILD(node, which_child); - AVL_SETBALANCE(node, 0); - AVL_SETPARENT(node, parent); - if (parent != NULL) { - ASSERT(parent->avl_child[which_child] == NULL); - parent->avl_child[which_child] = node; - } else { - ASSERT(tree->avl_root == NULL); - tree->avl_root = node; - } - /* - * Now, back up the tree modifying the balance of all nodes above the - * insertion point. If we get to a highly unbalanced ancestor, we - * need to do a rotation. If we back out of the tree we are done. - * If we brought any subtree into perfect balance (0), we are also done. - */ - for (;;) { - node = parent; - if (node == NULL) - return; - - /* - * Compute the new balance - */ - old_balance = AVL_XBALANCE(node); - new_balance = old_balance + avl_child2balance[which_child]; - - /* - * If we introduced equal balance, then we are done immediately - */ - if (new_balance == 0) { - AVL_SETBALANCE(node, 0); - return; - } - - /* - * If both old and new are not zero we went - * from -1 to -2 balance, do a rotation. - */ - if (old_balance != 0) - break; - - AVL_SETBALANCE(node, new_balance); - parent = AVL_XPARENT(node); - which_child = AVL_XCHILD(node); - } - - /* - * perform a rotation to fix the tree and return - */ - (void) avl_rotation(tree, node, new_balance); -} - -/* - * Insert "new_data" in "tree" in the given "direction" either after or - * before (AVL_AFTER, AVL_BEFORE) the data "here". - * - * Insertions can only be done at empty leaf points in the tree, therefore - * if the given child of the node is already present we move to either - * the AVL_PREV or AVL_NEXT and reverse the insertion direction. Since - * every other node in the tree is a leaf, this always works. - * - * To help developers using this interface, we assert that the new node - * is correctly ordered at every step of the way in DEBUG kernels. - */ -void -avl_insert_here( - avl_tree_t *tree, - void *new_data, - void *here, - int direction) -{ - avl_node_t *node; - int child = direction; /* rely on AVL_BEFORE == 0, AVL_AFTER == 1 */ -#ifdef DEBUG - int diff; -#endif - - ASSERT(tree != NULL); - ASSERT(new_data != NULL); - ASSERT(here != NULL); - ASSERT(direction == AVL_BEFORE || direction == AVL_AFTER); - - /* - * If corresponding child of node is not NULL, go to the neighboring - * node and reverse the insertion direction. - */ - node = AVL_DATA2NODE(here, tree->avl_offset); - -#ifdef DEBUG - diff = tree->avl_compar(new_data, here); - ASSERT(-1 <= diff && diff <= 1); - ASSERT(diff != 0); - ASSERT(diff > 0 ? child == 1 : child == 0); -#endif - - if (node->avl_child[child] != NULL) { - node = node->avl_child[child]; - child = 1 - child; - while (node->avl_child[child] != NULL) { -#ifdef DEBUG - diff = tree->avl_compar(new_data, - AVL_NODE2DATA(node, tree->avl_offset)); - ASSERT(-1 <= diff && diff <= 1); - ASSERT(diff != 0); - ASSERT(diff > 0 ? child == 1 : child == 0); -#endif - node = node->avl_child[child]; - } -#ifdef DEBUG - diff = tree->avl_compar(new_data, - AVL_NODE2DATA(node, tree->avl_offset)); - ASSERT(-1 <= diff && diff <= 1); - ASSERT(diff != 0); - ASSERT(diff > 0 ? child == 1 : child == 0); -#endif - } - ASSERT(node->avl_child[child] == NULL); - - avl_insert(tree, new_data, AVL_MKINDEX(node, child)); -} - -/* - * Add a new node to an AVL tree. - */ -void -avl_add(avl_tree_t *tree, void *new_node) -{ - avl_index_t where; - - /* - * This is unfortunate. We want to call panic() here, even for - * non-DEBUG kernels. In userland, however, we can't depend on anything - * in libc or else the rtld build process gets confused. So, all we can - * do in userland is resort to a normal ASSERT(). - */ - if (avl_find(tree, new_node, &where) != NULL) -#ifdef _KERNEL - panic("avl_find() succeeded inside avl_add()"); -#else - ASSERT(0); -#endif - avl_insert(tree, new_node, where); -} - -/* - * Delete a node from the AVL tree. Deletion is similar to insertion, but - * with 2 complications. - * - * First, we may be deleting an interior node. Consider the following subtree: - * - * d c c - * / \ / \ / \ - * b e b e b e - * / \ / \ / - * a c a a - * - * When we are deleting node (d), we find and bring up an adjacent valued leaf - * node, say (c), to take the interior node's place. In the code this is - * handled by temporarily swapping (d) and (c) in the tree and then using - * common code to delete (d) from the leaf position. - * - * Secondly, an interior deletion from a deep tree may require more than one - * rotation to fix the balance. This is handled by moving up the tree through - * parents and applying rotations as needed. The return value from - * avl_rotation() is used to detect when a subtree did not change overall - * height due to a rotation. - */ -void -avl_remove(avl_tree_t *tree, void *data) -{ - avl_node_t *delete; - avl_node_t *parent; - avl_node_t *node; - avl_node_t tmp; - int old_balance; - int new_balance; - int left; - int right; - int which_child; - size_t off = tree->avl_offset; - - ASSERT(tree); - - delete = AVL_DATA2NODE(data, off); - - /* - * Deletion is easiest with a node that has at most 1 child. - * We swap a node with 2 children with a sequentially valued - * neighbor node. That node will have at most 1 child. Note this - * has no effect on the ordering of the remaining nodes. - * - * As an optimization, we choose the greater neighbor if the tree - * is right heavy, otherwise the left neighbor. This reduces the - * number of rotations needed. - */ - if (delete->avl_child[0] != NULL && delete->avl_child[1] != NULL) { - - /* - * choose node to swap from whichever side is taller - */ - old_balance = AVL_XBALANCE(delete); - left = avl_balance2child[old_balance + 1]; - right = 1 - left; - - /* - * get to the previous value'd node - * (down 1 left, as far as possible right) - */ - for (node = delete->avl_child[left]; - node->avl_child[right] != NULL; - node = node->avl_child[right]) - ; - - /* - * create a temp placeholder for 'node' - * move 'node' to delete's spot in the tree - */ - tmp = *node; - - *node = *delete; - if (node->avl_child[left] == node) - node->avl_child[left] = &tmp; - - parent = AVL_XPARENT(node); - if (parent != NULL) - parent->avl_child[AVL_XCHILD(node)] = node; - else - tree->avl_root = node; - AVL_SETPARENT(node->avl_child[left], node); - AVL_SETPARENT(node->avl_child[right], node); - - /* - * Put tmp where node used to be (just temporary). - * It always has a parent and at most 1 child. - */ - delete = &tmp; - parent = AVL_XPARENT(delete); - parent->avl_child[AVL_XCHILD(delete)] = delete; - which_child = (delete->avl_child[1] != 0); - if (delete->avl_child[which_child] != NULL) - AVL_SETPARENT(delete->avl_child[which_child], delete); - } - - - /* - * Here we know "delete" is at least partially a leaf node. It can - * be easily removed from the tree. - */ - ASSERT(tree->avl_numnodes > 0); - --tree->avl_numnodes; - parent = AVL_XPARENT(delete); - which_child = AVL_XCHILD(delete); - if (delete->avl_child[0] != NULL) - node = delete->avl_child[0]; - else - node = delete->avl_child[1]; - - /* - * Connect parent directly to node (leaving out delete). - */ - if (node != NULL) { - AVL_SETPARENT(node, parent); - AVL_SETCHILD(node, which_child); - } - if (parent == NULL) { - tree->avl_root = node; - return; - } - parent->avl_child[which_child] = node; - - - /* - * Since the subtree is now shorter, begin adjusting parent balances - * and performing any needed rotations. - */ - do { - - /* - * Move up the tree and adjust the balance - * - * Capture the parent and which_child values for the next - * iteration before any rotations occur. - */ - node = parent; - old_balance = AVL_XBALANCE(node); - new_balance = old_balance - avl_child2balance[which_child]; - parent = AVL_XPARENT(node); - which_child = AVL_XCHILD(node); - - /* - * If a node was in perfect balance but isn't anymore then - * we can stop, since the height didn't change above this point - * due to a deletion. - */ - if (old_balance == 0) { - AVL_SETBALANCE(node, new_balance); - break; - } - - /* - * If the new balance is zero, we don't need to rotate - * else - * need a rotation to fix the balance. - * If the rotation doesn't change the height - * of the sub-tree we have finished adjusting. - */ - if (new_balance == 0) - AVL_SETBALANCE(node, new_balance); - else if (!avl_rotation(tree, node, new_balance)) - break; - } while (parent != NULL); -} - -#define AVL_REINSERT(tree, obj) \ - avl_remove((tree), (obj)); \ - avl_add((tree), (obj)) - -boolean_t -avl_update_lt(avl_tree_t *t, void *obj) -{ - void *neighbor; - - ASSERT(((neighbor = AVL_NEXT(t, obj)) == NULL) || - (t->avl_compar(obj, neighbor) <= 0)); - - neighbor = AVL_PREV(t, obj); - if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) < 0)) { - AVL_REINSERT(t, obj); - return (B_TRUE); - } - - return (B_FALSE); -} - -boolean_t -avl_update_gt(avl_tree_t *t, void *obj) -{ - void *neighbor; - - ASSERT(((neighbor = AVL_PREV(t, obj)) == NULL) || - (t->avl_compar(obj, neighbor) >= 0)); - - neighbor = AVL_NEXT(t, obj); - if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) > 0)) { - AVL_REINSERT(t, obj); - return (B_TRUE); - } - - return (B_FALSE); -} - -boolean_t -avl_update(avl_tree_t *t, void *obj) -{ - void *neighbor; - - neighbor = AVL_PREV(t, obj); - if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) < 0)) { - AVL_REINSERT(t, obj); - return (B_TRUE); - } - - neighbor = AVL_NEXT(t, obj); - if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) > 0)) { - AVL_REINSERT(t, obj); - return (B_TRUE); - } - - return (B_FALSE); -} - -void -avl_swap(avl_tree_t *tree1, avl_tree_t *tree2) -{ - avl_node_t *temp_node; - ulong_t temp_numnodes; - - ASSERT3P(tree1->avl_compar, ==, tree2->avl_compar); - ASSERT3U(tree1->avl_offset, ==, tree2->avl_offset); - ASSERT3U(tree1->avl_size, ==, tree2->avl_size); - - temp_node = tree1->avl_root; - temp_numnodes = tree1->avl_numnodes; - tree1->avl_root = tree2->avl_root; - tree1->avl_numnodes = tree2->avl_numnodes; - tree2->avl_root = temp_node; - tree2->avl_numnodes = temp_numnodes; -} - -/* - * initialize a new AVL tree - */ -void -avl_create(avl_tree_t *tree, int (*compar) (const void *, const void *), - size_t size, size_t offset) -{ - ASSERT(tree); - ASSERT(compar); - ASSERT(size > 0); - ASSERT(size >= offset + sizeof (avl_node_t)); -#ifdef _LP64 - ASSERT((offset & 0x7) == 0); -#endif - - tree->avl_compar = compar; - tree->avl_root = NULL; - tree->avl_numnodes = 0; - tree->avl_size = size; - tree->avl_offset = offset; -} - -/* - * Delete a tree. - */ -/* ARGSUSED */ -void -avl_destroy(avl_tree_t *tree) -{ - ASSERT(tree); - ASSERT(tree->avl_numnodes == 0); - ASSERT(tree->avl_root == NULL); -} - - -/* - * Return the number of nodes in an AVL tree. - */ -ulong_t -avl_numnodes(avl_tree_t *tree) -{ - ASSERT(tree); - return (tree->avl_numnodes); -} - -boolean_t -avl_is_empty(avl_tree_t *tree) -{ - ASSERT(tree); - return (tree->avl_numnodes == 0); -} - -#define CHILDBIT (1L) - -/* - * Post-order tree walk used to visit all tree nodes and destroy the tree - * in post order. This is used for destroying a tree without paying any cost - * for rebalancing it. - * - * example: - * - * void *cookie = NULL; - * my_data_t *node; - * - * while ((node = avl_destroy_nodes(tree, &cookie)) != NULL) - * free(node); - * avl_destroy(tree); - * - * The cookie is really an avl_node_t to the current node's parent and - * an indication of which child you looked at last. - * - * On input, a cookie value of CHILDBIT indicates the tree is done. - */ -void * -avl_destroy_nodes(avl_tree_t *tree, void **cookie) -{ - avl_node_t *node; - avl_node_t *parent; - int child; - void *first; - size_t off = tree->avl_offset; - - /* - * Initial calls go to the first node or it's right descendant. - */ - if (*cookie == NULL) { - first = avl_first(tree); - - /* - * deal with an empty tree - */ - if (first == NULL) { - *cookie = (void *)CHILDBIT; - return (NULL); - } - - node = AVL_DATA2NODE(first, off); - parent = AVL_XPARENT(node); - goto check_right_side; - } - - /* - * If there is no parent to return to we are done. - */ - parent = (avl_node_t *)((uintptr_t)(*cookie) & ~CHILDBIT); - if (parent == NULL) { - if (tree->avl_root != NULL) { - ASSERT(tree->avl_numnodes == 1); - tree->avl_root = NULL; - tree->avl_numnodes = 0; - } - return (NULL); - } - - /* - * Remove the child pointer we just visited from the parent and tree. - */ - child = (uintptr_t)(*cookie) & CHILDBIT; - parent->avl_child[child] = NULL; - ASSERT(tree->avl_numnodes > 1); - --tree->avl_numnodes; - - /* - * If we just did a right child or there isn't one, go up to parent. - */ - if (child == 1 || parent->avl_child[1] == NULL) { - node = parent; - parent = AVL_XPARENT(parent); - goto done; - } - - /* - * Do parent's right child, then leftmost descendent. - */ - node = parent->avl_child[1]; - while (node->avl_child[0] != NULL) { - parent = node; - node = node->avl_child[0]; - } - - /* - * If here, we moved to a left child. It may have one - * child on the right (when balance == +1). - */ -check_right_side: - if (node->avl_child[1] != NULL) { - ASSERT(AVL_XBALANCE(node) == 1); - parent = node; - node = node->avl_child[1]; - ASSERT(node->avl_child[0] == NULL && - node->avl_child[1] == NULL); - } else { - ASSERT(AVL_XBALANCE(node) <= 0); - } - -done: - if (parent == NULL) { - *cookie = (void *)CHILDBIT; - ASSERT(node == tree->avl_root); - } else { - *cookie = (void *)((uintptr_t)parent | AVL_XCHILD(node)); - } - - return (AVL_NODE2DATA(node, off)); -} diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c index 427b2fd..ab8a9bf 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c @@ -55,7 +55,6 @@ #include "zfs_prop.h" #include "zfeature_common.h" -int aok; int libzfs_errno(libzfs_handle_t *hdl) diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c index ef38696..f2515d5 100644 --- a/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c +++ b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c @@ -45,7 +45,9 @@ * Emulation of kernel services in userland. */ +#ifndef __FreeBSD__ int aok; +#endif uint64_t physmem; vnode_t *rootdir = (vnode_t *)0xabcd1234; char hw_serial[HW_HOSTID_LEN]; diff --git a/cddl/usr.bin/Makefile b/cddl/usr.bin/Makefile index 69179c5..78f745d 100644 --- a/cddl/usr.bin/Makefile +++ b/cddl/usr.bin/Makefile @@ -6,7 +6,6 @@ SUBDIR= \ ctfconvert \ ctfdump \ ctfmerge \ - sgsmsg \ ${_tests} \ ${_zinject} \ ${_zlook} \ diff --git a/cddl/usr.bin/ctfconvert/Makefile.depend b/cddl/usr.bin/ctfconvert/Makefile.depend index f479cfc..5331c43 100644 --- a/cddl/usr.bin/ctfconvert/Makefile.depend +++ b/cddl/usr.bin/ctfconvert/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ cddl/lib/libctf \ gnu/lib/csu \ diff --git a/cddl/usr.bin/ctfdump/Makefile.depend b/cddl/usr.bin/ctfdump/Makefile.depend index 6b3e8f7..fcfe6ac 100644 --- a/cddl/usr.bin/ctfdump/Makefile.depend +++ b/cddl/usr.bin/ctfdump/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/cddl/usr.bin/ctfmerge/Makefile.depend b/cddl/usr.bin/ctfmerge/Makefile.depend index f479cfc..5331c43 100644 --- a/cddl/usr.bin/ctfmerge/Makefile.depend +++ b/cddl/usr.bin/ctfmerge/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ cddl/lib/libctf \ gnu/lib/csu \ diff --git a/cddl/usr.bin/sgsmsg/Makefile b/cddl/usr.bin/sgsmsg/Makefile deleted file mode 100644 index e1b318c..0000000 --- a/cddl/usr.bin/sgsmsg/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/sgs/tools/common -.PATH: ${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/avl - -# This program is required as a bootstrap tool for 'make buildworld' -PROG= sgsmsg -MAN= -SRCS= avl.c sgsmsg.c string_table.c findprime.c - -WARNS?= 0 -CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \ - -I${.CURDIR}/../../../cddl/compat/opensolaris/include \ - -I${OPENSOLARIS_USR_DISTDIR}/cmd/sgs/include \ - -I${OPENSOLARIS_SYS_DISTDIR}/uts/common - -.include <bsd.prog.mk> diff --git a/cddl/usr.bin/sgsmsg/Makefile.depend b/cddl/usr.bin/sgsmsg/Makefile.depend deleted file mode 100644 index b767569..0000000 --- a/cddl/usr.bin/sgsmsg/Makefile.depend +++ /dev/null @@ -1,19 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - lib/libelf \ - - -.include <dirdeps.mk> - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/cddl/usr.sbin/dtrace/Makefile.depend b/cddl/usr.sbin/dtrace/Makefile.depend index 2efd35c..9971af1 100644 --- a/cddl/usr.sbin/dtrace/Makefile.depend +++ b/cddl/usr.sbin/dtrace/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ cddl/lib/libctf \ cddl/lib/libdtrace \ diff --git a/cddl/usr.sbin/dtrace/tests/common/privs/Makefile b/cddl/usr.sbin/dtrace/tests/common/privs/Makefile index 119ebe5..02cd83b 100644 --- a/cddl/usr.sbin/dtrace/tests/common/privs/Makefile +++ b/cddl/usr.sbin/dtrace/tests/common/privs/Makefile @@ -8,6 +8,7 @@ TESTFILES= \ tst.fds.ksh \ tst.func_access.ksh \ tst.getf.ksh \ + tst.kpriv.ksh \ tst.op_access.ksh \ tst.procpriv.ksh \ tst.providers.ksh \ diff --git a/cddl/usr.sbin/dtrace/tests/common/scalars/Makefile b/cddl/usr.sbin/dtrace/tests/common/scalars/Makefile index 8377f6b..2f471a6 100644 --- a/cddl/usr.sbin/dtrace/tests/common/scalars/Makefile +++ b/cddl/usr.sbin/dtrace/tests/common/scalars/Makefile @@ -14,6 +14,8 @@ TESTFILES= \ err.D_OP_INCOMPAT.dupltype.d \ err.D_OP_INCOMPAT.dupttype.d \ err.D_SYNTAX.declare.d \ + err.bigglobal.d \ + err.biglocal.d \ tst.basicvar.d \ tst.basicvar.d.out \ tst.localvar.d \ diff --git a/cddl/usr.sbin/dtruss/Makefile.depend b/cddl/usr.sbin/dtruss/Makefile.depend index d14a02b..f80275d 100644 --- a/cddl/usr.sbin/dtruss/Makefile.depend +++ b/cddl/usr.sbin/dtruss/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ diff --git a/contrib/compiler-rt/lib/builtins/arm/aeabi_memcmp.S b/contrib/compiler-rt/lib/builtins/arm/aeabi_memcmp.S index 051ce43..fa69327 100644 --- a/contrib/compiler-rt/lib/builtins/arm/aeabi_memcmp.S +++ b/contrib/compiler-rt/lib/builtins/arm/aeabi_memcmp.S @@ -18,3 +18,5 @@ END_COMPILERRT_FUNCTION(__aeabi_memcmp) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp4, __aeabi_memcmp) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp8, __aeabi_memcmp) + + .section .note.GNU-stack,"",%progbits diff --git a/contrib/compiler-rt/lib/builtins/arm/aeabi_memcpy.S b/contrib/compiler-rt/lib/builtins/arm/aeabi_memcpy.S index cf02332..35b8558 100644 --- a/contrib/compiler-rt/lib/builtins/arm/aeabi_memcpy.S +++ b/contrib/compiler-rt/lib/builtins/arm/aeabi_memcpy.S @@ -18,3 +18,5 @@ END_COMPILERRT_FUNCTION(__aeabi_memcpy) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy4, __aeabi_memcpy) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy8, __aeabi_memcpy) + + .section .note.GNU-stack,"",%progbits diff --git a/contrib/compiler-rt/lib/builtins/arm/aeabi_memmove.S b/contrib/compiler-rt/lib/builtins/arm/aeabi_memmove.S index 4dda06f..2f9f789 100644 --- a/contrib/compiler-rt/lib/builtins/arm/aeabi_memmove.S +++ b/contrib/compiler-rt/lib/builtins/arm/aeabi_memmove.S @@ -18,3 +18,5 @@ END_COMPILERRT_FUNCTION(__aeabi_memmove) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove4, __aeabi_memmove) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove8, __aeabi_memmove) + + .section .note.GNU-stack,"",%progbits diff --git a/contrib/compiler-rt/lib/builtins/arm/aeabi_memset.S b/contrib/compiler-rt/lib/builtins/arm/aeabi_memset.S index c8b49c7..f2342f0 100644 --- a/contrib/compiler-rt/lib/builtins/arm/aeabi_memset.S +++ b/contrib/compiler-rt/lib/builtins/arm/aeabi_memset.S @@ -32,3 +32,4 @@ END_COMPILERRT_FUNCTION(__aeabi_memclr) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr4, __aeabi_memclr) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr8, __aeabi_memclr) + .section .note.GNU-stack,"",%progbits diff --git a/contrib/gcc/config/arm/crti.asm b/contrib/gcc/config/arm/crti.asm index 166a3ce..8df00d2 100644 --- a/contrib/gcc/config/arm/crti.asm +++ b/contrib/gcc/config/arm/crti.asm @@ -60,6 +60,8 @@ .file "crti.asm" + .section .note.GNU-stack,"",%progbits + .section ".init" .align 2 .global _init diff --git a/contrib/gcc/config/arm/crtn.asm b/contrib/gcc/config/arm/crtn.asm index 360afae..1947919 100644 --- a/contrib/gcc/config/arm/crtn.asm +++ b/contrib/gcc/config/arm/crtn.asm @@ -68,6 +68,8 @@ .file "crtn.asm" + .section .note.GNU-stack,"",%progbits + .section ".init" ;; FUNC_END diff --git a/contrib/gcc/config/arm/lib1funcs.asm b/contrib/gcc/config/arm/lib1funcs.asm index 73c453d..8a48b25 100644 --- a/contrib/gcc/config/arm/lib1funcs.asm +++ b/contrib/gcc/config/arm/lib1funcs.asm @@ -1305,3 +1305,5 @@ LSYM(Lchange_\register): #include "ieee754-sf.S" #include "bpabi.S" #endif /* __symbian__ */ + + .section .note.GNU-stack,"",%progbits diff --git a/contrib/libcxxrt/exception.cc b/contrib/libcxxrt/exception.cc index e428773..c559f97 100644 --- a/contrib/libcxxrt/exception.cc +++ b/contrib/libcxxrt/exception.cc @@ -516,7 +516,7 @@ static void emergency_malloc_free(char *ptr) break; } } - assert(buffer > 0 && + assert(buffer >= 0 && "Trying to free something that is not an emergency buffer!"); // emergency_malloc() is expected to return 0-initialized data. We don't // zero the buffer when allocating it, because the static buffers will @@ -556,7 +556,7 @@ static void free_exception(char *e) { // If this allocation is within the address range of the emergency buffer, // don't call free() because it was not allocated with malloc() - if ((e > emergency_buffer) && + if ((e >= emergency_buffer) && (e < (emergency_buffer + sizeof(emergency_buffer)))) { emergency_malloc_free(e); diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c b/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c index 46c0ff1..20a9e42 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c @@ -53,6 +53,8 @@ run(int n, ...) va_start(va, n); #if defined(__FreeBSD__) && defined(__amd64__) for (i = 0; i < 5; i++) { +#elif defined(__FreeBSD__) && defined(__aarch64__) + for (i = 0; i < 7; i++) { #else for (i = 0; i < 9; i++) { #endif @@ -116,6 +118,10 @@ ATF_TC_BODY(setcontext_link, tc) /* FreeBSD/amd64 only permits up to 6 arguments. */ makecontext(&uc[i], (void *)run, 6, i, 0, 1, 2, 3, 4); +#elif defined(__FreeBSD__) && defined(__aarch64__) + /* FreeBSD/arm64 only permits up to 8 arguments. */ + makecontext(&uc[i], (void *)run, 8, i, + 0, 1, 2, 3, 4, 5, 6); #else makecontext(&uc[i], (void *)run, 10, i, 0, 1, 2, 3, 4, 5, 6, 7, 8); diff --git a/contrib/netcat/nc.1 b/contrib/netcat/nc.1 index e1f4c2d..7e7b9fd 100644 --- a/contrib/netcat/nc.1 +++ b/contrib/netcat/nc.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: nc.1,v 1.67 2014/02/26 20:56:11 claudio Exp $ +.\" $OpenBSD: nc.1,v 1.68 2015/03/26 10:35:04 tobias Exp $ .\" .\" Copyright (c) 1996 David Sacerdote .\" All rights reserved. @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 11, 2014 +.Dd September 26, 2015 .Dt NC 1 .Os .Sh NAME @@ -133,7 +133,7 @@ connection to another program (e.g.\& .Xr ssh 1 using the .Xr ssh_config 5 -.Cm ProxyUseFdPass +.Cm ProxyUseFdpass option). .It Fl h Prints out diff --git a/contrib/netcat/netcat.c b/contrib/netcat/netcat.c index 041fff8..04e31e8a 100644 --- a/contrib/netcat/netcat.c +++ b/contrib/netcat/netcat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: netcat.c,v 1.127 2015/02/14 22:40:22 jca Exp $ */ +/* $OpenBSD: netcat.c,v 1.130 2015/07/26 19:12:28 chl Exp $ */ /* * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> * @@ -52,15 +52,16 @@ #include <err.h> #include <errno.h> #include <getopt.h> +#include <fcntl.h> +#include <limits.h> #include <netdb.h> #include <poll.h> +#include <signal.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <fcntl.h> -#include <limits.h> #include "atomicio.h" #ifndef SUN_LEN @@ -163,6 +164,8 @@ main(int argc, char *argv[]) uport = NULL; sv = NULL; + signal(SIGPIPE, SIG_IGN); + while ((ch = getopt_long(argc, argv, "46DdEe:FhI:i:klNnoO:P:p:rSs:tT:UuV:vw:X:x:z", longopts, NULL)) != -1) { @@ -1042,7 +1045,6 @@ fdpass(int nfd) bzero(&mh, sizeof(mh)); bzero(&cmsgbuf, sizeof(cmsgbuf)); bzero(&iov, sizeof(iov)); - bzero(&pfd, sizeof(pfd)); mh.msg_control = (caddr_t)&cmsgbuf.buf; mh.msg_controllen = sizeof(cmsgbuf.buf); @@ -1059,17 +1061,17 @@ fdpass(int nfd) bzero(&pfd, sizeof(pfd)); pfd.fd = STDOUT_FILENO; + pfd.events = POLLOUT; for (;;) { r = sendmsg(STDOUT_FILENO, &mh, 0); if (r == -1) { if (errno == EAGAIN || errno == EINTR) { - pfd.events = POLLOUT; if (poll(&pfd, 1, -1) == -1) err(1, "poll"); continue; } err(1, "sendmsg"); - } else if (r == -1) + } else if (r != 1) errx(1, "sendmsg: unexpected return value %zd", r); else break; diff --git a/contrib/netcat/socks.c b/contrib/netcat/socks.c index f8adda4..1b06e0e 100644 --- a/contrib/netcat/socks.c +++ b/contrib/netcat/socks.c @@ -1,4 +1,4 @@ -/* $OpenBSD: socks.c,v 1.20 2012/03/08 09:56:28 espie Exp $ */ +/* $OpenBSD: socks.c,v 1.21 2015/03/26 21:19:51 tobias Exp $ */ /* * Copyright (c) 1999 Niklas Hallqvist. All rights reserved. @@ -308,8 +308,8 @@ socks_connect(const char *host, const char *port, } /* Terminate headers */ - if ((r = atomicio(vwrite, proxyfd, "\r\n", 2)) != 2) - err(1, "write failed (2/%d)", r); + if ((cnt = atomicio(vwrite, proxyfd, "\r\n", 2)) != 2) + err(1, "write failed (%zu/2)", cnt); /* Read status reply */ proxy_read_line(proxyfd, buf, sizeof(buf)); diff --git a/etc/etc.aarch64/ttys b/etc/etc.aarch64/ttys index b6fd9ed..f5f225e 100644 --- a/etc/etc.aarch64/ttys +++ b/etc/etc.aarch64/ttys @@ -29,7 +29,7 @@ # when going to single-user mode. console none unknown off secure # -ttyv0 "/usr/libexec/getty Pc" xterm off secure +ttyv0 "/usr/libexec/getty Pc" xterm onifconsole secure # Virtual terminals ttyv1 "/usr/libexec/getty Pc" xterm off secure ttyv2 "/usr/libexec/getty Pc" xterm off secure @@ -41,9 +41,9 @@ ttyv7 "/usr/libexec/getty Pc" xterm off secure #ttyv8 "/usr/local/bin/xdm -nodaemon" xterm off secure # Serial terminals # The 'dialup' keyword identifies dialin lines to login, fingerd etc. -ttyu0 "/usr/libexec/getty std.9600" vt100 on secure -ttyu1 "/usr/libexec/getty std.9600" dialup off secure -ttyu2 "/usr/libexec/getty std.9600" dialup off secure -ttyu3 "/usr/libexec/getty std.9600" dialup off secure +ttyu0 "/usr/libexec/getty 3wire" vt100 onifconsole secure +ttyu1 "/usr/libexec/getty 3wire" vt100 onifconsole secure +ttyu2 "/usr/libexec/getty 3wire" vt100 onifconsole secure +ttyu3 "/usr/libexec/getty 3wire" vt100 onifconsole secure # Dumb console dcons "/usr/libexec/getty std.9600" vt100 off secure diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist index 3d2ff51..8ff6189 100644 --- a/etc/mtree/BSD.tests.dist +++ b/etc/mtree/BSD.tests.dist @@ -14,6 +14,8 @@ .. expr .. + ls + .. mv .. pax diff --git a/etc/rc.d/ugidfw b/etc/rc.d/ugidfw index d65d6a3..09171e4 100755 --- a/etc/rc.d/ugidfw +++ b/etc/rc.d/ugidfw @@ -3,6 +3,7 @@ # $FreeBSD$ # PROVIDE: ugidfw +# REQUIRE: FILESYSTEMS # BEFORE: LOGIN # KEYWORD: nojail shutdown @@ -33,9 +34,17 @@ ugidfw_start() ugidfw_stop() { + local rulecount + # Disable the policy # - kldunload mac_bsdextended + # Check for the existence of rules and flush them if needed. + rulecount=$(sysctl -in security.mac.bsdextended.rule_count) + if [ ${rulecount:-0} -gt 0 ]; then + ugidfw list | sed -n '2,$p' | cut -d ' ' -f 1 | sort -r -n | + xargs -n 1 ugidfw remove + echo "MAC bsdextended rules flushed." + fi } load_rc_config $name diff --git a/etc/rc.subr b/etc/rc.subr index c23c8fd..cd933c6 100644 --- a/etc/rc.subr +++ b/etc/rc.subr @@ -768,6 +768,8 @@ check_startmsgs() # # ${name}_prepend n Command added before ${command}. # +# ${name}_login_class n Login class to use, else "daemon". +# # ${rc_arg}_cmd n If set, use this as the method when invoked; # Otherwise, use default command (see below) # @@ -942,7 +944,7 @@ run_rc_command() _nice=\$${name}_nice _user=\$${name}_user \ _group=\$${name}_group _groups=\$${name}_groups \ _fib=\$${name}_fib _env=\$${name}_env \ - _prepend=\$${name}_prepend + _prepend=\$${name}_prepend _login_class=\${${name}_login_class:-daemon} if [ -n "$_user" ]; then # unset $_user if running as that user if [ "$_user" = "$(eval $IDCMD)" ]; then @@ -1050,6 +1052,9 @@ $command $rc_flags $command_args" fi fi + # Prepend default limits + _doit="limits -C $_login_class $_doit" + # run the full command # if ! _run_rc_doit "$_doit"; then diff --git a/etc/sendmail/Makefile.depend b/etc/sendmail/Makefile.depend index 3af2d7f..f80275d 100644 --- a/etc/sendmail/Makefile.depend +++ b/etc/sendmail/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ diff --git a/gnu/lib/csu/Makefile b/gnu/lib/csu/Makefile index de78c7e..92d49dc 100644 --- a/gnu/lib/csu/Makefile +++ b/gnu/lib/csu/Makefile @@ -75,6 +75,4 @@ CLEANFILES+= tm.h tconfig.h options.h optionlist cs-tconfig.h cs-tm.h tm.h tconfig.h options.h: ${CCDIR}/cc_tools/Makefile (cd ${.CURDIR}; ${MAKE} -f ${.ALLSRC} MFILE=${.ALLSRC} GCCDIR=${GCCDIR} ${.TARGET}) -.NOPATH: ${CLEANFILES} - .include <bsd.lib.mk> diff --git a/gnu/lib/libreadline/readline/Makefile b/gnu/lib/libreadline/readline/Makefile index f0bfe5b..a16d216 100644 --- a/gnu/lib/libreadline/readline/Makefile +++ b/gnu/lib/libreadline/readline/Makefile @@ -16,8 +16,6 @@ INSTALLED_HEADERS= readline.h chardefs.h keymaps.h history.h tilde.h \ CFLAGS+= -I${.OBJDIR}/.. SRCDIR= ${.CURDIR}/../../../../contrib/libreadline -.NOPATH: ${INSTALLED_HEADERS} - beforebuild: ${INSTALLED_HEADERS} CLEANFILES+= ${INSTALLED_HEADERS} DPSRCS+= ${INSTALLED_HEADERS} diff --git a/gnu/lib/libssp/Makefile.depend b/gnu/lib/libssp/Makefile.depend index f52ca95..79eb58b 100644 --- a/gnu/lib/libssp/Makefile.depend +++ b/gnu/lib/libssp/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/gnu/usr.bin/binutils/ld/Makefile b/gnu/usr.bin/binutils/ld/Makefile index 77d89a2..e15fdae 100644 --- a/gnu/usr.bin/binutils/ld/Makefile +++ b/gnu/usr.bin/binutils/ld/Makefile @@ -1,5 +1,6 @@ # $FreeBSD$ +ELF_SCR_EXT= x xbn xc xd xdc xdw xn xr xs xsc xsw xu xw .include "../Makefile.inc0" .include <src.opts.mk> @@ -50,9 +51,9 @@ FILESDIR= ${SCRIPTDIR} HOST= ${TARGET_TUPLE} LIBSEARCHPATH= \"${TOOLS_PREFIX}/lib\":\"${TOOLS_PREFIX}/usr/lib\" -ELF_SCR_EXT= x xbn xc xd xdc xdw xn xr xs xsc xsw xu xw .for ext in ${ELF_SCR_EXT} LDSCRIPTS+= ${NATIVE_EMULATION}.${ext} +ldscripts/${NATIVE_EMULATION}.${ext}: e${NATIVE_EMULATION}.c .endfor EMXFR= diff --git a/gnu/usr.bin/binutils/ld/Makefile.amd64 b/gnu/usr.bin/binutils/ld/Makefile.amd64 index 0175820..c9919bf 100644 --- a/gnu/usr.bin/binutils/ld/Makefile.amd64 +++ b/gnu/usr.bin/binutils/ld/Makefile.amd64 @@ -16,6 +16,7 @@ _i386_path= \"${TOOLS_PREFIX}/usr/lib32\" EMS+= ${X86_EMULATION} .for ext in ${ELF_SCR_EXT} LDSCRIPTS+= ${X86_EMULATION}.${ext} +ldscripts/${X86_EMULATION}.${ext}: e${X86_EMULATION}.c .endfor SRCS+= e${X86_EMULATION}.c diff --git a/gnu/usr.bin/binutils/ld/Makefile.mips b/gnu/usr.bin/binutils/ld/Makefile.mips index c6cd69f..8a7dfbb 100644 --- a/gnu/usr.bin/binutils/ld/Makefile.mips +++ b/gnu/usr.bin/binutils/ld/Makefile.mips @@ -22,6 +22,7 @@ EMS+= ${abi} #.endif .for ext in ${ELF_SCR_EXT} LDSCRIPTS+= ${abi}.${ext} +ldscripts/${abi}.${ext}: e${abi}.c .endfor SRCS+= e${abi}.c CLEANFILES+= e${abi}.c diff --git a/gnu/usr.bin/binutils/ld/Makefile.powerpc64 b/gnu/usr.bin/binutils/ld/Makefile.powerpc64 index 29fba2a..9e18cb4 100644 --- a/gnu/usr.bin/binutils/ld/Makefile.powerpc64 +++ b/gnu/usr.bin/binutils/ld/Makefile.powerpc64 @@ -16,6 +16,7 @@ _ppc32_path= \"${TOOLS_PREFIX}/usr/lib32\" EMS+= ${PPC32_EMULATION} .for ext in ${ELF_SCR_EXT} LDSCRIPTS+= ${PPC32_EMULATION}.${ext} +ldscripts/${PPC32_EMULATION}.${ext}: e${PPC32_EMULATION}.c .endfor SRCS+= e${PPC32_EMULATION}.c diff --git a/gnu/usr.bin/binutils/ld/Makefile.sparc64 b/gnu/usr.bin/binutils/ld/Makefile.sparc64 index d28a235..9ce6c6f 100644 --- a/gnu/usr.bin/binutils/ld/Makefile.sparc64 +++ b/gnu/usr.bin/binutils/ld/Makefile.sparc64 @@ -17,6 +17,7 @@ e${NATIVE_EMULATION}.c: emulparams/${NATIVE_EMULATION}.sh emultempl/elf32.em \ EMS+= elf${BITS}_sparc .for ext in ${ELF_SCR_EXT} LDSCRIPTS+= elf${BITS}_sparc.${ext} +ldscripts/elf${BITS}_sparc.${ext}: eelf${BITS}_sparc.c .endfor SRCS+= eelf${BITS}_sparc.c diff --git a/gnu/usr.bin/binutils/libbfd/Makefile.i386 b/gnu/usr.bin/binutils/libbfd/Makefile.i386 index e6d24a9..e41e30d 100644 --- a/gnu/usr.bin/binutils/libbfd/Makefile.i386 +++ b/gnu/usr.bin/binutils/libbfd/Makefile.i386 @@ -17,3 +17,5 @@ VECS= ${DEFAULT_VECTOR} \ peigen.c: peXXigen.c sed -e s/XX/pe/g ${.ALLSRC} > ${.TARGET} + +CLEANFILES+= peigen.c diff --git a/gnu/usr.bin/cc/c++/Makefile.depend b/gnu/usr.bin/cc/c++/Makefile.depend index 07a2968..3884bc8 100644 --- a/gnu/usr.bin/cc/c++/Makefile.depend +++ b/gnu/usr.bin/cc/c++/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/gnu/usr.bin/cc/cc/Makefile.depend b/gnu/usr.bin/cc/cc/Makefile.depend index 49202cf..2bea3c0 100644 --- a/gnu/usr.bin/cc/cc/Makefile.depend +++ b/gnu/usr.bin/cc/cc/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/usr.bin/cc/cc_tools \ diff --git a/gnu/usr.bin/cc/cc1/Makefile.depend b/gnu/usr.bin/cc/cc1/Makefile.depend index 7638ce5..00ebeb0 100644 --- a/gnu/usr.bin/cc/cc1/Makefile.depend +++ b/gnu/usr.bin/cc/cc1/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/usr.bin/cc/cc_int \ gnu/usr.bin/cc/cc_tools \ diff --git a/gnu/usr.bin/cc/cc1plus/Makefile.depend b/gnu/usr.bin/cc/cc1plus/Makefile.depend index 7d1e3c7..3e8b125 100644 --- a/gnu/usr.bin/cc/cc1plus/Makefile.depend +++ b/gnu/usr.bin/cc/cc1plus/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/usr.bin/cc/cc_int \ gnu/usr.bin/cc/cc_tools \ diff --git a/gnu/usr.bin/cc/cc_int/Makefile.depend b/gnu/usr.bin/cc/cc_int/Makefile.depend index 3a8633f..ea841fd 100644 --- a/gnu/usr.bin/cc/cc_int/Makefile.depend +++ b/gnu/usr.bin/cc/cc_int/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/usr.bin/cc/cc_tools \ include \ diff --git a/gnu/usr.bin/cc/cc_tools/Makefile b/gnu/usr.bin/cc/cc_tools/Makefile index 4121f5c..f451171 100644 --- a/gnu/usr.bin/cc/cc_tools/Makefile +++ b/gnu/usr.bin/cc/cc_tools/Makefile @@ -216,8 +216,6 @@ tconfig.h: GENSRCS+= tconfig.h CLEANFILES+= cs-tconfig.h -.NOPATH: ${GENSRCS} ${CLEANFILES} - # Options optionlist: ${OPT_FILES} LC_ALL=C awk -f ${GCCDIR}/opt-gather.awk ${.ALLSRC} > ${.TARGET} diff --git a/gnu/usr.bin/cc/cc_tools/Makefile.depend b/gnu/usr.bin/cc/cc_tools/Makefile.depend index 5558f36..2b92e28 100644 --- a/gnu/usr.bin/cc/cc_tools/Makefile.depend +++ b/gnu/usr.bin/cc/cc_tools/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/gnu/usr.bin/cc/cpp/Makefile.depend b/gnu/usr.bin/cc/cpp/Makefile.depend index 07a2968..3884bc8 100644 --- a/gnu/usr.bin/cc/cpp/Makefile.depend +++ b/gnu/usr.bin/cc/cpp/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/gnu/usr.bin/cc/gcov/Makefile.depend b/gnu/usr.bin/cc/gcov/Makefile.depend index 0f7485d..98e3478 100644 --- a/gnu/usr.bin/cc/gcov/Makefile.depend +++ b/gnu/usr.bin/cc/gcov/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/gnu/usr.bin/cc/include/Makefile.depend b/gnu/usr.bin/cc/include/Makefile.depend index d14a02b..f80275d 100644 --- a/gnu/usr.bin/cc/include/Makefile.depend +++ b/gnu/usr.bin/cc/include/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ diff --git a/gnu/usr.bin/cc/libcpp/Makefile.depend b/gnu/usr.bin/cc/libcpp/Makefile.depend index 5427265..075613d 100644 --- a/gnu/usr.bin/cc/libcpp/Makefile.depend +++ b/gnu/usr.bin/cc/libcpp/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/gnu/usr.bin/cc/libdecnumber/Makefile.depend b/gnu/usr.bin/cc/libdecnumber/Makefile.depend index 3a8633f..ea841fd 100644 --- a/gnu/usr.bin/cc/libdecnumber/Makefile.depend +++ b/gnu/usr.bin/cc/libdecnumber/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/usr.bin/cc/cc_tools \ include \ diff --git a/gnu/usr.bin/cc/libiberty/Makefile.depend b/gnu/usr.bin/cc/libiberty/Makefile.depend index ccd19e5..18be76b 100644 --- a/gnu/usr.bin/cc/libiberty/Makefile.depend +++ b/gnu/usr.bin/cc/libiberty/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/gnu/usr.bin/diff/Makefile.depend b/gnu/usr.bin/diff/Makefile.depend index 4eb4a14..6029d00 100644 --- a/gnu/usr.bin/diff/Makefile.depend +++ b/gnu/usr.bin/diff/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ gnu/lib/libregex \ diff --git a/gnu/usr.bin/dtc/Makefile.depend b/gnu/usr.bin/dtc/Makefile.depend index 50fce9a..01e6ecb 100644 --- a/gnu/usr.bin/dtc/Makefile.depend +++ b/gnu/usr.bin/dtc/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c b/gnu/usr.bin/gdb/kgdb/trgt_amd64.c index cb13d71..104d8c5 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c +++ b/gnu/usr.bin/gdb/kgdb/trgt_amd64.c @@ -72,7 +72,6 @@ kgdb_trgt_fetch_registers(int regno __unused) supply_register(AMD64_R8_REGNUM + 6, (char *)&pcb.pcb_r14); supply_register(AMD64_R15_REGNUM, (char *)&pcb.pcb_r15); supply_register(AMD64_RIP_REGNUM, (char *)&pcb.pcb_rip); - amd64_supply_fxsave(current_regcache, -1, (struct fpusave *)(&pcb + 1)); } void diff --git a/gnu/usr.bin/gperf/Makefile.depend b/gnu/usr.bin/gperf/Makefile.depend index 1956799..8c58c1e 100644 --- a/gnu/usr.bin/gperf/Makefile.depend +++ b/gnu/usr.bin/gperf/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ gnu/lib/libstdc++ \ diff --git a/gnu/usr.bin/grep/Makefile.depend b/gnu/usr.bin/grep/Makefile.depend index 435d267..a5d26c4 100644 --- a/gnu/usr.bin/grep/Makefile.depend +++ b/gnu/usr.bin/grep/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ gnu/lib/libregex \ diff --git a/gnu/usr.bin/groff/tmac/Makefile b/gnu/usr.bin/groff/tmac/Makefile index d74f76a..b756ec0 100644 --- a/gnu/usr.bin/groff/tmac/Makefile +++ b/gnu/usr.bin/groff/tmac/Makefile @@ -14,7 +14,7 @@ MLINKS= groff_ms.7 ms.7 MLINKS+= groff_me.7 me.7 MLINKS+= groff_mdoc.7 mdoc.samples.7 -CLEANFILES= ${MAN} ${MDOCFILES:S/$/-s/} ${STRIPFILES:S/$/-s/} ${SPECIALFILES:S/$/-s/} +CLEANFILES= ${MAN} NORMALFILES= mandoc.tmac andoc.tmac an-old.tmac \ me.tmac \ @@ -39,45 +39,59 @@ NORMALFILES= mandoc.tmac andoc.tmac an-old.tmac \ composite.tmac \ eqnrc \ troffrc troffrc-end \ + koi8-r.tmac hyphen.ru \ hyphen.us hyphenex.us +# These are all generated into the OBJDIR. SPECIALFILES= an.tmac man.tmac s.tmac ms.tmac www.tmac STRIPFILES= e.tmac doc.tmac mdoc.local MDOCFILES= doc-common doc-ditroff doc-nroff doc-syms \ fr.ISO8859-1 ru.KOI8-R +# These are in srcdir and must be built special to avoid colliding with +# CURDIR=OBJDIR. +SRCFILES= fr.ISO8859-1 mdoc.local ru.KOI8-R +CLEANFILES+= ${SRCFILES} -all: ${MDOCFILES:S/$/-s/} ${STRIPFILES:S/$/-s/} ${SPECIALFILES:S/$/-s/} +FILESGROUPS= FILES +FILES= ${NORMALFILES} +FILESOWN= ${TMACOWN} +FILESGRP= ${TMACGRP} +FILESMODE= ${TMACMODE} +FILESDIR= ${TMACDIR} +MDOCFILESDIR= ${MDOCDIR} +# Setup handling for the generated and special file groups +.for var in SPECIAL STRIP MDOC +FILESGROUPS+= ${var}FILES +CLEANFILES+= ${${var}FILES} +${var}FILESOWN?=${TMACOWN} +${var}FILESGRP?=${TMACGRP} +${var}FILESMODE?=${TMACMODE} +${var}FILESDIR?=${TMACDIR} +.endfor + +beforeinstall: +.if !exists(${DESTDIR}${TMACDIR}/man.local) + ${INSTALL} -o ${TMACOWN} -g ${TMACGRP} -m ${TMACMODE} \ + ${DIST_DIR}/man.local ${DESTDIR}${TMACDIR} +.endif + +.include <bsd.prog.mk> + +# Do this after ../Makefile.inc gets included so DIST_DIR is defined. .for f in ${MDOCFILES} ${STRIPFILES} -$f-s: $f +# Generate the file from the contrib dir or src dir as needed. +.if ${SRCFILES:M${f}} != "" +${f}: ${.CURDIR}/${f}.in +.else +${f}: ${DIST_DIR}/${f} +.endif sed -f ${DIST_DIR}/strip.sed ${.ALLSRC} > ${.TARGET} .endfor .for f in ${SPECIALFILES} -$f-s: $f +${f}: ${DIST_DIR}/${f} sed -e "s;@TMAC_AN_PREFIX@;${tmac_an_prefix};g" \ -e "s;@TMAC_S_PREFIX@;${tmac_s_prefix};g" \ -e "s;@PNMTOPS_NOSETPAGE@;pnmtops;g" \ ${.ALLSRC} > ${.TARGET} .endfor - -beforeinstall: - (cd ${DIST_DIR} && \ - ${INSTALL} -o ${TMACOWN} -g ${TMACGRP} -m ${TMACMODE} \ - ${NORMALFILES} ${DESTDIR}${TMACDIR}) - (cd ${.CURDIR} && \ - ${INSTALL} -o ${TMACOWN} -g ${TMACGRP} -m ${TMACMODE} \ - koi8-r.tmac hyphen.ru ${DESTDIR}${TMACDIR}) -.for f in ${STRIPFILES} ${SPECIALFILES} - ${INSTALL} -o ${TMACOWN} -g ${TMACGRP} -m ${TMACMODE} \ - $f-s ${DESTDIR}${TMACDIR}/$f -.endfor -.for f in ${MDOCFILES} - ${INSTALL} -o ${TMACOWN} -g ${TMACGRP} -m ${TMACMODE} \ - $f-s ${DESTDIR}${MDOCDIR}/$f -.endfor -.if !exists(${DESTDIR}${TMACDIR}/man.local) - ${INSTALL} -o ${TMACOWN} -g ${TMACGRP} -m ${TMACMODE} \ - ${DIST_DIR}/man.local ${DESTDIR}${TMACDIR} -.endif - -.include <bsd.prog.mk> diff --git a/gnu/usr.bin/groff/tmac/fr.ISO8859-1 b/gnu/usr.bin/groff/tmac/fr.ISO8859-1.in index 2ec54f5..2ec54f5 100644 --- a/gnu/usr.bin/groff/tmac/fr.ISO8859-1 +++ b/gnu/usr.bin/groff/tmac/fr.ISO8859-1.in diff --git a/gnu/usr.bin/groff/tmac/mdoc.local b/gnu/usr.bin/groff/tmac/mdoc.local.in index e7ec4cf..e7ec4cf 100644 --- a/gnu/usr.bin/groff/tmac/mdoc.local +++ b/gnu/usr.bin/groff/tmac/mdoc.local.in diff --git a/gnu/usr.bin/groff/tmac/ru.KOI8-R b/gnu/usr.bin/groff/tmac/ru.KOI8-R.in index 4ae5697..4ae5697 100644 --- a/gnu/usr.bin/groff/tmac/ru.KOI8-R +++ b/gnu/usr.bin/groff/tmac/ru.KOI8-R.in diff --git a/kerberos5/Makefile b/kerberos5/Makefile index c66ad4d..c93126d 100644 --- a/kerberos5/Makefile +++ b/kerberos5/Makefile @@ -1,6 +1,8 @@ # $FreeBSD$ -SUBDIR= lib libexec tools usr.bin usr.sbin +SUBDIR= lib .WAIT \ + libexec tools usr.bin usr.sbin +SUBDIR_PARALLEL= # These are the programs which depend on Kerberos. KPROGS= lib/libpam \ diff --git a/kerberos5/lib/Makefile b/kerberos5/lib/Makefile index dddb4d2..3c03204 100644 --- a/kerberos5/lib/Makefile +++ b/kerberos5/lib/Makefile @@ -6,5 +6,7 @@ SUBDIR= libasn1 libgssapi_krb5 libgssapi_ntlm libgssapi_spnego libhdb \ libroken libsl libvers libkdc libwind libheimbase libheimipcc libheimipcs SUBDIR+= libkafs5 # requires krb_err.h from libkrb5 +SUBDIR_DEPEND_libkafs5= libkrb5 +SUBDIR_PARALLEL= .include <bsd.subdir.mk> diff --git a/kerberos5/libexec/Makefile b/kerberos5/libexec/Makefile index e6735ca..26a830d 100644 --- a/kerberos5/libexec/Makefile +++ b/kerberos5/libexec/Makefile @@ -2,5 +2,6 @@ SUBDIR= digest-service ipropd-master ipropd-slave hprop hpropd kadmind kdc \ kdigest kfd kimpersonate kpasswdd kcm +SUBDIR_PARALLEL= .include <bsd.subdir.mk> diff --git a/kerberos5/libexec/kdigest/Makefile b/kerberos5/libexec/kdigest/Makefile index f9b42e5..5f3fb24 100644 --- a/kerberos5/libexec/kdigest/Makefile +++ b/kerberos5/libexec/kdigest/Makefile @@ -10,12 +10,12 @@ SRCS= kdigest.c \ kdigest-commands.c \ kdigest-commands.h +CLEANFILES= kdigest-commands.h kdigest-commands.c + kdigest-commands.h: kdigest-commands.in ${SLC} ${.ALLSRC:M*.in} -.for ext in c o -kdigest-commands.${ext}: kdigest-commands.h -.endfor +kdigest-commands.c: kdigest-commands.h .include <bsd.prog.mk> diff --git a/kerberos5/tools/Makefile b/kerberos5/tools/Makefile index 0bbf2d4..b623a25 100644 --- a/kerberos5/tools/Makefile +++ b/kerberos5/tools/Makefile @@ -1,5 +1,6 @@ # $FreeBSD$ SUBDIR= make-roken asn1_compile slc +SUBDIR_PARALLEL= .include <bsd.subdir.mk> diff --git a/kerberos5/usr.bin/Makefile b/kerberos5/usr.bin/Makefile index da141e5..e9c5030 100644 --- a/kerberos5/usr.bin/Makefile +++ b/kerberos5/usr.bin/Makefile @@ -2,5 +2,6 @@ SUBDIR= hxtool kadmin kcc kdestroy kgetcred kf kinit kpasswd krb5-config ksu \ string2key verify_krb5_conf +SUBDIR_PARALLEL= .include <bsd.subdir.mk> diff --git a/kerberos5/usr.bin/hxtool/Makefile b/kerberos5/usr.bin/hxtool/Makefile index 53612fd..af85a44 100644 --- a/kerberos5/usr.bin/hxtool/Makefile +++ b/kerberos5/usr.bin/hxtool/Makefile @@ -9,12 +9,12 @@ CFLAGS+= -I${KRB5DIR}/lib/hx509 \ LIBADD= hx509 roken asn1 crypto sl vers edit SRCS= hxtool.c hxtool-commands.c hxtool-commands.h +CLEANFILES= hxtool-commands.h hxtool-commands.c + hxtool-commands.h: hxtool-commands.in ${SLC} ${.ALLSRC:M*.in} -.for ext in c o -hxtool-commands.${ext}: hxtool-commands.h -.endfor +hxtool-commands.c: hxtool-commands.h .include <bsd.prog.mk> diff --git a/kerberos5/usr.bin/kadmin/Makefile b/kerberos5/usr.bin/kadmin/Makefile index b3b84b9..e7aff44 100644 --- a/kerberos5/usr.bin/kadmin/Makefile +++ b/kerberos5/usr.bin/kadmin/Makefile @@ -31,14 +31,14 @@ DPADD= ${LDAPDPADD} LDADD= ${LDAPLDADD} LDFLAGS=${LDAPLDFLAGS} +CLEANFILES= kadmin-commands.h kadmin-commands.c + .include <bsd.prog.mk> kadmin-commands.h: ${KRB5DIR}/kadmin/kadmin-commands.in ${SLC} ${.ALLSRC:M*.in} -.for ext in o c -kadmin-commands.${ext}: kadmin-commands.h -.endfor +kadmin-commands.c: kadmin-commands.h .PATH: ${KRB5DIR}/kadmin diff --git a/kerberos5/usr.bin/kcc/Makefile b/kerberos5/usr.bin/kcc/Makefile index cde73f5..7c4b7ab 100644 --- a/kerberos5/usr.bin/kcc/Makefile +++ b/kerberos5/usr.bin/kcc/Makefile @@ -16,12 +16,12 @@ SRCS= kcc.c \ kswitch.c \ copy_cred_cache.c +CLEANFILES= kcc-commands.h kcc-commands.c + kcc-commands.h: kcc-commands.in ${SLC} ${.ALLSRC:M*.in} -.for ext in c o -kcc-commands.${ext}: kcc-commands.h -.endfor +kcc-commands.c: kcc-commands.h .include <bsd.prog.mk> diff --git a/kerberos5/usr.sbin/Makefile b/kerberos5/usr.sbin/Makefile index 5e8d58e..a7a69ce 100644 --- a/kerberos5/usr.sbin/Makefile +++ b/kerberos5/usr.sbin/Makefile @@ -1,5 +1,6 @@ # $FreeBSD$ SUBDIR= iprop-log kstash ktutil +SUBDIR_PARALLEL= .include <bsd.subdir.mk> diff --git a/kerberos5/usr.sbin/iprop-log/Makefile b/kerberos5/usr.sbin/iprop-log/Makefile index 2343919..1f71f9b 100644 --- a/kerberos5/usr.sbin/iprop-log/Makefile +++ b/kerberos5/usr.sbin/iprop-log/Makefile @@ -11,12 +11,12 @@ CFLAGS+= -I${KRB5DIR}/lib/kadm5 \ LIBADD= kadm5srv hdb krb5 roken edit sl vers LDFLAGS=${LDAPLDFLAGS} +CLEANFILES= iprop-commands.h iprop-commands.c + iprop-commands.h: iprop-commands.in ${SLC} ${.ALLSRC:M*.in} -.for ext in c o -iprop-commands.${ext}: iprop-commands.h -.endfor +iprop-commands.c: iprop-commands.h .include <bsd.prog.mk> diff --git a/kerberos5/usr.sbin/ktutil/Makefile b/kerberos5/usr.sbin/ktutil/Makefile index fe45494..c79d09e 100644 --- a/kerberos5/usr.sbin/ktutil/Makefile +++ b/kerberos5/usr.sbin/ktutil/Makefile @@ -19,13 +19,13 @@ SRCS= add.c \ CFLAGS+=-I${KRB5DIR}/lib/roken -I${KRB5DIR}/lib/sl -I. LIBADD= kadm5clnt krb5 roken crypto edit sl vers +CLEANFILES= ktutil-commands.h ktutil-commands.c + .include <bsd.prog.mk> ktutil-commands.h: ${KRB5DIR}/admin/ktutil-commands.in ${SLC} ${.ALLSRC:M*.in} -.for ext in c o -ktutil-commands.${ext}: ktutil-commands.h -.endfor +ktutil-commands.c: ktutil-commands.h .PATH: ${KRB5DIR}/admin diff --git a/lib/clang/include/Makefile b/lib/clang/include/Makefile index 7f639b5..1cea2e2 100644 --- a/lib/clang/include/Makefile +++ b/lib/clang/include/Makefile @@ -65,7 +65,7 @@ INCS= __stddef_max_align_t.h \ xtestintrin.h \ ${GENINCS} GENINCS= arm_neon.h -CLEANFILES= ${GENINCS} +CLEANFILES= ${GENINCS} ${GENINCS:C/\.h$/.d/} # avoid a circular dependency GENDIRDEPS_FILTER+= Nusr.bin/clang/clang-tblgen.host diff --git a/lib/clang/libllvminterpreter/Makefile.depend b/lib/clang/libllvminterpreter/Makefile.depend index 4fc7d45..ff32938 100644 --- a/lib/clang/libllvminterpreter/Makefile.depend +++ b/lib/clang/libllvminterpreter/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/lib/csu/arm/Makefile.depend b/lib/csu/arm/Makefile.depend index e8d7c61..79506ce 100644 --- a/lib/csu/arm/Makefile.depend +++ b/lib/csu/arm/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ include \ diff --git a/lib/csu/arm/crti.S b/lib/csu/arm/crti.S index 40e83bb..c6c37eb 100644 --- a/lib/csu/arm/crti.S +++ b/lib/csu/arm/crti.S @@ -19,3 +19,4 @@ _fini: stmdb sp!, {fp, ip, lr, pc} sub fp, ip, #4 + .section .note.GNU-stack,"",%progbits diff --git a/lib/csu/arm/crtn.S b/lib/csu/arm/crtn.S index 962f0ed..25bbd57 100644 --- a/lib/csu/arm/crtn.S +++ b/lib/csu/arm/crtn.S @@ -8,3 +8,5 @@ __FBSDID("$FreeBSD$"); .section .fini,"ax",%progbits ldmea fp, {fp, sp, pc} mov pc, lr + + .section .note.GNU-stack,"",%progbits diff --git a/lib/csu/i386/Makefile.depend b/lib/csu/i386/Makefile.depend index 76d719e..79506ce 100644 --- a/lib/csu/i386/Makefile.depend +++ b/lib/csu/i386/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ diff --git a/lib/csu/mips/Makefile.depend b/lib/csu/mips/Makefile.depend index e8d7c61..79506ce 100644 --- a/lib/csu/mips/Makefile.depend +++ b/lib/csu/mips/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ include \ diff --git a/lib/csu/powerpc/Makefile.depend b/lib/csu/powerpc/Makefile.depend index e8d7c61..79506ce 100644 --- a/lib/csu/powerpc/Makefile.depend +++ b/lib/csu/powerpc/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ include \ diff --git a/lib/csu/powerpc64/Makefile.depend b/lib/csu/powerpc64/Makefile.depend index e8d7c61..79506ce 100644 --- a/lib/csu/powerpc64/Makefile.depend +++ b/lib/csu/powerpc64/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ include \ diff --git a/lib/csu/sparc64/Makefile.depend b/lib/csu/sparc64/Makefile.depend index e8d7c61..79506ce 100644 --- a/lib/csu/sparc64/Makefile.depend +++ b/lib/csu/sparc64/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ include \ diff --git a/lib/libblocksruntime/Makefile.depend b/lib/libblocksruntime/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libblocksruntime/Makefile.depend +++ b/lib/libblocksruntime/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libc/arm/aeabi/aeabi_asm_double.S b/lib/libc/arm/aeabi/aeabi_asm_double.S index 7a5af82..ced4d78 100644 --- a/lib/libc/arm/aeabi/aeabi_asm_double.S +++ b/lib/libc/arm/aeabi/aeabi_asm_double.S @@ -117,3 +117,5 @@ ENTRY(__aeabi_cdcmpeq) msr cpsr_c, ip RET END(__aeabi_cdcmpeq) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/aeabi/aeabi_asm_float.S b/lib/libc/arm/aeabi/aeabi_asm_float.S index e05daa5..de6b1c8 100644 --- a/lib/libc/arm/aeabi/aeabi_asm_float.S +++ b/lib/libc/arm/aeabi/aeabi_asm_float.S @@ -108,3 +108,5 @@ ENTRY(__aeabi_cfcmpeq) msr cpsr_c, ip RET END(__aeabi_cfcmpeq) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/aeabi/aeabi_vfp_double.S b/lib/libc/arm/aeabi/aeabi_vfp_double.S index aae49f8..be4309d 100644 --- a/lib/libc/arm/aeabi/aeabi_vfp_double.S +++ b/lib/libc/arm/aeabi/aeabi_vfp_double.S @@ -201,3 +201,4 @@ AEABI_ENTRY(dsub) RET AEABI_END(dsub) + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/aeabi/aeabi_vfp_float.S b/lib/libc/arm/aeabi/aeabi_vfp_float.S index 7de8daf..c9df41c 100644 --- a/lib/libc/arm/aeabi/aeabi_vfp_float.S +++ b/lib/libc/arm/aeabi/aeabi_vfp_float.S @@ -188,3 +188,4 @@ AEABI_ENTRY(fsub) RET AEABI_END(fsub) + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/__aeabi_read_tp.S b/lib/libc/arm/gen/__aeabi_read_tp.S index 670d0b8..224d6a6 100644 --- a/lib/libc/arm/gen/__aeabi_read_tp.S +++ b/lib/libc/arm/gen/__aeabi_read_tp.S @@ -45,3 +45,4 @@ END(__aeabi_read_tp) .word ARM_TP_ADDRESS #endif + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/_ctx_start.S b/lib/libc/arm/gen/_ctx_start.S index 41bfff9..faedfb5 100644 --- a/lib/libc/arm/gen/_ctx_start.S +++ b/lib/libc/arm/gen/_ctx_start.S @@ -8,3 +8,5 @@ ENTRY(_ctx_start) bl _C_LABEL(ctx_done) bl _C_LABEL(abort) END(_ctx_start) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/_setjmp.S b/lib/libc/arm/gen/_setjmp.S index 853f61c..e3c67fa 100644 --- a/lib/libc/arm/gen/_setjmp.S +++ b/lib/libc/arm/gen/_setjmp.S @@ -157,3 +157,5 @@ botch: b . #endif END(_longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/alloca.S b/lib/libc/arm/gen/alloca.S index e4a73d4..2539b7a 100644 --- a/lib/libc/arm/gen/alloca.S +++ b/lib/libc/arm/gen/alloca.S @@ -44,3 +44,5 @@ ENTRY(alloca) mov r0, sp /* r0 = base of new space */ RET END(alloca) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/divsi3.S b/lib/libc/arm/gen/divsi3.S index 82de5de..fac0663 100644 --- a/lib/libc/arm/gen/divsi3.S +++ b/lib/libc/arm/gen/divsi3.S @@ -389,3 +389,5 @@ ENTRY(__divsi3) mov r0, r3 RET END(__divsi3) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/setjmp.S b/lib/libc/arm/gen/setjmp.S index c9ae329..4e3850d 100644 --- a/lib/libc/arm/gen/setjmp.S +++ b/lib/libc/arm/gen/setjmp.S @@ -158,3 +158,5 @@ ENTRY(__longjmp) bl PIC_SYM(_C_LABEL(abort), PLT) 1: b 1b /* Cannot get here */ END(__longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/sigsetjmp.S b/lib/libc/arm/gen/sigsetjmp.S index 3743e89..236f531 100644 --- a/lib/libc/arm/gen/sigsetjmp.S +++ b/lib/libc/arm/gen/sigsetjmp.S @@ -66,3 +66,5 @@ ENTRY(siglongjmp) beq PIC_SYM(_C_LABEL(_longjmp), PLT) b PIC_SYM(_C_LABEL(longjmp), PLT) END(siglongjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/ffs.S b/lib/libc/arm/string/ffs.S index cc7f396..0ed8152 100644 --- a/lib/libc/arm/string/ffs.S +++ b/lib/libc/arm/string/ffs.S @@ -84,3 +84,5 @@ ENTRY(ffs) RET #endif END(ffs) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/memcmp.S b/lib/libc/arm/string/memcmp.S index 6fd8130..33a11b7 100644 --- a/lib/libc/arm/string/memcmp.S +++ b/lib/libc/arm/string/memcmp.S @@ -181,3 +181,5 @@ ENTRY(memcmp) RET #endif END(memcmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/memcpy_arm.S b/lib/libc/arm/string/memcpy_arm.S index 56fb703..57b0449 100644 --- a/lib/libc/arm/string/memcpy_arm.S +++ b/lib/libc/arm/string/memcpy_arm.S @@ -334,3 +334,5 @@ ENTRY(memcpy) sub r1, r1, #1 b .Lmemcpy_l4 END(memcpy) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/memcpy_xscale.S b/lib/libc/arm/string/memcpy_xscale.S index a451de4..ab01544 100644 --- a/lib/libc/arm/string/memcpy_xscale.S +++ b/lib/libc/arm/string/memcpy_xscale.S @@ -1784,3 +1784,5 @@ ENTRY(memcpy) bx lr #endif /* !_STANDALONE */ END(memcpy) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/memmove.S b/lib/libc/arm/string/memmove.S index 2cd5a5e..8f96147 100644 --- a/lib/libc/arm/string/memmove.S +++ b/lib/libc/arm/string/memmove.S @@ -609,3 +609,5 @@ END(memmove) #else END(bcopy) #endif + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/memset.S b/lib/libc/arm/string/memset.S index 6d76901..96d2f93 100644 --- a/lib/libc/arm/string/memset.S +++ b/lib/libc/arm/string/memset.S @@ -263,3 +263,5 @@ END(bzero) #else END(memset) #endif + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/strcmp.S b/lib/libc/arm/string/strcmp.S index d610fea..1cdce8b 100644 --- a/lib/libc/arm/string/strcmp.S +++ b/lib/libc/arm/string/strcmp.S @@ -43,3 +43,5 @@ ENTRY(strcmp) sub r0, r2, r3 RET END(strcmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/strlen.S b/lib/libc/arm/string/strlen.S index c9334f9..240fa7d 100644 --- a/lib/libc/arm/string/strlen.S +++ b/lib/libc/arm/string/strlen.S @@ -83,3 +83,5 @@ ENTRY(strlen) mov r0, r1 RET END(strlen) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/strncmp.S b/lib/libc/arm/string/strncmp.S index a5c0320..affcaa0 100644 --- a/lib/libc/arm/string/strncmp.S +++ b/lib/libc/arm/string/strncmp.S @@ -56,3 +56,5 @@ ENTRY(strncmp) sub r0, r2, r3 RET END(strncmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/Ovfork.S b/lib/libc/arm/sys/Ovfork.S index 4520e02..73c619e 100644 --- a/lib/libc/arm/sys/Ovfork.S +++ b/lib/libc/arm/sys/Ovfork.S @@ -53,3 +53,5 @@ ENTRY(vfork) and r0, r0, r1 /* r0 == 0 if child, else unchanged */ mov r15, r2 END(vfork) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/brk.S b/lib/libc/arm/sys/brk.S index e5f8336..bf1b4fb 100644 --- a/lib/libc/arm/sys/brk.S +++ b/lib/libc/arm/sys/brk.S @@ -91,3 +91,5 @@ ENTRY(_brk) .Lcurbrk: .word PIC_SYM(CURBRK, GOT) END(_brk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/cerror.S b/lib/libc/arm/sys/cerror.S index 26f5211..5fad698 100644 --- a/lib/libc/arm/sys/cerror.S +++ b/lib/libc/arm/sys/cerror.S @@ -47,3 +47,5 @@ ASENTRY(CERROR) mvn r1, #0x00000000 ldmfd sp!, {r4, pc} END(CERROR) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/pipe.S b/lib/libc/arm/sys/pipe.S index 77ce0fc..778e923 100644 --- a/lib/libc/arm/sys/pipe.S +++ b/lib/libc/arm/sys/pipe.S @@ -49,3 +49,5 @@ ENTRY(_pipe) mov r0, #0x00000000 RET END(_pipe) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/ptrace.S b/lib/libc/arm/sys/ptrace.S index 876da32..dade223 100644 --- a/lib/libc/arm/sys/ptrace.S +++ b/lib/libc/arm/sys/ptrace.S @@ -47,3 +47,5 @@ ENTRY(ptrace) bcs PIC_SYM(CERROR, PLT) RET END(ptrace) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/sbrk.S b/lib/libc/arm/sys/sbrk.S index 5cd9a03..25622c4 100644 --- a/lib/libc/arm/sys/sbrk.S +++ b/lib/libc/arm/sys/sbrk.S @@ -78,3 +78,5 @@ ENTRY(_sbrk) .Lcurbrk: .word PIC_SYM(CURBRK, GOT) END(_sbrk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/shmat.S b/lib/libc/arm/sys/shmat.S index 3fc3d02..3574b1d 100644 --- a/lib/libc/arm/sys/shmat.S +++ b/lib/libc/arm/sys/shmat.S @@ -5,3 +5,5 @@ __FBSDID("$FreeBSD$"); #include "SYS.h" RSYSCALL(shmat) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/sigreturn.S b/lib/libc/arm/sys/sigreturn.S index 1e0f245..c377e4a 100644 --- a/lib/libc/arm/sys/sigreturn.S +++ b/lib/libc/arm/sys/sigreturn.S @@ -40,3 +40,5 @@ __FBSDID("$FreeBSD$"); */ RSYSCALL(sigreturn) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/syscall.S b/lib/libc/arm/sys/syscall.S index 73e6b83..c88d1ae 100644 --- a/lib/libc/arm/sys/syscall.S +++ b/lib/libc/arm/sys/syscall.S @@ -36,3 +36,5 @@ __FBSDID("$FreeBSD$"); #include "SYS.h" RSYSCALL(syscall) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/gen/fnmatch.c b/lib/libc/gen/fnmatch.c index 173592a..2f240a8 100644 --- a/lib/libc/gen/fnmatch.c +++ b/lib/libc/gen/fnmatch.c @@ -87,11 +87,14 @@ static int fnmatch1(const char *pattern, const char *string, const char *stringstart, int flags, mbstate_t patmbs, mbstate_t strmbs) { + const char *bt_pattern, *bt_string; + mbstate_t bt_patmbs, bt_strmbs; char *newp; char c; wchar_t pc, sc; size_t pclen, sclen; + bt_pattern = bt_string = NULL; for (;;) { pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs); if (pclen == (size_t)-1 || pclen == (size_t)-2) @@ -107,16 +110,18 @@ fnmatch1(const char *pattern, const char *string, const char *stringstart, case EOS: if ((flags & FNM_LEADING_DIR) && sc == '/') return (0); - return (sc == EOS ? 0 : FNM_NOMATCH); + if (sc == EOS) + return (0); + goto backtrack; case '?': if (sc == EOS) return (FNM_NOMATCH); if (sc == '/' && (flags & FNM_PATHNAME)) - return (FNM_NOMATCH); + goto backtrack; if (sc == '.' && (flags & FNM_PERIOD) && (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) - return (FNM_NOMATCH); + goto backtrack; string += sclen; break; case '*': @@ -128,7 +133,7 @@ fnmatch1(const char *pattern, const char *string, const char *stringstart, if (sc == '.' && (flags & FNM_PERIOD) && (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) - return (FNM_NOMATCH); + goto backtrack; /* Optimize for pattern with * at end or before /. */ if (c == EOS) @@ -144,33 +149,24 @@ fnmatch1(const char *pattern, const char *string, const char *stringstart, break; } - /* General case, use recursion. */ - while (sc != EOS) { - if (!fnmatch1(pattern, string, stringstart, - flags, patmbs, strmbs)) - return (0); - sclen = mbrtowc(&sc, string, MB_LEN_MAX, - &strmbs); - if (sclen == (size_t)-1 || - sclen == (size_t)-2) { - sc = (unsigned char)*string; - sclen = 1; - memset(&strmbs, 0, sizeof(strmbs)); - } - if (sc == '/' && flags & FNM_PATHNAME) - break; - string += sclen; - } - return (FNM_NOMATCH); + /* + * First try the shortest match for the '*' that + * could work. We can forget any earlier '*' since + * there is no way having it match more characters + * can help us, given that we are already here. + */ + bt_pattern = pattern, bt_patmbs = patmbs; + bt_string = string, bt_strmbs = strmbs; + break; case '[': if (sc == EOS) return (FNM_NOMATCH); if (sc == '/' && (flags & FNM_PATHNAME)) - return (FNM_NOMATCH); + goto backtrack; if (sc == '.' && (flags & FNM_PERIOD) && (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) - return (FNM_NOMATCH); + goto backtrack; switch (rangematch(pattern, sc, flags, &newp, &patmbs)) { @@ -180,7 +176,7 @@ fnmatch1(const char *pattern, const char *string, const char *stringstart, pattern = newp; break; case RANGE_NOMATCH: - return (FNM_NOMATCH); + goto backtrack; } string += sclen; break; @@ -195,14 +191,39 @@ fnmatch1(const char *pattern, const char *string, const char *stringstart, /* FALLTHROUGH */ default: norm: + string += sclen; if (pc == sc) ; else if ((flags & FNM_CASEFOLD) && (towlower(pc) == towlower(sc))) ; - else - return (FNM_NOMATCH); - string += sclen; + else { + backtrack: + /* + * If we have a mismatch (other than hitting + * the end of the string), go back to the last + * '*' seen and have it match one additional + * character. + */ + if (bt_pattern == NULL) + return (FNM_NOMATCH); + sclen = mbrtowc(&sc, bt_string, MB_LEN_MAX, + &bt_strmbs); + if (sclen == (size_t)-1 || + sclen == (size_t)-2) { + sc = (unsigned char)*bt_string; + sclen = 1; + memset(&bt_strmbs, 0, + sizeof(bt_strmbs)); + } + if (sc == EOS) + return (FNM_NOMATCH); + if (sc == '/' && flags & FNM_PATHNAME) + return (FNM_NOMATCH); + bt_string += sclen; + pattern = bt_pattern, patmbs = bt_patmbs; + string = bt_string, strmbs = bt_strmbs; + } break; } } diff --git a/lib/libc/gen/fts-compat.c b/lib/libc/gen/fts-compat.c index 313431a..51b6c26 100644 --- a/lib/libc/gen/fts-compat.c +++ b/lib/libc/gen/fts-compat.c @@ -137,9 +137,8 @@ __fts_open_44bsd(char * const *argv, int options, } /* Allocate/initialize the stream. */ - if ((priv = malloc(sizeof(*priv))) == NULL) + if ((priv = calloc(1, sizeof(*priv))) == NULL) return (NULL); - memset(priv, 0, sizeof(*priv)); sp = &priv->ftsp_fts; sp->fts_compar = compar; sp->fts_options = options; diff --git a/lib/libc/gen/wordexp.3 b/lib/libc/gen/wordexp.3 index 2fc20ef..dd4605f 100644 --- a/lib/libc/gen/wordexp.3 +++ b/lib/libc/gen/wordexp.3 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 18, 2015 +.Dd September 30, 2015 .Dt WORDEXP 3 .Os .Sh NAME @@ -108,8 +108,9 @@ function frees the memory allocated by .Sh IMPLEMENTATION NOTES The .Fn wordexp -function is implemented by executing -.Xr sh 1 . +function is implemented using the undocumented +.Ic freebsd_wordexp +shell built-in command. .Sh RETURN VALUES The .Fn wordexp @@ -191,18 +192,19 @@ and functions conform to .St -p1003.1-2001 . .Sh BUGS -Do not pass untrusted user data to -.Fn wordexp , -regardless of whether the -.Dv WRDE_NOCMD -flag is set. -The -.Fn wordexp -function attempts to detect input that would cause commands to be -executed before passing it to the shell -but it does not use the same parser so it may be fooled. -.Pp The current .Fn wordexp implementation does not recognize multibyte characters other than UTF-8, since the shell (which it invokes to perform expansions) does not. +.Sh SECURITY CONSIDERATIONS +Pathname generation may create output that is exponentially larger than the +input size. +.Pp +Although this implementation detects command substitution reliably for +.Dv WRDE_NOCMD , +the attack surface remains fairly large. +Also, some other implementations +(such as older versions of this one) +may execute command substitutions even if +.Dv WRDE_NOCMD +is set. diff --git a/lib/libc/gen/wordexp.c b/lib/libc/gen/wordexp.c index 859ca50..3791e1e 100644 --- a/lib/libc/gen/wordexp.c +++ b/lib/libc/gen/wordexp.c @@ -32,6 +32,7 @@ #include <fcntl.h> #include <paths.h> #include <signal.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -43,7 +44,7 @@ __FBSDID("$FreeBSD$"); static int we_askshell(const char *, wordexp_t *, int); -static int we_check(const char *, int); +static int we_check(const char *); /* * wordexp -- @@ -65,7 +66,7 @@ wordexp(const char * __restrict words, wordexp_t * __restrict we, int flags) we->we_strings = NULL; we->we_nbytes = 0; } - if ((error = we_check(words, flags)) != 0) { + if ((error = we_check(words)) != 0) { wordfree(we); return (error); } @@ -94,17 +95,37 @@ we_read_fully(int fd, char *buffer, size_t len) return done; } +static bool +we_write_fully(int fd, const char *buffer, size_t len) +{ + size_t done; + ssize_t nwritten; + + done = 0; + do { + nwritten = _write(fd, buffer + done, len - done); + if (nwritten == -1 && errno == EINTR) + continue; + if (nwritten <= 0) + return (false); + done += nwritten; + } while (done != len); + return (true); +} + /* * we_askshell -- - * Use the `wordexp' /bin/sh builtin function to do most of the work - * in expanding the word string. This function is complicated by + * Use the `freebsd_wordexp' /bin/sh builtin function to do most of the + * work in expanding the word string. This function is complicated by * memory management. */ static int we_askshell(const char *words, wordexp_t *we, int flags) { - int pdes[2]; /* Pipe to child */ - char buf[18]; /* Buffer for byte and word count */ + int pdesw[2]; /* Pipe for writing words */ + int pdes[2]; /* Pipe for reading output */ + char wfdstr[sizeof(int) * 3 + 1]; + char buf[35]; /* Buffer for byte and word count */ long nwords, nbytes; /* Number of words, bytes from child */ long i; /* Handy integer */ size_t sofs; /* Offset into we->we_strings */ @@ -119,18 +140,25 @@ we_askshell(const char *words, wordexp_t *we, int flags) char **nwv; /* Temporary for realloc() */ sigset_t newsigblock, oldsigblock; const char *ifs; - char save; serrno = errno; ifs = getenv("IFS"); - if (pipe2(pdes, O_CLOEXEC) < 0) + if (pipe2(pdesw, O_CLOEXEC) < 0) + return (WRDE_NOSPACE); /* XXX */ + snprintf(wfdstr, sizeof(wfdstr), "%d", pdesw[0]); + if (pipe2(pdes, O_CLOEXEC) < 0) { + _close(pdesw[0]); + _close(pdesw[1]); return (WRDE_NOSPACE); /* XXX */ + } (void)sigemptyset(&newsigblock); (void)sigaddset(&newsigblock, SIGCHLD); (void)__libc_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); if ((pid = fork()) < 0) { serrno = errno; + _close(pdesw[0]); + _close(pdesw[1]); _close(pdes[0]); _close(pdes[1]); (void)__libc_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); @@ -146,43 +174,54 @@ we_askshell(const char *words, wordexp_t *we, int flags) _dup2(pdes[1], STDOUT_FILENO) : _fcntl(pdes[1], F_SETFD, 0)) < 0) _exit(1); + if (_fcntl(pdesw[0], F_SETFD, 0) < 0) + _exit(1); execl(_PATH_BSHELL, "sh", flags & WRDE_UNDEF ? "-u" : "+u", - "-c", "IFS=$1;eval \"$2\";eval \"echo;set -- $3\";" - "IFS=;a=\"$*\";printf '%08x' \"$#\" \"${#a}\";" - "printf '%s\\0' \"$@\"", + "-c", "IFS=$1;eval \"$2\";" + "freebsd_wordexp -f \"$3\" ${4:+\"$4\"}", "", ifs != NULL ? ifs : " \t\n", - flags & WRDE_SHOWERR ? "" : "exec 2>/dev/null", words, + flags & WRDE_SHOWERR ? "" : "exec 2>/dev/null", + wfdstr, + flags & WRDE_NOCMD ? "-p" : "", (char *)NULL); _exit(1); } /* - * We are the parent; read the output of the shell wordexp function, - * which is a byte indicating that the words were parsed successfully, - * a 32-bit hexadecimal word count, a 32-bit hexadecimal byte count - * (not including terminating null bytes), followed by the expanded - * words separated by nulls. + * We are the parent; write the words. */ _close(pdes[1]); - switch (we_read_fully(pdes[0], buf, 17)) { + _close(pdesw[0]); + if (!we_write_fully(pdesw[1], words, strlen(words))) { + _close(pdesw[1]); + error = WRDE_SYNTAX; + goto cleanup; + } + _close(pdesw[1]); + /* + * Read the output of the shell wordexp function, + * which is a byte indicating that the words were parsed successfully, + * a 64-bit hexadecimal word count, a dummy byte, a 64-bit hexadecimal + * byte count (not including terminating null bytes), followed by the + * expanded words separated by nulls. + */ + switch (we_read_fully(pdes[0], buf, 34)) { case 1: - error = WRDE_BADVAL; + error = buf[0] == 'C' ? WRDE_CMDSUB : WRDE_BADVAL; serrno = errno; goto cleanup; - case 17: + case 34: break; default: error = WRDE_SYNTAX; serrno = errno; goto cleanup; } - save = buf[9]; - buf[9] = '\0'; - nwords = strtol(buf + 1, NULL, 16); - buf[9] = save; buf[17] = '\0'; - nbytes = strtol(buf + 9, NULL, 16) + nwords; + nwords = strtol(buf + 1, NULL, 16); + buf[34] = '\0'; + nbytes = strtol(buf + 18, NULL, 16) + nwords; /* * Allocate or reallocate (when flags & WRDE_APPEND) the word vector @@ -255,83 +294,96 @@ cleanup: * we_check -- * Check that the string contains none of the following unquoted * special characters: <newline> |&;<>(){} - * or command substitutions when WRDE_NOCMD is set in flags. + * This mainly serves for {} which are normally legal in sh. + * It deliberately does not attempt to model full sh syntax. */ static int -we_check(const char *words, int flags) +we_check(const char *words) { char c; - int dquote, level, quote, squote; + /* Saw \ or $, possibly not special: */ + bool quote = false, dollar = false; + /* Saw ', ", ${, ` or $(, possibly not special: */ + bool have_sq = false, have_dq = false, have_par_begin = false; + bool have_cmd = false; + /* Definitely saw a ', ", ${, ` or $(, need a closing character: */ + bool need_sq = false, need_dq = false, need_par_end = false; + bool need_cmd_old = false, need_cmd_new = false; - quote = squote = dquote = 0; while ((c = *words++) != '\0') { switch (c) { case '\\': - if (squote == 0) - quote ^= 1; + quote = !quote; + continue; + case '$': + if (quote) + quote = false; + else + dollar = !dollar; continue; case '\'': - if (quote + dquote == 0) - squote ^= 1; + if (!quote && !have_sq && !have_dq) + need_sq = true; + else + need_sq = false; + have_sq = true; break; case '"': - if (quote + squote == 0) - dquote ^= 1; + if (!quote && !have_sq && !have_dq) + need_dq = true; + else + need_dq = false; + have_dq = true; break; case '`': - if (quote + squote == 0 && flags & WRDE_NOCMD) - return (WRDE_CMDSUB); - while ((c = *words++) != '\0' && c != '`') - if (c == '\\' && (c = *words++) == '\0') - break; - if (c == '\0') - return (WRDE_SYNTAX); + if (!quote && !have_sq && !have_cmd) + need_cmd_old = true; + else + need_cmd_old = false; + have_cmd = true; break; - case '|': case '&': case ';': case '<': case '>': - case '{': case '}': case '(': case ')': case '\n': - if (quote + squote + dquote == 0) + case '{': + if (!quote && !dollar && !have_sq && !have_dq && + !have_cmd) return (WRDE_BADCHAR); + if (dollar) { + if (!quote && !have_sq) + need_par_end = true; + have_par_begin = true; + } break; - case '$': - if ((c = *words++) == '\0') - break; - else if (quote + squote == 0 && c == '(') { - if (flags & WRDE_NOCMD && *words != '(') - return (WRDE_CMDSUB); - level = 1; - while ((c = *words++) != '\0') { - if (c == '\\') { - if ((c = *words++) == '\0') - break; - } else if (c == '(') - level++; - else if (c == ')' && --level == 0) - break; - } - if (c == '\0' || level != 0) - return (WRDE_SYNTAX); - } else if (quote + squote == 0 && c == '{') { - level = 1; - while ((c = *words++) != '\0') { - if (c == '\\') { - if ((c = *words++) == '\0') - break; - } else if (c == '{') - level++; - else if (c == '}' && --level == 0) - break; - } - if (c == '\0' || level != 0) - return (WRDE_SYNTAX); - } else - --words; + case '}': + if (!quote && !have_sq && !have_dq && !have_par_begin && + !have_cmd) + return (WRDE_BADCHAR); + need_par_end = false; + break; + case '(': + if (!quote && !dollar && !have_sq && !have_dq && + !have_cmd) + return (WRDE_BADCHAR); + if (dollar) { + if (!quote && !have_sq) + need_cmd_new = true; + have_cmd = true; + } + break; + case ')': + if (!quote && !have_sq && !have_dq && !have_cmd) + return (WRDE_BADCHAR); + need_cmd_new = false; + break; + case '|': case '&': case ';': case '<': case '>': case '\n': + if (!quote && !have_sq && !have_dq && !have_cmd) + return (WRDE_BADCHAR); break; default: break; } - quote = 0; + quote = dollar = false; } - if (quote + squote + dquote != 0) + if (quote || dollar || need_sq || need_dq || need_par_end || + need_cmd_old || need_cmd_new) return (WRDE_SYNTAX); return (0); diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index a4414fa..e4fe1b2 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -102,7 +102,7 @@ SYM_MAPS+= ${LIBC_SRCTOP}/sys/Symbol.map CLEANFILES+= ${SASM} ${SPSEUDO} .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" || \ - ${MACHINE_CPUARCH} == "powerpc" + ${MACHINE_CPUARCH} == "powerpc" || ${MACHINE_ARCH:Marmv6*} NOTE_GNU_STACK='\t.section .note.GNU-stack,"",%%progbits\n' .else NOTE_GNU_STACK='' diff --git a/lib/libc/tests/gen/posix_spawn/Makefile b/lib/libc/tests/gen/posix_spawn/Makefile index d2dfa54..f20bbd7 100644 --- a/lib/libc/tests/gen/posix_spawn/Makefile +++ b/lib/libc/tests/gen/posix_spawn/Makefile @@ -21,6 +21,8 @@ PROGS+= h_spawnattr SCRIPTS= h_nonexec SCRIPTS+= h_zero +CLEANFILES+= h_nonexec + .include "../../Makefile.netbsd-tests" h_zero: diff --git a/lib/libc/tests/stdio/fmemopen2_test.c b/lib/libc/tests/stdio/fmemopen2_test.c index d137780..9555173 100644 --- a/lib/libc/tests/stdio/fmemopen2_test.c +++ b/lib/libc/tests/stdio/fmemopen2_test.c @@ -97,6 +97,7 @@ ATF_TC_BODY(test_preexisting, tc) /* Close the FILE *. */ rc = fclose(fp); + ATF_REQUIRE(rc == 0); /* Check that the string was not modified after the first 4 bytes. */ ATF_REQUIRE(strcmp(str, str3) == 0); diff --git a/lib/libcompiler_rt/Makefile b/lib/libcompiler_rt/Makefile index dae1624..86daee4 100644 --- a/lib/libcompiler_rt/Makefile +++ b/lib/libcompiler_rt/Makefile @@ -233,7 +233,7 @@ SYMLINKS+=libcompiler_rt_p.a ${LIBDIR}/libgcc_p.a .endif .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" || \ - ${MACHINE_CPUARCH} == "powerpc" + ${MACHINE_CPUARCH} == "powerpc" || ${MACHINE_ARCH:Marmv6*} AFLAGS+=--noexecstack ACFLAGS+=-Wa,--noexecstack .endif diff --git a/lib/libcrypt/tests/Makefile.depend b/lib/libcrypt/tests/Makefile.depend index d0caca1..dd2539c 100644 --- a/lib/libcrypt/tests/Makefile.depend +++ b/lib/libcrypt/tests/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libcuse/Makefile.depend b/lib/libcuse/Makefile.depend index 441e1ee..0a2f351 100644 --- a/lib/libcuse/Makefile.depend +++ b/lib/libcuse/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libcxxrt/Makefile.depend.host b/lib/libcxxrt/Makefile.depend.host index 9f46a2f..971c379 100644 --- a/lib/libcxxrt/Makefile.depend.host +++ b/lib/libcxxrt/Makefile.depend.host @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ usr.bin/clang/clang \ diff --git a/lib/libevent/Makefile.depend b/lib/libevent/Makefile.depend index ccd19e5..18be76b 100644 --- a/lib/libevent/Makefile.depend +++ b/lib/libevent/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c index 3095e06..ae8b79d 100644 --- a/lib/libfetch/common.c +++ b/lib/libfetch/common.c @@ -495,7 +495,8 @@ fetch_ssl_get_numeric_addrinfo(const char *hostname, size_t len) hints.ai_protocol = 0; hints.ai_flags = AI_NUMERICHOST; /* port is not relevant for this purpose */ - getaddrinfo(host, "443", &hints, &res); + if (getaddrinfo(host, "443", &hints, &res) != 0) + res = NULL; free(host); return res; } diff --git a/lib/libgpib/Makefile.depend b/lib/libgpib/Makefile.depend index 4370d1e..3699b06 100644 --- a/lib/libgpib/Makefile.depend +++ b/lib/libgpib/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/BIG5/Makefile.depend b/lib/libiconv_modules/BIG5/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/BIG5/Makefile.depend +++ b/lib/libiconv_modules/BIG5/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/DECHanyu/Makefile.depend b/lib/libiconv_modules/DECHanyu/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/DECHanyu/Makefile.depend +++ b/lib/libiconv_modules/DECHanyu/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/EUC/Makefile.depend b/lib/libiconv_modules/EUC/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/EUC/Makefile.depend +++ b/lib/libiconv_modules/EUC/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/EUCTW/Makefile.depend b/lib/libiconv_modules/EUCTW/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/EUCTW/Makefile.depend +++ b/lib/libiconv_modules/EUCTW/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/GBK2K/Makefile.depend b/lib/libiconv_modules/GBK2K/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/GBK2K/Makefile.depend +++ b/lib/libiconv_modules/GBK2K/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/HZ/Makefile.depend b/lib/libiconv_modules/HZ/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/HZ/Makefile.depend +++ b/lib/libiconv_modules/HZ/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/ISO2022/Makefile.depend b/lib/libiconv_modules/ISO2022/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/ISO2022/Makefile.depend +++ b/lib/libiconv_modules/ISO2022/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/JOHAB/Makefile.depend b/lib/libiconv_modules/JOHAB/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/JOHAB/Makefile.depend +++ b/lib/libiconv_modules/JOHAB/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/MSKanji/Makefile.depend b/lib/libiconv_modules/MSKanji/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/MSKanji/Makefile.depend +++ b/lib/libiconv_modules/MSKanji/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/UES/Makefile.depend b/lib/libiconv_modules/UES/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/UES/Makefile.depend +++ b/lib/libiconv_modules/UES/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/UTF1632/Makefile.depend b/lib/libiconv_modules/UTF1632/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/UTF1632/Makefile.depend +++ b/lib/libiconv_modules/UTF1632/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/UTF7/Makefile.depend b/lib/libiconv_modules/UTF7/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/UTF7/Makefile.depend +++ b/lib/libiconv_modules/UTF7/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/UTF8/Makefile.depend b/lib/libiconv_modules/UTF8/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/UTF8/Makefile.depend +++ b/lib/libiconv_modules/UTF8/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/VIQR/Makefile.depend b/lib/libiconv_modules/VIQR/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/VIQR/Makefile.depend +++ b/lib/libiconv_modules/VIQR/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/ZW/Makefile.depend b/lib/libiconv_modules/ZW/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/ZW/Makefile.depend +++ b/lib/libiconv_modules/ZW/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/iconv_none/Makefile.depend b/lib/libiconv_modules/iconv_none/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/iconv_none/Makefile.depend +++ b/lib/libiconv_modules/iconv_none/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/iconv_std/Makefile.depend b/lib/libiconv_modules/iconv_std/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/iconv_std/Makefile.depend +++ b/lib/libiconv_modules/iconv_std/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/mapper_646/Makefile.depend b/lib/libiconv_modules/mapper_646/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/mapper_646/Makefile.depend +++ b/lib/libiconv_modules/mapper_646/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/mapper_none/Makefile.depend b/lib/libiconv_modules/mapper_none/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/mapper_none/Makefile.depend +++ b/lib/libiconv_modules/mapper_none/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/mapper_parallel/Makefile.depend b/lib/libiconv_modules/mapper_parallel/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/mapper_parallel/Makefile.depend +++ b/lib/libiconv_modules/mapper_parallel/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/mapper_serial/Makefile.depend b/lib/libiconv_modules/mapper_serial/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/mapper_serial/Makefile.depend +++ b/lib/libiconv_modules/mapper_serial/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/mapper_std/Makefile.depend b/lib/libiconv_modules/mapper_std/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/mapper_std/Makefile.depend +++ b/lib/libiconv_modules/mapper_std/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libiconv_modules/mapper_zone/Makefile.depend b/lib/libiconv_modules/mapper_zone/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libiconv_modules/mapper_zone/Makefile.depend +++ b/lib/libiconv_modules/mapper_zone/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libmilter/Makefile.depend b/lib/libmilter/Makefile.depend index 17c2027..f78862e 100644 --- a/lib/libmilter/Makefile.depend +++ b/lib/libmilter/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/librpcsec_gss/Makefile.depend b/lib/librpcsec_gss/Makefile.depend index b376142..a352749 100644 --- a/lib/librpcsec_gss/Makefile.depend +++ b/lib/librpcsec_gss/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libsmb/Makefile.depend b/lib/libsmb/Makefile.depend index 441168d..4d66c46 100644 --- a/lib/libsmb/Makefile.depend +++ b/lib/libsmb/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libstand/Makefile.depend b/lib/libstand/Makefile.depend index bb85bcd..57cd80c 100644 --- a/lib/libstand/Makefile.depend +++ b/lib/libstand/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/arpa \ diff --git a/lib/libstdbuf/Makefile.depend b/lib/libstdbuf/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libstdbuf/Makefile.depend +++ b/lib/libstdbuf/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libstdthreads/Makefile.depend b/lib/libstdthreads/Makefile.depend index 441e1ee..0a2f351 100644 --- a/lib/libstdthreads/Makefile.depend +++ b/lib/libstdthreads/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libugidfw/ugidfw.c b/lib/libugidfw/ugidfw.c index a1e36d2..e533d1e 100644 --- a/lib/libugidfw/ugidfw.c +++ b/lib/libugidfw/ugidfw.c @@ -1233,7 +1233,7 @@ bsde_delete_rule(int rulenum, size_t buflen, char *errstr) name[len] = rulenum; len++; - error = sysctl(name, len, NULL, NULL, &rule, sizeof(rule)); + error = sysctl(name, len, NULL, NULL, &rule, 0); if (error) { len = snprintf(errstr, buflen, "%s.%d: %s", MIB ".rules", rulenum, strerror(errno)); diff --git a/lib/libunbound/Makefile.depend b/lib/libunbound/Makefile.depend index 45199c4..9ae472e 100644 --- a/lib/libunbound/Makefile.depend +++ b/lib/libunbound/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/libvgl/Makefile.depend b/lib/libvgl/Makefile.depend index 09164c1..dde2d60 100644 --- a/lib/libvgl/Makefile.depend +++ b/lib/libvgl/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/ncurses/form/Makefile.depend b/lib/ncurses/form/Makefile.depend index fc0fd0c..e753747 100644 --- a/lib/ncurses/form/Makefile.depend +++ b/lib/ncurses/form/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/ncurses/formw/Makefile.depend b/lib/ncurses/formw/Makefile.depend index 04d041a4..1448c10 100644 --- a/lib/ncurses/formw/Makefile.depend +++ b/lib/ncurses/formw/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/ncurses/menu/Makefile.depend b/lib/ncurses/menu/Makefile.depend index cb8d80b..7dbcb2b 100644 --- a/lib/ncurses/menu/Makefile.depend +++ b/lib/ncurses/menu/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/ncurses/menuw/Makefile.depend b/lib/ncurses/menuw/Makefile.depend index 771e004..0ffbc9b 100644 --- a/lib/ncurses/menuw/Makefile.depend +++ b/lib/ncurses/menuw/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ diff --git a/lib/ncurses/ncurses/Makefile b/lib/ncurses/ncurses/Makefile index fe68a39..94fb03a 100644 --- a/lib/ncurses/ncurses/Makefile +++ b/lib/ncurses/ncurses/Makefile @@ -282,6 +282,7 @@ CFLAGS+= -DFREEBSD_NATIVE -DTERMIOS # Installed HEADERS= curses.h term.h termcap.h unctrl.h SRCHDRS= ncurses_dll.h +CLEANFILES+= ncurses_dll.h .if defined(ENABLE_WIDEC) INCS= ${HEADERS} ${SRCHDRS} diff --git a/libexec/bootpd/Makefile.depend b/libexec/bootpd/Makefile.depend index 74de0b1..e0030e3 100644 --- a/libexec/bootpd/Makefile.depend +++ b/libexec/bootpd/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/libexec/rtld-elf/arm/rtld_start.S b/libexec/rtld-elf/arm/rtld_start.S index c482808..431ea48 100644 --- a/libexec/rtld-elf/arm/rtld_start.S +++ b/libexec/rtld-elf/arm/rtld_start.S @@ -97,3 +97,4 @@ _rtld_bind_start: ldmia sp!,{r0-r5,sl,fp,lr} /* restore the stack */ mov pc, ip /* jump to the new address */ + .section .note.GNU-stack,"",%progbits diff --git a/release/arm/BANANAPI.conf b/release/arm/BANANAPI.conf new file mode 100644 index 0000000..d304b8d --- /dev/null +++ b/release/arm/BANANAPI.conf @@ -0,0 +1,43 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +EMBEDDEDBUILD=1 +EMBEDDED_TARGET="arm" +EMBEDDED_TARGET_ARCH="armv6" +EMBEDDEDPORTS="sysutils/u-boot-bananapi" +KERNEL="A20" +WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x42000000" +IMAGE_SIZE="1G" +PART_SCHEME="MBR" +FAT_SIZE="32m -b 1m" +FAT_TYPE="16" +MD_ARGS="-x 63 -y 255" +NODOC=1 +export BOARDNAME="BANANAPI" + +arm_install_uboot() { + UBOOT_DIR="/usr/local/share/u-boot/u-boot-bananapi" + UBOOT_FILES="u-boot.img" + FATMOUNT="${DESTDIR%${KERNEL}}/fat" + UFSMOUNT="${DESTDIR%${KERNEL}}/ufs" + chroot ${CHROOTDIR} dd if=${UBOOT_DIR}/sunxi-spl.bin \ + of=/dev/${mddev} bs=1k seek=8 + chroot ${CHROOTDIR} dd if=${UBOOT_DIR}/${UBOOT_FILES} \ + of=/dev/${mddev} bs=1k seek=40 conv=notrunc,sync + chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}" + chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT} + chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT} + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \ + ${FATMOUNT}/ubldr.bin + chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot + sync + umount_loop ${CHROOTDIR}/${FATMOUNT} + umount_loop ${CHROOTDIR}/${UFSMOUNT} + chroot ${CHROOTDIR} rmdir ${FATMOUNT} + chroot ${CHROOTDIR} rmdir ${UFSMOUNT} + + return 0 +} diff --git a/release/arm/BEAGLEBONE.conf b/release/arm/BEAGLEBONE.conf index 4fcb07d..f9bb162 100644 --- a/release/arm/BEAGLEBONE.conf +++ b/release/arm/BEAGLEBONE.conf @@ -26,6 +26,8 @@ arm_install_uboot() { chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/MLO ${FATMOUNT}/MLO chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/u-boot.img ${FATMOUNT}/u-boot.img chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \ + ${FATMOUNT}/ubldr.bin chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot sync umount_loop ${CHROOTDIR}/${FATMOUNT} diff --git a/release/arm/CUBIEBOARD.conf b/release/arm/CUBIEBOARD.conf new file mode 100644 index 0000000..94b53a7 --- /dev/null +++ b/release/arm/CUBIEBOARD.conf @@ -0,0 +1,42 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +EMBEDDEDBUILD=1 +EMBEDDED_TARGET="arm" +EMBEDDED_TARGET_ARCH="armv6" +EMBEDDEDPORTS="sysutils/u-boot-cubieboard" +KERNEL="CUBIEBOARD" +WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x42000000" +IMAGE_SIZE="1G" +PART_SCHEME="MBR" +FAT_SIZE="32m -b 1m" +FAT_TYPE="16" +MD_ARGS="-x 63 -y 255" +NODOC=1 + +arm_install_uboot() { + UBOOT_DIR="/usr/local/share/u-boot/u-boot-cubieboard" + UBOOT_FILES="u-boot.img" + FATMOUNT="${DESTDIR%${KERNEL}}/fat" + UFSMOUNT="${DESTDIR%${KERNEL}}/ufs" + chroot ${CHROOTDIR} dd if=${UBOOT_DIR}/sunxi-spl.bin \ + of=/dev/${mddev} bs=1k seek=8 + chroot ${CHROOTDIR} dd if=${UBOOT_DIR}/${UBOOT_FILES} \ + of=/dev/${mddev} bs=1k seek=40 conv=notrunc,sync + chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}" + chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT} + chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT} + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \ + ${FATMOUNT}/ubldr.bin + chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot + sync + umount_loop ${CHROOTDIR}/${FATMOUNT} + umount_loop ${CHROOTDIR}/${UFSMOUNT} + chroot ${CHROOTDIR} rmdir ${FATMOUNT} + chroot ${CHROOTDIR} rmdir ${UFSMOUNT} + + return 0 +} diff --git a/release/arm/CUBIEBOARD2.conf b/release/arm/CUBIEBOARD2.conf new file mode 100644 index 0000000..c118c34 --- /dev/null +++ b/release/arm/CUBIEBOARD2.conf @@ -0,0 +1,43 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +EMBEDDEDBUILD=1 +EMBEDDED_TARGET="arm" +EMBEDDED_TARGET_ARCH="armv6" +EMBEDDEDPORTS="sysutils/u-boot-cubieboard2" +KERNEL="A20" +WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x42000000" +IMAGE_SIZE="1G" +PART_SCHEME="MBR" +FAT_SIZE="32m -b 1m" +FAT_TYPE="16" +MD_ARGS="-x 63 -y 255" +NODOC=1 +export BOARDNAME="CUBIEBOARD2" + +arm_install_uboot() { + UBOOT_DIR="/usr/local/share/u-boot/u-boot-cubieboard2" + UBOOT_FILES="u-boot.img" + FATMOUNT="${DESTDIR%${KERNEL}}/fat" + UFSMOUNT="${DESTDIR%${KERNEL}}/ufs" + chroot ${CHROOTDIR} dd if=${UBOOT_DIR}/sunxi-spl.bin \ + of=/dev/${mddev} bs=1k seek=8 + chroot ${CHROOTDIR} dd if=${UBOOT_DIR}/${UBOOT_FILES} \ + of=/dev/${mddev} bs=1k seek=40 conv=notrunc,sync + chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}" + chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT} + chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT} + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \ + ${FATMOUNT}/ubldr.bin + chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot + sync + umount_loop ${CHROOTDIR}/${FATMOUNT} + umount_loop ${CHROOTDIR}/${UFSMOUNT} + chroot ${CHROOTDIR} rmdir ${FATMOUNT} + chroot ${CHROOTDIR} rmdir ${UFSMOUNT} + + return 0 +} diff --git a/release/arm/CUBOX-HUMMINGBOARD.conf b/release/arm/CUBOX-HUMMINGBOARD.conf index 79e9389..d69ca8e 100644 --- a/release/arm/CUBOX-HUMMINGBOARD.conf +++ b/release/arm/CUBOX-HUMMINGBOARD.conf @@ -28,6 +28,8 @@ arm_install_uboot() { chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT} chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT} chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \ + ${FATMOUNT}/ubldr.bin chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot sync umount_loop ${CHROOTDIR}/${FATMOUNT} diff --git a/release/arm/GUMSTIX.conf b/release/arm/GUMSTIX.conf index 6812a5f..38445b1 100644 --- a/release/arm/GUMSTIX.conf +++ b/release/arm/GUMSTIX.conf @@ -26,6 +26,8 @@ arm_install_uboot() { chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/MLO ${FATMOUNT}/MLO chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/u-boot.img ${FATMOUNT}/u-boot.img chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \ + ${FATMOUNT}/ubldr.bin chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot sync umount_loop ${CHROOTDIR}/${FATMOUNT} diff --git a/release/arm/PANDABOARD.conf b/release/arm/PANDABOARD.conf index 6b75566..0b238df 100644 --- a/release/arm/PANDABOARD.conf +++ b/release/arm/PANDABOARD.conf @@ -26,6 +26,8 @@ arm_install_uboot() { chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/MLO ${FATMOUNT}/MLO chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/u-boot.img ${FATMOUNT}/u-boot.img chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \ + ${FATMOUNT}/ubldr.bin chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot sync umount_loop ${CHROOTDIR}/${FATMOUNT} diff --git a/release/arm/RPI-B.conf b/release/arm/RPI-B.conf index e5abaab..b97b7d0 100644 --- a/release/arm/RPI-B.conf +++ b/release/arm/RPI-B.conf @@ -30,6 +30,8 @@ arm_install_uboot() { ${FATMOUNT}/${_UF} done chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \ + ${FATMOUNT}/ubldr.bin chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/dtb/rpi.dtb \ ${FATMOUNT}/rpi.dtb chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot diff --git a/release/arm/RPI2.conf b/release/arm/RPI2.conf index 2da7e96..886a5aa 100644 --- a/release/arm/RPI2.conf +++ b/release/arm/RPI2.conf @@ -30,6 +30,8 @@ arm_install_uboot() { ${FATMOUNT}/${_UF} done chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \ + ${FATMOUNT}/ubldr.bin chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/dtb/rpi2.dtb \ ${FATMOUNT}/rpi2.dtb chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot diff --git a/release/arm/WANDBOARD.conf b/release/arm/WANDBOARD.conf index 4033d09..1afdc72 100644 --- a/release/arm/WANDBOARD.conf +++ b/release/arm/WANDBOARD.conf @@ -28,6 +28,8 @@ arm_install_uboot() { chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT} chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT} chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \ + ${FATMOUNT}/ubldr.bin chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot sync umount_loop ${CHROOTDIR}/${FATMOUNT} diff --git a/release/doc/en_US.ISO8859-1/hardware/article.xml b/release/doc/en_US.ISO8859-1/hardware/article.xml index 23f78ee..191ac57 100644 --- a/release/doc/en_US.ISO8859-1/hardware/article.xml +++ b/release/doc/en_US.ISO8859-1/hardware/article.xml @@ -1011,6 +1011,8 @@ <para>Marvell 88W8363 IEEE 802.11n wireless network adapters (&man.mwl.4; driver)</para> + &hwlist.otus; + &hwlist.ral; &hwlist.rsu; diff --git a/release/doc/share/misc/dev.archlist.txt b/release/doc/share/misc/dev.archlist.txt index 6872ec0..5f62f48 100644 --- a/release/doc/share/misc/dev.archlist.txt +++ b/release/doc/share/misc/dev.archlist.txt @@ -101,6 +101,7 @@ nxge i386,amd64 oce i386,amd64 ohci i386,pc98,amd64,powerpc oltr i386 +otus i386,amd64 pcn i386,pc98,amd64 pst i386 qlxgb amd64 diff --git a/release/release.sh b/release/release.sh index 94a9bb6..e168422 100755 --- a/release/release.sh +++ b/release/release.sh @@ -311,6 +311,18 @@ chroot_build_target() { # chroot_build_release(): Invoke the 'make release' target. chroot_build_release() { load_target_env + if [ ! -z "${WITH_VMIMAGES}" ]; then + if [ -z "${VMFORMATS}" ]; then + VMFORMATS="$(eval chroot ${CHROOTDIR} \ + make -C /usr/src/release -V VMFORMATS)" + fi + if [ -z "${VMSIZE}" ]; then + VMSIZE="$(eval chroot ${CHROOTDIR} \ + make -C /usr/src/release -V VMSIZE)" + fi + RELEASE_RMAKEFLAGS="${RELEASE_RMAKEFLAGS} \ + VMFORMATS=\"${VMFORMATS}\" VMSIZE=${VMSIZE}" + fi eval chroot ${CHROOTDIR} make -C /usr/src/release \ ${RELEASE_RMAKEFLAGS} release eval chroot ${CHROOTDIR} make -C /usr/src/release \ diff --git a/release/tools/vmimage.subr b/release/tools/vmimage.subr index 262e245b..b5a8bf7 100644 --- a/release/tools/vmimage.subr +++ b/release/tools/vmimage.subr @@ -108,7 +108,7 @@ vm_copy_base() { umount_loop /dev/${mdnew} rmdir ${DESTDIR}/new - tunefs -j enable /dev/${mdnew} + tunefs -n enable /dev/${mdnew} mdconfig -d -u ${mdnew} mv ${VMBASE}.tmp ${VMBASE} } diff --git a/rescue/librescue/Makefile.depend b/rescue/librescue/Makefile.depend index 479669f..a3f06d6 100644 --- a/rescue/librescue/Makefile.depend +++ b/rescue/librescue/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ include \ include/arpa \ diff --git a/sbin/fdisk_pc98/Makefile.depend b/sbin/fdisk_pc98/Makefile.depend index 4c7271b..2df49d0 100644 --- a/sbin/fdisk_pc98/Makefile.depend +++ b/sbin/fdisk_pc98/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/sbin/ifconfig/af_inet6.c b/sbin/ifconfig/af_inet6.c index 6dd8622..95f2b2d 100644 --- a/sbin/ifconfig/af_inet6.c +++ b/sbin/ifconfig/af_inet6.c @@ -521,7 +521,6 @@ static struct option in6_Lopt = { static __constructor void inet6_ctor(void) { -#define N(a) (sizeof(a) / sizeof(a[0])) size_t i; #ifndef RESCUE @@ -529,9 +528,8 @@ inet6_ctor(void) return; #endif - for (i = 0; i < N(inet6_cmds); i++) + for (i = 0; i < nitems(inet6_cmds); i++) cmd_register(&inet6_cmds[i]); af_register(&af_inet6); opt_register(&in6_Lopt); -#undef N } diff --git a/sbin/ifconfig/carp.c b/sbin/ifconfig/carp.c index adff153..2a2ee47 100644 --- a/sbin/ifconfig/carp.c +++ b/sbin/ifconfig/carp.c @@ -217,11 +217,9 @@ static struct afswtch af_carp = { static __constructor void carp_ctor(void) { -#define N(a) (sizeof(a) / sizeof(a[0])) int i; - for (i = 0; i < N(carp_cmds); i++) + for (i = 0; i < nitems(carp_cmds); i++) cmd_register(&carp_cmds[i]); af_register(&af_carp); -#undef N } diff --git a/sbin/ifconfig/ifbridge.c b/sbin/ifconfig/ifbridge.c index 65c3317..7758e21 100644 --- a/sbin/ifconfig/ifbridge.c +++ b/sbin/ifconfig/ifbridge.c @@ -749,11 +749,9 @@ static struct afswtch af_bridge = { static __constructor void bridge_ctor(void) { -#define N(a) (sizeof(a) / sizeof(a[0])) int i; - for (i = 0; i < N(bridge_cmds); i++) + for (i = 0; i < nitems(bridge_cmds); i++) cmd_register(&bridge_cmds[i]); af_register(&af_bridge); -#undef N } diff --git a/sbin/ifconfig/ifclone.c b/sbin/ifconfig/ifclone.c index 1ce92c8..6a60d41 100644 --- a/sbin/ifconfig/ifclone.c +++ b/sbin/ifconfig/ifclone.c @@ -32,9 +32,9 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ -#include <sys/queue.h> -#include <sys/types.h> +#include <sys/param.h> #include <sys/ioctl.h> +#include <sys/queue.h> #include <sys/socket.h> #include <net/if.h> @@ -184,11 +184,9 @@ static struct option clone_Copt = { .opt = "C", .opt_usage = "[-C]", .cb = clone static __constructor void clone_ctor(void) { -#define N(a) (sizeof(a) / sizeof(a[0])) size_t i; - for (i = 0; i < N(clone_cmds); i++) + for (i = 0; i < nitems(clone_cmds); i++) cmd_register(&clone_cmds[i]); opt_register(&clone_Copt); -#undef N } diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 52de660..0018b5c 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -43,11 +43,11 @@ static const char rcsid[] = #include <sys/param.h> #include <sys/ioctl.h> -#include <sys/socket.h> -#include <sys/time.h> #include <sys/module.h> #include <sys/linker.h> #include <sys/queue.h> +#include <sys/socket.h> +#include <sys/time.h> #include <net/ethernet.h> #include <net/if.h> @@ -604,7 +604,6 @@ cmd_register(struct cmd *p) static const struct cmd * cmd_lookup(const char *name, int iscreate) { -#define N(a) (sizeof(a)/sizeof(a[0])) const struct cmd *p; for (p = cmds; p != NULL; p = p->c_next) @@ -618,7 +617,6 @@ cmd_lookup(const char *name, int iscreate) } } return NULL; -#undef N } struct callback { @@ -1387,10 +1385,8 @@ static struct cmd basic_cmds[] = { static __constructor void ifconfig_ctor(void) { -#define N(a) (sizeof(a) / sizeof(a[0])) size_t i; - for (i = 0; i < N(basic_cmds); i++) + for (i = 0; i < nitems(basic_cmds); i++) cmd_register(&basic_cmds[i]); -#undef N } diff --git a/sbin/ifconfig/iffib.c b/sbin/ifconfig/iffib.c index 07ded3c..f54eab7 100644 --- a/sbin/ifconfig/iffib.c +++ b/sbin/ifconfig/iffib.c @@ -113,11 +113,9 @@ static struct afswtch af_fib = { static __constructor void fib_ctor(void) { -#define N(a) (sizeof(a) / sizeof(a[0])) size_t i; - for (i = 0; i < N(fib_cmds); i++) + for (i = 0; i < nitems(fib_cmds); i++) cmd_register(&fib_cmds[i]); af_register(&af_fib); -#undef N } diff --git a/sbin/ifconfig/ifgre.c b/sbin/ifconfig/ifgre.c index 3ac7454..98d1bf6 100644 --- a/sbin/ifconfig/ifgre.c +++ b/sbin/ifconfig/ifgre.c @@ -113,11 +113,9 @@ static struct afswtch af_gre = { static __constructor void gre_ctor(void) { -#define N(a) (sizeof(a) / sizeof(a[0])) size_t i; - for (i = 0; i < N(gre_cmds); i++) + for (i = 0; i < nitems(gre_cmds); i++) cmd_register(&gre_cmds[i]); af_register(&af_gre); -#undef N } diff --git a/sbin/ifconfig/ifgroup.c b/sbin/ifconfig/ifgroup.c index e3f271d..d12c5fb 100644 --- a/sbin/ifconfig/ifgroup.c +++ b/sbin/ifconfig/ifgroup.c @@ -28,7 +28,7 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ -#include <sys/types.h> +#include <sys/param.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <net/if.h> @@ -174,12 +174,10 @@ static struct option group_gopt = { "g:", "[-g groupname]", printgroup }; static __constructor void group_ctor(void) { -#define N(a) (sizeof(a) / sizeof(a[0])) int i; - for (i = 0; i < N(group_cmds); i++) + for (i = 0; i < nitems(group_cmds); i++) cmd_register(&group_cmds[i]); af_register(&af_group); opt_register(&group_gopt); -#undef N } diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c index d0b4917..accb175 100644 --- a/sbin/ifconfig/ifieee80211.c +++ b/sbin/ifconfig/ifieee80211.c @@ -2856,7 +2856,6 @@ printrsnie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) static void printwpsie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) { -#define N(a) (sizeof(a) / sizeof(a[0])) u_int8_t len = ie[1]; printf("%s", tag); @@ -2897,7 +2896,7 @@ printwpsie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) break; case IEEE80211_WPS_DEV_PASS_ID: n = LE_READ_2(ie); - if (n < N(dev_pass_id)) + if (n < nitems(dev_pass_id)) printf(" dpi:%s", dev_pass_id[n]); break; case IEEE80211_WPS_UUID_E: @@ -2911,7 +2910,6 @@ printwpsie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) } printf(">"); } -#undef N } static void @@ -3418,7 +3416,6 @@ list_stations(int s) static const char * mesh_linkstate_string(uint8_t state) { -#define N(a) (sizeof(a) / sizeof(a[0])) static const char *state_names[] = { [0] = "IDLE", [1] = "OPEN-TX", @@ -3428,13 +3425,12 @@ mesh_linkstate_string(uint8_t state) [5] = "HOLDING", }; - if (state >= N(state_names)) { + if (state >= nitems(state_names)) { static char buf[10]; snprintf(buf, sizeof(buf), "#%u", state); return buf; } else return state_names[state]; -#undef N } static const char * @@ -5320,12 +5316,10 @@ static struct afswtch af_ieee80211 = { static __constructor void ieee80211_ctor(void) { -#define N(a) (sizeof(a) / sizeof(a[0])) int i; - for (i = 0; i < N(ieee80211_cmds); i++) + for (i = 0; i < nitems(ieee80211_cmds); i++) cmd_register(&ieee80211_cmds[i]); af_register(&af_ieee80211); clone_setdefcallback("wlan", wlan_create); -#undef N } diff --git a/sbin/ifconfig/iflagg.c b/sbin/ifconfig/iflagg.c index c595dc9..97b42e3 100644 --- a/sbin/ifconfig/iflagg.c +++ b/sbin/ifconfig/iflagg.c @@ -308,11 +308,9 @@ static struct afswtch af_lagg = { static __constructor void lagg_ctor(void) { -#define N(a) (sizeof(a) / sizeof(a[0])) int i; - for (i = 0; i < N(lagg_cmds); i++) + for (i = 0; i < nitems(lagg_cmds); i++) cmd_register(&lagg_cmds[i]); af_register(&af_lagg); -#undef N } diff --git a/sbin/ifconfig/ifmac.c b/sbin/ifconfig/ifmac.c index d7e1e5b..a8bef81 100644 --- a/sbin/ifconfig/ifmac.c +++ b/sbin/ifconfig/ifmac.c @@ -111,11 +111,9 @@ static struct afswtch af_mac = { static __constructor void mac_ctor(void) { -#define N(a) (sizeof(a) / sizeof(a[0])) size_t i; - for (i = 0; i < N(mac_cmds); i++) + for (i = 0; i < nitems(mac_cmds); i++) cmd_register(&mac_cmds[i]); af_register(&af_mac); -#undef N } diff --git a/sbin/ifconfig/ifmedia.c b/sbin/ifconfig/ifmedia.c index eee3391..f1c7752 100644 --- a/sbin/ifconfig/ifmedia.c +++ b/sbin/ifconfig/ifmedia.c @@ -845,11 +845,9 @@ static struct afswtch af_media = { static __constructor void ifmedia_ctor(void) { -#define N(a) (sizeof(a) / sizeof(a[0])) size_t i; - for (i = 0; i < N(media_cmds); i++) + for (i = 0; i < nitems(media_cmds); i++) cmd_register(&media_cmds[i]); af_register(&af_media); -#undef N } diff --git a/sbin/ifconfig/ifpfsync.c b/sbin/ifconfig/ifpfsync.c index 0af89e2..9dbe1d6 100644 --- a/sbin/ifconfig/ifpfsync.c +++ b/sbin/ifconfig/ifpfsync.c @@ -26,7 +26,7 @@ * $FreeBSD$ */ -#include <sys/types.h> +#include <sys/param.h> #include <sys/ioctl.h> #include <sys/socket.h> @@ -227,11 +227,9 @@ static struct afswtch af_pfsync = { static __constructor void pfsync_ctor(void) { -#define N(a) (sizeof(a) / sizeof(a[0])) int i; - for (i = 0; i < N(pfsync_cmds); i++) + for (i = 0; i < nitems(pfsync_cmds); i++) cmd_register(&pfsync_cmds[i]); af_register(&af_pfsync); -#undef N } diff --git a/sbin/ifconfig/ifvlan.c b/sbin/ifconfig/ifvlan.c index 1a3fbaa..107b87b 100644 --- a/sbin/ifconfig/ifvlan.c +++ b/sbin/ifconfig/ifvlan.c @@ -194,13 +194,11 @@ static struct afswtch af_vlan = { static __constructor void vlan_ctor(void) { -#define N(a) (sizeof(a) / sizeof(a[0])) size_t i; - for (i = 0; i < N(vlan_cmds); i++) + for (i = 0; i < nitems(vlan_cmds); i++) cmd_register(&vlan_cmds[i]); af_register(&af_vlan); callback_register(vlan_cb, NULL); clone_setdefcallback("vlan", vlan_create); -#undef N } diff --git a/sbin/ifconfig/ifvxlan.c b/sbin/ifconfig/ifvxlan.c index 48f5331..91c2538 100644 --- a/sbin/ifconfig/ifvxlan.c +++ b/sbin/ifconfig/ifvxlan.c @@ -635,13 +635,11 @@ static struct afswtch af_vxlan = { static __constructor void vxlan_ctor(void) { -#define N(a) (sizeof(a) / sizeof(a[0])) size_t i; - for (i = 0; i < N(vxlan_cmds); i++) + for (i = 0; i < nitems(vxlan_cmds); i++) cmd_register(&vxlan_cmds[i]); af_register(&af_vxlan); callback_register(vxlan_cb, NULL); clone_setdefcallback("vxlan", vxlan_create); -#undef N } diff --git a/sbin/init/init.c b/sbin/init/init.c index 5ab3527..edc38e6 100644 --- a/sbin/init/init.c +++ b/sbin/init/init.c @@ -1487,6 +1487,15 @@ static state_func_t death(void) { session_t *sp; + int block, blocked; + size_t len; + + /* Temporarily block suspend. */ + len = sizeof(blocked); + block = 1; + if (sysctlbyname("kern.suspend_blocked", &blocked, &len, + &block, sizeof(block)) == -1) + blocked = 0; /* * Also revoke the TTY here. Because runshutdown() may reopen @@ -1503,6 +1512,11 @@ death(void) /* Try to run the rc.shutdown script within a period of time */ runshutdown(); + /* Unblock suspend if we blocked it. */ + if (!blocked) + sysctlbyname("kern.suspend_blocked", NULL, NULL, + &blocked, sizeof(blocked)); + return (state_func_t) death_single; } diff --git a/sbin/ipf/Makefile b/sbin/ipf/Makefile index df57c80..8b10c98 100644 --- a/sbin/ipf/Makefile +++ b/sbin/ipf/Makefile @@ -1,8 +1,7 @@ # $FreeBSD$ -#.WAIT -SUBDIR= libipf +SUBDIR= libipf .WAIT SUBDIR+= ipf ipfs ipfstat ipftest ipmon ipnat ippool ipresend -#SUBDIR+= ipsend iptest rules +SUBDIR_PARALLEL= .include <bsd.subdir.mk> diff --git a/sbin/ipf/ipsend/Makefile b/sbin/ipf/ipsend/Makefile deleted file mode 100644 index 176cb10..0000000 --- a/sbin/ipf/ipsend/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# $FreeBSD$ - -NOGCCERROR= # defined - -.include <bsd.own.mk> - -PROG= ipsend -SRCS= ipsend.c ip.c ipsopt.c iplang_y.c iplang_l.l sbpf.c \ - sock.c 44arp.c -MAN= ipsend.1 ipsend.5 -LIBADD+= l - -CFLAGS+= -I${NETBSDSRCDIR}/dist/ipf/ipsend -CFLAGS+= -I${NETBSDSRCDIR}/dist/ipf/iplang -CFLAGS+= -I. - -CLEANFILES+= iplang_y.c iplang_y.h - -DPSRCS+= iplang_y.h - -.PATH: ${NETBSDSRCDIR}/dist/ipf/ipsend \ - ${NETBSDSRCDIR}/dist/ipf/iplang - -iplang_y.c: iplang_y.y - ${YACC} -d ${.ALLSRC} - mv y.tab.c ${.TARGET} - mv y.tab.h ${.TARGET:.c=.h} - -iplang_y.h: iplang_y.c - -# XXX -# We have a problem with make and linking ipsend -# cc -o /home/source/src/usr.sbin/ipf/ipsend/../../../dist/ipf/ipsend ..... -# isn't correct. -# Use .NOPATH as an workaround for that problem -.NOPATH: ipsend - -.include <bsd.prog.mk> diff --git a/sbin/ipf/iptest/Makefile b/sbin/ipf/iptest/Makefile deleted file mode 100644 index 647471c..0000000 --- a/sbin/ipf/iptest/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# $FreeBSD$ - -.include <bsd.own.mk> - -PROG= iptest -SRCS= iptest.c iptests.c ip.c sbpf.c sock.c 44arp.c -MAN= iptest.1 - -.PATH: ${NETBSDSRCDIR}/dist/ipf/ipsend - -.include <bsd.prog.mk> diff --git a/sbin/ipf/rules/Makefile b/sbin/ipf/rules/Makefile deleted file mode 100644 index a90907f..0000000 --- a/sbin/ipf/rules/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ - -.include <bsd.own.mk> - -MAN= mkfilters.1 -.if ${MKSHARE} != "no" -FILESDIR= /usr/share/examples/ipf - -FILES= BASIC.NAT BASIC_1.FW BASIC_2.FW example.1 example.2 example.3 \ - example.4 example.5 example.6 example.7 example.8 example.9 \ - example.10 example.11 example.12 example.13 example.sr \ - firewall ftp-proxy ftppxy mediaone nat-setup \ - nat.eg server tcpstate mkfilters -.endif - -.PATH: ${NETBSDSRCDIR}/dist/ipf/rules -.include <bsd.prog.mk> diff --git a/sbin/natd/natd.c b/sbin/natd/natd.c index 959e1ee..4d9061d 100644 --- a/sbin/natd/natd.c +++ b/sbin/natd/natd.c @@ -124,7 +124,7 @@ static void StrToAddr (const char* str, struct in_addr* addr); static u_short StrToPort (const char* str, const char* proto); static int StrToPortRange (const char* str, const char* proto, port_range *portRange); static int StrToProto (const char* str); -static int StrToAddrAndPortRange (const char* str, struct in_addr* addr, char* proto, port_range *portRange); +static int StrToAddrAndPortRange (char* str, struct in_addr* addr, char* proto, port_range *portRange); static void ParseArgs (int argc, char** argv); static void SetupPunchFW(const char *strValue); static void SetupSkinnyPort(const char *strValue); @@ -1896,7 +1896,7 @@ u_short StrToPort (const char* str, const char* proto) int StrToPortRange (const char* str, const char* proto, port_range *portRange) { - char* sep; + const char* sep; struct servent* sp; char* end; u_short loPort; @@ -1938,7 +1938,8 @@ int StrToPortRange (const char* str, const char* proto, port_range *portRange) } -int StrToProto (const char* str) +static int +StrToProto (const char* str) { if (!strcmp (str, "tcp")) return IPPROTO_TCP; @@ -1949,7 +1950,8 @@ int StrToProto (const char* str) errx (1, "unknown protocol %s. Expected tcp or udp", str); } -int StrToAddrAndPortRange (const char* str, struct in_addr* addr, char* proto, port_range *portRange) +static int +StrToAddrAndPortRange (char* str, struct in_addr* addr, char* proto, port_range *portRange) { char* ptr; diff --git a/sbin/routed/Makefile.depend b/sbin/routed/Makefile.depend index 9807567d..d734286 100644 --- a/sbin/routed/Makefile.depend +++ b/sbin/routed/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/sbin/sconfig/Makefile.depend b/sbin/sconfig/Makefile.depend index f52ca95..79eb58b 100644 --- a/sbin/sconfig/Makefile.depend +++ b/sbin/sconfig/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/sbin/sunlabel/Makefile.depend b/sbin/sunlabel/Makefile.depend index 4c7271b..2df49d0 100644 --- a/sbin/sunlabel/Makefile.depend +++ b/sbin/sunlabel/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/share/doc/legal/realtek/Makefile.depend b/share/doc/legal/realtek/Makefile.depend index d14a02b..f80275d 100644 --- a/share/doc/legal/realtek/Makefile.depend +++ b/share/doc/legal/realtek/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ diff --git a/share/doc/llvm/Makefile.depend b/share/doc/llvm/Makefile.depend index 3af2d7f..f80275d 100644 --- a/share/doc/llvm/Makefile.depend +++ b/share/doc/llvm/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ diff --git a/share/examples/libvgl/Makefile.depend b/share/examples/libvgl/Makefile.depend index f52ca95..79eb58b 100644 --- a/share/examples/libvgl/Makefile.depend +++ b/share/examples/libvgl/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/share/examples/mdoc/example.4 b/share/examples/mdoc/example.4 index e5c8a1f..946dd3a 100644 --- a/share/examples/mdoc/example.4 +++ b/share/examples/mdoc/example.4 @@ -26,15 +26,14 @@ .\" .\" Note: The date here should be updated whenever a non-trivial .\" change is made to the manual page. -.Dd April 1, 2006 +.Dd July 31, 2015 .Dt EXAMPLE 4 i386 .Os .Sh NAME .Nm example .Nd "example device driver manual page" .Sh SYNOPSIS -To compile the -driver into the kernel, +To compile the driver into the kernel, place the following lines in the kernel configuration file: .Bd -ragged -offset indent @@ -42,8 +41,7 @@ kernel configuration file: .Cd "options EXAMPLE_DEBUG" .Ed .Pp -Alternatively, to load the -driver as a +Alternatively, to load the driver as a module at boot time, place the following line in .Xr loader.conf 5 : .Bd -literal -offset indent diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index fcf7b9d..94c2ad3 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -379,6 +379,8 @@ MAN= aac.4 \ oce.4 \ ohci.4 \ orm.4 \ + otus.4 \ + otusfw.4 \ ow.4 \ ow_temp.4 \ owc.4 \ diff --git a/share/man/man4/ctl.4 b/share/man/man4/ctl.4 index e2485b9..1061ead 100644 --- a/share/man/man4/ctl.4 +++ b/share/man/man4/ctl.4 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd September 12, 2015 +.Dd September 27, 2015 .Dt CTL 4 .Os .Sh NAME @@ -53,7 +53,7 @@ It supports features such as: .Pp .Bl -bullet -compact .It -Disk and processor device emulation +Disk, processor and cdrom device emulation .It Tagged queueing .It diff --git a/share/man/man4/man4.arm/Makefile.depend b/share/man/man4/man4.arm/Makefile.depend index 3af2d7f..f80275d 100644 --- a/share/man/man4/man4.arm/Makefile.depend +++ b/share/man/man4/man4.arm/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ diff --git a/share/man/man4/man4.i386/Makefile.depend b/share/man/man4/man4.i386/Makefile.depend index 3af2d7f..f80275d 100644 --- a/share/man/man4/man4.i386/Makefile.depend +++ b/share/man/man4/man4.i386/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ diff --git a/share/man/man4/man4.powerpc/Makefile.depend b/share/man/man4/man4.powerpc/Makefile.depend index 3af2d7f..f80275d 100644 --- a/share/man/man4/man4.powerpc/Makefile.depend +++ b/share/man/man4/man4.powerpc/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ diff --git a/share/man/man4/man4.sparc64/Makefile.depend b/share/man/man4/man4.sparc64/Makefile.depend index 3af2d7f..f80275d 100644 --- a/share/man/man4/man4.sparc64/Makefile.depend +++ b/share/man/man4/man4.sparc64/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ diff --git a/share/man/man4/otus.4 b/share/man/man4/otus.4 new file mode 100644 index 0000000..2a7875c --- /dev/null +++ b/share/man/man4/otus.4 @@ -0,0 +1,169 @@ +.\" $FreeBSD$ +.\" +.\" Copyright (c) 2015 Adrian Chadd <adrian@FreeBSD.org> +.\" +.\" 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. +.\" +.Dd September 25, 2015 +.Dt OTUS 4 +.Os +.Sh NAME +.Nm otus +.Nd Atheros AR9170 USB IEEE 802.11a/b/g/n wireless network device +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following lines in your kernel configuration file: +.Bd -ragged -offset indent +.Cd "device ehci" +.Cd "device uhci" +.Cd "device ohci" +.Cd "device usb" +.Cd "device otus" +.Cd "device wlan" +.Ed +.Pp +Alternatively, to load the driver as a module at boot time, +place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +if_otus_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +driver supports USB 2.0 wireless network devices based on the Atheros +AR9170 chipset. +.Pp +The Atheros AR9170 is a draft-802.11n adapter that uses an external +radio to operate in either 2.4GHz only or 2.4GHz and 5GHz. +.Pp +The AR9101 radio supports 1T1R operation in 2GHz only. +.Pp +The AR9102 radio supports 2T2R operation in 2GHz only. +.Pp +The AR9104 radio supports 2T2R operation both 2GHz and 5GHz. +.Pp +These are the modes the +.Nm +driver can operate in: +.Bl -tag -width "IBSS-masterXX" +.It BSS mode +Also known as +.Em infrastructure +mode, this is used when associating with an access point, through +which all traffic passes. +This mode is the default. +.El +.Pp +The +.Nm +driver can be configured to use +Wired Equivalent Privacy (WEP) or +Wi-Fi Protected Access (WPA-PSK and WPA2-PSK). +WPA is the de facto encryption standard for wireless networks. +It is strongly recommended that WEP +not be used as the sole mechanism +to secure wireless communication, +due to serious weaknesses in it. +.Pp +The +.Nm +driver can be configured at runtime with +.Xr ifconfig 8 . +.Sh FILES +The driver needs at least version 1.0 of the following firmware files, +which is loaded when an interface is attached: +.Pp +.Bl -tag -width Ds -offset indent -compact +.It Pa /boot/kernel/otusfw-init.ko +.It Pa /boot/kernel/otusfw-main.ko +.El +.Sh HARDWARE +The +.Nm +driver provices support for Atheros AR9170 USB IEEE 802.11b/g/n +wireless network adapters, including: +.Pp +.Bl -tag -width Ds -offset indent -compact +.It 3Com 3CRUSBN275 +.It Arcadyan WN7512 +.\" .It AVM FRITZ!WLAN USB Stick N +.It CACE AirPcap \&Nx +.It D-Link DWA-130 rev \&D1 +.It D-Link DWA-160 rev A1 +.It D-Link DWA-160 rev A2 +.It IO-Data WN-GDN/US2 +.It NEC Aterm WL300NU-G +.It Netgear WNDA3100 +.It Netgear WN111 v2 +.It Planex GW-US300 +.It SMC Networks SMCWUSB-N2 +.It TP-Link TL-WN821N v1, v2 +.It Ubiquiti SR71 USB +.It Unex DNUA-81 +.It Z-Com UB81 +.It Z-Com UB82 +.It ZyXEL NWD-271N +.El +.Sh EXAMPLES +Join an existing BSS network (i.e., connect to an access point): +.Bd -literal -offset indent +ifconfig wlan create wlandev otus0 inet 192.168.0.20 \e + netmask 0xffffff00 +.Ed +.Pp +Join a specific BSS network with network name +.Dq Li my_net : +.Pp +.Dl "ifconfig wlan create wlandev otus0 ssid my_net up" +.Pp +Join a specific BSS network with 64-bit WEP encryption: +.Bd -literal -offset indent +ifconfig wlan create wlandev otus0 ssid my_net \e + wepmode on wepkey 0x1234567890 weptxkey 1 up +.Ed +.Sh DIAGNOSTICS +.Bl -diag +.It "%s: failed load firmware of file otusfw-main" +For some reason, the driver was unable to read the microcode file from the +filesystem. +The file might be missing or corrupted. +.El +.Sh SEE ALSO +.Xr intro 1 , +.Xr netintro 4 , +.Xr otusfw 4 , +.Xr usb 4 , +.Xr wlan 4 , +.Xr arp 8 , +.Xr hostapd 8 , +.Xr ifconfig 8 , +.Xr wpa_supplicant 8 +.Sh HISTORY +The +.Nm +driver first appeared in +.Ox 4.6 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An Damien Bergamini Aq Mt damien@openbsd.org +and ported by +.An Adrian Chadd Aq Mt adrian@freebsd.org . +.Sh CAVEATS +The +.Nm +driver only supports 802.11a/b/g operations. +802.11 operation is not supported at this time. diff --git a/share/man/man4/otusfw.4 b/share/man/man4/otusfw.4 new file mode 100644 index 0000000..7996625 --- /dev/null +++ b/share/man/man4/otusfw.4 @@ -0,0 +1,45 @@ +.\" $FreeBSD$ +.\" Copyright (c) 2015 Adrian Chadd <adrian@FreeBSD.org> +.\" +.\" 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. +.\" +.Dd September 25, 2015 +.Dt OTUSFW 4 +.Os +.Sh NAME +.Nm otusfw +.Nd "Firmware Module for AR9170 driver" +.Sh SYNOPSIS +To compile this module into the kernel, place the following line in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device otusfw" +.Ed +.Pp +This will include the firmware image, AR9170, inside the kernel. +.Xr otus 4 +will load the image into the chip. +.Pp +Alternatively, to load the firmware images as a module at boot time, place +the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +otusfw_init_load="YES" +otusfw_main_load="YES" +.Ed +.Sh DESCRIPTION +This module provides the firmware for the Atheros AR9170 based +USB WiFi adapters. +.Sh SEE ALSO +.Xr otus 4 , +.Xr firmware 9 diff --git a/share/man/man4/usb_quirk.4 b/share/man/man4/usb_quirk.4 index 9b05973..0140ccb 100644 --- a/share/man/man4/usb_quirk.4 +++ b/share/man/man4/usb_quirk.4 @@ -16,7 +16,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 24, 2015 +.Dd September 26, 2015 .Dt USB_QUIRK 4 .Os .Sh NAME @@ -193,9 +193,10 @@ The value is a string whose format is: Installs the quirks .Ic UQ_QUIRK,... for all USB devices matching -.Ic VendorId , +.Ic VendorId +and .Ic ProductId -and has a hardware revision between and including +which have a hardware revision between and including .Ic LowRevision and .Ic HighRevision . diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 2a10157..f26123d 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -39,6 +39,7 @@ MAN= accept_filter.9 \ bus_generic_print_child.9 \ bus_generic_read_ivar.9 \ bus_generic_shutdown.9 \ + bus_get_resource.9 \ BUS_NEW_PASS.9 \ BUS_PRINT_CHILD.9 \ BUS_READ_IVAR.9 \ @@ -1007,12 +1008,7 @@ MLINKS+=\ mbuf.9 m_dup.9 \ mbuf.9 m_dup_pkthdr.9 \ mbuf.9 MEXTADD.9 \ - mbuf.9 MEXT_ADD_REF.9 \ - mbuf.9 MEXTFREE.9 \ - mbuf.9 MEXT_IS_REF.9 \ - mbuf.9 MEXT_REM_REF.9 \ mbuf.9 m_fixhdr.9 \ - mbuf.9 MFREE.9 \ mbuf.9 m_free.9 \ mbuf.9 m_freem.9 \ mbuf.9 MGET.9 \ diff --git a/share/man/man9/VOP_ADVISE.9 b/share/man/man9/VOP_ADVISE.9 index 50cd860..7cc2916 100644 --- a/share/man/man9/VOP_ADVISE.9 +++ b/share/man/man9/VOP_ADVISE.9 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 3, 2013 +.Dd September 26, 2015 .Dt VOP_ADVISE 9 .Os .Sh NAME @@ -52,6 +52,9 @@ The vnode of the file. The start of the range of file data. .It Fa end The end of the range of file data. +A value of +.Dv OFF_MAX +indicates that the advice is to be applied up to the end of the file. .It Fa advice The type of operation to apply to the file data. Possible values are: diff --git a/share/man/man9/bus_get_resource.9 b/share/man/man9/bus_get_resource.9 new file mode 100644 index 0000000..2f6898a --- /dev/null +++ b/share/man/man9/bus_get_resource.9 @@ -0,0 +1,94 @@ +.\" +.\" Copyright (c) 2008 +.\" The DragonFly Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" 3. Neither the name of The DragonFly Project nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific, prior written permission. +.\" +.\" 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 HOLDERS 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. +.\" +.\" $DragonFly: src/share/man/man9/bus_get_resource.9,v 1.1 2008/11/09 09:48:41 swildner Exp $ +.\" $FreeBSD$ +.\" +.Dd September 26, 2015 +.Dt BUS_GET_RESOURCE 9 +.Os +.Sh NAME +.Nm bus_get_resource +.Nd "read a resource range/value with a given resource ID" +.Sh SYNOPSIS +.In sys/param.h +.In sys/bus.h +.In sys/rman.h +.Ft int +.Fo bus_get_resource +.Fa "device_t dev" "int type" "int rid" "u_long *startp" "u_long *countp" +.Fc +.Sh DESCRIPTION +The +.Fn bus_get_resource +function reads the range or value of the resource +.Fa type , rid +pair and stores it in the +.Fa startp +and +.Fa countp +arguments. +.Pp +The arguments are as follows: +.Bl -tag -width ".Fa startp" +.It Fa dev +The device to read the resource from. +.It Fa type +The type of resource you want to read. +It is one of: +.Pp +.Bl -tag -width ".Dv SYS_RES_MEMORY" -compact +.It Dv SYS_RES_IRQ +for IRQs +.It Dv SYS_RES_DRQ +for ISA DMA lines +.It Dv SYS_RES_MEMORY +for I/O memory +.It Dv SYS_RES_IOPORT +for I/O ports +.El +.It Fa rid +A bus-specific handle that identifies the resource being read. +.It Fa startp +A pointer to the start address of this resource. +.It Fa countp +A pointer to the length of the resource. +For example, the size of the memory in bytes. +.El +.Sh RETURN VALUES +Zero is returned on success, otherwise an error is returned. +.Sh SEE ALSO +.Xr bus_set_resource 9 , +.Xr device 9 , +.Xr driver 9 +.Sh AUTHORS +This manual page was written by +.An Sascha Wildner . diff --git a/share/man/man9/mbuf.9 b/share/man/man9/mbuf.9 index ea53ab9..9515cdf 100644 --- a/share/man/man9/mbuf.9 +++ b/share/man/man9/mbuf.9 @@ -52,8 +52,6 @@ .Fa "short flags" .Fa "int type" .Fc -.Fn MEXTFREE "struct mbuf *mbuf" -.Fn MFREE "struct mbuf *mbuf" "struct mbuf *successor" .\" .Ss Mbuf utility macros .Fn mtod "struct mbuf *mbuf" "type" diff --git a/share/mk/bsd.README b/share/mk/bsd.README index d519e14..b81a714 100644 --- a/share/mk/bsd.README +++ b/share/mk/bsd.README @@ -39,7 +39,7 @@ bsd.port.post.mk - building ports bsd.port.pre.mk - building ports bsd.port.subdir.mk - targets for building subdirectories for ports bsd.prog.mk - building programs from source files -bsd.progs.mk - build multiple programs from sources (deprecated) +bsd.progs.mk - build multiple programs from sources bsd.snmpmod.mk - building modules for the SNMP daemon bsnmpd bsd.subdir.mk - targets for building subdirectories bsd.sys.mk - common settings used for building FreeBSD sources diff --git a/share/mk/bsd.files.mk b/share/mk/bsd.files.mk index 1c957fc..b9379d9 100644 --- a/share/mk/bsd.files.mk +++ b/share/mk/bsd.files.mk @@ -47,10 +47,12 @@ ${group}NAME_${file:T}?= ${${group}NAME} ${group}NAME_${file:T}?= ${file:T} .endif .if !make(buildincludes) -STAGE_AS_SETS+= ${group} +STAGE_AS_SETS+= ${file:T} .endif STAGE_AS_${file:T}= ${${group}NAME_${file:T}} -stage_as.${group}: ${file} +# XXX {group}OWN,GRP,MODE +STAGE_DIR.${file:T}= ${STAGE_OBJTOP}${${group}DIR_${file:T}} +stage_as.${file:T}: ${file} installfiles-${group}: _${group}INS_${file:T} _${group}INS_${file:T}: ${file} diff --git a/share/mk/bsd.incs.mk b/share/mk/bsd.incs.mk index e1e0a4a..1c178b0 100644 --- a/share/mk/bsd.incs.mk +++ b/share/mk/bsd.incs.mk @@ -42,10 +42,12 @@ ${group}NAME_${header:T}?= ${${group}NAME} .else ${group}NAME_${header:T}?= ${header:T} .endif -STAGE_AS_SETS+= ${group} +STAGE_AS_SETS+= ${header:T} STAGE_AS_${header:T}= ${${group}NAME_${header:T}} -stage_as.${group}: ${header} -stage_includes: stage_as.${group} +# XXX {group}OWN,GRP,MODE +STAGE_DIR.${header:T}= ${STAGE_OBJTOP}${${group}DIR_${header:T}} +stage_as.${header:T}: ${header} +stage_includes: stage_as.${header:T} installincludes: _${group}INS_${header:T} _${group}INS_${header:T}: ${header} diff --git a/share/mk/bsd.progs.mk b/share/mk/bsd.progs.mk index dce109f..721987f 100644 --- a/share/mk/bsd.progs.mk +++ b/share/mk/bsd.progs.mk @@ -66,8 +66,6 @@ all: ${PROGS} # We cannot capture dependencies for meta mode here UPDATE_DEPENDFILE = NO -# nor can we safely run in parallel. -.NOTPARALLEL: .endif .endif # PROGS || PROGS_CXX @@ -84,7 +82,7 @@ $v = .if !empty(PROGS) && !defined(_RECURSING_PROGS) # tell progs.mk we might want to install things -PROGS_TARGETS+= checkdpadd clean cleandepend cleandir cleanobj depend install +PROGS_TARGETS+= checkdpadd clean cleandepend cleandir depend install .for p in ${PROGS} .if defined(PROGS_CXX) && !empty(PROGS_CXX:M$p) diff --git a/share/mk/bsd.subdir.mk b/share/mk/bsd.subdir.mk index 8fab656..9c480ac 100644 --- a/share/mk/bsd.subdir.mk +++ b/share/mk/bsd.subdir.mk @@ -60,7 +60,7 @@ distribute: .MAKE _SUBDIR: .USE .MAKE .if defined(SUBDIR) && !empty(SUBDIR) && !defined(NO_SUBDIR) - @${_+_}set -e; for entry in ${SUBDIR:N.WAIT}; do \ + @${_+_}for entry in ${SUBDIR:N.WAIT}; do \ if test -d ${.CURDIR}/$${entry}.${MACHINE_ARCH}; then \ ${ECHODIR} "===> ${DIRPRFX}$${entry}.${MACHINE_ARCH} (${.TARGET:S,realinstall,install,:S,^_sub.,,})"; \ edir=$${entry}.${MACHINE_ARCH}; \ @@ -101,8 +101,7 @@ __deps+= ${__target}_subdir_${__dep} .endfor ${__target}_subdir_${__dir}: .MAKE ${__deps} .if !defined(NO_SUBDIR) - @${_+_}set -e; \ - if test -d ${.CURDIR}/${__dir}.${MACHINE_ARCH}; then \ + @${_+_}if test -d ${.CURDIR}/${__dir}.${MACHINE_ARCH}; then \ ${ECHODIR} "===> ${DIRPRFX}${__dir}.${MACHINE_ARCH} (${__target:realinstall=install})"; \ edir=${__dir}.${MACHINE_ARCH}; \ cd ${.CURDIR}/$${edir}; \ @@ -133,7 +132,7 @@ _sub.${__stage}${__target}: _SUBDIR .endfor .if !target(${__target}) ${__target}: .MAKE - ${_+_}set -e; cd ${.CURDIR}; ${MAKE} build${__target}; ${MAKE} install${__target} + ${_+_}cd ${.CURDIR}; ${MAKE} build${__target}; ${MAKE} install${__target} .endif .endfor diff --git a/share/mk/local.gendirdeps.mk b/share/mk/local.gendirdeps.mk index 47f463e..833ac80 100644 --- a/share/mk/local.gendirdeps.mk +++ b/share/mk/local.gendirdeps.mk @@ -44,7 +44,3 @@ GENDIRDEPS_FILTER_VARS+= \ GENDIRDEPS_FILTER+= ${GENDIRDEPS_FILTER_DIR_VARS:@v@S,${$v},_{${v}},@} GENDIRDEPS_FILTER+= ${GENDIRDEPS_FILTER_VARS:@v@S,/${$v}/,/_{${v}}/,@:NS,//,*:u} - -# handle the non-standard way that gnu/usr.bin/groff/tmac is staged -GENDIRDEPS_FILTER+= C,.*usr/share/tmac.*stage,gnu/usr.bin/groff/tmac, - diff --git a/share/mk/local.init.mk b/share/mk/local.init.mk index cf95063..5d71d1f 100644 --- a/share/mk/local.init.mk +++ b/share/mk/local.init.mk @@ -28,8 +28,12 @@ CXXFLAGS_LAST+= -I/usr/include .if ${.MAKE.DEPENDFILE:E} != "host" UPDATE_DEPENDFILE?= no .endif -HOST_CC?= /usr/bin/cc +HOST_CC?= /usr/bin/cc +CC= ${HOST_CC} +HOST_CXX?= /usr/bin/c++ +CXX= ${HOST_CXX} +HOST_CPP?= /usr/bin/cpp +CPP= ${HOST_CPP} HOST_CFLAGS+= -DHOSTPROG -CC= ${HOST_CC} CFLAGS+= ${HOST_CFLAGS} .endif diff --git a/share/mk/local.meta.sys.mk b/share/mk/local.meta.sys.mk index 8095bea..adc884b 100644 --- a/share/mk/local.meta.sys.mk +++ b/share/mk/local.meta.sys.mk @@ -213,10 +213,13 @@ TOOLSDIR?= ${STAGE_HOST_OBJTOP} PATH:= ${PATH:S,:, ,g:@d@${exists(${TOOLSDIR}$d):?${TOOLSDIR}$d:}@:ts:}:${PATH} .export PATH .if exists(${TOOLSDIR}/usr/bin/cc) -HOST_CC?= ${TOOLSDIR}/usr/bin/cc -CC?= ${TOOLSDIR}/usr/bin/cc -CXX?= ${TOOLSDIR}/usr/bin/c++ -.export HOST_CC CC CXX +HOST_CC?= ${TOOLSDIR}/usr/bin/cc +CC?= ${HOST_CC} +HOST_CXX?= ${TOOLSDIR}/usr/bin/c++ +CXX?= ${HOST_CXX} +HOST_CPP?= ${TOOLSDIR}/usr/bin/cpp +CPP?= ${HOST_CPP} +.export HOST_CC CC HOST_CXX CXX HOST_CPP CPP .endif .endif .endif diff --git a/share/mk/suite.test.mk b/share/mk/suite.test.mk index 34b3764..c447a17 100644 --- a/share/mk/suite.test.mk +++ b/share/mk/suite.test.mk @@ -110,8 +110,7 @@ realtest: .PHONY @echo "*** installed in ${TESTSBASE}. This test run may raise false" @echo "*** positives and/or false negatives." @echo - @set -e; \ - ${KYUA} test -k ${DESTDIR}${TESTSDIR}/Kyuafile; \ + @${KYUA} test -k ${DESTDIR}${TESTSDIR}/Kyuafile; \ result=0; \ echo; \ echo "*** Once again, note that "make test" is unsupported."; \ diff --git a/share/mk/sys.mk b/share/mk/sys.mk index 041a1f8..e8f4892 100644 --- a/share/mk/sys.mk +++ b/share/mk/sys.mk @@ -394,6 +394,10 @@ SHELL= ${__MAKE_SHELL} # Tell bmake the makefile preference .MAKE.MAKEFILE_PREFERENCE= BSDmakefile makefile Makefile +# Tell bmake to always pass job tokens, regardless of target depending on +# .MAKE or looking like ${MAKE}/${.MAKE}/$(MAKE)/$(.MAKE)/make. +.MAKE.ALWAYS_PASS_JOB_QUEUE= yes + # By default bmake does *not* use set -e # when running target scripts, this is a problem for many makefiles here. # So define a shell that will do what FreeBSD expects. diff --git a/share/security/Makefile.depend b/share/security/Makefile.depend index 3af2d7f..f80275d 100644 --- a/share/security/Makefile.depend +++ b/share/security/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ diff --git a/share/vt/fonts/Makefile b/share/vt/fonts/Makefile index 05e99a5..051f2c1 100644 --- a/share/vt/fonts/Makefile +++ b/share/vt/fonts/Makefile @@ -4,6 +4,7 @@ FILES= gallant.fnt \ vgarom-8x8.fnt \ vgarom-8x14.fnt \ vgarom-8x16.fnt \ + vgarom-16x32.fnt \ vgarom-thin-8x8.fnt \ vgarom-thin-8x16.fnt diff --git a/share/vt/fonts/vgarom-16x32.hex b/share/vt/fonts/vgarom-16x32.hex new file mode 100644 index 0000000..be2a4de --- /dev/null +++ b/share/vt/fonts/vgarom-16x32.hex @@ -0,0 +1,587 @@ +# $FreeBSD$ +# Height: 32 +# Width: 16 +0000:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0020:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0021:000000000000000003C003C00FF00FF00FF00FF00FF00FF003C003C003C003C003C003C00000000003C003C003C003C000000000000000000000000000000000 +0022:000000003C3C3C3C3C3C3C3C3C3C3C3C0C300C300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0023:0000000000000000000000003CF03CF03CF03CF0FFFCFFFC3CF03CF03CF03CF03CF03CF0FFFCFFFC3CF03CF03CF03CF000000000000000000000000000000000 +0024:03C003C003C003C03FF03FF0F03CF03CF00CF00CF000F0003FF03FF0003C003C003C003CC03CC03CF03CF03C3FF03FF003C003C003C003C00000000000000000 +0025:00000000000000000000000000000000F00CF00CF03CF03C00F000F003C003C00F000F003C003C00F03CF03CC03CC03C00000000000000000000000000000000 +0026:00000000000000000FC00FC03CF03CF03CF03CF00FC00FC03F3C3F3CF3F0F3F0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +0027:000000000F000F000F000F000F000F003C003C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0028:000000000000000000F000F003C003C00F000F000F000F000F000F000F000F000F000F000F000F0003C003C000F000F000000000000000000000000000000000 +0029:00000000000000000F000F0003C003C000F000F000F000F000F000F000F000F000F000F000F000F003C003C00F000F0000000000000000000000000000000000 +002A:00000000000000000000000000000000000000003C3C3C3C0FF00FF0FFFFFFFF0FF00FF03C3C3C3C000000000000000000000000000000000000000000000000 +002B:000000000000000000000000000000000000000003C003C003C003C03FFC3FFC03C003C003C003C0000000000000000000000000000000000000000000000000 +002C:00000000000000000000000000000000000000000000000000000000000000000000000003C003C003C003C003C003C00F000F00000000000000000000000000 +002D:00000000000000000000000000000000000000000000000000000000FFFCFFFC0000000000000000000000000000000000000000000000000000000000000000 +002E:0000000000000000000000000000000000000000000000000000000000000000000000000000000003C003C003C003C000000000000000000000000000000000 +002F:00000000000000000000000000000000000C000C003C003C00F000F003C003C00F000F003C003C00F000F000C000C00000000000000000000000000000000000 +0030:00000000000000000FC00FC03CF03CF0F03CF03CF03CF03CF33CF33CF33CF33CF03CF03CF03CF03C3CF03CF00FC00FC000000000000000000000000000000000 +0031:000000000000000003C003C00FC00FC03FC03FC003C003C003C003C003C003C003C003C003C003C003C003C03FFC3FFC00000000000000000000000000000000 +0032:00000000000000003FF03FF0F03CF03C003C003C00F000F003C003C00F000F003C003C00F000F000F03CF03CFFFCFFFC00000000000000000000000000000000 +0033:00000000000000003FF03FF0F03CF03C003C003C003C003C0FF00FF0003C003C003C003C003C003CF03CF03C3FF03FF000000000000000000000000000000000 +0034:000000000000000000F000F003F003F00FF00FF03CF03CF0F0F0F0F0FFFCFFFC00F000F000F000F000F000F003FC03FC00000000000000000000000000000000 +0035:0000000000000000FFFCFFFCF000F000F000F000F000F000FFF0FFF0003C003C003C003C003C003CF03CF03C3FF03FF000000000000000000000000000000000 +0036:00000000000000000FC00FC03C003C00F000F000F000F000FFF0FFF0F03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +0037:0000000000000000FFFCFFFCF03CF03C003C003C003C003C00F000F003C003C00F000F000F000F000F000F000F000F0000000000000000000000000000000000 +0038:00000000000000003FF03FF0F03CF03CF03CF03CF03CF03C3FF03FF0F03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +0039:00000000000000003FF03FF0F03CF03CF03CF03CF03CF03C3FFC3FFC003C003C003C003C003C003C00F000F03FC03FC000000000000000000000000000000000 +003A:0000000000000000000000000000000003C003C003C003C000000000000000000000000003C003C003C003C00000000000000000000000000000000000000000 +003B:0000000000000000000000000000000003C003C003C003C000000000000000000000000003C003C003C003C00F000F0000000000000000000000000000000000 +003C:000000000000000000000000003C003C00F000F003C003C00F000F003C003C000F000F0003C003C000F000F0003C003C00000000000000000000000000000000 +003D:00000000000000000000000000000000000000003FFC3FFC00000000000000003FFC3FFC00000000000000000000000000000000000000000000000000000000 +003E:0000000000000000000000003C003C000F000F0003C003C000F000F0003C003C00F000F003C003C00F000F003C003C0000000000000000000000000000000000 +003F:00000000000000003FF03FF0F03CF03CF03CF03C00F000F003C003C003C003C003C003C00000000003C003C003C003C000000000000000000000000000000000 +0040:0000000000000000000000003FF03FF0F03CF03CF03CF03CF3FCF3FCF3FCF3FCF3FCF3FCF3F0F3F0F000F0003FF03FF000000000000000000000000000000000 +0041:0000000000000000030003000FC00FC03CF03CF0F03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +0042:0000000000000000FFF0FFF03C3C3C3C3C3C3C3C3C3C3C3C3FF03FF03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3CFFF0FFF000000000000000000000000000000000 +0043:00000000000000000FF00FF03C3C3C3CF00CF00CF000F000F000F000F000F000F000F000F00CF00C3C3C3C3C0FF00FF000000000000000000000000000000000 +0044:0000000000000000FFC0FFC03CF03CF03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3CF03CF0FFC0FFC000000000000000000000000000000000 +0045:0000000000000000FFFCFFFC3C3C3C3C3C0C3C0C3CC03CC03FC03FC03CC03CC03C003C003C0C3C0C3C3C3C3CFFFCFFFC00000000000000000000000000000000 +0046:0000000000000000FFFCFFFC3C3C3C3C3C0C3C0C3CC03CC03FC03FC03CC03CC03C003C003C003C003C003C00FF00FF0000000000000000000000000000000000 +0047:00000000000000000FF00FF03C3C3C3CF00CF00CF000F000F000F000F3FCF3FCF03CF03CF03CF03C3C3C3C3C0FCC0FCC00000000000000000000000000000000 +0048:0000000000000000F03CF03CF03CF03CF03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +0049:00000000000000000FF00FF003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +004A:000000000000000003FC03FC00F000F000F000F000F000F000F000F000F000F0F0F0F0F0F0F0F0F0F0F0F0F03FC03FC000000000000000000000000000000000 +004B:0000000000000000FC3CFC3C3C3C3C3C3C3C3C3C3CF03CF03FC03FC03FC03FC03CF03CF03C3C3C3C3C3C3C3CFC3CFC3C00000000000000000000000000000000 +004C:0000000000000000FF00FF003C003C003C003C003C003C003C003C003C003C003C003C003C0C3C0C3C3C3C3CFFFCFFFC00000000000000000000000000000000 +004D:0000000000000000F03CF03CFCFCFCFCFFFCFFFCFFFCFFFCF33CF33CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +004E:0000000000000000F03CF03CFC3CFC3CFF3CFF3CFFFCFFFCF3FCF3FCF0FCF0FCF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +004F:00000000000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +0050:0000000000000000FFF0FFF03C3C3C3C3C3C3C3C3C3C3C3C3FF03FF03C003C003C003C003C003C003C003C00FF00FF0000000000000000000000000000000000 +0051:00000000000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF33CF33CF3FCF3FC3FF03FF000F000F000FC00FC0000000000000000 +0052:0000000000000000FFF0FFF03C3C3C3C3C3C3C3C3C3C3C3C3FF03FF03CF03CF03C3C3C3C3C3C3C3C3C3C3C3CFC3CFC3C00000000000000000000000000000000 +0053:00000000000000003FF03FF0F03CF03CF03CF03C3C003C000FC00FC000F000F0003C003CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +0054:00000000000000003FFC3FFC3FFC3FFC33CC33CC03C003C003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +0055:0000000000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +0056:0000000000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3CF03CF00FC00FC00300030000000000000000000000000000000000 +0057:0000000000000000F03CF03CF03CF03CF03CF03CF03CF03CF33CF33CF33CF33CF33CF33CFFFCFFFCFCFCFCFC3CF03CF000000000000000000000000000000000 +0058:0000000000000000F03CF03CF03CF03C3CF03CF03FF03FF00FC00FC00FC00FC03FF03FF03CF03CF0F03CF03CF03CF03C00000000000000000000000000000000 +0059:00000000000000003C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C0FF00FF003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +005A:0000000000000000FFFCFFFCF03CF03CC03CC03C00F000F003C003C00F000F003C003C00F00CF00CF03CF03CFFFCFFFC00000000000000000000000000000000 +005B:00000000000000000FF00FF00F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000FF00FF000000000000000000000000000000000 +005C:000000000000000000000000C000C000F000F000FC00FC003F003F000FC00FC003F003F000FC00FC003C003C000C000C00000000000000000000000000000000 +005D:00000000000000000FF00FF000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F00FF00FF000000000000000000000000000000000 +005E:030003000FC00FC03CF03CF0F03CF03C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +005F:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFF0000000000000000 +0060:0F000F000F000F0003C003C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0061:00000000000000000000000000000000000000003FC03FC000F000F03FF03FF0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +0062:0000000000000000FC00FC003C003C003C003C003FC03FC03CF03CF03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3FF03FF000000000000000000000000000000000 +0063:00000000000000000000000000000000000000003FF03FF0F03CF03CF000F000F000F000F000F000F03CF03C3FF03FF000000000000000000000000000000000 +0064:000000000000000003F003F000F000F000F000F00FF00FF03CF03CF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +0065:00000000000000000000000000000000000000003FF03FF0F03CF03CFFFCFFFCF000F000F000F000F03CF03C3FF03FF000000000000000000000000000000000 +0066:00000000000000000FC00FC03CF03CF03C303C303C003C00FF00FF003C003C003C003C003C003C003C003C00FF00FF0000000000000000000000000000000000 +0067:00000000000000000000000000000000000000003F3C3F3CF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03FF03FF000F000F0F0F0F0F03FC03FC000000000 +0068:0000000000000000FC00FC003C003C003C003C003CF03CF03F3C3F3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3CFC3CFC3C00000000000000000000000000000000 +0069:000000000000000003C003C003C003C0000000000FC00FC003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +006A:0000000000000000003C003C003C003C0000000000FC00FC003C003C003C003C003C003C003C003C003C003C003C003C3C3C3C3C3C3C3C3C0FF00FF000000000 +006B:0000000000000000FC00FC003C003C003C003C003C3C3C3C3CF03CF03FC03FC03FC03FC03CF03CF03C3C3C3CFC3CFC3C00000000000000000000000000000000 +006C:00000000000000000FC00FC003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +006D:0000000000000000000000000000000000000000FCF0FCF0FFFCFFFCF33CF33CF33CF33CF33CF33CF33CF33CF03CF03C00000000000000000000000000000000 +006E:0000000000000000000000000000000000000000F3F0F3F03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C00000000000000000000000000000000 +006F:00000000000000000000000000000000000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +0070:0000000000000000000000000000000000000000F3F0F3F03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3FF03FF03C003C003C003C00FF00FF0000000000 +0071:00000000000000000000000000000000000000003F3C3F3CF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03FF03FF000F000F000F000F003FC03FC00000000 +0072:0000000000000000000000000000000000000000F3F0F3F03F3C3F3C3C3C3C3C3C003C003C003C003C003C00FF00FF0000000000000000000000000000000000 +0073:00000000000000000000000000000000000000003FF03FF0F03CF03C3C003C000FC00FC000F000F0F03CF03C3FF03FF000000000000000000000000000000000 +0074:0000000000000000030003000F000F000F000F00FFF0FFF00F000F000F000F000F000F000F000F000F3C0F3C03F003F000000000000000000000000000000000 +0075:0000000000000000000000000000000000000000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +0076:00000000000000000000000000000000000000003C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C0FF00FF003C003C000000000000000000000000000000000 +0077:0000000000000000000000000000000000000000F03CF03CF03CF03CF33CF33CF33CF33CF33CF33CFFFCFFFC3CF03CF000000000000000000000000000000000 +0078:0000000000000000000000000000000000000000F03CF03C3CF03CF00FC00FC00FC00FC00FC00FC03CF03CF0F03CF03C00000000000000000000000000000000 +0079:0000000000000000000000000000000000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FFC3FFC003C003C00F000F0FFC0FFC000000000 +007A:0000000000000000000000000000000000000000FFFCFFFCF0F0F0F003C003C00F000F003C003C00F03CF03CFFFCFFFC00000000000000000000000000000000 +007B:000000000000000000FC00FC03C003C003C003C003C003C03F003F0003C003C003C003C003C003C003C003C000FC00FC00000000000000000000000000000000 +007C:000000000000000003C003C003C003C003C003C003C003C00000000003C003C003C003C003C003C003C003C003C003C000000000000000000000000000000000 +007D:00000000000000003F003F0003C003C003C003C003C003C000FC00FC03C003C003C003C003C003C003C003C03F003F0000000000000000000000000000000000 +007E:00000000000000003F3C3F3CF3F0F3F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00A0:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00A1:000000000000000003C003C003C003C00000000003C003C003C003C003C003C00FF00FF00FF00FF00FF00FF003C003C000000000000000000000000000000000 +00A2:0000000003C003C003C003C00FF00FF03C3C3C3C3C003C003C003C003C003C003C3C3C3C0FF00FF003C003C003C003C000000000000000000000000000000000 +00A3:000000000FC00FC03CF03CF03C303C303C003C00FF00FF003C003C003C003C003C003C003C003C00FC3CFC3CFFF0FFF000000000000000000000000000000000 +00A4:000000000000000000000000C00CC00CF03CF03C3FF03FF0F03CF03CF03CF03CF03CF03CF03CF03C3FF03FF0F03CF03CC00CC00C000000000000000000000000 +00A5:00000000000000003C3C3C3C3C3C3C3C0FF00FF003C003C03FFC3FFC03C003C03FFC3FFC03C003C003C003C003C003C000000000000000000000000000000000 +00A6:000000000000000003C003C003C003C003C003C003C003C00000000003C003C003C003C003C003C003C003C003C003C000000000000000000000000000000000 +00A7:000000003FF03FF0F03CF03C3C003C000FC00FC03CF03CF0F03CF03CF03CF03C3CF03CF00FC00FC000F000F0F03CF03C3FF03FF0000000000000000000000000 +00A8:00000000F03CF03C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00A9:00000000000000003FF03FF0F03CF03CC00CC00CCFCCCFCCCC0CCC0CCC0CCC0CCFCCCFCCC00CC00CF03CF03C3FF03FF000000000000000000000000000000000 +00AA:000000000FF00FF03CF03CF03CF03CF00FFC0FFC000000003FFC3FFC000000000000000000000000000000000000000000000000000000000000000000000000 +00AB:00000000000000000000000000000000000000000F3C0F3C3CF03CF0F3C0F3C03CF03CF00F3C0F3C000000000000000000000000000000000000000000000000 +00AC:000000000000000000000000000000000000000000000000FFFCFFFC003C003C003C003C003C003C003C003C0000000000000000000000000000000000000000 +00AD:000000000000000000000000000000000000000000000000000000003FF03FF00000000000000000000000000000000000000000000000000000000000000000 +00AE:00000000000000003FF03FF0F03CF03CC00CC00CCFCCCFCCCCCCCCCCCF0CCF0CCCCCCCCCC00CC00CF03CF03C3FF03FF000000000000000000000000000000000 +00AF:00000000FFFCFFFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00B0:000000000FC00FC03CF03CF03CF03CF00FC00FC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00B1:0000000000000000000000000000000003C003C003C003C03FFC3FFC03C003C003C003C00000000000000000FFFFFFFF00000000000000000000000000000000 +00B2:000000003F003F00F3C0F3C00F000F003C003C00F0C0F0C0FFC0FFC0000000000000000000000000000000000000000000000000000000000000000000000000 +00B3:00000000FFC0FFC003C003C00F000F0003C003C0F3C0F3C03F003F00000000000000000000000000000000000000000000000000000000000000000000000000 +00B4:03C003C00F000F003C003C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00B5:000000000000000000000000000000003C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3FF03FF03C003C003C003C00F000F000000000000000000000000000 +00B6:00000000000000003FFF3FFFF3CFF3CFF3CFF3CFF3CFF3CF3FCF3FCF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF00000000000000000000000000000000 +00B7:000000000000000000000000000000000000000000000000000000000000000003C003C000000000000000000000000000000000000000000000000000000000 +00B8:0000000000000000000000000000000000000000000000000000000000000000000000000000000003C003C000F000F0003C003C0FF00FF00000000000000000 +00B9:000000003C003C00FC00FC003C003C003C003C003C003C00FF00FF00000000000000000000000000000000000000000000000000000000000000000000000000 +00BA:000000000FC00FC03CF03CF03CF03CF00FC00FC0000000003FF03FF0000000000000000000000000000000000000000000000000000000000000000000000000 +00BB:0000000000000000000000000000000000000000F3C0F3C03CF03CF00F3C0F3C3CF03CF0F3C0F3C0000000000000000000000000000000000000000000000000 +00BC:00000000F000F000F000F000F00CF00CF03CF03CF0F0F0F003C003C00F000F003C3C3C3CF0FCF0FCC3FCC3FC0FFC0FFC003C003C003C003C0000000000000000 +00BD:00000000F000F000F000F000F00CF00CF03CF03CF0F0F0F003C003C00F000F003C003C00F3F0F3F0C03CC03C00F000F003C003C00FFC0FFC0000000000000000 +00BE:00000000FF00FF000F000F003F0C3F0C0F3C0F3CFCF0FCF003C003C00F000F003C3C3C3CF0FCF0FCC33CC33C0FFC0FFC003C003C003C003C0000000000000000 +00BF:00000000000000000F000F000F000F00000000000F000F000F000F003C003C00F000F000F03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +00C0:3C003C000F000F0003C003C0000000000FC00FC03CF03CF0F03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +00C1:00F000F003C003C00F000F00000000000FC00FC03CF03CF0F03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +00C2:030003000FC00FC03CF03CF0000000000FC00FC03CF03CF0F03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +00C3:000000003F3C3F3CF3F0F3F0000000000FC00FC03CF03CF0F03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +00C4:00000000F03CF03C00000000030003000FC00FC03CF03CF0F03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +00C5:0FC00FC03CF03CF00FC00FC0000000000FC00FC03CF03CF0F03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +00C6:00000000000000000FFC0FFC3CF03CF0F0F0F0F0F0F0F0F0FFFCFFFCF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0FCF0FC00000000000000000000000000000000 +00C7:00000000000000000FF00FF03C3C3C3CF00CF00CF000F000F000F000F000F000F00CF00C3C3C3C3C0FF00FF000F000F0003C003C3FF03FF00000000000000000 +00C8:0F000F0003C003C000F000F000000000FFFCFFFC3C3C3C3C3C003C003FF03FF03C003C003C003C003C3C3C3CFFFCFFFC00000000000000000000000000000000 +00C9:03C003C00F000F003C003C0000000000FFFCFFFC3C3C3C3C3C003C003FF03FF03C003C003C003C003C3C3C3CFFFCFFFC00000000000000000000000000000000 +00CA:030003000FC00FC03CF03CF000000000FFFCFFFC3C3C3C3C3C003C003FF03FF03C003C003C003C003C3C3C3CFFFCFFFC00000000000000000000000000000000 +00CB:00000000F03CF03C00000000FFFCFFFC3C3C3C3C3C003C003C003C003FF03FF03C003C003C003C003C3C3C3CFFFCFFFC00000000000000000000000000000000 +00CC:0F000F0003C003C000F000F0000000000FF00FF003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +00CD:00F000F003C003C00F000F00000000000FF00FF003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +00CE:03C003C00FF00FF03C3C3C3C000000000FF00FF003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +00CF:000000003C3C3C3C000000000FF00FF003C003C003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +00D0:00000000000000003FC03FC03CF03CF03C3C3C3C3C3C3C3C3C3C3C3CFF3CFF3C3C3C3C3C3C3C3C3C3CF03CF03FC03FC000000000000000000000000000000000 +00D1:3F3C3F3CF3F0F3F000000000F03CF03CFC3CFC3CFF3CFF3CFFFCFFFCF3FCF3FCF0FCF0FCF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +00D2:3C003C000F000F0003C003C0000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +00D3:00F000F003C003C00F000F00000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +00D4:030003000FC00FC03CF03CF0000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +00D5:3F3C3F3CF3F0F3F0000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +00D6:00000000F03CF03C000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +00D7:00000000000000000000000000000000F03CF03C3CF03CF00FC00FC0030003000FC00FC03CF03CF0F03CF03C0000000000000000000000000000000000000000 +00D8:000C000C003C003C3FF03FF0F0FCF0FCF0FCF0FCF3FCF3FCF33CF33CF33CF33CFF3CFF3CFC3CFC3CFC3CFC3C3FF03FF0F000F000C000C0000000000000000000 +00D9:3C003C000F000F0003C003C000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +00DA:00F000F003C003C00F000F0000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +00DB:030003000FC00FC03CF03CF000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +00DC:00000000F03CF03C00000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +00DD:00F000F003C003C00F000F0000000000F00FF00FF00FF00F3C3C3C3C0FF00FF003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +00DE:FF00FF003C003C003FF03FF03C3C3C3C3C3C3C3C3C3C3C3C3FF03FF03C003C003C003C003C003C003C003C00FF00FF0000000000000000000000000000000000 +00DF:00000000000000003FC03FC0F0F0F0F0F0F0F0F0F0F0F0F0F3C0F3C0F0F0F0F0F03CF03CF03CF03CF03CF03CF0F0F0F000000000000000000000000000000000 +00E0:000000003C003C000F000F0003C003C0000000003FC03FC000F000F03FF03FF0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +00E1:0000000003C003C00F000F003C003C00000000003FC03FC000F000F03FF03FF0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +00E2:00000000030003000FC00FC03CF03CF0000000003FC03FC000F000F03FF03FF0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +00E3:00000000000000003F3C3F3CF3F0F3F0000000003FC03FC000F000F03FF03FF0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +00E4:0000000000000000F0F0F0F000000000000000003FC03FC000F000F03FF03FF0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +00E5:000000000FC00FC03CF03CF00FC00FC0000000003FC03FC000F000F03FF03FF0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +00E6:0000000000000000000000000000000000000000F0F0F0F03F3C3F3C0F3C0F3C3FFC3FFCF3C0F3C0F3C0F3C03CFC3CFC00000000000000000000000000000000 +00E7:000000000000000000000000000000000FF00FF03C3C3C3C3C003C003C003C003C3C3C3C0FF00FF000F000F0003C003C0FF00FF0000000000000000000000000 +00E8:000000003C003C000F000F0003C003C0000000003FF03FF0F03CF03CFFFCFFFCF000F000F000F000F03CF03C3FF03FF000000000000000000000000000000000 +00E9:0000000000F000F003C003C00F000F00000000003FF03FF0F03CF03CFFFCFFFCF000F000F000F000F03CF03C3FF03FF000000000000000000000000000000000 +00EA:00000000030003000FC00FC03CF03CF0000000003FF03FF0F03CF03CFFFCFFFCF000F000F000F000F03CF03C3FF03FF000000000000000000000000000000000 +00EB:0000000000000000F03CF03C00000000000000003FF03FF0F03CF03CFFFCFFFCF000F000F000F000F03CF03C3FF03FF000000000000000000000000000000000 +00EC:000000003C003C000F000F0003C003C0000000000FC00FC003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +00ED:0000000000F000F003C003C00F000F00000000000FC00FC003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +00EE:0000000003C003C00FF00FF03C3C3C3C000000000FC00FC003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +00EF:00000000000000003C3C3C3C00000000000000000FC00FC003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +00F0:000000003CF03CF00FC00FC00FC00FC03CF03CF000F000F00FF00FF03CF03CF0F0F0F0F0F0F0F0F0F0F0F0F03FC03FC000000000000000000000000000000000 +00F1:00000000000000003F3C3F3CF3F0F3F000000000F3F0F3F03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C00000000000000000000000000000000 +00F2:000000003C003C000F000F0003C003C0000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +00F3:0000000003C003C00F000F003C003C00000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +00F4:00000000030003000FC00FC03CF03CF0000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +00F5:00000000000000003F3C3F3CF3F0F3F0000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +00F6:0000000000000000F03CF03C00000000000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +00F7:0000000000000000000000000000000003C003C003C003C0000000003FFC3FFC0000000003C003C003C003C00000000000000000000000000000000000000000 +00F8:000000000000000000000000000C000C003C003C3FF03FF0F0FCF0FCF3FCF3FCF33CF33CFF3CFF3CFC3CFC3C3FF03FF0F000F000C000C0000000000000000000 +00F9:000000003C003C000F000F0003C003C000000000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +00FA:0000000003C003C00F000F003C003C0000000000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +00FB:000000000F000F003FC03FC0F0F0F0F000000000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +00FC:0000000000000000F0F0F0F00000000000000000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +00FD:0000000003C003C00F000F003C003C0000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FFC3FFC003C003C00F000F0FFC0FFC000000000 +00FE:000000000000000000000000FF00FF003C003C003FF03FF03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3FF03FF03C003C003C003C00FF00FF0000000000 +00FF:0000000000000000F03CF03C0000000000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FFC3FFC003C003C00F000F03FC03FC000000000 +0100:000000003FF03FF0000000000FC00FC03CF03CF0F03CF03CF03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03CF03CF03C000000000000000000000000 +0101:000000000000000000000000000000003FF03FF0000000003FC03FC000F000F03FF03FF0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C000000000000000000000000 +0102:F03CF03C3FF03FF000000000030003000FC00FC03CF03CF0F03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +0103:0000000000000000F03CF03C3FF03FF0000000003FC03FC000F000F03FF03FF0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +0104:0000000000000000030003000FC00FC03CF03CF0F03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03CF03CF03C03C003C00F000F0003FC03FC00000000 +0105:00000000000000000000000000000000000000003FC03FC000F000F03FF03FF0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C03C003C00F000F0003FC03FC00000000 +0106:00F000F003C003C0000000000FF00FF03C3C3C3CF00CF00CF000F000F000F000F000F000F00CF00C3C3C3C3C0FF00FF000000000000000000000000000000000 +0107:0000000000F000F003C003C00F000F00000000003FF03FF0F03CF03CF000F000F000F000F000F000F03CF03C3FF03FF000000000000000000000000000000000 +010C:3CF03CF00FC00FC0000000000FF00FF03C3C3C3CF00CF00CF000F000F000F000F000F000F00CF00C3C3C3C3C0FF00FF000000000000000000000000000000000 +010D:00000000000000003CF03CF00FC00FC0000000003FF03FF0F03CF03CF000F000F000F000F000F000F03CF03C3FF03FF000000000000000000000000000000000 +010E:3CF03CF00FC00FC000000000FFC0FFC03CF03CF03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3CF03CF0FFC0FFC000000000000000000000000000000000 +010F:3CF03CF00FC00FC00000000003F003F000F000F000F000F00FF00FF03CF03CF0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +0110:0000000000000000FFC0FFC03CF03CF03C3C3C3C3C3C3C3CFF3CFF3C3C3C3C3C3C3C3C3C3C3C3C3C3CF03CF0FFC0FFC000000000000000000000000000000000 +0111:000000000000000000F000F000F000F03FFC3FFC00F000F00FF00FF03CF03CF0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +0112:3FF03FF00000000000000000FFFCFFFC3C3C3C3C3C003C003C003C003FF03FF03C003C003C003C003C003C003C3C3C3CFFFCFFFC000000000000000000000000 +0113:000000000000000000000000000000003FF03FF0000000003FF03FF0F03CF03CF03CF03CFFFCFFFCF000F000F03CF03C3FF03FF0000000000000000000000000 +0116:03C003C003C003C000000000FFFCFFFC3C3C3C3C3C003C003C003C003FC03FC03C003C003C003C003C003C003C3C3C3CFFFCFFFC000000000000000000000000 +0117:0000000000000000030003000FC00FC003000300000000003FF03FF0F03CF03CF03CF03CFFFCFFFCF000F000F03CF03C3FF03FF0000000000000000000000000 +0118:0000000000000000FFFCFFFC3C3C3C3C3C0C3C0C3CC03CC03FC03FC03CC03CC03C003C003C0C3C0C3C3C3C3CFFFCFFFC03C003C00F000F0003FC03FC00000000 +0119:00000000000000000000000000000000000000003FF03FF0F03CF03CFFFCFFFCF000F000F000F000F03CF03C3FF03FF00F000F003C003C000FF00FF000000000 +011A:3CF03CF00FC00FC000000000FFFCFFFC3C3C3C3C3C0C3C0C3CC03CC03FC03FC03CC03CC03C0C3C0C3C3C3C3CFFFCFFFC00000000000000000000000000000000 +011B:00000000000000003CF03CF00FC00FC0000000003FF03FF0F03CF03CFFFCFFFCF000F000F000F000F03CF03C3FF03FF000000000000000000000000000000000 +011E:300C300C0FF00FF0000000000FF00FF03C3C3C3CF00CF00CF000F000F3FCF3FCF03CF03CF03CF03C3C3C3C3C0FCC0FCC00000000000000000000000000000000 +011F:0000000000000000303030300FC00FC0000000003F3C3F3CF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03FF03FF000F000F0F0F0F0F03FC03FC000000000 +0122:0000000000000000000000003FF03FF0F03CF03CF03CF03CF000F000F000F000F0FCF0FCF0FCF0FCF03CF03CF03CF03C3FF03FF000F000F03FC03FC000000000 +0123:00000000000000000FF00FF03C003C000F000F00000000003F3C3F3CF0FCF0FCF03CF03CF03CF03CF03CF03CF0FCF0FC3F3C3F3C003C003CFFF0FFF000000000 +0128:3F3C3F3CF3F0F3F0000000000FF00FF003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF0000000000000000000000000 +0129:0000000000000000000000003F3C3F3CF3F0F3F0000000000FC00FC003C003C003C003C003C003C003C003C003C003C00FF00FF0000000000000000000000000 +012A:000000000FF00FF0000000000FF00FF003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF0000000000000000000000000 +012B:000000000000000000000000000000003FF03FF0000000000FC00FC003C003C003C003C003C003C003C003C003C003C00FF00FF0000000000000000000000000 +012E:0000000000000000000000000FF00FF003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF00F000F0003FC03FC00000000 +012F:00000000000000000000000003C003C003C003C0000000000FC00FC003C003C003C003C003C003C003C003C003C003C00FF00FF00F000F0003F003F000000000 +0130:000000000000000003C003C0000000000FF00FF003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +0131:00000000000000000000000000000000000000000FC00FC003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +0136:000000000000000000000000F03CF03CF03CF03CF0F0F0F0F3C0F3C0FF00FF00FF00FF00F3C0F3C0F0F0F0F0F03CF03CF03CF03C00F000F03FC03FC000000000 +0137:000000000000000000000000FC00FC003C003C003C003C003C3C3C3C3C3C3C3C3CF03CF03FC03FC03CF03CF03C3C3C3CFC3CFC3C03C003C0FF00FF0000000000 +0138:000000000000000000000000000000000000000000000000FC3CFC3C3CF03CF03FC03FC03FC03FC03CF03CF03C3C3C3CFC3CFC3C000000000000000000000000 +0139:0000000000000000FF3CFF3C3CF03CF03C003C003C003C003C003C003C003C003C003C003C0C3C0C3C3C3C3CFFFCFFFC00000000000000000000000000000000 +013A:0000000000000000FC3CFC3C3CF03CF03C003C003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF0000000000000000000000000000000000 +013B:000000000000000000000000FF00FF003C003C003C003C003C003C003C003C003C003C003C003C003C0C3C0C3C3C3C3CFFFCFFFC00F000F03FC03FC000000000 +013C:0000000000000000000000000FC00FC003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF000F000F03FC03FC000000000 +013D:0000000003CF03CFFCFCFCFC3C003C003C003C003C003C003C003C003C003C003C003C003C0C3C0C3C3C3C3CFFFCFFFC00000000000000000000000000000000 +013E:0000000003CF03CFFCFCFCFC3C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF0000000000000000000000000000000000 +0141:0000000000000000FF00FF003C303C303CF03CF03FC03FC03F003F00FC00FC00FC00FC003C0C3C0C3C3C3C3CFFFCFFFC00000000000000000000000000000000 +0142:00000000000000000FC00FC003CC03CC03FC03FC03F003F003C003C00FC00FC03FC03FC033C033C003C003C00FF00FF000000000000000000000000000000000 +0143:00F000F003C003C000000000F03CF03CFC3CFC3CFF3CFF3CFFFCFFFCF3FCF3FCF0FCF0FCF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +0144:0000000000F000F003C003C00F000F0000000000F3F0F3F03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C00000000000000000000000000000000 +0145:000000000000000000000000F03CF03CF03CF03CFC3CFC3CFF3CFF3CFFFCFFFCF3FCF3FCF0FCF0FCF03CF03CF03CF03CF03CF03C00F000F03FC03FC000000000 +0146:000000000000000000000000000000000000000000000000F3F0F3F03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C00F000F03FC03FC000000000 +0147:3CF03CF00FC00FC000000000F03CF03CFC3CFC3CFF3CFF3CFFFCFFFCF3FCF3FCF0FCF0FCF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +0148:00000000000000003CF03CF00FC00FC000000000F3F0F3F03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C00000000000000000000000000000000 +014A:000000000000000000000000F3F0F3F0FFFCFFFCFC3CFC3CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF3F0F3F0000000000000000000000000 +014B:0000000000000000000000000000000000000000F3F0F3F0FFFCFFFCFC3CFC3CF03CF03CF03CF03CF03CF03C003C003C03F003F0000000000000000000000000 +014C:000000003FF03FF0000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF0000000000000000000000000 +014D:000000000000000000000000000000003FF03FF0000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF0000000000000000000000000 +0150:0F3C0F3C3CF03CF0000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +0151:00000000000000000F3C0F3C3CF03CF0000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +0152:00000000000000003FFC3FFCF0F0F0F0F0F0F0F0F0F0F0F0F0FCF0FCF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03FFC3FFC00000000000000000000000000000000 +0153:00000000000000000000000000000000000000003CFC3CFCF3CFF3CFF3CFF3CFF3FCF3FCF3C0F3C0F3F0F3F03C3F3C3F00000000000000000000000000000000 +0154:00F000F003C003C000000000FFF0FFF03C3C3C3C3C3C3C3C3C3C3C3C3FF03FF03CF03CF03C3C3C3C3C3C3C3CFC3CFC3C00000000000000000000000000000000 +0155:0000000000F000F003C003C00F000F0000000000F3F0F3F03F3C3F3C3C3C3C3C3C003C003C003C003C003C00FF00FF0000000000000000000000000000000000 +0156:000000000000000000000000FFF0FFF03C3C3C3C3C3C3C3C3C3C3C3C3FF03FF03FC03FC03CF03CF03C3C3C3C3C3C3C3CFF3CFF3C03C003C0FF00FF0000000000 +0157:000000000000000000000000000000000000000000000000F3F0F3F03C3C3C3C3C003C003C003C003C003C003C003C00FF00FF0003C003C0FF00FF0000000000 +0158:3CF03CF00FC00FC000000000FFF0FFF03C3C3C3C3C3C3C3C3C3C3C3C3FF03FF03CF03CF03C3C3C3C3C3C3C3CFC3CFC3C00000000000000000000000000000000 +0159:00000000000000003CF03CF00FC00FC000000000F3F0F3F03F3C3F3C3C3C3C3C3C003C003C003C003C003C00FF00FF0000000000000000000000000000000000 +015A:00F000F003C003C0000000003FF03FF0F03CF03CF03CF03C3C003C000FC00FC000F000F0F03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +015B:0000000000F000F003C003C00F000F00000000003FF03FF0F03CF03C3C003C000FC00FC000F000F0F03CF03C3FF03FF000000000000000000000000000000000 +015E:00000000000000003FF03FF0F03CF03CF03CF03C3C003C000FC00FC000F000F0003C003CF03CF03CF03CF03C3FF03FF003C003C000F000F03FC03FC000000000 +015F:00000000000000000000000000000000000000003FF03FF0F03CF03C3C003C000FC00FC000F000F0F03CF03C3FF03FF003C003C000F000F03FC03FC000000000 +0160:3CF03CF00FC00FC0000000003FF03FF0F03CF03CF03CF03C3C003C000FC00FC000F000F0F03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +0161:00000000000000003CF03CF00FC00FC0000000003FF03FF0F03CF03C3C003C000FC00FC000F000F0F03CF03C3FF03FF000000000000000000000000000000000 +0162:00000000000000003FFC3FFC3FFC3FFC33CC33CC03C003C003C003C003C003C003C003C003C003C003C003C00FF00FF003C003C000F000F03FC03FC000000000 +0163:0000000000000000030003000F000F000F000F00FFF0FFF00F000F000F000F000F000F000F000F000F3C0F3C03F003F003C003C000F000F03FC03FC000000000 +0164:0F3C0F3C03F003F0000000003FFC3FFC3FFC3FFC33CC33CC03C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +0165:3CF03CF00FC00FC000000000030003000F000F000F000F00FFF0FFF00F000F000F000F000F000F000F3C0F3C03F003F000000000000000000000000000000000 +0166:000000000000000000000000FFFFFFFFF3CFF3CFC3C3C3C303C003C003FC03FC0FF00FF03FC03FC003C003C003C003C00FF00FF0000000000000000000000000 +0167:0000000000000000000000000F000F000F000F000F000F00FFF0FFF00F000F000FF00FF03FC03FC0FF00FF000F3C0F3C03F003F0000000000000000000000000 +0168:3F3C3F3CF3F0F3F000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF0000000000000000000000000 +0169:0000000000000000000000003F3C3F3CF3F0F3F000000000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C000000000000000000000000 +016A:000000003FF03FF000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF0000000000000000000000000 +016B:00000000000000000000000000000000FFF0FFF000000000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C000000000000000000000000 +016E:0FC00FC03CF03CF00FC00FC0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +016F:000000000FC00FC03CF03CF00FC00FC000000000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +0170:0F3C0F3C3CF03CF000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +0171:00000000000000000F3C0F3C3CF03CF000000000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C00000000000000000000000000000000 +0172:000000000000000000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF03C003C000FF00FF000000000 +0173:000000000000000000000000000000000000000000000000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03F3C3F3C3C003C000FF00FF000000000 +0178:00000000F00FF00F00000000F00FF00FF00FF00F3C3C3C3C0FF00FF003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +0179:00F000F003C003C000000000FFFCFFFCF03CF03CC0F0C0F003C003C00F000F003C003C00F00CF00CF03CF03CFFFCFFFC00000000000000000000000000000000 +017A:0000000000F000F003C003C00F000F0000000000FFFCFFFCF0F0F0F003C003C00F000F003C003C00F03CF03CFFFCFFFC00000000000000000000000000000000 +017B:03C003C003C003C000000000FFFCFFFCF03CF03CC0F0C0F003C003C00F000F003C003C00F00CF00CF03CF03CFFFCFFFC00000000000000000000000000000000 +017C:000000000000000003C003C003C003C000000000FFFCFFFCF0F0F0F003C003C00F000F003C003C00F03CF03CFFFCFFFC00000000000000000000000000000000 +017D:3CF03CF00FC00FC000000000FFFCFFFCF03CF03CC0F0C0F003C003C00F000F003C003C00F00CF00CF03CF03CFFFCFFFC00000000000000000000000000000000 +017E:00000000000000003CF03CF00FC00FC000000000FFFCFFFCF0F0F0F003C003C00F000F003C003C00F03CF03CFFFCFFFC00000000000000000000000000000000 +0192:0000000000FC00FC03CF03CF03C003C003C003C003C003C03FFC3FFC03C003C003C003C003C003C003C003C003C003C0F3C0F3C03F003F000000000000000000 +02C7:000000003CF03CF00FC00FC000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +02D8:00000000F03CF03C3FF03FF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +02D9:0000000003C003C003C003C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +02DB:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F000F003C003C000FF00FF000000000 +02DD:000000000F3C0F3C3CF03CF0F3C0F3C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +037A:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0384:003C003C00F000F003C003C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0385:003C003C00F000F003C003C0F00FF00F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0386:00000000F000F000C300C300CFC0CFC03CF03CF0F03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +0388:0000000000000000CFFFCFFFCF03CF030F000F000F000F000FFC0FFC0F000F000F000F000F030F030F030F030FFF0FFF00000000000000000000000000000000 +0389:0000000000000000CF0FCF0FCF0FCF0F0F0F0F0F0F0F0F0F0FFF0FFF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0000000000000000000000000000000000000000 +038A:0000000000000000CFF0CFF0C3C0C3C003C003C003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +038C:0000000000000000C3FCC3FCCF0FCF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03FC03FC0000000000000000000000000000000000000000 +038E:0000000000000000CF0FCF0FCF0FCF0F0F0F0F0F0F0F0F0F03FC03FC00F000F000F000F000F000F000F000F003FC03FC00000000000000000000000000000000 +038F:0000000000000000C3FCC3FCCF0FCF0F0C030C030C030C030C030C030C030C030C030C030F0F0F0F030C030C0F0F0F0F00000000000000000000000000000000 +0390:00F000F000C000C0000000003C3C3C3C0000000003C003C003C003C003C003C003C003C003C003C003C003C000FC00FC00000000000000000000000000000000 +0391:0000000000000000030003000FC00FC03CF03CF0F03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +0392:0000000000000000FFF0FFF03C3C3C3C3C3C3C3C3C3C3C3C3FF03FF03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3CFFF0FFF000000000000000000000000000000000 +0393:0000000000000000FFFCFFFCF03CF03CF03CF03CF000F000F000F000F000F000F000F000F000F000F000F000F000F00000000000000000000000000000000000 +0394:0000000000000000030003000FC00FC03CF03CF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CFFFCFFFC00000000000000000000000000000000 +0395:0000000000000000FFFCFFFC3C3C3C3C3C0C3C0C3CC03CC03FC03FC03CC03CC03C003C003C0C3C0C3C3C3C3CFFFCFFFC00000000000000000000000000000000 +0396:0000000000000000FFFCFFFCF03CF03CC03CC03C00F000F003C003C00F000F003C003C00F00CF00CF03CF03CFFFCFFFC00000000000000000000000000000000 +0397:0000000000000000F03CF03CF03CF03CF03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +0398:0000000000000000000000000FC00FC03CF03CF0F03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03C3CF03CF00FC00FC000000000000000000000000000000000 +0399:00000000000000000FF00FF003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +039A:0000000000000000FC3CFC3C3C3C3C3C3C3C3C3C3CF03CF03FC03FC03FC03FC03CF03CF03C3C3C3C3C3C3C3CFC3CFC3C00000000000000000000000000000000 +039B:0000000000000000030003000FC00FC03CF03CF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +039C:0000000000000000F03CF03CFCFCFCFCFFFCFFFCFFFCFFFCF33CF33CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +039D:0000000000000000F03CF03CFC3CFC3CFF3CFF3CFFFCFFFCF3FCF3FCF0FCF0FCF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +039E:0000000000000000FFFCFFFCC00CC00C00000000000000003FF03FF0000000000000000000000000C00CC00CFFFCFFFC00000000000000000000000000000000 +039F:00000000000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +03A0:0000000000000000FFFCFFFCF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +03A1:0000000000000000FFF0FFF03C3C3C3C3C3C3C3C3C3C3C3C3FF03FF03C003C003C003C003C003C003C003C00FF00FF0000000000000000000000000000000000 +03A3:000000000000000000000000FFFCFFFCF03CF03C3C003C000F000F0003C003C00F000F003C003C00F03CF03CFFFCFFFC00000000000000000000000000000000 +03A4:00000000000000003FFC3FFC3FFC3FFC33CC33CC03C003C003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +03A5:00000000000000003C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C0FF00FF003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +03A6:0000000000000000000000003FFC3FFC03C003C00FF00FF03C3C3C3C3C3C3C3C3C3C3C3C0FF00FF003C003C03FFC3FFC00000000000000000000000000000000 +03A7:0000000000000000F03CF03CF03CF03C3CF03CF03FF03FF00FC00FC00FC00FC03FF03FF03CF03CF0F03CF03CF03CF03C00000000000000000000000000000000 +03A8:000000000000000003C003C0F3CFF3CFF3CFF3CFF3CFF3CFF3CFF3CFF3CFF3CF3FFC3FFC03C003C003C003C00FF00FF000000000000000000000000000000000 +03A9:00000000000000000FC00FC03CF03CF0F03CF03CF03CF03CF03CF03C3CF03CF03CF03CF03CF03CF03CF03CF0FCFCFCFC00000000000000000000000000000000 +03AA:00000000F00FF00F03C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C000000000000000000000000000000000 +03AB:F00FF00F000000003C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C0FF00FF003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +03AC:00000000000000000FC00FC003000300000000003FCF3FCFF0FCF0FCF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03FCF3FCF00000000000000000000000000000000 +03AD:00000000000000000FC00FC003000300000000003FF03FF0F03CF03CF000F0003FC03FC0F000F000F03CF03C3FF03FF000000000000000000000000000000000 +03AE:00000000000000000FC00FC00300030000000000F3F0F3F03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C003C003C003C003C003C003C00000000 +03AF:00000000000000000FC00FC0030003000000000003C003C003C003C003C003C003C003C003C003C003C003C000FC00FC00000000000000000000000000000000 +03B0:0000000003C003C0F00FF00F0000000000000000FC3FFC3F3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C0FF00FF000000000000000000000000000000000 +03B1:00000000000000000000000000000000000000003F3C3F3CF3F0F3F0F3C0F3C0F3C0F3C0F3C0F3C0F3F0F3F03F3C3F3C00000000000000000000000000000000 +03B2:00000000000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CFFF0FFF0F03CF03CF03CF03CF03CF03CFFF0FFF0F000F000F000F000F000F00000000000 +03B3:0000000000000000000000000000000000000000F00FF00F3C3C3C3C0FF00FF003C003C00FF00FF03C3C3C3C300C300C3C3C3C3C0FF00FF00000000000000000 +03B4:000000000000000003FC03FC0F000F0003C003C000F000F00FFC0FFC3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C0FF00FF000000000000000000000000000000000 +03B5:000000000000000003F003F00F000F003C003C003C003C003FF03FF03C003C003C003C003C003C000F000F0003F003F000000000000000000000000000000000 +03B6:0000000000000000FFF0FFF000F000F003C003C00F000F003C003C00F000F000F000F000F000F000F000F0003FC03FC000F000F000F000F03FC03FC000000000 +03B7:0000000000000000000000000000000000000000F3F0F3F03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C003C003C003C003C003C003C00000000 +03B8:00000000000000000FFC0FFC3C0F3C0F3C0F3C0F3C0F3C0F3FFF3FFF3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F0FFC0FFC00000000000000000000000000000000 +03B9:000000000000000000000000000000000000000003C003C003C003C003C003C003C003C003C003C003C003C000FC00FC00000000000000000000000000000000 +03BA:0000000000000000000000000000000000000000FC3CFC3C3CF03CF03FC03FC03FC03FC03CF03CF03C3C3C3CFC3CFC3C00000000000000000000000000000000 +03BB:00000000000000000FC00FC03CF03CF000F000F000F000F000F000F00F3C0F3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C00000000000000000000000000000000 +03BC:00000000000000000000000000000000000000003C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3FFF3FFF3C003C003C003C003C003C0000000000 +03BD:0000000000000000000000000000000000000000C00CC00CF03CF03CF03CF03C3CF03CF03CF03CF00FC00FC00FC00FC000000000000000000000000000000000 +03BE:0000000000000000FFF0FFF03C003C00F000F0003FC03FC00F000F003C003C00F000F000F000F000F000F0003FF03FF0003C003C003C003C0FF00FF000000000 +03BF:00000000000000000000000000000000000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +03C0:00000000000000000000000000000000FFFCFFFC3CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF000000000000000000000000000000000 +03C1:00000000000000000000000000000000000000000FF00FF03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3FF03FF03C003C003C003C003C003C0000000000 +03C2:00000000000000000000000000000000000000000FFC0FFC3C0F3C0FF000F000F000F0003C003C000FC00FC000F000F0F03CF03C3FF03FF00000000000000000 +03C3:00000000000000000000000000000000000000003FFC3FFCF3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C03F003F0000000000000000000000000000000000 +03C4:000000000000000000000000000000003F3C3F3CF3F0F3F003C003C003C003C003C003C003C003C003C003C003C003C000000000000000000000000000000000 +03C5:0000000000000000000000000000000000000000FC3FFC3F3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C0FF00FF000000000000000000000000000000000 +03C6:000000000000000000000000000F000F003C003C3FFC3FFCF3CFF3CFF3CFF3CFFF0FFF0F3FFC3FFC3C003C00F000F00000000000000000000000000000000000 +03C7:0000000000000000000000000000000000000000F03CF03C3CF03CF00FC00FC00FC00FC00FC00FC03CF03CF0F03CF03C00000000000000000000000000000000 +03C8:0000000000000000000000000000000000000000F33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33C3FF03FF003000300030003000300030000000000 +03C9:00000000000000000000000000000000000000003C3C3C3CF00FF00FF00FF00FF00FF00FF3CFF3CFFFFFFFFF3C3C3C3C00000000000000000000000000000000 +03CA:0000000000000000F00FF00F000000000000000003C003C003C003C003C003C003C003C003C003C003C003C000FC00FC00000000000000000000000000000000 +03CB:0000000000000000F00FF00F0000000000000000FC3FFC3F3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C0FF00FF000000000000000000000000000000000 +03CC:00000000000000000FC00FC003000300000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +03CD:00000000000000000FC00FC00300030000000000FC3FFC3F3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C0FF00FF000000000000000000000000000000000 +03CE:00000000000000000FC00FC003000300000000003C3C3C3CF00FF00FF00FF00FF00FF00FF3CFF3CFFFFFFFFF3C3C3C3C00000000000000000000000000000000 +0401:3C3C3C3C3C3C3C3C00000000FFFCFFFCF03CF03CF000F000F000F000FF00FF00F000F000F000F000F03CF03CFFFCFFFC00000000000000000000000000000000 +0402:0000000000000000FFC0FFC03C003C003C003C003C003C003FF03FF03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3CF03CF000000000000000000000000000000000 +0403:03C003C00F000F00000000003FFC3FFC3C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0000000000000000000000000000000000 +0404:00000000000000000FF00FF03C3C3C3CF000F000F000F000FFC0FFC0F000F000F000F000F000F0003C3C3C3C0FF00FF000000000000000000000000000000000 +0405:00000000000000003FF03FF0F03CF03CF03CF03C3C003C000FC00FC000F000F0003C003CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +0406:0000000003C003C0000000000FF00FF003C003C003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +0407:000000003C3C3C3C000000000FF00FF003C003C003C003C003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +0408:000000000000000003FC03FC00F000F000F000F000F000F000F000F000F000F0F0F0F0F0F0F0F0F0F0F0F0F03FC03FC000000000000000000000000000000000 +0409:000000000000000003C003C00FC00FC03FC03FC0F3C0F3C0F3C0F3C0F3FCF3FCF3CFF3CFF3CFF3CFF3CFF3CFF3FCF3FC00000000000000000000000000000000 +040A:0000000000000000F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0FFFCFFFCF3CFF3CFF3CFF3CFF3CFF3CFF3FCF3FC00000000000000000000000000000000 +040B:0000000000000000FFF0FFF00F000F000F000F000F000F000FF00FF00F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C00000000000000000000000000000000 +040C:03C003C00F000F0000000000F03CF03CF0F0F0F0F3C0F3C0FF00FF00FFC0FFC0F0F0F0F0F03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +040E:0CC00CC00300030000000000F03CF03CF03CF03CF03CF03CF03CF03C3FFC3FFC003C003C003C003CF03CF03C3FF03FF000000000000000000000000000000000 +040F:0000000000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CFFFCFFFC0FC00FC00FC00FC000000000000000000000000000000000 +0410:00000000000000000FFC0FFC3C3C3C3CF03CF03CF03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +0411:0000000000000000FFFCFFFCF000F000F000F000F000F000FFF0FFF0F03CF03CF03CF03CF03CF03CF03CF03CFFF0FFF000000000000000000000000000000000 +0412:0000000000000000FFF0FFF0F03CF03CF03CF03CF03CF03CFFF0FFF0F03CF03CF03CF03CF03CF03CF03CF03CFFF0FFF000000000000000000000000000000000 +0413:0000000000000000FFFCFFFCF03CF03CF000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F00000000000000000000000000000000000 +0414:00000000000000000FF00FF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF0FFFCFFFCF03CF03CC00CC00C0000000000000000 +0415:0000000000000000FFFCFFFCF03CF03CF000F000F000F000FF00FF00F000F000F000F000F000F000F03CF03CFFFCFFFC00000000000000000000000000000000 +0416:0000000000000000F33CF33CF33CF33CF33CF33C333033303FF03FF0F33CF33CF33CF33CF33CF33CF33CF33CF33CF33C00000000000000000000000000000000 +0417:00000000000000003FF03FF0F03CF03C003C003C003C003C03F003F0003C003C003C003CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +0418:0000000000000000F03CF03CF03CF03CF03CF03CF03CF03CF0FCF0FCF3FCF3FCFF3CFF3CFC3CFC3CF03CF03CF03CF03C00000000000000000000000000000000 +0419:0000000000F000F0F3CCF3CCF03CF03CF03CF03CF03CF03CF0FCF0FCF3FCF3FCFF3CFF3CFC3CFC3CF03CF03CF03CF03C00000000000000000000000000000000 +041A:0000000000000000F03CF03CF0F0F0F0F3C0F3C0FF00FF00FF00FF00F3C0F3C0F0F0F0F0F03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +041B:000000000000000003FC03FC0F3C0F3C3C3C3C3CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +041C:0000000000000000F03CF03CF03CF03CFCFCFCFCFCFCFCFCFFFCFFFCFFFCFFFCF33CF33CF33CF33CF03CF03CF03CF03C00000000000000000000000000000000 +041D:0000000000000000F03CF03CF03CF03CF03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +041E:00000000000000003FFC3FFCF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CFFF0FFF000000000000000000000000000000000 +041F:0000000000000000FFFCFFFCF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +0420:0000000000000000FFF0FFF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CFFF0FFF0F000F000F000F000F000F00000000000000000000000000000000000 +0421:00000000000000003FF03FF0F03CF03CF03CF03CF000F000F000F000F000F000F000F000F03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +0422:00000000000000003FFC3FFC3FFC3FFC33CC33CC03C003C003C003C003C003C003C003C003C003C003C003C003C003C000000000000000000000000000000000 +0423:0000000000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FFC3FFC003C003CF03CF03C3FF03FF000000000000000000000000000000000 +0424:00000000000000003FF03FF0F33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33C3FF03FF0030003000FC00FC000000000000000000000000000000000 +0425:0000000000000000F03CF03CF03CF03C3CF03CF00FC00FC00FC00FC03CF03CF0F03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +0426:0000000000000000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0FFFCFFFC000C000C003C003C0030003000000000 +0427:0000000000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FFC3FFC003C003C003C003C003C003C003C003C00000000000000000000000000000000 +0428:0000000000000000F33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CFFFCFFFC00000000000000000000000000000000 +0429:0000000000000000F33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CFFFCFFFC000C000C003C003C0030003000000000 +042A:0000000000000000FC00FC00FC00FC003C003C003C003C003FF03FF03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3FF03FF000000000000000000000000000000000 +042B:0000000000000000F03CF03CF03CF03CF03CF03CF03CF03CFC3CFC3CCF3CCF3CCF3CCF3CCF3CCF3CCF3CCF3CFC3CFC3C00000000000000000000000000000000 +042C:0000000000000000F000F000F000F000F000F000F000F000FFF0FFF0F03CF03CF03CF03CF03CF03CF03CF03CFFF0FFF000000000000000000000000000000000 +042D:00000000000000003FC03FC0F0F0F0F0003C003C003C003C03FC03FC03FC03FC003C003C003C003CF0F0F0F03FC03FC000000000000000000000000000000000 +042E:0000000000000000C3F0C3F0CF3CCF3CCF3CCF3CCF3CCF3CFF3CFF3CCF3CCF3CCF3CCF3CCF3CCF3CCF3CCF3CC3F0C3F000000000000000000000000000000000 +042F:00000000000000003FFC3FFCF03CF03CF03CF03CF03CF03CF03CF03C3FFC3FFC0F3C0F3C3C3C3C3CF03CF03CF03CF03C00000000000000000000000000000000 +0430:00000000000000000000000000000000000000003FF03FF0F03CF03CF03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03C00000000000000000000000000000000 +0431:0000000000000000000000000000000000000000FFFCFFFCF000F000FFF0FFF0F03CF03CF03CF03CF03CF03CFFF0FFF000000000000000000000000000000000 +0432:0000000000000000000000000000000000000000FFF0FFF0F03CF03CF03CF03CFFF0FFF0F03CF03CF03CF03CFFF0FFF000000000000000000000000000000000 +0433:0000000000000000000000000000000000000000FFFCFFFCF03CF03CF00CF00CF000F000F000F000F000F000F000F00000000000000000000000000000000000 +0434:00000000000000000000000000000000000000000FF00FF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF0FFFCFFFCF03CF03CC00CC00C0000000000000000 +0435:00000000000000000000000000000000000000003FF03FF0F03CF03CF03CF03CFFF0FFF0F000F000F03CF03C3FF03FF000000000000000000000000000000000 +0436:0000000000000000000000000000000000000000F33CF33CF33CF33CF33CF33C3FF03FF0F33CF33CF33CF33CF33CF33C00000000000000000000000000000000 +0437:00000000000000000000000000000000000000003FF03FF0F03CF03C003C003C03F003F0003C003CF03CF03C3FF03FF000000000000000000000000000000000 +0438:0000000000000000000000000000000000000000F03CF03CF03CF03CF0FCF0FCF3FCF3FCFF3CFF3CFC3CFC3CF03CF03C00000000000000000000000000000000 +0439:00000000000000000000000000F000F003C003C0F03CF03CF03CF03CF0FCF0FCF3FCF3FCFF3CFF3CFC3CFC3CF03CF03C00000000000000000000000000000000 +043A:0000000000000000000000000000000000000000F03CF03CF0F0F0F0F3C0F3C0FFC0FFC0F3C0F3C0F0F0F0F0F03CF03C00000000000000000000000000000000 +043B:00000000000000000000000000000000000000000FFC0FFC3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3CF03CF03C00000000000000000000000000000000 +043C:0000000000000000000000000000000000000000F03CF03CFCFCFCFCFFFCFFFCF33CF33CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +043D:0000000000000000000000000000000000000000F03CF03CF03CF03CF03CF03CFFFCFFFCF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +043E:00000000000000000000000000000000000000003FFC3FFCF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CFFF0FFF000000000000000000000000000000000 +043F:0000000000000000000000000000000000000000FFFCFFFCF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +0440:0000000000000000000000000000000000000000FFF0FFF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CFFF0FFF0F000F000F000F000F000F00000000000 +0441:00000000000000000000000000000000000000003FF03FF0F03CF03CF000F000F000F000F00CF00CF03CF03C3FF03FF000000000000000000000000000000000 +0442:00000000000000000000000000000000000000003FFC3FFC33CC33CC03C003C003C003C003C003C003C003C003C003C000000000000000000000000000000000 +0443:0000000000000000000000000000000000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FFC3FFC003C003CF03CF03C3FF03FF000000000 +0444:00000000000000000000000000000000030003003FF03FF0F33CF33CF33CF33CF33CF33CF33CF33CF33CF33C3FF03FF0030003000FC00FC00000000000000000 +0445:0000000000000000000000000000000000000000F03CF03C3CF03CF00FC00FC00FC00FC03CF03CF0F03CF03CF03CF03C00000000000000000000000000000000 +0446:0000000000000000000000000000000000000000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0FFFCFFFC003C003C00F000F00000000000000000 +0447:0000000000000000000000000000000000000000F03CF03CF03CF03CF03CF03CF03CF03C3FFC3FFC003C003C003C003C00000000000000000000000000000000 +0448:0000000000000000000000000000000000000000F33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CFFFCFFFC00000000000000000000000000000000 +0449:0000000000000000000000000000000000000000F33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CF33CFFFCFFFC000C000C003C003C0030003000000000 +044A:0000000000000000000000000000000000000000FC00FC003C003C003FF03FF03C3C3C3C3C3C3C3C3C3C3C3C3FF03FF000000000000000000000000000000000 +044B:0000000000000000000000000000000000000000F03CF03CF03CF03CFC3CFC3CCF3CCF3CCF3CCF3CCF3CCF3CFC3CFC3C00000000000000000000000000000000 +044C:0000000000000000000000000000000000000000F000F000F000F000FFF0FFF0F03CF03CF03CF03CF03CF03CFFF0FFF000000000000000000000000000000000 +044D:00000000000000000000000000000000000000003FF03FF0F03CF03C003C003C03FC03FC003C003CF03CF03C3FF03FF000000000000000000000000000000000 +044E:0000000000000000000000000000000000000000C3F0C3F0CF3CCF3CCF3CCF3CFF3CFF3CCF3CCF3CCF3CCF3CC3F0C3F000000000000000000000000000000000 +044F:00000000000000000000000000000000000000003FFC3FFCF03CF03CF03CF03C3FFC3FFC0F3C0F3C3C3C3C3CF03CF03C00000000000000000000000000000000 +0451:00000000000000003CF03CF03CF03CF0000000003FF03FF0F03CF03CF03CF03CFFF0FFF0F000F000F03CF03C3FF03FF000000000000000000000000000000000 +0452:00000000000000003C003C003C003C003C003C00FFC0FFC03C003C003FF03FF03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C00F000F0000000000000000000000000 +0453:000000000000000003C003C00F000F00000000003FF03FF03C003C003C003C003C003C003C003C003C003C003C003C0000000000000000000000000000000000 +0454:00000000000000000000000000000000000000003FF03FF0F03CF03CF000F000FF00FF00F000F000F03CF03C3FF03FF000000000000000000000000000000000 +0455:00000000000000000000000000000000000000003FF03FF0F03CF03C3C003C000FC00FC000F000F0F03CF03C3FF03FF000000000000000000000000000000000 +0456:00000000000000000300030003000300000000000FC00FC003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +0457:00000000000000000CC00CC00CC00CC0000000000FC00FC003C003C003C003C003C003C003C003C003C003C00FF00FF000000000000000000000000000000000 +0458:000000000000000000300030003000300000000000FC00FC003C003C003C003C003C003C003C003C003C003C003C003C3C3C3C3C3C3C3C3C0FF00FF000000000 +0459:000000000000000000000000000000000000000003C003C00FC00FC03FC03FC0F3FCF3FCF3CFF3CFF3CFF3CFF3FCF3FC00000000000000000000000000000000 +045A:0000000000000000000000000000000000000000F3C0F3C0F3C0F3C0F3C0F3C0FFFCFFFCF3CFF3CFF3CFF3CFF3FCF3FC00000000000000000000000000000000 +045B:00000000000000000F000F000F000F000F000F00FFF0FFF00F000F000FF00FF00F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C00000000000000000000000000000000 +045C:000000000000000003C003C00F000F0000000000F030F030F0F0F0F0F3C0F3C0FF00FF00F3C0F3C0F0F0F0F0F0F0F0F000000000000000000000000000000000 +045E:00000000000000000CC00CC00300030000000000F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C3FFC3FFC003C003CF03CF03C3FF03FF000000000 +045F:0000000000000000000000000000000000000000F03CF03CF03CF03CF03CF03CF03CF03CFFFCFFFC0FC00FC00FC00FC000000000000000000000000000000000 +05D0:00000000000000000000000000000000F03CF03CF03CF03C3C3C3C3C3F3C3F3CF3F0F3F0F0F0F0F0F03CF03CF03CF03C00000000000000000000000000000000 +05D1:00000000000000000000000000000000FFC0FFC000F000F000F000F000F000F000F000F000F000F000F000F0FFFCFFFC00000000000000000000000000000000 +05D2:000000000000000000000000000000000FC00FC000F000F000F000F000F000F000F000F003F003F00F3C0F3CFC3CFC3C00000000000000000000000000000000 +05D3:00000000000000000000000000000000FFFCFFFC00F000F000F000F000F000F000F000F000F000F000F000F000F000F000000000000000000000000000000000 +05D4:00000000000000000000000000000000FFF0FFF0003C003C003C003C003C003CF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +05D5:000000000000000000000000000000003F003F0003C003C003C003C003C003C003C003C003C003C003C003C003C003C000000000000000000000000000000000 +05D6:00000000000000000000000000000000FFF0FFF00F000F000F000F000F000F0003C003C003C003C00F000F003C003C0000000000000000000000000000000000 +05D7:00000000000000000000000000000000FFF0FFF03C3C3C3CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +05D8:00000000000000000000000000000000F0F0F0F0F33CF33CF33CF33CF03CF03CF03CF03CF03CF03CF03CF03C3FF03FF000000000000000000000000000000000 +05D9:000000000000000000000000000000003F003F0003C003C003C003C003C003C00F000F0000000000000000000000000000000000000000000000000000000000 +05DA:00000000000000000000000000000000FFF0FFF0003C003C003C003C003C003C00F000F000F000F000F000F000F000F000F000F000F000F000FC00FC00000000 +05DB:00000000000000000000000000000000FFF0FFF0003C003C003C003C003C003C003C003C003C003C003C003CFFF0FFF000000000000000000000000000000000 +05DC:0000000000000000F000F000F000F000FFF0FFF0003C003C003C003C003C003C003C003C00F000F003C003C003C003C000000000000000000000000000000000 +05DD:00000000000000000000000000000000FFF0FFF03C3C3C3CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CFFFCFFFC00000000000000000000000000000000 +05DE:00000000000000000000000000000000F3F0F3F03F3C3F3C3C3C3C3CF03CF03CF03CF03CF03CF03CF03CF03CF3FCF3FC00000000000000000000000000000000 +05DF:000000000000000000000000000000000FC00FC000F000F000F000F003C003C003C003C003C003C003C003C003C003C003C003C003C003C003F003F000000000 +05E0:000000000000000000000000000000000FC00FC000F000F000F000F000F000F000F000F000F000F000F000F03FF03FF000000000000000000000000000000000 +05E1:00000000000000000000000000000000FFF0FFF03C3C3C3CF03CF03CF03CF03CF03CF03CF03CF03CF0F0F0F03FC03FC000000000000000000000000000000000 +05E2:00000000000000000000000000000000FCFCFCFC3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C0CF00CF0FFC0FFC000000000000000000000000000000000 +05E3:00000000000000000000000000000000FFC0FFC030F030F0F0F0F0F0F0F0F0F0FCF0FCF000F000F000F000F000F000F000F000F000F000F000FC00FC00000000 +05E4:00000000000000000000000000000000FFF0FFF0303C303CF03CF03CF03CF03CFC3CFC3C003C003C003C003CFFFCFFFC00000000000000000000000000000000 +05E5:00000000000000000000000000000000FCFCFCFC3C3C3C3C3C3C3C3C3CF03CF03FC03FC03C003C003C003C003C003C003C003C003C003C003F003F0000000000 +05E6:00000000000000000000000000000000FCFCFCFC3C3C3C3C3C3C3C3C0F300F3003C003C000F000F0003C003CFFFCFFFC00000000000000000000000000000000 +05E7:00000000000000000000000000000000FFF0FFF0003C003C003C003C3C3C3C3C3C303C303CF03CF03CFC3CFC3C003C003C003C003C003C003C003C0000000000 +05E8:00000000000000000000000000000000FFF0FFF0003C003C003C003C003C003C003C003C003C003C003C003C003C003C00000000000000000000000000000000 +05E9:00000000000000000000000000000000F33CF33CF33CF33CF33CF33CF33CF33CF33CF33CFF3CFF3CF03CF03C3FF03FF000000000000000000000000000000000 +05EA:00000000000000000000000000000000FFF0FFF03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3CFC3CFC3CFC3CFC3C00000000000000000000000000000000 +200E:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +200F:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +2015:00000000000000000000000000000000000000000000000000000000FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000 +2017:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFF00000000FFFFFFFF00000000 +2018:000000000F000F003C003C003C003C000F000F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +2019:0000000000F000F0003C003C003C003C00F000F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +2022:00000000000000000000000000000000000000000000000003C003C00FF00FF00FF00FF003C003C0000000000000000000000000000000000000000000000000 +203C:00000000000000003C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C000000003C3C3C3C3C3C3C3C00000000000000000000000000000000 +207F:00000000F3C0F3C03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF0000000000000000000000000000000000000000000000000000000000000000000000000 +20A7:00000000FFC0FFC0F0F0F0F0F0F0F0F0FFC0FFC0F030F030F0F0F0F0F3FCF3FCF0F0F0F0F0F0F0F0F0F0F0F0F03CF03C00000000000000000000000000000000 +20AC:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +20AF:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +2116:0000000000000000C0C0C0C0C0CCC0CCF0F3F0F3FCCCFCCCCFC0CFC0C3C0C3C0C0CFC0CFC0C0C0C0C0CFC0CFC0C0C0C000000000000000000000000000000000 +2190:00000000000000000000000000000000000000000F000F003C003C00FFFCFFFC3C003C000F000F00000000000000000000000000000000000000000000000000 +2191:000000000000000003C003C00FF00FF03FFC3FFC03C003C003C003C003C003C003C003C003C003C003C003C003C003C000000000000000000000000000000000 +2192:000000000000000000000000000000000000000003C003C000F000F0FFFCFFFC00F000F003C003C0000000000000000000000000000000000000000000000000 +2193:000000000000000003C003C003C003C003C003C003C003C003C003C003C003C003C003C03FFC3FFC0FF00FF003C003C000000000000000000000000000000000 +2194:00000000000000000000000000000000000000000CC00CC03CF03CF0FFFCFFFC3CF03CF00CC00CC0000000000000000000000000000000000000000000000000 +2195:000000000000000003C003C00FF00FF03FFC3FFC03C003C003C003C003C003C03FFC3FFC0FF00FF003C003C00000000000000000000000000000000000000000 +21A8:000000000000000003C003C00FF00FF03FFC3FFC03C003C003C003C003C003C03FFC3FFC0FF00FF003C003C03FFC3FFC00000000000000000000000000000000 +2219:0000000000000000000000000000000000000000000000000000000003C003C003C003C000000000000000000000000000000000000000000000000000000000 +221A:0000000000FF00FF00F000F000F000F000F000F000F000F000F000F0FCF0FCF03CF03CF03CF03CF00FF00FF003F003F000000000000000000000000000000000 +221E:00000000000000000000000000000000000000003FFC3FFCF3CFF3CFF3CFF3CFF3CFF3CF3FFC3FFC000000000000000000000000000000000000000000000000 +221F:000000000000000000000000000000000000000000000000F000F000F000F000F000F000FFFCFFFC000000000000000000000000000000000000000000000000 +2229:0000000000000000000000003FF03FF0F03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03CF03C00000000000000000000000000000000 +2248:00000000000000000000000000000000000000003F3C3F3CF3F0F3F0000000003F3C3F3CF3F0F3F0000000000000000000000000000000000000000000000000 +2261:00000000000000000000000000000000FFFCFFFC0000000000000000FFFCFFFC0000000000000000FFFCFFFC0000000000000000000000000000000000000000 +2264:00000000000000000000000000F000F003C003C00F000F003C003C000F000F0003C003C000F000F0000000003FFC3FFC00000000000000000000000000000000 +2265:0000000000000000000000000F000F0003C003C000F000F0003C003C00F000F003C003C00F000F00000000003FFC3FFC00000000000000000000000000000000 +2302:00000000000000000000000000000000030003000FC00FC03CF03CF0F03CF03CF03CF03CF03CF03CFFFCFFFC0000000000000000000000000000000000000000 +2310:000000000000000000000000000000000000000000000000FFFCFFFCF000F000F000F000F000F000F000F0000000000000000000000000000000000000000000 +2320:000000000000000000FC00FC03CF03CF03CF03CF03C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0 +2321:03C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0F3C0F3C0F3C0F3C0F3C0F3C03F003F0000000000000000000000000000000000 +2500:00000000000000000000000000000000000000000000000000000000FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000 +2502:03C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0 +250C:0000000000000000000000000000000000000000000000000000000003FF03FF03C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0 +2510:00000000000000000000000000000000000000000000000000000000FFC0FFC003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0 +2514:03C003C003C003C003C003C003C003C003C003C003C003C003C003C003FF03FF0000000000000000000000000000000000000000000000000000000000000000 +2518:03C003C003C003C003C003C003C003C003C003C003C003C003C003C0FFC0FFC00000000000000000000000000000000000000000000000000000000000000000 +251C:03C003C003C003C003C003C003C003C003C003C003C003C003C003C003FF03FF03C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0 +2524:03C003C003C003C003C003C003C003C003C003C003C003C003C003C0FFC0FFC003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0 +252C:00000000000000000000000000000000000000000000000000000000FFFFFFFF03C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0 +2534:03C003C003C003C003C003C003C003C003C003C003C003C003C003C0FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000 +253C:03C003C003C003C003C003C003C003C003C003C003C003C003C003C0FFFFFFFF03C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0 +2550:0000000000000000000000000000000000000000FFFFFFFF00000000FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000 +2551:0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C +2552:000000000000000000000000000000000000000003FF03FF03C003C003FF03FF03C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0 +2553:000000000000000000000000000000000000000000000000000000000FFF0FFF0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C +2554:00000000000000000000000000000000000000000FFF0FFF0F000F000F3F0F3F0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C +2555:0000000000000000000000000000000000000000FFC0FFC003C003C0FFC0FFC003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0 +2556:00000000000000000000000000000000000000000000000000000000FFFCFFFC0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C +2557:0000000000000000000000000000000000000000FFFCFFFC003C003CFF3CFF3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C +2558:03C003C003C003C003C003C003C003C003C003C003FF03FF03C003C003FF03FF0000000000000000000000000000000000000000000000000000000000000000 +2559:0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0FFF0FFF0000000000000000000000000000000000000000000000000000000000000000 +255A:0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3F0F3F0F000F000FFF0FFF0000000000000000000000000000000000000000000000000000000000000000 +255B:03C003C003C003C003C003C003C003C003C003C0FFC0FFC003C003C0FFC0FFC00000000000000000000000000000000000000000000000000000000000000000 +255C:0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3CFFFCFFFC0000000000000000000000000000000000000000000000000000000000000000 +255D:0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3CFF3CFF3C003C003CFFFCFFFC0000000000000000000000000000000000000000000000000000000000000000 +255E:03C003C003C003C003C003C003C003C003C003C003FF03FF03C003C003FF03FF03C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0 +255F:0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3F0F3F0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C +2560:0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3F0F3F0F000F000F3F0F3F0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C +2561:03C003C003C003C003C003C003C003C003C003C0FFC0FFC003C003C0FFC0FFC003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0 +2562:0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3CFF3CFF3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C +2563:0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3CFF3CFF3C003C003CFF3CFF3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C +2564:0000000000000000000000000000000000000000FFFFFFFF00000000FFFFFFFF03C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0 +2565:00000000000000000000000000000000000000000000000000000000FFFFFFFF0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C +2566:0000000000000000000000000000000000000000FFFFFFFF00000000FF3FFF3F0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C +2567:03C003C003C003C003C003C003C003C003C003C0FFFFFFFF00000000FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000 +2568:0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3CFFFFFFFF0000000000000000000000000000000000000000000000000000000000000000 +2569:0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3CFF3FFF3F00000000FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000 +256A:03C003C003C003C003C003C003C003C003C003C0FFFFFFFF03C003C0FFFFFFFF03C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C0 +256B:0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3CFFFFFFFF0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C +256C:0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3CFF3FFF3F00000000FF3FFF3F0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C +2580:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000 +2584:00000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +2588:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +258C:FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 +2590:00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF +2591:03030303303030300303030330303030030303033030303003030303303030300303030330303030030303033030303003030303303030300303030330303030 +2592:33333333CCCCCCCC33333333CCCCCCCC33333333CCCCCCCC33333333CCCCCCCC33333333CCCCCCCC33333333CCCCCCCC33333333CCCCCCCC33333333CCCCCCCC +2593:F3F3F3F33F3F3F3FF3F3F3F33F3F3F3FF3F3F3F33F3F3F3FF3F3F3F33F3F3F3FF3F3F3F33F3F3F3FF3F3F3F33F3F3F3FF3F3F3F33F3F3F3FF3F3F3F33F3F3F3F +25A0:000000000000000000000000000000003FF03FF03FF03FF03FF03FF03FF03FF03FF03FF03FF03FF03FF03FF00000000000000000000000000000000000000000 +25AC:0000000000000000000000000000000000000000000000000000000000000000FFFCFFFCFFFCFFFCFFFCFFFCFFFCFFFC00000000000000000000000000000000 +25B2:00000000000000000000000000000000030003000FC00FC00FC00FC03FF03FF03FF03FF0FFFCFFFCFFFCFFFC0000000000000000000000000000000000000000 +25BA:00000000C000C000F000F000FC00FC00FF00FF00FFC0FFC0FFFCFFFCFFC0FFC0FF00FF00FC00FC00F000F000C000C00000000000000000000000000000000000 +25BC:00000000000000000000000000000000FFFCFFFCFFFCFFFC3FF03FF03FF03FF00FC00FC00FC00FC0030003000000000000000000000000000000000000000000 +25C4:00000000000C000C003C003C00FC00FC03FC03FC0FFC0FFCFFFCFFFC0FFC0FFC03FC03FC00FC00FC003C003C000C000C00000000000000000000000000000000 +25CB:00000000000000000000000000000000000000000FF00FF03C3C3C3C300C300C300C300C3C3C3C3C0FF00FF00000000000000000000000000000000000000000 +25D8:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3FFC3FF00FF00FF00FF00FFC3FFC3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +25D9:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF00FC3C3C3C3CFF3CFF3CFF3CFF3C3C3C3C3F00FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +263A:00000000000000003FFC3FFCC003C003CC33CC33C003C003C003C003CFF3CFF3C3C3C3C3C003C003C003C0033FFC3FFC00000000000000000000000000000000 +263B:00000000000000003FFC3FFCFFFFFFFFF3CFF3CFFFFFFFFFFFFFFFFFF00FF00FFC3FFC3FFFFFFFFFFFFFFFFF3FFC3FFC00000000000000000000000000000000 +263C:00000000000000000000000003C003C003C003C0F3CFF3CF0FF00FF0FC3FFC3F0FF00FF0F3CFF3CF03C003C003C003C000000000000000000000000000000000 +2640:00000000000000000FF00FF03C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C0FF00FF003C003C03FFC3FFC03C003C003C003C000000000000000000000000000000000 +2642:000000000000000003FC03FC00FC00FC03CC03CC0F0C0F0C3FC03FC0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F03FC03FC000000000000000000000000000000000 +2660:00000000000000000000000003C003C00FF00FF03FFC3FFCFFFFFFFFFFFFFFFF3FFC3FFC03C003C003C003C00FF00FF000000000000000000000000000000000 +2663:00000000000000000000000003C003C00FF00FF00FF00FF0FC3FFC3FFC3FFC3FFC3FFC3F03C003C003C003C00FF00FF000000000000000000000000000000000 +2665:000000000000000000000000000000003CF03CF0FFFCFFFCFFFCFFFCFFFCFFFCFFFCFFFC3FF03FF00FC00FC00300030000000000000000000000000000000000 +2666:00000000000000000000000000000000030003000FC00FC03FF03FF0FFFCFFFC3FF03FF00FC00FC0030003000000000000000000000000000000000000000000 +266A:00000000000000000FFF0FFF0F0F0F0F0FFF0FFF0F000F000F000F000F000F000F000F003F003F00FF00FF00FC00FC0000000000000000000000000000000000 +266C:00000000000000003FFF3FFF3C0F3C0F3FFF3FFF3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C0F3C3F3C3FFC3FFC3FFC3CFC3CF000F000000000000000000000000000 diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index f3e54805..cc1b73e 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -2860,7 +2860,7 @@ free_pv_chunk(struct pv_chunk *pc) /* entire chunk is free, return it */ m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pc)); dump_drop_page(m->phys_addr); - vm_page_unwire(m, PQ_INACTIVE); + vm_page_unwire(m, PQ_NONE); vm_page_free(m); } diff --git a/sys/arm/arm/pmap-v6-new.c b/sys/arm/arm/pmap-v6-new.c index 864e05c..d0a3f0f 100644 --- a/sys/arm/arm/pmap-v6-new.c +++ b/sys/arm/arm/pmap-v6-new.c @@ -2866,7 +2866,7 @@ free_pv_chunk(struct pv_chunk *pc) /* entire chunk is free, return it */ m = PHYS_TO_VM_PAGE(pmap_kextract((vm_offset_t)pc)); pmap_qremove((vm_offset_t)pc, 1); - vm_page_unwire(m, PQ_INACTIVE); + vm_page_unwire(m, PQ_NONE); vm_page_free(m); pmap_pte2list_free(&pv_vafree, (vm_offset_t)pc); } diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c index 50172f2..437891e 100644 --- a/sys/arm/arm/pmap-v6.c +++ b/sys/arm/arm/pmap-v6.c @@ -4292,7 +4292,7 @@ pmap_free_pv_chunk(struct pv_chunk *pc) /* entire chunk is free, return it */ m = PHYS_TO_VM_PAGE(pmap_kextract((vm_offset_t)pc)); pmap_qremove((vm_offset_t)pc, 1); - vm_page_unwire(m, PQ_INACTIVE); + vm_page_unwire(m, PQ_NONE); vm_page_free(m); pmap_ptelist_free(&pv_vafree, (vm_offset_t)pc); diff --git a/sys/arm/broadcom/bcm2835/bcm2836_mp.c b/sys/arm/broadcom/bcm2835/bcm2836_mp.c index 717f242..93cc0d8 100644 --- a/sys/arm/broadcom/bcm2835/bcm2836_mp.c +++ b/sys/arm/broadcom/bcm2835/bcm2836_mp.c @@ -182,6 +182,8 @@ pic_ipi_read(int i) if (val == 0) return (0); ipi = ffs(val) - 1; + BSWR4(MBOX0CLR_CORE(cpu), 1 << ipi); + dsb(); return (ipi); } return (0x3ff); @@ -190,12 +192,6 @@ pic_ipi_read(int i) void pic_ipi_clear(int ipi) { - int cpu; - - cpu = PCPU_GET(cpuid); - dsb(); - BSWR4(MBOX0CLR_CORE(cpu), 1 << ipi); - wmb(); } void diff --git a/sys/arm/mv/mpic.c b/sys/arm/mv/mpic.c index bfb5554..7eb5d2a 100644 --- a/sys/arm/mv/mpic.c +++ b/sys/arm/mv/mpic.c @@ -378,10 +378,14 @@ int pic_ipi_read(int i __unused) { uint32_t val; + int ipi; val = MPIC_CPU_READ(mv_mpic_sc, MPIC_IN_DRBL); - if (val) - return (ffs(val) - 1); + if (val) { + ipi = ffs(val) - 1; + MPIC_CPU_WRITE(mv_mpic_sc, MPIC_IN_DRBL, ~(1 << ipi)); + return (ipi); + } return (0x3ff); } @@ -389,10 +393,6 @@ pic_ipi_read(int i __unused) void pic_ipi_clear(int ipi) { - uint32_t val; - - val = ~(1 << ipi); - MPIC_CPU_WRITE(mv_mpic_sc, MPIC_IN_DRBL, val); } #endif diff --git a/sys/arm64/arm64/exception.S b/sys/arm64/arm64/exception.S index 2e6fee8..3dc484e 100644 --- a/sys/arm64/arm64/exception.S +++ b/sys/arm64/arm64/exception.S @@ -131,45 +131,51 @@ __FBSDID("$FreeBSD$"); 2: .endm -handle_el1h_sync: +ENTRY(handle_el1h_sync) save_registers 1 mov x0, sp bl do_el1h_sync restore_registers 1 eret +END(handle_el1h_sync) -handle_el1h_irq: +ENTRY(handle_el1h_irq) save_registers 1 mov x0, sp bl arm_cpu_intr restore_registers 1 eret +END(handle_el1h_irq) -handle_el1h_error: +ENTRY(handle_el1h_error) brk 0xf13 +END(handle_el1h_error) -handle_el0_sync: +ENTRY(handle_el0_sync) save_registers 0 mov x0, sp bl do_el0_sync do_ast restore_registers 0 eret +END(handle_el0_sync) -handle_el0_irq: +ENTRY(handle_el0_irq) save_registers 0 mov x0, sp bl arm_cpu_intr do_ast restore_registers 0 eret +END(handle_el0_irq) -handle_el0_error: +ENTRY(handle_el0_error) save_registers 0 mov x0, sp bl do_el0_error brk 0xf23 1: b 1b +END(handle_el0_error) .macro vempty .align 7 diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c index 379198c..688cc79 100644 --- a/sys/arm64/arm64/mp_machdep.c +++ b/sys/arm64/arm64/mp_machdep.c @@ -190,7 +190,7 @@ release_aps(void *dummy __unused) DELAY(1000); } - printf("AP's not started\n"); + printf("APs not started\n"); } SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL); diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 62fe394..004b4a7 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -243,6 +243,16 @@ static void _pmap_unwire_l3(pmap_t pmap, vm_offset_t va, vm_page_t m, struct spglist *free); static int pmap_unuse_l3(pmap_t, vm_offset_t, pd_entry_t, struct spglist *); +/* + * These load the old table data and store the new value. + * They need to be atomic as the System MMU may write to the table at + * the same time as the CPU. + */ +#define pmap_load_store(table, entry) atomic_swap_64(table, entry) +#define pmap_set(table, mask) atomic_set_64(table, mask) +#define pmap_load_clear(table) atomic_swap_64(table, 0) +#define pmap_load(table) (*table) + /********************/ /* Inline functions */ /********************/ @@ -277,7 +287,7 @@ pmap_l1_to_l2(pd_entry_t *l1, vm_offset_t va) { pd_entry_t *l2; - l2 = (pd_entry_t *)PHYS_TO_DMAP(*l1 & ~ATTR_MASK); + l2 = (pd_entry_t *)PHYS_TO_DMAP(pmap_load(l1) & ~ATTR_MASK); return (&l2[pmap_l2_index(va)]); } @@ -287,7 +297,7 @@ pmap_l2(pmap_t pmap, vm_offset_t va) pd_entry_t *l1; l1 = pmap_l1(pmap, va); - if ((*l1 & ATTR_DESCR_MASK) != L1_TABLE) + if ((pmap_load(l1) & ATTR_DESCR_MASK) != L1_TABLE) return (NULL); return (pmap_l1_to_l2(l1, va)); @@ -298,7 +308,7 @@ pmap_l2_to_l3(pd_entry_t *l2, vm_offset_t va) { pt_entry_t *l3; - l3 = (pd_entry_t *)PHYS_TO_DMAP(*l2 & ~ATTR_MASK); + l3 = (pd_entry_t *)PHYS_TO_DMAP(pmap_load(l2) & ~ATTR_MASK); return (&l3[pmap_l3_index(va)]); } @@ -308,7 +318,7 @@ pmap_l3(pmap_t pmap, vm_offset_t va) pd_entry_t *l2; l2 = pmap_l2(pmap, va); - if (l2 == NULL || (*l2 & ATTR_DESCR_MASK) != L2_TABLE) + if (l2 == NULL || (pmap_load(l2) & ATTR_DESCR_MASK) != L2_TABLE) return (NULL); return (pmap_l2_to_l3(l2, va)); @@ -326,19 +336,19 @@ pmap_get_tables(pmap_t pmap, vm_offset_t va, pd_entry_t **l1, pd_entry_t **l2, l1p = pmap_l1(pmap, va); *l1 = l1p; - if ((*l1p & ATTR_DESCR_MASK) == L1_BLOCK) { + if ((pmap_load(l1p) & ATTR_DESCR_MASK) == L1_BLOCK) { *l2 = NULL; *l3 = NULL; return (true); } - if ((*l1p & ATTR_DESCR_MASK) != L1_TABLE) + if ((pmap_load(l1p) & ATTR_DESCR_MASK) != L1_TABLE) return (false); l2p = pmap_l1_to_l2(l1p, va); *l2 = l2p; - if ((*l2p & ATTR_DESCR_MASK) == L2_BLOCK) { + if ((pmap_load(l2p) & ATTR_DESCR_MASK) == L2_BLOCK) { *l3 = NULL; return (true); } @@ -348,16 +358,6 @@ pmap_get_tables(pmap_t pmap, vm_offset_t va, pd_entry_t **l1, pd_entry_t **l2, return (true); } -/* - * These load the old table data and store the new value. - * They need to be atomic as the System MMU may write to the table at - * the same time as the CPU. - */ -#define pmap_load_store(table, entry) atomic_swap_64(table, entry) -#define pmap_set(table, mask) atomic_set_64(table, mask) -#define pmap_load_clear(table) atomic_swap_64(table, 0) -#define pmap_load(table) (*table) - static __inline int pmap_is_current(pmap_t pmap) { @@ -799,11 +799,11 @@ pmap_extract(pmap_t pmap, vm_offset_t va) */ l2p = pmap_l2(pmap, va); if (l2p != NULL) { - l2 = *l2p; + l2 = pmap_load(l2p); if ((l2 & ATTR_DESCR_MASK) == L2_TABLE) { l3p = pmap_l2_to_l3(l2p, va); if (l3p != NULL) { - l3 = *l3p; + l3 = pmap_load(l3p); if ((l3 & ATTR_DESCR_MASK) == L3_PAGE) pa = (l3 & ~ATTR_MASK) | @@ -852,23 +852,25 @@ retry: vm_paddr_t pmap_kextract(vm_offset_t va) { - pd_entry_t *l2; + pd_entry_t *l2p, l2; pt_entry_t *l3; vm_paddr_t pa; if (va >= DMAP_MIN_ADDRESS && va < DMAP_MAX_ADDRESS) { pa = DMAP_TO_PHYS(va); } else { - l2 = pmap_l2(kernel_pmap, va); - if (l2 == NULL) + l2p = pmap_l2(kernel_pmap, va); + if (l2p == NULL) panic("pmap_kextract: No l2"); - if ((*l2 & ATTR_DESCR_MASK) == L2_BLOCK) - return ((*l2 & ~ATTR_MASK) | (va & L2_OFFSET)); + l2 = pmap_load(l2p); + if ((l2 & ATTR_DESCR_MASK) == L2_BLOCK) + return ((l2 & ~ATTR_MASK) | + (va & L2_OFFSET)); - l3 = pmap_l2_to_l3(l2, va); + l3 = pmap_l2_to_l3(l2p, va); if (l3 == NULL) panic("pmap_kextract: No l3..."); - pa = (*l3 & ~ATTR_MASK) | (va & PAGE_MASK); + pa = (pmap_load(l3) & ~ATTR_MASK) | (va & PAGE_MASK); } return (pa); } @@ -1242,11 +1244,11 @@ _pmap_alloc_l3(pmap_t pmap, vm_pindex_t ptepindex, struct rwlock **lockp) return (NULL); } } else { - pdpg = PHYS_TO_VM_PAGE(*l1 & ~ATTR_MASK); + pdpg = PHYS_TO_VM_PAGE(pmap_load(l1) & ~ATTR_MASK); pdpg->wire_count++; } - l2 = (pd_entry_t *)PHYS_TO_DMAP(*l1 & ~ATTR_MASK); + l2 = (pd_entry_t *)PHYS_TO_DMAP(pmap_load(l1) & ~ATTR_MASK); l2 = &l2[ptepindex & Ln_ADDR_MASK]; pmap_load_store(l2, VM_PAGE_TO_PHYS(m) | L2_TABLE); PTE_SYNC(l2); @@ -1517,7 +1519,7 @@ free_pv_chunk(struct pv_chunk *pc) /* entire chunk is free, return it */ m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pc)); dump_drop_page(m->phys_addr); - vm_page_unwire(m, PQ_INACTIVE); + vm_page_unwire(m, PQ_NONE); vm_page_free(m); } @@ -1738,7 +1740,7 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) if (l2 == NULL) continue; - l3_paddr = *l2; + l3_paddr = pmap_load(l2); /* * Weed out invalid mappings. @@ -1805,7 +1807,7 @@ pmap_remove_all(vm_page_t m) pv_entry_t pv; pmap_t pmap; pt_entry_t *l3, tl3; - pd_entry_t *l2; + pd_entry_t *l2, tl2; struct spglist free; KASSERT((m->oflags & VPO_UNMANAGED) == 0, @@ -1817,7 +1819,9 @@ pmap_remove_all(vm_page_t m) PMAP_LOCK(pmap); pmap_resident_count_dec(pmap, 1); l2 = pmap_l2(pmap, pv->pv_va); - KASSERT((*l2 & ATTR_DESCR_MASK) == L2_TABLE, + KASSERT(l2 != NULL, ("pmap_remove_all: no l2 table found")); + tl2 = pmap_load(l2); + KASSERT((tl2 & ATTR_DESCR_MASK) == L2_TABLE, ("pmap_remove_all: found a table when expecting " "a block in %p's pv list", m)); l3 = pmap_l2_to_l3(l2, pv->pv_va); @@ -1837,7 +1841,7 @@ pmap_remove_all(vm_page_t m) */ if (pmap_page_dirty(tl3)) vm_page_dirty(m); - pmap_unuse_l3(pmap, pv->pv_va, *l2, &free); + pmap_unuse_l3(pmap, pv->pv_va, tl2, &free); TAILQ_REMOVE(&m->md.pv_list, pv, pv_next); m->md.pv_gen++; free_pv_entry(pmap, pv); @@ -1883,7 +1887,7 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) va_next = eva; l2 = pmap_l1_to_l2(l1, sva); - if (l2 == NULL || (*l2 & ATTR_DESCR_MASK) != L2_TABLE) + if (l2 == NULL || (pmap_load(l2) & ATTR_DESCR_MASK) != L2_TABLE) continue; if (va_next > eva) @@ -2345,7 +2349,7 @@ pmap_unwire(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) continue; if ((pmap_load(l3) & ATTR_SW_WIRED) == 0) panic("pmap_unwire: l3 %#jx is missing " - "ATTR_SW_WIRED", (uintmax_t)*l3); + "ATTR_SW_WIRED", (uintmax_t)pmap_load(l3)); /* * PG_W must be cleared atomically. Although the pmap @@ -2836,7 +2840,7 @@ retry_pv_loop: } l3 = pmap_l3(pmap, pv->pv_va); retry: - oldl3 = *l3; + oldl3 = pmap_load(l3); if ((oldl3 & ATTR_AP_RW_BIT) == ATTR_AP(ATTR_AP_RW)) { if (!atomic_cmpset_long(l3, oldl3, oldl3 | ATTR_AP(ATTR_AP_RO))) @@ -2879,7 +2883,7 @@ pmap_ts_referenced(vm_page_t m) pv_entry_t pv, pvf; pmap_t pmap; struct rwlock *lock; - pd_entry_t *l2; + pd_entry_t *l2p, l2; pt_entry_t *l3; vm_paddr_t pa; int cleared, md_gen, not_cleared; @@ -2912,12 +2916,14 @@ retry: goto retry; } } - l2 = pmap_l2(pmap, pv->pv_va); - KASSERT((*l2 & ATTR_DESCR_MASK) == L2_TABLE, + l2p = pmap_l2(pmap, pv->pv_va); + KASSERT(l2p != NULL, ("pmap_ts_referenced: no l2 table found")); + l2 = pmap_load(l2p); + KASSERT((l2 & ATTR_DESCR_MASK) == L2_TABLE, ("pmap_ts_referenced: found an invalid l2 table")); - l3 = pmap_l2_to_l3(l2, pv->pv_va); + l3 = pmap_l2_to_l3(l2p, pv->pv_va); if ((pmap_load(l3) & ATTR_AF) != 0) { - if (safe_to_clear_referenced(pmap, *l3)) { + if (safe_to_clear_referenced(pmap, pmap_load(l3))) { /* * TODO: We don't handle the access flag * at all. We need to be able to set it in @@ -2931,8 +2937,8 @@ retry: * them is wasted effort. We do the * hard work for unwired pages only. */ - pmap_remove_l3(pmap, l3, pv->pv_va, - *l2, &free, &lock); + pmap_remove_l3(pmap, l3, pv->pv_va, l2, + &free, &lock); pmap_invalidate_page(pmap, pv->pv_va); cleared++; if (pvf == pv) diff --git a/sys/boot/efi/libefi/Makefile.depend b/sys/boot/efi/libefi/Makefile.depend index c77da59..18be76b 100644 --- a/sys/boot/efi/libefi/Makefile.depend +++ b/sys/boot/efi/libefi/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ include \ include/xlocale \ diff --git a/sys/boot/efi/loader/copy.c b/sys/boot/efi/loader/copy.c index 3d42d7e..716e9ea 100644 --- a/sys/boot/efi/loader/copy.c +++ b/sys/boot/efi/loader/copy.c @@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$"); #define EFI_STAGING_SIZE 48 #endif -#define STAGE_PAGES ((EFI_STAGING_SIZE) * 1024 * 1024 / 4096) +#define STAGE_PAGES EFI_SIZE_TO_PAGES((EFI_STAGING_SIZE) * 1024 * 1024) EFI_PHYSICAL_ADDRESS staging, staging_end; int stage_offset_set = 0; @@ -59,7 +59,7 @@ efi_copy_init(void) (unsigned long)(status & EFI_ERROR_MASK)); return (status); } - staging_end = staging + STAGE_PAGES * 4096; + staging_end = staging + STAGE_PAGES * EFI_PAGE_SIZE; #if defined(__aarch64__) || defined(__arm__) /* @@ -132,7 +132,7 @@ efi_copy_finish(void) src = (uint64_t *)staging; dst = (uint64_t *)(staging - stage_offset); - last = (uint64_t *)(staging + STAGE_PAGES * EFI_PAGE_SIZE); + last = (uint64_t *)staging_end; while (src < last) *dst++ = *src++; diff --git a/sys/boot/fdt/dts/arm/bcm2836.dtsi b/sys/boot/fdt/dts/arm/bcm2836.dtsi index bd75c84..c1caac3 100644 --- a/sys/boot/fdt/dts/arm/bcm2836.dtsi +++ b/sys/boot/fdt/dts/arm/bcm2836.dtsi @@ -379,6 +379,8 @@ }; bsc0 { + #address-cells = <1>; + #size-cells = <0>; compatible = "broadcom,bcm2835-bsc", "broadcom,bcm2708-bsc"; reg = <0x205000 0x20>; @@ -387,6 +389,8 @@ }; bsc1 { + #address-cells = <1>; + #size-cells = <0>; compatible = "broadcom,bcm2835-bsc", "broadcom,bcm2708-bsc"; reg = <0x804000 0x20>; diff --git a/sys/boot/ficl/Makefile.depend b/sys/boot/ficl/Makefile.depend index ab9c549..729ef23 100644 --- a/sys/boot/ficl/Makefile.depend +++ b/sys/boot/ficl/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ include \ include/xlocale \ diff --git a/sys/boot/i386/boot0/Makefile.depend b/sys/boot/i386/boot0/Makefile.depend index 3af2d7f..f80275d 100644 --- a/sys/boot/i386/boot0/Makefile.depend +++ b/sys/boot/i386/boot0/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ diff --git a/sys/boot/i386/boot0sio/Makefile.depend b/sys/boot/i386/boot0sio/Makefile.depend index 3af2d7f..f80275d 100644 --- a/sys/boot/i386/boot0sio/Makefile.depend +++ b/sys/boot/i386/boot0sio/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ diff --git a/sys/boot/i386/boot2/Makefile.depend b/sys/boot/i386/boot2/Makefile.depend index 3af2d7f..f80275d 100644 --- a/sys/boot/i386/boot2/Makefile.depend +++ b/sys/boot/i386/boot2/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ diff --git a/sys/boot/i386/loader/Makefile.depend b/sys/boot/i386/loader/Makefile.depend index 3af2d7f..f80275d 100644 --- a/sys/boot/i386/loader/Makefile.depend +++ b/sys/boot/i386/loader/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ diff --git a/sys/boot/i386/zfsloader/Makefile.depend b/sys/boot/i386/zfsloader/Makefile.depend index 3af2d7f..f80275d 100644 --- a/sys/boot/i386/zfsloader/Makefile.depend +++ b/sys/boot/i386/zfsloader/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ diff --git a/sys/cam/cam_compat.c b/sys/cam/cam_compat.c index bcce814..b8e57bb 100644 --- a/sys/cam/cam_compat.c +++ b/sys/cam/cam_compat.c @@ -300,7 +300,7 @@ cam_compat_translate_dev_match_0x18(union ccb *ccb) /* Remap the CCB into kernel address space */ bzero(&mapinfo, sizeof(mapinfo)); - cam_periph_mapmem(ccb, &mapinfo); + cam_periph_mapmem(ccb, &mapinfo, MAXPHYS); dm = ccb->cdm.matches; /* Translate in-place: old fields are smaller */ diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index 956e5d0..91cb45d 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -716,16 +716,19 @@ camperiphfree(struct cam_periph *periph) * buffers to map stuff in and out, we're limited to the buffer size. */ int -cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo) +cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo, + u_int maxmap) { int numbufs, i, j; int flags[CAM_PERIPH_MAXMAPS]; u_int8_t **data_ptrs[CAM_PERIPH_MAXMAPS]; u_int32_t lengths[CAM_PERIPH_MAXMAPS]; u_int32_t dirs[CAM_PERIPH_MAXMAPS]; - /* Some controllers may not be able to handle more data. */ - size_t maxmap = DFLTPHYS; + if (maxmap == 0) + maxmap = DFLTPHYS; /* traditional default */ + else if (maxmap > MAXPHYS) + maxmap = MAXPHYS; /* for safety */ switch(ccb->ccb_h.func_code) { case XPT_DEV_MATCH: if (ccb->cdm.match_buf_len == 0) { diff --git a/sys/cam/cam_periph.h b/sys/cam/cam_periph.h index ebcf1a4..e28d5b1 100644 --- a/sys/cam/cam_periph.h +++ b/sys/cam/cam_periph.h @@ -160,7 +160,8 @@ int cam_periph_hold(struct cam_periph *periph, int priority); void cam_periph_unhold(struct cam_periph *periph); void cam_periph_invalidate(struct cam_periph *periph); int cam_periph_mapmem(union ccb *ccb, - struct cam_periph_map_info *mapinfo); + struct cam_periph_map_info *mapinfo, + u_int maxmap); void cam_periph_unmapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo); union ccb *cam_periph_getccb(struct cam_periph *periph, diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index ad55373..4ce48a3 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -536,7 +536,7 @@ xptdoioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread * * Map the pattern and match buffers into kernel * virtual address space. */ - error = cam_periph_mapmem(inccb, &mapinfo); + error = cam_periph_mapmem(inccb, &mapinfo, MAXPHYS); if (error) { inccb->ccb_h.path = old_path; diff --git a/sys/cam/ctl/README.ctl.txt b/sys/cam/ctl/README.ctl.txt index c37527b..89030e2 100644 --- a/sys/cam/ctl/README.ctl.txt +++ b/sys/cam/ctl/README.ctl.txt @@ -19,9 +19,9 @@ Userland Commands Introduction: ============ -CTL is a disk and processor device emulation subsystem originally written -for Copan Systems under Linux starting in 2003. It has been shipping in -Copan (now SGI) products since 2005. +CTL is a disk, processor and cdrom device emulation subsystem originally +written for Copan Systems under Linux starting in 2003. It has been +shipping in Copan (now SGI) products since 2005. It was ported to FreeBSD in 2008, and thanks to an agreement between SGI (who acquired Copan's assets in 2010) and Spectra Logic in 2010, CTL is @@ -31,7 +31,7 @@ that Spectra would work to get CTL into the FreeBSD tree. Features: ======== - - Disk and processor device emulation. + - Disk, processor and cdrom device emulation. - Tagged queueing - SCSI task attribute support (ordered, head of queue, simple tags) - SCSI implicit command ordering support. (e.g. if a read follows a mode diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 8d85bc55..30c4eb0 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$"); #include <cam/cam.h> #include <cam/scsi/scsi_all.h> +#include <cam/scsi/scsi_cd.h> #include <cam/scsi/scsi_da.h> #include <cam/ctl/ctl_io.h> #include <cam/ctl/ctl.h> @@ -353,6 +354,52 @@ const static struct ctl_logical_block_provisioning_page lbp_page_changeable = {{ } }; +const static struct scsi_cddvd_capabilities_page cddvd_page_default = { + /*page_code*/SMS_CDDVD_CAPS_PAGE, + /*page_length*/sizeof(struct scsi_cddvd_capabilities_page) - 2, + /*caps1*/0x3f, + /*caps2*/0x00, + /*caps3*/0xf0, + /*caps4*/0x00, + /*caps5*/0x29, + /*caps6*/0x00, + /*obsolete*/{0, 0}, + /*nvol_levels*/{0, 0}, + /*buffer_size*/{8, 0}, + /*obsolete2*/{0, 0}, + /*reserved*/0, + /*digital*/0, + /*obsolete3*/0, + /*copy_management*/0, + /*reserved2*/0, + /*rotation_control*/0, + /*cur_write_speed*/0, + /*num_speed_descr*/0, +}; + +const static struct scsi_cddvd_capabilities_page cddvd_page_changeable = { + /*page_code*/SMS_CDDVD_CAPS_PAGE, + /*page_length*/sizeof(struct scsi_cddvd_capabilities_page) - 2, + /*caps1*/0, + /*caps2*/0, + /*caps3*/0, + /*caps4*/0, + /*caps5*/0, + /*caps6*/0, + /*obsolete*/{0, 0}, + /*nvol_levels*/{0, 0}, + /*buffer_size*/{0, 0}, + /*obsolete2*/{0, 0}, + /*reserved*/0, + /*digital*/0, + /*obsolete3*/0, + /*copy_management*/0, + /*reserved2*/0, + /*rotation_control*/0, + /*cur_write_speed*/0, + /*num_speed_descr*/0, +}; + SYSCTL_NODE(_kern_cam, OID_AUTO, ctl, CTLFLAG_RD, 0, "CAM Target Layer"); static int worker_threads = -1; SYSCTL_INT(_kern_cam_ctl, OID_AUTO, worker_threads, CTLFLAG_RDTUN, @@ -378,7 +425,7 @@ void ctl_shutdown(void); static int ctl_open(struct cdev *dev, int flags, int fmt, struct thread *td); static int ctl_close(struct cdev *dev, int flags, int fmt, struct thread *td); static int ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio); -static int ctl_ioctl_fill_ooa(struct ctl_lun *lun, uint32_t *cur_fill_num, +static void ctl_ioctl_fill_ooa(struct ctl_lun *lun, uint32_t *cur_fill_num, struct ctl_ooa *ooa_hdr, struct ctl_ooa_entry *kern_entries); static int ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, @@ -424,7 +471,7 @@ static int ctl_check_blocked(struct ctl_lun *lun); static int ctl_scsiio_lun_check(struct ctl_lun *lun, const struct ctl_cmd_entry *entry, struct ctl_scsiio *ctsio); -static void ctl_failover_lun(struct ctl_lun *lun); +static void ctl_failover_lun(union ctl_io *io); static int ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio); static int ctl_scsiio(struct ctl_scsiio *ctsio); @@ -457,7 +504,7 @@ static int ctl_datamove_remote_xfer(union ctl_io *io, unsigned command, ctl_ha_dt_cb callback); static void ctl_datamove_remote_read(union ctl_io *io); static void ctl_datamove_remote(union ctl_io *io); -static int ctl_process_done(union ctl_io *io); +static void ctl_process_done(union ctl_io *io); static void ctl_lun_thread(void *arg); static void ctl_thresh_thread(void *arg); static void ctl_work_thread(void *arg); @@ -515,6 +562,151 @@ static struct ctl_frontend ha_frontend = }; static void +ctl_ha_datamove(union ctl_io *io) +{ + struct ctl_lun *lun; + struct ctl_sg_entry *sgl; + union ctl_ha_msg msg; + uint32_t sg_entries_sent; + int do_sg_copy, i, j; + + lun = (struct ctl_lun *)io->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + memset(&msg.dt, 0, sizeof(msg.dt)); + msg.hdr.msg_type = CTL_MSG_DATAMOVE; + msg.hdr.original_sc = io->io_hdr.original_sc; + msg.hdr.serializing_sc = io; + msg.hdr.nexus = io->io_hdr.nexus; + msg.hdr.status = io->io_hdr.status; + msg.dt.flags = io->io_hdr.flags; + + /* + * We convert everything into a S/G list here. We can't + * pass by reference, only by value between controllers. + * So we can't pass a pointer to the S/G list, only as many + * S/G entries as we can fit in here. If it's possible for + * us to get more than CTL_HA_MAX_SG_ENTRIES S/G entries, + * then we need to break this up into multiple transfers. + */ + if (io->scsiio.kern_sg_entries == 0) { + msg.dt.kern_sg_entries = 1; +#if 0 + if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR) { + msg.dt.sg_list[0].addr = io->scsiio.kern_data_ptr; + } else { + /* XXX KDM use busdma here! */ + msg.dt.sg_list[0].addr = + (void *)vtophys(io->scsiio.kern_data_ptr); + } +#else + KASSERT((io->io_hdr.flags & CTL_FLAG_BUS_ADDR) == 0, + ("HA does not support BUS_ADDR")); + msg.dt.sg_list[0].addr = io->scsiio.kern_data_ptr; +#endif + msg.dt.sg_list[0].len = io->scsiio.kern_data_len; + do_sg_copy = 0; + } else { + msg.dt.kern_sg_entries = io->scsiio.kern_sg_entries; + do_sg_copy = 1; + } + + msg.dt.kern_data_len = io->scsiio.kern_data_len; + msg.dt.kern_total_len = io->scsiio.kern_total_len; + msg.dt.kern_data_resid = io->scsiio.kern_data_resid; + msg.dt.kern_rel_offset = io->scsiio.kern_rel_offset; + msg.dt.sg_sequence = 0; + + /* + * Loop until we've sent all of the S/G entries. On the + * other end, we'll recompose these S/G entries into one + * contiguous list before processing. + */ + for (sg_entries_sent = 0; sg_entries_sent < msg.dt.kern_sg_entries; + msg.dt.sg_sequence++) { + msg.dt.cur_sg_entries = MIN((sizeof(msg.dt.sg_list) / + sizeof(msg.dt.sg_list[0])), + msg.dt.kern_sg_entries - sg_entries_sent); + if (do_sg_copy != 0) { + sgl = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr; + for (i = sg_entries_sent, j = 0; + i < msg.dt.cur_sg_entries; i++, j++) { +#if 0 + if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR) { + msg.dt.sg_list[j].addr = sgl[i].addr; + } else { + /* XXX KDM use busdma here! */ + msg.dt.sg_list[j].addr = + (void *)vtophys(sgl[i].addr); + } +#else + KASSERT((io->io_hdr.flags & + CTL_FLAG_BUS_ADDR) == 0, + ("HA does not support BUS_ADDR")); + msg.dt.sg_list[j].addr = sgl[i].addr; +#endif + msg.dt.sg_list[j].len = sgl[i].len; + } + } + + sg_entries_sent += msg.dt.cur_sg_entries; + msg.dt.sg_last = (sg_entries_sent >= msg.dt.kern_sg_entries); + if (ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg, + sizeof(msg.dt) - sizeof(msg.dt.sg_list) + + sizeof(struct ctl_sg_entry) * msg.dt.cur_sg_entries, + M_WAITOK) > CTL_HA_STATUS_SUCCESS) { + io->io_hdr.port_status = 31341; + io->scsiio.be_move_done(io); + return; + } + msg.dt.sent_sg_entries = sg_entries_sent; + } + + /* + * Officially handover the request from us to peer. + * If failover has just happened, then we must return error. + * If failover happen just after, then it is not our problem. + */ + if (lun) + mtx_lock(&lun->lun_lock); + if (io->io_hdr.flags & CTL_FLAG_FAILOVER) { + if (lun) + mtx_unlock(&lun->lun_lock); + io->io_hdr.port_status = 31342; + io->scsiio.be_move_done(io); + return; + } + io->io_hdr.flags &= ~CTL_FLAG_IO_ACTIVE; + io->io_hdr.flags |= CTL_FLAG_DMA_INPROG; + if (lun) + mtx_unlock(&lun->lun_lock); +} + +static void +ctl_ha_done(union ctl_io *io) +{ + union ctl_ha_msg msg; + + if (io->io_hdr.io_type == CTL_IO_SCSI) { + memset(&msg, 0, sizeof(msg)); + msg.hdr.msg_type = CTL_MSG_FINISH_IO; + msg.hdr.original_sc = io->io_hdr.original_sc; + msg.hdr.nexus = io->io_hdr.nexus; + msg.hdr.status = io->io_hdr.status; + msg.scsi.scsi_status = io->scsiio.scsi_status; + msg.scsi.tag_num = io->scsiio.tag_num; + msg.scsi.tag_type = io->scsiio.tag_type; + msg.scsi.sense_len = io->scsiio.sense_len; + msg.scsi.sense_residual = io->scsiio.sense_residual; + msg.scsi.residual = io->scsiio.residual; + memcpy(&msg.scsi.sense_data, &io->scsiio.sense_data, + io->scsiio.sense_len); + ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg, + sizeof(msg.scsi) - sizeof(msg.scsi.sense_data) + + msg.scsi.sense_len, M_WAITOK); + } + ctl_free_io(io); +} + +static void ctl_isc_handler_finish_xfer(struct ctl_softc *ctl_softc, union ctl_ha_msg *msg_info) { @@ -589,9 +781,9 @@ alloc: msg->hdr.nexus.targ_lun = lun->lun; msg->hdr.nexus.targ_mapped_lun = lun->lun; msg->lun.flags = lun->flags; - msg->lun.pr_generation = lun->PRGeneration; + msg->lun.pr_generation = lun->pr_generation; msg->lun.pr_res_idx = lun->pr_res_idx; - msg->lun.pr_res_type = lun->res_type; + msg->lun.pr_res_type = lun->pr_res_type; msg->lun.pr_key_count = lun->pr_key_count; i = 0; if (lun->lun_devid) { @@ -624,7 +816,7 @@ alloc: void ctl_isc_announce_port(struct ctl_port *port) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = port->ctl_softc; union ctl_ha_msg *msg; int i; @@ -685,7 +877,7 @@ ctl_isc_announce_port(struct ctl_port *port) void ctl_isc_announce_iid(struct ctl_port *port, int iid) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = port->ctl_softc; union ctl_ha_msg *msg; int i, l; @@ -893,9 +1085,9 @@ ctl_isc_lun_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) /* If peer is primary and we are not -- use data */ if ((lun->flags & CTL_LUN_PRIMARY_SC) == 0 && (lun->flags & CTL_LUN_PEER_SC_PRIMARY)) { - lun->PRGeneration = msg->lun.pr_generation; + lun->pr_generation = msg->lun.pr_generation; lun->pr_res_idx = msg->lun.pr_res_idx; - lun->res_type = msg->lun.pr_res_type; + lun->pr_res_type = msg->lun.pr_res_type; lun->pr_key_count = msg->lun.pr_key_count; for (k = 0; k < CTL_MAX_INITIATORS; k++) ctl_clr_prkey(lun, k); @@ -937,6 +1129,8 @@ ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) port = malloc(sizeof(*port), M_CTL, M_WAITOK | M_ZERO); port->frontend = &ha_frontend; port->targ_port = msg->hdr.nexus.targ_port; + port->fe_datamove = ctl_ha_datamove; + port->fe_done = ctl_ha_done; } else if (port->frontend == &ha_frontend) { CTL_DEBUG_PRINT(("%s: Updated port %d\n", __func__, msg->hdr.nexus.targ_port)); @@ -1126,12 +1320,11 @@ ctl_isc_mode_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) static void ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param) { - struct ctl_softc *softc; + struct ctl_softc *softc = control_softc; union ctl_io *io; struct ctl_prio *presio; ctl_ha_status isc_status; - softc = control_softc; CTL_DEBUG_PRINT(("CTL: Isc Msg event %d\n", event)); if (event == CTL_HA_EVT_MSG_RECV) { union ctl_ha_msg *msg, msgbuf; @@ -1181,7 +1374,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param) io->scsiio.tag_type = msg->scsi.tag_type; #ifdef CTL_TIME_IO io->io_hdr.start_time = time_uptime; - getbintime(&io->io_hdr.start_bt); + getbinuptime(&io->io_hdr.start_bt); #endif /* CTL_TIME_IO */ io->scsiio.cdb_len = msg->scsi.cdb_len; memcpy(io->scsiio.cdb, msg->scsi.cdb, @@ -1219,6 +1412,9 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param) io->io_hdr.status = msg->hdr.status; if (msg->dt.sg_sequence == 0) { +#ifdef CTL_TIME_IO + getbinuptime(&io->io_hdr.dma_start_bt); +#endif i = msg->dt.kern_sg_entries + msg->dt.kern_data_len / CTL_HA_DATAMOVE_SEGMENT + 1; @@ -1367,7 +1563,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param) taskio->tag_type = msg->task.tag_type; #ifdef CTL_TIME_IO taskio->io_hdr.start_time = time_uptime; - getbintime(&taskio->io_hdr.start_bt); + getbinuptime(&taskio->io_hdr.start_bt); #endif /* CTL_TIME_IO */ ctl_run_task((union ctl_io *)taskio); break; @@ -1579,16 +1775,13 @@ ctl_init(void) { struct ctl_softc *softc; void *other_pool; - int i, error, retval; + int i, error; - retval = 0; - control_softc = malloc(sizeof(*control_softc), M_DEVBUF, + softc = control_softc = malloc(sizeof(*control_softc), M_DEVBUF, M_WAITOK | M_ZERO); - softc = control_softc; softc->dev = make_dev(&ctl_cdevsw, 0, UID_ROOT, GID_OPERATOR, 0600, "cam/ctl"); - softc->dev->si_drv1 = softc; sysctl_ctx_init(&softc->sysctl_ctx); @@ -1607,13 +1800,7 @@ ctl_init(void) mtx_init(&softc->ctl_lock, "CTL mutex", NULL, MTX_DEF); softc->io_zone = uma_zcreate("CTL IO", sizeof(union ctl_io), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); - softc->open_count = 0; - - /* - * Default to actually sending a SYNCHRONIZE CACHE command down to - * the drive. - */ - softc->flags = CTL_FLAG_REAL_SYNC; + softc->flags = 0; SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "ha_mode", CTLFLAG_RDTUN, (int *)&softc->ha_mode, 0, @@ -1720,11 +1907,9 @@ ctl_init(void) void ctl_shutdown(void) { - struct ctl_softc *softc; + struct ctl_softc *softc = control_softc; struct ctl_lun *lun, *next_lun; - softc = (struct ctl_softc *)control_softc; - if (softc->is_single == 0) { ctl_ha_msg_shutdown(softc); if (ctl_ha_msg_deregister(CTL_HA_CHAN_CTL) @@ -1737,13 +1922,8 @@ ctl_shutdown(void) mtx_lock(&softc->ctl_lock); - /* - * Free up each LUN. - */ - for (lun = STAILQ_FIRST(&softc->lun_list); lun != NULL; lun = next_lun){ - next_lun = STAILQ_NEXT(lun, links); + STAILQ_FOREACH_SAFE(lun, &softc->lun_list, links, next_lun) ctl_free_lun(lun); - } mtx_unlock(&softc->ctl_lock); @@ -1801,7 +1981,7 @@ ctl_close(struct cdev *dev, int flags, int fmt, struct thread *td) int ctl_remove_initiator(struct ctl_port *port, int iid) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = port->ctl_softc; mtx_assert(&softc->ctl_lock, MA_NOTOWNED); @@ -1827,7 +2007,7 @@ ctl_remove_initiator(struct ctl_port *port, int iid) int ctl_add_initiator(struct ctl_port *port, int iid, uint64_t wwpn, char *name) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = port->ctl_softc; time_t best_time; int i, best; @@ -2002,17 +2182,26 @@ ctl_create_iid(struct ctl_port *port, int iid, uint8_t *buf) static int ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio) { - struct ctl_softc *softc; + struct ctl_softc *softc = control_softc; union ctl_ha_msg msg_info; + struct ctl_port *port; struct ctl_lun *lun; const struct ctl_cmd_entry *entry; int retval = 0; uint32_t targ_lun; - softc = control_softc; - targ_lun = ctsio->io_hdr.nexus.targ_mapped_lun; mtx_lock(&softc->ctl_lock); + + /* Make sure that we know about this port. */ + port = ctl_io_port(&ctsio->io_hdr); + if (port == NULL || (port->status & CTL_PORT_STATUS_ONLINE) == 0) { + ctl_set_internal_failure(ctsio, /*sks_valid*/ 0, + /*retry_count*/ 1); + goto badjuju; + } + + /* Make sure that we know about this LUN. */ if ((targ_lun < CTL_MAX_LUNS) && ((lun = softc->ctl_luns[targ_lun]) != NULL)) { mtx_lock(&lun->lun_lock); @@ -2038,25 +2227,13 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio) * a race, so respond to initiator in the most opaque way. */ ctl_set_busy(ctsio); - ctl_copy_sense_data_back((union ctl_io *)ctsio, &msg_info); - msg_info.hdr.original_sc = ctsio->io_hdr.original_sc; - msg_info.hdr.serializing_sc = NULL; - msg_info.hdr.msg_type = CTL_MSG_BAD_JUJU; - ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info, - sizeof(msg_info.scsi), M_WAITOK); - return(1); + goto badjuju; } entry = ctl_get_cmd_entry(ctsio, NULL); if (ctl_scsiio_lun_check(lun, entry, ctsio) != 0) { mtx_unlock(&lun->lun_lock); - ctl_copy_sense_data_back((union ctl_io *)ctsio, &msg_info); - msg_info.hdr.original_sc = ctsio->io_hdr.original_sc; - msg_info.hdr.serializing_sc = NULL; - msg_info.hdr.msg_type = CTL_MSG_BAD_JUJU; - ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info, - sizeof(msg_info.scsi), M_WAITOK); - return(1); + goto badjuju; } ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr = lun; @@ -2102,42 +2279,28 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio) case CTL_ACTION_OVERLAP: TAILQ_REMOVE(&lun->ooa_queue, &ctsio->io_hdr, ooa_links); mtx_unlock(&lun->lun_lock); - retval = 1; - ctl_set_overlapped_cmd(ctsio); - ctl_copy_sense_data_back((union ctl_io *)ctsio, &msg_info); - msg_info.hdr.original_sc = ctsio->io_hdr.original_sc; - msg_info.hdr.serializing_sc = NULL; - msg_info.hdr.msg_type = CTL_MSG_BAD_JUJU; - ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info, - sizeof(msg_info.scsi), M_WAITOK); - break; + goto badjuju; case CTL_ACTION_OVERLAP_TAG: TAILQ_REMOVE(&lun->ooa_queue, &ctsio->io_hdr, ooa_links); mtx_unlock(&lun->lun_lock); - retval = 1; ctl_set_overlapped_tag(ctsio, ctsio->tag_num); - ctl_copy_sense_data_back((union ctl_io *)ctsio, &msg_info); - msg_info.hdr.original_sc = ctsio->io_hdr.original_sc; - msg_info.hdr.serializing_sc = NULL; - msg_info.hdr.msg_type = CTL_MSG_BAD_JUJU; - ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info, - sizeof(msg_info.scsi), M_WAITOK); - break; + goto badjuju; case CTL_ACTION_ERROR: default: TAILQ_REMOVE(&lun->ooa_queue, &ctsio->io_hdr, ooa_links); mtx_unlock(&lun->lun_lock); - retval = 1; ctl_set_internal_failure(ctsio, /*sks_valid*/ 0, /*retry_count*/ 0); +badjuju: ctl_copy_sense_data_back((union ctl_io *)ctsio, &msg_info); msg_info.hdr.original_sc = ctsio->io_hdr.original_sc; msg_info.hdr.serializing_sc = NULL; msg_info.hdr.msg_type = CTL_MSG_BAD_JUJU; ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info, sizeof(msg_info.scsi), M_WAITOK); + retval = 1; break; } return (retval); @@ -2146,14 +2309,11 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio) /* * Returns 0 for success, errno for failure. */ -static int +static void ctl_ioctl_fill_ooa(struct ctl_lun *lun, uint32_t *cur_fill_num, struct ctl_ooa *ooa_hdr, struct ctl_ooa_entry *kern_entries) { union ctl_io *io; - int retval; - - retval = 0; mtx_lock(&lun->lun_lock); for (io = (union ctl_io *)TAILQ_FIRST(&lun->ooa_queue); (io != NULL); @@ -2193,8 +2353,6 @@ ctl_ioctl_fill_ooa(struct ctl_lun *lun, uint32_t *cur_fill_num, entry->cmd_flags |= CTL_OOACMD_FLAG_DMA_QUEUED; } mtx_unlock(&lun->lun_lock); - - return (retval); } static void * @@ -2377,12 +2535,10 @@ static int ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) { - struct ctl_softc *softc; + struct ctl_softc *softc = dev->si_drv1; struct ctl_lun *lun; int retval; - softc = control_softc; - retval = 0; switch (cmd) { @@ -2466,112 +2622,6 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, mtx_unlock(&softc->ctl_lock); break; } - case CTL_GET_PORT_LIST: { - struct ctl_port *port; - struct ctl_port_list *list; - int i; - - list = (struct ctl_port_list *)addr; - - if (list->alloc_len != (list->alloc_num * - sizeof(struct ctl_port_entry))) { - printf("%s: CTL_GET_PORT_LIST: alloc_len %u != " - "alloc_num %u * sizeof(struct ctl_port_entry) " - "%zu\n", __func__, list->alloc_len, - list->alloc_num, sizeof(struct ctl_port_entry)); - retval = EINVAL; - break; - } - list->fill_len = 0; - list->fill_num = 0; - list->dropped_num = 0; - i = 0; - mtx_lock(&softc->ctl_lock); - STAILQ_FOREACH(port, &softc->port_list, links) { - struct ctl_port_entry entry, *list_entry; - - if (list->fill_num >= list->alloc_num) { - list->dropped_num++; - continue; - } - - entry.port_type = port->port_type; - strlcpy(entry.port_name, port->port_name, - sizeof(entry.port_name)); - entry.targ_port = port->targ_port; - entry.physical_port = port->physical_port; - entry.virtual_port = port->virtual_port; - entry.wwnn = port->wwnn; - entry.wwpn = port->wwpn; - if (port->status & CTL_PORT_STATUS_ONLINE) - entry.online = 1; - else - entry.online = 0; - - list_entry = &list->entries[i]; - - retval = copyout(&entry, list_entry, sizeof(entry)); - if (retval != 0) { - printf("%s: CTL_GET_PORT_LIST: copyout " - "returned %d\n", __func__, retval); - break; - } - i++; - list->fill_num++; - list->fill_len += sizeof(entry); - } - mtx_unlock(&softc->ctl_lock); - - /* - * If this is non-zero, we had a copyout fault, so there's - * probably no point in attempting to set the status inside - * the structure. - */ - if (retval != 0) - break; - - if (list->dropped_num > 0) - list->status = CTL_PORT_LIST_NEED_MORE_SPACE; - else - list->status = CTL_PORT_LIST_OK; - break; - } - case CTL_DUMP_OOA: { - union ctl_io *io; - char printbuf[128]; - struct sbuf sb; - - mtx_lock(&softc->ctl_lock); - printf("Dumping OOA queues:\n"); - STAILQ_FOREACH(lun, &softc->lun_list, links) { - mtx_lock(&lun->lun_lock); - for (io = (union ctl_io *)TAILQ_FIRST( - &lun->ooa_queue); io != NULL; - io = (union ctl_io *)TAILQ_NEXT(&io->io_hdr, - ooa_links)) { - sbuf_new(&sb, printbuf, sizeof(printbuf), - SBUF_FIXEDLEN); - sbuf_printf(&sb, "LUN %jd tag 0x%04x%s%s%s%s: ", - (intmax_t)lun->lun, - io->scsiio.tag_num, - (io->io_hdr.flags & - CTL_FLAG_BLOCKED) ? "" : " BLOCKED", - (io->io_hdr.flags & - CTL_FLAG_DMA_INPROG) ? " DMA" : "", - (io->io_hdr.flags & - CTL_FLAG_ABORT) ? " ABORT" : "", - (io->io_hdr.flags & - CTL_FLAG_IS_WAS_ON_RTR) ? " RTR" : ""); - ctl_scsi_command_string(&io->scsiio, NULL, &sb); - sbuf_finish(&sb); - printf("%s\n", sbuf_data(&sb)); - } - mtx_unlock(&lun->lun_lock); - } - printf("OOA queues dump done\n"); - mtx_unlock(&softc->ctl_lock); - break; - } case CTL_GET_OOA: { struct ctl_ooa *ooa_hdr; struct ctl_ooa_entry *entries; @@ -2622,21 +2672,13 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, if (ooa_hdr->flags & CTL_OOA_FLAG_ALL_LUNS) { STAILQ_FOREACH(lun, &softc->lun_list, links) { - retval = ctl_ioctl_fill_ooa(lun, &cur_fill_num, - ooa_hdr, entries); - if (retval != 0) - break; - } - if (retval != 0) { - mtx_unlock(&softc->ctl_lock); - free(entries, M_CTL); - break; + ctl_ioctl_fill_ooa(lun, &cur_fill_num, + ooa_hdr, entries); } } else { lun = softc->ctl_luns[ooa_hdr->lun_num]; - - retval = ctl_ioctl_fill_ooa(lun, &cur_fill_num,ooa_hdr, - entries); + ctl_ioctl_fill_ooa(lun, &cur_fill_num, ooa_hdr, + entries); } mtx_unlock(&softc->ctl_lock); @@ -2649,7 +2691,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, __func__, ooa_hdr->fill_len); } - getbintime(&ooa_hdr->cur_bt); + getbinuptime(&ooa_hdr->cur_bt); if (cur_fill_num > ooa_hdr->alloc_num) { ooa_hdr->dropped_num = cur_fill_num -ooa_hdr->alloc_num; @@ -2662,38 +2704,6 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, free(entries, M_CTL); break; } - case CTL_CHECK_OOA: { - union ctl_io *io; - struct ctl_ooa_info *ooa_info; - - - ooa_info = (struct ctl_ooa_info *)addr; - - if (ooa_info->lun_id >= CTL_MAX_LUNS) { - ooa_info->status = CTL_OOA_INVALID_LUN; - break; - } - mtx_lock(&softc->ctl_lock); - lun = softc->ctl_luns[ooa_info->lun_id]; - if (lun == NULL) { - mtx_unlock(&softc->ctl_lock); - ooa_info->status = CTL_OOA_INVALID_LUN; - break; - } - mtx_lock(&lun->lun_lock); - mtx_unlock(&softc->ctl_lock); - ooa_info->num_entries = 0; - for (io = (union ctl_io *)TAILQ_FIRST(&lun->ooa_queue); - io != NULL; io = (union ctl_io *)TAILQ_NEXT( - &io->io_hdr, ooa_links)) { - ooa_info->num_entries++; - } - mtx_unlock(&lun->lun_lock); - - ooa_info->status = CTL_OOA_SUCCESS; - - break; - } case CTL_DELAY_IO: { struct ctl_io_delay_info *delay_info; @@ -2749,70 +2759,6 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, #endif /* CTL_IO_DELAY */ break; } - case CTL_REALSYNC_SET: { - int *syncstate; - - syncstate = (int *)addr; - - mtx_lock(&softc->ctl_lock); - switch (*syncstate) { - case 0: - softc->flags &= ~CTL_FLAG_REAL_SYNC; - break; - case 1: - softc->flags |= CTL_FLAG_REAL_SYNC; - break; - default: - retval = EINVAL; - break; - } - mtx_unlock(&softc->ctl_lock); - break; - } - case CTL_REALSYNC_GET: { - int *syncstate; - - syncstate = (int*)addr; - - mtx_lock(&softc->ctl_lock); - if (softc->flags & CTL_FLAG_REAL_SYNC) - *syncstate = 1; - else - *syncstate = 0; - mtx_unlock(&softc->ctl_lock); - - break; - } - case CTL_SETSYNC: - case CTL_GETSYNC: { - struct ctl_sync_info *sync_info; - - sync_info = (struct ctl_sync_info *)addr; - - mtx_lock(&softc->ctl_lock); - lun = softc->ctl_luns[sync_info->lun_id]; - if (lun == NULL) { - mtx_unlock(&softc->ctl_lock); - sync_info->status = CTL_GS_SYNC_NO_LUN; - break; - } - /* - * Get or set the sync interval. We're not bounds checking - * in the set case, hopefully the user won't do something - * silly. - */ - mtx_lock(&lun->lun_lock); - mtx_unlock(&softc->ctl_lock); - if (cmd == CTL_GETSYNC) - sync_info->sync_interval = lun->sync_interval; - else - lun->sync_interval = sync_info->sync_interval; - mtx_unlock(&lun->lun_lock); - - sync_info->status = CTL_GS_SYNC_OK; - - break; - } case CTL_GETSTATS: { struct ctl_stats *stats; int i; @@ -2829,9 +2775,9 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, * XXX KDM no locking here. If the LUN list changes, * things can blow up. */ - for (i = 0, lun = STAILQ_FIRST(&softc->lun_list); lun != NULL; - i++, lun = STAILQ_NEXT(lun, links)) { - retval = copyout(&lun->stats, &stats->lun_stats[i], + i = 0; + STAILQ_FOREACH(lun, &softc->lun_list, links) { + retval = copyout(&lun->stats, &stats->lun_stats[i++], sizeof(lun->stats)); if (retval != 0) break; @@ -3481,7 +3427,7 @@ ctl_get_initindex(struct ctl_nexus *nexus) int ctl_lun_map_init(struct ctl_port *port) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = port->ctl_softc; struct ctl_lun *lun; uint32_t i; @@ -3505,7 +3451,7 @@ ctl_lun_map_init(struct ctl_port *port) int ctl_lun_map_deinit(struct ctl_port *port) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = port->ctl_softc; struct ctl_lun *lun; if (port->lun_map == NULL) @@ -3811,46 +3757,6 @@ ctl_zero_io(union ctl_io *io) io->io_hdr.pool = pool_ref; } -/* - * This routine is currently used for internal copies of ctl_ios that need - * to persist for some reason after we've already returned status to the - * FETD. (Thus the flag set.) - * - * XXX XXX - * Note that this makes a blind copy of all fields in the ctl_io, except - * for the pool reference. This includes any memory that has been - * allocated! That memory will no longer be valid after done has been - * called, so this would be VERY DANGEROUS for command that actually does - * any reads or writes. Right now (11/7/2005), this is only used for immediate - * start and stop commands, which don't transfer any data, so this is not a - * problem. If it is used for anything else, the caller would also need to - * allocate data buffer space and this routine would need to be modified to - * copy the data buffer(s) as well. - */ -void -ctl_copy_io(union ctl_io *src, union ctl_io *dest) -{ - void *pool_ref; - - if ((src == NULL) - || (dest == NULL)) - return; - - /* - * May need to preserve linked list pointers at some point too. - */ - pool_ref = dest->io_hdr.pool; - - memcpy(dest, src, MIN(sizeof(*src), sizeof(*dest))); - - dest->io_hdr.pool = pool_ref; - /* - * We need to know that this is an internal copy, and doesn't need - * to get passed back to the FETD that allocated it. - */ - dest->io_hdr.flags |= CTL_FLAG_INT_COPY; -} - int ctl_expand_number(const char *buf, uint64_t *num) { @@ -3915,14 +3821,14 @@ ctl_init_page_index(struct ctl_lun *lun) for (i = 0; i < CTL_NUM_MODE_PAGES; i++) { page_index = &lun->mode_pages.index[i]; - /* - * If this is a disk-only mode page, there's no point in - * setting it up. For some pages, we have to have some - * basic information about the disk in order to calculate the - * mode page data. - */ - if ((lun->be_lun->lun_type != T_DIRECT) - && (page_index->page_flags & CTL_PAGE_FLAG_DISK_ONLY)) + if (lun->be_lun->lun_type == T_DIRECT && + (page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0) + continue; + if (lun->be_lun->lun_type == T_PROCESSOR && + (page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0) + continue; + if (lun->be_lun->lun_type == T_CDROM && + (page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0) continue; switch (page_index->page_code & SMPH_PC_MASK) { @@ -4254,12 +4160,26 @@ ctl_init_page_index(struct ctl_lun *lun) }} break; } + case SMS_CDDVD_CAPS_PAGE:{ + memcpy(&lun->mode_pages.cddvd_page[CTL_PAGE_DEFAULT], + &cddvd_page_default, + sizeof(cddvd_page_default)); + memcpy(&lun->mode_pages.cddvd_page[ + CTL_PAGE_CHANGEABLE], &cddvd_page_changeable, + sizeof(cddvd_page_changeable)); + memcpy(&lun->mode_pages.cddvd_page[CTL_PAGE_SAVED], + &cddvd_page_default, + sizeof(cddvd_page_default)); + memcpy(&lun->mode_pages.cddvd_page[CTL_PAGE_CURRENT], + &lun->mode_pages.cddvd_page[CTL_PAGE_SAVED], + sizeof(cddvd_page_default)); + page_index->page_data = + (uint8_t *)lun->mode_pages.cddvd_page; + break; + } case SMS_VENDOR_SPECIFIC_PAGE:{ switch (page_index->subpage) { case DBGCNF_SUBPAGE_CODE: { - struct copan_debugconf_subpage *current_page, - *saved_page; - memcpy(&lun->mode_pages.debugconf_subpage[ CTL_PAGE_CURRENT], &debugconf_page_default, @@ -4277,16 +4197,7 @@ ctl_init_page_index(struct ctl_lun *lun) &debugconf_page_default, sizeof(debugconf_page_default)); page_index->page_data = - (uint8_t *)lun->mode_pages.debugconf_subpage; - - current_page = (struct copan_debugconf_subpage *) - (page_index->page_data + - (page_index->page_len * - CTL_PAGE_CURRENT)); - saved_page = (struct copan_debugconf_subpage *) - (page_index->page_data + - (page_index->page_len * - CTL_PAGE_SAVED)); + (uint8_t *)lun->mode_pages.debugconf_subpage; break; } default: @@ -4319,18 +4230,18 @@ ctl_init_log_page_index(struct ctl_lun *lun) for (i = 0, j = 0, k = 0; i < CTL_NUM_LOG_PAGES; i++) { page_index = &lun->log_pages.index[i]; - /* - * If this is a disk-only mode page, there's no point in - * setting it up. For some pages, we have to have some - * basic information about the disk in order to calculate the - * mode page data. - */ - if ((lun->be_lun->lun_type != T_DIRECT) - && (page_index->page_flags & CTL_PAGE_FLAG_DISK_ONLY)) + if (lun->be_lun->lun_type == T_DIRECT && + (page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0) + continue; + if (lun->be_lun->lun_type == T_PROCESSOR && + (page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0) + continue; + if (lun->be_lun->lun_type == T_CDROM && + (page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0) continue; if (page_index->page_code == SLS_LOGICAL_BLOCK_PROVISIONING && - lun->backend->lun_attr == NULL) + lun->backend->lun_attr == NULL) continue; if (page_index->page_code != prev) { @@ -4402,7 +4313,7 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun, struct ctl_lun *nlun, *lun; struct scsi_vpd_id_descriptor *desc; struct scsi_vpd_id_t10 *t10id; - const char *eui, *naa, *scsiname, *vendor; + const char *eui, *naa, *scsiname, *vendor, *value; int lun_number, i, lun_malloced; int devidlen, idlen1, idlen2 = 0, len; @@ -4414,8 +4325,8 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun, */ switch (be_lun->lun_type) { case T_DIRECT: - break; case T_PROCESSOR: + case T_CDROM: break; case T_SEQUENTIAL: case T_CHANGER: @@ -4556,18 +4467,23 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun, be_lun->ctl_lun = lun; be_lun->lun_id = lun_number; atomic_add_int(&be_lun->be->num_luns, 1); - if (be_lun->flags & CTL_LUN_FLAG_OFFLINE) - lun->flags |= CTL_LUN_OFFLINE; - - if (be_lun->flags & CTL_LUN_FLAG_POWERED_OFF) + if (be_lun->flags & CTL_LUN_FLAG_EJECTED) + lun->flags |= CTL_LUN_EJECTED; + if (be_lun->flags & CTL_LUN_FLAG_NO_MEDIA) + lun->flags |= CTL_LUN_NO_MEDIA; + if (be_lun->flags & CTL_LUN_FLAG_STOPPED) lun->flags |= CTL_LUN_STOPPED; - if (be_lun->flags & CTL_LUN_FLAG_INOPERABLE) - lun->flags |= CTL_LUN_INOPERABLE; - if (be_lun->flags & CTL_LUN_FLAG_PRIMARY) lun->flags |= CTL_LUN_PRIMARY_SC; + value = ctl_get_opt(&be_lun->options, "removable"); + if (value != NULL) { + if (strcmp(value, "on") == 0) + lun->flags |= CTL_LUN_REMOVABLE; + } else if (be_lun->lun_type == T_CDROM) + lun->flags |= CTL_LUN_REMOVABLE; + lun->ctl_softc = ctl_softc; #ifdef CTL_TIME_IO lun->last_busy = getsbinuptime(); @@ -4602,9 +4518,8 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun, /* Setup statistics gathering */ lun->stats.device_type = be_lun->lun_type; lun->stats.lun_number = lun_number; - if (lun->stats.device_type == T_DIRECT) - lun->stats.blocksize = be_lun->blocksize; - else + lun->stats.blocksize = be_lun->blocksize; + if (be_lun->blocksize == 0) lun->stats.flags = CTL_LUN_STATS_NO_BLOCKSIZE; for (i = 0;i < CTL_MAX_PORTS;i++) lun->stats.ports[i].targ_port = i; @@ -4672,14 +4587,11 @@ ctl_free_lun(struct ctl_lun *lun) static void ctl_create_lun(struct ctl_be_lun *be_lun) { - struct ctl_softc *softc; - - softc = control_softc; /* * ctl_alloc_lun() should handle all potential failure cases. */ - ctl_alloc_lun(softc, NULL, be_lun); + ctl_alloc_lun(control_softc, NULL, be_lun); } int @@ -4720,8 +4632,7 @@ ctl_enable_lun(struct ctl_be_lun *be_lun) lun->flags &= ~CTL_LUN_DISABLED; mtx_unlock(&lun->lun_lock); - for (port = STAILQ_FIRST(&softc->port_list); port != NULL; port = nport) { - nport = STAILQ_NEXT(port, links); + STAILQ_FOREACH_SAFE(port, &softc->port_list, links, nport) { if ((port->status & CTL_PORT_STATUS_ONLINE) == 0 || port->lun_map != NULL || port->lun_enable == NULL) continue; @@ -4821,23 +4732,51 @@ ctl_stop_lun(struct ctl_be_lun *be_lun) } int -ctl_lun_offline(struct ctl_be_lun *be_lun) +ctl_lun_no_media(struct ctl_be_lun *be_lun) { struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun; mtx_lock(&lun->lun_lock); - lun->flags |= CTL_LUN_OFFLINE; + lun->flags |= CTL_LUN_NO_MEDIA; mtx_unlock(&lun->lun_lock); return (0); } int -ctl_lun_online(struct ctl_be_lun *be_lun) +ctl_lun_has_media(struct ctl_be_lun *be_lun) { struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun; + union ctl_ha_msg msg; mtx_lock(&lun->lun_lock); - lun->flags &= ~CTL_LUN_OFFLINE; + lun->flags &= ~(CTL_LUN_NO_MEDIA | CTL_LUN_EJECTED); + if (lun->flags & CTL_LUN_REMOVABLE) + ctl_est_ua_all(lun, -1, CTL_UA_MEDIUM_CHANGE); + mtx_unlock(&lun->lun_lock); + if ((lun->flags & CTL_LUN_REMOVABLE) && + lun->ctl_softc->ha_mode == CTL_HA_MODE_XFER) { + bzero(&msg.ua, sizeof(msg.ua)); + msg.hdr.msg_type = CTL_MSG_UA; + msg.hdr.nexus.initid = -1; + msg.hdr.nexus.targ_port = -1; + msg.hdr.nexus.targ_lun = lun->lun; + msg.hdr.nexus.targ_mapped_lun = lun->lun; + msg.ua.ua_all = 1; + msg.ua.ua_set = 1; + msg.ua.ua_type = CTL_UA_MEDIUM_CHANGE; + ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg, sizeof(msg.ua), + M_WAITOK); + } + return (0); +} + +int +ctl_lun_ejected(struct ctl_be_lun *be_lun) +{ + struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun; + + mtx_lock(&lun->lun_lock); + lun->flags |= CTL_LUN_EJECTED; mtx_unlock(&lun->lun_lock); return (0); } @@ -4907,28 +4846,6 @@ ctl_invalidate_lun(struct ctl_be_lun *be_lun) return (0); } -int -ctl_lun_inoperable(struct ctl_be_lun *be_lun) -{ - struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun; - - mtx_lock(&lun->lun_lock); - lun->flags |= CTL_LUN_INOPERABLE; - mtx_unlock(&lun->lun_lock); - return (0); -} - -int -ctl_lun_operable(struct ctl_be_lun *be_lun) -{ - struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun; - - mtx_lock(&lun->lun_lock); - lun->flags &= ~CTL_LUN_INOPERABLE; - mtx_unlock(&lun->lun_lock); - return (0); -} - void ctl_lun_capacity_changed(struct ctl_be_lun *be_lun) { @@ -4936,7 +4853,7 @@ ctl_lun_capacity_changed(struct ctl_be_lun *be_lun) union ctl_ha_msg msg; mtx_lock(&lun->lun_lock); - ctl_est_ua_all(lun, -1, CTL_UA_CAPACITY_CHANGED); + ctl_est_ua_all(lun, -1, CTL_UA_CAPACITY_CHANGE); mtx_unlock(&lun->lun_lock); if (lun->ctl_softc->ha_mode == CTL_HA_MODE_XFER) { /* Send msg to other side. */ @@ -4948,7 +4865,7 @@ ctl_lun_capacity_changed(struct ctl_be_lun *be_lun) msg.hdr.nexus.targ_mapped_lun = lun->lun; msg.ua.ua_all = 1; msg.ua.ua_set = 1; - msg.ua.ua_type = CTL_UA_CAPACITY_CHANGED; + msg.ua.ua_type = CTL_UA_CAPACITY_CHANGE; ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg, sizeof(msg.ua), M_WAITOK); } @@ -5125,36 +5042,14 @@ ctl_config_read_done(union ctl_io *io) int ctl_scsi_release(struct ctl_scsiio *ctsio) { - int length, longid, thirdparty_id, resv_id; struct ctl_lun *lun; uint32_t residx; - length = 0; - resv_id = 0; - CTL_DEBUG_PRINT(("ctl_scsi_release\n")); residx = ctl_get_initindex(&ctsio->io_hdr.nexus); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - switch (ctsio->cdb[0]) { - case RELEASE_10: { - struct scsi_release_10 *cdb; - - cdb = (struct scsi_release_10 *)ctsio->cdb; - - if (cdb->byte2 & SR10_LONGID) - longid = 1; - else - thirdparty_id = cdb->thirdparty_id; - - resv_id = cdb->resv_id; - length = scsi_2btoul(cdb->length); - break; - } - } - - /* * XXX KDM right now, we only support LUN reservation. We don't * support 3rd party reservations, or extent reservations, which @@ -5162,25 +5057,6 @@ ctl_scsi_release(struct ctl_scsiio *ctsio) * far, we've got a LUN reservation. Anything else got kicked out * above. So, according to SPC, ignore the length. */ - length = 0; - - if (((ctsio->io_hdr.flags & CTL_FLAG_ALLOCATED) == 0) - && (length > 0)) { - ctsio->kern_data_ptr = malloc(length, M_CTL, M_WAITOK); - ctsio->kern_data_len = length; - ctsio->kern_total_len = length; - ctsio->kern_data_resid = 0; - ctsio->kern_rel_offset = 0; - ctsio->kern_sg_entries = 0; - ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; - ctsio->be_move_done = ctl_config_move_done; - ctl_datamove((union ctl_io *)ctsio); - - return (CTL_RETVAL_COMPLETE); - } - - if (length > 0) - thirdparty_id = scsi_8btou64(ctsio->kern_data_ptr); mtx_lock(&lun->lun_lock); @@ -5196,11 +5072,6 @@ ctl_scsi_release(struct ctl_scsiio *ctsio) mtx_unlock(&lun->lun_lock); - if (ctsio->io_hdr.flags & CTL_FLAG_ALLOCATED) { - free(ctsio->kern_data_ptr, M_CTL); - ctsio->io_hdr.flags &= ~CTL_FLAG_ALLOCATED; - } - ctl_set_success(ctsio); ctl_done((union ctl_io *)ctsio); return (CTL_RETVAL_COMPLETE); @@ -5209,41 +5080,14 @@ ctl_scsi_release(struct ctl_scsiio *ctsio) int ctl_scsi_reserve(struct ctl_scsiio *ctsio) { - int extent, thirdparty, longid; - int resv_id, length; - uint64_t thirdparty_id; struct ctl_lun *lun; uint32_t residx; - extent = 0; - thirdparty = 0; - longid = 0; - resv_id = 0; - length = 0; - thirdparty_id = 0; - CTL_DEBUG_PRINT(("ctl_reserve\n")); residx = ctl_get_initindex(&ctsio->io_hdr.nexus); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - switch (ctsio->cdb[0]) { - case RESERVE_10: { - struct scsi_reserve_10 *cdb; - - cdb = (struct scsi_reserve_10 *)ctsio->cdb; - - if (cdb->byte2 & SR10_LONGID) - longid = 1; - else - thirdparty_id = cdb->thirdparty_id; - - resv_id = cdb->resv_id; - length = scsi_2btoul(cdb->length); - break; - } - } - /* * XXX KDM right now, we only support LUN reservation. We don't * support 3rd party reservations, or extent reservations, which @@ -5251,25 +5095,6 @@ ctl_scsi_reserve(struct ctl_scsiio *ctsio) * far, we've got a LUN reservation. Anything else got kicked out * above. So, according to SPC, ignore the length. */ - length = 0; - - if (((ctsio->io_hdr.flags & CTL_FLAG_ALLOCATED) == 0) - && (length > 0)) { - ctsio->kern_data_ptr = malloc(length, M_CTL, M_WAITOK); - ctsio->kern_data_len = length; - ctsio->kern_total_len = length; - ctsio->kern_data_resid = 0; - ctsio->kern_rel_offset = 0; - ctsio->kern_sg_entries = 0; - ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; - ctsio->be_move_done = ctl_config_move_done; - ctl_datamove((union ctl_io *)ctsio); - - return (CTL_RETVAL_COMPLETE); - } - - if (length > 0) - thirdparty_id = scsi_8btou64(ctsio->kern_data_ptr); mtx_lock(&lun->lun_lock); if ((lun->flags & CTL_LUN_RESERVED) && (lun->res_idx != residx)) { @@ -5277,19 +5102,18 @@ ctl_scsi_reserve(struct ctl_scsiio *ctsio) goto bailout; } + /* SPC-3 exceptions to SPC-2 RESERVE and RELEASE behavior. */ + if (lun->flags & CTL_LUN_PR_RESERVED) { + ctl_set_success(ctsio); + goto bailout; + } + lun->flags |= CTL_LUN_RESERVED; lun->res_idx = residx; - ctl_set_success(ctsio); bailout: mtx_unlock(&lun->lun_lock); - - if (ctsio->io_hdr.flags & CTL_FLAG_ALLOCATED) { - free(ctsio->kern_data_ptr, M_CTL); - ctsio->io_hdr.flags &= ~CTL_FLAG_ALLOCATED; - } - ctl_done((union ctl_io *)ctsio); return (CTL_RETVAL_COMPLETE); } @@ -5304,113 +5128,83 @@ ctl_start_stop(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_start_stop\n")); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - retval = 0; - cdb = (struct scsi_start_stop_unit *)ctsio->cdb; - /* - * XXX KDM - * We don't support the immediate bit on a stop unit. In order to - * do that, we would need to code up a way to know that a stop is - * pending, and hold off any new commands until it completes, one - * way or another. Then we could accept or reject those commands - * depending on its status. We would almost need to do the reverse - * of what we do below for an immediate start -- return the copy of - * the ctl_io to the FETD with status to send to the host (and to - * free the copy!) and then free the original I/O once the stop - * actually completes. That way, the OOA queue mechanism can work - * to block commands that shouldn't proceed. Another alternative - * would be to put the copy in the queue in place of the original, - * and return the original back to the caller. That could be - * slightly safer.. - */ - if ((cdb->byte2 & SSS_IMMED) - && ((cdb->how & SSS_START) == 0)) { - ctl_set_invalid_field(ctsio, - /*sks_valid*/ 1, - /*command*/ 1, - /*field*/ 1, - /*bit_valid*/ 1, - /*bit*/ 0); - ctl_done((union ctl_io *)ctsio); - return (CTL_RETVAL_COMPLETE); - } + if ((cdb->how & SSS_PC_MASK) == 0) { + if ((lun->flags & CTL_LUN_PR_RESERVED) && + (cdb->how & SSS_START) == 0) { + uint32_t residx; - if ((lun->flags & CTL_LUN_PR_RESERVED) - && ((cdb->how & SSS_START)==0)) { - uint32_t residx; + residx = ctl_get_initindex(&ctsio->io_hdr.nexus); + if (ctl_get_prkey(lun, residx) == 0 || + (lun->pr_res_idx != residx && lun->pr_res_type < 4)) { - residx = ctl_get_initindex(&ctsio->io_hdr.nexus); - if (ctl_get_prkey(lun, residx) == 0 - || (lun->pr_res_idx!=residx && lun->res_type < 4)) { + ctl_set_reservation_conflict(ctsio); + ctl_done((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); + } + } - ctl_set_reservation_conflict(ctsio); + if ((cdb->how & SSS_LOEJ) && + (lun->flags & CTL_LUN_REMOVABLE) == 0) { + ctl_set_invalid_field(ctsio, + /*sks_valid*/ 1, + /*command*/ 1, + /*field*/ 4, + /*bit_valid*/ 1, + /*bit*/ 1); + ctl_done((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); + } + + if ((cdb->how & SSS_START) == 0 && (cdb->how & SSS_LOEJ) && + lun->prevent_count > 0) { + /* "Medium removal prevented" */ + ctl_set_sense(ctsio, /*current_error*/ 1, + /*sense_key*/(lun->flags & CTL_LUN_NO_MEDIA) ? + SSD_KEY_NOT_READY : SSD_KEY_ILLEGAL_REQUEST, + /*asc*/ 0x53, /*ascq*/ 0x02, SSD_ELEM_NONE); ctl_done((union ctl_io *)ctsio); return (CTL_RETVAL_COMPLETE); } } - /* - * If there is no backend on this device, we can't start or stop - * it. In theory we shouldn't get any start/stop commands in the - * first place at this level if the LUN doesn't have a backend. - * That should get stopped by the command decode code. - */ - if (lun->backend == NULL) { + retval = lun->backend->config_write((union ctl_io *)ctsio); + return (retval); +} + +int +ctl_prevent_allow(struct ctl_scsiio *ctsio) +{ + struct ctl_lun *lun; + struct scsi_prevent *cdb; + int retval; + uint32_t initidx; + + CTL_DEBUG_PRINT(("ctl_prevent_allow\n")); + + lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + cdb = (struct scsi_prevent *)ctsio->cdb; + + if ((lun->flags & CTL_LUN_REMOVABLE) == 0) { ctl_set_invalid_opcode(ctsio); ctl_done((union ctl_io *)ctsio); return (CTL_RETVAL_COMPLETE); } - /* - * XXX KDM Copan-specific offline behavior. - * Figure out a reasonable way to port this? - */ -#ifdef NEEDTOPORT + initidx = ctl_get_initindex(&ctsio->io_hdr.nexus); mtx_lock(&lun->lun_lock); - - if (((cdb->byte2 & SSS_ONOFFLINE) == 0) - && (lun->flags & CTL_LUN_OFFLINE)) { - /* - * If the LUN is offline, and the on/offline bit isn't set, - * reject the start or stop. Otherwise, let it through. - */ - mtx_unlock(&lun->lun_lock); - ctl_set_lun_not_ready(ctsio); - ctl_done((union ctl_io *)ctsio); - } else { - mtx_unlock(&lun->lun_lock); -#endif /* NEEDTOPORT */ - /* - * This could be a start or a stop when we're online, - * or a stop/offline or start/online. A start or stop when - * we're offline is covered in the case above. - */ - /* - * In the non-immediate case, we send the request to - * the backend and return status to the user when - * it is done. - * - * In the immediate case, we allocate a new ctl_io - * to hold a copy of the request, and send that to - * the backend. We then set good status on the - * user's request and return it immediately. - */ - if (cdb->byte2 & SSS_IMMED) { - union ctl_io *new_io; - - new_io = ctl_alloc_io(ctsio->io_hdr.pool); - ctl_copy_io((union ctl_io *)ctsio, new_io); - retval = lun->backend->config_write(new_io); - ctl_set_success(ctsio); - ctl_done((union ctl_io *)ctsio); - } else { - retval = lun->backend->config_write( - (union ctl_io *)ctsio); - } -#ifdef NEEDTOPORT + if ((cdb->how & PR_PREVENT) && + ctl_is_set(lun->prevent, initidx) == 0) { + ctl_set_mask(lun->prevent, initidx); + lun->prevent_count++; + } else if ((cdb->how & PR_PREVENT) == 0 && + ctl_is_set(lun->prevent, initidx)) { + ctl_clear_mask(lun->prevent, initidx); + lun->prevent_count--; } -#endif + mtx_unlock(&lun->lun_lock); + retval = lun->backend->config_write((union ctl_io *)ctsio); return (retval); } @@ -5475,38 +5269,13 @@ ctl_sync_cache(struct ctl_scsiio *ctsio) goto bailout; } - /* - * If this LUN has no backend, we can't flush the cache anyway. - */ - if (lun->backend == NULL) { - ctl_set_invalid_opcode(ctsio); - ctl_done((union ctl_io *)ctsio); - goto bailout; - } - lbalen = (struct ctl_lba_len_flags *)&ctsio->io_hdr.ctl_private[CTL_PRIV_LBA_LEN]; lbalen->lba = starting_lba; lbalen->len = block_count; lbalen->flags = byte2; - - /* - * Check to see whether we're configured to send the SYNCHRONIZE - * CACHE command directly to the back end. - */ - mtx_lock(&lun->lun_lock); - if ((softc->flags & CTL_FLAG_REAL_SYNC) - && (++(lun->sync_count) >= lun->sync_interval)) { - lun->sync_count = 0; - mtx_unlock(&lun->lun_lock); - retval = lun->backend->config_write((union ctl_io *)ctsio); - } else { - mtx_unlock(&lun->lun_lock); - ctl_set_success(ctsio); - ctl_done((union ctl_io *)ctsio); - } + retval = lun->backend->config_write((union ctl_io *)ctsio); bailout: - return (retval); } @@ -5584,17 +5353,6 @@ ctl_format(struct ctl_scsiio *ctsio) } } - /* - * The format command will clear out the "Medium format corrupted" - * status if set by the configuration code. That status is really - * just a way to notify the host that we have lost the media, and - * get them to issue a command that will basically make them think - * they're blowing away the media. - */ - mtx_lock(&lun->lun_lock); - lun->flags &= ~CTL_LUN_INOPERABLE; - mtx_unlock(&lun->lun_lock); - ctl_set_success(ctsio); bailout: @@ -5769,8 +5527,6 @@ ctl_write_same(struct ctl_scsiio *ctsio) int len, retval; uint8_t byte2; - retval = CTL_RETVAL_COMPLETE; - CTL_DEBUG_PRINT(("ctl_write_same\n")); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; @@ -5887,8 +5643,6 @@ ctl_unmap(struct ctl_scsiio *ctsio) int len, retval; uint8_t byte2; - retval = CTL_RETVAL_COMPLETE; - CTL_DEBUG_PRINT(("ctl_unmap\n")); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; @@ -6147,9 +5901,6 @@ ctl_debugconf_sp_sense_handler(struct ctl_scsiio *ctsio, page->ctl_time_io_secs[1] = ctl_time_io_secs >> 0; break; default: -#ifdef NEEDTOPORT - EPRINT(0, "Invalid PC %d!!", pc); -#endif /* NEEDTOPORT */ break; } return (0); @@ -6162,8 +5913,7 @@ ctl_do_mode_select(union ctl_io *io) struct scsi_mode_page_header *page_header; struct ctl_page_index *page_index; struct ctl_scsiio *ctsio; - int control_dev, page_len; - int page_len_offset, page_len_size; + int page_len, page_len_offset, page_len_size; union ctl_modepage_info *modepage_info; struct ctl_lun *lun; int *len_left, *len_used; @@ -6172,15 +5922,8 @@ ctl_do_mode_select(union ctl_io *io) ctsio = &io->scsiio; page_index = NULL; page_len = 0; - retval = CTL_RETVAL_COMPLETE; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - if (lun->be_lun->lun_type != T_DIRECT) - control_dev = 1; - else - control_dev = 0; - modepage_info = (union ctl_modepage_info *) ctsio->io_hdr.ctl_private[CTL_PRIV_MODEPAGE].bytes; len_left = &modepage_info->header.len_left; @@ -6217,13 +5960,18 @@ do_next_page: * XXX KDM should we do something with the block descriptor? */ for (i = 0; i < CTL_NUM_MODE_PAGES; i++) { - - if ((control_dev != 0) - && (lun->mode_pages.index[i].page_flags & - CTL_PAGE_FLAG_DISK_ONLY)) + page_index = &lun->mode_pages.index[i]; + if (lun->be_lun->lun_type == T_DIRECT && + (page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0) + continue; + if (lun->be_lun->lun_type == T_PROCESSOR && + (page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0) + continue; + if (lun->be_lun->lun_type == T_CDROM && + (page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0) continue; - if ((lun->mode_pages.index[i].page_code & SMPH_PC_MASK) != + if ((page_index->page_code & SMPH_PC_MASK) != (page_header->page_code & SMPH_PC_MASK)) continue; @@ -6231,9 +5979,8 @@ do_next_page: * If neither page has a subpage code, then we've got a * match. */ - if (((lun->mode_pages.index[i].page_code & SMPH_SPF) == 0) + if (((page_index->page_code & SMPH_SPF) == 0) && ((page_header->page_code & SMPH_SPF) == 0)) { - page_index = &lun->mode_pages.index[i]; page_len = page_header->page_length; break; } @@ -6242,15 +5989,12 @@ do_next_page: * If both pages have subpages, then the subpage numbers * have to match. */ - if ((lun->mode_pages.index[i].page_code & SMPH_SPF) + if ((page_index->page_code & SMPH_SPF) && (page_header->page_code & SMPH_SPF)) { struct scsi_mode_page_header_sp *sph; sph = (struct scsi_mode_page_header_sp *)page_header; - - if (lun->mode_pages.index[i].subpage == - sph->subpage) { - page_index = &lun->mode_pages.index[i]; + if (page_index->subpage == sph->subpage) { page_len = scsi_2btoul(sph->page_length); break; } @@ -6261,7 +6005,7 @@ do_next_page: * If we couldn't find the page, or if we don't have a mode select * handler for it, send back an error to the user. */ - if ((page_index == NULL) + if ((i >= CTL_NUM_MODE_PAGES) || (page_index->select_handler == NULL)) { ctl_set_invalid_field(ctsio, /*sks_valid*/ 1, @@ -6391,28 +6135,7 @@ ctl_mode_select(struct ctl_scsiio *ctsio) { int param_len, pf, sp; int header_size, bd_len; - int len_left, len_used; - struct ctl_page_index *page_index; - struct ctl_lun *lun; - int control_dev, page_len; union ctl_modepage_info *modepage_info; - int retval; - - pf = 0; - sp = 0; - page_len = 0; - len_used = 0; - len_left = 0; - retval = 0; - bd_len = 0; - page_index = NULL; - - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - - if (lun->be_lun->lun_type != T_DIRECT) - control_dev = 1; - else - control_dev = 0; switch (ctsio->cdb[0]) { case MODE_SELECT_6: { @@ -6422,7 +6145,6 @@ ctl_mode_select(struct ctl_scsiio *ctsio) pf = (cdb->byte2 & SMS_PF) ? 1 : 0; sp = (cdb->byte2 & SMS_SP) ? 1 : 0; - param_len = cdb->length; header_size = sizeof(struct scsi_mode_header_6); break; @@ -6434,7 +6156,6 @@ ctl_mode_select(struct ctl_scsiio *ctsio) pf = (cdb->byte2 & SMS_PF) ? 1 : 0; sp = (cdb->byte2 & SMS_SP) ? 1 : 0; - param_len = scsi_2btoul(cdb->length); header_size = sizeof(struct scsi_mode_header_10); break; @@ -6443,7 +6164,6 @@ ctl_mode_select(struct ctl_scsiio *ctsio) ctl_set_invalid_opcode(ctsio); ctl_done((union ctl_io *)ctsio); return (CTL_RETVAL_COMPLETE); - break; /* NOTREACHED */ } /* @@ -6525,14 +6245,9 @@ ctl_mode_select(struct ctl_scsiio *ctsio) modepage_info = (union ctl_modepage_info *) ctsio->io_hdr.ctl_private[CTL_PRIV_MODEPAGE].bytes; - memset(modepage_info, 0, sizeof(*modepage_info)); - - len_left = param_len - header_size - bd_len; - len_used = header_size + bd_len; - - modepage_info->header.len_left = len_left; - modepage_info->header.len_used = len_used; + modepage_info->header.len_left = param_len - header_size - bd_len; + modepage_info->header.len_used = header_size + bd_len; return (ctl_do_mode_select((union ctl_io *)ctsio)); } @@ -6545,22 +6260,14 @@ ctl_mode_sense(struct ctl_scsiio *ctsio) int alloc_len, page_len, header_len, total_len; struct scsi_mode_block_descr *block_desc; struct ctl_page_index *page_index; - int control_dev; dbd = 0; llba = 0; block_desc = NULL; - page_index = NULL; CTL_DEBUG_PRINT(("ctl_mode_sense\n")); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - - if (lun->be_lun->lun_type != T_DIRECT) - control_dev = 1; - else - control_dev = 0; - switch (ctsio->cdb[0]) { case MODE_SENSE_6: { struct scsi_mode_sense_6 *cdb; @@ -6633,26 +6340,33 @@ ctl_mode_sense(struct ctl_scsiio *ctsio) } for (i = 0; i < CTL_NUM_MODE_PAGES; i++) { - if ((control_dev != 0) - && (lun->mode_pages.index[i].page_flags & - CTL_PAGE_FLAG_DISK_ONLY)) + page_index = &lun->mode_pages.index[i]; + + /* Make sure the page is supported for this dev type */ + if (lun->be_lun->lun_type == T_DIRECT && + (page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0) + continue; + if (lun->be_lun->lun_type == T_PROCESSOR && + (page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0) + continue; + if (lun->be_lun->lun_type == T_CDROM && + (page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0) continue; /* * We don't use this subpage if the user didn't * request all subpages. */ - if ((lun->mode_pages.index[i].subpage != 0) + if ((page_index->subpage != 0) && (subpage == SMS_SUBPAGE_PAGE_0)) continue; #if 0 printf("found page %#x len %d\n", - lun->mode_pages.index[i].page_code & - SMPH_PC_MASK, - lun->mode_pages.index[i].page_len); + page_index->page_code & SMPH_PC_MASK, + page_index->page_len); #endif - page_len += lun->mode_pages.index[i].page_len; + page_len += page_index->page_len; } break; } @@ -6662,30 +6376,35 @@ ctl_mode_sense(struct ctl_scsiio *ctsio) page_len = 0; for (i = 0; i < CTL_NUM_MODE_PAGES; i++) { + page_index = &lun->mode_pages.index[i]; + + /* Make sure the page is supported for this dev type */ + if (lun->be_lun->lun_type == T_DIRECT && + (page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0) + continue; + if (lun->be_lun->lun_type == T_PROCESSOR && + (page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0) + continue; + if (lun->be_lun->lun_type == T_CDROM && + (page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0) + continue; + /* Look for the right page code */ - if ((lun->mode_pages.index[i].page_code & - SMPH_PC_MASK) != page_code) + if ((page_index->page_code & SMPH_PC_MASK) != page_code) continue; /* Look for the right subpage or the subpage wildcard*/ - if ((lun->mode_pages.index[i].subpage != subpage) + if ((page_index->subpage != subpage) && (subpage != SMS_SUBPAGE_ALL)) continue; - /* Make sure the page is supported for this dev type */ - if ((control_dev != 0) - && (lun->mode_pages.index[i].page_flags & - CTL_PAGE_FLAG_DISK_ONLY)) - continue; - #if 0 printf("found page %#x len %d\n", - lun->mode_pages.index[i].page_code & - SMPH_PC_MASK, - lun->mode_pages.index[i].page_len); + page_index->page_code & SMPH_PC_MASK, + page_index->page_len); #endif - page_len += lun->mode_pages.index[i].page_len; + page_len += page_index->page_len; } if (page_len == 0) { @@ -6729,7 +6448,7 @@ ctl_mode_sense(struct ctl_scsiio *ctsio) header = (struct scsi_mode_hdr_6 *)ctsio->kern_data_ptr; header->datalen = MIN(total_len - 1, 254); - if (control_dev == 0) { + if (lun->be_lun->lun_type == T_DIRECT) { header->dev_specific = 0x10; /* DPOFUA */ if ((lun->be_lun->flags & CTL_LUN_FLAG_READONLY) || (lun->mode_pages.control_page[CTL_PAGE_CURRENT] @@ -6752,7 +6471,7 @@ ctl_mode_sense(struct ctl_scsiio *ctsio) datalen = MIN(total_len - 2, 65533); scsi_ulto2b(datalen, header->datalen); - if (control_dev == 0) { + if (lun->be_lun->lun_type == T_DIRECT) { header->dev_specific = 0x10; /* DPOFUA */ if ((lun->be_lun->flags & CTL_LUN_FLAG_READONLY) || (lun->mode_pages.control_page[CTL_PAGE_CURRENT] @@ -6777,7 +6496,7 @@ ctl_mode_sense(struct ctl_scsiio *ctsio) * descriptor. Otherwise, just set it to 0. */ if (dbd == 0) { - if (control_dev == 0) + if (lun->be_lun->lun_type == T_DIRECT) scsi_ulto3b(lun->be_lun->blocksize, block_desc->block_len); else @@ -6793,10 +6512,14 @@ ctl_mode_sense(struct ctl_scsiio *ctsio) struct ctl_page_index *page_index; page_index = &lun->mode_pages.index[i]; - - if ((control_dev != 0) - && (page_index->page_flags & - CTL_PAGE_FLAG_DISK_ONLY)) + if (lun->be_lun->lun_type == T_DIRECT && + (page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0) + continue; + if (lun->be_lun->lun_type == T_PROCESSOR && + (page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0) + continue; + if (lun->be_lun->lun_type == T_CDROM && + (page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0) continue; /* @@ -6844,9 +6567,14 @@ ctl_mode_sense(struct ctl_scsiio *ctsio) continue; /* Make sure the page is supported for this dev type */ - if ((control_dev != 0) - && (page_index->page_flags & - CTL_PAGE_FLAG_DISK_ONLY)) + if (lun->be_lun->lun_type == T_DIRECT && + (page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0) + continue; + if (lun->be_lun->lun_type == T_PROCESSOR && + (page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0) + continue; + if (lun->be_lun->lun_type == T_CDROM && + (page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0) continue; /* @@ -7819,7 +7547,7 @@ retry: goto retry; } - scsi_ulto4b(lun->PRGeneration, res_keys->header.generation); + scsi_ulto4b(lun->pr_generation, res_keys->header.generation); scsi_ulto4b(sizeof(struct scsi_per_res_key) * lun->pr_key_count, res_keys->header.length); @@ -7836,18 +7564,6 @@ retry: * sync), we've got a problem. */ if (key_count >= lun->pr_key_count) { -#ifdef NEEDTOPORT - csevent_log(CSC_CTL | CSC_SHELF_SW | - CTL_PR_ERROR, - csevent_LogType_Fault, - csevent_AlertLevel_Yellow, - csevent_FRU_ShelfController, - csevent_FRU_Firmware, - csevent_FRU_Unknown, - "registered keys %d >= key " - "count %d", key_count, - lun->pr_key_count); -#endif key_count++; continue; } @@ -7862,7 +7578,7 @@ retry: res = (struct scsi_per_res_in_rsrv *)ctsio->kern_data_ptr; - scsi_ulto4b(lun->PRGeneration, res->header.generation); + scsi_ulto4b(lun->pr_generation, res->header.generation); if (lun->flags & CTL_LUN_PR_RESERVED) { @@ -7905,7 +7621,7 @@ retry: scsi_u64to8b(ctl_get_prkey(lun, lun->pr_res_idx), res->data.reservation); } - res->data.scopetype = lun->res_type; + res->data.scopetype = lun->pr_res_type; break; } case SPRI_RC: //report capabilities @@ -7915,7 +7631,8 @@ retry: res_cap = (struct scsi_per_res_cap *)ctsio->kern_data_ptr; scsi_ulto2b(sizeof(*res_cap), res_cap->length); - res_cap->flags2 |= SPRI_TMV | SPRI_ALLOW_5; + res_cap->flags1 = SPRI_CRH; + res_cap->flags2 = SPRI_TMV | SPRI_ALLOW_5; type_mask = SPRI_TM_WR_EX_AR | SPRI_TM_EX_AC_RO | SPRI_TM_WR_EX_RO | @@ -7950,7 +7667,7 @@ retry: goto retry; } - scsi_ulto4b(lun->PRGeneration, res_status->header.generation); + scsi_ulto4b(lun->pr_generation, res_status->header.generation); res_desc = &res_status->desc[0]; for (i = 0; i < CTL_MAX_INITIATORS; i++) { @@ -7962,7 +7679,7 @@ retry: (lun->pr_res_idx == i || lun->pr_res_idx == CTL_PR_ALL_REGISTRANTS)) { res_desc->flags = SPRI_FULL_R_HOLDER; - res_desc->scopetype = lun->res_type; + res_desc->scopetype = lun->pr_res_type; } scsi_ulto2b(i / CTL_MAX_INIT_PER_PORT, res_desc->rel_trgt_port_id); @@ -8051,11 +7768,11 @@ ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun, uint64_t res_key, ctl_est_ua(lun, i, CTL_UA_REG_PREEMPT); } lun->pr_key_count = 1; - lun->res_type = type; - if (lun->res_type != SPR_TYPE_WR_EX_AR - && lun->res_type != SPR_TYPE_EX_AC_AR) + lun->pr_res_type = type; + if (lun->pr_res_type != SPR_TYPE_WR_EX_AR && + lun->pr_res_type != SPR_TYPE_EX_AC_AR) lun->pr_res_idx = residx; - lun->PRGeneration++; + lun->pr_generation++; mtx_unlock(&lun->lun_lock); /* send msg to other side */ @@ -8125,7 +7842,7 @@ ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun, uint64_t res_key, ctl_done((union ctl_io *)ctsio); return (CTL_RETVAL_COMPLETE); } - lun->PRGeneration++; + lun->pr_generation++; mtx_unlock(&lun->lun_lock); /* send msg to other side */ @@ -8191,19 +7908,19 @@ ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun, uint64_t res_key, ctl_clr_prkey(lun, i); lun->pr_key_count--; ctl_est_ua(lun, i, CTL_UA_REG_PREEMPT); - } else if (type != lun->res_type - && (lun->res_type == SPR_TYPE_WR_EX_RO - || lun->res_type ==SPR_TYPE_EX_AC_RO)){ + } else if (type != lun->pr_res_type && + (lun->pr_res_type == SPR_TYPE_WR_EX_RO || + lun->pr_res_type == SPR_TYPE_EX_AC_RO)) { ctl_est_ua(lun, i, CTL_UA_RES_RELEASE); } } - lun->res_type = type; - if (lun->res_type != SPR_TYPE_WR_EX_AR - && lun->res_type != SPR_TYPE_EX_AC_AR) + lun->pr_res_type = type; + if (lun->pr_res_type != SPR_TYPE_WR_EX_AR && + lun->pr_res_type != SPR_TYPE_EX_AC_AR) lun->pr_res_idx = residx; else lun->pr_res_idx = CTL_PR_ALL_REGISTRANTS; - lun->PRGeneration++; + lun->pr_generation++; mtx_unlock(&lun->lun_lock); persis_io.hdr.nexus = ctsio->io_hdr.nexus; @@ -8240,7 +7957,7 @@ ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun, uint64_t res_key, ctl_done((union ctl_io *)ctsio); return (1); } - lun->PRGeneration++; + lun->pr_generation++; mtx_unlock(&lun->lun_lock); persis_io.hdr.nexus = ctsio->io_hdr.nexus; @@ -8284,9 +8001,9 @@ ctl_pro_preempt_other(struct ctl_lun *lun, union ctl_ha_msg *msg) } lun->pr_key_count = 1; - lun->res_type = msg->pr.pr_info.res_type; - if (lun->res_type != SPR_TYPE_WR_EX_AR - && lun->res_type != SPR_TYPE_EX_AC_AR) + lun->pr_res_type = msg->pr.pr_info.res_type; + if (lun->pr_res_type != SPR_TYPE_WR_EX_AR && + lun->pr_res_type != SPR_TYPE_EX_AC_AR) lun->pr_res_idx = msg->pr.pr_info.residx; } else { for (i = 0; i < CTL_MAX_INITIATORS; i++) { @@ -8308,20 +8025,20 @@ ctl_pro_preempt_other(struct ctl_lun *lun, union ctl_ha_msg *msg) ctl_clr_prkey(lun, i); lun->pr_key_count--; ctl_est_ua(lun, i, CTL_UA_REG_PREEMPT); - } else if (msg->pr.pr_info.res_type != lun->res_type - && (lun->res_type == SPR_TYPE_WR_EX_RO - || lun->res_type == SPR_TYPE_EX_AC_RO)) { + } else if (msg->pr.pr_info.res_type != lun->pr_res_type + && (lun->pr_res_type == SPR_TYPE_WR_EX_RO || + lun->pr_res_type == SPR_TYPE_EX_AC_RO)) { ctl_est_ua(lun, i, CTL_UA_RES_RELEASE); } } - lun->res_type = msg->pr.pr_info.res_type; - if (lun->res_type != SPR_TYPE_WR_EX_AR - && lun->res_type != SPR_TYPE_EX_AC_AR) + lun->pr_res_type = msg->pr.pr_info.res_type; + if (lun->pr_res_type != SPR_TYPE_WR_EX_AR && + lun->pr_res_type != SPR_TYPE_EX_AC_AR) lun->pr_res_idx = msg->pr.pr_info.residx; else lun->pr_res_idx = CTL_PR_ALL_REGISTRANTS; } - lun->PRGeneration++; + lun->pr_generation++; } @@ -8503,9 +8220,9 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) lun->flags &= ~CTL_LUN_PR_RESERVED; lun->pr_res_idx = CTL_PR_NO_RESERVATION; - if ((lun->res_type == SPR_TYPE_WR_EX_RO - || lun->res_type == SPR_TYPE_EX_AC_RO) - && lun->pr_key_count) { + if ((lun->pr_res_type == SPR_TYPE_WR_EX_RO || + lun->pr_res_type == SPR_TYPE_EX_AC_RO) && + lun->pr_key_count) { /* * If the reservation is a registrants * only type we need to generate a UA @@ -8521,15 +8238,15 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) CTL_UA_RES_RELEASE); } } - lun->res_type = 0; + lun->pr_res_type = 0; } else if (lun->pr_res_idx == CTL_PR_ALL_REGISTRANTS) { if (lun->pr_key_count==0) { lun->flags &= ~CTL_LUN_PR_RESERVED; - lun->res_type = 0; + lun->pr_res_type = 0; lun->pr_res_idx = CTL_PR_NO_RESERVATION; } } - lun->PRGeneration++; + lun->pr_generation++; mtx_unlock(&lun->lun_lock); persis_io.hdr.nexus = ctsio->io_hdr.nexus; @@ -8548,7 +8265,7 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) if (ctl_get_prkey(lun, residx) == 0) lun->pr_key_count++; ctl_set_prkey(lun, residx, sa_res_key); - lun->PRGeneration++; + lun->pr_generation++; mtx_unlock(&lun->lun_lock); persis_io.hdr.nexus = ctsio->io_hdr.nexus; @@ -8577,7 +8294,7 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) */ if ((lun->pr_res_idx != residx && lun->pr_res_idx != CTL_PR_ALL_REGISTRANTS) - || lun->res_type != type) { + || lun->pr_res_type != type) { mtx_unlock(&lun->lun_lock); free(ctsio->kern_data_ptr, M_CTL); ctl_set_reservation_conflict(ctsio); @@ -8597,7 +8314,7 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) lun->pr_res_idx = CTL_PR_ALL_REGISTRANTS; lun->flags |= CTL_LUN_PR_RESERVED; - lun->res_type = type; + lun->pr_res_type = type; mtx_unlock(&lun->lun_lock); @@ -8632,7 +8349,7 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) goto done; } - if (lun->res_type != type) { + if (lun->pr_res_type != type) { mtx_unlock(&lun->lun_lock); free(ctsio->kern_data_ptr, M_CTL); ctl_set_illegal_pr_release(ctsio); @@ -8643,7 +8360,7 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) /* okay to release */ lun->flags &= ~CTL_LUN_PR_RESERVED; lun->pr_res_idx = CTL_PR_NO_RESERVATION; - lun->res_type = 0; + lun->pr_res_type = 0; /* * if this isn't an exclusive access @@ -8673,7 +8390,7 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) mtx_lock(&lun->lun_lock); lun->flags &= ~CTL_LUN_PR_RESERVED; - lun->res_type = 0; + lun->pr_res_type = 0; lun->pr_key_count = 0; lun->pr_res_idx = CTL_PR_NO_RESERVATION; @@ -8683,7 +8400,7 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) ctl_clr_prkey(lun, i); ctl_est_ua(lun, i, CTL_UA_REG_PREEMPT); } - lun->PRGeneration++; + lun->pr_generation++; mtx_unlock(&lun->lun_lock); persis_io.hdr.nexus = ctsio->io_hdr.nexus; @@ -8724,12 +8441,11 @@ done: static void ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg) { + struct ctl_softc *softc = control_softc; struct ctl_lun *lun; - struct ctl_softc *softc; int i; uint32_t residx, targ_lun; - softc = control_softc; targ_lun = msg->hdr.nexus.targ_mapped_lun; mtx_lock(&softc->ctl_lock); if ((targ_lun >= CTL_MAX_LUNS) || @@ -8751,7 +8467,7 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg) lun->pr_key_count++; ctl_set_prkey(lun, msg->pr.pr_info.residx, scsi_8btou64(msg->pr.pr_info.sa_res_key)); - lun->PRGeneration++; + lun->pr_generation++; break; case CTL_PR_UNREG_KEY: @@ -8764,9 +8480,9 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg) lun->flags &= ~CTL_LUN_PR_RESERVED; lun->pr_res_idx = CTL_PR_NO_RESERVATION; - if ((lun->res_type == SPR_TYPE_WR_EX_RO - || lun->res_type == SPR_TYPE_EX_AC_RO) - && lun->pr_key_count) { + if ((lun->pr_res_type == SPR_TYPE_WR_EX_RO || + lun->pr_res_type == SPR_TYPE_EX_AC_RO) && + lun->pr_key_count) { /* * If the reservation is a registrants * only type we need to generate a UA @@ -8782,20 +8498,20 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg) ctl_est_ua(lun, i, CTL_UA_RES_RELEASE); } } - lun->res_type = 0; + lun->pr_res_type = 0; } else if (lun->pr_res_idx == CTL_PR_ALL_REGISTRANTS) { if (lun->pr_key_count==0) { lun->flags &= ~CTL_LUN_PR_RESERVED; - lun->res_type = 0; + lun->pr_res_type = 0; lun->pr_res_idx = CTL_PR_NO_RESERVATION; } } - lun->PRGeneration++; + lun->pr_generation++; break; case CTL_PR_RESERVE: lun->flags |= CTL_LUN_PR_RESERVED; - lun->res_type = msg->pr.pr_info.res_type; + lun->pr_res_type = msg->pr.pr_info.res_type; lun->pr_res_idx = msg->pr.pr_info.residx; break; @@ -8805,8 +8521,8 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg) * if this isn't an exclusive access res generate UA for all * other registrants. */ - if (lun->res_type != SPR_TYPE_EX_AC - && lun->res_type != SPR_TYPE_WR_EX) { + if (lun->pr_res_type != SPR_TYPE_EX_AC && + lun->pr_res_type != SPR_TYPE_WR_EX) { for (i = softc->init_min; i < softc->init_max; i++) if (i == residx || ctl_get_prkey(lun, i) == 0) continue; @@ -8815,7 +8531,7 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg) lun->flags &= ~CTL_LUN_PR_RESERVED; lun->pr_res_idx = CTL_PR_NO_RESERVATION; - lun->res_type = 0; + lun->pr_res_type = 0; break; case CTL_PR_PREEMPT: @@ -8823,7 +8539,7 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg) break; case CTL_PR_CLEAR: lun->flags &= ~CTL_LUN_PR_RESERVED; - lun->res_type = 0; + lun->pr_res_type = 0; lun->pr_key_count = 0; lun->pr_res_idx = CTL_PR_NO_RESERVATION; @@ -8833,7 +8549,7 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg) ctl_clr_prkey(lun, i); ctl_est_ua(lun, i, CTL_UA_REG_PREEMPT); } - lun->PRGeneration++; + lun->pr_generation++; break; } @@ -8855,8 +8571,6 @@ ctl_read_write(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_read_write: command: %#x\n", ctsio->cdb[0])); flags = 0; - retval = CTL_RETVAL_COMPLETE; - isread = ctsio->cdb[0] == READ_6 || ctsio->cdb[0] == READ_10 || ctsio->cdb[0] == READ_12 || ctsio->cdb[0] == READ_16; switch (ctsio->cdb[0]) { @@ -9033,7 +8747,6 @@ ctl_read_write(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_read_write: calling data_submit()\n")); retval = lun->backend->data_submit((union ctl_io *)ctsio); - return (retval); } @@ -9073,8 +8786,6 @@ ctl_cnw(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_cnw: command: %#x\n", ctsio->cdb[0])); flags = 0; - retval = CTL_RETVAL_COMPLETE; - switch (ctsio->cdb[0]) { case COMPARE_AND_WRITE: { struct scsi_compare_and_write *cdb; @@ -9165,8 +8876,6 @@ ctl_verify(struct ctl_scsiio *ctsio) bytchk = 0; flags = CTL_LLF_FUA; - retval = CTL_RETVAL_COMPLETE; - switch (ctsio->cdb[0]) { case VERIFY_10: { struct scsi_verify_10 *cdb; @@ -9257,7 +8966,7 @@ ctl_verify(struct ctl_scsiio *ctsio) int ctl_report_luns(struct ctl_scsiio *ctsio) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc; struct scsi_report_luns *cdb; struct scsi_report_luns_data *lun_data; struct ctl_lun *lun, *request_lun; @@ -9270,6 +8979,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio) retval = CTL_RETVAL_COMPLETE; cdb = (struct scsi_report_luns *)ctsio->cdb; port = ctl_io_port(&ctsio->io_hdr); + softc = port->ctl_softc; CTL_DEBUG_PRINT(("ctl_report_luns\n")); @@ -10094,7 +9804,6 @@ ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, int alloc_len) { struct scsi_vpd_block_limits *bl_ptr; struct ctl_lun *lun; - int bs; lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; @@ -10131,7 +9840,6 @@ ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, int alloc_len) bl_ptr->max_cmp_write_len = 0xff; scsi_ulto4b(0xffffffff, bl_ptr->max_txfer_len); if (lun != NULL) { - bs = lun->be_lun->blocksize; scsi_ulto4b(lun->be_lun->opttxferlen, bl_ptr->opt_txfer_len); if (lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) { scsi_ulto4b(0xffffffff, bl_ptr->max_unmap_lba_cnt); @@ -10346,25 +10054,15 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio) { struct scsi_inquiry_data *inq_ptr; struct scsi_inquiry *cdb; - struct ctl_softc *softc; + struct ctl_softc *softc = control_softc; struct ctl_port *port; struct ctl_lun *lun; char *val; uint32_t alloc_len, data_len; ctl_port_type port_type; - softc = control_softc; - - /* - * Figure out whether we're talking to a Fibre Channel port or not. - * We treat the ioctl front end, and any SCSI adapters, as packetized - * SCSI front ends. - */ port = ctl_io_port(&ctsio->io_hdr); - if (port != NULL) - port_type = port->port_type; - else - port_type = CTL_PORT_SCSI; + port_type = port->port_type; if (port_type == CTL_PORT_IOCTL || port_type == CTL_PORT_INTERNAL) port_type = CTL_PORT_SCSI; @@ -10403,6 +10101,8 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio) inq_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | lun->be_lun->lun_type; } + if (lun->flags & CTL_LUN_REMOVABLE) + inq_ptr->dev_qual2 |= SID_RMB; } else inq_ptr->device = (SID_QUAL_BAD_LU << 5) | T_NODEVICE; @@ -10434,23 +10134,13 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio) inq_ptr->additional_length)); inq_ptr->spc3_flags = SPC3_SID_3PC | SPC3_SID_TPGS_IMPLICIT; - /* 16 bit addressing */ if (port_type == CTL_PORT_SCSI) inq_ptr->spc2_flags = SPC2_SID_ADDR16; - /* XXX set the SID_MultiP bit here if we're actually going to - respond on multiple ports */ inq_ptr->spc2_flags |= SPC2_SID_MultiP; - - /* 16 bit data bus, synchronous transfers */ + inq_ptr->flags = SID_CmdQue; if (port_type == CTL_PORT_SCSI) - inq_ptr->flags = SID_WBus16 | SID_Sync; - /* - * XXX KDM do we want to support tagged queueing on the control - * device at all? - */ - if ((lun == NULL) - || (lun->be_lun->lun_type != T_PROCESSOR)) - inq_ptr->flags |= SID_CmdQue; + inq_ptr->flags |= SID_WBus16 | SID_Sync; + /* * Per SPC-3, unused bytes in ASCII strings are filled with spaces. * We have 8 bytes for the vendor name, and 16 bytes for the device @@ -10477,6 +10167,10 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio) strncpy(inq_ptr->product, CTL_PROCESSOR_PRODUCT, sizeof(inq_ptr->product)); break; + case T_CDROM: + strncpy(inq_ptr->product, CTL_CDROM_PRODUCT, + sizeof(inq_ptr->product)); + break; default: strncpy(inq_ptr->product, CTL_UNKNOWN_PRODUCT, sizeof(inq_ptr->product)); @@ -10539,6 +10233,11 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio) scsi_ulto2b(0x0600, inq_ptr->version4); break; case T_PROCESSOR: + break; + case T_CDROM: + /* MMC-6 (no version claimed) */ + scsi_ulto2b(0x04E0, inq_ptr->version4); + break; default: break; } @@ -10578,6 +10277,398 @@ ctl_inquiry(struct ctl_scsiio *ctsio) return (retval); } +int +ctl_get_config(struct ctl_scsiio *ctsio) +{ + struct scsi_get_config_header *hdr; + struct scsi_get_config_feature *feature; + struct scsi_get_config *cdb; + struct ctl_lun *lun; + uint32_t alloc_len, data_len; + int rt, starting; + + lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + cdb = (struct scsi_get_config *)ctsio->cdb; + rt = (cdb->rt & SGC_RT_MASK); + starting = scsi_2btoul(cdb->starting_feature); + alloc_len = scsi_2btoul(cdb->length); + + data_len = sizeof(struct scsi_get_config_header) + + sizeof(struct scsi_get_config_feature) + 8 + + sizeof(struct scsi_get_config_feature) + 8 + + sizeof(struct scsi_get_config_feature) + 4 + + sizeof(struct scsi_get_config_feature) + 4 + + sizeof(struct scsi_get_config_feature) + 8 + + sizeof(struct scsi_get_config_feature) + + sizeof(struct scsi_get_config_feature) + 4 + + sizeof(struct scsi_get_config_feature) + 4 + + sizeof(struct scsi_get_config_feature) + 4 + + sizeof(struct scsi_get_config_feature) + 4 + + sizeof(struct scsi_get_config_feature) + 4 + + sizeof(struct scsi_get_config_feature) + 4; + ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); + ctsio->kern_sg_entries = 0; + ctsio->kern_data_resid = 0; + ctsio->kern_rel_offset = 0; + + hdr = (struct scsi_get_config_header *)ctsio->kern_data_ptr; + if (lun->flags & CTL_LUN_NO_MEDIA) + scsi_ulto2b(0x0000, hdr->current_profile); + else + scsi_ulto2b(0x0010, hdr->current_profile); + feature = (struct scsi_get_config_feature *)(hdr + 1); + + if (starting > 0x003b) + goto done; + if (starting > 0x003a) + goto f3b; + if (starting > 0x002b) + goto f3a; + if (starting > 0x002a) + goto f2b; + if (starting > 0x001f) + goto f2a; + if (starting > 0x001e) + goto f1f; + if (starting > 0x001d) + goto f1e; + if (starting > 0x0010) + goto f1d; + if (starting > 0x0003) + goto f10; + if (starting > 0x0002) + goto f3; + if (starting > 0x0001) + goto f2; + if (starting > 0x0000) + goto f1; + + /* Profile List */ + scsi_ulto2b(0x0000, feature->feature_code); + feature->flags = SGC_F_PERSISTENT | SGC_F_CURRENT; + feature->add_length = 8; + scsi_ulto2b(0x0008, &feature->feature_data[0]); /* CD-ROM */ + feature->feature_data[2] = 0x00; + scsi_ulto2b(0x0010, &feature->feature_data[4]); /* DVD-ROM */ + feature->feature_data[6] = 0x01; + feature = (struct scsi_get_config_feature *) + &feature->feature_data[feature->add_length]; + +f1: /* Core */ + scsi_ulto2b(0x0001, feature->feature_code); + feature->flags = 0x08 | SGC_F_PERSISTENT | SGC_F_CURRENT; + feature->add_length = 8; + scsi_ulto4b(0x00000000, &feature->feature_data[0]); + feature->feature_data[4] = 0x03; + feature = (struct scsi_get_config_feature *) + &feature->feature_data[feature->add_length]; + +f2: /* Morphing */ + scsi_ulto2b(0x0002, feature->feature_code); + feature->flags = 0x04 | SGC_F_PERSISTENT | SGC_F_CURRENT; + feature->add_length = 4; + feature->feature_data[0] = 0x02; + feature = (struct scsi_get_config_feature *) + &feature->feature_data[feature->add_length]; + +f3: /* Removable Medium */ + scsi_ulto2b(0x0003, feature->feature_code); + feature->flags = 0x04 | SGC_F_PERSISTENT | SGC_F_CURRENT; + feature->add_length = 4; + feature->feature_data[0] = 0x39; + feature = (struct scsi_get_config_feature *) + &feature->feature_data[feature->add_length]; + + if (rt == SGC_RT_CURRENT && (lun->flags & CTL_LUN_NO_MEDIA)) + goto done; + +f10: /* Random Read */ + scsi_ulto2b(0x0010, feature->feature_code); + feature->flags = 0x00; + if ((lun->flags & CTL_LUN_NO_MEDIA) == 0) + feature->flags |= SGC_F_CURRENT; + feature->add_length = 8; + scsi_ulto4b(lun->be_lun->blocksize, &feature->feature_data[0]); + scsi_ulto2b(1, &feature->feature_data[4]); + feature->feature_data[6] = 0x00; + feature = (struct scsi_get_config_feature *) + &feature->feature_data[feature->add_length]; + +f1d: /* Multi-Read */ + scsi_ulto2b(0x001D, feature->feature_code); + feature->flags = 0x00; + if ((lun->flags & CTL_LUN_NO_MEDIA) == 0) + feature->flags |= SGC_F_CURRENT; + feature->add_length = 0; + feature = (struct scsi_get_config_feature *) + &feature->feature_data[feature->add_length]; + +f1e: /* CD Read */ + scsi_ulto2b(0x001E, feature->feature_code); + feature->flags = 0x00; + if ((lun->flags & CTL_LUN_NO_MEDIA) == 0) + feature->flags |= SGC_F_CURRENT; + feature->add_length = 4; + feature->feature_data[0] = 0x00; + feature = (struct scsi_get_config_feature *) + &feature->feature_data[feature->add_length]; + +f1f: /* DVD Read */ + scsi_ulto2b(0x001F, feature->feature_code); + feature->flags = 0x08; + if ((lun->flags & CTL_LUN_NO_MEDIA) == 0) + feature->flags |= SGC_F_CURRENT; + feature->add_length = 4; + feature->feature_data[0] = 0x01; + feature->feature_data[2] = 0x03; + feature = (struct scsi_get_config_feature *) + &feature->feature_data[feature->add_length]; + +f2a: /* DVD+RW */ + scsi_ulto2b(0x002A, feature->feature_code); + feature->flags = 0x04; + if ((lun->flags & CTL_LUN_NO_MEDIA) == 0) + feature->flags |= SGC_F_CURRENT; + feature->add_length = 4; + feature->feature_data[0] = 0x00; + feature->feature_data[1] = 0x00; + feature = (struct scsi_get_config_feature *) + &feature->feature_data[feature->add_length]; + +f2b: /* DVD+R */ + scsi_ulto2b(0x002B, feature->feature_code); + feature->flags = 0x00; + if ((lun->flags & CTL_LUN_NO_MEDIA) == 0) + feature->flags |= SGC_F_CURRENT; + feature->add_length = 4; + feature->feature_data[0] = 0x00; + feature = (struct scsi_get_config_feature *) + &feature->feature_data[feature->add_length]; + +f3a: /* DVD+RW Dual Layer */ + scsi_ulto2b(0x003A, feature->feature_code); + feature->flags = 0x00; + if ((lun->flags & CTL_LUN_NO_MEDIA) == 0) + feature->flags |= SGC_F_CURRENT; + feature->add_length = 4; + feature->feature_data[0] = 0x00; + feature->feature_data[1] = 0x00; + feature = (struct scsi_get_config_feature *) + &feature->feature_data[feature->add_length]; + +f3b: /* DVD+R Dual Layer */ + scsi_ulto2b(0x003B, feature->feature_code); + feature->flags = 0x00; + if ((lun->flags & CTL_LUN_NO_MEDIA) == 0) + feature->flags |= SGC_F_CURRENT; + feature->add_length = 4; + feature->feature_data[0] = 0x00; + feature = (struct scsi_get_config_feature *) + &feature->feature_data[feature->add_length]; + +done: + data_len = (uint8_t *)feature - (uint8_t *)hdr; + if (rt == SGC_RT_SPECIFIC && data_len > 4) { + feature = (struct scsi_get_config_feature *)(hdr + 1); + if (scsi_2btoul(feature->feature_code) == starting) + feature = (struct scsi_get_config_feature *) + &feature->feature_data[feature->add_length]; + data_len = (uint8_t *)feature - (uint8_t *)hdr; + } + scsi_ulto4b(data_len - 4, hdr->data_length); + if (data_len < alloc_len) { + ctsio->residual = alloc_len - data_len; + ctsio->kern_data_len = data_len; + ctsio->kern_total_len = data_len; + } else { + ctsio->residual = 0; + ctsio->kern_data_len = alloc_len; + ctsio->kern_total_len = alloc_len; + } + + ctl_set_success(ctsio); + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; + ctsio->be_move_done = ctl_config_move_done; + ctl_datamove((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); +} + +int +ctl_get_event_status(struct ctl_scsiio *ctsio) +{ + struct scsi_get_event_status_header *hdr; + struct scsi_get_event_status *cdb; + struct ctl_lun *lun; + uint32_t alloc_len, data_len; + int notif_class; + + lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + cdb = (struct scsi_get_event_status *)ctsio->cdb; + if ((cdb->byte2 & SGESN_POLLED) == 0) { + ctl_set_invalid_field(ctsio, /*sks_valid*/ 1, /*command*/ 1, + /*field*/ 1, /*bit_valid*/ 1, /*bit*/ 0); + ctl_done((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); + } + notif_class = cdb->notif_class; + alloc_len = scsi_2btoul(cdb->length); + + data_len = sizeof(struct scsi_get_event_status_header); + ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); + ctsio->kern_sg_entries = 0; + ctsio->kern_data_resid = 0; + ctsio->kern_rel_offset = 0; + + if (data_len < alloc_len) { + ctsio->residual = alloc_len - data_len; + ctsio->kern_data_len = data_len; + ctsio->kern_total_len = data_len; + } else { + ctsio->residual = 0; + ctsio->kern_data_len = alloc_len; + ctsio->kern_total_len = alloc_len; + } + + hdr = (struct scsi_get_event_status_header *)ctsio->kern_data_ptr; + scsi_ulto2b(0, hdr->descr_length); + hdr->nea_class = SGESN_NEA; + hdr->supported_class = 0; + + ctl_set_success(ctsio); + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; + ctsio->be_move_done = ctl_config_move_done; + ctl_datamove((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); +} + +int +ctl_mechanism_status(struct ctl_scsiio *ctsio) +{ + struct scsi_mechanism_status_header *hdr; + struct scsi_mechanism_status *cdb; + struct ctl_lun *lun; + uint32_t alloc_len, data_len; + + lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + cdb = (struct scsi_mechanism_status *)ctsio->cdb; + alloc_len = scsi_2btoul(cdb->length); + + data_len = sizeof(struct scsi_mechanism_status_header); + ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); + ctsio->kern_sg_entries = 0; + ctsio->kern_data_resid = 0; + ctsio->kern_rel_offset = 0; + + if (data_len < alloc_len) { + ctsio->residual = alloc_len - data_len; + ctsio->kern_data_len = data_len; + ctsio->kern_total_len = data_len; + } else { + ctsio->residual = 0; + ctsio->kern_data_len = alloc_len; + ctsio->kern_total_len = alloc_len; + } + + hdr = (struct scsi_mechanism_status_header *)ctsio->kern_data_ptr; + hdr->state1 = 0x00; + hdr->state2 = 0xe0; + scsi_ulto3b(0, hdr->lba); + hdr->slots_num = 0; + scsi_ulto2b(0, hdr->slots_length); + + ctl_set_success(ctsio); + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; + ctsio->be_move_done = ctl_config_move_done; + ctl_datamove((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); +} + +static void +ctl_ultomsf(uint32_t lba, uint8_t *buf) +{ + + lba += 150; + buf[0] = 0; + buf[1] = bin2bcd((lba / 75) / 60); + buf[2] = bin2bcd((lba / 75) % 60); + buf[3] = bin2bcd(lba % 75); +} + +int +ctl_read_toc(struct ctl_scsiio *ctsio) +{ + struct scsi_read_toc_hdr *hdr; + struct scsi_read_toc_type01_descr *descr; + struct scsi_read_toc *cdb; + struct ctl_lun *lun; + uint32_t alloc_len, data_len; + int format, msf; + + lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + cdb = (struct scsi_read_toc *)ctsio->cdb; + msf = (cdb->byte2 & CD_MSF) != 0; + format = cdb->format; + alloc_len = scsi_2btoul(cdb->data_len); + + data_len = sizeof(struct scsi_read_toc_hdr); + if (format == 0) + data_len += 2 * sizeof(struct scsi_read_toc_type01_descr); + else + data_len += sizeof(struct scsi_read_toc_type01_descr); + ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); + ctsio->kern_sg_entries = 0; + ctsio->kern_data_resid = 0; + ctsio->kern_rel_offset = 0; + + if (data_len < alloc_len) { + ctsio->residual = alloc_len - data_len; + ctsio->kern_data_len = data_len; + ctsio->kern_total_len = data_len; + } else { + ctsio->residual = 0; + ctsio->kern_data_len = alloc_len; + ctsio->kern_total_len = alloc_len; + } + + hdr = (struct scsi_read_toc_hdr *)ctsio->kern_data_ptr; + if (format == 0) { + scsi_ulto2b(0x12, hdr->data_length); + hdr->first = 1; + hdr->last = 1; + descr = (struct scsi_read_toc_type01_descr *)(hdr + 1); + descr->addr_ctl = 0x14; + descr->track_number = 1; + if (msf) + ctl_ultomsf(0, descr->track_start); + else + scsi_ulto4b(0, descr->track_start); + descr++; + descr->addr_ctl = 0x14; + descr->track_number = 0xaa; + if (msf) + ctl_ultomsf(lun->be_lun->maxlba+1, descr->track_start); + else + scsi_ulto4b(lun->be_lun->maxlba+1, descr->track_start); + } else { + scsi_ulto2b(0x0a, hdr->data_length); + hdr->first = 1; + hdr->last = 1; + descr = (struct scsi_read_toc_type01_descr *)(hdr + 1); + descr->addr_ctl = 0x14; + descr->track_number = 1; + if (msf) + ctl_ultomsf(0, descr->track_start); + else + scsi_ulto4b(0, descr->track_start); + } + + ctl_set_success(ctsio); + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; + ctsio->be_move_done = ctl_config_move_done; + ctl_datamove((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); +} + /* * For known CDB types, parse the LBA and length. */ @@ -10833,7 +10924,7 @@ ctl_check_for_blockage(struct ctl_lun *lun, union ctl_io *pending_io, union ctl_io *ooa_io) { const struct ctl_cmd_entry *pending_entry, *ooa_entry; - ctl_serialize_action *serialize_row; + const ctl_serialize_action *serialize_row; /* * The initiator attempted multiple untagged commands at the same @@ -11203,9 +11294,9 @@ ctl_scsiio_lun_check(struct ctl_lun *lun, (entry->flags & CTL_CMD_FLAG_ALLOW_ON_PR_RESV)) { /* No reservation or command is allowed. */; } else if ((entry->flags & CTL_CMD_FLAG_ALLOW_ON_PR_WRESV) && - (lun->res_type == SPR_TYPE_WR_EX || - lun->res_type == SPR_TYPE_WR_EX_RO || - lun->res_type == SPR_TYPE_WR_EX_AR)) { + (lun->pr_res_type == SPR_TYPE_WR_EX || + lun->pr_res_type == SPR_TYPE_WR_EX_RO || + lun->pr_res_type == SPR_TYPE_WR_EX_AR)) { /* The command is allowed for Write Exclusive resv. */; } else { /* @@ -11213,33 +11304,26 @@ ctl_scsiio_lun_check(struct ctl_lun *lun, * reservation and this isn't the res holder then set a * conflict. */ - if (ctl_get_prkey(lun, residx) == 0 - || (residx != lun->pr_res_idx && lun->res_type < 4)) { + if (ctl_get_prkey(lun, residx) == 0 || + (residx != lun->pr_res_idx && lun->pr_res_type < 4)) { ctl_set_reservation_conflict(ctsio); retval = 1; goto bailout; } } - if ((lun->flags & CTL_LUN_OFFLINE) - && ((entry->flags & CTL_CMD_FLAG_OK_ON_STANDBY) == 0)) { - ctl_set_lun_not_ready(ctsio); - retval = 1; - goto bailout; - } - - if ((lun->flags & CTL_LUN_STOPPED) - && ((entry->flags & CTL_CMD_FLAG_OK_ON_STOPPED) == 0)) { - /* "Logical unit not ready, initializing cmd. required" */ - ctl_set_lun_stopped(ctsio); - retval = 1; - goto bailout; - } - - if ((lun->flags & CTL_LUN_INOPERABLE) - && ((entry->flags & CTL_CMD_FLAG_OK_ON_INOPERABLE) == 0)) { - /* "Medium format corrupted" */ - ctl_set_medium_format_corrupted(ctsio); + if ((entry->flags & CTL_CMD_FLAG_OK_ON_NO_MEDIA) == 0) { + if (lun->flags & CTL_LUN_EJECTED) + ctl_set_lun_ejected(ctsio); + else if (lun->flags & CTL_LUN_NO_MEDIA) { + if (lun->flags & CTL_LUN_REMOVABLE) + ctl_set_lun_no_media(ctsio); + else + ctl_set_lun_int_reqd(ctsio); + } else if (lun->flags & CTL_LUN_STOPPED) + ctl_set_lun_stopped(ctsio); + else + goto bailout; retval = 1; goto bailout; } @@ -11256,12 +11340,31 @@ ctl_failover_io(union ctl_io *io, int have_lock) } static void -ctl_failover_lun(struct ctl_lun *lun) +ctl_failover_lun(union ctl_io *rio) { - struct ctl_softc *softc = lun->ctl_softc; + struct ctl_softc *softc = control_softc; + struct ctl_lun *lun; struct ctl_io_hdr *io, *next_io; + uint32_t targ_lun; + + targ_lun = rio->io_hdr.nexus.targ_mapped_lun; + CTL_DEBUG_PRINT(("FAILOVER for lun %ju\n", targ_lun)); + + /* Find and lock the LUN. */ + mtx_lock(&softc->ctl_lock); + if ((targ_lun < CTL_MAX_LUNS) && + ((lun = softc->ctl_luns[targ_lun]) != NULL)) { + mtx_lock(&lun->lun_lock); + mtx_unlock(&softc->ctl_lock); + if (lun->flags & CTL_LUN_DISABLED) { + mtx_unlock(&lun->lun_lock); + return; + } + } else { + mtx_unlock(&softc->ctl_lock); + return; + } - CTL_DEBUG_PRINT(("FAILOVER for lun %ju\n", lun->lun)); if (softc->ha_mode == CTL_HA_MODE_XFER) { TAILQ_FOREACH_SAFE(io, &lun->ooa_queue, ooa_links, next_io) { /* We are master */ @@ -11319,6 +11422,7 @@ ctl_failover_lun(struct ctl_lun *lun) } ctl_check_blocked(lun); } + mtx_unlock(&lun->lun_lock); } static int @@ -11607,12 +11711,16 @@ ctl_cmd_applicable(uint8_t lun_type, const struct ctl_cmd_entry *entry) { switch (lun_type) { + case T_DIRECT: + if ((entry->flags & CTL_CMD_FLAG_OK_ON_DIRECT) == 0) + return (0); + break; case T_PROCESSOR: if ((entry->flags & CTL_CMD_FLAG_OK_ON_PROC) == 0) return (0); break; - case T_DIRECT: - if ((entry->flags & CTL_CMD_FLAG_OK_ON_SLUN) == 0) + case T_CDROM: + if ((entry->flags & CTL_CMD_FLAG_OK_ON_CDROM) == 0) return (0); break; default: @@ -11687,7 +11795,7 @@ ctl_target_reset(struct ctl_softc *softc, union ctl_io *io, retval = 0; mtx_lock(&softc->ctl_lock); - port = softc->ctl_ports[io->io_hdr.nexus.targ_port]; + port = ctl_io_port(&io->io_hdr); STAILQ_FOREACH(lun, &softc->lun_list, links) { if (port != NULL && ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) @@ -11727,9 +11835,7 @@ ctl_do_lun_reset(struct ctl_lun *lun, union ctl_io *io, ctl_ua_type ua_type) #if 0 uint32_t initidx; #endif -#ifdef CTL_WITH_CA int i; -#endif mtx_lock(&lun->lun_lock); /* @@ -11764,6 +11870,9 @@ ctl_do_lun_reset(struct ctl_lun *lun, union ctl_io *io, ctl_ua_type ua_type) for (i = 0; i < CTL_MAX_INITIATORS; i++) ctl_clear_mask(lun->have_ca, i); #endif + lun->prevent_count = 0; + for (i = 0; i < CTL_MAX_INITIATORS; i++) + ctl_clear_mask(lun->prevent, i); mtx_unlock(&lun->lun_lock); return (0); @@ -11909,6 +12018,10 @@ ctl_i_t_nexus_reset(union ctl_io *io) #endif if ((lun->flags & CTL_LUN_RESERVED) && (lun->res_idx == initidx)) lun->flags &= ~CTL_LUN_RESERVED; + if (ctl_is_set(lun->prevent, initidx)) { + ctl_clear_mask(lun->prevent, initidx); + lun->prevent_count--; + } ctl_est_ua(lun, initidx, CTL_UA_I_T_NEXUS_LOSS); mtx_unlock(&lun->lun_lock); } @@ -12188,11 +12301,9 @@ ctl_handle_isc(union ctl_io *io) { int free_io; struct ctl_lun *lun; - struct ctl_softc *softc; + struct ctl_softc *softc = control_softc; uint32_t targ_lun; - softc = control_softc; - targ_lun = io->io_hdr.nexus.targ_mapped_lun; lun = softc->ctl_luns[targ_lun]; @@ -12253,9 +12364,7 @@ ctl_handle_isc(union ctl_io *io) io->scsiio.be_move_done(io); break; case CTL_MSG_FAILOVER: - mtx_lock(&lun->lun_lock); - ctl_failover_lun(lun); - mtx_unlock(&lun->lun_lock); + ctl_failover_lun(io); free_io = 1; break; default: @@ -12506,178 +12615,19 @@ ctl_datamove(union ctl_io *io) return; } - /* - * If we're in XFER mode and this I/O is from the other shelf - * controller, we need to send the DMA to the other side to - * actually transfer the data to/from the host. In serialize only - * mode the transfer happens below CTL and ctl_datamove() is only - * called on the machine that originally received the I/O. - */ - if ((control_softc->ha_mode == CTL_HA_MODE_XFER) - && (io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC)) { - union ctl_ha_msg msg; - uint32_t sg_entries_sent; - int do_sg_copy; - int i; - - memset(&msg, 0, sizeof(msg)); - msg.hdr.msg_type = CTL_MSG_DATAMOVE; - msg.hdr.original_sc = io->io_hdr.original_sc; - msg.hdr.serializing_sc = io; - msg.hdr.nexus = io->io_hdr.nexus; - msg.hdr.status = io->io_hdr.status; - msg.dt.flags = io->io_hdr.flags; - /* - * We convert everything into a S/G list here. We can't - * pass by reference, only by value between controllers. - * So we can't pass a pointer to the S/G list, only as many - * S/G entries as we can fit in here. If it's possible for - * us to get more than CTL_HA_MAX_SG_ENTRIES S/G entries, - * then we need to break this up into multiple transfers. - */ - if (io->scsiio.kern_sg_entries == 0) { - msg.dt.kern_sg_entries = 1; -#if 0 - /* - * Convert to a physical address if this is a - * virtual address. - */ - if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR) { - msg.dt.sg_list[0].addr = - io->scsiio.kern_data_ptr; - } else { - /* - * XXX KDM use busdma here! - */ - msg.dt.sg_list[0].addr = (void *) - vtophys(io->scsiio.kern_data_ptr); - } -#else - KASSERT((io->io_hdr.flags & CTL_FLAG_BUS_ADDR) == 0, - ("HA does not support BUS_ADDR")); - msg.dt.sg_list[0].addr = io->scsiio.kern_data_ptr; -#endif - - msg.dt.sg_list[0].len = io->scsiio.kern_data_len; - do_sg_copy = 0; - } else { - msg.dt.kern_sg_entries = io->scsiio.kern_sg_entries; - do_sg_copy = 1; - } - - msg.dt.kern_data_len = io->scsiio.kern_data_len; - msg.dt.kern_total_len = io->scsiio.kern_total_len; - msg.dt.kern_data_resid = io->scsiio.kern_data_resid; - msg.dt.kern_rel_offset = io->scsiio.kern_rel_offset; - msg.dt.sg_sequence = 0; - - /* - * Loop until we've sent all of the S/G entries. On the - * other end, we'll recompose these S/G entries into one - * contiguous list before passing it to the - */ - for (sg_entries_sent = 0; sg_entries_sent < - msg.dt.kern_sg_entries; msg.dt.sg_sequence++) { - msg.dt.cur_sg_entries = MIN((sizeof(msg.dt.sg_list)/ - sizeof(msg.dt.sg_list[0])), - msg.dt.kern_sg_entries - sg_entries_sent); - - if (do_sg_copy != 0) { - struct ctl_sg_entry *sgl; - int j; - - sgl = (struct ctl_sg_entry *) - io->scsiio.kern_data_ptr; - /* - * If this is in cached memory, flush the cache - * before we send the DMA request to the other - * controller. We want to do this in either - * the * read or the write case. The read - * case is straightforward. In the write - * case, we want to make sure nothing is - * in the local cache that could overwrite - * the DMAed data. - */ - - for (i = sg_entries_sent, j = 0; - i < msg.dt.cur_sg_entries; i++, j++) { -#if 0 - if ((io->io_hdr.flags & - CTL_FLAG_BUS_ADDR) == 0) { - /* - * XXX KDM use busdma. - */ - msg.dt.sg_list[j].addr =(void *) - vtophys(sgl[i].addr); - } else { - msg.dt.sg_list[j].addr = - sgl[i].addr; - } -#else - KASSERT((io->io_hdr.flags & - CTL_FLAG_BUS_ADDR) == 0, - ("HA does not support BUS_ADDR")); - msg.dt.sg_list[j].addr = sgl[i].addr; -#endif - msg.dt.sg_list[j].len = sgl[i].len; - } - } - - sg_entries_sent += msg.dt.cur_sg_entries; - if (sg_entries_sent >= msg.dt.kern_sg_entries) - msg.dt.sg_last = 1; - else - msg.dt.sg_last = 0; - - if (ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg, - sizeof(msg.dt) - sizeof(msg.dt.sg_list) + - sizeof(struct ctl_sg_entry)*msg.dt.cur_sg_entries, - M_WAITOK) > CTL_HA_STATUS_SUCCESS) { - io->io_hdr.port_status = 31341; - io->scsiio.be_move_done(io); - return; - } - - msg.dt.sent_sg_entries = sg_entries_sent; - } - - /* - * Officially handover the request from us to peer. - * If failover has just happened, then we must return error. - * If failover happen just after, then it is not our problem. - */ - if (lun) - mtx_lock(&lun->lun_lock); - if (io->io_hdr.flags & CTL_FLAG_FAILOVER) { - if (lun) - mtx_unlock(&lun->lun_lock); - io->io_hdr.port_status = 31342; - io->scsiio.be_move_done(io); - return; - } - io->io_hdr.flags &= ~CTL_FLAG_IO_ACTIVE; - io->io_hdr.flags |= CTL_FLAG_DMA_INPROG; - if (lun) - mtx_unlock(&lun->lun_lock); - } else { - - /* - * Lookup the fe_datamove() function for this particular - * front end. - */ - fe_datamove = ctl_io_port(&io->io_hdr)->fe_datamove; - - fe_datamove(io); - } + fe_datamove = ctl_io_port(&io->io_hdr)->fe_datamove; + fe_datamove(io); } static void ctl_send_datamove_done(union ctl_io *io, int have_lock) { union ctl_ha_msg msg; +#ifdef CTL_TIME_IO + struct bintime cur_bt; +#endif memset(&msg, 0, sizeof(msg)); - msg.hdr.msg_type = CTL_MSG_DATAMOVE_DONE; msg.hdr.original_sc = io; msg.hdr.serializing_sc = io->io_hdr.serializing_sc; @@ -12693,15 +12643,20 @@ ctl_send_datamove_done(union ctl_io *io, int have_lock) msg.scsi.fetd_status = io->io_hdr.port_status; msg.scsi.residual = io->scsiio.residual; io->io_hdr.flags &= ~CTL_FLAG_IO_ACTIVE; - if (io->io_hdr.flags & CTL_FLAG_FAILOVER) { ctl_failover_io(io, /*have_lock*/ have_lock); return; } - ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg, sizeof(msg.scsi) - sizeof(msg.scsi.sense_data) + msg.scsi.sense_len, M_WAITOK); + +#ifdef CTL_TIME_IO + getbinuptime(&cur_bt); + bintime_sub(&cur_bt, &io->io_hdr.dma_start_bt); + bintime_add(&io->io_hdr.dma_bt, &cur_bt); +#endif + io->io_hdr.num_dmas++; } /* @@ -12861,13 +12816,11 @@ static int ctl_datamove_remote_sgl_setup(union ctl_io *io) { struct ctl_sg_entry *local_sglist; - struct ctl_softc *softc; uint32_t len_to_go; int retval; int i; retval = 0; - softc = control_softc; local_sglist = io->io_hdr.local_sglist; len_to_go = io->scsiio.kern_data_len; @@ -13104,7 +13057,7 @@ ctl_datamove_remote(union ctl_io *io) } } -static int +static void ctl_process_done(union ctl_io *io) { struct ctl_lun *lun; @@ -13114,11 +13067,7 @@ ctl_process_done(union ctl_io *io) uint32_t targ_port = io->io_hdr.nexus.targ_port; CTL_DEBUG_PRINT(("ctl_process_done\n")); - - if ((io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC) == 0) - fe_done = softc->ctl_ports[targ_port]->fe_done; - else - fe_done = NULL; + fe_done = softc->ctl_ports[targ_port]->fe_done; #ifdef CTL_TIME_IO if ((time_uptime - io->io_hdr.start_time) > ctl_time_io_secs) { @@ -13162,11 +13111,8 @@ ctl_process_done(union ctl_io *io) case CTL_IO_TASK: if (ctl_debug & CTL_DEBUG_INFO) ctl_io_error_print(io, NULL); - if (io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC) - ctl_free_io(io); - else - fe_done(io); - return (CTL_RETVAL_COMPLETE); + fe_done(io); + return; default: panic("ctl_process_done: invalid io type %d\n", io->io_hdr.io_type); @@ -13186,7 +13132,7 @@ ctl_process_done(union ctl_io *io) * Check to see if we have any errors to inject here. We only * inject errors for commands that don't already have errors set. */ - if ((STAILQ_FIRST(&lun->error_list) != NULL) && + if (!STAILQ_EMPTY(&lun->error_list) && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS) && ((io->io_hdr.flags & CTL_FLAG_STATUS_SENT) == 0)) ctl_inject_error(lun, io); @@ -13219,12 +13165,12 @@ ctl_process_done(union ctl_io *io) #ifdef CTL_TIME_IO bintime_add(&lun->stats.ports[targ_port].dma_time[type], &io->io_hdr.dma_bt); - lun->stats.ports[targ_port].num_dmas[type] += - io->io_hdr.num_dmas; - getbintime(&cur_bt); + getbinuptime(&cur_bt); bintime_sub(&cur_bt, &io->io_hdr.start_bt); bintime_add(&lun->stats.ports[targ_port].time[type], &cur_bt); #endif + lun->stats.ports[targ_port].num_dmas[type] += + io->io_hdr.num_dmas; } /* @@ -13287,30 +13233,8 @@ bailout: sizeof(msg.scsi) - sizeof(msg.scsi.sense_data), M_WAITOK); } - if ((softc->ha_mode == CTL_HA_MODE_XFER) - && (io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC)) { - memset(&msg, 0, sizeof(msg)); - msg.hdr.msg_type = CTL_MSG_FINISH_IO; - msg.hdr.original_sc = io->io_hdr.original_sc; - msg.hdr.nexus = io->io_hdr.nexus; - msg.hdr.status = io->io_hdr.status; - msg.scsi.scsi_status = io->scsiio.scsi_status; - msg.scsi.tag_num = io->scsiio.tag_num; - msg.scsi.tag_type = io->scsiio.tag_type; - msg.scsi.sense_len = io->scsiio.sense_len; - msg.scsi.sense_residual = io->scsiio.sense_residual; - msg.scsi.residual = io->scsiio.residual; - memcpy(&msg.scsi.sense_data, &io->scsiio.sense_data, - io->scsiio.sense_len); - ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg, - sizeof(msg.scsi) - sizeof(msg.scsi.sense_data) + - msg.scsi.sense_len, M_WAITOK); - ctl_free_io(io); - } else - fe_done(io); - - return (CTL_RETVAL_COMPLETE); + fe_done(io); } #ifdef CTL_WITH_CA @@ -13390,7 +13314,7 @@ ctl_queue(union ctl_io *io) #ifdef CTL_TIME_IO io->io_hdr.start_time = time_uptime; - getbintime(&io->io_hdr.start_bt); + getbinuptime(&io->io_hdr.start_bt); #endif /* CTL_TIME_IO */ /* Map FE-specific LUN ID into global one. */ @@ -13516,8 +13440,6 @@ ctl_work_thread(void *arg) CTL_DEBUG_PRINT(("ctl_work_thread starting\n")); for (;;) { - retval = 0; - /* * We handle the queues in this order: * - ISC @@ -13541,7 +13463,7 @@ ctl_work_thread(void *arg) STAILQ_REMOVE_HEAD(&thr->done_queue, links); /* clear any blocked commands, call fe_done */ mtx_unlock(&thr->queue_lock); - retval = ctl_process_done(io); + ctl_process_done(io); continue; } io = (union ctl_io *)STAILQ_FIRST(&thr->incoming_queue); @@ -13574,12 +13496,10 @@ ctl_lun_thread(void *arg) { struct ctl_softc *softc = (struct ctl_softc *)arg; struct ctl_be_lun *be_lun; - int retval; CTL_DEBUG_PRINT(("ctl_lun_thread starting\n")); for (;;) { - retval = 0; mtx_lock(&softc->ctl_lock); be_lun = STAILQ_FIRST(&softc->pending_lun_queue); if (be_lun != NULL) { @@ -13600,7 +13520,6 @@ ctl_thresh_thread(void *arg) { struct ctl_softc *softc = (struct ctl_softc *)arg; struct ctl_lun *lun; - struct ctl_be_lun *be_lun; struct scsi_da_rw_recovery_page *rwpage; struct ctl_logical_block_provisioning_page *page; const char *attr; @@ -13613,9 +13532,8 @@ ctl_thresh_thread(void *arg) for (;;) { mtx_lock(&softc->ctl_lock); STAILQ_FOREACH(lun, &softc->lun_list, links) { - be_lun = lun->be_lun; if ((lun->flags & CTL_LUN_DISABLED) || - (lun->flags & CTL_LUN_OFFLINE) || + (lun->flags & CTL_LUN_NO_MEDIA) || lun->backend->lun_attr == NULL) continue; if ((lun->flags & CTL_LUN_PRIMARY_SC) == 0 && diff --git a/sys/cam/ctl/ctl.h b/sys/cam/ctl/ctl.h index 9fd6cce..35fc4c3 100644 --- a/sys/cam/ctl/ctl.h +++ b/sys/cam/ctl/ctl.h @@ -123,10 +123,11 @@ typedef enum { CTL_UA_INQ_CHANGE = 0x0100, CTL_UA_RES_PREEMPT = 0x0400, CTL_UA_RES_RELEASE = 0x0800, - CTL_UA_REG_PREEMPT = 0x1000, - CTL_UA_ASYM_ACC_CHANGE = 0x2000, - CTL_UA_CAPACITY_CHANGED = 0x4000, - CTL_UA_THIN_PROV_THRES = 0x8000 + CTL_UA_REG_PREEMPT = 0x1000, + CTL_UA_ASYM_ACC_CHANGE = 0x2000, + CTL_UA_CAPACITY_CHANGE = 0x4000, + CTL_UA_THIN_PROV_THRES = 0x8000, + CTL_UA_MEDIUM_CHANGE = 0x10000 } ctl_ua_type; #ifdef _KERNEL diff --git a/sys/cam/ctl/ctl_backend.c b/sys/cam/ctl/ctl_backend.c index f243d0b..91576c4 100644 --- a/sys/cam/ctl/ctl_backend.c +++ b/sys/cam/ctl/ctl_backend.c @@ -65,11 +65,9 @@ extern struct ctl_softc *control_softc; int ctl_backend_register(struct ctl_backend_driver *be) { - struct ctl_softc *softc; + struct ctl_softc *softc = control_softc; struct ctl_backend_driver *be_tmp; - softc = control_softc; - mtx_lock(&softc->ctl_lock); /* * Sanity check, make sure this isn't a duplicate registration. @@ -120,9 +118,7 @@ ctl_backend_register(struct ctl_backend_driver *be) int ctl_backend_deregister(struct ctl_backend_driver *be) { - struct ctl_softc *softc; - - softc = control_softc; + struct ctl_softc *softc = control_softc; mtx_lock(&softc->ctl_lock); @@ -153,20 +149,16 @@ ctl_backend_deregister(struct ctl_backend_driver *be) struct ctl_backend_driver * ctl_backend_find(char *backend_name) { - struct ctl_softc *softc; + struct ctl_softc *softc = control_softc; struct ctl_backend_driver *be_tmp; - softc = control_softc; - mtx_lock(&softc->ctl_lock); - STAILQ_FOREACH(be_tmp, &softc->be_list, links) { if (strcmp(be_tmp->name, backend_name) == 0) { mtx_unlock(&softc->ctl_lock); return (be_tmp); } } - mtx_unlock(&softc->ctl_lock); return (NULL); diff --git a/sys/cam/ctl/ctl_backend.h b/sys/cam/ctl/ctl_backend.h index f5bfd83..4177e2d 100644 --- a/sys/cam/ctl/ctl_backend.h +++ b/sys/cam/ctl/ctl_backend.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 2003 Silicon Graphics International Corp. + * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,14 +50,11 @@ * particular LUN ID in the req_lun_id field. If we cannot allocate that * LUN ID, the ctl_add_lun() call will fail. * - * The POWERED_OFF flag tells us that the LUN should default to the powered + * The STOPPED flag tells us that the LUN should default to the powered * off state. It will return 0x04,0x02 until it is powered up. ("Logical * unit not ready, initializing command required.") * - * The INOPERABLE flag tells us that this LUN is not operable for whatever - * reason. This means that user data may have been (or has been?) lost. - * We will return 0x31,0x00 ("Medium format corrupted") until the host - * issues a FORMAT UNIT command to clear the error. + * The NO_MEDIA flag tells us that the LUN has no media inserted. * * The PRIMARY flag tells us that this LUN is registered as a Primary LUN * which is accessible via the Master shelf controller in an HA. This flag @@ -72,20 +70,22 @@ * * The DEV_TYPE flag tells us that the device_type field is filled in. * + * The EJECTED flag tells us that the removable LUN has tray open. + * * The UNMAP flag tells us that this LUN supports UNMAP. * * The OFFLINE flag tells us that this LUN can not access backing store. */ typedef enum { CTL_LUN_FLAG_ID_REQ = 0x01, - CTL_LUN_FLAG_POWERED_OFF = 0x02, - CTL_LUN_FLAG_INOPERABLE = 0x04, + CTL_LUN_FLAG_STOPPED = 0x02, + CTL_LUN_FLAG_NO_MEDIA = 0x04, CTL_LUN_FLAG_PRIMARY = 0x08, CTL_LUN_FLAG_SERIAL_NUM = 0x10, CTL_LUN_FLAG_DEVID = 0x20, CTL_LUN_FLAG_DEV_TYPE = 0x40, CTL_LUN_FLAG_UNMAP = 0x80, - CTL_LUN_FLAG_OFFLINE = 0x100, + CTL_LUN_FLAG_EJECTED = 0x100, CTL_LUN_FLAG_READONLY = 0x200 } ctl_backend_lun_flags; @@ -289,23 +289,11 @@ int ctl_start_lun(struct ctl_be_lun *be_lun); int ctl_stop_lun(struct ctl_be_lun *be_lun); /* - * If a LUN is inoperable, call ctl_lun_inoperable(). Generally the LUN - * will become operable once again when the user issues the SCSI FORMAT UNIT - * command. (CTL will automatically clear the inoperable flag.) If we - * need to re-enable the LUN, we can call ctl_lun_operable() to enable it - * without a SCSI command. - */ -int ctl_lun_inoperable(struct ctl_be_lun *be_lun); -int ctl_lun_operable(struct ctl_be_lun *be_lun); - -/* - * To take a LUN offline, call ctl_lun_offline(). Generally the LUN will - * be online again once the user sends a SCSI START STOP UNIT command with - * the start and on/offline bits set. The backend can bring the LUN back - * online via the ctl_lun_online() function, if necessary. + * Methods to notify about media and tray status changes. */ -int ctl_lun_offline(struct ctl_be_lun *be_lun); -int ctl_lun_online(struct ctl_be_lun *be_lun); +int ctl_lun_no_media(struct ctl_be_lun *be_lun); +int ctl_lun_has_media(struct ctl_be_lun *be_lun); +int ctl_lun_ejected(struct ctl_be_lun *be_lun); /* * Called on LUN HA role change. @@ -314,7 +302,7 @@ int ctl_lun_primary(struct ctl_be_lun *be_lun); int ctl_lun_secondary(struct ctl_be_lun *be_lun); /* - * Let the backend notify the initiator about changed capacity. + * Let the backend notify the initiators about changes. */ void ctl_lun_capacity_changed(struct ctl_be_lun *be_lun); diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c index a37ac7b..40a0c79 100644 --- a/sys/cam/ctl/ctl_backend_block.c +++ b/sys/cam/ctl/ctl_backend_block.c @@ -2,6 +2,7 @@ * Copyright (c) 2003 Silicon Graphics International Corp. * Copyright (c) 2009-2011 Spectra Logic Corporation * Copyright (c) 2012 The FreeBSD Foundation + * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Portions of this software were developed by Edward Tomasz Napierala @@ -256,8 +257,7 @@ static int ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, static int ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req); static int ctl_be_block_close(struct ctl_be_block_lun *be_lun); -static int ctl_be_block_open(struct ctl_be_block_softc *softc, - struct ctl_be_block_lun *be_lun, +static int ctl_be_block_open(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req); static int ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req); @@ -405,11 +405,11 @@ ctl_be_block_move_done(union ctl_io *io) DPRINTF("entered\n"); #ifdef CTL_TIME_IO - getbintime(&cur_bt); + getbinuptime(&cur_bt); bintime_sub(&cur_bt, &io->io_hdr.dma_start_bt); bintime_add(&io->io_hdr.dma_bt, &cur_bt); +#endif io->io_hdr.num_dmas++; -#endif io->scsiio.kern_rel_offset += io->scsiio.kern_data_len; /* @@ -463,14 +463,8 @@ ctl_be_block_move_done(union ctl_io *io) * interrupt context, and therefore we cannot block. */ mtx_lock(&be_lun->queue_lock); - /* - * XXX KDM make sure that links is okay to use at this point. - * Otherwise, we either need to add another field to ctl_io_hdr, - * or deal with resource allocation here. - */ STAILQ_INSERT_TAIL(&be_lun->datamove_queue, &io->io_hdr, links); mtx_unlock(&be_lun->queue_lock); - taskqueue_enqueue(be_lun->io_taskqueue, &be_lun->io_task); return (0); @@ -563,8 +557,8 @@ ctl_be_block_biodone(struct bio *bio) ctl_serseq_done(io); } #ifdef CTL_TIME_IO - getbintime(&io->io_hdr.dma_start_bt); -#endif + getbinuptime(&io->io_hdr.dma_start_bt); +#endif ctl_datamove(io); } } @@ -586,15 +580,12 @@ ctl_be_block_flush_file(struct ctl_be_block_lun *be_lun, (void) vn_start_write(be_lun->vn, &mountpoint, V_WAIT); - if (MNT_SHARED_WRITES(mountpoint) - || ((mountpoint == NULL) - && MNT_SHARED_WRITES(be_lun->vn->v_mount))) + if (MNT_SHARED_WRITES(mountpoint) || + ((mountpoint == NULL) && MNT_SHARED_WRITES(be_lun->vn->v_mount))) lock_flags = LK_SHARED; else lock_flags = LK_EXCLUSIVE; - vn_lock(be_lun->vn, lock_flags | LK_RETRY); - error = VOP_FSYNC(be_lun->vn, beio->io_arg ? MNT_NOWAIT : MNT_WAIT, curthread); VOP_UNLOCK(be_lun->vn, 0); @@ -716,13 +707,11 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun, (void)vn_start_write(be_lun->vn, &mountpoint, V_WAIT); - if (MNT_SHARED_WRITES(mountpoint) - || ((mountpoint == NULL) + if (MNT_SHARED_WRITES(mountpoint) || ((mountpoint == NULL) && MNT_SHARED_WRITES(be_lun->vn->v_mount))) lock_flags = LK_SHARED; else lock_flags = LK_EXCLUSIVE; - vn_lock(be_lun->vn, lock_flags | LK_RETRY); /* @@ -785,8 +774,8 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun, ctl_serseq_done(io); } #ifdef CTL_TIME_IO - getbintime(&io->io_hdr.dma_start_bt); -#endif + getbinuptime(&io->io_hdr.dma_start_bt); +#endif ctl_datamove(io); } } @@ -956,8 +945,8 @@ ctl_be_block_dispatch_zvol(struct ctl_be_block_lun *be_lun, ctl_serseq_done(io); } #ifdef CTL_TIME_IO - getbintime(&io->io_hdr.dma_start_bt); -#endif + getbinuptime(&io->io_hdr.dma_start_bt); +#endif ctl_datamove(io); } } @@ -1014,13 +1003,10 @@ ctl_be_block_flush_dev(struct ctl_be_block_lun *be_lun, struct ctl_be_block_io *beio) { struct bio *bio; - union ctl_io *io; struct cdevsw *csw; struct cdev *dev; int ref; - io = beio->io; - DPRINTF("entered\n"); /* This can't fail, it's a blocking allocation. */ @@ -1540,14 +1526,8 @@ ctl_be_block_next(struct ctl_be_block_io *beio) io->io_hdr.status |= CTL_STATUS_NONE; mtx_lock(&be_lun->queue_lock); - /* - * XXX KDM make sure that links is okay to use at this point. - * Otherwise, we either need to add another field to ctl_io_hdr, - * or deal with resource allocation here. - */ STAILQ_INSERT_TAIL(&be_lun->input_queue, &io->io_hdr, links); mtx_unlock(&be_lun->queue_lock); - taskqueue_enqueue(be_lun->io_taskqueue, &be_lun->io_task); } @@ -1663,8 +1643,8 @@ ctl_be_block_dispatch(struct ctl_be_block_lun *be_lun, } else { SDT_PROBE(cbb, kernel, write, alloc_done, 0, 0, 0, 0, 0); #ifdef CTL_TIME_IO - getbintime(&io->io_hdr.dma_start_bt); -#endif + getbinuptime(&io->io_hdr.dma_start_bt); +#endif ctl_datamove(io); } } @@ -1680,7 +1660,7 @@ ctl_be_block_worker(void *context, int pending) DPRINTF("entered\n"); /* * Fetch and process I/Os from all queues. If we detect LUN - * CTL_LUN_FLAG_OFFLINE status here -- it is result of a race, + * CTL_LUN_FLAG_NO_MEDIA status here -- it is result of a race, * so make response maximally opaque to not confuse initiator. */ for (;;) { @@ -1692,7 +1672,7 @@ ctl_be_block_worker(void *context, int pending) ctl_io_hdr, links); mtx_unlock(&be_lun->queue_lock); beio = (struct ctl_be_block_io *)PRIV(io)->ptr; - if (cbe_lun->flags & CTL_LUN_FLAG_OFFLINE) { + if (cbe_lun->flags & CTL_LUN_FLAG_NO_MEDIA) { ctl_set_busy(&io->scsiio); ctl_complete_beio(beio); return; @@ -1706,7 +1686,7 @@ ctl_be_block_worker(void *context, int pending) STAILQ_REMOVE(&be_lun->config_write_queue, &io->io_hdr, ctl_io_hdr, links); mtx_unlock(&be_lun->queue_lock); - if (cbe_lun->flags & CTL_LUN_FLAG_OFFLINE) { + if (cbe_lun->flags & CTL_LUN_FLAG_NO_MEDIA) { ctl_set_busy(&io->scsiio); ctl_config_write_done(io); return; @@ -1720,7 +1700,7 @@ ctl_be_block_worker(void *context, int pending) STAILQ_REMOVE(&be_lun->config_read_queue, &io->io_hdr, ctl_io_hdr, links); mtx_unlock(&be_lun->queue_lock); - if (cbe_lun->flags & CTL_LUN_FLAG_OFFLINE) { + if (cbe_lun->flags & CTL_LUN_FLAG_NO_MEDIA) { ctl_set_busy(&io->scsiio); ctl_config_read_done(io); return; @@ -1734,7 +1714,7 @@ ctl_be_block_worker(void *context, int pending) STAILQ_REMOVE(&be_lun->input_queue, &io->io_hdr, ctl_io_hdr, links); mtx_unlock(&be_lun->queue_lock); - if (cbe_lun->flags & CTL_LUN_FLAG_OFFLINE) { + if (cbe_lun->flags & CTL_LUN_FLAG_NO_MEDIA) { ctl_set_busy(&io->scsiio); ctl_data_submit_done(io); return; @@ -1778,11 +1758,6 @@ ctl_be_block_submit(union ctl_io *io) PRIV(io)->len = 0; mtx_lock(&be_lun->queue_lock); - /* - * XXX KDM make sure that links is okay to use at this point. - * Otherwise, we either need to add another field to ctl_io_hdr, - * or deal with resource allocation here. - */ STAILQ_INSERT_TAIL(&be_lun->input_queue, &io->io_hdr, links); mtx_unlock(&be_lun->queue_lock); taskqueue_enqueue(be_lun->io_taskqueue, &be_lun->io_task); @@ -1845,7 +1820,6 @@ ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) off_t ps, pss, po, pos, us, uss, uo, uos; int error; - error = 0; cbe_lun = &be_lun->cbe_lun; file_data = &be_lun->backend.file; params = &be_lun->params; @@ -1895,6 +1869,8 @@ ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) */ if (params->blocksize_bytes != 0) cbe_lun->blocksize = params->blocksize_bytes; + else if (cbe_lun->lun_type == T_CDROM) + cbe_lun->blocksize = 2048; else cbe_lun->blocksize = 512; be_lun->size_blocks = be_lun->size_bytes / cbe_lun->blocksize; @@ -2023,7 +1999,9 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) "requested blocksize %u < backing device " "blocksize %u", params->blocksize_bytes, tmp); return (EINVAL); - } else + } else if (cbe_lun->lun_type == T_CDROM) + cbe_lun->blocksize = MAX(tmp, 2048); + else cbe_lun->blocksize = tmp; error = csw->d_ioctl(dev, DIOCGMEDIASIZE, (caddr_t)&otmp, FREAD, @@ -2156,8 +2134,7 @@ ctl_be_block_close(struct ctl_be_block_lun *be_lun) } static int -ctl_be_block_open(struct ctl_be_block_softc *softc, - struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) +ctl_be_block_open(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) { struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun; struct nameidata nd; @@ -2183,7 +2160,10 @@ ctl_be_block_open(struct ctl_be_block_softc *softc, flags = FREAD; value = ctl_get_opt(&cbe_lun->options, "readonly"); - if (value == NULL || strcmp(value, "on") != 0) + if (value != NULL) { + if (strcmp(value, "on") != 0) + flags |= FWRITE; + } else if (cbe_lun->lun_type == T_DIRECT) flags |= FWRITE; again: @@ -2299,10 +2279,13 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) } else if (control_softc->flags & CTL_FLAG_ACTIVE_SHELF) cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY; - if (cbe_lun->lun_type == T_DIRECT) { + if (cbe_lun->lun_type == T_DIRECT || + cbe_lun->lun_type == T_CDROM) { be_lun->size_bytes = params->lun_size_bytes; if (params->blocksize_bytes != 0) cbe_lun->blocksize = params->blocksize_bytes; + else if (cbe_lun->lun_type == T_CDROM) + cbe_lun->blocksize = 2048; else cbe_lun->blocksize = 512; be_lun->size_blocks = be_lun->size_bytes / cbe_lun->blocksize; @@ -2311,7 +2294,7 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) if ((cbe_lun->flags & CTL_LUN_FLAG_PRIMARY) || control_softc->ha_mode == CTL_HA_MODE_SER_ONLY) { - retval = ctl_be_block_open(softc, be_lun, req); + retval = ctl_be_block_open(be_lun, req); if (retval != 0) { retval = 0; req->status = CTL_LUN_WARNING; @@ -2322,10 +2305,6 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) num_threads = 1; } - /* - * XXX This searching loop might be refactored to be combined with - * the loop above, - */ value = ctl_get_opt(&cbe_lun->options, "num_threads"); if (value != NULL) { tmp_num_threads = strtol(value, NULL, 0); @@ -2345,7 +2324,7 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) } if (be_lun->vn == NULL) - cbe_lun->flags |= CTL_LUN_FLAG_OFFLINE; + cbe_lun->flags |= CTL_LUN_FLAG_NO_MEDIA; /* Tell the user the blocksize we ended up using */ params->lun_size_bytes = be_lun->size_bytes; params->blocksize_bytes = cbe_lun->blocksize; @@ -2515,7 +2494,6 @@ ctl_be_block_rm(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) break; } mtx_unlock(&softc->lock); - if (be_lun == NULL) { snprintf(req->error_str, sizeof(req->error_str), "LUN %u is not managed by the block backend", @@ -2533,8 +2511,8 @@ ctl_be_block_rm(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) } if (be_lun->vn != NULL) { - cbe_lun->flags |= CTL_LUN_FLAG_OFFLINE; - ctl_lun_offline(cbe_lun); + cbe_lun->flags |= CTL_LUN_FLAG_NO_MEDIA; + ctl_lun_no_media(cbe_lun); taskqueue_drain_all(be_lun->io_taskqueue); ctl_be_block_close(be_lun); } @@ -2583,13 +2561,10 @@ ctl_be_block_rm(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) free(be_lun, M_CTLBLK); req->status = CTL_LUN_OK; - return (0); bailout_error: - req->status = CTL_LUN_ERROR; - return (0); } @@ -2611,7 +2586,6 @@ ctl_be_block_modify(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) break; } mtx_unlock(&softc->lock); - if (be_lun == NULL) { snprintf(req->error_str, sizeof(req->error_str), "LUN %u is not managed by the block backend", @@ -2646,22 +2620,27 @@ ctl_be_block_modify(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) if ((cbe_lun->flags & CTL_LUN_FLAG_PRIMARY) || control_softc->ha_mode == CTL_HA_MODE_SER_ONLY) { if (be_lun->vn == NULL) - error = ctl_be_block_open(softc, be_lun, req); + error = ctl_be_block_open(be_lun, req); else if (vn_isdisk(be_lun->vn, &error)) error = ctl_be_block_open_dev(be_lun, req); else if (be_lun->vn->v_type == VREG) error = ctl_be_block_open_file(be_lun, req); else error = EINVAL; - if ((cbe_lun->flags & CTL_LUN_FLAG_OFFLINE) && + if ((cbe_lun->flags & CTL_LUN_FLAG_NO_MEDIA) && be_lun->vn != NULL) { - cbe_lun->flags &= ~CTL_LUN_FLAG_OFFLINE; - ctl_lun_online(cbe_lun); + cbe_lun->flags &= ~CTL_LUN_FLAG_NO_MEDIA; + ctl_lun_has_media(cbe_lun); + } else if ((cbe_lun->flags & CTL_LUN_FLAG_NO_MEDIA) == 0 && + be_lun->vn == NULL) { + cbe_lun->flags |= CTL_LUN_FLAG_NO_MEDIA; + ctl_lun_no_media(cbe_lun); } + cbe_lun->flags &= ~CTL_LUN_FLAG_EJECTED; } else { if (be_lun->vn != NULL) { - cbe_lun->flags |= CTL_LUN_FLAG_OFFLINE; - ctl_lun_offline(cbe_lun); + cbe_lun->flags |= CTL_LUN_FLAG_NO_MEDIA; + ctl_lun_no_media(cbe_lun); taskqueue_drain_all(be_lun->io_taskqueue); error = ctl_be_block_close(be_lun); } else @@ -2688,7 +2667,6 @@ ctl_be_block_lun_shutdown(void *be_lun) struct ctl_be_block_softc *softc; lun = (struct ctl_be_block_lun *)be_lun; - softc = lun->softc; mtx_lock(&softc->lock); @@ -2696,7 +2674,6 @@ ctl_be_block_lun_shutdown(void *be_lun) if (lun->flags & CTL_BE_BLOCK_LUN_WAITING) wakeup(lun); mtx_unlock(&softc->lock); - } static void @@ -2745,14 +2722,13 @@ ctl_be_block_config_write(union ctl_io *io) struct ctl_be_lun *cbe_lun; int retval; - retval = 0; - DPRINTF("entered\n"); cbe_lun = (struct ctl_be_lun *)io->io_hdr.ctl_private[ CTL_PRIV_BACKEND_LUN].ptr; be_lun = (struct ctl_be_block_lun *)cbe_lun->be_lun; + retval = 0; switch (io->scsiio.cdb[0]) { case SYNCHRONIZE_CACHE: case SYNCHRONIZE_CACHE_16: @@ -2775,40 +2751,46 @@ ctl_be_block_config_write(union ctl_io *io) break; case START_STOP_UNIT: { struct scsi_start_stop_unit *cdb; + struct ctl_lun_req req; cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb; - - if (cdb->how & SSS_START) - retval = ctl_start_lun(cbe_lun); - else { - retval = ctl_stop_lun(cbe_lun); - /* - * XXX KDM Copan-specific offline behavior. - * Figure out a reasonable way to port this? - */ -#ifdef NEEDTOPORT - if ((retval == 0) - && (cdb->byte2 & SSS_ONOFFLINE)) - retval = ctl_lun_offline(cbe_lun); -#endif + if ((cdb->how & SSS_PC_MASK) != 0) { + ctl_set_success(&io->scsiio); + ctl_config_write_done(io); + break; } - - /* - * In general, the above routines should not fail. They - * just set state for the LUN. So we've got something - * pretty wrong here if we can't start or stop the LUN. - */ - if (retval != 0) { - ctl_set_internal_failure(&io->scsiio, - /*sks_valid*/ 1, - /*retry_count*/ 0xf051); - retval = CTL_RETVAL_COMPLETE; + if (cdb->how & SSS_START) { + if ((cdb->how & SSS_LOEJ) && be_lun->vn == NULL) { + retval = ctl_be_block_open(be_lun, &req); + cbe_lun->flags &= ~CTL_LUN_FLAG_EJECTED; + if (retval == 0) { + cbe_lun->flags &= ~CTL_LUN_FLAG_NO_MEDIA; + ctl_lun_has_media(cbe_lun); + } else { + cbe_lun->flags |= CTL_LUN_FLAG_NO_MEDIA; + ctl_lun_no_media(cbe_lun); + } + } + ctl_start_lun(cbe_lun); } else { - ctl_set_success(&io->scsiio); + ctl_stop_lun(cbe_lun); + if (cdb->how & SSS_LOEJ) { + cbe_lun->flags |= CTL_LUN_FLAG_NO_MEDIA; + cbe_lun->flags |= CTL_LUN_FLAG_EJECTED; + ctl_lun_ejected(cbe_lun); + if (be_lun->vn != NULL) + ctl_be_block_close(be_lun); + } } + + ctl_set_success(&io->scsiio); ctl_config_write_done(io); break; } + case PREVENT_ALLOW: + ctl_set_success(&io->scsiio); + ctl_config_write_done(io); + break; default: ctl_set_invalid_opcode(&io->scsiio); ctl_config_write_done(io); @@ -2870,22 +2852,16 @@ ctl_be_block_lun_info(void *be_lun, struct sbuf *sb) int retval; lun = (struct ctl_be_block_lun *)be_lun; - retval = 0; retval = sbuf_printf(sb, "\t<num_threads>"); - if (retval != 0) goto bailout; - retval = sbuf_printf(sb, "%d", lun->num_threads); - if (retval != 0) goto bailout; - retval = sbuf_printf(sb, "</num_threads>\n"); bailout: - return (retval); } diff --git a/sys/cam/ctl/ctl_backend_ramdisk.c b/sys/cam/ctl/ctl_backend_ramdisk.c index 4c95d5c..d170446 100644 --- a/sys/cam/ctl/ctl_backend_ramdisk.c +++ b/sys/cam/ctl/ctl_backend_ramdisk.c @@ -1,6 +1,7 @@ /*- * Copyright (c) 2003, 2008 Silicon Graphics International Corp. * Copyright (c) 2012 The FreeBSD Foundation + * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Portions of this software were developed by Edward Tomasz Napierala @@ -145,18 +146,13 @@ CTL_BACKEND_DECLARE(cbr, ctl_be_ramdisk_driver); int ctl_backend_ramdisk_init(void) { - struct ctl_be_ramdisk_softc *softc; + struct ctl_be_ramdisk_softc *softc = &rd_softc; #ifdef CTL_RAMDISK_PAGES int i; #endif - - softc = &rd_softc; - memset(softc, 0, sizeof(*softc)); - mtx_init(&softc->lock, "ctlramdisk", NULL, MTX_DEF); - STAILQ_INIT(&softc->lun_list); softc->rd_size = 1024 * 1024; #ifdef CTL_RAMDISK_PAGES @@ -177,23 +173,14 @@ ctl_backend_ramdisk_init(void) void ctl_backend_ramdisk_shutdown(void) { - struct ctl_be_ramdisk_softc *softc; + struct ctl_be_ramdisk_softc *softc = &rd_softc; struct ctl_be_ramdisk_lun *lun, *next_lun; #ifdef CTL_RAMDISK_PAGES int i; #endif - softc = &rd_softc; - mtx_lock(&softc->lock); - for (lun = STAILQ_FIRST(&softc->lun_list); lun != NULL; lun = next_lun){ - /* - * Grab the next LUN. The current LUN may get removed by - * ctl_invalidate_lun(), which will call our LUN shutdown - * routine, if there is no outstanding I/O for this LUN. - */ - next_lun = STAILQ_NEXT(lun, links); - + STAILQ_FOREACH_SAFE(lun, &softc->lun_list, links, next_lun) { /* * Drop our lock here. Since ctl_invalidate_lun() can call * back into us, this could potentially lead to a recursive @@ -235,11 +222,11 @@ ctl_backend_ramdisk_move_done(union ctl_io *io) CTL_PRIV_BACKEND_LUN].ptr; be_lun = (struct ctl_be_ramdisk_lun *)cbe_lun->be_lun; #ifdef CTL_TIME_IO - getbintime(&cur_bt); + getbinuptime(&cur_bt); bintime_sub(&cur_bt, &io->io_hdr.dma_start_bt); bintime_add(&io->io_hdr.dma_bt, &cur_bt); - io->io_hdr.num_dmas++; #endif + io->io_hdr.num_dmas++; if (io->scsiio.kern_sg_entries > 0) free(io->scsiio.kern_data_ptr, M_RAMDISK); io->scsiio.kern_rel_offset += io->scsiio.kern_data_len; @@ -339,7 +326,7 @@ ctl_backend_ramdisk_continue(union ctl_io *io) io->io_hdr.flags |= CTL_FLAG_ALLOCATED; io->io_hdr.ctl_private[CTL_PRIV_BACKEND].integer -= len_filled; #ifdef CTL_TIME_IO - getbintime(&io->io_hdr.dma_start_bt); + getbinuptime(&io->io_hdr.dma_start_bt); #endif ctl_datamove(io); } @@ -347,12 +334,10 @@ ctl_backend_ramdisk_continue(union ctl_io *io) static void ctl_backend_ramdisk_worker(void *context, int pending) { - struct ctl_be_ramdisk_softc *softc; struct ctl_be_ramdisk_lun *be_lun; union ctl_io *io; be_lun = (struct ctl_be_ramdisk_lun *)context; - softc = be_lun->softc; mtx_lock(&be_lun->queue_lock); for (;;) { @@ -360,11 +345,8 @@ ctl_backend_ramdisk_worker(void *context, int pending) if (io != NULL) { STAILQ_REMOVE(&be_lun->cont_queue, &io->io_hdr, ctl_io_hdr, links); - mtx_unlock(&be_lun->queue_lock); - ctl_backend_ramdisk_continue(io); - mtx_lock(&be_lun->queue_lock); continue; } @@ -382,18 +364,14 @@ static int ctl_backend_ramdisk_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) { - struct ctl_be_ramdisk_softc *softc; + struct ctl_be_ramdisk_softc *softc = &rd_softc; + struct ctl_lun_req *lun_req; int retval; retval = 0; - softc = &rd_softc; - switch (cmd) { - case CTL_LUN_REQ: { - struct ctl_lun_req *lun_req; - + case CTL_LUN_REQ: lun_req = (struct ctl_lun_req *)addr; - switch (lun_req->reqtype) { case CTL_LUNREQ_CREATE: retval = ctl_backend_ramdisk_create(softc, lun_req); @@ -412,7 +390,6 @@ ctl_backend_ramdisk_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, break; } break; - } default: retval = ENOTTY; break; @@ -429,20 +406,13 @@ ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc, struct ctl_lun_rm_params *params; int retval; - - retval = 0; params = &req->reqdata.rm; - - be_lun = NULL; - mtx_lock(&softc->lock); - STAILQ_FOREACH(be_lun, &softc->lun_list, links) { if (be_lun->cbe_lun.lun_id == params->lun_id) break; } mtx_unlock(&softc->lock); - if (be_lun == NULL) { snprintf(req->error_str, sizeof(req->error_str), "%s: LUN %u is not managed by the ramdisk backend", @@ -451,7 +421,6 @@ ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc, } retval = ctl_disable_lun(&be_lun->cbe_lun); - if (retval != 0) { snprintf(req->error_str, sizeof(req->error_str), "%s: error %d returned from ctl_disable_lun() for " @@ -483,10 +452,9 @@ ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc, } mtx_lock(&softc->lock); - while ((be_lun->flags & CTL_BE_RAMDISK_LUN_UNCONFIGURED) == 0) { retval = msleep(be_lun, &softc->lock, PCATCH, "ctlram", 0); - if (retval == EINTR) + if (retval == EINTR) break; } be_lun->flags &= ~CTL_BE_RAMDISK_LUN_WAITING; @@ -514,12 +482,10 @@ ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc, } req->status = CTL_LUN_OK; - return (retval); bailout_error: req->status = CTL_LUN_ERROR; - return (0); } @@ -558,9 +524,12 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, } else if (control_softc->flags & CTL_FLAG_ACTIVE_SHELF) cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY; - if (cbe_lun->lun_type == T_DIRECT) { + if (cbe_lun->lun_type == T_DIRECT || + cbe_lun->lun_type == T_CDROM) { if (params->blocksize_bytes != 0) cbe_lun->blocksize = params->blocksize_bytes; + else if (cbe_lun->lun_type == T_CDROM) + cbe_lun->blocksize = 2048; else cbe_lun->blocksize = 512; if (params->lun_size_bytes < cbe_lun->blocksize) { @@ -584,7 +553,10 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, if (value != NULL && strcmp(value, "on") == 0) cbe_lun->flags |= CTL_LUN_FLAG_UNMAP; value = ctl_get_opt(&cbe_lun->options, "readonly"); - if (value != NULL && strcmp(value, "on") == 0) + if (value != NULL) { + if (strcmp(value, "on") == 0) + cbe_lun->flags |= CTL_LUN_FLAG_READONLY; + } else if (cbe_lun->lun_type != T_DIRECT) cbe_lun->flags |= CTL_LUN_FLAG_READONLY; cbe_lun->serseq = CTL_LUN_SERSEQ_OFF; value = ctl_get_opt(&cbe_lun->options, "serseq"); @@ -656,7 +628,6 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, mtx_lock(&softc->lock); softc->num_luns++; STAILQ_INSERT_TAIL(&softc->lun_list, be_lun, links); - mtx_unlock(&softc->lock); retval = ctl_add_lun(&be_lun->cbe_lun); @@ -703,7 +674,6 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, mtx_unlock(&softc->lock); req->status = CTL_LUN_OK; - return (retval); bailout_error: @@ -716,7 +686,6 @@ bailout_error: mtx_destroy(&be_lun->queue_lock); free(be_lun, M_RAMDISK); } - return (retval); } @@ -739,7 +708,6 @@ ctl_backend_ramdisk_modify(struct ctl_be_ramdisk_softc *softc, break; } mtx_unlock(&softc->lock); - if (be_lun == NULL) { snprintf(req->error_str, sizeof(req->error_str), "%s: LUN %u is not managed by the ramdisk backend", @@ -786,12 +754,10 @@ ctl_backend_ramdisk_modify(struct ctl_be_ramdisk_softc *softc, params->lun_size_bytes = be_lun->size_bytes; req->status = CTL_LUN_OK; - return (0); bailout_error: req->status = CTL_LUN_ERROR; - return (0); } @@ -807,9 +773,7 @@ ctl_backend_ramdisk_lun_shutdown(void *be_lun) do_free = 0; mtx_lock(&softc->lock); - lun->flags |= CTL_BE_RAMDISK_LUN_UNCONFIGURED; - if (lun->flags & CTL_BE_RAMDISK_LUN_WAITING) { wakeup(lun); } else { @@ -818,7 +782,6 @@ ctl_backend_ramdisk_lun_shutdown(void *be_lun) softc->num_luns--; do_free = 1; } - mtx_unlock(&softc->lock); if (do_free != 0) @@ -879,12 +842,12 @@ ctl_backend_ramdisk_lun_config_status(void *be_lun, static int ctl_backend_ramdisk_config_write(union ctl_io *io) { - struct ctl_be_ramdisk_softc *softc; + struct ctl_be_lun *cbe_lun; int retval; + cbe_lun = (struct ctl_be_lun *)io->io_hdr.ctl_private[ + CTL_PRIV_BACKEND_LUN].ptr; retval = 0; - softc = &rd_softc; - switch (io->scsiio.cdb[0]) { case SYNCHRONIZE_CACHE: case SYNCHRONIZE_CACHE_16: @@ -908,42 +871,27 @@ ctl_backend_ramdisk_config_write(union ctl_io *io) break; case START_STOP_UNIT: { struct scsi_start_stop_unit *cdb; - struct ctl_be_lun *cbe_lun; - struct ctl_be_ramdisk_lun *be_lun; cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb; - - cbe_lun = (struct ctl_be_lun *)io->io_hdr.ctl_private[ - CTL_PRIV_BACKEND_LUN].ptr; - be_lun = (struct ctl_be_ramdisk_lun *)cbe_lun->be_lun; - - if (cdb->how & SSS_START) - retval = ctl_start_lun(cbe_lun); - else { - retval = ctl_stop_lun(cbe_lun); -#ifdef NEEDTOPORT - if ((retval == 0) - && (cdb->byte2 & SSS_ONOFFLINE)) - retval = ctl_lun_offline(cbe_lun); -#endif + if ((cdb->how & SSS_PC_MASK) != 0) { + ctl_set_success(&io->scsiio); + ctl_config_write_done(io); + break; } - - /* - * In general, the above routines should not fail. They - * just set state for the LUN. So we've got something - * pretty wrong here if we can't start or stop the LUN. - */ - if (retval != 0) { - ctl_set_internal_failure(&io->scsiio, - /*sks_valid*/ 1, - /*retry_count*/ 0xf051); - retval = CTL_RETVAL_COMPLETE; + if (cdb->how & SSS_START) { + if (cdb->how & SSS_LOEJ) + ctl_lun_has_media(cbe_lun); + ctl_start_lun(cbe_lun); } else { - ctl_set_success(&io->scsiio); + ctl_stop_lun(cbe_lun); + if (cdb->how & SSS_LOEJ) + ctl_lun_ejected(cbe_lun); } + ctl_set_success(&io->scsiio); ctl_config_write_done(io); break; } + case PREVENT_ALLOW: case WRITE_SAME_10: case WRITE_SAME_16: case UNMAP: diff --git a/sys/cam/ctl/ctl_cmd_table.c b/sys/cam/ctl/ctl_cmd_table.c index 0753f28..498f7c5 100644 --- a/sys/cam/ctl/ctl_cmd_table.c +++ b/sys/cam/ctl/ctl_cmd_table.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2003, 2004, 2005, 2009 Silicon Graphics International Corp. + * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -67,8 +68,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5e[32] = /* 00 READ KEYS */ {ctl_persistent_reserve_in, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, @@ -78,8 +78,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5e[32] = /* 01 READ RESERVATION */ {ctl_persistent_reserve_in, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, @@ -89,8 +88,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5e[32] = /* 02 REPORT CAPABILITIES */ {ctl_persistent_reserve_in, CTL_SERIDX_INQ, CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, @@ -100,8 +98,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5e[32] = /* 03 READ FULL STATUS */ {ctl_persistent_reserve_in, CTL_SERIDX_INQ, CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, @@ -117,8 +114,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5f[32] = /* 00 REGISTER */ {ctl_persistent_reserve_out, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_OUT | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, @@ -128,8 +124,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5f[32] = /* 01 RESERVE */ {ctl_persistent_reserve_out, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_OUT | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, @@ -139,8 +134,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5f[32] = /* 02 RELEASE */ {ctl_persistent_reserve_out, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_OUT | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, @@ -150,8 +144,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5f[32] = /* 03 CLEAR */ {ctl_persistent_reserve_out, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_OUT | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, @@ -161,8 +154,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5f[32] = /* 04 PREEMPT */ {ctl_persistent_reserve_out, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_OUT | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, @@ -172,8 +164,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5f[32] = /* 05 PREEMPT AND ABORT */ {ctl_persistent_reserve_out, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_OUT | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, @@ -183,8 +174,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5f[32] = /* 06 REGISTER AND IGNORE EXISTING KEY */ {ctl_persistent_reserve_out, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_OUT | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, @@ -202,12 +192,14 @@ const struct ctl_cmd_entry ctl_cmd_table_83[32] = { /* 00 EXTENDED COPY (LID1) */ {ctl_extended_copy_lid1, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_BOTH | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_FLAG_DATA_OUT, CTL_LUN_PAT_NONE, 16, { 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}}, /* 01 EXTENDED COPY (LID4) */ {ctl_extended_copy_lid4, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_BOTH | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_FLAG_DATA_OUT, CTL_LUN_PAT_NONE, 16, { 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}}, @@ -255,7 +247,7 @@ const struct ctl_cmd_entry ctl_cmd_table_83[32] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 10 POPULATE TOKEN */ -{ctl_populate_token, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_populate_token, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_OUT | CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, CTL_LUN_PAT_NONE, @@ -263,7 +255,7 @@ const struct ctl_cmd_entry ctl_cmd_table_83[32] = 0xff, 0xff, 0xff, 0xff, 0, 0x07}}, /* 11 WRITE USING TOKEN */ -{ctl_write_using_token, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_write_using_token, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_OUT, CTL_LUN_PAT_NONE, 16, { 0x11, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, @@ -301,6 +293,7 @@ const struct ctl_cmd_entry ctl_cmd_table_83[32] = /* 1C COPY OPERATION ABORT */ {ctl_copy_operation_abort, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_BOTH | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_FLAG_DATA_NONE, CTL_LUN_PAT_NONE, 16, { 0x1c, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x07}}, @@ -312,6 +305,7 @@ const struct ctl_cmd_entry ctl_cmd_table_84[32] = /* 00 RECEIVE COPY STATUS (LID1) */ {ctl_receive_copy_status_lid1, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_BOTH | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, CTL_LUN_PAT_NONE, @@ -326,8 +320,7 @@ const struct ctl_cmd_entry ctl_cmd_table_84[32] = /* 03 RECEIVE COPY OPERATING PARAMETERS */ {ctl_receive_copy_operating_parameters, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, @@ -337,6 +330,7 @@ const struct ctl_cmd_entry ctl_cmd_table_84[32] = /* 04 RECEIVE COPY FAILURE DETAILS (LID1) */ {ctl_receive_copy_failure_details, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_BOTH | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, CTL_LUN_PAT_NONE, @@ -345,6 +339,7 @@ const struct ctl_cmd_entry ctl_cmd_table_84[32] = /* 05 RECEIVE COPY STATUS (LID4) */ {ctl_receive_copy_status_lid4, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_BOTH | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, CTL_LUN_PAT_NONE, @@ -356,6 +351,7 @@ const struct ctl_cmd_entry ctl_cmd_table_84[32] = /* 07 RECEIVE ROD TOKEN INFORMATION */ {ctl_receive_rod_token_information, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_BOTH | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, CTL_LUN_PAT_NONE, @@ -364,6 +360,7 @@ const struct ctl_cmd_entry ctl_cmd_table_84[32] = /* 08 REPORT ALL ROD TOKENS */ {ctl_report_all_rod_tokens, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_BOTH | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, CTL_LUN_PAT_NONE, @@ -422,9 +419,7 @@ const struct ctl_cmd_entry ctl_cmd_table_9e[32] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 10 READ CAPACITY(16) */ -{ctl_read_capacity_16, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_SLUN | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | +{ctl_read_capacity_16, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, CTL_LUN_PAT_READCAP, @@ -434,7 +429,7 @@ const struct ctl_cmd_entry ctl_cmd_table_9e[32] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 12 GET LBA STATUS */ -{ctl_get_lba_status, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_get_lba_status, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE, @@ -479,8 +474,7 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] = /* 0A REPORT TARGET PORT GROUPS */ {ctl_report_tagret_port_groups, CTL_SERIDX_INQ, CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_CMD_FLAG_OK_ON_UNAVAIL | CTL_FLAG_DATA_IN | @@ -493,8 +487,7 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] = /* 0C REPORT SUPPORTED_OPCODES */ {ctl_report_supported_opcodes, CTL_SERIDX_INQ, CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_CMD_FLAG_OK_ON_UNAVAIL | CTL_FLAG_DATA_IN | @@ -504,8 +497,7 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] = /* 0D REPORT SUPPORTED_TASK MANAGEMENT FUNCTIONS */ {ctl_report_supported_tmf, CTL_SERIDX_INQ, CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_CMD_FLAG_OK_ON_UNAVAIL | CTL_FLAG_DATA_IN | @@ -518,8 +510,7 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] = /* 0F REPORT TIMESTAMP */ {ctl_report_timestamp, CTL_SERIDX_INQ, CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_CMD_FLAG_OK_ON_UNAVAIL | CTL_FLAG_DATA_IN | @@ -550,8 +541,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = CTL_CMD_FLAG_OK_ON_BOTH | CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_NO_SENSE | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_CMD_FLAG_OK_ON_UNAVAIL | CTL_CMD_FLAG_ALLOW_ON_PR_RESV | @@ -559,8 +549,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = CTL_LUN_PAT_NONE, 6, {0x01, 0, 0, 0xff, 0x07}}, /* 04 FORMAT UNIT */ -{ctl_format, CTL_SERIDX_FORMAT, CTL_CMD_FLAG_OK_ON_SLUN | - CTL_CMD_FLAG_OK_ON_INOPERABLE | +{ctl_format, CTL_SERIDX_FORMAT, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_OUT, CTL_LUN_PAT_NONE, 6, {0xff, 0, 0, 0, 0x07}}, @@ -574,7 +563,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 08 READ(6) */ -{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE, 6, {0x1f, 0xff, 0xff, 0xff, 0x07}}, @@ -583,7 +572,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 0A WRITE(6) */ -{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_OUT, CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE, 6, {0x1f, 0xff, 0xff, 0xff, 0x07}}, @@ -613,8 +602,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = CTL_CMD_FLAG_OK_ON_BOTH | CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_NO_SENSE | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_CMD_FLAG_OK_ON_UNAVAIL | CTL_FLAG_DATA_IN | @@ -629,8 +617,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = /* 15 MODE SELECT(6) */ {ctl_mode_select, CTL_SERIDX_MD_SEL, CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_OUT, CTL_LUN_PAT_NONE, 6, {0x11, 0, 0, 0xff, 0x07}}, @@ -638,8 +625,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = /* 16 RESERVE(6) */ {ctl_scsi_reserve, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_OUT, CTL_LUN_PAT_NONE, 6, {0, 0, 0, 0, 0x07}}, @@ -647,8 +633,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = /* 17 RELEASE(6) */ {ctl_scsi_release, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_NONE, CTL_LUN_PAT_NONE, 6, {0, 0, 0, 0, 0x07}}, @@ -661,20 +646,19 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = /* 1A MODE SENSE(6) */ {ctl_mode_sense, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, CTL_LUN_PAT_NONE, 6, {0x08, 0xff, 0xff, 0xff, 0x07}}, /* 1B START STOP UNIT */ -{ctl_start_stop, CTL_SERIDX_START, CTL_CMD_FLAG_OK_ON_SLUN | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | +{ctl_start_stop, CTL_SERIDX_START, CTL_CMD_FLAG_OK_ON_DIRECT | + CTL_CMD_FLAG_OK_ON_CDROM | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_FLAG_DATA_NONE | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, - CTL_LUN_PAT_NONE, 6, {0x01, 0, 0, 0x03, 0x07}}, + CTL_LUN_PAT_NONE, 6, {0x01, 0, 0x0f, 0xf7, 0x07}}, /* 1C RECEIVE DIAGNOSTIC RESULTS */ {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, @@ -683,7 +667,11 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 1E PREVENT ALLOW MEDIUM REMOVAL */ -{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, +{ctl_prevent_allow, CTL_SERIDX_START, CTL_CMD_FLAG_OK_ON_DIRECT | + CTL_CMD_FLAG_OK_ON_CDROM | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | + CTL_FLAG_DATA_NONE, + CTL_LUN_PAT_NONE, 6, {0x01, 0, 0, 0x03, 0x07}}, /* 1F */ {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, @@ -704,9 +692,8 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 25 READ CAPACITY(10) */ -{ctl_read_capacity, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_SLUN| - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | +{ctl_read_capacity, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_DIRECT | + CTL_CMD_FLAG_OK_ON_CDROM | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, CTL_LUN_PAT_READCAP, 10, {0, 0, 0, 0, 0, 0, 0, 0, 0x07}}, @@ -718,7 +705,8 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 28 READ(10) */ -{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT | + CTL_CMD_FLAG_OK_ON_CDROM | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE, @@ -728,7 +716,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 2A WRITE(10) */ -{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT, +{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT, CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE, 10, {0x1a, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}}, @@ -742,12 +730,12 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 2E WRITE AND VERIFY(10) */ -{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT, +{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT, CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE, 10, {0x12, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}}, /* 2F VERIFY(10) */ -{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_OUT | CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE, @@ -769,16 +757,16 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 35 SYNCHRONIZE CACHE(10) */ -{ctl_sync_cache, CTL_SERIDX_SYNC, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_sync_cache, CTL_SERIDX_SYNC, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_NONE, CTL_LUN_PAT_WRITE, - 10, {0x02, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}}, + 10, {0x06, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}}, /* 36 LOCK UNLOCK CACHE(10) */ {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 37 READ DEFECT DATA(10) */ -{ctl_read_defect, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_read_defect, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, CTL_LUN_PAT_NONE, @@ -795,8 +783,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = /* 3B WRITE BUFFER */ {ctl_write_buffer, CTL_SERIDX_MD_SEL, CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_OUT, CTL_LUN_PAT_NONE, @@ -804,8 +791,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = /* 3C READ BUFFER */ {ctl_read_buffer, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, @@ -825,18 +811,22 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 41 WRITE SAME(10) */ -{ctl_write_same, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_write_same, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_OUT, CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE, 10, {0x1a, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}}, /* 42 READ SUB-CHANNEL / UNMAP */ -{ctl_unmap, CTL_SERIDX_UNMAP, CTL_CMD_FLAG_OK_ON_SLUN | CTL_FLAG_DATA_OUT, +{ctl_unmap, CTL_SERIDX_UNMAP, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_OUT, CTL_LUN_PAT_WRITE, 10, {1, 0, 0, 0, 0, 0, 0xff, 0xff, 0x07}}, /* 43 READ TOC/PMA/ATIP */ -{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, +{ctl_read_toc, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_CDROM | + CTL_CMD_FLAG_ALLOW_ON_PR_WRESV | + CTL_FLAG_DATA_IN, + CTL_LUN_PAT_NONE, + 10, {0x02, 0x01, 0, 0, 0, 0xff, 0xff, 0xff, 0x07}}, /* 44 REPORT DENSITY SUPPORT */ {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, @@ -845,7 +835,12 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 46 GET CONFIGURATION */ -{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, +{ctl_get_config, CTL_SERIDX_INQ, CTL_CMD_FLAG_OK_ON_CDROM | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | + CTL_CMD_FLAG_ALLOW_ON_PR_RESV | + CTL_FLAG_DATA_IN, + CTL_LUN_PAT_NONE, + 10, {0x03, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0x07}}, /* 47 PLAY AUDIO MSF */ {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, @@ -857,7 +852,12 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 4A GET EVENT STATUS NOTIFICATION */ -{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, +{ctl_get_event_status, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_CDROM | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | + CTL_CMD_FLAG_ALLOW_ON_PR_RESV | + CTL_FLAG_DATA_IN, + CTL_LUN_PAT_NONE, + 10, {0x02, 0x01, 0, 0, 0, 0xff, 0xff, 0xff, 0x07}}, /* 4B PAUSE/RESUME */ {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, @@ -866,7 +866,9 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 4D LOG SENSE */ -{ctl_log_sense, CTL_SERIDX_LOG_SNS, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_log_sense, CTL_SERIDX_LOG_SNS, CTL_CMD_FLAG_OK_ON_BOTH | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | + CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, CTL_LUN_PAT_NONE, 10, {0, 0xff, 0xff, 0, 0xff, 0xff, 0xff, 0xff, 0x07} }, @@ -894,8 +896,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = /* 55 MODE SELECT(10) */ {ctl_mode_select, CTL_SERIDX_MD_SEL, CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_OUT, CTL_LUN_PAT_NONE, 10, {0x11, 0, 0, 0, 0, 0, 0xff, 0xff, 0x07} }, @@ -903,20 +904,18 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = /* 56 RESERVE(10) */ {ctl_scsi_reserve, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_OUT, - CTL_LUN_PAT_NONE, 10, {0x02, 0, 0xff, 0, 0, 0, 0xff, 0xff, 0x07} }, + CTL_LUN_PAT_NONE, 10, {0, 0, 0, 0, 0, 0, 0, 0, 0x07} }, /* 57 RELEASE(10) */ {ctl_scsi_release, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_OUT, - CTL_LUN_PAT_NONE, 10, {0x02, 0, 0xff, 0, 0, 0, 0xff, 0xff, 0x07} }, + CTL_LUN_PAT_NONE, 10, {0, 0, 0, 0, 0, 0, 0, 0, 0x07}}, /* 58 REPAIR TRACK */ {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, @@ -926,8 +925,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = /* 5A MODE SENSE(10) */ {ctl_mode_sense, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, @@ -1073,20 +1071,20 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 88 READ(16) */ -{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN | CTL_FLAG_DATA_IN | +{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE, 16, {0x1a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}}, /* 89 COMPARE AND WRITE */ -{ctl_cnw, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT, +{ctl_cnw, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT, CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE, 16, {0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0, 0x07}}, /* 8A WRITE(16) */ -{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT, +{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT, CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE, 16, {0x1a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}}, @@ -1101,13 +1099,13 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 8E WRITE AND VERIFY(16) */ -{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT, +{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT, CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE, 16, {0x12, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}}, /* 8F VERIFY(16) */ -{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_OUT | CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE, @@ -1118,17 +1116,17 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 91 SYNCHRONIZE CACHE(16) */ -{ctl_sync_cache, CTL_SERIDX_SYNC, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_sync_cache, CTL_SERIDX_SYNC, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_NONE, CTL_LUN_PAT_WRITE, - 16, {0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 16, {0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}}, /* 92 LOCK UNLOCK CACHE(16) */ {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 93 WRITE SAME(16) */ -{ctl_write_same, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_write_same, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_OUT, CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE, 16, {0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -1157,8 +1155,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = /* 9B READ BUFFER(16) */ {ctl_read_buffer, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_BOTH | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, @@ -1167,7 +1164,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}}, /* 9C WRITE ATOMIC (16) */ -{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT, +{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT, CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE, 16, {0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0xff, 0xff, 0, 0x07}}, @@ -1188,8 +1185,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = CTL_CMD_FLAG_OK_ON_BOTH | CTL_CMD_FLAG_ALLOW_ON_RESV | CTL_CMD_FLAG_NO_SENSE | - CTL_CMD_FLAG_OK_ON_STOPPED | - CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_CMD_FLAG_OK_ON_UNAVAIL | CTL_CMD_FLAG_ALLOW_ON_PR_RESV | @@ -1220,8 +1216,10 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* A8 READ(12) */ -{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN | CTL_FLAG_DATA_IN | - CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, +{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT | + CTL_CMD_FLAG_OK_ON_CDROM | + CTL_FLAG_DATA_IN | + CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE, 12, {0x1a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}}, @@ -1229,7 +1227,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* AA WRITE(12) */ -{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT, +{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT, CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE, 12, {0x1a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}}, @@ -1243,12 +1241,12 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* AE WRITE AND VERIFY(12) */ -{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT, +{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT, CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE, 12, {0x12, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}}, /* AF VERIFY(12) */ -{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_OUT | CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE, @@ -1276,7 +1274,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* B7 READ DEFECT DATA(12) */ -{ctl_read_defect, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_SLUN | +{ctl_read_defect, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_WRESV, CTL_LUN_PAT_NONE, @@ -1297,8 +1295,13 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = /* BC SPARE IN */ {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, -/* BD SPARE OUT */ -{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, +/* BD SPARE OUT / MECHANISM STATUS */ +{ctl_mechanism_status, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_CDROM | + CTL_CMD_FLAG_OK_ON_NO_MEDIA | + CTL_CMD_FLAG_ALLOW_ON_PR_RESV | + CTL_FLAG_DATA_IN, + CTL_LUN_PAT_NONE, + 12, {0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0x07}}, /* BE VOLUME SET IN */ {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, diff --git a/sys/cam/ctl/ctl_error.c b/sys/cam/ctl/ctl_error.c index 217bf30..61ec4ec 100644 --- a/sys/cam/ctl/ctl_error.c +++ b/sys/cam/ctl/ctl_error.c @@ -1,6 +1,7 @@ /*- * Copyright (c) 2003-2009 Silicon Graphics International Corp. * Copyright (c) 2011 Spectra Logic Corporation + * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -444,7 +445,7 @@ ctl_ua_to_acsq(struct ctl_lun *lun, ctl_ua_type ua_to_build, int *asc, *asc = 0x2A; *ascq = 0x06; break; - case CTL_UA_CAPACITY_CHANGED: + case CTL_UA_CAPACITY_CHANGE: /* 2Ah/09h CAPACITY DATA HAS CHANGED */ *asc = 0x2A; *ascq = 0x09; @@ -455,6 +456,11 @@ ctl_ua_to_acsq(struct ctl_lun *lun, ctl_ua_type ua_to_build, int *asc, *ascq = 0x07; *info = lun->ua_tpt_info; break; + case CTL_UA_MEDIUM_CHANGE: + /* 28h/00h NOT READY TO READY CHANGE, MEDIUM MAY HAVE CHANGED */ + *asc = 0x28; + *ascq = 0x00; + break; default: panic("%s: Unknown UA %x", __func__, ua_to_build); } @@ -606,11 +612,8 @@ ctl_set_invalid_field(struct ctl_scsiio *ctsio, int sks_valid, int command, void ctl_set_invalid_opcode(struct ctl_scsiio *ctsio) { - struct scsi_sense_data *sense; uint8_t sks[3]; - sense = &ctsio->sense_data; - sks[0] = SSD_SCS_VALID | SSD_FIELDPTR_CMD; scsi_ulto2b(0, &sks[1]); @@ -744,7 +747,7 @@ ctl_set_lun_stopped(struct ctl_scsiio *ctsio) } void -ctl_set_lun_not_ready(struct ctl_scsiio *ctsio) +ctl_set_lun_int_reqd(struct ctl_scsiio *ctsio) { /* "Logical unit not ready, manual intervention required" */ ctl_set_sense(ctsio, @@ -756,6 +759,30 @@ ctl_set_lun_not_ready(struct ctl_scsiio *ctsio) } void +ctl_set_lun_ejected(struct ctl_scsiio *ctsio) +{ + /* "Medium not present - tray open" */ + ctl_set_sense(ctsio, + /*current_error*/ 1, + /*sense_key*/ SSD_KEY_NOT_READY, + /*asc*/ 0x3A, + /*ascq*/ 0x02, + SSD_ELEM_NONE); +} + +void +ctl_set_lun_no_media(struct ctl_scsiio *ctsio) +{ + /* "Medium not present - tray closed" */ + ctl_set_sense(ctsio, + /*current_error*/ 1, + /*sense_key*/ SSD_KEY_NOT_READY, + /*asc*/ 0x3A, + /*ascq*/ 0x01, + SSD_ELEM_NONE); +} + +void ctl_set_illegal_pr_release(struct ctl_scsiio *ctsio) { /* "Invalid release of persistent reservation" */ diff --git a/sys/cam/ctl/ctl_error.h b/sys/cam/ctl/ctl_error.h index 064f621..9870643 100644 --- a/sys/cam/ctl/ctl_error.h +++ b/sys/cam/ctl/ctl_error.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 2003 Silicon Graphics International Corp. + * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -77,7 +78,9 @@ void ctl_set_medium_error(struct ctl_scsiio *ctsio, int read); void ctl_set_aborted(struct ctl_scsiio *ctsio); void ctl_set_lba_out_of_range(struct ctl_scsiio *ctsio); void ctl_set_lun_stopped(struct ctl_scsiio *ctsio); -void ctl_set_lun_not_ready(struct ctl_scsiio *ctsio); +void ctl_set_lun_int_reqd(struct ctl_scsiio *ctsio); +void ctl_set_lun_ejected(struct ctl_scsiio *ctsio); +void ctl_set_lun_no_media(struct ctl_scsiio *ctsio); void ctl_set_illegal_pr_release(struct ctl_scsiio *ctsio); void ctl_set_medium_format_corrupted(struct ctl_scsiio *ctsio); void ctl_set_medium_magazine_inaccessible(struct ctl_scsiio *ctsio); diff --git a/sys/cam/ctl/ctl_frontend.c b/sys/cam/ctl/ctl_frontend.c index 1caab65..87ed9d5 100644 --- a/sys/cam/ctl/ctl_frontend.c +++ b/sys/cam/ctl/ctl_frontend.c @@ -145,9 +145,8 @@ ctl_port_register(struct ctl_port *port) int port_num; int retval; - retval = 0; - KASSERT(softc != NULL, ("CTL is not initialized")); + port->ctl_softc = softc; mtx_lock(&softc->ctl_lock); if (port->targ_port >= 0) @@ -218,7 +217,7 @@ error: int ctl_port_deregister(struct ctl_port *port) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = port->ctl_softc; struct ctl_io_pool *pool; int retval, i; @@ -309,7 +308,7 @@ ctl_port_set_wwns(struct ctl_port *port, int wwnn_valid, uint64_t wwnn, void ctl_port_online(struct ctl_port *port) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = port->ctl_softc; struct ctl_lun *lun; uint32_t l; @@ -344,7 +343,7 @@ ctl_port_online(struct ctl_port *port) void ctl_port_offline(struct ctl_port *port) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = port->ctl_softc; struct ctl_lun *lun; uint32_t l; diff --git a/sys/cam/ctl/ctl_frontend.h b/sys/cam/ctl/ctl_frontend.h index a6ca9e1..9a1a4ee 100644 --- a/sys/cam/ctl/ctl_frontend.h +++ b/sys/cam/ctl/ctl_frontend.h @@ -211,6 +211,7 @@ struct ctl_wwpn_iid { * shouldn't touch this field. */ struct ctl_port { + struct ctl_softc *ctl_softc; struct ctl_frontend *frontend; ctl_port_type port_type; /* passed to CTL */ int num_requested_ctl_io; /* passed to CTL */ diff --git a/sys/cam/ctl/ctl_frontend_cam_sim.c b/sys/cam/ctl/ctl_frontend_cam_sim.c index 5423a17..428cf44 100644 --- a/sys/cam/ctl/ctl_frontend_cam_sim.c +++ b/sys/cam/ctl/ctl_frontend_cam_sim.c @@ -130,13 +130,9 @@ cfcs_init(void) struct cfcs_softc *softc; struct ccb_setasync csa; struct ctl_port *port; -#ifdef NEEDTOPORT - char wwnn[8]; -#endif int retval; softc = &cfcs_softc; - retval = 0; bzero(softc, sizeof(*softc)); mtx_init(&softc->lock, "ctl2cam", NULL, MTX_DEF); port = &softc->port; @@ -168,15 +164,6 @@ cfcs_init(void) } /* - * Get the WWNN out of the database, and create a WWPN as well. - */ -#ifdef NEEDTOPORT - ddb_GetWWNN((char *)wwnn); - softc->wwnn = be64dec(wwnn); - softc->wwpn = softc->wwnn + (softc->port.targ_port & 0xff); -#endif - - /* * If the CTL frontend didn't tell us what our WWNN/WWPN is, go * ahead and set something random. */ diff --git a/sys/cam/ctl/ctl_frontend_ioctl.c b/sys/cam/ctl/ctl_frontend_ioctl.c index d58fc6a..6ef2f66 100644 --- a/sys/cam/ctl/ctl_frontend_ioctl.c +++ b/sys/cam/ctl/ctl_frontend_ioctl.c @@ -56,6 +56,18 @@ __FBSDID("$FreeBSD$"); #include <cam/ctl/ctl_debug.h> #include <cam/ctl/ctl_error.h> +typedef enum { + CTL_IOCTL_INPROG, + CTL_IOCTL_DATAMOVE, + CTL_IOCTL_DONE +} ctl_fe_ioctl_state; + +struct ctl_fe_ioctl_params { + struct cv sem; + struct mtx ioctl_mtx; + ctl_fe_ioctl_state state; +}; + struct cfi_softc { uint32_t cur_tag_num; struct ctl_port port; @@ -307,10 +319,7 @@ cfi_submit_wait(union ctl_io *io) ctl_fe_ioctl_state last_state; int done, retval; - retval = 0; - bzero(¶ms, sizeof(params)); - mtx_init(¶ms.ioctl_mtx, "ctliocmtx", NULL, MTX_DEF); cv_init(¶ms.sem, "ctlioccv"); params.state = CTL_IOCTL_INPROG; diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c index 87f5787..30cca91 100644 --- a/sys/cam/ctl/ctl_frontend_iscsi.c +++ b/sys/cam/ctl/ctl_frontend_iscsi.c @@ -174,7 +174,6 @@ static void cfiscsi_target_release(struct cfiscsi_target *ct); static void cfiscsi_session_delete(struct cfiscsi_session *cs); static struct cfiscsi_softc cfiscsi_softc; -extern struct ctl_softc *control_softc; static struct ctl_frontend cfiscsi_frontend = { @@ -462,6 +461,7 @@ cfiscsi_decode_lun(uint64_t encoded) break; } result = (lun[1] << 16) + (lun[2] << 8) + lun[3]; + break; default: CFISCSI_WARN("unsupported LUN format 0x%jx", (uintmax_t)encoded); @@ -1378,10 +1378,8 @@ int cfiscsi_init(void) { struct cfiscsi_softc *softc; - int retval; softc = &cfiscsi_softc; - retval = 0; bzero(softc, sizeof(*softc)); mtx_init(&softc->lock, "cfiscsi", NULL, MTX_DEF); diff --git a/sys/cam/ctl/ctl_ha.c b/sys/cam/ctl/ctl_ha.c index 03401ae..5e31b41 100644 --- a/sys/cam/ctl/ctl_ha.c +++ b/sys/cam/ctl/ctl_ha.c @@ -160,8 +160,6 @@ struct ha_softc { TAILQ_HEAD(, ctl_ha_dt_req) ha_dts; } ha_softc; -extern struct ctl_softc *control_softc; - static void ctl_ha_conn_wake(struct ha_softc *softc) { @@ -429,6 +427,7 @@ static int ctl_ha_connect(struct ha_softc *softc) { struct thread *td = curthread; + struct sockaddr_in sa; struct socket *so; int error; @@ -442,7 +441,8 @@ ctl_ha_connect(struct ha_softc *softc) softc->ha_so = so; ctl_ha_sock_setup(softc); - error = soconnect(so, (struct sockaddr *)&softc->ha_peer_in, td); + memcpy(&sa, &softc->ha_peer_in, sizeof(sa)); + error = soconnect(so, (struct sockaddr *)&sa, td); if (error != 0) { printf("%s: soconnect() error %d\n", __func__, error); goto out; @@ -519,6 +519,7 @@ static int ctl_ha_listen(struct ha_softc *softc) { struct thread *td = curthread; + struct sockaddr_in sa; struct sockopt opt; int error, val; @@ -559,7 +560,8 @@ ctl_ha_listen(struct ha_softc *softc) SOCKBUF_UNLOCK(&softc->ha_lso->so_rcv); } - error = sobind(softc->ha_lso, (struct sockaddr *)&softc->ha_peer_in, td); + memcpy(&sa, &softc->ha_peer_in, sizeof(sa)); + error = sobind(softc->ha_lso, (struct sockaddr *)&sa, td); if (error != 0) { printf("%s: sobind() error %d\n", __func__, error); goto out; diff --git a/sys/cam/ctl/ctl_io.h b/sys/cam/ctl/ctl_io.h index 17fce7e..21db94a 100644 --- a/sys/cam/ctl/ctl_io.h +++ b/sys/cam/ctl/ctl_io.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 2003 Silicon Graphics International Corp. + * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -223,8 +224,8 @@ struct ctl_io_hdr { struct bintime start_bt; /* Timer start ticks */ struct bintime dma_start_bt; /* DMA start ticks */ struct bintime dma_bt; /* DMA total ticks */ - uint32_t num_dmas; /* Number of DMAs */ #endif /* CTL_TIME_IO */ + uint32_t num_dmas; /* Number of DMAs */ union ctl_io *original_sc; union ctl_io *serializing_sc; void *pool; /* I/O pool */ @@ -577,7 +578,6 @@ union ctl_io *ctl_alloc_io(void *pool_ref); union ctl_io *ctl_alloc_io_nowait(void *pool_ref); void ctl_free_io(union ctl_io *io); void ctl_zero_io(union ctl_io *io); -void ctl_copy_io(union ctl_io *src, union ctl_io *dest); #endif /* _KERNEL */ diff --git a/sys/cam/ctl/ctl_ioctl.h b/sys/cam/ctl/ctl_ioctl.h index a691a1d..7a6fc78 100644 --- a/sys/cam/ctl/ctl_ioctl.h +++ b/sys/cam/ctl/ctl_ioctl.h @@ -81,17 +81,6 @@ #define CTL_MINOR 225 typedef enum { - CTL_OOA_INVALID_LUN, - CTL_OOA_SUCCESS -} ctl_ooa_status; - -struct ctl_ooa_info { - uint32_t lun_id; /* Passed in to CTL */ - uint32_t num_entries; /* Returned from CTL */ - ctl_ooa_status status; /* Returned from CTL */ -}; - -typedef enum { CTL_DELAY_TYPE_NONE, CTL_DELAY_TYPE_CONT, CTL_DELAY_TYPE_ONESHOT @@ -121,22 +110,6 @@ struct ctl_io_delay_info { }; typedef enum { - CTL_GS_SYNC_NONE, - CTL_GS_SYNC_OK, - CTL_GS_SYNC_NO_LUN -} ctl_gs_sync_status; - -/* - * The target and LUN id specify which device to modify. The sync interval - * means that we will let through every N SYNCHRONIZE CACHE commands. - */ -struct ctl_sync_info { - uint32_t lun_id; /* passed to kernel */ - int sync_interval; /* depends on whether get/set */ - ctl_gs_sync_status status; /* passed from kernel */ -}; - -typedef enum { CTL_STATS_NO_IO, CTL_STATS_READ, CTL_STATS_WRITE @@ -322,23 +295,6 @@ struct ctl_ooa { }; typedef enum { - CTL_PORT_LIST_NONE, - CTL_PORT_LIST_OK, - CTL_PORT_LIST_NEED_MORE_SPACE, - CTL_PORT_LIST_ERROR -} ctl_port_list_status; - -struct ctl_port_list { - uint32_t alloc_len; /* passed to kernel */ - uint32_t alloc_num; /* passed to kernel */ - struct ctl_port_entry *entries; /* filled in kernel */ - uint32_t fill_len; /* passed to userland */ - uint32_t fill_num; /* passed to userland */ - uint32_t dropped_num; /* passed to userland */ - ctl_port_list_status status; /* passed to userland */ -}; - -typedef enum { CTL_LUN_NOSTATUS, CTL_LUN_OK, CTL_LUN_ERROR, @@ -804,18 +760,11 @@ struct ctl_lun_map { #define CTL_IO _IOWR(CTL_MINOR, 0x00, union ctl_io) #define CTL_ENABLE_PORT _IOW(CTL_MINOR, 0x04, struct ctl_port_entry) #define CTL_DISABLE_PORT _IOW(CTL_MINOR, 0x05, struct ctl_port_entry) -#define CTL_DUMP_OOA _IO(CTL_MINOR, 0x06) -#define CTL_CHECK_OOA _IOWR(CTL_MINOR, 0x07, struct ctl_ooa_info) #define CTL_DELAY_IO _IOWR(CTL_MINOR, 0x10, struct ctl_io_delay_info) -#define CTL_REALSYNC_GET _IOR(CTL_MINOR, 0x11, int) -#define CTL_REALSYNC_SET _IOW(CTL_MINOR, 0x12, int) -#define CTL_SETSYNC _IOWR(CTL_MINOR, 0x13, struct ctl_sync_info) -#define CTL_GETSYNC _IOWR(CTL_MINOR, 0x14, struct ctl_sync_info) #define CTL_GETSTATS _IOWR(CTL_MINOR, 0x15, struct ctl_stats) #define CTL_ERROR_INJECT _IOWR(CTL_MINOR, 0x16, struct ctl_error_desc) #define CTL_GET_OOA _IOWR(CTL_MINOR, 0x18, struct ctl_ooa) #define CTL_DUMP_STRUCTS _IO(CTL_MINOR, 0x19) -#define CTL_GET_PORT_LIST _IOWR(CTL_MINOR, 0x20, struct ctl_port_list) #define CTL_LUN_REQ _IOWR(CTL_MINOR, 0x21, struct ctl_lun_req) #define CTL_LUN_LIST _IOWR(CTL_MINOR, 0x22, struct ctl_lun_list) #define CTL_ERROR_INJECT_DELETE _IOW(CTL_MINOR, 0x23, struct ctl_error_desc) diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h index caa6a4b..f9b29ff 100644 --- a/sys/cam/ctl/ctl_private.h +++ b/sys/cam/ctl/ctl_private.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 2003, 2004, 2005, 2008 Silicon Graphics International Corp. + * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,26 +40,19 @@ #ifndef _CTL_PRIVATE_H_ #define _CTL_PRIVATE_H_ +#include <cam/scsi/scsi_all.h> +#include <cam/scsi/scsi_cd.h> +#include <cam/scsi/scsi_da.h> + /* * SCSI vendor and product names. */ #define CTL_VENDOR "FREEBSD " #define CTL_DIRECT_PRODUCT "CTLDISK " #define CTL_PROCESSOR_PRODUCT "CTLPROCESSOR " +#define CTL_CDROM_PRODUCT "CTLCDROM " #define CTL_UNKNOWN_PRODUCT "CTLDEVICE " -typedef enum { - CTL_IOCTL_INPROG, - CTL_IOCTL_DATAMOVE, - CTL_IOCTL_DONE -} ctl_fe_ioctl_state; - -struct ctl_fe_ioctl_params { - struct cv sem; - struct mtx ioctl_mtx; - ctl_fe_ioctl_state state; -}; - #define CTL_POOL_ENTRIES_OTHER_SC 200 struct ctl_io_pool { @@ -98,17 +92,17 @@ typedef enum { typedef enum { CTL_CMD_FLAG_NONE = 0x0000, CTL_CMD_FLAG_NO_SENSE = 0x0010, - CTL_CMD_FLAG_OK_ON_NO_LUN = 0x0020, - CTL_CMD_FLAG_ALLOW_ON_RESV = 0x0040, + CTL_CMD_FLAG_ALLOW_ON_RESV = 0x0020, + CTL_CMD_FLAG_ALLOW_ON_PR_RESV = 0x0040, CTL_CMD_FLAG_ALLOW_ON_PR_WRESV = 0x0080, CTL_CMD_FLAG_OK_ON_PROC = 0x0100, - CTL_CMD_FLAG_OK_ON_SLUN = 0x0200, - CTL_CMD_FLAG_OK_ON_BOTH = 0x0300, - CTL_CMD_FLAG_OK_ON_STOPPED = 0x0400, - CTL_CMD_FLAG_OK_ON_INOPERABLE = 0x0800, - CTL_CMD_FLAG_OK_ON_STANDBY = 0x1000, - CTL_CMD_FLAG_OK_ON_UNAVAIL = 0x2000, - CTL_CMD_FLAG_ALLOW_ON_PR_RESV = 0x4000, + CTL_CMD_FLAG_OK_ON_DIRECT = 0x0200, + CTL_CMD_FLAG_OK_ON_CDROM = 0x0400, + CTL_CMD_FLAG_OK_ON_BOTH = 0x0700, + CTL_CMD_FLAG_OK_ON_NO_LUN = 0x0800, + CTL_CMD_FLAG_OK_ON_NO_MEDIA = 0x1000, + CTL_CMD_FLAG_OK_ON_STANDBY = 0x2000, + CTL_CMD_FLAG_OK_ON_UNAVAIL = 0x4000, CTL_CMD_FLAG_SA5 = 0x8000, CTL_CMD_FLAG_RUN_HERE = 0x10000 } ctl_cmd_flags; @@ -153,13 +147,14 @@ typedef enum { CTL_LUN_DISABLED = 0x008, CTL_LUN_MALLOCED = 0x010, CTL_LUN_STOPPED = 0x020, - CTL_LUN_INOPERABLE = 0x040, - CTL_LUN_OFFLINE = 0x080, + CTL_LUN_NO_MEDIA = 0x040, + CTL_LUN_EJECTED = 0x080, CTL_LUN_PR_RESERVED = 0x100, CTL_LUN_PRIMARY_SC = 0x200, CTL_LUN_SENSE_DESC = 0x400, CTL_LUN_READONLY = 0x800, - CTL_LUN_PEER_SC_PRIMARY = 0x1000 + CTL_LUN_PEER_SC_PRIMARY = 0x1000, + CTL_LUN_REMOVABLE = 0x2000 } ctl_lun_flags; typedef enum { @@ -243,7 +238,10 @@ typedef int ctl_modesel_handler(struct ctl_scsiio *ctsio, typedef enum { CTL_PAGE_FLAG_NONE = 0x00, - CTL_PAGE_FLAG_DISK_ONLY = 0x01 + CTL_PAGE_FLAG_DIRECT = 0x01, + CTL_PAGE_FLAG_PROC = 0x02, + CTL_PAGE_FLAG_CDROM = 0x04, + CTL_PAGE_FLAG_ALL = 0x07 } ctl_page_flags; struct ctl_page_index { @@ -274,25 +272,29 @@ struct ctl_logical_block_provisioning_page { static const struct ctl_page_index page_index_template[] = { {SMS_RW_ERROR_RECOVERY_PAGE, 0, sizeof(struct scsi_da_rw_recovery_page), NULL, - CTL_PAGE_FLAG_DISK_ONLY, NULL, NULL}, + CTL_PAGE_FLAG_DIRECT | CTL_PAGE_FLAG_CDROM, NULL, NULL}, {SMS_FORMAT_DEVICE_PAGE, 0, sizeof(struct scsi_format_page), NULL, - CTL_PAGE_FLAG_DISK_ONLY, NULL, NULL}, + CTL_PAGE_FLAG_DIRECT, NULL, NULL}, {SMS_RIGID_DISK_PAGE, 0, sizeof(struct scsi_rigid_disk_page), NULL, - CTL_PAGE_FLAG_DISK_ONLY, NULL, NULL}, + CTL_PAGE_FLAG_DIRECT, NULL, NULL}, {SMS_CACHING_PAGE, 0, sizeof(struct scsi_caching_page), NULL, - CTL_PAGE_FLAG_DISK_ONLY, NULL, ctl_caching_sp_handler}, + CTL_PAGE_FLAG_DIRECT | CTL_PAGE_FLAG_CDROM, + NULL, ctl_caching_sp_handler}, {SMS_CONTROL_MODE_PAGE, 0, sizeof(struct scsi_control_page), NULL, - CTL_PAGE_FLAG_NONE, NULL, ctl_control_page_handler}, + CTL_PAGE_FLAG_ALL, NULL, ctl_control_page_handler}, {SMS_CONTROL_MODE_PAGE | SMPH_SPF, 0x01, sizeof(struct scsi_control_ext_page), NULL, - CTL_PAGE_FLAG_NONE, NULL, NULL}, + CTL_PAGE_FLAG_ALL, NULL, NULL}, {SMS_INFO_EXCEPTIONS_PAGE, 0, sizeof(struct scsi_info_exceptions_page), NULL, - CTL_PAGE_FLAG_NONE, NULL, NULL}, + CTL_PAGE_FLAG_ALL, NULL, NULL}, {SMS_INFO_EXCEPTIONS_PAGE | SMPH_SPF, 0x02, sizeof(struct ctl_logical_block_provisioning_page), NULL, - CTL_PAGE_FLAG_DISK_ONLY, NULL, NULL}, + CTL_PAGE_FLAG_DIRECT, NULL, NULL}, + {SMS_CDDVD_CAPS_PAGE, 0, + sizeof(struct scsi_cddvd_capabilities_page), NULL, + CTL_PAGE_FLAG_CDROM, NULL, NULL}, {SMS_VENDOR_SPECIFIC_PAGE | SMPH_SPF, DBGCNF_SUBPAGE_CODE, - sizeof(struct copan_debugconf_subpage), NULL, CTL_PAGE_FLAG_NONE, + sizeof(struct copan_debugconf_subpage), NULL, CTL_PAGE_FLAG_ALL, ctl_debugconf_sp_sense_handler, ctl_debugconf_sp_select_handler}, }; @@ -308,19 +310,20 @@ struct ctl_mode_pages { struct scsi_control_ext_page control_ext_page[4]; struct scsi_info_exceptions_page ie_page[4]; struct ctl_logical_block_provisioning_page lbp_page[4]; + struct scsi_cddvd_capabilities_page cddvd_page[4]; struct copan_debugconf_subpage debugconf_subpage[4]; struct ctl_page_index index[CTL_NUM_MODE_PAGES]; }; static const struct ctl_page_index log_page_index_template[] = { {SLS_SUPPORTED_PAGES_PAGE, 0, 0, NULL, - CTL_PAGE_FLAG_NONE, NULL, NULL}, + CTL_PAGE_FLAG_ALL, NULL, NULL}, {SLS_SUPPORTED_PAGES_PAGE, SLS_SUPPORTED_SUBPAGES_SUBPAGE, 0, NULL, - CTL_PAGE_FLAG_NONE, NULL, NULL}, + CTL_PAGE_FLAG_ALL, NULL, NULL}, {SLS_LOGICAL_BLOCK_PROVISIONING, 0, 0, NULL, - CTL_PAGE_FLAG_NONE, ctl_lbp_log_sense_handler, NULL}, + CTL_PAGE_FLAG_DIRECT, ctl_lbp_log_sense_handler, NULL}, {SLS_STAT_AND_PERF, 0, 0, NULL, - CTL_PAGE_FLAG_NONE, ctl_sap_log_sense_handler, NULL}, + CTL_PAGE_FLAG_ALL, ctl_sap_log_sense_handler, NULL}, }; #define CTL_NUM_LOG_PAGES sizeof(log_page_index_template)/ \ @@ -345,17 +348,6 @@ struct ctl_lun_delay_info { uint32_t done_delay; }; -typedef enum { - CTL_ERR_INJ_NONE = 0x00, - CTL_ERR_INJ_ABORTED = 0x01 -} ctl_err_inject_flags; - -typedef enum { - CTL_PR_FLAG_NONE = 0x00, - CTL_PR_FLAG_REGISTERED = 0x01, - CTL_PR_FLAG_ACTIVE_RES = 0x02 -} ctl_per_res_flags; - #define CTL_PR_ALL_REGISTRANTS 0xFFFFFFFF #define CTL_PR_NO_RESERVATION 0xFFFFFFF0 @@ -381,10 +373,7 @@ struct ctl_lun { struct ctl_softc *ctl_softc; struct ctl_be_lun *be_lun; struct ctl_backend_driver *backend; - int io_count; struct ctl_lun_delay_info delay_info; - int sync_interval; - int sync_count; #ifdef CTL_TIME_IO sbintime_t idle_time; sbintime_t last_busy; @@ -392,7 +381,6 @@ struct ctl_lun { TAILQ_HEAD(ctl_ooaq, ctl_io_hdr) ooa_queue; TAILQ_HEAD(ctl_blockq,ctl_io_hdr) blocked_queue; STAILQ_ENTRY(ctl_lun) links; - STAILQ_ENTRY(ctl_lun) run_links; #ifdef CTL_WITH_CA uint32_t have_ca[CTL_MAX_INITIATORS >> 5]; struct scsi_sense_data pending_sense[CTL_MAX_INITIATORS]; @@ -404,18 +392,19 @@ struct ctl_lun { struct ctl_log_pages log_pages; struct ctl_lun_io_stats stats; uint32_t res_idx; - unsigned int PRGeneration; + uint32_t pr_generation; uint64_t *pr_keys[CTL_MAX_PORTS]; int pr_key_count; uint32_t pr_res_idx; - uint8_t res_type; + uint8_t pr_res_type; + int prevent_count; + uint32_t prevent[(CTL_MAX_INITIATORS+31)/32]; uint8_t *write_buffer; struct ctl_devid *lun_devid; TAILQ_HEAD(tpc_lists, tpc_list) tpc_lists; }; typedef enum { - CTL_FLAG_REAL_SYNC = 0x02, CTL_FLAG_ACTIVE_SHELF = 0x04 } ctl_gen_flags; @@ -435,8 +424,6 @@ struct tpc_token; struct ctl_softc { struct mtx ctl_lock; struct cdev *dev; - int open_count; - int num_disks; int num_luns; ctl_gen_flags flags; ctl_ha_mode ha_mode; @@ -452,7 +439,6 @@ struct ctl_softc { struct sysctl_oid *sysctl_tree; void *othersc_pool; struct proc *ctl_proc; - int targ_online; uint32_t ctl_lun_mask[(CTL_MAX_LUNS + 31) / 32]; struct ctl_lun *ctl_luns[CTL_MAX_LUNS]; uint32_t ctl_port_mask[(CTL_MAX_PORTS + 31) / 32]; @@ -490,6 +476,7 @@ void ctl_pool_free(struct ctl_io_pool *pool); int ctl_scsi_release(struct ctl_scsiio *ctsio); int ctl_scsi_reserve(struct ctl_scsiio *ctsio); int ctl_start_stop(struct ctl_scsiio *ctsio); +int ctl_prevent_allow(struct ctl_scsiio *ctsio); int ctl_sync_cache(struct ctl_scsiio *ctsio); int ctl_format(struct ctl_scsiio *ctsio); int ctl_read_buffer(struct ctl_scsiio *ctsio); @@ -502,6 +489,7 @@ int ctl_log_sense(struct ctl_scsiio *ctsio); int ctl_read_capacity(struct ctl_scsiio *ctsio); int ctl_read_capacity_16(struct ctl_scsiio *ctsio); int ctl_read_defect(struct ctl_scsiio *ctsio); +int ctl_read_toc(struct ctl_scsiio *ctsio); int ctl_read_write(struct ctl_scsiio *ctsio); int ctl_cnw(struct ctl_scsiio *ctsio); int ctl_report_luns(struct ctl_scsiio *ctsio); @@ -509,6 +497,9 @@ int ctl_request_sense(struct ctl_scsiio *ctsio); int ctl_tur(struct ctl_scsiio *ctsio); int ctl_verify(struct ctl_scsiio *ctsio); int ctl_inquiry(struct ctl_scsiio *ctsio); +int ctl_get_config(struct ctl_scsiio *ctsio); +int ctl_get_event_status(struct ctl_scsiio *ctsio); +int ctl_mechanism_status(struct ctl_scsiio *ctsio); int ctl_persistent_reserve_in(struct ctl_scsiio *ctsio); int ctl_persistent_reserve_out(struct ctl_scsiio *ctsio); int ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio); diff --git a/sys/cam/ctl/ctl_ser_table.c b/sys/cam/ctl/ctl_ser_table.c index 8d5d6bc..ef0ee2f 100644 --- a/sys/cam/ctl/ctl_ser_table.c +++ b/sys/cam/ctl/ctl_ser_table.c @@ -61,7 +61,7 @@ #define xO CTL_SER_EXTENTOPT /* Optional extent check */ #define xS CTL_SER_EXTENTSEQ /* Sequential extent check */ -static ctl_serialize_action +const static ctl_serialize_action ctl_serialize_table[CTL_SERIDX_COUNT][CTL_SERIDX_COUNT] = { /**>IDX_ :: 2nd:TUR RD WRT UNM SYN MDSN MDSL RQSN INQ RDCP RES LSNS FMT STR*/ /*TUR */{ pS, pS, pS, pS, pS, bK, bK, bK, pS, pS, bK, pS, bK, bK}, diff --git a/sys/cam/ctl/ctl_tpc.c b/sys/cam/ctl/ctl_tpc.c index 0b8879d..6aa2080 100644 --- a/sys/cam/ctl/ctl_tpc.c +++ b/sys/cam/ctl/ctl_tpc.c @@ -837,7 +837,7 @@ tpc_process_b2b(struct tpc_list *list) ctl_set_sense(list->ctsio, /*current_error*/ 1, /*sense_key*/ SSD_KEY_COPY_ABORTED, /*asc*/ 0x0d, /*ascq*/ 0x01, - SSD_ELEM_COMMAND, csi, sizeof(csi), + SSD_ELEM_COMMAND, sizeof(csi), csi, SSD_ELEM_NONE); return (CTL_RETVAL_ERROR); } @@ -854,7 +854,7 @@ tpc_process_b2b(struct tpc_list *list) ctl_set_sense(list->ctsio, /*current_error*/ 1, /*sense_key*/ SSD_KEY_COPY_ABORTED, /*asc*/ 0x08, /*ascq*/ 0x04, - SSD_ELEM_COMMAND, csi, sizeof(csi), + SSD_ELEM_COMMAND, sizeof(csi), csi, SSD_ELEM_NONE); return (CTL_RETVAL_ERROR); } @@ -885,7 +885,7 @@ tpc_process_b2b(struct tpc_list *list) ctl_set_sense(list->ctsio, /*current_error*/ 1, /*sense_key*/ SSD_KEY_COPY_ABORTED, /*asc*/ 0x26, /*ascq*/ 0x0A, - SSD_ELEM_COMMAND, csi, sizeof(csi), + SSD_ELEM_COMMAND, sizeof(csi), csi, SSD_ELEM_NONE); return (CTL_RETVAL_ERROR); } @@ -986,7 +986,7 @@ tpc_process_verify(struct tpc_list *list) ctl_set_sense(list->ctsio, /*current_error*/ 1, /*sense_key*/ SSD_KEY_COPY_ABORTED, /*asc*/ 0x0d, /*ascq*/ 0x01, - SSD_ELEM_COMMAND, csi, sizeof(csi), + SSD_ELEM_COMMAND, sizeof(csi), csi, SSD_ELEM_NONE); return (CTL_RETVAL_ERROR); } else @@ -1000,7 +1000,7 @@ tpc_process_verify(struct tpc_list *list) ctl_set_sense(list->ctsio, /*current_error*/ 1, /*sense_key*/ SSD_KEY_COPY_ABORTED, /*asc*/ 0x08, /*ascq*/ 0x04, - SSD_ELEM_COMMAND, csi, sizeof(csi), + SSD_ELEM_COMMAND, sizeof(csi), csi, SSD_ELEM_NONE); return (CTL_RETVAL_ERROR); } @@ -1050,7 +1050,7 @@ tpc_process_register_key(struct tpc_list *list) ctl_set_sense(list->ctsio, /*current_error*/ 1, /*sense_key*/ SSD_KEY_COPY_ABORTED, /*asc*/ 0x0d, /*ascq*/ 0x01, - SSD_ELEM_COMMAND, csi, sizeof(csi), + SSD_ELEM_COMMAND, sizeof(csi), csi, SSD_ELEM_NONE); return (CTL_RETVAL_ERROR); } else @@ -1064,7 +1064,7 @@ tpc_process_register_key(struct tpc_list *list) ctl_set_sense(list->ctsio, /*current_error*/ 1, /*sense_key*/ SSD_KEY_COPY_ABORTED, /*asc*/ 0x08, /*ascq*/ 0x04, - SSD_ELEM_COMMAND, csi, sizeof(csi), + SSD_ELEM_COMMAND, sizeof(csi), csi, SSD_ELEM_NONE); return (CTL_RETVAL_ERROR); } @@ -1295,7 +1295,6 @@ complete: ctl_free_io(tio->io); free(tio, M_CTL); } - free(list->buf, M_CTL); if (list->abort) { ctl_set_task_aborted(list->ctsio); return (CTL_RETVAL_ERROR); @@ -1311,7 +1310,6 @@ complete: } dstblock = list->lun->be_lun->blocksize; - list->buf = malloc(dstblock, M_CTL, M_WAITOK | M_ZERO); TAILQ_INIT(&run); prun = &run; list->tbdio = 1; @@ -1328,9 +1326,9 @@ complete: TAILQ_INSERT_TAIL(&list->allio, tiow, links); tiow->io = tpcl_alloc_io(); ctl_scsi_write_same(tiow->io, - /*data_ptr*/ list->buf, - /*data_len*/ dstblock, - /*byte2*/ 0, + /*data_ptr*/ NULL, + /*data_len*/ 0, + /*byte2*/ SWS_NDOB, /*lba*/ scsi_8btou64(list->range[r].lba), /*num_blocks*/ len, /*tag_type*/ CTL_TAG_SIMPLE, @@ -1398,7 +1396,7 @@ tpc_process(struct tpc_list *list) ctl_set_sense(ctsio, /*current_error*/ 1, /*sense_key*/ SSD_KEY_COPY_ABORTED, /*asc*/ 0x26, /*ascq*/ 0x09, - SSD_ELEM_COMMAND, csi, sizeof(csi), + SSD_ELEM_COMMAND, sizeof(csi), csi, SSD_ELEM_NONE); goto done; } diff --git a/sys/cam/ctl/ctl_tpc_local.c b/sys/cam/ctl/ctl_tpc_local.c index 5c566dd..4f368f9 100644 --- a/sys/cam/ctl/ctl_tpc_local.c +++ b/sys/cam/ctl/ctl_tpc_local.c @@ -142,10 +142,6 @@ tpcl_datamove(union ctl_io *io) struct ctl_scsiio *ctsio; int i, j; - ext_sg_start = 0; - ext_offset = 0; - ext_sglist = NULL; - CTL_DEBUG_PRINT(("%s\n", __func__)); ctsio = &io->scsiio; diff --git a/sys/cam/ctl/ctl_util.c b/sys/cam/ctl/ctl_util.c index d501b57..6fcec03 100644 --- a/sys/cam/ctl/ctl_util.c +++ b/sys/cam/ctl/ctl_util.c @@ -489,8 +489,7 @@ ctl_scsi_mode_sense(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, void ctl_scsi_start_stop(union ctl_io *io, int start, int load_eject, int immediate, - int power_conditions, int onoffline __unused, - ctl_tag_type tag_type, uint8_t control) + int power_conditions, ctl_tag_type tag_type, uint8_t control) { struct scsi_start_stop_unit *cdb; @@ -501,10 +500,6 @@ ctl_scsi_start_stop(union ctl_io *io, int start, int load_eject, int immediate, cdb->opcode = START_STOP_UNIT; if (immediate) cdb->byte2 |= SSS_IMMED; -#ifdef NEEDTOPORT - if (onoffline) - cdb->byte2 |= SSS_ONOFFLINE; -#endif cdb->how = power_conditions; if (load_eject) cdb->how |= SSS_LOEJ; @@ -849,24 +844,8 @@ void ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data) { char str[512]; -#ifdef NEEDTOPORT - char *message; - char *line; - - message = io_error_string(io, inq_data, str, sizeof(str)); - - for (line = strsep(&message, "\n"); line != NULL; - line = strsep(&message, "\n")) { - csevent_log(CSC_CTL | CSC_SHELF_SW | CTL_ERROR_REPORT, - csevent_LogType_Trace, - csevent_Severity_Information, - csevent_AlertLevel_Green, - csevent_FRU_Firmware, - csevent_FRU_Unknown, "%s", line); - } -#else + printf("%s", ctl_io_error_string(io, inq_data, str, sizeof(str))); -#endif } diff --git a/sys/cam/ctl/ctl_util.h b/sys/cam/ctl/ctl_util.h index b1c0d84..2966b49 100644 --- a/sys/cam/ctl/ctl_util.h +++ b/sys/cam/ctl/ctl_util.h @@ -77,7 +77,7 @@ void ctl_scsi_mode_sense(union ctl_io *io, uint8_t *data_ptr, int minimum_cdb_size, ctl_tag_type tag_type, uint8_t control); void ctl_scsi_start_stop(union ctl_io *io, int start, int load_eject, - int immediate, int power_conditions, int onoffline, + int immediate, int power_conditions, ctl_tag_type tag_type, uint8_t control); void ctl_scsi_sync_cache(union ctl_io *io, int immed, int reladr, int minimum_cdb_size, uint64_t starting_lba, diff --git a/sys/cam/scsi/scsi_cd.h b/sys/cam/scsi/scsi_cd.h index f502d66..cf8baaf 100644 --- a/sys/cam/scsi/scsi_cd.h +++ b/sys/cam/scsi/scsi_cd.h @@ -56,6 +56,83 @@ * SCSI command format */ +struct scsi_get_config +{ + uint8_t opcode; + uint8_t rt; +#define SGC_RT_ALL 0x00 +#define SGC_RT_CURRENT 0x01 +#define SGC_RT_SPECIFIC 0x02 +#define SGC_RT_MASK 0x03 + uint8_t starting_feature[2]; + uint8_t reserved[3]; + uint8_t length[2]; + uint8_t control; +}; + +struct scsi_get_config_header +{ + uint8_t data_length[4]; + uint8_t reserved[2]; + uint8_t current_profile[2]; +}; + +struct scsi_get_config_feature +{ + uint8_t feature_code[2]; + uint8_t flags; +#define SGC_F_CURRENT 0x01 +#define SGC_F_PERSISTENT 0x02 +#define SGC_F_VERSION_MASK 0x2C +#define SGC_F_VERSION_SHIFT 2 + uint8_t add_length; + uint8_t feature_data[]; +}; + +struct scsi_get_event_status +{ + uint8_t opcode; + uint8_t byte2; +#define SGESN_POLLED 1 + uint8_t reserved[2]; + uint8_t notif_class; + uint8_t reserved2[2]; + uint8_t length[2]; + uint8_t control; +}; + +struct scsi_get_event_status_header +{ + uint8_t descr_length[4]; + uint8_t nea_class; +#define SGESN_NEA 0x80 + uint8_t supported_class; +}; + +struct scsi_get_event_status_descr +{ + uint8_t event_code; + uint8_t event_info[]; +}; + +struct scsi_mechanism_status +{ + uint8_t opcode; + uint8_t reserved[7]; + uint8_t length[2]; + uint8_t reserved2; + uint8_t control; +}; + +struct scsi_mechanism_status_header +{ + uint8_t state1; + uint8_t state2; + uint8_t lba[3]; + uint8_t slots_num; + uint8_t slots_length[2]; +}; + struct scsi_pause { u_int8_t op_code; @@ -151,12 +228,29 @@ struct scsi_read_toc { u_int8_t op_code; u_int8_t byte2; - u_int8_t unused[4]; + u_int8_t format; + u_int8_t unused[3]; u_int8_t from_track; u_int8_t data_len[2]; u_int8_t control; }; +struct scsi_read_toc_hdr +{ + uint8_t data_length[2]; + uint8_t first; + uint8_t last; +}; + +struct scsi_read_toc_type01_descr +{ + uint8_t reserved; + uint8_t addr_ctl; + uint8_t track_number; + uint8_t reserved2; + uint8_t track_start[4]; +}; + struct scsi_read_cd_capacity { u_int8_t op_code; @@ -252,9 +346,11 @@ struct scsi_read_dvd_structure #define READ_TOC 0x43 /* cdrom read TOC */ #define READ_HEADER 0x44 /* cdrom read header */ #define PLAY_10 0x45 /* cdrom play 'play audio' mode */ +#define GET_CONFIGURATION 0x46 /* Get device configuration */ #define PLAY_MSF 0x47 /* cdrom play Min,Sec,Frames mode */ #define PLAY_TRACK 0x48 /* cdrom play track/index mode */ #define PLAY_TRACK_REL 0x49 /* cdrom play track/index mode */ +#define GET_EVENT_STATUS 0x4a /* Get event status notification */ #define PAUSE 0x4b /* cdrom pause in 'play audio' mode */ #define SEND_KEY 0xa3 /* dvd send key command */ #define REPORT_KEY 0xa4 /* dvd report key command */ @@ -262,6 +358,7 @@ struct scsi_read_dvd_structure #define PLAY_TRACK_REL_BIG 0xa9 /* cdrom play track/index mode */ #define READ_DVD_STRUCTURE 0xad /* read dvd structure */ #define SET_CD_SPEED 0xbb /* set c/dvd speed */ +#define MECHANISM_STATUS 0xbd /* get status of c/dvd mechanics */ struct scsi_report_key_data_header { @@ -686,6 +783,37 @@ struct cd_audio_page #define RIGHT_PORT 1 }; +struct scsi_cddvd_capabilities_page_sd { + uint8_t reserved; + uint8_t rotation_control; + uint8_t write_speed_supported[2]; +}; + +struct scsi_cddvd_capabilities_page { + uint8_t page_code; +#define SMS_CDDVD_CAPS_PAGE 0x2a + uint8_t page_length; + uint8_t caps1; + uint8_t caps2; + uint8_t caps3; + uint8_t caps4; + uint8_t caps5; + uint8_t caps6; + uint8_t obsolete[2]; + uint8_t nvol_levels[2]; + uint8_t buffer_size[2]; + uint8_t obsolete2[2]; + uint8_t reserved; + uint8_t digital; + uint8_t obsolete3; + uint8_t copy_management; + uint8_t reserved2; + uint8_t rotation_control; + uint8_t cur_write_speed; + uint8_t num_speed_descr; + struct scsi_cddvd_capabilities_page_sd speed_descr[]; +}; + union cd_pages { struct cd_audio_page audio; diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c index 584b6b3..055291b 100644 --- a/sys/cam/scsi/scsi_pass.c +++ b/sys/cam/scsi/scsi_pass.c @@ -77,6 +77,7 @@ struct pass_softc { u_int8_t pd_type; union ccb saved_ccb; int open_count; + u_int maxio; struct devstat *device_stats; struct cdev *dev; struct cdev *alias_dev; @@ -366,6 +367,13 @@ passregister(struct cam_periph *periph, void *arg) cpi.ccb_h.func_code = XPT_PATH_INQ; xpt_action((union ccb *)&cpi); + if (cpi.maxio == 0) + softc->maxio = DFLTPHYS; /* traditional default */ + else if (cpi.maxio > MAXPHYS) + softc->maxio = MAXPHYS; /* for safety */ + else + softc->maxio = cpi.maxio; /* real value */ + /* * We pass in 0 for a blocksize, since we don't * know what the blocksize of this device is, if @@ -657,7 +665,7 @@ passsendccb(struct cam_periph *periph, union ccb *ccb, union ccb *inccb) * Dropping it here is reasonably safe. */ cam_periph_unlock(periph); - error = cam_periph_mapmem(ccb, &mapinfo); + error = cam_periph_mapmem(ccb, &mapinfo, softc->maxio); cam_periph_lock(periph); /* diff --git a/sys/cam/scsi/scsi_sg.c b/sys/cam/scsi/scsi_sg.c index 3e80ac3..3e13003 100644 --- a/sys/cam/scsi/scsi_sg.c +++ b/sys/cam/scsi/scsi_sg.c @@ -99,6 +99,7 @@ struct sg_softc { sg_state state; sg_flags flags; int open_count; + u_int maxio; struct devstat *device_stats; TAILQ_HEAD(, sg_rdwr) rdwr_done; struct cdev *dev; @@ -325,6 +326,13 @@ sgregister(struct cam_periph *periph, void *arg) cpi.ccb_h.func_code = XPT_PATH_INQ; xpt_action((union ccb *)&cpi); + if (cpi.maxio == 0) + softc->maxio = DFLTPHYS; /* traditional default */ + else if (cpi.maxio > MAXPHYS) + softc->maxio = MAXPHYS; /* for safety */ + else + softc->maxio = cpi.maxio; /* real value */ + /* * We pass in 0 for all blocksize, since we don't know what the * blocksize of the device is, if it even has a blocksize. @@ -894,7 +902,7 @@ sgsendccb(struct cam_periph *periph, union ccb *ccb) * need for additional checks. */ cam_periph_unlock(periph); - error = cam_periph_mapmem(ccb, &mapinfo); + error = cam_periph_mapmem(ccb, &mapinfo, softc->maxio); cam_periph_lock(periph); if (error) return (error); diff --git a/sys/cam/scsi/scsi_target.c b/sys/cam/scsi/scsi_target.c index 42dc152..f2504ab 100644 --- a/sys/cam/scsi/scsi_target.c +++ b/sys/cam/scsi/scsi_target.c @@ -94,6 +94,7 @@ struct targ_softc { struct cam_periph *periph; struct cam_path *path; targ_state state; + u_int maxio; struct selinfo read_select; struct devstat device_stats; }; @@ -403,6 +404,12 @@ targenable(struct targ_softc *softc, struct cam_path *path, int grp6_len, status = CAM_FUNC_NOTAVAIL; goto enable_fail; } + if (cpi.maxio == 0) + softc->maxio = DFLTPHYS; /* traditional default */ + else if (cpi.maxio > MAXPHYS) + softc->maxio = MAXPHYS; /* for safety */ + else + softc->maxio = cpi.maxio; /* real value */ /* Destroy any periph on our path if it is disabled */ periph = cam_periph_find(path, "targ"); @@ -725,7 +732,7 @@ targsendccb(struct targ_softc *softc, union ccb *ccb, if ((ccb_h->func_code == XPT_CONT_TARGET_IO) || (ccb_h->func_code == XPT_DEV_MATCH)) { - error = cam_periph_mapmem(ccb, mapinfo); + error = cam_periph_mapmem(ccb, mapinfo, softc->maxio); /* * cam_periph_mapmem returned an error, we can't continue. diff --git a/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c b/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c index cd6af4e..7038f7f 100644 --- a/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c +++ b/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c @@ -44,6 +44,14 @@ #endif #define skip_whitespace(p) while ((*(p) == ' ') || (*(p) == '\t')) p++ +#if defined(__FreeBSD__) && !defined(_KERNEL) +/* + * libnvpair is the lowest commen denominator for ZFS related libraries, + * defining aok here makes it usable by all ZFS related libraries + */ +int aok; +#endif + /* * nvpair.c - Provides kernel & userland interfaces for manipulating * name-value pairs. diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c index cf2f7bb..4b356d7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c +++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c @@ -155,7 +155,7 @@ int dtrace_destructive_disallow = 0; dtrace_optval_t dtrace_nonroot_maxsize = (16 * 1024 * 1024); size_t dtrace_difo_maxsize = (256 * 1024); dtrace_optval_t dtrace_dof_maxsize = (8 * 1024 * 1024); -size_t dtrace_global_maxsize = (16 * 1024); +size_t dtrace_statvar_maxsize = (16 * 1024); size_t dtrace_actions_max = (16 * 1024); size_t dtrace_retain_max = 1024; dtrace_optval_t dtrace_helper_actions_max = 128; @@ -699,13 +699,33 @@ dtrace_canstore_statvar(uint64_t addr, size_t sz, dtrace_statvar_t **svars, int nsvars) { int i; + size_t maxglobalsize, maxlocalsize; + + if (nsvars == 0) + return (0); + + maxglobalsize = dtrace_statvar_maxsize; + maxlocalsize = (maxglobalsize + sizeof (uint64_t)) * NCPU; for (i = 0; i < nsvars; i++) { dtrace_statvar_t *svar = svars[i]; + uint8_t scope; + size_t size; - if (svar == NULL || svar->dtsv_size == 0) + if (svar == NULL || (size = svar->dtsv_size) == 0) continue; + scope = svar->dtsv_var.dtdv_scope; + + /* + * We verify that our size is valid in the spirit of providing + * defense in depth: we want to prevent attackers from using + * DTrace to escalate an orthogonal kernel heap corruption bug + * into the ability to store to arbitrary locations in memory. + */ + VERIFY((scope == DIFV_SCOPE_GLOBAL && size < maxglobalsize) || + (scope == DIFV_SCOPE_LOCAL && size < maxlocalsize)); + if (DTRACE_INRANGE(addr, sz, svar->dtsv_data, svar->dtsv_size)) return (1); } @@ -4455,7 +4475,8 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, if (!dtrace_destructive_disallow && dtrace_priv_proc_control(state) && - !dtrace_istoxic(kaddr, size)) { + !dtrace_istoxic(kaddr, size) && + dtrace_canload(kaddr, size, mstate, vstate)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); dtrace_copyout(kaddr, uaddr, size, flags); DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); @@ -4470,7 +4491,8 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, if (!dtrace_destructive_disallow && dtrace_priv_proc_control(state) && - !dtrace_istoxic(kaddr, size)) { + !dtrace_istoxic(kaddr, size) && + dtrace_strcanload(kaddr, size, mstate, vstate)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); dtrace_copyoutstr(kaddr, uaddr, size, flags); DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); @@ -6458,6 +6480,11 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, regs[r2] ? regs[r2] : dtrace_strsize_default) + 1; } else { + if (regs[r2] > LONG_MAX) { + *flags |= CPU_DTRACE_ILLOP; + break; + } + tupregs[ttop].dttk_size = regs[r2]; } @@ -9915,9 +9942,10 @@ dtrace_difo_validate(dtrace_difo_t *dp, dtrace_vstate_t *vstate, uint_t nregs, break; } - if (v->dtdv_scope == DIFV_SCOPE_GLOBAL && - vt->dtdt_size > dtrace_global_maxsize) { - err += efunc(i, "oversized by-ref global\n"); + if ((v->dtdv_scope == DIFV_SCOPE_GLOBAL || + v->dtdv_scope == DIFV_SCOPE_LOCAL) && + vt->dtdt_size > dtrace_statvar_maxsize) { + err += efunc(i, "oversized by-ref static\n"); break; } } @@ -10261,6 +10289,9 @@ dtrace_difo_chunksize(dtrace_difo_t *dp, dtrace_vstate_t *vstate) if (srd == 0) return; + if (sval > LONG_MAX) + return; + tupregs[ttop++].dttk_size = sval; } @@ -10322,6 +10353,19 @@ dtrace_difo_chunksize(dtrace_difo_t *dp, dtrace_vstate_t *vstate) */ size = P2ROUNDUP(size, sizeof (uint64_t)); + /* + * Before setting the chunk size, check that we're not going + * to set it to a negative value... + */ + if (size > LONG_MAX) + return; + + /* + * ...and make certain that we didn't badly overflow. + */ + if (size < ksize || size < sizeof (dtrace_dynvar_t)) + return; + if (size > vstate->dtvs_dynvars.dtds_chunksize) vstate->dtvs_dynvars.dtds_chunksize = size; } @@ -13942,6 +13986,8 @@ dtrace_dstate_init(dtrace_dstate_t *dstate, size_t size) if ((dstate->dtds_chunksize = chunksize) == 0) dstate->dtds_chunksize = DTRACE_DYNVAR_CHUNKSIZE; + VERIFY(dstate->dtds_chunksize < LONG_MAX); + if (size < (min = dstate->dtds_chunksize + sizeof (dtrace_dynhash_t))) size = min; @@ -13982,6 +14028,9 @@ dtrace_dstate_init(dtrace_dstate_t *dstate, size_t size) ((uintptr_t)base + hashsize * sizeof (dtrace_dynhash_t)); limit = (uintptr_t)base + size; + VERIFY((uintptr_t)start < limit); + VERIFY((uintptr_t)start >= (uintptr_t)base); + maxper = (limit - (uintptr_t)start) / NCPU; maxper = (maxper / dstate->dtds_chunksize) * dstate->dtds_chunksize; @@ -14007,7 +14056,7 @@ dtrace_dstate_init(dtrace_dstate_t *dstate, size_t size) start = (dtrace_dynvar_t *)limit; } - ASSERT(limit <= (uintptr_t)base + size); + VERIFY(limit <= (uintptr_t)base + size); for (;;) { next = (dtrace_dynvar_t *)((uintptr_t)dvar + @@ -14016,6 +14065,8 @@ dtrace_dstate_init(dtrace_dstate_t *dstate, size_t size) if ((uintptr_t)next + dstate->dtds_chunksize >= limit) break; + VERIFY((uintptr_t)dvar >= (uintptr_t)base && + (uintptr_t)dvar <= (uintptr_t)base + size); dvar->dtdv_next = next; dvar = next; } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c index 9ad18f0..f84ff37 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c @@ -680,40 +680,8 @@ dmu_objset_evict(objset_t *os) for (int t = 0; t < TXG_SIZE; t++) ASSERT(!dmu_objset_is_dirty(os, t)); - if (ds) { - if (!ds->ds_is_snapshot) { - VERIFY0(dsl_prop_unregister(ds, - zfs_prop_to_name(ZFS_PROP_CHECKSUM), - checksum_changed_cb, os)); - VERIFY0(dsl_prop_unregister(ds, - zfs_prop_to_name(ZFS_PROP_COMPRESSION), - compression_changed_cb, os)); - VERIFY0(dsl_prop_unregister(ds, - zfs_prop_to_name(ZFS_PROP_COPIES), - copies_changed_cb, os)); - VERIFY0(dsl_prop_unregister(ds, - zfs_prop_to_name(ZFS_PROP_DEDUP), - dedup_changed_cb, os)); - VERIFY0(dsl_prop_unregister(ds, - zfs_prop_to_name(ZFS_PROP_LOGBIAS), - logbias_changed_cb, os)); - VERIFY0(dsl_prop_unregister(ds, - zfs_prop_to_name(ZFS_PROP_SYNC), - sync_changed_cb, os)); - VERIFY0(dsl_prop_unregister(ds, - zfs_prop_to_name(ZFS_PROP_REDUNDANT_METADATA), - redundant_metadata_changed_cb, os)); - VERIFY0(dsl_prop_unregister(ds, - zfs_prop_to_name(ZFS_PROP_RECORDSIZE), - recordsize_changed_cb, os)); - } - VERIFY0(dsl_prop_unregister(ds, - zfs_prop_to_name(ZFS_PROP_PRIMARYCACHE), - primary_cache_changed_cb, os)); - VERIFY0(dsl_prop_unregister(ds, - zfs_prop_to_name(ZFS_PROP_SECONDARYCACHE), - secondary_cache_changed_cb, os)); - } + if (ds) + dsl_prop_unregister_all(ds, os); if (os->os_sa) sa_tear_down(os); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c index f4fdaf9..4fbbe7c 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c @@ -288,6 +288,7 @@ dsl_dataset_evict(void *dbu) ASSERT(!list_link_active(&ds->ds_synced_link)); + list_destroy(&ds->ds_prop_cbs); if (mutex_owned(&ds->ds_lock)) mutex_exit(&ds->ds_lock); mutex_destroy(&ds->ds_lock); @@ -434,6 +435,9 @@ dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag, list_create(&ds->ds_sendstreams, sizeof (dmu_sendarg_t), offsetof(dmu_sendarg_t, dsa_link)); + list_create(&ds->ds_prop_cbs, sizeof (dsl_prop_cb_record_t), + offsetof(dsl_prop_cb_record_t, cbr_ds_node)); + if (doi.doi_type == DMU_OTN_ZAP_METADATA) { for (spa_feature_t f = 0; f < SPA_FEATURES; f++) { if (!(spa_feature_table[f].fi_flags & diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c index 4b268da..00341ad 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c @@ -152,11 +152,7 @@ dsl_dir_evict(void *dbu) spa_async_close(dd->dd_pool->dp_spa, dd); - /* - * The props callback list should have been cleaned up by - * objset_evict(). - */ - list_destroy(&dd->dd_prop_cbs); + dsl_prop_fini(dd); mutex_destroy(&dd->dd_lock); kmem_free(dd, sizeof (dsl_dir_t)); } @@ -191,9 +187,7 @@ dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj, dd->dd_dbuf = dbuf; dd->dd_pool = dp; mutex_init(&dd->dd_lock, NULL, MUTEX_DEFAULT, NULL); - - list_create(&dd->dd_prop_cbs, sizeof (dsl_prop_cb_record_t), - offsetof(dsl_prop_cb_record_t, cbr_node)); + dsl_prop_init(dd); dsl_dir_snap_cmtime_update(dd); @@ -251,6 +245,7 @@ dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj, if (winner != NULL) { if (dd->dd_parent) dsl_dir_rele(dd->dd_parent, dd); + dsl_prop_fini(dd); mutex_destroy(&dd->dd_lock); kmem_free(dd, sizeof (dsl_dir_t)); dd = winner; @@ -278,6 +273,7 @@ dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj, errout: if (dd->dd_parent) dsl_dir_rele(dd->dd_parent, dd); + dsl_prop_fini(dd); mutex_destroy(&dd->dd_lock); kmem_free(dd, sizeof (dsl_dir_t)); dmu_buf_rele(dbuf, tag); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_prop.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_prop.c index 094b07d..12e2771 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_prop.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_prop.c @@ -215,6 +215,58 @@ dsl_prop_get_ds(dsl_dataset_t *ds, const char *propname, intsz, numints, buf, setpoint, ds->ds_is_snapshot)); } +static dsl_prop_record_t * +dsl_prop_record_find(dsl_dir_t *dd, const char *propname) +{ + dsl_prop_record_t *pr = NULL; + + ASSERT(MUTEX_HELD(&dd->dd_lock)); + + for (pr = list_head(&dd->dd_props); + pr != NULL; pr = list_next(&dd->dd_props, pr)) { + if (strcmp(pr->pr_propname, propname) == 0) + break; + } + + return (pr); +} + +static dsl_prop_record_t * +dsl_prop_record_create(dsl_dir_t *dd, const char *propname) +{ + dsl_prop_record_t *pr; + + ASSERT(MUTEX_HELD(&dd->dd_lock)); + + pr = kmem_alloc(sizeof (dsl_prop_record_t), KM_SLEEP); + pr->pr_propname = spa_strdup(propname); + list_create(&pr->pr_cbs, sizeof (dsl_prop_cb_record_t), + offsetof(dsl_prop_cb_record_t, cbr_pr_node)); + list_insert_head(&dd->dd_props, pr); + + return (pr); +} + +void +dsl_prop_init(dsl_dir_t *dd) +{ + list_create(&dd->dd_props, sizeof (dsl_prop_record_t), + offsetof(dsl_prop_record_t, pr_node)); +} + +void +dsl_prop_fini(dsl_dir_t *dd) +{ + dsl_prop_record_t *pr; + + while ((pr = list_remove_head(&dd->dd_props)) != NULL) { + list_destroy(&pr->pr_cbs); + strfree((char *)pr->pr_propname); + kmem_free(pr, sizeof (dsl_prop_record_t)); + } + list_destroy(&dd->dd_props); +} + /* * Register interest in the named property. We'll call the callback * once to notify it of the current property value, and again each time @@ -229,6 +281,7 @@ dsl_prop_register(dsl_dataset_t *ds, const char *propname, dsl_dir_t *dd = ds->ds_dir; dsl_pool_t *dp = dd->dd_pool; uint64_t value; + dsl_prop_record_t *pr; dsl_prop_cb_record_t *cbr; int err; @@ -240,12 +293,16 @@ dsl_prop_register(dsl_dataset_t *ds, const char *propname, cbr = kmem_alloc(sizeof (dsl_prop_cb_record_t), KM_SLEEP); cbr->cbr_ds = ds; - cbr->cbr_propname = kmem_alloc(strlen(propname)+1, KM_SLEEP); - (void) strcpy((char *)cbr->cbr_propname, propname); cbr->cbr_func = callback; cbr->cbr_arg = cbarg; + mutex_enter(&dd->dd_lock); - list_insert_head(&dd->dd_prop_cbs, cbr); + pr = dsl_prop_record_find(dd, propname); + if (pr == NULL) + pr = dsl_prop_record_create(dd, propname); + cbr->cbr_pr = pr; + list_insert_head(&pr->pr_cbs, cbr); + list_insert_head(&ds->ds_prop_cbs, cbr); mutex_exit(&dd->dd_lock); cbr->cbr_func(cbr->cbr_arg, value); @@ -376,56 +433,34 @@ dsl_prop_predict(dsl_dir_t *dd, const char *propname, } /* - * Unregister this callback. Return 0 on success, ENOENT if ddname is - * invalid, or ENOMSG if no matching callback registered. + * Unregister all callbacks that are registered with the + * given callback argument. */ -int -dsl_prop_unregister(dsl_dataset_t *ds, const char *propname, - dsl_prop_changed_cb_t *callback, void *cbarg) +void +dsl_prop_unregister_all(dsl_dataset_t *ds, void *cbarg) { + dsl_prop_cb_record_t *cbr, *next_cbr; + dsl_dir_t *dd = ds->ds_dir; - dsl_prop_cb_record_t *cbr; mutex_enter(&dd->dd_lock); - for (cbr = list_head(&dd->dd_prop_cbs); - cbr; cbr = list_next(&dd->dd_prop_cbs, cbr)) { - if (cbr->cbr_ds == ds && - cbr->cbr_func == callback && - cbr->cbr_arg == cbarg && - strcmp(cbr->cbr_propname, propname) == 0) - break; - } - - if (cbr == NULL) { - mutex_exit(&dd->dd_lock); - return (SET_ERROR(ENOMSG)); + next_cbr = list_head(&ds->ds_prop_cbs); + while (next_cbr != NULL) { + cbr = next_cbr; + next_cbr = list_next(&ds->ds_prop_cbs, cbr); + if (cbr->cbr_arg == cbarg) { + list_remove(&ds->ds_prop_cbs, cbr); + list_remove(&cbr->cbr_pr->pr_cbs, cbr); + kmem_free(cbr, sizeof (dsl_prop_cb_record_t)); + } } - - list_remove(&dd->dd_prop_cbs, cbr); mutex_exit(&dd->dd_lock); - kmem_free((void*)cbr->cbr_propname, strlen(cbr->cbr_propname)+1); - kmem_free(cbr, sizeof (dsl_prop_cb_record_t)); - - return (0); } boolean_t dsl_prop_hascb(dsl_dataset_t *ds) { - dsl_dir_t *dd = ds->ds_dir; - boolean_t rv = B_FALSE; - dsl_prop_cb_record_t *cbr; - - mutex_enter(&dd->dd_lock); - for (cbr = list_head(&dd->dd_prop_cbs); cbr; - cbr = list_next(&dd->dd_prop_cbs, cbr)) { - if (cbr->cbr_ds == ds) { - rv = B_TRUE; - break; - } - } - mutex_exit(&dd->dd_lock); - return (rv); + return (!list_is_empty(&ds->ds_prop_cbs)); } /* ARGSUSED */ @@ -433,38 +468,50 @@ static int dsl_prop_notify_all_cb(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg) { dsl_dir_t *dd = ds->ds_dir; + dsl_prop_record_t *pr; dsl_prop_cb_record_t *cbr; mutex_enter(&dd->dd_lock); - for (cbr = list_head(&dd->dd_prop_cbs); cbr; - cbr = list_next(&dd->dd_prop_cbs, cbr)) { - uint64_t value; + for (pr = list_head(&dd->dd_props); + pr; pr = list_next(&dd->dd_props, pr)) { + for (cbr = list_head(&pr->pr_cbs); cbr; + cbr = list_next(&pr->pr_cbs, cbr)) { + uint64_t value; - /* - * Callback entries do not have holds on their datasets - * so that datasets with registered callbacks are still - * eligible for eviction. Unlike operations on callbacks - * for a single dataset, we are performing a recursive - * descent of related datasets and the calling context - * for this iteration only has a dataset hold on the root. - * Without a hold, the callback's pointer to the dataset - * could be invalidated by eviction at any time. - * - * Use dsl_dataset_try_add_ref() to verify that the - * dataset has not begun eviction processing and to - * prevent eviction from occurring for the duration - * of the callback. If the hold attempt fails, this - * object is already being evicted and the callback can - * be safely ignored. - */ - if (!dsl_dataset_try_add_ref(dp, cbr->cbr_ds, FTAG)) - continue; + /* + * Callback entries do not have holds on their + * datasets so that datasets with registered + * callbacks are still eligible for eviction. + * Unlike operations to update properties on a + * single dataset, we are performing a recursive + * descent of related head datasets. The caller + * of this function only has a dataset hold on + * the passed in head dataset, not the snapshots + * associated with this dataset. Without a hold, + * the dataset pointer within callback records + * for snapshots can be invalidated by eviction + * at any time. + * + * Use dsl_dataset_try_add_ref() to verify + * that the dataset for a snapshot has not + * begun eviction processing and to prevent + * eviction from occurring for the duration of + * the callback. If the hold attempt fails, + * this object is already being evicted and the + * callback can be safely ignored. + */ + if (ds != cbr->cbr_ds && + !dsl_dataset_try_add_ref(dp, cbr->cbr_ds, FTAG)) + continue; - if (dsl_prop_get_ds(cbr->cbr_ds, cbr->cbr_propname, - sizeof (value), 1, &value, NULL) == 0) - cbr->cbr_func(cbr->cbr_arg, value); + if (dsl_prop_get_ds(cbr->cbr_ds, + cbr->cbr_pr->pr_propname, sizeof (value), 1, + &value, NULL) == 0) + cbr->cbr_func(cbr->cbr_arg, value); - dsl_dataset_rele(cbr->cbr_ds, FTAG); + if (ds != cbr->cbr_ds) + dsl_dataset_rele(cbr->cbr_ds, FTAG); + } } mutex_exit(&dd->dd_lock); @@ -489,6 +536,7 @@ dsl_prop_changed_notify(dsl_pool_t *dp, uint64_t ddobj, const char *propname, uint64_t value, int first) { dsl_dir_t *dd; + dsl_prop_record_t *pr; dsl_prop_cb_record_t *cbr; objset_t *mos = dp->dp_meta_objset; zap_cursor_t zc; @@ -515,30 +563,33 @@ dsl_prop_changed_notify(dsl_pool_t *dp, uint64_t ddobj, } mutex_enter(&dd->dd_lock); - for (cbr = list_head(&dd->dd_prop_cbs); cbr; - cbr = list_next(&dd->dd_prop_cbs, cbr)) { - uint64_t propobj; + pr = dsl_prop_record_find(dd, propname); + if (pr != NULL) { + for (cbr = list_head(&pr->pr_cbs); cbr; + cbr = list_next(&pr->pr_cbs, cbr)) { + uint64_t propobj; - /* - * cbr->cbf_ds may be invalidated due to eviction, - * requiring the use of dsl_dataset_try_add_ref(). - * See comment block in dsl_prop_notify_all_cb() - * for details. - */ - if (strcmp(cbr->cbr_propname, propname) != 0 || - !dsl_dataset_try_add_ref(dp, cbr->cbr_ds, FTAG)) - continue; + /* + * cbr->cbr_ds may be invalidated due to eviction, + * requiring the use of dsl_dataset_try_add_ref(). + * See comment block in dsl_prop_notify_all_cb() + * for details. + */ + if (!dsl_dataset_try_add_ref(dp, cbr->cbr_ds, FTAG)) + continue; - propobj = dsl_dataset_phys(cbr->cbr_ds)->ds_props_obj; + propobj = dsl_dataset_phys(cbr->cbr_ds)->ds_props_obj; - /* - * If the property is not set on this ds, then it is - * inherited here; call the callback. - */ - if (propobj == 0 || zap_contains(mos, propobj, propname) != 0) - cbr->cbr_func(cbr->cbr_arg, value); + /* + * If the property is not set on this ds, then it is + * inherited here; call the callback. + */ + if (propobj == 0 || + zap_contains(mos, propobj, propname) != 0) + cbr->cbr_func(cbr->cbr_arg, value); - dsl_dataset_rele(cbr->cbr_ds, FTAG); + dsl_dataset_rele(cbr->cbr_ds, FTAG); + } } mutex_exit(&dd->dd_lock); @@ -678,10 +729,10 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname, * ds here. */ mutex_enter(&ds->ds_dir->dd_lock); - for (cbr = list_head(&ds->ds_dir->dd_prop_cbs); cbr; - cbr = list_next(&ds->ds_dir->dd_prop_cbs, cbr)) { - if (cbr->cbr_ds == ds && - strcmp(cbr->cbr_propname, propname) == 0) + for (cbr = list_head(&ds->ds_prop_cbs); cbr; + cbr = list_next(&ds->ds_prop_cbs, cbr)) { + if (strcmp(cbr->cbr_pr->pr_propname, + propname) == 0) cbr->cbr_func(cbr->cbr_arg, intval); } mutex_exit(&ds->ds_dir->dd_lock); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h index 001bff5..c9cd589 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h @@ -184,6 +184,9 @@ typedef struct dsl_dataset { kmutex_t ds_sendstream_lock; list_t ds_sendstreams; + /* Protected by our dsl_dir's dd_lock */ + list_t ds_prop_cbs; + /* * For ZFEATURE_FLAG_PER_DATASET features, set if this dataset * uses this feature. diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h index f50014d..93fb73f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h @@ -102,7 +102,7 @@ struct dsl_dir { /* Protected by dd_lock */ kmutex_t dd_lock; - list_t dd_prop_cbs; /* list of dsl_prop_cb_record_t's */ + list_t dd_props; /* list of dsl_prop_record_t's */ timestruc_t dd_snap_cmtime; /* last time snapshot namespace changed */ uint64_t dd_origin_txg; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_prop.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_prop.h index 5fe18d6..21e6f46 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_prop.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_prop.h @@ -41,10 +41,17 @@ struct dsl_dir; /* The callback func may not call into the DMU or DSL! */ typedef void (dsl_prop_changed_cb_t)(void *arg, uint64_t newval); +typedef struct dsl_prop_record { + list_node_t pr_node; /* link on dd_props */ + const char *pr_propname; + list_t pr_cbs; +} dsl_prop_record_t; + typedef struct dsl_prop_cb_record { - list_node_t cbr_node; /* link on dd_prop_cbs */ + list_node_t cbr_pr_node; /* link on pr_cbs */ + list_node_t cbr_ds_node; /* link on ds_prop_cbs */ + dsl_prop_record_t *cbr_pr; struct dsl_dataset *cbr_ds; - const char *cbr_propname; dsl_prop_changed_cb_t *cbr_func; void *cbr_arg; } dsl_prop_cb_record_t; @@ -54,10 +61,11 @@ typedef struct dsl_props_arg { zprop_source_t pa_source; } dsl_props_arg_t; +void dsl_prop_init(dsl_dir_t *dd); +void dsl_prop_fini(dsl_dir_t *dd); int dsl_prop_register(struct dsl_dataset *ds, const char *propname, dsl_prop_changed_cb_t *callback, void *cbarg); -int dsl_prop_unregister(struct dsl_dataset *ds, const char *propname, - dsl_prop_changed_cb_t *callback, void *cbarg); +void dsl_prop_unregister_all(struct dsl_dataset *ds, void *cbarg); void dsl_prop_notify_all(struct dsl_dir *dd); boolean_t dsl_prop_hascb(struct dsl_dataset *ds); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c index b45d958..e8bcaf5 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c @@ -555,35 +555,7 @@ zfs_register_callbacks(vfs_t *vfsp) return (0); unregister: - /* - * We may attempt to unregister some callbacks that are not - * registered, but this is OK; it will simply return ENOMSG, - * which we will ignore. - */ - (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_ATIME), - atime_changed_cb, zfsvfs); - (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_XATTR), - xattr_changed_cb, zfsvfs); - (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_RECORDSIZE), - blksz_changed_cb, zfsvfs); - (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_READONLY), - readonly_changed_cb, zfsvfs); -#ifdef illumos - (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_DEVICES), - devices_changed_cb, zfsvfs); -#endif - (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_SETUID), - setuid_changed_cb, zfsvfs); - (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_EXEC), - exec_changed_cb, zfsvfs); - (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_SNAPDIR), - snapdir_changed_cb, zfsvfs); - (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_ACLMODE), - acl_mode_changed_cb, zfsvfs); - (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_ACLINHERIT), - acl_inherit_changed_cb, zfsvfs); - (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_VSCAN), - vscan_changed_cb, zfsvfs); + dsl_prop_unregister_all(ds, zfsvfs); return (error); } @@ -1263,43 +1235,9 @@ void zfs_unregister_callbacks(zfsvfs_t *zfsvfs) { objset_t *os = zfsvfs->z_os; - struct dsl_dataset *ds; - - /* - * Unregister properties. - */ - if (!dmu_objset_is_snapshot(os)) { - ds = dmu_objset_ds(os); - VERIFY(dsl_prop_unregister(ds, "atime", atime_changed_cb, - zfsvfs) == 0); - - VERIFY(dsl_prop_unregister(ds, "xattr", xattr_changed_cb, - zfsvfs) == 0); - VERIFY(dsl_prop_unregister(ds, "recordsize", blksz_changed_cb, - zfsvfs) == 0); - - VERIFY(dsl_prop_unregister(ds, "readonly", readonly_changed_cb, - zfsvfs) == 0); - - VERIFY(dsl_prop_unregister(ds, "setuid", setuid_changed_cb, - zfsvfs) == 0); - - VERIFY(dsl_prop_unregister(ds, "exec", exec_changed_cb, - zfsvfs) == 0); - - VERIFY(dsl_prop_unregister(ds, "snapdir", snapdir_changed_cb, - zfsvfs) == 0); - - VERIFY(dsl_prop_unregister(ds, "aclmode", acl_mode_changed_cb, - zfsvfs) == 0); - - VERIFY(dsl_prop_unregister(ds, "aclinherit", - acl_inherit_changed_cb, zfsvfs) == 0); - - VERIFY(dsl_prop_unregister(ds, "vscan", - vscan_changed_cb, zfsvfs) == 0); - } + if (!dmu_objset_is_snapshot(os)) + dsl_prop_unregister_all(dmu_objset_ds(os), zfsvfs); } #ifdef SECLABEL diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h index a65d1ae..1ec9091 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h @@ -1317,16 +1317,19 @@ extern void dtrace_copystr(uintptr_t, uintptr_t, size_t, volatile uint16_t *); /* * DTrace Assertions * - * DTrace calls ASSERT from probe context. To assure that a failed ASSERT - * does not induce a markedly more catastrophic failure (e.g., one from which - * a dump cannot be gleaned), DTrace must define its own ASSERT to be one that - * may safely be called from probe context. This header file must thus be - * included by any DTrace component that calls ASSERT from probe context, and - * _only_ by those components. (The only exception to this is kernel - * debugging infrastructure at user-level that doesn't depend on calling - * ASSERT.) + * DTrace calls ASSERT and VERIFY from probe context. To assure that a failed + * ASSERT or VERIFY does not induce a markedly more catastrophic failure (e.g., + * one from which a dump cannot be gleaned), DTrace must define its own ASSERT + * and VERIFY macros to be ones that may safely be called from probe context. + * This header file must thus be included by any DTrace component that calls + * ASSERT and/or VERIFY from probe context, and _only_ by those components. + * (The only exception to this is kernel debugging infrastructure at user-level + * that doesn't depend on calling ASSERT.) */ #undef ASSERT +#undef VERIFY +#define VERIFY(EX) ((void)((EX) || \ + dtrace_assfail(#EX, __FILE__, __LINE__))) #ifdef DEBUG #define ASSERT(EX) ((void)((EX) || \ dtrace_assfail(#EX, __FILE__, __LINE__))) diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_isa.c b/sys/cddl/dev/dtrace/amd64/dtrace_isa.c index e05932d..d233be4 100644 --- a/sys/cddl/dev/dtrace/amd64/dtrace_isa.c +++ b/sys/cddl/dev/dtrace/amd64/dtrace_isa.c @@ -448,7 +448,6 @@ load: DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); return (val); - return (0); } int diff --git a/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c b/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c index d35bf77..d80e950 100644 --- a/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c +++ b/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c @@ -520,7 +520,6 @@ load: DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); return (val); - return (0); } int diff --git a/sys/cddl/dev/sdt/sdt.c b/sys/cddl/dev/sdt/sdt.c index a321317..4e5dd71 100644 --- a/sys/cddl/dev/sdt/sdt.c +++ b/sys/cddl/dev/sdt/sdt.c @@ -99,8 +99,8 @@ static dtrace_pops_t sdt_pops = { static TAILQ_HEAD(, sdt_provider) sdt_prov_list; -eventhandler_tag sdt_kld_load_tag; -eventhandler_tag sdt_kld_unload_try_tag; +static eventhandler_tag sdt_kld_load_tag; +static eventhandler_tag sdt_kld_unload_try_tag; static void sdt_create_provider(struct sdt_provider *prov) @@ -141,6 +141,12 @@ sdt_create_probe(struct sdt_probe *probe) char *to; size_t len; + if (probe->version != (int)sizeof(*probe)) { + printf("ignoring probe %p, version %u expected %u\n", + probe, probe->version, (int)sizeof(*probe)); + return; + } + TAILQ_FOREACH(prov, &sdt_prov_list, prov_entry) if (strcmp(prov->name, probe->prov->name) == 0) break; @@ -162,6 +168,8 @@ sdt_create_probe(struct sdt_probe *probe) * in the C compiler, so we have to respect const vs non-const. */ strlcpy(func, probe->func, sizeof(func)); + if (func[0] == '\0') + strcpy(func, "none"); from = probe->name; to = name; @@ -401,4 +409,3 @@ sdt_modevent(module_t mod __unused, int type, void *data __unused) DEV_MODULE(sdt, sdt_modevent, NULL); MODULE_VERSION(sdt, 1); MODULE_DEPEND(sdt, dtrace, 1, 1, 1); -MODULE_DEPEND(sdt, opensolaris, 1, 1, 1); diff --git a/sys/compat/linux/linux_dtrace.h b/sys/compat/linux/linux_dtrace.h index b713f16..c446b3e 100644 --- a/sys/compat/linux/linux_dtrace.h +++ b/sys/compat/linux/linux_dtrace.h @@ -82,7 +82,7 @@ c, d, e, f) #define LIN_SDT_PROBE4(a, b, c, d, e, f, g) SDT_PROBE4(LINUX_DTRACE, a, b, \ c, d, e, f, g) -#define _LIN_SDT_PROBE5(a, b, c, d, e, f, g, h, i) SDT_PROBE(a, b, c, d, \ +#define _LIN_SDT_PROBE5(a, b, c, d, e, f, g, h, i) SDT_PROBE5(a, b, c, d, \ e, f, g, h, i) #define LIN_SDT_PROBE5(a, b, c, d, e, f, g, h) _LIN_SDT_PROBE5(LINUX_DTRACE, \ a, b, c, d, e, f, g, h) diff --git a/sys/contrib/dev/otus/otus-init b/sys/contrib/dev/otus/otus-init Binary files differnew file mode 100644 index 0000000..d422bdb --- /dev/null +++ b/sys/contrib/dev/otus/otus-init diff --git a/sys/contrib/dev/otus/otus-license b/sys/contrib/dev/otus/otus-license new file mode 100644 index 0000000..0fc7576 --- /dev/null +++ b/sys/contrib/dev/otus/otus-license @@ -0,0 +1,47 @@ +Copyright (c) 2008, Atheros Communications, Inc. +All rights reserved. + +Redistribution. Redistribution and use in binary form, without +modification, are permitted provided that the following conditions are +met: + +* Redistributions must reproduce the above copyright notice and the + following disclaimer in the documentation and/or other materials + provided with the distribution. + +* Neither the name of Atheros Communications, Inc. nor the names of + its suppliers may be used to endorse or promote products derived + from this software without specific prior written permission. + +* No reverse engineering, decompilation, or disassembly of this + software is permitted. + +Limited patent license. Atheros Communications, Inc. grants a +world-wide, royalty-free, non-exclusive license under patents it +now or hereafter owns or controls to make, have made, use, import, +offer to sell and sell ("Utilize") this software, but solely to +the extent that any such patent is necessary to Utilize the software +alone, or in combination with an operating system licensed under an +approved Open Source license as listed by the Open Source Initiative +at http://opensource.org/licenses. The patent license shall not +apply to any other combinations which include this software. No +hardware per se is licensed hereunder. + +DISCLAIMER. 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. + + +The following files are under this license: + +otus-init otus-main + +These files are needed by otus(4) devices. diff --git a/sys/contrib/dev/otus/otus-main b/sys/contrib/dev/otus/otus-main Binary files differnew file mode 100644 index 0000000..aa0e807 --- /dev/null +++ b/sys/contrib/dev/otus/otus-main diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c index 36b4fe3..9ec450b 100644 --- a/sys/contrib/ipfilter/netinet/ip_nat.c +++ b/sys/contrib/ipfilter/netinet/ip_nat.c @@ -8075,13 +8075,13 @@ ipf_nat_rehash(softc, t, p) * the outbound lookup table and the hash chain length for each. */ KMALLOCS(newtab[0], nat_t **, newsize * sizeof(nat_t *)); - if (newtab == NULL) { + if (newtab[0] == NULL) { error = 60063; goto badrehash; } KMALLOCS(newtab[1], nat_t **, newsize * sizeof(nat_t *)); - if (newtab == NULL) { + if (newtab[1] == NULL) { error = 60064; goto badrehash; } diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 92f1292..0593235 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -2574,8 +2574,11 @@ acpi_ReqSleepState(struct acpi_softc *sc, int state) if (!acpi_sleep_states[state]) return (EOPNOTSUPP); - /* If a suspend request is already in progress, just return. */ - if (sc->acpi_next_sstate != 0) { + /* + * If a reboot/shutdown/suspend request is already in progress or + * suspend is blocked due to an upcoming shutdown, just return. + */ + if (rebooting || sc->acpi_next_sstate != 0 || suspend_blocked) { return (0); } diff --git a/sys/dev/ath/if_ath_ahb.c b/sys/dev/ath/if_ath_ahb.c index fe6420c..0b546a0 100644 --- a/sys/dev/ath/if_ath_ahb.c +++ b/sys/dev/ath/if_ath_ahb.c @@ -261,7 +261,6 @@ ath_ahb_attach(device_t dev) ATH_PCU_LOCK_INIT(sc); ATH_RX_LOCK_INIT(sc); ATH_TX_LOCK_INIT(sc); - ATH_TX_IC_LOCK_INIT(sc); ATH_TXSTATUS_LOCK_INIT(sc); error = ath_attach(device_id, sc); @@ -271,7 +270,6 @@ ath_ahb_attach(device_t dev) ATH_TXSTATUS_LOCK_DESTROY(sc); ATH_RX_LOCK_DESTROY(sc); ATH_TX_LOCK_DESTROY(sc); - ATH_TX_IC_LOCK_DESTROY(sc); ATH_PCU_LOCK_DESTROY(sc); ATH_LOCK_DESTROY(sc); bus_dma_tag_destroy(sc->sc_dmat); @@ -315,7 +313,6 @@ ath_ahb_detach(device_t dev) ATH_TXSTATUS_LOCK_DESTROY(sc); ATH_RX_LOCK_DESTROY(sc); ATH_TX_LOCK_DESTROY(sc); - ATH_TX_IC_LOCK_DESTROY(sc); ATH_PCU_LOCK_DESTROY(sc); ATH_LOCK_DESTROY(sc); diff --git a/sys/dev/ath/if_ath_pci.c b/sys/dev/ath/if_ath_pci.c index 5610882..bc4f7f0 100644 --- a/sys/dev/ath/if_ath_pci.c +++ b/sys/dev/ath/if_ath_pci.c @@ -283,7 +283,6 @@ ath_pci_attach(device_t dev) ATH_PCU_LOCK_INIT(sc); ATH_RX_LOCK_INIT(sc); ATH_TX_LOCK_INIT(sc); - ATH_TX_IC_LOCK_INIT(sc); ATH_TXSTATUS_LOCK_INIT(sc); /* @@ -371,7 +370,6 @@ bad1: ATH_TXSTATUS_LOCK_DESTROY(sc); ATH_PCU_LOCK_DESTROY(sc); ATH_RX_LOCK_DESTROY(sc); - ATH_TX_IC_LOCK_DESTROY(sc); ATH_TX_LOCK_DESTROY(sc); ATH_LOCK_DESTROY(sc); @@ -408,7 +406,6 @@ ath_pci_detach(device_t dev) ATH_TXSTATUS_LOCK_DESTROY(sc); ATH_PCU_LOCK_DESTROY(sc); ATH_RX_LOCK_DESTROY(sc); - ATH_TX_IC_LOCK_DESTROY(sc); ATH_TX_LOCK_DESTROY(sc); ATH_LOCK_DESTROY(sc); diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h index e25bc7a..1af99aa 100644 --- a/sys/dev/ath/if_athvar.h +++ b/sys/dev/ath/if_athvar.h @@ -941,26 +941,6 @@ struct ath_softc { mtx_trylock(&(_sc)->sc_tx_mtx)) /* - * The IC TX lock is non-reentrant and serialises packet queuing from - * the upper layers. - */ -#define ATH_TX_IC_LOCK_INIT(_sc) do {\ - snprintf((_sc)->sc_tx_ic_mtx_name, \ - sizeof((_sc)->sc_tx_ic_mtx_name), \ - "%s IC TX lock", \ - device_get_nameunit((_sc)->sc_dev)); \ - mtx_init(&(_sc)->sc_tx_ic_mtx, (_sc)->sc_tx_ic_mtx_name, \ - NULL, MTX_DEF); \ - } while (0) -#define ATH_TX_IC_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_tx_ic_mtx) -#define ATH_TX_IC_LOCK(_sc) mtx_lock(&(_sc)->sc_tx_ic_mtx) -#define ATH_TX_IC_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_tx_ic_mtx) -#define ATH_TX_IC_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_tx_ic_mtx, \ - MA_OWNED) -#define ATH_TX_IC_UNLOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_tx_ic_mtx, \ - MA_NOTOWNED) - -/* * The PCU lock is non-recursive and should be treated as a spinlock. * Although currently the interrupt code is run in netisr context and * doesn't require this, this may change in the future. diff --git a/sys/dev/drm2/i915/i915_gem_execbuffer.c b/sys/dev/drm2/i915/i915_gem_execbuffer.c index a852338..088043d 100644 --- a/sys/dev/drm2/i915/i915_gem_execbuffer.c +++ b/sys/dev/drm2/i915/i915_gem_execbuffer.c @@ -1151,7 +1151,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (ctx_id != 0) { DRM_DEBUG("Ring %s doesn't support contexts\n", ring->name); - return -EPERM; + ret = -EPERM; + goto pre_struct_lock_err; } break; case I915_EXEC_BLT: @@ -1159,7 +1160,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (ctx_id != 0) { DRM_DEBUG("Ring %s doesn't support contexts\n", ring->name); - return -EPERM; + ret = -EPERM; + goto pre_struct_lock_err; } break; default: @@ -1171,7 +1173,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (!intel_ring_initialized(ring)) { DRM_DEBUG("execbuf with invalid ring: %d\n", (int)(args->flags & I915_EXEC_RING_MASK)); - return -EINVAL; + ret = -EINVAL; + goto pre_struct_lock_err; } mode = args->flags & I915_EXEC_CONSTANTS_MASK; diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index 54c8c83..c1ed6ab 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -5344,6 +5344,8 @@ iwn_updateedca(struct ieee80211com *ic) memset(&cmd, 0, sizeof cmd); cmd.flags = htole32(IWN_EDCA_UPDATE); + + IEEE80211_LOCK(ic); for (aci = 0; aci < WME_NUM_AC; aci++) { const struct wmeParams *ac = &ic->ic_wme.wme_chanParams.cap_wmeParams[aci]; @@ -5354,10 +5356,10 @@ iwn_updateedca(struct ieee80211com *ic) htole16(IEEE80211_TXOP_TO_US(ac->wmep_txopLimit)); } IEEE80211_UNLOCK(ic); + IWN_LOCK(sc); (void)iwn_cmd(sc, IWN_CMD_EDCA_PARAMS, &cmd, sizeof cmd, 1); IWN_UNLOCK(sc); - IEEE80211_LOCK(ic); DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__); diff --git a/sys/dev/nxge/if_nxge.c b/sys/dev/nxge/if_nxge.c index 90871ae..af95e8b 100644 --- a/sys/dev/nxge/if_nxge.c +++ b/sys/dev/nxge/if_nxge.c @@ -1457,7 +1457,7 @@ xge_ioctl_stats(xge_lldev_t *lldev, struct ifreq *ifreqp) case XGE_READ_VERSION: info = xge_os_malloc(NULL, XGE_BUFFER_SIZE); - if(version != NULL) { + if(info != NULL) { strcpy(info, XGE_DRIVER_VERSION); if(copyout(info, ifreqp->ifr_data, XGE_BUFFER_SIZE) == 0) retValue = 0; diff --git a/sys/dev/nxge/xgehal/xgehal-fifo.c b/sys/dev/nxge/xgehal/xgehal-fifo.c index 303afaf..78c0923 100644 --- a/sys/dev/nxge/xgehal/xgehal-fifo.c +++ b/sys/dev/nxge/xgehal/xgehal-fifo.c @@ -464,7 +464,7 @@ __hal_fifo_hw_initialize(xge_hal_device_h devh) if (!hldev->config.fifo.queue[i].configured || !hldev->config.fifo.queue[i].intr_vector || - !hldev->config.intr_mode != XGE_HAL_INTR_MODE_MSIX) + hldev->config.intr_mode != XGE_HAL_INTR_MODE_MSIX) continue; /* find channel */ diff --git a/sys/dev/nxge/xgehal/xgehal-ring.c b/sys/dev/nxge/xgehal/xgehal-ring.c index 444e10c..061b773 100644 --- a/sys/dev/nxge/xgehal/xgehal-ring.c +++ b/sys/dev/nxge/xgehal/xgehal-ring.c @@ -609,7 +609,7 @@ __hal_ring_hw_initialize(xge_hal_device_h devh) if (!hldev->config.ring.queue[i].configured || !hldev->config.ring.queue[i].intr_vector || - !hldev->config.intr_mode != XGE_HAL_INTR_MODE_MSIX) + hldev->config.intr_mode != XGE_HAL_INTR_MODE_MSIX) continue; /* find channel */ diff --git a/sys/dev/otus/if_otus.c b/sys/dev/otus/if_otus.c new file mode 100644 index 0000000..e60157a --- /dev/null +++ b/sys/dev/otus/if_otus.c @@ -0,0 +1,3156 @@ +/* $OpenBSD: if_otus.c,v 1.46 2015/03/14 03:38:49 jsg Exp $ */ + +/*- + * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> + * Copyright (c) 2015 Adrian Chadd <adrian@FreeBSD.org> + * + * 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. + */ + +/* + * Driver for Atheros AR9001U chipset. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include "opt_wlan.h" + +#include <sys/param.h> +#include <sys/endian.h> +#include <sys/sockio.h> +#include <sys/mbuf.h> +#include <sys/kernel.h> +#include <sys/socket.h> +#include <sys/systm.h> +#include <sys/conf.h> +#include <sys/bus.h> +#include <sys/rman.h> +#include <sys/firmware.h> +#include <sys/module.h> +#include <sys/taskqueue.h> + +#include <machine/bus.h> +#include <machine/resource.h> + +#include <net/bpf.h> +#include <net/if.h> +#include <net/if_var.h> +#include <net/if_arp.h> +#include <net/if_dl.h> +#include <net/if_media.h> +#include <net/if_types.h> + +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/in_var.h> +#include <netinet/if_ether.h> +#include <netinet/ip.h> + +#include <net80211/ieee80211_var.h> +#include <net80211/ieee80211_regdomain.h> +#include <net80211/ieee80211_radiotap.h> +#include <net80211/ieee80211_ratectl.h> +#include <net80211/ieee80211_input.h> +#ifdef IEEE80211_SUPPORT_SUPERG +#include <net80211/ieee80211_superg.h> +#endif + +#include <dev/usb/usb.h> +#include <dev/usb/usbdi.h> +#include "usbdevs.h" + +#define USB_DEBUG_VAR otus_debug +#include <dev/usb/usb_debug.h> + +#include "if_otusreg.h" + +static int otus_debug = 0; +static SYSCTL_NODE(_hw_usb, OID_AUTO, otus, CTLFLAG_RW, 0, "USB otus"); +SYSCTL_INT(_hw_usb_otus, OID_AUTO, debug, CTLFLAG_RWTUN, &otus_debug, 0, + "Debug level"); +#define OTUS_DEBUG_XMIT 0x00000001 +#define OTUS_DEBUG_RECV 0x00000002 +#define OTUS_DEBUG_TXDONE 0x00000004 +#define OTUS_DEBUG_RXDONE 0x00000008 +#define OTUS_DEBUG_CMD 0x00000010 +#define OTUS_DEBUG_CMDDONE 0x00000020 +#define OTUS_DEBUG_RESET 0x00000040 +#define OTUS_DEBUG_STATE 0x00000080 +#define OTUS_DEBUG_CMDNOTIFY 0x00000100 +#define OTUS_DEBUG_REGIO 0x00000200 +#define OTUS_DEBUG_IRQ 0x00000400 +#define OTUS_DEBUG_TXCOMP 0x00000800 +#define OTUS_DEBUG_ANY 0xffffffff + +#define OTUS_DPRINTF(sc, dm, ...) \ + do { \ + if ((dm == OTUS_DEBUG_ANY) || (dm & otus_debug)) \ + device_printf(sc->sc_dev, __VA_ARGS__); \ + } while (0) + +#define OTUS_DEV(v, p) { USB_VPI(v, p, 0) } +static const STRUCT_USB_HOST_ID otus_devs[] = { + OTUS_DEV(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_WN7512), + OTUS_DEV(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_3CRUSBN275), + OTUS_DEV(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_TG121N), + OTUS_DEV(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9170), + OTUS_DEV(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_WN612), + OTUS_DEV(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_WN821NV2), + OTUS_DEV(USB_VENDOR_AVM, USB_PRODUCT_AVM_FRITZWLAN), + OTUS_DEV(USB_VENDOR_CACE, USB_PRODUCT_CACE_AIRPCAPNX), + OTUS_DEV(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA130D1), + OTUS_DEV(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160A1), + OTUS_DEV(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160A2), + OTUS_DEV(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_WNGDNUS2), + OTUS_DEV(USB_VENDOR_NEC, USB_PRODUCT_NEC_WL300NUG), + OTUS_DEV(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WN111V2), + OTUS_DEV(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000), + OTUS_DEV(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNDA3100), + OTUS_DEV(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US300), + OTUS_DEV(USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_O8494), + OTUS_DEV(USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_WNC0600), + OTUS_DEV(USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_UB81), + OTUS_DEV(USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_UB82), + OTUS_DEV(USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1221), + OTUS_DEV(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_NWD271N), +}; + +static device_probe_t otus_match; +static device_attach_t otus_attach; +static device_detach_t otus_detach; + +static int otus_attachhook(struct otus_softc *); +void otus_get_chanlist(struct otus_softc *); +int otus_load_firmware(struct otus_softc *, const char *, + uint32_t); +int otus_open_pipes(struct otus_softc *); +void otus_close_pipes(struct otus_softc *); + +static int otus_alloc_tx_cmd_list(struct otus_softc *); +static void otus_free_tx_cmd_list(struct otus_softc *); + +static int otus_alloc_rx_list(struct otus_softc *); +static void otus_free_rx_list(struct otus_softc *); +static int otus_alloc_tx_list(struct otus_softc *); +static void otus_free_tx_list(struct otus_softc *); +static void otus_free_list(struct otus_softc *, struct otus_data [], int); +static struct otus_data *_otus_getbuf(struct otus_softc *); +static struct otus_data *otus_getbuf(struct otus_softc *); +static void otus_freebuf(struct otus_softc *, struct otus_data *); + +static struct otus_tx_cmd *_otus_get_txcmd(struct otus_softc *); +static struct otus_tx_cmd *otus_get_txcmd(struct otus_softc *); +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, + int); +int otus_cmd(struct otus_softc *, uint8_t, const void *, int, + void *, int); +void otus_write(struct otus_softc *, uint32_t, uint32_t); +int otus_write_barrier(struct otus_softc *); +struct ieee80211_node *otus_node_alloc(struct ieee80211com *); +int otus_media_change(struct ifnet *); +int otus_read_eeprom(struct otus_softc *); +void otus_newassoc(struct ieee80211_node *, int); +void otus_cmd_rxeof(struct otus_softc *, uint8_t *, int); +void otus_sub_rxeof(struct otus_softc *, uint8_t *, int, + struct mbufq *); +static int otus_tx(struct otus_softc *, struct ieee80211_node *, + struct mbuf *, struct otus_data *); +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); +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 *, + struct ieee80211_channel *); +int otus_program_phy(struct otus_softc *, + struct ieee80211_channel *); +int otus_set_rf_bank4(struct otus_softc *, + struct ieee80211_channel *); +void otus_get_delta_slope(uint32_t, uint32_t *, uint32_t *); +static int otus_set_chan(struct otus_softc *, struct ieee80211_channel *, + int); +int otus_set_key(struct ieee80211com *, struct ieee80211_node *, + struct ieee80211_key *); +void otus_set_key_cb(struct otus_softc *, void *); +void otus_delete_key(struct ieee80211com *, struct ieee80211_node *, + struct ieee80211_key *); +void otus_delete_key_cb(struct otus_softc *, void *); +void otus_calibrate_to(void *, int); +int otus_set_bssid(struct otus_softc *, const uint8_t *); +int otus_set_macaddr(struct otus_softc *, const uint8_t *); +void otus_led_newstate_type1(struct otus_softc *); +void otus_led_newstate_type2(struct otus_softc *); +void otus_led_newstate_type3(struct otus_softc *); +int otus_init(struct otus_softc *sc); +void otus_stop(struct otus_softc *sc); + +static device_method_t otus_methods[] = { + DEVMETHOD(device_probe, otus_match), + DEVMETHOD(device_attach, otus_attach), + DEVMETHOD(device_detach, otus_detach), + + DEVMETHOD_END +}; + +static driver_t otus_driver = { + .name = "otus", + .methods = otus_methods, + .size = sizeof(struct otus_softc) +}; + +static devclass_t otus_devclass; + +DRIVER_MODULE(otus, uhub, otus_driver, otus_devclass, NULL, 0); +MODULE_DEPEND(otus, wlan, 1, 1, 1); +MODULE_DEPEND(otus, usb, 1, 1, 1); +MODULE_DEPEND(otus, firmware, 1, 1, 1); +MODULE_VERSION(otus, 1); + +static usb_callback_t otus_bulk_tx_callback; +static usb_callback_t otus_bulk_rx_callback; +static usb_callback_t otus_bulk_irq_callback; +static usb_callback_t otus_bulk_cmd_callback; + +static const struct usb_config otus_config[OTUS_N_XFER] = { + [OTUS_BULK_TX] = { + .type = UE_BULK, + .endpoint = UE_ADDR_ANY, + .direction = UE_DIR_OUT, + .bufsize = 0x200, + .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, + .callback = otus_bulk_tx_callback, + .timeout = 5000, /* ms */ + }, + [OTUS_BULK_RX] = { + .type = UE_BULK, + .endpoint = UE_ADDR_ANY, + .direction = UE_DIR_IN, + .bufsize = OTUS_RXBUFSZ, + .flags = { .ext_buffer = 1, .pipe_bof = 1,.short_xfer_ok = 1,}, + .callback = otus_bulk_rx_callback, + }, + [OTUS_BULK_IRQ] = { + .type = UE_INTERRUPT, + .endpoint = UE_ADDR_ANY, + .direction = UE_DIR_IN, + .bufsize = OTUS_MAX_CTRLSZ, + .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, + .callback = otus_bulk_irq_callback, + }, + [OTUS_BULK_CMD] = { + .type = UE_INTERRUPT, + .endpoint = UE_ADDR_ANY, + .direction = UE_DIR_OUT, + .bufsize = OTUS_MAX_CTRLSZ, + .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, + .callback = otus_bulk_cmd_callback, + .timeout = 5000, /* ms */ + }, +}; + +static int +otus_match(device_t self) +{ + struct usb_attach_arg *uaa = device_get_ivars(self); + + if (uaa->usb_mode != USB_MODE_HOST || + uaa->info.bIfaceIndex != 0 || + uaa->info.bConfigIndex != 0) + return (ENXIO); + + return (usbd_lookup_id_by_uaa(otus_devs, sizeof(otus_devs), uaa)); +} + +static int +otus_attach(device_t self) +{ + struct usb_attach_arg *uaa = device_get_ivars(self); + struct otus_softc *sc = device_get_softc(self); + int error; + uint8_t iface_index; + + device_set_usb_desc(self); + sc->sc_udev = uaa->device; + sc->sc_dev = self; + + mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, + MTX_DEF); + + 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; + error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, + otus_config, OTUS_N_XFER, sc, &sc->sc_mtx); + if (error) { + device_printf(sc->sc_dev, + "could not allocate USB transfers, err=%s\n", + usbd_errstr(error)); + goto fail_usb; + } + + if ((error = otus_open_pipes(sc)) != 0) { + device_printf(sc->sc_dev, "%s: could not open pipes\n", + __func__); + goto fail; + } + + /* XXX check return status; fail out if appropriate */ + if (otus_attachhook(sc) != 0) + goto fail; + + return (0); + +fail: + otus_close_pipes(sc); +fail_usb: + mtx_destroy(&sc->sc_mtx); + return (ENXIO); +} + +static int +otus_detach(device_t self) +{ + struct otus_softc *sc = device_get_softc(self); + struct ieee80211com *ic = &sc->sc_ic; + + otus_stop(sc); + + usbd_transfer_unsetup(sc->sc_xfer, OTUS_N_XFER); + + 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 + /* Wait for all queued asynchronous commands to complete. */ + usb_rem_wait_task(sc->sc_udev, &sc->sc_task); + + usbd_ref_wait(sc->sc_udev); +#endif + + ieee80211_ifdetach(ic); + mtx_destroy(&sc->sc_mtx); + return 0; +} + +static void +otus_delay_ms(struct otus_softc *sc, int ms) +{ + + DELAY(1000 * ms); +} + +static struct ieee80211vap * +otus_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, + enum ieee80211_opmode opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct otus_vap *uvp; + struct ieee80211vap *vap; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ + return (NULL); + + uvp = malloc(sizeof(struct otus_vap), M_80211_VAP, M_WAITOK | M_ZERO); + vap = &uvp->vap; + + if (ieee80211_vap_setup(ic, vap, name, unit, opmode, + flags, bssid) != 0) { + /* out of memory */ + free(uvp, M_80211_VAP); + return (NULL); + } + + /* override state transition machine */ + uvp->newstate = vap->iv_newstate; + vap->iv_newstate = otus_newstate; + + /* XXX TODO: double-check */ + vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_16; + vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_32K; + + ieee80211_ratectl_init(vap); + + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, + ieee80211_media_status, mac); + ic->ic_opmode = opmode; + + return (vap); +} + +static void +otus_vap_delete(struct ieee80211vap *vap) +{ + struct otus_vap *uvp = OTUS_VAP(vap); + + ieee80211_ratectl_deinit(vap); + ieee80211_vap_detach(vap); + free(uvp, M_80211_VAP); +} + +static void +otus_parent(struct ieee80211com *ic) +{ + struct otus_softc *sc = ic->ic_softc; + int startall = 0; + + if (ic->ic_nrunning > 0) { + if (!sc->sc_running) { + otus_init(sc); + startall = 1; + } else { + (void) otus_set_multi(sc); + } + } else if (sc->sc_running) + otus_stop(sc); + + if (startall) + ieee80211_start_all(ic); +} + +static void +otus_drain_mbufq(struct otus_softc *sc) +{ + struct mbuf *m; + struct ieee80211_node *ni; + + OTUS_LOCK_ASSERT(sc); + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + m->m_pkthdr.rcvif = NULL; + ieee80211_free_node(ni); + m_freem(m); + } +} + +static void +otus_tx_start(struct otus_softc *sc) +{ + + taskqueue_enqueue(taskqueue_thread, &sc->tx_task); +} + +static int +otus_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct otus_softc *sc = ic->ic_softc; + int error; + + OTUS_LOCK(sc); + if (! sc->sc_running) { + OTUS_UNLOCK(sc); + return (ENXIO); + } + + /* XXX TODO: handle fragments */ + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT, + "%s: mbufq_enqueue failed: %d\n", + __func__, + error); + OTUS_UNLOCK(sc); + return (error); + } + OTUS_UNLOCK(sc); + + /* Kick TX */ + otus_tx_start(sc); + + return (0); +} + +static void +_otus_start(struct otus_softc *sc) +{ + struct ieee80211_node *ni; + struct otus_data *bf; + struct mbuf *m; + + OTUS_LOCK_ASSERT(sc); + + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { + bf = otus_getbuf(sc); + if (bf == NULL) { + OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT, + "%s: failed to get buffer\n", __func__); + mbufq_prepend(&sc->sc_snd, m); + break; + } + + ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; + m->m_pkthdr.rcvif = NULL; + + if (otus_tx(sc, ni, m, bf) != 0) { + OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT, + "%s: failed to transmit\n", __func__); + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); + otus_freebuf(sc, bf); + ieee80211_free_node(ni); + m_freem(m); + break; + } + } +} + +static void +otus_tx_task(void *arg, int pending) +{ + struct otus_softc *sc = arg; + + OTUS_LOCK(sc); + _otus_start(sc); + OTUS_UNLOCK(sc); +} + +static int +otus_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, + const struct ieee80211_bpf_params *params) +{ + struct ieee80211com *ic= ni->ni_ic; + struct otus_softc *sc = ic->ic_softc; + struct otus_data *bf = NULL; + int error = 0; + + /* Don't transmit if we're not running */ + OTUS_LOCK(sc); + if (! sc->sc_running) { + error = ENETDOWN; + goto error; + } + + bf = otus_getbuf(sc); + if (bf == NULL) { + error = ENOBUFS; + goto error; + } + + /* + * XXX TODO: support TX bpf params + */ + if (otus_tx(sc, ni, m, bf) != 0) { + error = EIO; + goto error; + } + + OTUS_UNLOCK(sc); + return (0); +error: + if (bf) + otus_freebuf(sc, bf); + OTUS_UNLOCK(sc); + ieee80211_free_node(ni); + m_freem(m); + return (ENXIO); +} + +static void +otus_update_chw(struct ieee80211com *ic) +{ + + printf("%s: TODO\n", __func__); +} + +static void +otus_set_channel(struct ieee80211com *ic) +{ + struct otus_softc *sc = ic->ic_softc; + OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, "%s: set channel: %d\n", + __func__, + ic->ic_curchan->ic_freq); + + OTUS_LOCK(sc); + (void) otus_set_chan(sc, ic->ic_curchan, 0); + 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) +{ + + /* For now, no A-MPDU TX support in the driver */ + return (0); +} + +static void +otus_scan_start(struct ieee80211com *ic) +{ + +// printf("%s: TODO\n", __func__); +} + +static void +otus_scan_end(struct ieee80211com *ic) +{ + +// printf("%s: TODO\n", __func__); +} + +static void +otus_update_mcast(struct ieee80211com *ic) +{ + struct otus_softc *sc = ic->ic_softc; + + (void) otus_set_multi(sc); +} + +static int +otus_attachhook(struct otus_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + usb_device_request_t req; + uint32_t in, out; + int error; + uint8_t bands; + + /* Not locked */ + error = otus_load_firmware(sc, "otusfw_init", AR_FW_INIT_ADDR); + if (error != 0) { + device_printf(sc->sc_dev, "%s: could not load %s firmware\n", + __func__, "init"); + return (ENXIO); + } + + /* XXX not locked? */ + otus_delay_ms(sc, 1000); + + /* Not locked */ + error = otus_load_firmware(sc, "otusfw_main", AR_FW_MAIN_ADDR); + if (error != 0) { + device_printf(sc->sc_dev, "%s: could not load %s firmware\n", + __func__, "main"); + return (ENXIO); + } + + OTUS_LOCK(sc); + + /* Tell device that firmware transfer is complete. */ + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = AR_FW_DOWNLOAD_COMPLETE; + USETW(req.wValue, 0); + USETW(req.wIndex, 0); + USETW(req.wLength, 0); + if (usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx, &req, NULL, + 0, NULL, 250) != 0) { + OTUS_UNLOCK(sc); + device_printf(sc->sc_dev, + "%s: firmware initialization failed\n", + __func__); + return (ENXIO); + } + + /* Send an ECHO command to check that everything is settled. */ + in = 0xbadc0ffe; + if (otus_cmd(sc, AR_CMD_ECHO, &in, sizeof in, &out, sizeof(out)) != 0) { + OTUS_UNLOCK(sc); + device_printf(sc->sc_dev, + "%s: echo command failed\n", __func__); + return (ENXIO); + } + if (in != out) { + OTUS_UNLOCK(sc); + device_printf(sc->sc_dev, + "%s: echo reply mismatch: 0x%08x!=0x%08x\n", + __func__, in, out); + return (ENXIO); + } + + /* Read entire EEPROM. */ + if (otus_read_eeprom(sc) != 0) { + OTUS_UNLOCK(sc); + device_printf(sc->sc_dev, + "%s: could not read EEPROM\n", + __func__); + return (ENXIO); + } + + OTUS_UNLOCK(sc); + + sc->txmask = sc->eeprom.baseEepHeader.txMask; + sc->rxmask = sc->eeprom.baseEepHeader.rxMask; + sc->capflags = sc->eeprom.baseEepHeader.opCapFlags; + IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->eeprom.baseEepHeader.macAddr); + sc->sc_led_newstate = otus_led_newstate_type3; /* XXX */ + + device_printf(sc->sc_dev, + "MAC/BBP AR9170, RF AR%X, MIMO %dT%dR, address %s\n", + (sc->capflags & AR5416_OPFLAGS_11A) ? + 0x9104 : ((sc->txmask == 0x5) ? 0x9102 : 0x9101), + (sc->txmask == 0x5) ? 2 : 1, (sc->rxmask == 0x5) ? 2 : 1, + ether_sprintf(ic->ic_macaddr)); + + ic->ic_softc = sc; + ic->ic_name = device_get_nameunit(sc->sc_dev); + ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ + ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ + + /* Set device capabilities. */ + ic->ic_caps = + IEEE80211_C_STA | /* station mode */ +#if 0 + IEEE80211_C_BGSCAN | /* Background scan. */ +#endif + IEEE80211_C_SHPREAMBLE | /* Short preamble supported. */ + IEEE80211_C_WME | /* WME/QoS */ + IEEE80211_C_SHSLOT | /* Short slot time supported. */ + IEEE80211_C_FF | /* Atheros fast-frames supported. */ + IEEE80211_C_WPA; /* WPA/RSN. */ + + /* XXX TODO: 11n */ + +#if 0 + if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) { + /* Set supported .11b and .11g rates. */ + ic->ic_sup_rates[IEEE80211_MODE_11B] = + ieee80211_std_rateset_11b; + ic->ic_sup_rates[IEEE80211_MODE_11G] = + ieee80211_std_rateset_11g; + } + if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) { + /* Set supported .11a rates. */ + ic->ic_sup_rates[IEEE80211_MODE_11A] = + ieee80211_std_rateset_11a; + } +#endif + +#if 0 + /* Build the list of supported channels. */ + otus_get_chanlist(sc); +#else + /* Set supported .11b and .11g rates. */ + bands = 0; + if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) { + setbit(&bands, IEEE80211_MODE_11B); + setbit(&bands, IEEE80211_MODE_11G); + } + if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) { + setbit(&bands, IEEE80211_MODE_11A); + } +#if 0 + if (sc->sc_ht) + setbit(&bands, IEEE80211_MODE_11NG); +#endif + ieee80211_init_channels(ic, NULL, &bands); +#endif + + ieee80211_ifattach(ic); + ic->ic_raw_xmit = otus_raw_xmit; + ic->ic_scan_start = otus_scan_start; + ic->ic_scan_end = otus_scan_end; + ic->ic_set_channel = otus_set_channel; + ic->ic_vap_create = otus_vap_create; + ic->ic_vap_delete = otus_vap_delete; + ic->ic_update_mcast = otus_update_mcast; + ic->ic_update_promisc = otus_update_mcast; + ic->ic_parent = otus_parent; + 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_newassoc = otus_newassoc; + +#ifdef notyet + ic->ic_set_key = otus_set_key; + ic->ic_delete_key = otus_delete_key; +#endif + + ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, + sizeof(sc->sc_txtap), OTUS_TX_RADIOTAP_PRESENT, + &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), + OTUS_RX_RADIOTAP_PRESENT); + + return (0); +} + +void +otus_get_chanlist(struct otus_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + uint16_t domain; + uint8_t chan; + int i; + + /* XXX regulatory domain. */ + domain = le16toh(sc->eeprom.baseEepHeader.regDmn[0]); + OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, "regdomain=0x%04x\n", domain); + + if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) { + for (i = 0; i < 14; i++) { + chan = ar_chans[i]; + ic->ic_channels[chan].ic_freq = + ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ); + ic->ic_channels[chan].ic_flags = + IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | + IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; + } + } + if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) { + for (i = 14; i < nitems(ar_chans); i++) { + chan = ar_chans[i]; + ic->ic_channels[chan].ic_freq = + ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ); + ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A; + } + } +} + +int +otus_load_firmware(struct otus_softc *sc, const char *name, uint32_t addr) +{ + usb_device_request_t req; + char *ptr; + const struct firmware *fw; + int mlen, error, size; + + error = 0; + + /* Read firmware image from the filesystem. */ + if ((fw = firmware_get(name)) == NULL) { + device_printf(sc->sc_dev, + "%s: failed loadfirmware of file %s\n", __func__, name); + return (ENXIO); + } + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = AR_FW_DOWNLOAD; + USETW(req.wIndex, 0); + + OTUS_LOCK(sc); + + /* XXX const */ + ptr = __DECONST(char *, fw->data); + size = fw->datasize; + addr >>= 8; + while (size > 0) { + mlen = MIN(size, 4096); + + USETW(req.wValue, addr); + USETW(req.wLength, mlen); + if (usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx, + &req, ptr, 0, NULL, 250) != 0) { + error = EIO; + break; + } + addr += mlen >> 8; + ptr += mlen; + size -= mlen; + } + + OTUS_UNLOCK(sc); + + firmware_put(fw, FIRMWARE_UNLOAD); + if (error != 0) + device_printf(sc->sc_dev, + "%s: %s: error=%d\n", __func__, name, error); + return error; +} + +int +otus_open_pipes(struct otus_softc *sc) +{ +#if 0 + int isize, error; + int i; +#endif + int error; + + OTUS_UNLOCK_ASSERT(sc); + + if ((error = otus_alloc_tx_cmd_list(sc)) != 0) { + device_printf(sc->sc_dev, + "%s: could not allocate command xfer\n", + __func__); + goto fail; + } + + if ((error = otus_alloc_tx_list(sc)) != 0) { + device_printf(sc->sc_dev, "%s: could not allocate Tx xfers\n", + __func__); + goto fail; + } + + if ((error = otus_alloc_rx_list(sc)) != 0) { + device_printf(sc->sc_dev, "%s: could not allocate Rx xfers\n", + __func__); + goto fail; + } + + /* Enable RX transfers; needed for initial firmware messages */ + OTUS_LOCK(sc); + usbd_transfer_start(sc->sc_xfer[OTUS_BULK_RX]); + usbd_transfer_start(sc->sc_xfer[OTUS_BULK_IRQ]); + OTUS_UNLOCK(sc); + return 0; + +fail: otus_close_pipes(sc); + return error; +} + +void +otus_close_pipes(struct otus_softc *sc) +{ + + OTUS_LOCK(sc); + otus_free_tx_cmd_list(sc); + otus_free_tx_list(sc); + otus_free_rx_list(sc); + OTUS_UNLOCK(sc); + + usbd_transfer_unsetup(sc->sc_xfer, OTUS_N_XFER); +} + +static void +otus_free_cmd_list(struct otus_softc *sc, struct otus_tx_cmd cmd[], int ndata) +{ + int i; + + /* XXX TODO: someone has to have waken up waiters! */ + for (i = 0; i < ndata; i++) { + struct otus_tx_cmd *dp = &cmd[i]; + + if (dp->buf != NULL) { + free(dp->buf, M_USBDEV); + dp->buf = NULL; + } + } +} + +static int +otus_alloc_cmd_list(struct otus_softc *sc, struct otus_tx_cmd cmd[], + int ndata, int maxsz) +{ + int i, error; + + for (i = 0; i < ndata; i++) { + struct otus_tx_cmd *dp = &cmd[i]; + dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT); + dp->odata = NULL; + if (dp->buf == NULL) { + device_printf(sc->sc_dev, + "could not allocate buffer\n"); + error = ENOMEM; + goto fail; + } + } + + return (0); +fail: + otus_free_cmd_list(sc, cmd, ndata); + return (error); +} + +static int +otus_alloc_tx_cmd_list(struct otus_softc *sc) +{ + int error, i; + + error = otus_alloc_cmd_list(sc, sc->sc_cmd, OTUS_CMD_LIST_COUNT, + OTUS_MAX_TXCMDSZ); + if (error != 0) + return (error); + + STAILQ_INIT(&sc->sc_cmd_active); + STAILQ_INIT(&sc->sc_cmd_inactive); + STAILQ_INIT(&sc->sc_cmd_pending); + STAILQ_INIT(&sc->sc_cmd_waiting); + + for (i = 0; i < OTUS_CMD_LIST_COUNT; i++) + STAILQ_INSERT_HEAD(&sc->sc_cmd_inactive, &sc->sc_cmd[i], + next_cmd); + + return (0); +} + +static void +otus_free_tx_cmd_list(struct otus_softc *sc) +{ + + /* + * XXX TODO: something needs to wake up any pending/sleeping + * waiters! + */ + STAILQ_INIT(&sc->sc_cmd_active); + STAILQ_INIT(&sc->sc_cmd_inactive); + STAILQ_INIT(&sc->sc_cmd_pending); + STAILQ_INIT(&sc->sc_cmd_waiting); + + otus_free_cmd_list(sc, sc->sc_cmd, OTUS_CMD_LIST_COUNT); +} + +static int +otus_alloc_list(struct otus_softc *sc, struct otus_data data[], + int ndata, int maxsz) +{ + int i, error; + + for (i = 0; i < ndata; i++) { + struct otus_data *dp = &data[i]; + dp->sc = sc; + dp->m = NULL; + dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT); + if (dp->buf == NULL) { + device_printf(sc->sc_dev, + "could not allocate buffer\n"); + error = ENOMEM; + goto fail; + } + dp->ni = NULL; + } + + return (0); +fail: + otus_free_list(sc, data, ndata); + return (error); +} + +static int +otus_alloc_rx_list(struct otus_softc *sc) +{ + int error, i; + + error = otus_alloc_list(sc, sc->sc_rx, OTUS_RX_LIST_COUNT, + OTUS_RXBUFSZ); + if (error != 0) + return (error); + + STAILQ_INIT(&sc->sc_rx_active); + STAILQ_INIT(&sc->sc_rx_inactive); + + for (i = 0; i < OTUS_RX_LIST_COUNT; i++) + STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next); + + return (0); +} + +static int +otus_alloc_tx_list(struct otus_softc *sc) +{ + int error, i; + + error = otus_alloc_list(sc, sc->sc_tx, OTUS_TX_LIST_COUNT, + OTUS_TXBUFSZ); + if (error != 0) + return (error); + + STAILQ_INIT(&sc->sc_tx_inactive); + + for (i = 0; i != OTUS_N_XFER; i++) { + STAILQ_INIT(&sc->sc_tx_active[i]); + STAILQ_INIT(&sc->sc_tx_pending[i]); + } + + for (i = 0; i < OTUS_TX_LIST_COUNT; i++) { + STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i], next); + } + + return (0); +} + +static void +otus_free_tx_list(struct otus_softc *sc) +{ + int i; + + /* prevent further allocations from TX list(s) */ + STAILQ_INIT(&sc->sc_tx_inactive); + + for (i = 0; i != OTUS_N_XFER; i++) { + STAILQ_INIT(&sc->sc_tx_active[i]); + STAILQ_INIT(&sc->sc_tx_pending[i]); + } + + otus_free_list(sc, sc->sc_tx, OTUS_TX_LIST_COUNT); +} + +static void +otus_free_rx_list(struct otus_softc *sc) +{ + /* prevent further allocations from RX list(s) */ + STAILQ_INIT(&sc->sc_rx_inactive); + STAILQ_INIT(&sc->sc_rx_active); + + otus_free_list(sc, sc->sc_rx, OTUS_RX_LIST_COUNT); +} + +static void +otus_free_list(struct otus_softc *sc, struct otus_data data[], int ndata) +{ + int i; + + for (i = 0; i < ndata; i++) { + struct otus_data *dp = &data[i]; + + if (dp->buf != NULL) { + free(dp->buf, M_USBDEV); + dp->buf = NULL; + } + if (dp->ni != NULL) { + ieee80211_free_node(dp->ni); + dp->ni = NULL; + } + } +} + +static struct otus_data * +_otus_getbuf(struct otus_softc *sc) +{ + struct otus_data *bf; + + bf = STAILQ_FIRST(&sc->sc_tx_inactive); + if (bf != NULL) + STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next); + else + bf = NULL; + return (bf); +} + +static struct otus_data * +otus_getbuf(struct otus_softc *sc) +{ + struct otus_data *bf; + + OTUS_LOCK_ASSERT(sc); + + bf = _otus_getbuf(sc); + return (bf); +} + +static void +otus_freebuf(struct otus_softc *sc, struct otus_data *bf) +{ + + OTUS_LOCK_ASSERT(sc); + STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, bf, next); +} + +static struct otus_tx_cmd * +_otus_get_txcmd(struct otus_softc *sc) +{ + struct otus_tx_cmd *bf; + + bf = STAILQ_FIRST(&sc->sc_cmd_inactive); + if (bf != NULL) + STAILQ_REMOVE_HEAD(&sc->sc_cmd_inactive, next_cmd); + else + bf = NULL; + return (bf); +} + +static struct otus_tx_cmd * +otus_get_txcmd(struct otus_softc *sc) +{ + struct otus_tx_cmd *bf; + + OTUS_LOCK_ASSERT(sc); + + bf = _otus_get_txcmd(sc); + if (bf == NULL) { + device_printf(sc->sc_dev, "%s: no tx cmd buffers\n", + __func__); + } + return (bf); +} + +static void +otus_free_txcmd(struct otus_softc *sc, struct otus_tx_cmd *bf) +{ + + OTUS_LOCK_ASSERT(sc); + STAILQ_INSERT_TAIL(&sc->sc_cmd_inactive, bf, next_cmd); +} + +void +otus_next_scan(void *arg, int pending) +{ +#if 0 + struct otus_softc *sc = arg; + + if (usbd_is_dying(sc->sc_udev)) + return; + + usbd_ref_incr(sc->sc_udev); + + if (sc->sc_ic.ic_state == IEEE80211_S_SCAN) + ieee80211_next_scan(&sc->sc_ic.ic_if); + + usbd_ref_decr(sc->sc_udev); +#endif +} + +int +otus_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) +{ + struct otus_vap *uvp = OTUS_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; + struct otus_softc *sc = ic->ic_softc; + struct ieee80211_node *ni; + enum ieee80211_state ostate; + + ostate = vap->iv_state; + OTUS_DPRINTF(sc, OTUS_DEBUG_STATE, "%s: %s -> %s\n", __func__, + ieee80211_state_name[ostate], + ieee80211_state_name[nstate]); + + IEEE80211_UNLOCK(ic); + + OTUS_LOCK(sc); + + /* XXX TODO: more fleshing out! */ + + switch (nstate) { + case IEEE80211_S_RUN: + ni = ieee80211_ref_node(vap->iv_bss); + + if (ic->ic_opmode == IEEE80211_M_STA) { + otus_updateslot(sc); + otus_set_bssid(sc, ni->ni_bssid); + + /* Start calibration timer. */ + taskqueue_enqueue_timeout(taskqueue_thread, + &sc->calib_to, hz); + } + break; + default: + break; + } + + /* XXX TODO: calibration? */ + + sc->sc_led_newstate(sc); + + OTUS_UNLOCK(sc); + IEEE80211_LOCK(ic); + return (uvp->newstate(vap, nstate, arg)); +} + +int +otus_cmd(struct otus_softc *sc, uint8_t code, const void *idata, int ilen, + void *odata, int odatalen) +{ + struct otus_tx_cmd *cmd; + struct ar_cmd_hdr *hdr; + int xferlen, error; + + OTUS_LOCK_ASSERT(sc); + + /* Always bulk-out a multiple of 4 bytes. */ + xferlen = (sizeof (*hdr) + ilen + 3) & ~3; + if (xferlen > OTUS_MAX_TXCMDSZ) { + device_printf(sc->sc_dev, "%s: command (0x%02x) size (%d) > %d\n", + __func__, + code, + xferlen, + OTUS_MAX_TXCMDSZ); + return (EIO); + } + + cmd = otus_get_txcmd(sc); + if (cmd == NULL) { + device_printf(sc->sc_dev, "%s: failed to get buf\n", + __func__); + return (EIO); + } + + hdr = (struct ar_cmd_hdr *)cmd->buf; + hdr->code = code; + hdr->len = ilen; + hdr->token = ++sc->token; /* Don't care about endianness. */ + cmd->token = hdr->token; + /* XXX TODO: check max cmd length? */ + memcpy((uint8_t *)&hdr[1], idata, ilen); + + OTUS_DPRINTF(sc, OTUS_DEBUG_CMD, + "%s: sending command code=0x%02x len=%d token=%d\n", + __func__, code, ilen, hdr->token); + + cmd->odata = odata; + cmd->odatalen = odatalen; + cmd->buflen = xferlen; + + /* Queue the command to the endpoint */ + STAILQ_INSERT_TAIL(&sc->sc_cmd_pending, cmd, next_cmd); + usbd_transfer_start(sc->sc_xfer[OTUS_BULK_CMD]); + + /* Sleep on the command; wait for it to complete */ + error = msleep(cmd, &sc->sc_mtx, PCATCH, "otuscmd", hz); + + /* + * At this point we don't own cmd any longer; it'll be + * freed by the cmd bulk path or the RX notification + * path. If the data is made available then it'll be copied + * to the caller. All that is left to do is communicate + * status back to the caller. + */ + if (error != 0) { + device_printf(sc->sc_dev, + "%s: timeout waiting for command 0x%02x reply\n", + __func__, code); + } + return error; +} + +void +otus_write(struct otus_softc *sc, uint32_t reg, uint32_t val) +{ + + OTUS_LOCK_ASSERT(sc); + + sc->write_buf[sc->write_idx].reg = htole32(reg); + sc->write_buf[sc->write_idx].val = htole32(val); + + if (++sc->write_idx > (AR_MAX_WRITE_IDX-1)) + (void)otus_write_barrier(sc); +} + +int +otus_write_barrier(struct otus_softc *sc) +{ + int error; + + OTUS_LOCK_ASSERT(sc); + + if (sc->write_idx == 0) + return 0; /* Nothing to flush. */ + + OTUS_DPRINTF(sc, OTUS_DEBUG_REGIO, "%s: called; %d updates\n", + __func__, + sc->write_idx); + + error = otus_cmd(sc, AR_CMD_WREG, sc->write_buf, + sizeof (sc->write_buf[0]) * sc->write_idx, NULL, 0); + sc->write_idx = 0; + return error; +} + +struct ieee80211_node * +otus_node_alloc(struct ieee80211com *ic) +{ + return malloc(sizeof (struct otus_node), M_DEVBUF, M_NOWAIT | M_ZERO); +} + +#if 0 +int +otus_media_change(struct ifnet *ifp) +{ + struct otus_softc *sc = ifp->if_softc; + struct ieee80211com *ic = &sc->sc_ic; + uint8_t rate, ridx; + int error; + + error = ieee80211_media_change(ifp); + if (error != ENETRESET) + return error; + + if (ic->ic_fixed_rate != -1) { + rate = ic->ic_sup_rates[ic->ic_curmode]. + rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; + for (ridx = 0; ridx <= OTUS_RIDX_MAX; ridx++) + if (otus_rates[ridx].rate == rate) + break; + sc->fixed_ridx = ridx; + } + + if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) + error = otus_init(sc); + + return error; +} +#endif + +int +otus_read_eeprom(struct otus_softc *sc) +{ + uint32_t regs[8], reg; + uint8_t *eep; + int i, j, error; + + OTUS_LOCK_ASSERT(sc); + + /* Read EEPROM by blocks of 32 bytes. */ + eep = (uint8_t *)&sc->eeprom; + reg = AR_EEPROM_OFFSET; + for (i = 0; i < sizeof (sc->eeprom) / 32; i++) { + for (j = 0; j < 8; j++, reg += 4) + regs[j] = htole32(reg); + error = otus_cmd(sc, AR_CMD_RREG, regs, sizeof regs, eep, 32); + if (error != 0) + break; + eep += 32; + } + return error; +} + +void +otus_newassoc(struct ieee80211_node *ni, int isnew) +{ + struct ieee80211com *ic = ni->ni_ic; + struct otus_softc *sc = ic->ic_softc; + struct otus_node *on = OTUS_NODE(ni); + + OTUS_DPRINTF(sc, OTUS_DEBUG_STATE, "new assoc isnew=%d addr=%s\n", + isnew, ether_sprintf(ni->ni_macaddr)); + + on->tx_done = 0; + on->tx_err = 0; + on->tx_retries = 0; +} + +static void +otus_cmd_handle_response(struct otus_softc *sc, struct ar_cmd_hdr *hdr) +{ + struct otus_tx_cmd *cmd; + + OTUS_LOCK_ASSERT(sc); + + OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE, + "%s: received reply code=0x%02x len=%d token=%d\n", + __func__, + hdr->code, hdr->len, hdr->token); + + /* + * Walk the list, freeing items that aren't ours, + * stopping when we hit our token. + */ + while ((cmd = STAILQ_FIRST(&sc->sc_cmd_waiting)) != NULL) { + STAILQ_REMOVE_HEAD(&sc->sc_cmd_waiting, next_cmd); + OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE, + "%s: cmd=%p; hdr.token=%d, cmd.token=%d\n", + __func__, + cmd, + (int) hdr->token, + (int) cmd->token); + if (hdr->token == cmd->token) { + /* Copy answer into caller's supplied buffer. */ + if (cmd->odata != NULL) { + if (hdr->len != cmd->odatalen) { + device_printf(sc->sc_dev, + "%s: code 0x%02x, len=%d, olen=%d\n", + __func__, + (int) hdr->code, + (int) hdr->len, + (int) cmd->odatalen); + } + memcpy(cmd->odata, &hdr[1], + MIN(cmd->odatalen, hdr->len)); + } + wakeup(cmd); + } + + STAILQ_INSERT_TAIL(&sc->sc_cmd_inactive, cmd, next_cmd); + } +} + +void +otus_cmd_rxeof(struct otus_softc *sc, uint8_t *buf, int len) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct ar_cmd_hdr *hdr; + + OTUS_LOCK_ASSERT(sc); + + if (__predict_false(len < sizeof (*hdr))) { + OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE, + "cmd too small %d\n", len); + return; + } + hdr = (struct ar_cmd_hdr *)buf; + if (__predict_false(sizeof (*hdr) + hdr->len > len || + sizeof (*hdr) + hdr->len > 64)) { + OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE, + "cmd too large %d\n", hdr->len); + return; + } + + OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, + "%s: code=%.02x\n", + __func__, + hdr->code); + + /* + * This has to reach into the cmd queue "waiting for + * an RX response" list, grab the head entry and check + * if we need to wake anyone up. + */ + if ((hdr->code & 0xc0) != 0xc0) { + otus_cmd_handle_response(sc, hdr); + return; + } + + /* Received unsolicited notification. */ + switch (hdr->code & 0x3f) { + case AR_EVT_BEACON: + break; + case AR_EVT_TX_COMP: + { + struct ar_evt_tx_comp *tx = (struct ar_evt_tx_comp *)&hdr[1]; + struct ieee80211_node *ni; + + ni = ieee80211_find_node(&ic->ic_sta, tx->macaddr); + if (ni == NULL) { + device_printf(sc->sc_dev, + "%s: txcomp on unknown node (%s)\n", + __func__, + ether_sprintf(tx->macaddr)); + break; + } + + OTUS_DPRINTF(sc, OTUS_DEBUG_TXCOMP, + "tx completed %s status=%d phy=0x%x\n", + ether_sprintf(tx->macaddr), le16toh(tx->status), + le32toh(tx->phy)); + + switch (le16toh(tx->status)) { + case AR_TX_STATUS_COMP: +#if 0 + ackfailcnt = 0; + ieee80211_ratectl_tx_complete(ni->ni_vap, ni, + IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL); +#endif + /* + * We don't get the above; only error notifications. + * Sigh. So, don't worry about this. + */ + break; + case AR_TX_STATUS_RETRY_COMP: + OTUS_NODE(ni)->tx_retries++; + break; + case AR_TX_STATUS_FAILED: + OTUS_NODE(ni)->tx_err++; + break; + } + ieee80211_free_node(ni); + break; + } + case AR_EVT_TBTT: + break; + case AR_EVT_DO_BB_RESET: + /* + * This is "tell driver to reset baseband" from ar9170-fw. + * + * I'm not sure what we should do here, so I'm going to + * fall through; it gets generated when RTSRetryCnt internally + * reaches '5' - I guess the firmware authors thought that + * meant that the BB may have gone deaf or something. + */ + default: + device_printf(sc->sc_dev, + "%s: received notification code=0x%02x len=%d\n", + __func__, + hdr->code, hdr->len); + } +} + +void +otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len, struct mbufq *rxq) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_rx_stats rxs; +#if 0 + struct ieee80211_node *ni; +#endif + struct ar_rx_tail *tail; + struct ieee80211_frame *wh; + struct mbuf *m; + uint8_t *plcp; +// int s; + int mlen; + + if (__predict_false(len < AR_PLCP_HDR_LEN)) { + OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, + "sub-xfer too short %d\n", len); + return; + } + plcp = buf; + + /* All bits in the PLCP header are set to 1 for non-MPDU. */ + if (memcmp(plcp, AR_PLCP_HDR_INTR, AR_PLCP_HDR_LEN) == 0) { + otus_cmd_rxeof(sc, plcp + AR_PLCP_HDR_LEN, + len - AR_PLCP_HDR_LEN); + return; + } + + /* Received MPDU. */ + if (__predict_false(len < AR_PLCP_HDR_LEN + sizeof (*tail))) { + OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "MPDU too short %d\n", len); + counter_u64_add(ic->ic_ierrors, 1); + return; + } + tail = (struct ar_rx_tail *)(plcp + len - sizeof (*tail)); + + /* Discard error frames. */ + if (__predict_false(tail->error != 0)) { + OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "error frame 0x%02x\n", tail->error); + if (tail->error & AR_RX_ERROR_FCS) { + OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "bad FCS\n"); + } else if (tail->error & AR_RX_ERROR_MMIC) { + /* Report Michael MIC failures to net80211. */ +#if 0 + ieee80211_notify_michael_failure(ni->ni_vap, wh, keyidx); +#endif + device_printf(sc->sc_dev, "%s: MIC failure\n", __func__); + } + counter_u64_add(ic->ic_ierrors, 1); + return; + } + /* Compute MPDU's length. */ + mlen = len - AR_PLCP_HDR_LEN - sizeof (*tail); + /* Make sure there's room for an 802.11 header + FCS. */ + if (__predict_false(mlen < IEEE80211_MIN_LEN)) { + counter_u64_add(ic->ic_ierrors, 1); + return; + } + mlen -= IEEE80211_CRC_LEN; /* strip 802.11 FCS */ + + wh = (struct ieee80211_frame *)(plcp + AR_PLCP_HDR_LEN); + + m = m_get2(mlen, M_NOWAIT, MT_DATA, M_PKTHDR); + if (m == NULL) { + device_printf(sc->sc_dev, "%s: failed m_get2()\n", __func__); + counter_u64_add(ic->ic_ierrors, 1); + } + + /* Finalize mbuf. */ + memcpy(mtod(m, uint8_t *), wh, mlen); + m->m_pkthdr.len = m->m_len = mlen; + +#if 0 + if (__predict_false(sc->sc_drvbpf != NULL)) { + struct otus_rx_radiotap_header *tap = &sc->sc_rxtap; + struct mbuf mb; + + tap->wr_flags = 0; + tap->wr_chan_freq = htole16(ic->ic_ibss_chan->ic_freq); + tap->wr_chan_flags = htole16(ic->ic_ibss_chan->ic_flags); + tap->wr_antsignal = tail->rssi; + tap->wr_rate = 2; /* In case it can't be found below. */ + switch (tail->status & AR_RX_STATUS_MT_MASK) { + case AR_RX_STATUS_MT_CCK: + switch (plcp[0]) { + case 10: tap->wr_rate = 2; break; + case 20: tap->wr_rate = 4; break; + case 55: tap->wr_rate = 11; break; + case 110: tap->wr_rate = 22; break; + } + if (tail->status & AR_RX_STATUS_SHPREAMBLE) + tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; + break; + case AR_RX_STATUS_MT_OFDM: + switch (plcp[0] & 0xf) { + case 0xb: tap->wr_rate = 12; break; + case 0xf: tap->wr_rate = 18; break; + case 0xa: tap->wr_rate = 24; break; + case 0xe: tap->wr_rate = 36; break; + case 0x9: tap->wr_rate = 48; break; + case 0xd: tap->wr_rate = 72; break; + case 0x8: tap->wr_rate = 96; break; + case 0xc: tap->wr_rate = 108; break; + } + break; + } + mb.m_data = (caddr_t)tap; + mb.m_len = sc->sc_rxtap_len; + mb.m_next = m; + mb.m_nextpkt = NULL; + mb.m_type = 0; + mb.m_flags = 0; + bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN); + } +#endif + + /* Add RSSI/NF to this mbuf */ + bzero(&rxs, sizeof(rxs)); + rxs.r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI; + rxs.nf = sc->sc_nf[0]; /* XXX chain 0 != combined rssi/nf */ + rxs.rssi = tail->rssi; + /* XXX TODO: add MIMO RSSI/NF as well */ + ieee80211_add_rx_params(m, &rxs); + + /* XXX make a method */ + STAILQ_INSERT_TAIL(&rxq->mq_head, m, m_stailqpkt); + +#if 0 + OTUS_UNLOCK(sc); + ni = ieee80211_find_rxnode(ic, wh); + rxi.rxi_flags = 0; + rxi.rxi_rssi = tail->rssi; + rxi.rxi_tstamp = 0; /* unused */ + ieee80211_input(ifp, m, ni, &rxi); + + /* Node is no longer needed. */ + ieee80211_release_node(ic, ni); + OTUS_LOCK(sc); +#endif +} + +static void +otus_rxeof(struct usb_xfer *xfer, struct otus_data *data, struct mbufq *rxq) +{ + struct otus_softc *sc = usbd_xfer_softc(xfer); + caddr_t buf = data->buf; + struct ar_rx_head *head; + uint16_t hlen; + int len; + + usbd_xfer_status(xfer, &len, NULL, NULL, NULL); + + while (len >= sizeof (*head)) { + head = (struct ar_rx_head *)buf; + if (__predict_false(head->tag != htole16(AR_RX_HEAD_TAG))) { + OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, + "tag not valid 0x%x\n", le16toh(head->tag)); + break; + } + hlen = le16toh(head->len); + if (__predict_false(sizeof (*head) + hlen > len)) { + OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, + "xfer too short %d/%d\n", len, hlen); + break; + } + /* Process sub-xfer. */ + otus_sub_rxeof(sc, (uint8_t *)&head[1], hlen, rxq); + + /* Next sub-xfer is aligned on a 32-bit boundary. */ + hlen = (sizeof (*head) + hlen + 3) & ~3; + buf += hlen; + len -= hlen; + } +} + +static void +otus_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) +{ + struct otus_softc *sc = usbd_xfer_softc(xfer); + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_frame *wh; + struct ieee80211_node *ni; + struct mbuf *m; + struct mbufq scrx; + struct otus_data *data; + + OTUS_LOCK_ASSERT(sc); + + mbufq_init(&scrx, 1024); + +#if 0 + device_printf(sc->sc_dev, "%s: called; state=%d; error=%d\n", + __func__, + USB_GET_STATE(xfer), + error); +#endif + + switch (USB_GET_STATE(xfer)) { + case USB_ST_TRANSFERRED: + data = STAILQ_FIRST(&sc->sc_rx_active); + if (data == NULL) + goto tr_setup; + STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next); + otus_rxeof(xfer, data, &scrx); + STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); + /* FALLTHROUGH */ + case USB_ST_SETUP: +tr_setup: + /* + * XXX TODO: what if sc_rx isn't empty, but data + * is empty? Then we leak mbufs. + */ + data = STAILQ_FIRST(&sc->sc_rx_inactive); + if (data == NULL) { + //KASSERT(m == NULL, ("mbuf isn't NULL")); + return; + } + STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next); + STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next); + usbd_xfer_set_frame_data(xfer, 0, data->buf, + usbd_xfer_max_len(xfer)); + usbd_transfer_submit(xfer); + /* + * To avoid LOR we should unlock our private mutex here to call + * ieee80211_input() because here is at the end of a USB + * callback and safe to unlock. + */ + OTUS_UNLOCK(sc); + while ((m = mbufq_dequeue(&scrx)) != NULL) { + wh = mtod(m, struct ieee80211_frame *); + ni = ieee80211_find_rxnode(ic, + (struct ieee80211_frame_min *)wh); + if (ni != NULL) { + if (ni->ni_flags & IEEE80211_NODE_HT) + m->m_flags |= M_AMPDU; + (void)ieee80211_input_mimo(ni, m, NULL); + ieee80211_free_node(ni); + } else + (void)ieee80211_input_mimo_all(ic, m, NULL); + } +#ifdef IEEE80211_SUPPORT_SUPERG + ieee80211_ff_age_all(ic, 100); +#endif + OTUS_LOCK(sc); + break; + default: + /* needs it to the inactive queue due to a error. */ + data = STAILQ_FIRST(&sc->sc_rx_active); + if (data != NULL) { + STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next); + STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); + } + if (error != USB_ERR_CANCELLED) { + usbd_xfer_set_stall(xfer); + counter_u64_add(ic->ic_ierrors, 1); + goto tr_setup; + } + break; + } +} + +static void +otus_txeof(struct usb_xfer *xfer, struct otus_data *data) +{ + struct otus_softc *sc = usbd_xfer_softc(xfer); + + OTUS_DPRINTF(sc, OTUS_DEBUG_TXDONE, + "%s: called; data=%p\n", __func__, data); + + OTUS_LOCK_ASSERT(sc); + + if (sc->sc_tx_n_active == 0) { + device_printf(sc->sc_dev, + "%s: completed but tx_active=0\n", + __func__); + } else { + sc->sc_tx_n_active--; + } + + if (data->m) { + /* XXX status? */ + /* XXX we get TX status via the RX path.. */ + ieee80211_tx_complete(data->ni, data->m, 0); + data->m = NULL; + data->ni = NULL; + } +} + +static void +otus_txcmdeof(struct usb_xfer *xfer, struct otus_tx_cmd *cmd) +{ + struct otus_softc *sc = usbd_xfer_softc(xfer); + + OTUS_LOCK_ASSERT(sc); + + OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE, + "%s: called; data=%p; odata=%p\n", + __func__, cmd, cmd->odata); + + /* + * Non-response commands still need wakeup so the caller + * knows it was submitted and completed OK; response commands should + * wait until they're ACKed by the firmware with a response. + */ + if (cmd->odata) { + STAILQ_INSERT_TAIL(&sc->sc_cmd_waiting, cmd, next_cmd); + } else { + wakeup(cmd); + otus_free_txcmd(sc, cmd); + } +} + +static void +otus_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error) +{ + uint8_t which = OTUS_BULK_TX; + struct otus_softc *sc = usbd_xfer_softc(xfer); + struct ieee80211com *ic = &sc->sc_ic; + struct otus_data *data; + + OTUS_LOCK_ASSERT(sc); + + switch (USB_GET_STATE(xfer)) { + case USB_ST_TRANSFERRED: + data = STAILQ_FIRST(&sc->sc_tx_active[which]); + if (data == NULL) + goto tr_setup; + OTUS_DPRINTF(sc, OTUS_DEBUG_TXDONE, + "%s: transfer done %p\n", __func__, data); + STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next); + otus_txeof(xfer, data); + otus_freebuf(sc, data); + /* FALLTHROUGH */ + case USB_ST_SETUP: +tr_setup: + data = STAILQ_FIRST(&sc->sc_tx_pending[which]); + if (data == NULL) { + OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT, + "%s: empty pending queue sc %p\n", __func__, sc); + sc->sc_tx_n_active = 0; + goto finish; + } + STAILQ_REMOVE_HEAD(&sc->sc_tx_pending[which], next); + STAILQ_INSERT_TAIL(&sc->sc_tx_active[which], data, next); + usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen); + OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT, + "%s: submitting transfer %p\n", __func__, data); + usbd_transfer_submit(xfer); + sc->sc_tx_n_active++; + break; + default: + data = STAILQ_FIRST(&sc->sc_tx_active[which]); + if (data != NULL) { + STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next); + otus_txeof(xfer, data); + otus_freebuf(sc, data); + } + counter_u64_add(ic->ic_oerrors, 1); + + if (error != USB_ERR_CANCELLED) { + usbd_xfer_set_stall(xfer); + goto tr_setup; + } + break; + } + +finish: +#ifdef IEEE80211_SUPPORT_SUPERG + /* + * If the TX active queue drops below a certain + * threshold, ensure we age fast-frames out so they're + * transmitted. + */ + if (sc->sc_tx_n_active < 2) { + /* XXX ew - net80211 should defer this for us! */ + OTUS_UNLOCK(sc); + ieee80211_ff_flush(ic, WME_AC_VO); + ieee80211_ff_flush(ic, WME_AC_VI); + ieee80211_ff_flush(ic, WME_AC_BE); + ieee80211_ff_flush(ic, WME_AC_BK); + OTUS_LOCK(sc); + } +#endif + /* Kick TX */ + otus_tx_start(sc); +} + +static void +otus_bulk_cmd_callback(struct usb_xfer *xfer, usb_error_t error) +{ + struct otus_softc *sc = usbd_xfer_softc(xfer); +#if 0 + struct ieee80211com *ic = &sc->sc_ic; +#endif + struct otus_tx_cmd *cmd; + + OTUS_LOCK_ASSERT(sc); + + switch (USB_GET_STATE(xfer)) { + case USB_ST_TRANSFERRED: + cmd = STAILQ_FIRST(&sc->sc_cmd_active); + if (cmd == NULL) + goto tr_setup; + OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE, + "%s: transfer done %p\n", __func__, cmd); + STAILQ_REMOVE_HEAD(&sc->sc_cmd_active, next_cmd); + otus_txcmdeof(xfer, cmd); + /* FALLTHROUGH */ + case USB_ST_SETUP: +tr_setup: + cmd = STAILQ_FIRST(&sc->sc_cmd_pending); + if (cmd == NULL) { + OTUS_DPRINTF(sc, OTUS_DEBUG_CMD, + "%s: empty pending queue sc %p\n", __func__, sc); + return; + } + STAILQ_REMOVE_HEAD(&sc->sc_cmd_pending, next_cmd); + STAILQ_INSERT_TAIL(&sc->sc_cmd_active, cmd, next_cmd); + usbd_xfer_set_frame_data(xfer, 0, cmd->buf, cmd->buflen); + OTUS_DPRINTF(sc, OTUS_DEBUG_CMD, + "%s: submitting transfer %p; buf=%p, buflen=%d\n", __func__, cmd, cmd->buf, cmd->buflen); + usbd_transfer_submit(xfer); + break; + default: + cmd = STAILQ_FIRST(&sc->sc_cmd_active); + if (cmd != NULL) { + STAILQ_REMOVE_HEAD(&sc->sc_cmd_active, next_cmd); + otus_txcmdeof(xfer, cmd); + } + + if (error != USB_ERR_CANCELLED) { + usbd_xfer_set_stall(xfer); + goto tr_setup; + } + break; + } +} + +/* + * This isn't used by carl9170; it however may be used by the + * initial bootloader. + */ +static void +otus_bulk_irq_callback(struct usb_xfer *xfer, usb_error_t error) +{ + struct otus_softc *sc = usbd_xfer_softc(xfer); + int actlen; + int sumlen; + + usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); + OTUS_DPRINTF(sc, OTUS_DEBUG_IRQ, + "%s: called; state=%d\n", __func__, USB_GET_STATE(xfer)); + + switch (USB_GET_STATE(xfer)) { + case USB_ST_TRANSFERRED: + /* + * Read usb frame data, if any. + * "actlen" has the total length for all frames + * transferred. + */ + OTUS_DPRINTF(sc, OTUS_DEBUG_IRQ, + "%s: comp; %d bytes\n", + __func__, + actlen); +#if 0 + pc = usbd_xfer_get_frame(xfer, 0); + otus_dump_usb_rx_page(sc, pc, actlen); +#endif + /* XXX fallthrough */ + case USB_ST_SETUP: + /* + * Setup xfer frame lengths/count and data + */ + OTUS_DPRINTF(sc, OTUS_DEBUG_IRQ, "%s: setup\n", __func__); + usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); + usbd_transfer_submit(xfer); + break; + + default: /* Error */ + /* + * Print error message and clear stall + * for example. + */ + OTUS_DPRINTF(sc, OTUS_DEBUG_IRQ, "%s: ERROR?\n", __func__); + break; + } +} + +/* + * Map net80211 rate to hw rate for otus MAC/PHY. + */ +static uint8_t +otus_rate_to_hw_rate(struct otus_softc *sc, uint8_t rate) +{ + int is_2ghz; + + is_2ghz = !! (IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_curchan)); + + switch (rate) { + /* CCK */ + case 2: + return (0x0); + case 4: + return (0x1); + case 11: + return (0x2); + case 22: + return (0x3); + /* OFDM */ + case 12: + return (0xb); + case 18: + return (0xf); + case 24: + return (0xa); + case 36: + return (0xe); + case 48: + return (0x9); + case 72: + return (0xd); + case 96: + return (0x8); + case 108: + return (0xc); + default: + device_printf(sc->sc_dev, "%s: unknown rate '%d'\n", + __func__, (int) rate); + case 0: + if (is_2ghz) + return (0x0); /* 1MB CCK */ + else + return (0xb); /* 6MB OFDM */ + + /* XXX TODO: HT */ + } +} + +static int +otus_hw_rate_is_ofdm(struct otus_softc *sc, uint8_t hw_rate) +{ + + switch (hw_rate) { + case 0x0: + case 0x1: + case 0x2: + case 0x3: + return (0); + default: + return (1); + } +} + + +static void +otus_tx_update_ratectl(struct otus_softc *sc, struct ieee80211_node *ni) +{ + int tx, tx_success, tx_retry; + + tx = OTUS_NODE(ni)->tx_done; + tx_success = OTUS_NODE(ni)->tx_done - OTUS_NODE(ni)->tx_err; + tx_retry = OTUS_NODE(ni)->tx_retries; + + ieee80211_ratectl_tx_update(ni->ni_vap, ni, &tx, &tx_success, + &tx_retry); +} + +/* + * XXX TODO: support tx bpf parameters for configuration! + */ +static int +otus_tx(struct otus_softc *sc, struct ieee80211_node *ni, struct mbuf *m, + struct otus_data *data) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211_frame *wh; + struct ieee80211_key *k; + struct ar_tx_head *head; + uint32_t phyctl; + uint16_t macctl, qos; + uint8_t qid, rate; + int hasqos, xferlen; + + wh = mtod(m, struct ieee80211_frame *); + if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { + k = ieee80211_crypto_encap(ni, m); + if (k == NULL) { + device_printf(sc->sc_dev, + "%s: m=%p: ieee80211_crypto_encap returns NULL\n", + __func__, + m); + return (ENOBUFS); + } + wh = mtod(m, struct ieee80211_frame *); + } + + /* Calculate transfer length; ensure data buffer is large enough */ + xferlen = sizeof (*head) + m->m_pkthdr.len; + if (xferlen > OTUS_TXBUFSZ) { + device_printf(sc->sc_dev, + "%s: 802.11 TX frame is %d bytes, max %d bytes\n", + __func__, + xferlen, + OTUS_TXBUFSZ); + return (ENOBUFS); + } + + hasqos = !! IEEE80211_QOS_HAS_SEQ(wh); + + if (hasqos) { + uint8_t tid; + qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0]; + tid = qos & IEEE80211_QOS_TID; + qid = TID_TO_WME_AC(tid); + } else { + qos = 0; + qid = WME_AC_BE; + } + + /* Pickup a rate index. */ + if (IEEE80211_IS_MULTICAST(wh->i_addr1) || + (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA) { + /* Get lowest rate */ + rate = otus_rate_to_hw_rate(sc, 0); + } else { + (void) ieee80211_ratectl_rate(ni, NULL, 0); + rate = otus_rate_to_hw_rate(sc, ni->ni_txrate); + } + + phyctl = 0; + macctl = AR_TX_MAC_BACKOFF | AR_TX_MAC_HW_DUR | AR_TX_MAC_QID(qid); + + if (IEEE80211_IS_MULTICAST(wh->i_addr1) || + (hasqos && ((qos & IEEE80211_QOS_ACKPOLICY) == + IEEE80211_QOS_ACKPOLICY_NOACK))) + macctl |= AR_TX_MAC_NOACK; + + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { + if (m->m_pkthdr.len + IEEE80211_CRC_LEN >= vap->iv_rtsthreshold) + macctl |= AR_TX_MAC_RTS; + else if (ic->ic_flags & IEEE80211_F_USEPROT) { + if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) + macctl |= AR_TX_MAC_CTS; + else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) + macctl |= AR_TX_MAC_RTS; + } + } + + phyctl |= AR_TX_PHY_MCS(rate); + if (otus_hw_rate_is_ofdm(sc, rate)) { + phyctl |= AR_TX_PHY_MT_OFDM; + /* Always use all tx antennas for now, just to be safe */ + phyctl |= AR_TX_PHY_ANTMSK(sc->txmask); + } else { /* CCK */ + phyctl |= AR_TX_PHY_MT_CCK; + phyctl |= AR_TX_PHY_ANTMSK(sc->txmask); + } + + /* Update net80211 with the current counters */ + otus_tx_update_ratectl(sc, ni); + + /* Update rate control stats for frames that are ACK'ed. */ + if (!(macctl & AR_TX_MAC_NOACK)) + OTUS_NODE(ni)->tx_done++; + + + /* Fill Tx descriptor. */ + head = (struct ar_tx_head *)data->buf; + head->len = htole16(m->m_pkthdr.len + IEEE80211_CRC_LEN); + head->macctl = htole16(macctl); + head->phyctl = htole32(phyctl); + + m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)&head[1]); + + data->buflen = xferlen; + data->ni = ni; + data->m = m; + + OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT, + "%s: tx: m=%p; data=%p; len=%d mac=0x%04x phy=0x%08x rate=0x%02x, ni_txrate=%d\n", + __func__, m, data, head->len, head->macctl, head->phyctl, + (int) rate, (int) ni->ni_txrate); + + /* Submit transfer */ + STAILQ_INSERT_TAIL(&sc->sc_tx_pending[OTUS_BULK_TX], data, next); + usbd_transfer_start(sc->sc_xfer[OTUS_BULK_TX]); + + return 0; +} + +int +otus_set_multi(struct otus_softc *sc) +{ + uint32_t lo, hi; + struct ieee80211com *ic = &sc->sc_ic; + int r; + + if (ic->ic_allmulti > 0 || ic->ic_promisc > 0 || + ic->ic_opmode == IEEE80211_M_MONITOR) { + lo = 0xffffffff; + hi = 0xffffffff; + } else { + struct ieee80211vap *vap; + struct ifnet *ifp; + struct ifmultiaddr *ifma; + + lo = hi = 0; + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { + ifp = vap->iv_ifp; + if_maddr_rlock(ifp); + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + caddr_t dl; + uint32_t val; + + dl = LLADDR((struct sockaddr_dl *) ifma->ifma_addr); + val = LE_READ_4(dl + 4); + /* Get address byte 5 */ + val = val & 0x0000ff00; + val = val >> 8; + + /* As per below, shift it >> 2 to get only 6 bits */ + val = val >> 2; + if (val < 32) + lo |= 1 << val; + else + hi |= 1 << (val - 32); + } + if_maddr_runlock(ifp); + } + } +#if 0 + /* XXX openbsd code */ + while (enm != NULL) { + bit = enm->enm_addrlo[5] >> 2; + if (bit < 32) + lo |= 1 << bit; + else + hi |= 1 << (bit - 32); + ETHER_NEXT_MULTI(step, enm); + } +#endif + + hi |= 1U << 31; /* Make sure the broadcast bit is set. */ + + OTUS_LOCK(sc); + otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_L, lo); + otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_H, hi); + r = otus_write_barrier(sc); + OTUS_UNLOCK(sc); + return (r); +} + +static void +otus_updateedca(struct otus_softc *sc) +{ +#define EXP2(val) ((1 << (val)) - 1) +#define AIFS(val) ((val) * 9 + 10) + struct ieee80211com *ic = &sc->sc_ic; + const struct wmeParams *edca; + + OTUS_LOCK_ASSERT(sc); + + edca = ic->ic_wme.wme_chanParams.cap_wmeParams; + + /* Set CWmin/CWmax values. */ + otus_write(sc, AR_MAC_REG_AC0_CW, + EXP2(edca[WME_AC_BE].wmep_logcwmax) << 16 | + EXP2(edca[WME_AC_BE].wmep_logcwmin)); + otus_write(sc, AR_MAC_REG_AC1_CW, + EXP2(edca[WME_AC_BK].wmep_logcwmax) << 16 | + EXP2(edca[WME_AC_BK].wmep_logcwmin)); + otus_write(sc, AR_MAC_REG_AC2_CW, + EXP2(edca[WME_AC_VI].wmep_logcwmax) << 16 | + EXP2(edca[WME_AC_VI].wmep_logcwmin)); + otus_write(sc, AR_MAC_REG_AC3_CW, + EXP2(edca[WME_AC_VO].wmep_logcwmax) << 16 | + EXP2(edca[WME_AC_VO].wmep_logcwmin)); + otus_write(sc, AR_MAC_REG_AC4_CW, /* Special TXQ. */ + EXP2(edca[WME_AC_VO].wmep_logcwmax) << 16 | + EXP2(edca[WME_AC_VO].wmep_logcwmin)); + + /* Set AIFSN values. */ + otus_write(sc, AR_MAC_REG_AC1_AC0_AIFS, + AIFS(edca[WME_AC_VI].wmep_aifsn) << 24 | + AIFS(edca[WME_AC_BK].wmep_aifsn) << 12 | + AIFS(edca[WME_AC_BE].wmep_aifsn)); + otus_write(sc, AR_MAC_REG_AC3_AC2_AIFS, + AIFS(edca[WME_AC_VO].wmep_aifsn) << 16 | /* Special TXQ. */ + AIFS(edca[WME_AC_VO].wmep_aifsn) << 4 | + AIFS(edca[WME_AC_VI].wmep_aifsn) >> 8); + + /* Set TXOP limit. */ + otus_write(sc, AR_MAC_REG_AC1_AC0_TXOP, + edca[WME_AC_BK].wmep_txopLimit << 16 | + edca[WME_AC_BE].wmep_txopLimit); + otus_write(sc, AR_MAC_REG_AC3_AC2_TXOP, + edca[WME_AC_VO].wmep_txopLimit << 16 | + edca[WME_AC_VI].wmep_txopLimit); + + /* XXX ACK policy? */ + + (void)otus_write_barrier(sc); + +#undef AIFS +#undef EXP2 +} + +static void +otus_updateslot(struct otus_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + uint32_t slottime; + + OTUS_LOCK_ASSERT(sc); + + slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; + otus_write(sc, AR_MAC_REG_SLOT_TIME, slottime << 10); + (void)otus_write_barrier(sc); +} + +int +otus_init_mac(struct otus_softc *sc) +{ + int error; + + OTUS_LOCK_ASSERT(sc); + + otus_write(sc, AR_MAC_REG_ACK_EXTENSION, 0x40); + otus_write(sc, AR_MAC_REG_RETRY_MAX, 0); + otus_write(sc, AR_MAC_REG_SNIFFER, 0x2000000); + otus_write(sc, AR_MAC_REG_RX_THRESHOLD, 0xc1f80); + otus_write(sc, AR_MAC_REG_RX_PE_DELAY, 0x70); + otus_write(sc, AR_MAC_REG_EIFS_AND_SIFS, 0xa144000); + otus_write(sc, AR_MAC_REG_SLOT_TIME, 9 << 10); + otus_write(sc, 0x1c3b2c, 0x19000000); + /* NAV protects ACK only (in TXOP). */ + otus_write(sc, 0x1c3b38, 0x201); + /* Set beacon Tx power to 0x7. */ + otus_write(sc, AR_MAC_REG_BCN_HT1, 0x8000170); + otus_write(sc, AR_MAC_REG_BACKOFF_PROTECT, 0x105); + otus_write(sc, 0x1c3b9c, 0x10000a); + /* Filter any control frames, BAR is bit 24. */ + otus_write(sc, 0x1c368c, 0x0500ffff); + otus_write(sc, 0x1c3c40, 0x1); + otus_write(sc, AR_MAC_REG_BASIC_RATE, 0x150f); + otus_write(sc, AR_MAC_REG_MANDATORY_RATE, 0x150f); + otus_write(sc, AR_MAC_REG_RTS_CTS_RATE, 0x10b01bb); + otus_write(sc, 0x1c3694, 0x4003c1e); + /* Enable LED0 and LED1. */ + otus_write(sc, 0x1d0100, 0x3); + otus_write(sc, 0x1d0104, 0x3); + /* Switch MAC to OTUS interface. */ + otus_write(sc, 0x1c3600, 0x3); + otus_write(sc, 0x1c3c50, 0xffff); + otus_write(sc, 0x1c3680, 0xf00008); + /* Disable Rx timeout (workaround). */ + otus_write(sc, 0x1c362c, 0); + + /* Set USB Rx stream mode maximum frame number to 2. */ + otus_write(sc, 0x1e1110, 0x4); + /* Set USB Rx stream mode timeout to 10us. */ + otus_write(sc, 0x1e1114, 0x80); + + /* Set clock frequency to 88/80MHz. */ + otus_write(sc, 0x1d4008, 0x73); + /* Set WLAN DMA interrupt mode: generate intr per packet. */ + otus_write(sc, 0x1c3d7c, 0x110011); + otus_write(sc, 0x1c3bb0, 0x4); + otus_write(sc, AR_MAC_REG_TXOP_NOT_ENOUGH_INDICATION, 0x141e0f48); + + /* Disable HW decryption for now. */ + otus_write(sc, 0x1c3678, 0x78); + + if ((error = otus_write_barrier(sc)) != 0) + return error; + + /* Set default EDCA parameters. */ + otus_updateedca(sc); + + return 0; +} + +/* + * Return default value for PHY register based on current operating mode. + */ +uint32_t +otus_phy_get_def(struct otus_softc *sc, uint32_t reg) +{ + int i; + + for (i = 0; i < nitems(ar5416_phy_regs); i++) + if (AR_PHY(ar5416_phy_regs[i]) == reg) + return sc->phy_vals[i]; + return 0; /* Register not found. */ +} + +/* + * Update PHY's programming based on vendor-specific data stored in EEPROM. + * This is for FEM-type devices only. + */ +int +otus_set_board_values(struct otus_softc *sc, struct ieee80211_channel *c) +{ + const struct ModalEepHeader *eep; + uint32_t tmp, offset; + + if (IEEE80211_IS_CHAN_5GHZ(c)) + eep = &sc->eeprom.modalHeader[0]; + else + eep = &sc->eeprom.modalHeader[1]; + + /* Offset of chain 2. */ + offset = 2 * 0x1000; + + tmp = le32toh(eep->antCtrlCommon); + otus_write(sc, AR_PHY_SWITCH_COM, tmp); + + tmp = le32toh(eep->antCtrlChain[0]); + otus_write(sc, AR_PHY_SWITCH_CHAIN_0, tmp); + + tmp = le32toh(eep->antCtrlChain[1]); + otus_write(sc, AR_PHY_SWITCH_CHAIN_0 + offset, tmp); + + if (1 /* sc->sc_sco == AR_SCO_SCN */) { + tmp = otus_phy_get_def(sc, AR_PHY_SETTLING); + tmp &= ~(0x7f << 7); + tmp |= (eep->switchSettling & 0x7f) << 7; + otus_write(sc, AR_PHY_SETTLING, tmp); + } + + tmp = otus_phy_get_def(sc, AR_PHY_DESIRED_SZ); + tmp &= ~0xffff; + tmp |= eep->pgaDesiredSize << 8 | eep->adcDesiredSize; + otus_write(sc, AR_PHY_DESIRED_SZ, tmp); + + tmp = eep->txEndToXpaOff << 24 | eep->txEndToXpaOff << 16 | + eep->txFrameToXpaOn << 8 | eep->txFrameToXpaOn; + otus_write(sc, AR_PHY_RF_CTL4, tmp); + + tmp = otus_phy_get_def(sc, AR_PHY_RF_CTL3); + tmp &= ~(0xff << 16); + tmp |= eep->txEndToRxOn << 16; + otus_write(sc, AR_PHY_RF_CTL3, tmp); + + tmp = otus_phy_get_def(sc, AR_PHY_CCA); + tmp &= ~(0x7f << 12); + tmp |= (eep->thresh62 & 0x7f) << 12; + otus_write(sc, AR_PHY_CCA, tmp); + + tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN); + tmp &= ~(0x3f << 12); + tmp |= (eep->txRxAttenCh[0] & 0x3f) << 12; + otus_write(sc, AR_PHY_RXGAIN, tmp); + + tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN + offset); + tmp &= ~(0x3f << 12); + tmp |= (eep->txRxAttenCh[1] & 0x3f) << 12; + otus_write(sc, AR_PHY_RXGAIN + offset, tmp); + + tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ); + tmp &= ~(0x3f << 18); + tmp |= (eep->rxTxMarginCh[0] & 0x3f) << 18; + if (IEEE80211_IS_CHAN_5GHZ(c)) { + tmp &= ~(0xf << 10); + tmp |= (eep->bswMargin[0] & 0xf) << 10; + } + otus_write(sc, AR_PHY_GAIN_2GHZ, tmp); + + tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ + offset); + tmp &= ~(0x3f << 18); + tmp |= (eep->rxTxMarginCh[1] & 0x3f) << 18; + otus_write(sc, AR_PHY_GAIN_2GHZ + offset, tmp); + + tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4); + tmp &= ~(0x3f << 5 | 0x1f); + tmp |= (eep->iqCalICh[0] & 0x3f) << 5 | (eep->iqCalQCh[0] & 0x1f); + otus_write(sc, AR_PHY_TIMING_CTRL4, tmp); + + tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4 + offset); + tmp &= ~(0x3f << 5 | 0x1f); + tmp |= (eep->iqCalICh[1] & 0x3f) << 5 | (eep->iqCalQCh[1] & 0x1f); + otus_write(sc, AR_PHY_TIMING_CTRL4 + offset, tmp); + + tmp = otus_phy_get_def(sc, AR_PHY_TPCRG1); + tmp &= ~(0xf << 16); + tmp |= (eep->xpd & 0xf) << 16; + otus_write(sc, AR_PHY_TPCRG1, tmp); + + return otus_write_barrier(sc); +} + +int +otus_program_phy(struct otus_softc *sc, struct ieee80211_channel *c) +{ + const uint32_t *vals; + int error, i; + + /* Select PHY programming based on band and bandwidth. */ + if (IEEE80211_IS_CHAN_2GHZ(c)) + vals = ar5416_phy_vals_2ghz_20mhz; + else + vals = ar5416_phy_vals_5ghz_20mhz; + for (i = 0; i < nitems(ar5416_phy_regs); i++) + otus_write(sc, AR_PHY(ar5416_phy_regs[i]), vals[i]); + sc->phy_vals = vals; + + if (sc->eeprom.baseEepHeader.deviceType == 0x80) /* FEM */ + if ((error = otus_set_board_values(sc, c)) != 0) + return error; + + /* Initial Tx power settings. */ + otus_write(sc, AR_PHY_POWER_TX_RATE_MAX, 0x7f); + otus_write(sc, AR_PHY_POWER_TX_RATE1, 0x3f3f3f3f); + otus_write(sc, AR_PHY_POWER_TX_RATE2, 0x3f3f3f3f); + otus_write(sc, AR_PHY_POWER_TX_RATE3, 0x3f3f3f3f); + otus_write(sc, AR_PHY_POWER_TX_RATE4, 0x3f3f3f3f); + otus_write(sc, AR_PHY_POWER_TX_RATE5, 0x3f3f3f3f); + otus_write(sc, AR_PHY_POWER_TX_RATE6, 0x3f3f3f3f); + otus_write(sc, AR_PHY_POWER_TX_RATE7, 0x3f3f3f3f); + otus_write(sc, AR_PHY_POWER_TX_RATE8, 0x3f3f3f3f); + otus_write(sc, AR_PHY_POWER_TX_RATE9, 0x3f3f3f3f); + + if (IEEE80211_IS_CHAN_2GHZ(c)) + otus_write(sc, 0x1d4014, 0x5163); + else + otus_write(sc, 0x1d4014, 0x5143); + + return otus_write_barrier(sc); +} + +static __inline uint8_t +otus_reverse_bits(uint8_t v) +{ + v = ((v >> 1) & 0x55) | ((v & 0x55) << 1); + v = ((v >> 2) & 0x33) | ((v & 0x33) << 2); + v = ((v >> 4) & 0x0f) | ((v & 0x0f) << 4); + return v; +} + +int +otus_set_rf_bank4(struct otus_softc *sc, struct ieee80211_channel *c) +{ + uint8_t chansel, d0, d1; + uint16_t data; + int error; + + OTUS_LOCK_ASSERT(sc); + + d0 = 0; + if (IEEE80211_IS_CHAN_5GHZ(c)) { + chansel = (c->ic_freq - 4800) / 5; + if (chansel & 1) + d0 |= AR_BANK4_AMODE_REFSEL(2); + else + d0 |= AR_BANK4_AMODE_REFSEL(1); + } else { + d0 |= AR_BANK4_AMODE_REFSEL(2); + if (c->ic_freq == 2484) { /* CH 14 */ + d0 |= AR_BANK4_BMODE_LF_SYNTH_FREQ; + chansel = 10 + (c->ic_freq - 2274) / 5; + } else + chansel = 16 + (c->ic_freq - 2272) / 5; + chansel <<= 2; + } + d0 |= AR_BANK4_ADDR(1) | AR_BANK4_CHUP; + d1 = otus_reverse_bits(chansel); + + /* Write bits 0-4 of d0 and d1. */ + data = (d1 & 0x1f) << 5 | (d0 & 0x1f); + otus_write(sc, AR_PHY(44), data); + /* Write bits 5-7 of d0 and d1. */ + data = (d1 >> 5) << 5 | (d0 >> 5); + otus_write(sc, AR_PHY(58), data); + + if ((error = otus_write_barrier(sc)) == 0) + otus_delay_ms(sc, 10); + return error; +} + +void +otus_get_delta_slope(uint32_t coeff, uint32_t *exponent, uint32_t *mantissa) +{ +#define COEFF_SCALE_SHIFT 24 + uint32_t exp, man; + + /* exponent = 14 - floor(log2(coeff)) */ + for (exp = 31; exp > 0; exp--) + if (coeff & (1 << exp)) + break; + KASSERT(exp != 0, ("exp")); + exp = 14 - (exp - COEFF_SCALE_SHIFT); + + /* mantissa = floor(coeff * 2^exponent + 0.5) */ + man = coeff + (1 << (COEFF_SCALE_SHIFT - exp - 1)); + + *mantissa = man >> (COEFF_SCALE_SHIFT - exp); + *exponent = exp - 16; +#undef COEFF_SCALE_SHIFT +} + +static int +otus_set_chan(struct otus_softc *sc, struct ieee80211_channel *c, int assoc) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct ar_cmd_frequency cmd; + struct ar_rsp_frequency rsp; + const uint32_t *vals; + uint32_t coeff, exp, man, tmp; + uint8_t code; + int error, chan, i; + + error = 0; + chan = ieee80211_chan2ieee(ic, c); + + OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, + "setting channel %d (%dMHz)\n", chan, c->ic_freq); + + tmp = IEEE80211_IS_CHAN_2GHZ(c) ? 0x105 : 0x104; + otus_write(sc, AR_MAC_REG_DYNAMIC_SIFS_ACK, tmp); + if ((error = otus_write_barrier(sc)) != 0) + goto finish; + + /* Disable BB Heavy Clip. */ + otus_write(sc, AR_PHY_HEAVY_CLIP_ENABLE, 0x200); + if ((error = otus_write_barrier(sc)) != 0) + goto finish; + + /* XXX Is that FREQ_START ? */ + error = otus_cmd(sc, AR_CMD_FREQ_STRAT, NULL, 0, NULL, 0); + if (error != 0) + goto finish; + + /* Reprogram PHY and RF on channel band or bandwidth changes. */ + if (sc->bb_reset || c->ic_flags != sc->sc_curchan->ic_flags) { + OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, "band switch\n"); + + /* Cold/Warm reset BB/ADDA. */ + otus_write(sc, 0x1d4004, sc->bb_reset ? 0x800 : 0x400); + if ((error = otus_write_barrier(sc)) != 0) + goto finish; + otus_write(sc, 0x1d4004, 0); + if ((error = otus_write_barrier(sc)) != 0) + goto finish; + sc->bb_reset = 0; + + if ((error = otus_program_phy(sc, c)) != 0) { + device_printf(sc->sc_dev, + "%s: could not program PHY\n", + __func__); + goto finish; + } + + /* Select RF programming based on band. */ + if (IEEE80211_IS_CHAN_5GHZ(c)) + vals = ar5416_banks_vals_5ghz; + else + vals = ar5416_banks_vals_2ghz; + for (i = 0; i < nitems(ar5416_banks_regs); i++) + otus_write(sc, AR_PHY(ar5416_banks_regs[i]), vals[i]); + if ((error = otus_write_barrier(sc)) != 0) { + device_printf(sc->sc_dev, + "%s: could not program RF\n", + __func__); + goto finish; + } + code = AR_CMD_RF_INIT; + } else { + code = AR_CMD_FREQUENCY; + } + + if ((error = otus_set_rf_bank4(sc, c)) != 0) + goto finish; + + tmp = (sc->txmask == 0x5) ? 0x340 : 0x240; + otus_write(sc, AR_PHY_TURBO, tmp); + if ((error = otus_write_barrier(sc)) != 0) + goto finish; + + /* Send firmware command to set channel. */ + cmd.freq = htole32((uint32_t)c->ic_freq * 1000); + cmd.dynht2040 = htole32(0); + cmd.htena = htole32(1); + /* Set Delta Slope (exponent and mantissa). */ + coeff = (100 << 24) / c->ic_freq; + otus_get_delta_slope(coeff, &exp, &man); + cmd.dsc_exp = htole32(exp); + cmd.dsc_man = htole32(man); + OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, + "ds coeff=%u exp=%u man=%u\n", coeff, exp, man); + /* For Short GI, coeff is 9/10 that of normal coeff. */ + coeff = (9 * coeff) / 10; + otus_get_delta_slope(coeff, &exp, &man); + cmd.dsc_shgi_exp = htole32(exp); + cmd.dsc_shgi_man = htole32(man); + OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, + "ds shgi coeff=%u exp=%u man=%u\n", coeff, exp, man); + /* Set wait time for AGC and noise calibration (100 or 200ms). */ + cmd.check_loop_count = assoc ? htole32(2000) : htole32(1000); + OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, + "%s\n", (code == AR_CMD_RF_INIT) ? "RF_INIT" : "FREQUENCY"); + error = otus_cmd(sc, code, &cmd, sizeof cmd, &rsp, sizeof(rsp)); + if (error != 0) + goto finish; + if ((rsp.status & htole32(AR_CAL_ERR_AGC | AR_CAL_ERR_NF_VAL)) != 0) { + OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, + "status=0x%x\n", le32toh(rsp.status)); + /* Force cold reset on next channel. */ + sc->bb_reset = 1; + } +#ifdef USB_DEBUG + if (otus_debug & OTUS_DEBUG_RESET) { + device_printf(sc->sc_dev, "calibration status=0x%x\n", + le32toh(rsp.status)); + for (i = 0; i < 2; i++) { /* 2 Rx chains */ + /* Sign-extend 9-bit NF values. */ + device_printf(sc->sc_dev, + "noisefloor chain %d=%d\n", i, + (((int32_t)le32toh(rsp.nf[i])) << 4) >> 23); + device_printf(sc->sc_dev, + "noisefloor ext chain %d=%d\n", i, + ((int32_t)le32toh(rsp.nf_ext[i])) >> 23); + } + } +#endif + for (i = 0; i < OTUS_NUM_CHAINS; i++) { + sc->sc_nf[i] = ((((int32_t)le32toh(rsp.nf[i])) << 4) >> 23); + } + sc->sc_curchan = c; +finish: + return (error); +} + +#ifdef notyet +int +otus_set_key(struct ieee80211com *ic, struct ieee80211_node *ni, + struct ieee80211_key *k) +{ + struct otus_softc *sc = ic->ic_softc; + struct otus_cmd_key cmd; + + /* Defer setting of WEP keys until interface is brought up. */ + if ((ic->ic_if.if_flags & (IFF_UP | IFF_RUNNING)) != + (IFF_UP | IFF_RUNNING)) + return 0; + + /* Do it in a process context. */ + cmd.key = *k; + cmd.associd = (ni != NULL) ? ni->ni_associd : 0; + otus_do_async(sc, otus_set_key_cb, &cmd, sizeof cmd); + return 0; +} + +void +otus_set_key_cb(struct otus_softc *sc, void *arg) +{ + struct otus_cmd_key *cmd = arg; + struct ieee80211_key *k = &cmd->key; + struct ar_cmd_ekey key; + uint16_t cipher; + int error; + + memset(&key, 0, sizeof key); + if (k->k_flags & IEEE80211_KEY_GROUP) { + key.uid = htole16(k->k_id); + IEEE80211_ADDR_COPY(key.macaddr, sc->sc_ic.ic_myaddr); + key.macaddr[0] |= 0x80; + } else { + key.uid = htole16(OTUS_UID(cmd->associd)); + IEEE80211_ADDR_COPY(key.macaddr, ni->ni_macaddr); + } + key.kix = htole16(0); + /* Map net80211 cipher to hardware. */ + switch (k->k_cipher) { + case IEEE80211_CIPHER_WEP40: + cipher = AR_CIPHER_WEP64; + break; + case IEEE80211_CIPHER_WEP104: + cipher = AR_CIPHER_WEP128; + break; + case IEEE80211_CIPHER_TKIP: + cipher = AR_CIPHER_TKIP; + break; + case IEEE80211_CIPHER_CCMP: + cipher = AR_CIPHER_AES; + break; + default: + return; + } + key.cipher = htole16(cipher); + memcpy(key.key, k->k_key, MIN(k->k_len, 16)); + error = otus_cmd(sc, AR_CMD_EKEY, &key, sizeof key, NULL, 0); + if (error != 0 || k->k_cipher != IEEE80211_CIPHER_TKIP) + return; + + /* TKIP: set Tx/Rx MIC Key. */ + key.kix = htole16(1); + memcpy(key.key, k->k_key + 16, 16); + (void)otus_cmd(sc, AR_CMD_EKEY, &key, sizeof key, NULL, 0); +} + +void +otus_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, + struct ieee80211_key *k) +{ + struct otus_softc *sc = ic->ic_softc; + struct otus_cmd_key cmd; + + if (!(ic->ic_if.if_flags & IFF_RUNNING) || + ic->ic_state != IEEE80211_S_RUN) + return; /* Nothing to do. */ + + /* Do it in a process context. */ + cmd.key = *k; + cmd.associd = (ni != NULL) ? ni->ni_associd : 0; + otus_do_async(sc, otus_delete_key_cb, &cmd, sizeof cmd); +} + +void +otus_delete_key_cb(struct otus_softc *sc, void *arg) +{ + struct otus_cmd_key *cmd = arg; + struct ieee80211_key *k = &cmd->key; + uint32_t uid; + + if (k->k_flags & IEEE80211_KEY_GROUP) + uid = htole32(k->k_id); + else + uid = htole32(OTUS_UID(cmd->associd)); + (void)otus_cmd(sc, AR_CMD_DKEY, &uid, sizeof uid, NULL, 0); +} +#endif + +/* + * XXX TODO: check if we have to be doing any calibration in the host + * or whether it's purely a firmware thing. + */ +void +otus_calibrate_to(void *arg, int pending) +{ +#if 0 + struct otus_softc *sc = arg; + + device_printf(sc->sc_dev, "%s: called\n", __func__); + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_node *ni; + int s; + + if (usbd_is_dying(sc->sc_udev)) + return; + + usbd_ref_incr(sc->sc_udev); + + s = splnet(); + ni = ic->ic_bss; + ieee80211_amrr_choose(&sc->amrr, ni, &((struct otus_node *)ni)->amn); + splx(s); + + if (!usbd_is_dying(sc->sc_udev)) + timeout_add_sec(&sc->calib_to, 1); + + usbd_ref_decr(sc->sc_udev); +#endif +} + +int +otus_set_bssid(struct otus_softc *sc, const uint8_t *bssid) +{ + + OTUS_LOCK_ASSERT(sc); + + otus_write(sc, AR_MAC_REG_BSSID_L, + bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24); + otus_write(sc, AR_MAC_REG_BSSID_H, + bssid[4] | bssid[5] << 8); + return otus_write_barrier(sc); +} + +int +otus_set_macaddr(struct otus_softc *sc, const uint8_t *addr) +{ + OTUS_LOCK_ASSERT(sc); + + otus_write(sc, AR_MAC_REG_MAC_ADDR_L, + addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24); + otus_write(sc, AR_MAC_REG_MAC_ADDR_H, + addr[4] | addr[5] << 8); + return otus_write_barrier(sc); +} + +/* Default single-LED. */ +void +otus_led_newstate_type1(struct otus_softc *sc) +{ + /* TBD */ + device_printf(sc->sc_dev, "%s: TODO\n", __func__); +} + +/* NETGEAR, dual-LED. */ +void +otus_led_newstate_type2(struct otus_softc *sc) +{ + /* TBD */ + device_printf(sc->sc_dev, "%s: TODO\n", __func__); +} + +/* NETGEAR, single-LED/3 colors (blue, red, purple.) */ +void +otus_led_newstate_type3(struct otus_softc *sc) +{ +#if 0 + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + + uint32_t state = sc->led_state; + + OTUS_LOCK_ASSERT(sc); + + if (!vap) { + state = 0; /* led off */ + } else if (vap->iv_state == IEEE80211_S_INIT) { + state = 0; /* LED off. */ + } else if (vap->iv_state == IEEE80211_S_RUN) { + /* Associated, LED always on. */ + if (IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan)) + state = AR_LED0_ON; /* 2GHz=>Red. */ + else + state = AR_LED1_ON; /* 5GHz=>Blue. */ + } else { + /* Scanning, blink LED. */ + state ^= AR_LED0_ON | AR_LED1_ON; + if (IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan)) + state &= ~AR_LED1_ON; + else + state &= ~AR_LED0_ON; + } + if (state != sc->led_state) { + otus_write(sc, 0x1d0104, state); + if (otus_write_barrier(sc) == 0) + sc->led_state = state; + } +#endif +} + +int +otus_init(struct otus_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + int error; + + OTUS_UNLOCK_ASSERT(sc); + + OTUS_LOCK(sc); + + /* Drain any pending TX frames */ + otus_drain_mbufq(sc); + + /* Init MAC */ + if ((error = otus_init_mac(sc)) != 0) { + OTUS_UNLOCK(sc); + device_printf(sc->sc_dev, + "%s: could not initialize MAC\n", __func__); + return error; + } + + (void) otus_set_macaddr(sc, ic->ic_macaddr); + +#if 0 + switch (ic->ic_opmode) { +#ifdef notyet +#ifndef IEEE80211_STA_ONLY + case IEEE80211_M_HOSTAP: + otus_write(sc, 0x1c3700, 0x0f0000a1); + otus_write(sc, 0x1c3c40, 0x1); + break; + case IEEE80211_M_IBSS: + otus_write(sc, 0x1c3700, 0x0f000000); + otus_write(sc, 0x1c3c40, 0x1); + break; +#endif +#endif + case IEEE80211_M_STA: + otus_write(sc, 0x1c3700, 0x0f000002); + otus_write(sc, 0x1c3c40, 0x1); + break; + default: + break; + } +#endif + + /* Expect STA operation */ + otus_write(sc, 0x1c3700, 0x0f000002); + otus_write(sc, 0x1c3c40, 0x1); + + /* XXX ic_opmode? */ + otus_write(sc, AR_MAC_REG_SNIFFER, + (ic->ic_opmode == IEEE80211_M_MONITOR) ? 0x2000001 : 0x2000000); + (void)otus_write_barrier(sc); + + sc->bb_reset = 1; /* Force cold reset. */ + + if ((error = otus_set_chan(sc, ic->ic_curchan, 0)) != 0) { + OTUS_UNLOCK(sc); + device_printf(sc->sc_dev, + "%s: could not set channel\n", __func__); + return error; + } + + /* Start Rx. */ + otus_write(sc, 0x1c3d30, 0x100); + (void)otus_write_barrier(sc); + + sc->sc_running = 1; + + OTUS_UNLOCK(sc); + return 0; +} + +void +otus_stop(struct otus_softc *sc) +{ +#if 0 + int s; +#endif + + OTUS_UNLOCK_ASSERT(sc); + + OTUS_LOCK(sc); + sc->sc_running = 0; + sc->sc_tx_timer = 0; + OTUS_UNLOCK(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; + /* Stop Rx. */ + otus_write(sc, 0x1c3d30, 0); + (void)otus_write_barrier(sc); + + /* Drain any pending TX frames */ + otus_drain_mbufq(sc); + + OTUS_UNLOCK(sc); +} diff --git a/sys/dev/otus/if_otusreg.h b/sys/dev/otus/if_otusreg.h new file mode 100644 index 0000000..4f11b8d --- /dev/null +++ b/sys/dev/otus/if_otusreg.h @@ -0,0 +1,1030 @@ +/* $OpenBSD: if_otusreg.h,v 1.9 2013/11/26 20:33:18 deraadt Exp $ */ + +/*- + * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * Copyright (c) 2015 Adrian Chadd <adrian@FreeBSD.org> + * + * 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 __IF_OTUSREG_H__ +#define __IF_OTUSREG_H__ + +/* USB Endpoints addresses. */ +#define AR_EPT_BULK_TX_NO (UE_DIR_OUT | 1) +#define AR_EPT_BULK_RX_NO (UE_DIR_IN | 2) +#define AR_EPT_INTR_RX_NO (UE_DIR_IN | 3) +#define AR_EPT_INTR_TX_NO (UE_DIR_OUT | 4) + +/* USB Requests. */ +#define AR_FW_DOWNLOAD 0x30 +#define AR_FW_DOWNLOAD_COMPLETE 0x31 + +/* Maximum number of writes that can fit in a single FW command is 7. */ +#define AR_MAX_WRITE_IDX 6 /* 56 bytes */ + +#define AR_FW_INIT_ADDR 0x102800 +#define AR_FW_MAIN_ADDR 0x200000 +#define AR_USB_MODE_CTRL 0x1e1108 + +/* + * AR9170 MAC registers. + */ +#define AR_MAC_REG_BASE 0x1c3000 +#define AR_MAC_REG_MAC_ADDR_L (AR_MAC_REG_BASE + 0x610) +#define AR_MAC_REG_MAC_ADDR_H (AR_MAC_REG_BASE + 0x614) +#define AR_MAC_REG_BSSID_L (AR_MAC_REG_BASE + 0x618) +#define AR_MAC_REG_BSSID_H (AR_MAC_REG_BASE + 0x61c) +#define AR_MAC_REG_GROUP_HASH_TBL_L (AR_MAC_REG_BASE + 0x624) +#define AR_MAC_REG_GROUP_HASH_TBL_H (AR_MAC_REG_BASE + 0x628) +#define AR_MAC_REG_BASIC_RATE (AR_MAC_REG_BASE + 0x630) +#define AR_MAC_REG_MANDATORY_RATE (AR_MAC_REG_BASE + 0x634) +#define AR_MAC_REG_RTS_CTS_RATE (AR_MAC_REG_BASE + 0x638) +#define AR_MAC_REG_BACKOFF_PROTECT (AR_MAC_REG_BASE + 0x63c) +#define AR_MAC_REG_RX_THRESHOLD (AR_MAC_REG_BASE + 0x640) +#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_REG_ACK_EXTENSION (AR_MAC_REG_BASE + 0x690) +#define AR_MAC_REG_EIFS_AND_SIFS (AR_MAC_REG_BASE + 0x698) +#define AR_MAC_REG_BUSY (AR_MAC_REG_BASE + 0x6e8) +#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_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) +#define AR_MAC_REG_AC3_CW (AR_MAC_REG_BASE + 0xb0c) +#define AR_MAC_REG_AC4_CW (AR_MAC_REG_BASE + 0xb10) +#define AR_MAC_REG_AC1_AC0_AIFS (AR_MAC_REG_BASE + 0xb14) +#define AR_MAC_REG_AC3_AC2_AIFS (AR_MAC_REG_BASE + 0xb18) +#define AR_MAC_REG_RETRY_MAX (AR_MAC_REG_BASE + 0xb28) +#define AR_MAC_REG_TXOP_NOT_ENOUGH_INDICATION \ + (AR_MAC_REG_BASE + 0xb30) +#define AR_MAC_REG_AC1_AC0_TXOP (AR_MAC_REG_BASE + 0xb44) +#define AR_MAC_REG_AC3_AC2_TXOP (AR_MAC_REG_BASE + 0xb48) +#define AR_MAC_REG_OFDM_PHY_ERRORS (AR_MAC_REG_BASE + 0xcb4) +#define AR_MAC_REG_CCK_PHY_ERRORS (AR_MAC_REG_BASE + 0xcb8) +#define AR_MAC_REG_BCN_HT1 (AR_MAC_REG_BASE + 0xda0) + +/* Possible values for register AR_USB_MODE_CTRL. */ +#define AR_USB_DS_ENA (1 << 0) +#define AR_USB_US_ENA (1 << 1) +#define AR_USB_US_PACKET_MODE (1 << 3) +#define AR_USB_RX_STREAM_4K (0 << 4) +#define AR_USB_RX_STREAM_8K (1 << 4) +#define AR_USB_RX_STREAM_16K (2 << 4) +#define AR_USB_RX_STREAM_32K (3 << 4) +#define AR_USB_TX_STREAM_MODE (1 << 6) + +#define AR_LED0_ON (1 << 0) +#define AR_LED1_ON (1 << 1) + +/* + * PHY registers. + */ +#define AR_PHY_BASE 0x1c5800 +#define AR_PHY(reg) (AR_PHY_BASE + (reg) * 4) +#define AR_PHY_TURBO (AR_PHY_BASE + 0x0004) +#define AR_PHY_RF_CTL3 (AR_PHY_BASE + 0x0028) +#define AR_PHY_RF_CTL4 (AR_PHY_BASE + 0x0034) +#define AR_PHY_SETTLING (AR_PHY_BASE + 0x0044) +#define AR_PHY_RXGAIN (AR_PHY_BASE + 0x0048) +#define AR_PHY_DESIRED_SZ (AR_PHY_BASE + 0x0050) +#define AR_PHY_FIND_SIG (AR_PHY_BASE + 0x0058) +#define AR_PHY_AGC_CTL1 (AR_PHY_BASE + 0x005c) +#define AR_PHY_SFCORR (AR_PHY_BASE + 0x0068) +#define AR_PHY_SFCORR_LOW (AR_PHY_BASE + 0x006c) +#define AR_PHY_TIMING_CTRL4 (AR_PHY_BASE + 0x0120) +#define AR_PHY_TIMING5 (AR_PHY_BASE + 0x0124) +#define AR_PHY_POWER_TX_RATE1 (AR_PHY_BASE + 0x0134) +#define AR_PHY_POWER_TX_RATE2 (AR_PHY_BASE + 0x0138) +#define AR_PHY_POWER_TX_RATE_MAX (AR_PHY_BASE + 0x013c) +#define AR_PHY_SWITCH_CHAIN_0 (AR_PHY_BASE + 0x0160) +#define AR_PHY_SWITCH_COM (AR_PHY_BASE + 0x0164) +#define AR_PHY_HEAVY_CLIP_ENABLE (AR_PHY_BASE + 0x01e0) +#define AR_PHY_CCK_DETECT (AR_PHY_BASE + 0x0a08) +#define AR_PHY_GAIN_2GHZ (AR_PHY_BASE + 0x0a0c) +#define AR_PHY_POWER_TX_RATE3 (AR_PHY_BASE + 0x0a34) +#define AR_PHY_POWER_TX_RATE4 (AR_PHY_BASE + 0x0a38) +#define AR_PHY_TPCRG1 (AR_PHY_BASE + 0x0a58) +#define AR_PHY_POWER_TX_RATE5 (AR_PHY_BASE + 0x0b8c) +#define AR_PHY_POWER_TX_RATE6 (AR_PHY_BASE + 0x0b90) +#define AR_PHY_POWER_TX_RATE7 (AR_PHY_BASE + 0x0bcc) +#define AR_PHY_POWER_TX_RATE8 (AR_PHY_BASE + 0x0bd0) +#define AR_PHY_POWER_TX_RATE9 (AR_PHY_BASE + 0x0bd4) +#define AR_PHY_CCA (AR_PHY_BASE + 0x3064) + +#define AR_SEEPROM_HW_TYPE_OFFSET 0x1374 +#define AR_EEPROM_OFFSET 0x1600 + +#define AR_BANK4_CHUP (1 << 0) +#define AR_BANK4_BMODE_LF_SYNTH_FREQ (1 << 1) +#define AR_BANK4_AMODE_REFSEL(x) ((x) << 2) +#define AR_BANK4_ADDR(x) ((x) << 5) + +/* Tx descriptor. */ +struct ar_tx_head { + uint16_t len; + uint16_t macctl; +#define AR_TX_MAC_RTS (1 << 0) +#define AR_TX_MAC_CTS (1 << 1) +#define AR_TX_MAC_BACKOFF (1 << 3) +#define AR_TX_MAC_NOACK (1 << 2) +#define AR_TX_MAC_HW_DUR (1 << 9) +#define AR_TX_MAC_QID(qid) ((qid) << 10) +#define AR_TX_MAC_RATE_PROBING (1 << 15) + + uint32_t phyctl; +/* Modulation type. */ +#define AR_TX_PHY_MT_CCK 0 +#define AR_TX_PHY_MT_OFDM 1 +#define AR_TX_PHY_MT_HT 2 +#define AR_TX_PHY_GF (1 << 2) +#define AR_TX_PHY_BW_SHIFT 3 +#define AR_TX_PHY_TPC_SHIFT 9 +#define AR_TX_PHY_ANTMSK(msk) ((msk) << 15) +#define AR_TX_PHY_MCS(mcs) ((mcs) << 18) +#define AR_TX_PHY_SHGI (1U << 31) +} __packed; + +/* USB Rx stream mode header. */ +struct ar_rx_head { + uint16_t len; + uint16_t tag; +#define AR_RX_HEAD_TAG 0x4e00 +} __packed; + +/* Rx descriptor. */ +struct ar_rx_tail { + uint8_t rssi_ant[3]; + uint8_t rssi_ant_ext[3]; + uint8_t rssi; /* Combined RSSI. */ + uint8_t evm[2][6]; /* Error Vector Magnitude. */ + uint8_t phy_err; + uint8_t sa_idx; + uint8_t da_idx; + uint8_t error; +#define AR_RX_ERROR_TIMEOUT (1 << 0) +#define AR_RX_ERROR_OVERRUN (1 << 1) +#define AR_RX_ERROR_DECRYPT (1 << 2) +#define AR_RX_ERROR_FCS (1 << 3) +#define AR_RX_ERROR_BAD_RA (1 << 4) +#define AR_RX_ERROR_PLCP (1 << 5) +#define AR_RX_ERROR_MMIC (1 << 6) + + uint8_t status; +/* Modulation type (same as AR_TX_PHY_MT). */ +#define AR_RX_STATUS_MT_MASK 0x3 +#define AR_RX_STATUS_MT_CCK 0 +#define AR_RX_STATUS_MT_OFDM 1 +#define AR_RX_STATUS_MT_HT 2 +#define AR_RX_STATUS_SHPREAMBLE (1 << 3) +} __packed; + +#define AR_PLCP_HDR_LEN 12 +/* Magic PLCP header for firmware notifications through Rx bulk pipe. */ +static uint8_t AR_PLCP_HDR_INTR[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + +/* Firmware command/reply header. */ +struct ar_cmd_hdr { + uint8_t len; + uint8_t code; +#define AR_CMD_RREG 0x00 +#define AR_CMD_WREG 0x01 +#define AR_CMD_RMEM 0x02 +#define AR_CMD_WMEM 0x03 +#define AR_CMD_BITAND 0x04 +#define AR_CMD_BITOR 0x05 +#define AR_CMD_EKEY 0x28 +#define AR_CMD_DKEY 0x29 +#define AR_CMD_FREQUENCY 0x30 +#define AR_CMD_RF_INIT 0x31 +#define AR_CMD_SYNTH 0x32 +#define AR_CMD_FREQ_STRAT 0x33 +#define AR_CMD_ECHO 0x80 +#define AR_CMD_TALLY 0x81 +#define AR_CMD_TALLY_APD 0x82 +#define AR_CMD_CONFIG 0x83 +#define AR_CMD_RESET 0x90 +#define AR_CMD_DKRESET 0x91 +#define AR_CMD_DKTX_STATUS 0x92 +#define AR_CMD_FDC 0xa0 +#define AR_CMD_WREEPROM 0xb0 +#define AR_CMD_WFLASH AR_CMD_WREEPROM +#define AR_CMD_FLASH_ERASE 0xb1 +#define AR_CMD_FLASH_PROG 0xb2 +#define AR_CMD_FLASH_CHKSUM 0xb3 +#define AR_CMD_FLASH_READ 0xb4 +#define AR_CMD_FW_DL_INIT 0xb5 +#define AR_CMD_MEM_WREEPROM 0xbb +/* Those have the 2 MSB set to 1. */ +#define AR_EVT_BEACON 0x00 +#define AR_EVT_TX_COMP 0x01 +#define AR_EVT_TBTT 0x02 +#define AR_EVT_ATIM 0x03 +#define AR_EVT_DO_BB_RESET 0x09 + + uint16_t token; /* Driver private data. */ +} __packed; + +/* Structure for command AR_CMD_RF_INIT/AR_CMD_FREQUENCY. */ +struct ar_cmd_frequency { + uint32_t freq; + uint32_t dynht2040; + uint32_t htena; + uint32_t dsc_exp; + uint32_t dsc_man; + uint32_t dsc_shgi_exp; + uint32_t dsc_shgi_man; + uint32_t check_loop_count; +} __packed; + +/* Firmware reply for command AR_CMD_FREQUENCY. */ +struct ar_rsp_frequency { + uint32_t status; +#define AR_CAL_ERR_AGC (1 << 0) /* AGC cal unfinished. */ +#define AR_CAL_ERR_NF (1 << 1) /* Noise cal unfinished. */ +#define AR_CAL_ERR_NF_VAL (1 << 2) /* NF value unexpected. */ + + uint32_t nf[3]; /* Noisefloor. */ + uint32_t nf_ext[3]; /* Noisefloor ext. */ +} __packed; + +/* Structure for command AR_CMD_EKEY. */ +struct ar_cmd_ekey { + uint16_t uid; /* user ID */ + uint16_t kix; + uint16_t cipher; +#define AR_CIPHER_NONE 0 +#define AR_CIPHER_WEP64 1 +#define AR_CIPHER_TKIP 2 +#define AR_CIPHER_AES 4 +#define AR_CIPHER_WEP128 5 +#define AR_CIPHER_WEP256 6 +#define AR_CIPHER_CENC 7 + + uint8_t macaddr[IEEE80211_ADDR_LEN]; + uint8_t key[16]; +} __packed; + +/* Structure for event AR_EVT_TX_COMP. */ +struct ar_evt_tx_comp { + uint8_t macaddr[IEEE80211_ADDR_LEN]; + uint32_t phy; + uint16_t status; +#define AR_TX_STATUS_COMP 0 +#define AR_TX_STATUS_RETRY_COMP 1 +#define AR_TX_STATUS_FAILED 2 +} __packed; + +/* List of supported channels. */ +static const uint8_t ar_chans[] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, + 128, 132, 136, 140, 149, 153, 157, 161, 165, 34, 38, 42, 46 +}; + +/* + * This data is automatically generated from the "otus.ini" file. + * It is stored in a different way though, to reduce kernel's .rodata + * section overhead (5.1KB instead of 8.5KB). + */ + +/* NB: apply AR_PHY(). */ +static const uint16_t ar5416_phy_regs[] = { + 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, 0x008, + 0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f, 0x010, 0x011, + 0x012, 0x013, 0x014, 0x015, 0x016, 0x017, 0x018, 0x01a, 0x01b, + 0x040, 0x041, 0x042, 0x043, 0x045, 0x046, 0x047, 0x048, 0x049, + 0x04a, 0x04b, 0x04d, 0x04e, 0x04f, 0x051, 0x052, 0x053, 0x055, + 0x056, 0x058, 0x059, 0x05c, 0x05d, 0x05e, 0x05f, 0x060, 0x061, + 0x062, 0x063, 0x064, 0x065, 0x066, 0x067, 0x068, 0x069, 0x06a, + 0x06b, 0x06c, 0x06d, 0x070, 0x071, 0x072, 0x073, 0x074, 0x075, + 0x076, 0x077, 0x078, 0x079, 0x07a, 0x07b, 0x07c, 0x07f, 0x080, + 0x081, 0x082, 0x083, 0x084, 0x085, 0x086, 0x087, 0x088, 0x089, + 0x08a, 0x08b, 0x08c, 0x08d, 0x08e, 0x08f, 0x090, 0x091, 0x092, + 0x093, 0x094, 0x095, 0x096, 0x097, 0x098, 0x099, 0x09a, 0x09b, + 0x09c, 0x09d, 0x09e, 0x09f, 0x0a0, 0x0a1, 0x0a2, 0x0a3, 0x0a4, + 0x0a5, 0x0a6, 0x0a7, 0x0a8, 0x0a9, 0x0aa, 0x0ab, 0x0ac, 0x0ad, + 0x0ae, 0x0af, 0x0b0, 0x0b1, 0x0b2, 0x0b3, 0x0b4, 0x0b5, 0x0b6, + 0x0b7, 0x0b8, 0x0b9, 0x0ba, 0x0bb, 0x0bc, 0x0bd, 0x0be, 0x0bf, + 0x0c0, 0x0c1, 0x0c2, 0x0c3, 0x0c4, 0x0c5, 0x0c6, 0x0c7, 0x0c8, + 0x0c9, 0x0ca, 0x0cb, 0x0cc, 0x0cd, 0x0ce, 0x0cf, 0x0d0, 0x0d1, + 0x0d2, 0x0d3, 0x0d4, 0x0d5, 0x0d6, 0x0d7, 0x0d8, 0x0d9, 0x0da, + 0x0db, 0x0dc, 0x0dd, 0x0de, 0x0df, 0x0e0, 0x0e1, 0x0e2, 0x0e3, + 0x0e4, 0x0e5, 0x0e6, 0x0e7, 0x0e8, 0x0e9, 0x0ea, 0x0eb, 0x0ec, + 0x0ed, 0x0ee, 0x0ef, 0x0f0, 0x0f1, 0x0f2, 0x0f3, 0x0f4, 0x0f5, + 0x0f6, 0x0f7, 0x0f8, 0x0f9, 0x0fa, 0x0fb, 0x0fc, 0x0fd, 0x0fe, + 0x0ff, 0x100, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, + 0x10a, 0x10b, 0x10c, 0x10d, 0x10e, 0x10f, 0x13c, 0x13d, 0x13e, + 0x13f, 0x280, 0x281, 0x282, 0x283, 0x284, 0x285, 0x286, 0x287, + 0x288, 0x289, 0x28a, 0x28b, 0x28c, 0x28d, 0x28e, 0x28f, 0x290, + 0x291, 0x292, 0x293, 0x294, 0x295, 0x296, 0x297, 0x298, 0x299, + 0x29a, 0x29b, 0x29d, 0x29e, 0x29f, 0x2c0, 0x2c1, 0x2c2, 0x2c3, + 0x2c4, 0x2c5, 0x2c6, 0x2c7, 0x2c8, 0x2c9, 0x2ca, 0x2cb, 0x2cc, + 0x2cd, 0x2ce, 0x2cf, 0x2d0, 0x2d1, 0x2d2, 0x2d3, 0x2d4, 0x2d5, + 0x2d6, 0x2e2, 0x2e3, 0x2e4, 0x2e5, 0x2e6, 0x2e7, 0x2e8, 0x2e9, + 0x2ea, 0x2eb, 0x2ec, 0x2ed, 0x2ee, 0x2ef, 0x2f0, 0x2f1, 0x2f2, + 0x2f3, 0x2f4, 0x2f5, 0x2f6, 0x2f7, 0x2f8, 0x412, 0x448, 0x458, + 0x683, 0x69b, 0x812, 0x848, 0x858, 0xa83, 0xa9b, 0xc19, 0xc57, + 0xc5a, 0xc6f, 0xe9c, 0xed7, 0xed8, 0xed9, 0xeda, 0xedb, 0xedc, + 0xedd, 0xede, 0xedf, 0xee0, 0xee1 +}; + +static const uint32_t ar5416_phy_vals_5ghz_20mhz[] = { + 0x00000007, 0x00000300, 0x00000000, 0xad848e19, 0x7d14e000, + 0x9c0a9f6b, 0x00000090, 0x00000000, 0x02020200, 0x00000e0e, + 0x0a020001, 0x0000a000, 0x00000000, 0x00000e0e, 0x00000007, + 0x00200400, 0x206a002e, 0x1372161e, 0x001a6a65, 0x1284233c, + 0x6c48b4e4, 0x00000859, 0x7ec80d2e, 0x31395c5e, 0x0004dd10, + 0x409a4190, 0x050cb081, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000007d0, 0x00000118, 0x10000fff, 0x0510081c, + 0xd0058a15, 0x00000001, 0x00000004, 0x3f3f3f3f, 0x3f3f3f3f, + 0x0000007f, 0xdfb81020, 0x9280b212, 0x00020028, 0x5d50e188, + 0x00081fff, 0x00009b40, 0x00001120, 0x190fb515, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000007, 0x001fff00, 0x006f00c4, 0x03051000, + 0x00000820, 0x038919be, 0x06336f77, 0x60f6532c, 0x08f186c8, + 0x00046384, 0x00000000, 0x00000000, 0x00000000, 0x00000200, + 0x64646464, 0x3c787878, 0x000000aa, 0x00000000, 0x00001042, + 0x00000000, 0x00000040, 0x00000080, 0x000001a1, 0x000001e1, + 0x00000021, 0x00000061, 0x00000168, 0x000001a8, 0x000001e8, + 0x00000028, 0x00000068, 0x00000189, 0x000001c9, 0x00000009, + 0x00000049, 0x00000089, 0x00000170, 0x000001b0, 0x000001f0, + 0x00000030, 0x00000070, 0x00000191, 0x000001d1, 0x00000011, + 0x00000051, 0x00000091, 0x000001b8, 0x000001f8, 0x00000038, + 0x00000078, 0x00000199, 0x000001d9, 0x00000019, 0x00000059, + 0x00000099, 0x000000d9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x00000000, + 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, + 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c, + 0x0000000d, 0x00000010, 0x00000011, 0x00000012, 0x00000013, + 0x00000014, 0x00000015, 0x00000018, 0x00000019, 0x0000001a, + 0x0000001b, 0x0000001c, 0x0000001d, 0x00000020, 0x00000021, + 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000028, + 0x00000029, 0x0000002a, 0x0000002b, 0x0000002c, 0x0000002d, + 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000010, 0x0000001a, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000008, 0x00000440, 0xd6be4788, 0x012e8160, + 0x40806333, 0x00106c10, 0x009c4060, 0x1883800a, 0x018830c6, + 0x00000400, 0x000009b5, 0x00000000, 0x00000108, 0x3f3f3f3f, + 0x3f3f3f3f, 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc, + 0x00000001, 0x0000a000, 0x00000000, 0x0cc75380, 0x0f0f0f01, + 0xdfa91f01, 0x00418a11, 0x00000000, 0x09249126, 0x0a1a9caa, + 0x1ce739ce, 0x051701ce, 0x18010000, 0x30032602, 0x48073e06, + 0x560b4c0a, 0x641a600f, 0x7a4f6e1b, 0x8c5b7e5a, 0x9d0f96cf, + 0xb51fa69f, 0xcb3fbd07, 0x0000d7bf, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff, 0x79a8aa1f, + 0x08000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x1ce739ce, 0x000001ce, + 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, + 0x00000000, 0x1ce739ce, 0x000000c0, 0x00180a65, 0x0510001c, + 0x00009b40, 0x012e8160, 0x09249126, 0x00180a65, 0x0510001c, + 0x00009b40, 0x012e8160, 0x09249126, 0x0001c600, 0x004b6a8e, + 0x000003ce, 0x00181400, 0x00820820, 0x066c420f, 0x0f282207, + 0x17601685, 0x1f801104, 0x37a00c03, 0x3fc40883, 0x57c00803, + 0x5fd80682, 0x7fe00482, 0x7f3c7bba, 0xf3307ff0 +}; + +#ifdef notyet +static const uint32_t ar5416_phy_vals_5ghz_40mhz[] = { + 0x00000007, 0x000003c4, 0x00000000, 0xad848e19, 0x7d14e000, + 0x9c0a9f6b, 0x00000090, 0x00000000, 0x02020200, 0x00000e0e, + 0x0a020001, 0x0000a000, 0x00000000, 0x00000e0e, 0x00000007, + 0x00200400, 0x206a002e, 0x13721c1e, 0x001a6a65, 0x1284233c, + 0x6c48b4e4, 0x00000859, 0x7ec80d2e, 0x31395c5e, 0x0004dd10, + 0x409a4190, 0x050cb081, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000007d0, 0x00000230, 0x10000fff, 0x0510081c, + 0xd0058a15, 0x00000001, 0x00000004, 0x3f3f3f3f, 0x3f3f3f3f, + 0x0000007f, 0xdfb81020, 0x9280b212, 0x00020028, 0x5d50e188, + 0x00081fff, 0x00009b40, 0x00001120, 0x190fb515, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000007, 0x001fff00, 0x006f00c4, 0x03051000, + 0x00000820, 0x038919be, 0x06336f77, 0x60f6532c, 0x08f186c8, + 0x00046384, 0x00000000, 0x00000000, 0x00000000, 0x00000200, + 0x64646464, 0x3c787878, 0x000000aa, 0x00000000, 0x00001042, + 0x00000000, 0x00000040, 0x00000080, 0x000001a1, 0x000001e1, + 0x00000021, 0x00000061, 0x00000168, 0x000001a8, 0x000001e8, + 0x00000028, 0x00000068, 0x00000189, 0x000001c9, 0x00000009, + 0x00000049, 0x00000089, 0x00000170, 0x000001b0, 0x000001f0, + 0x00000030, 0x00000070, 0x00000191, 0x000001d1, 0x00000011, + 0x00000051, 0x00000091, 0x000001b8, 0x000001f8, 0x00000038, + 0x00000078, 0x00000199, 0x000001d9, 0x00000019, 0x00000059, + 0x00000099, 0x000000d9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x00000000, + 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, + 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c, + 0x0000000d, 0x00000010, 0x00000011, 0x00000012, 0x00000013, + 0x00000014, 0x00000015, 0x00000018, 0x00000019, 0x0000001a, + 0x0000001b, 0x0000001c, 0x0000001d, 0x00000020, 0x00000021, + 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000028, + 0x00000029, 0x0000002a, 0x0000002b, 0x0000002c, 0x0000002d, + 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000010, 0x0000001a, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000008, 0x00000440, 0xd6be4788, 0x012e8160, + 0x40806333, 0x00106c10, 0x009c4060, 0x1883800a, 0x018830c6, + 0x00000400, 0x000009b5, 0x00000000, 0x00000210, 0x3f3f3f3f, + 0x3f3f3f3f, 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc, + 0x00000001, 0x0000a000, 0x00000000, 0x0cc75380, 0x0f0f0f01, + 0xdfa91f01, 0x00418a11, 0x00000000, 0x09249126, 0x0a1a9caa, + 0x1ce739ce, 0x051701ce, 0x18010000, 0x30032602, 0x48073e06, + 0x560b4c0a, 0x641a600f, 0x7a4f6e1b, 0x8c5b7e5a, 0x9d0f96cf, + 0xb51fa69f, 0xcb3fbcbf, 0x0000d7bf, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff, 0x79a8aa1f, + 0x08000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x1ce739ce, 0x000001ce, + 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, + 0x00000000, 0x1ce739ce, 0x000000c0, 0x00180a65, 0x0510001c, + 0x00009b40, 0x012e8160, 0x09249126, 0x00180a65, 0x0510001c, + 0x00009b40, 0x012e8160, 0x09249126, 0x0001c600, 0x004b6a8e, + 0x000003ce, 0x00181400, 0x00820820, 0x066c420f, 0x0f282207, + 0x17601685, 0x1f801104, 0x37a00c03, 0x3fc40883, 0x57c00803, + 0x5fd80682, 0x7fe00482, 0x7f3c7bba, 0xf3307ff0 +}; +#endif + +#ifdef notyet +static const uint32_t ar5416_phy_vals_2ghz_40mhz[] = { + 0x00000007, 0x000003c4, 0x00000000, 0xad848e19, 0x7d14e000, + 0x9c0a9f6b, 0x00000090, 0x00000000, 0x02020200, 0x00000e0e, + 0x0a020001, 0x0000a000, 0x00000000, 0x00000e0e, 0x00000007, + 0x00200400, 0x206a002e, 0x13721c24, 0x00197a68, 0x1284233c, + 0x6c48b0e4, 0x00000859, 0x7ec80d2e, 0x31395c5e, 0x0004dd20, + 0x409a4190, 0x050cb081, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000898, 0x00000268, 0x10000fff, 0x0510001c, + 0xd0058a15, 0x00000001, 0x00000004, 0x3f3f3f3f, 0x3f3f3f3f, + 0x0000007f, 0xdfb81020, 0x9280b212, 0x00020028, 0x5d50e188, + 0x00081fff, 0x00009b40, 0x00001120, 0x190fb515, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000007, 0x001fff00, 0x006f00c4, 0x03051000, + 0x00000820, 0x038919be, 0x06336f77, 0x60f6532c, 0x08f186c8, + 0x00046384, 0x00000000, 0x00000000, 0x00000000, 0x00000200, + 0x64646464, 0x3c787878, 0x000000aa, 0x00000000, 0x00001042, + 0x00000000, 0x00000040, 0x00000080, 0x00000141, 0x00000181, + 0x000001c1, 0x00000001, 0x00000041, 0x000001a8, 0x000001e8, + 0x00000028, 0x00000068, 0x000000a8, 0x00000169, 0x000001a9, + 0x000001e9, 0x00000029, 0x00000069, 0x00000190, 0x000001d0, + 0x00000010, 0x00000050, 0x00000090, 0x00000151, 0x00000191, + 0x000001d1, 0x00000011, 0x00000051, 0x00000198, 0x000001d8, + 0x00000018, 0x00000058, 0x00000098, 0x00000159, 0x00000199, + 0x000001d9, 0x00000019, 0x00000059, 0x00000099, 0x000000d9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x00000000, + 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, + 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c, + 0x0000000d, 0x00000010, 0x00000011, 0x00000012, 0x00000013, + 0x00000014, 0x00000015, 0x00000018, 0x00000019, 0x0000001a, + 0x0000001b, 0x0000001c, 0x0000001d, 0x00000020, 0x00000021, + 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000028, + 0x00000029, 0x0000002a, 0x0000002b, 0x0000002c, 0x0000002d, + 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000010, 0x0000001a, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x0000000e, 0x00000440, 0xd03e4788, 0x012a8160, + 0x40806333, 0x00106c10, 0x009c4060, 0x1883800a, 0x018830c6, + 0x00000400, 0x000009b5, 0x00000000, 0x00000210, 0x3f3f3f3f, + 0x3f3f3f3f, 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc, + 0x00000001, 0x0000a000, 0x00000000, 0x0cc75380, 0x0f0f0f01, + 0xdfa91f01, 0x00418a11, 0x00000000, 0x09249126, 0x0a1a7caa, + 0x1ce739ce, 0x051701ce, 0x18010000, 0x2e032402, 0x4a0a3c06, + 0x621a540b, 0x764f6c1b, 0x845b7a5a, 0x950f8ccf, 0xa5cf9b4f, + 0xbddfaf1f, 0xd1ffc93f, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff, 0x79a8aa1f, + 0x08000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x1ce739ce, 0x000001ce, + 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, + 0x00000000, 0x1ce739ce, 0x000000c0, 0x00180a68, 0x0510001c, + 0x00009b40, 0x012a8160, 0x09249126, 0x00180a68, 0x0510001c, + 0x00009b40, 0x012a8160, 0x09249126, 0x0001c600, 0x004b6a8e, + 0x000003ce, 0x00181400, 0x00820820, 0x066c420f, 0x0f282207, + 0x17601685, 0x1f801104, 0x37a00c03, 0x3fc40883, 0x57c00803, + 0x5fd80682, 0x7fe00482, 0x7f3c7bba, 0xf3307ff0 +}; +#endif + +static const uint32_t ar5416_phy_vals_2ghz_20mhz[] = { + 0x00000007, 0x00000300, 0x00000000, 0xad848e19, 0x7d14e000, + 0x9c0a9f6b, 0x00000090, 0x00000000, 0x02020200, 0x00000e0e, + 0x0a020001, 0x0000a000, 0x00000000, 0x00000e0e, 0x00000007, + 0x00200400, 0x206a002e, 0x137216a4, 0x00197a68, 0x1284233c, + 0x6c48b0e4, 0x00000859, 0x7ec80d2e, 0x31395c5e, 0x0004dd20, + 0x409a4190, 0x050cb081, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000898, 0x00000134, 0x10000fff, 0x0510001c, + 0xd0058a15, 0x00000001, 0x00000004, 0x3f3f3f3f, 0x3f3f3f3f, + 0x0000007f, 0xdfb81020, 0x9280b212, 0x00020028, 0x5d50e188, + 0x00081fff, 0x00009b40, 0x00001120, 0x190fb515, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000007, 0x001fff00, 0x006f00c4, 0x03051000, + 0x00000820, 0x038919be, 0x06336f77, 0x60f6532c, 0x08f186c8, + 0x00046384, 0x00000000, 0x00000000, 0x00000000, 0x00000200, + 0x64646464, 0x3c787878, 0x000000aa, 0x00000000, 0x00001042, + 0x00000000, 0x00000040, 0x00000080, 0x00000141, 0x00000181, + 0x000001c1, 0x00000001, 0x00000041, 0x000001a8, 0x000001e8, + 0x00000028, 0x00000068, 0x000000a8, 0x00000169, 0x000001a9, + 0x000001e9, 0x00000029, 0x00000069, 0x00000190, 0x000001d0, + 0x00000010, 0x00000050, 0x00000090, 0x00000151, 0x00000191, + 0x000001d1, 0x00000011, 0x00000051, 0x00000198, 0x000001d8, + 0x00000018, 0x00000058, 0x00000098, 0x00000159, 0x00000199, + 0x000001d9, 0x00000019, 0x00000059, 0x00000099, 0x000000d9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x00000000, + 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, + 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c, + 0x0000000d, 0x00000010, 0x00000011, 0x00000012, 0x00000013, + 0x00000014, 0x00000015, 0x00000018, 0x00000019, 0x0000001a, + 0x0000001b, 0x0000001c, 0x0000001d, 0x00000020, 0x00000021, + 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000028, + 0x00000029, 0x0000002a, 0x0000002b, 0x0000002c, 0x0000002d, + 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000010, 0x0000001a, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x0000000e, 0x00000440, 0xd03e4788, 0x012a8160, + 0x40806333, 0x00106c10, 0x009c4060, 0x1883800a, 0x018830c6, + 0x00000400, 0x000009b5, 0x00000000, 0x00000108, 0x3f3f3f3f, + 0x3f3f3f3f, 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc, + 0x00000001, 0x0000a000, 0x00000000, 0x0cc75380, 0x0f0f0f01, + 0xdfa91f01, 0x00418a11, 0x00000000, 0x09249126, 0x0a1a7caa, + 0x1ce739ce, 0x051701ce, 0x18010000, 0x2e032402, 0x4a0a3c06, + 0x621a540b, 0x764f6c1b, 0x845b7a5a, 0x950f8ccf, 0xa5cf9b4f, + 0xbddfaf1f, 0xd1ffc93f, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff, 0x79a8aa1f, + 0x08000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x1ce739ce, 0x000001ce, + 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, + 0x00000000, 0x1ce739ce, 0x000000c0, 0x00180a68, 0x0510001c, + 0x00009b40, 0x012a8160, 0x09249126, 0x00180a68, 0x0510001c, + 0x00009b40, 0x012a8160, 0x09249126, 0x0001c600, 0x004b6a8e, + 0x000003ce, 0x00181400, 0x00820820, 0x066c420f, 0x0f282207, + 0x17601685, 0x1f801104, 0x37a00c03, 0x3fc40883, 0x57c00803, + 0x5fd80682, 0x7fe00482, 0x7f3c7bba, 0xf3307ff0 +}; + +/* NB: apply AR_PHY(). */ +static const uint8_t ar5416_banks_regs[] = { + 0x2c, 0x38, 0x2c, 0x3b, 0x2c, 0x38, 0x3c, 0x2c, 0x3a, 0x2c, 0x39, + 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, + 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, + 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, + 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, + 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x38, 0x2c, 0x2c, + 0x2c, 0x3c +}; + +static const uint32_t ar5416_banks_vals_5ghz[] = { + 0x1e5795e5, 0x02008020, 0x02108421, 0x00000008, 0x0e73ff17, + 0x00000420, 0x01400018, 0x000001a1, 0x00000001, 0x00000013, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00004000, 0x00006c00, 0x00002c00, 0x00004800, + 0x00004000, 0x00006000, 0x00001000, 0x00004000, 0x00007c00, + 0x00007c00, 0x00007c00, 0x00007c00, 0x00007c00, 0x00087c00, + 0x00007c00, 0x00005400, 0x00000c00, 0x00001800, 0x00007c00, + 0x00006c00, 0x00006c00, 0x00007c00, 0x00002c00, 0x00003c00, + 0x00003800, 0x00001c00, 0x00000800, 0x00000408, 0x00004c15, + 0x00004188, 0x0000201e, 0x00010408, 0x00000801, 0x00000c08, + 0x0000181e, 0x00001016, 0x00002800, 0x00004010, 0x0000081c, + 0x00000115, 0x00000015, 0x00000066, 0x0000001c, 0x00000000, + 0x00000004, 0x00000015, 0x0000001f, 0x00000000, 0x000000a0, + 0x00000000, 0x00000040, 0x0000001c +}; + +static const uint32_t ar5416_banks_vals_2ghz[] = { + 0x1e5795e5, 0x02008020, 0x02108421, 0x00000008, 0x0e73ff17, + 0x00000420, 0x01c00018, 0x000001a1, 0x00000001, 0x00000013, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00004000, 0x00006c00, 0x00002c00, 0x00004800, + 0x00004000, 0x00006000, 0x00001000, 0x00004000, 0x00007c00, + 0x00007c00, 0x00007c00, 0x00007c00, 0x00007c00, 0x00087c00, + 0x00007c00, 0x00005400, 0x00000c00, 0x00001800, 0x00007c00, + 0x00006c00, 0x00006c00, 0x00007c00, 0x00002c00, 0x00003c00, + 0x00003800, 0x00001c00, 0x00000800, 0x00000408, 0x00004c15, + 0x00004188, 0x0000201e, 0x00010408, 0x00000801, 0x00000c08, + 0x0000181e, 0x00001016, 0x00002800, 0x00004010, 0x0000081c, + 0x00000115, 0x00000015, 0x00000066, 0x0000001c, 0x00000000, + 0x00000004, 0x00000015, 0x0000001f, 0x00000400, 0x000000a0, + 0x00000000, 0x00000040, 0x0000001c +}; + +/* + * EEPROM. + */ +/* Possible flags for opCapFlags. */ +#define AR5416_OPFLAGS_11A 0x01 +#define AR5416_OPFLAGS_11G 0x02 +#define AR5416_OPFLAGS_5G_HT40 0x04 +#define AR5416_OPFLAGS_2G_HT40 0x08 +#define AR5416_OPFLAGS_5G_HT20 0x10 +#define AR5416_OPFLAGS_2G_HT20 0x20 + +#define AR5416_NUM_5G_CAL_PIERS 8 +#define AR5416_NUM_2G_CAL_PIERS 4 +#define AR5416_NUM_5G_20_TARGET_POWERS 8 +#define AR5416_NUM_5G_40_TARGET_POWERS 8 +#define AR5416_NUM_2G_CCK_TARGET_POWERS 3 +#define AR5416_NUM_2G_20_TARGET_POWERS 4 +#define AR5416_NUM_2G_40_TARGET_POWERS 4 +#define AR5416_NUM_CTLS 24 +#define AR5416_NUM_BAND_EDGES 8 +#define AR5416_NUM_PD_GAINS 4 +#define AR5416_PD_GAIN_ICEPTS 5 +#define AR5416_EEPROM_MODAL_SPURS 5 +#define AR5416_MAX_CHAINS 2 + +struct BaseEepHeader { + uint16_t length; + uint16_t checksum; + uint16_t version; + uint8_t opCapFlags; + uint8_t eepMisc; + uint16_t regDmn[2]; + uint8_t macAddr[6]; + uint8_t rxMask; + uint8_t txMask; + uint16_t rfSilent; + uint16_t blueToothOptions; + uint16_t deviceCap; + uint32_t binBuildNumber; + uint8_t deviceType; + uint8_t futureBase[33]; +} __packed; + +struct spurChanStruct { + uint16_t spurChan; + uint8_t spurRangeLow; + uint8_t spurRangeHigh; +} __packed; + +struct ModalEepHeader { + uint32_t antCtrlChain[AR5416_MAX_CHAINS]; + uint32_t antCtrlCommon; + int8_t antennaGainCh[AR5416_MAX_CHAINS]; + uint8_t switchSettling; + uint8_t txRxAttenCh[AR5416_MAX_CHAINS]; + uint8_t rxTxMarginCh[AR5416_MAX_CHAINS]; + uint8_t adcDesiredSize; + int8_t pgaDesiredSize; + uint8_t xlnaGainCh[AR5416_MAX_CHAINS]; + uint8_t txEndToXpaOff; + uint8_t txEndToRxOn; + uint8_t txFrameToXpaOn; + uint8_t thresh62; + uint8_t noiseFloorThreshCh[AR5416_MAX_CHAINS]; + uint8_t xpdGain; + uint8_t xpd; + int8_t iqCalICh[AR5416_MAX_CHAINS]; + int8_t iqCalQCh[AR5416_MAX_CHAINS]; + uint8_t pdGainOverlap; + uint8_t ob; + uint8_t db; + uint8_t xpaBiasLvl; + uint8_t pwrDecreaseFor2Chain; + uint8_t pwrDecreaseFor3Chain; + uint8_t txFrameToDataStart; + uint8_t txFrameToPaOn; + uint8_t ht40PowerIncForPdadc; + uint8_t bswAtten[AR5416_MAX_CHAINS]; + uint8_t bswMargin[AR5416_MAX_CHAINS]; + uint8_t swSettleHt40; + uint8_t futureModal[22]; + struct spurChanStruct spurChans[AR5416_EEPROM_MODAL_SPURS]; +} __packed; + +struct calDataPerFreq { + uint8_t pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; + uint8_t vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; +} __packed; + +struct CalTargetPowerLegacy { + uint8_t bChannel; + uint8_t tPow2x[4]; +} __packed; + +struct CalTargetPowerHt { + uint8_t bChannel; + uint8_t tPow2x[8]; +} __packed; + +struct CalCtlEdges { + uint8_t bChannel; + uint8_t tPowerFlag; +} __packed; + +struct CalCtlData { + struct CalCtlEdges ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES]; +} __packed; + +struct ar5416eeprom { + struct BaseEepHeader baseEepHeader; + uint8_t custData[64]; + struct ModalEepHeader modalHeader[2]; + uint8_t calFreqPier5G[AR5416_NUM_5G_CAL_PIERS]; + uint8_t calFreqPier2G[AR5416_NUM_2G_CAL_PIERS]; + struct calDataPerFreq calPierData5G[AR5416_MAX_CHAINS] + [AR5416_NUM_5G_CAL_PIERS]; + struct calDataPerFreq calPierData2G[AR5416_MAX_CHAINS] + [AR5416_NUM_2G_CAL_PIERS]; + struct CalTargetPowerLegacy calTPow5G[AR5416_NUM_5G_20_TARGET_POWERS]; + struct CalTargetPowerHt calTPow5GHT20[AR5416_NUM_5G_20_TARGET_POWERS]; + struct CalTargetPowerHt calTPow5GHT40[AR5416_NUM_5G_40_TARGET_POWERS]; + struct CalTargetPowerLegacy calTPowCck[AR5416_NUM_2G_CCK_TARGET_POWERS]; + struct CalTargetPowerLegacy calTPow2G[AR5416_NUM_2G_20_TARGET_POWERS]; + struct CalTargetPowerHt calTPow2GHT20[AR5416_NUM_2G_20_TARGET_POWERS]; + struct CalTargetPowerHt calTPow2GHT40[AR5416_NUM_2G_40_TARGET_POWERS]; + uint8_t ctlIndex[AR5416_NUM_CTLS]; + struct CalCtlData ctlData[AR5416_NUM_CTLS]; + uint8_t padding; +} __packed; + +#define OTUS_NUM_CHAINS 2 + +#define OTUS_UID(aid) (IEEE80211_AID(aid) + 4) + +#define OTUS_MAX_TXCMDSZ 64 +#define OTUS_RXBUFSZ (8 * 1024) +/* Bumped for later A-MSDU and legacy fast-frames TX support */ +#define OTUS_TXBUFSZ (8 * 1024) + +/* Default EDCA parameters for when QoS is disabled. */ +static const struct wmeParams otus_edca_def[WME_NUM_AC] = { + { 4, 10, 3, 0 }, + { 4, 10, 7, 0 }, + { 3, 4, 2, 94 }, + { 2, 3, 2, 47 } +}; + +#define OTUS_RIDX_CCK1 0 +#define OTUS_RIDX_OFDM6 4 +#define OTUS_RIDX_OFDM24 8 +#define OTUS_RIDX_MAX 11 +static const struct otus_rate { + uint8_t rate; + uint8_t mcs; +} otus_rates[] = { + { 2, 0x0 }, + { 4, 0x1 }, + { 11, 0x2 }, + { 22, 0x3 }, + { 12, 0xb }, + { 18, 0xf }, + { 24, 0xa }, + { 36, 0xe }, + { 48, 0x9 }, + { 72, 0xd }, + { 96, 0x8 }, + { 108, 0xc } +}; + +struct otus_rx_radiotap_header { + struct ieee80211_radiotap_header wr_ihdr; + uint8_t wr_flags; + uint8_t wr_rate; + uint16_t wr_chan_freq; + uint16_t wr_chan_flags; + uint8_t wr_antsignal; +} __packed; + +#define OTUS_RX_RADIOTAP_PRESENT \ + (1 << IEEE80211_RADIOTAP_FLAGS | \ + 1 << IEEE80211_RADIOTAP_RATE | \ + 1 << IEEE80211_RADIOTAP_CHANNEL | \ + 1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) + +struct otus_tx_radiotap_header { + struct ieee80211_radiotap_header wt_ihdr; + uint8_t wt_flags; + uint8_t wt_rate; + uint16_t wt_chan_freq; + uint16_t wt_chan_flags; +} __packed; + +#define OTUS_TX_RADIOTAP_PRESENT \ + (1 << IEEE80211_RADIOTAP_FLAGS | \ + 1 << IEEE80211_RADIOTAP_RATE | \ + 1 << IEEE80211_RADIOTAP_CHANNEL) + +struct otus_softc; + +/* Firmware commands */ +struct otus_tx_cmd { + uint8_t *buf; + uint16_t buflen; + void * *odata; + uint16_t odatalen; + uint16_t token; + STAILQ_ENTRY(otus_tx_cmd) next_cmd; +}; + +/* TX, RX buffers */ +struct otus_data { + struct otus_softc *sc; + uint8_t *buf; + uint16_t buflen; + struct mbuf *m; + struct ieee80211_node *ni; + STAILQ_ENTRY(otus_data) next; +}; + +struct otus_node { + struct ieee80211_node ni; + uint64_t tx_done; + uint64_t tx_err; + uint64_t tx_retries; +}; + +#define OTUS_CONFIG_INDEX 0 +#define OTUS_IFACE_INDEX 0 + +/* + * The carl9170 firmware has the following specification: + * + * 0 - USB control + * 1 - TX + * 2 - RX + * 3 - IRQ + * 4 - CMD + * .. + * 10 - end + */ +enum { + OTUS_BULK_TX, + OTUS_BULK_RX, + OTUS_BULK_IRQ, + OTUS_BULK_CMD, + OTUS_N_XFER +}; + +struct otus_vap { + struct ieee80211vap vap; + int (*newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +#define OTUS_VAP(vap) ((struct otus_vap *)(vap)) +#define OTUS_NODE(ni) ((struct otus_node *)(ni)) + +#define OTUS_LOCK(sc) mtx_lock(&(sc)->sc_mtx) +#define OTUS_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) +#define OTUS_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) +#define OTUS_UNLOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_NOTOWNED) + +/* XXX the TX/RX endpoint dump says it's 0x200, (512)? */ +#define OTUS_MAX_TXSZ 512 +#define OTUS_MAX_RXSZ 512 +/* intr/cmd endpoint dump says 0x40 */ +#define OTUS_MAX_CTRLSZ 64 + +#define OTUS_CMD_LIST_COUNT 32 +#define OTUS_RX_LIST_COUNT 128 +#define OTUS_TX_LIST_COUNT 32 + +struct otus_softc { + struct ieee80211com sc_ic; + struct mbufq sc_snd; + device_t sc_dev; + struct usb_device *sc_udev; + int (*sc_newstate)(struct ieee80211com *, + enum ieee80211_state, int); + void (*sc_led_newstate)(struct otus_softc *); + struct usbd_interface *sc_iface; + struct mtx sc_mtx; + + struct ar5416eeprom eeprom; + uint8_t capflags; + uint8_t rxmask; + uint8_t txmask; + int sc_running:1, + sc_calibrating:1, + sc_scanning:1; + + int sc_if_flags; + int sc_tx_timer; + int fixed_ridx; + int bb_reset; + + struct ieee80211_channel *sc_curchan; + + struct task tx_task; + struct task wme_update_task; + struct timeout_task scan_to; + struct timeout_task calib_to; + + /* register batch writes */ + int write_idx; + + uint32_t led_state; + + /* current firmware message serial / token number */ + int token; + + /* current noisefloor, from SET_FREQUENCY */ + int sc_nf[OTUS_NUM_CHAINS]; + + /* How many pending, active transmit frames */ + int sc_tx_n_pending; + int sc_tx_n_active; + + const uint32_t *phy_vals; + + struct { + uint32_t reg; + uint32_t val; + } __packed write_buf[AR_MAX_WRITE_IDX + 1]; + + struct otus_data sc_rx[OTUS_RX_LIST_COUNT]; + struct otus_data sc_tx[OTUS_TX_LIST_COUNT]; + struct otus_tx_cmd sc_cmd[OTUS_CMD_LIST_COUNT]; + + struct usb_xfer *sc_xfer[OTUS_N_XFER]; + + STAILQ_HEAD(, otus_data) sc_rx_active; + STAILQ_HEAD(, otus_data) sc_rx_inactive; + STAILQ_HEAD(, otus_data) sc_tx_active[OTUS_N_XFER]; + STAILQ_HEAD(, otus_data) sc_tx_inactive; + STAILQ_HEAD(, otus_data) sc_tx_pending[OTUS_N_XFER]; + + STAILQ_HEAD(, otus_tx_cmd) sc_cmd_active; + STAILQ_HEAD(, otus_tx_cmd) sc_cmd_inactive; + STAILQ_HEAD(, otus_tx_cmd) sc_cmd_pending; + STAILQ_HEAD(, otus_tx_cmd) sc_cmd_waiting; + + union { + struct otus_rx_radiotap_header th; + uint8_t pad[64]; + } sc_rxtapu; +#define sc_rxtap sc_rxtapu.th + int sc_rxtap_len; + + union { + struct otus_tx_radiotap_header th; + uint8_t pad[64]; + } sc_txtapu; +#define sc_txtap sc_txtapu.th + int sc_txtap_len; +}; + +#endif /* __IF_OTUSREG_H__ */ diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 1666b43..42f2e85 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -776,6 +776,7 @@ vendor MOSCHIP 0x9710 MosChip Semiconductor vendor NETGEAR4 0x9846 Netgear vendor MARVELL 0x9e88 Marvell Technology Group Ltd. vendor 3COM3 0xa727 3Com +vendor CACE 0xcace CACE Technologies vendor EVOLUTION 0xdeee Evolution Robotics products vendor DATAAPEX 0xdaae DataApex vendor HP2 0xf003 Hewlett Packard @@ -863,6 +864,7 @@ product ACCTON RT3070_3 0xc522 RT3070 product ACCTON RT3070_5 0xd522 RT3070 product ACCTON RTL8192SU 0xc512 RTL8192SU product ACCTON ZD1211B 0xe501 ZD1211B +product ACCTON WN7512 0xf522 WN7512 /* Aceeca products */ product ACEECA MEZ1000 0x0001 MEZ1000 RDA @@ -1223,6 +1225,11 @@ product ATHEROS2 AR5523_2 0x0003 AR5523 product ATHEROS2 AR5523_2_NF 0x0004 AR5523 (no firmware) product ATHEROS2 AR5523_3 0x0005 AR5523 product ATHEROS2 AR5523_3_NF 0x0006 AR5523 (no firmware) +product ATHEROS2 TG121N 0x1001 TG121N +product ATHEROS2 WN821NV2 0x1002 WN821NV2 +product ATHEROS2 3CRUSBN275 0x1010 3CRUSBN275 +product ATHEROS2 WN612 0x1011 WN612 +product ATHEROS2 AR9170 0x9170 AR9170 /* Atmel Comp. products */ product ATMEL STK541 0x2109 Zigbee Controller @@ -1238,6 +1245,9 @@ product AUTHENTEC AES1610 0x1600 AES1610 Fingerprint Sensor /* Avision products */ product AVISION 1200U 0x0268 1200U scanner +/* AVM products */ +product AVM FRITZWLAN 0x8401 FRITZ!WLAN N + /* Axesstel products */ product AXESSTEL DATAMODEM 0x1000 Data Modem @@ -1340,6 +1350,9 @@ product BROTHER MFC8600_9650 0x0100 MFC8600/9650 multifunction device product BTC BTC6100 0x5550 6100C Keyboard product BTC BTC7932 0x6782 Keyboard with mouse port +/* CACE Technologies products */ +product CACE AIRPCAPNX 0x0300 AirPcap NX + /* Canon, Inc. products */ product CANON N656U 0x2206 CanoScan N656U product CANON N1220U 0x2207 CanoScan N1220U @@ -1640,8 +1653,10 @@ product DLINK DWA131B 0x330d DWA-131 rev B product DLINK2 RTL8192SU_1 0x3300 RTL8192SU product DLINK2 RTL8192SU_2 0x3302 RTL8192SU product DLINK2 DWA131A1 0x3303 DWA-131 A1 +product DLINK2 DWA160A2 0x3a09 DWA-160 A2 product DLINK2 DWA120 0x3a0c DWA-120 product DLINK2 DWA120_NF 0x3a0d DWA-120 (no firmware) +product DLINK2 DWA130D1 0x3a0f DWA-130 D1 product DLINK2 DWLG122C1 0x3c03 DWL-G122 c1 product DLINK2 WUA1340 0x3c04 WUA-1340 product DLINK2 DWA111 0x3c06 DWA-111 @@ -1652,6 +1667,7 @@ product DLINK2 RT3072_1 0x3c0b RT3072 product DLINK2 RT3070_1 0x3c0d RT3070 product DLINK2 RT3070_2 0x3c0e RT3070 product DLINK2 RT3070_3 0x3c0f RT3070 +product DLINK2 DWA160A1 0x3c10 DWA-160 A1 product DLINK2 RT2870_2 0x3c11 RT2870 product DLINK2 DWA130 0x3c13 DWA-130 product DLINK2 RT3070_4 0x3c15 RT3070 @@ -2469,6 +2485,7 @@ product IODATA USBETTXS 0x0913 USB ETTX product IODATA USBWNB11A 0x0919 USB WN-B11 product IODATA USBWNB11 0x0922 USB Airport WN-B11 product IODATA ETGUS2 0x0930 ETG-US2 +product IODATA WNGDNUS2 0x093f WN-GDN/US2 product IODATA RT3072_1 0x0944 RT3072 product IODATA RT3072_2 0x0945 RT3072 product IODATA RT3072_3 0x0947 RT3072 @@ -3209,6 +3226,7 @@ product NATIONAL BEARPAW2400 0x1001 BearPaw 2400 /* NEC products */ product NEC HUB_0050 0x0050 USB 2.0 7-Port Hub product NEC HUB_005A 0x005a USB 2.0 4-Port Hub +product NEC WL300NUG 0x0249 WL300NU-G product NEC HUB 0x55aa hub product NEC HUB_B 0x55ab hub @@ -3241,7 +3259,11 @@ product NETGEAR WG111V3 0x4260 WG111v3 product NETGEAR WG111U 0x4300 WG111U product NETGEAR WG111U_NF 0x4301 WG111U (no firmware) product NETGEAR WG111V2 0x6a00 WG111V2 +product NETGEAR WN111V2 0x9001 WN111V2 +product NETGEAR WNDA3100 0x9010 WNDA3100 +product NETGEAR WNDA3200 0x9018 WNDA3200 product NETGEAR RTL8192CU 0x9021 RTL8192CU +product NETGEAR WNA1000 0x9040 WNA1000 product NETGEAR WNA1000M 0x9041 WNA1000M product NETGEAR2 MA101 0x4100 MA101 product NETGEAR2 MA101B 0x4102 MA101 Rev B @@ -3505,6 +3527,7 @@ product PLANEX GW_US11H 0x14ea GW-US11H WLAN product PLANEX2 RTL8188CUS 0x1201 RTL8188CUS product PLANEX2 GW_US11S 0x3220 GW-US11S WLAN product PLANEX2 GW_US54GXS 0x5303 GW-US54GXS WLAN +product PLANEX2 GW_US300 0x5304 GW-US300 product PLANEX2 RTL8188CU_1 0xab2a RTL8188CU product PLANEX2 RTL8188CU_2 0xed17 RTL8188CU product PLANEX2 RTL8188CU_3 0x4902 RTL8188CU @@ -4577,8 +4600,10 @@ product WINBOND UH104 0x5518 4-port USB Hub product WINMAXGROUP FLASH64MC 0x6660 USB Flash Disk 64M-C /* Wistron NeWeb products */ +product WISTRONNEWEB WNC0600 0x0326 WNC-0600USB product WISTRONNEWEB UR045G 0x0427 PrismGT USB 2.0 WLAN product WISTRONNEWEB UR055G 0x0711 UR055G +product WISTRONNEWEB O8494 0x0804 ORiNOCO 802.11n product WISTRONNEWEB AR5523_1 0x0826 AR5523 product WISTRONNEWEB AR5523_1_NF 0x0827 AR5523 (no firmware) product WISTRONNEWEB AR5523_2 0x082a AR5523 @@ -4627,7 +4652,9 @@ product ZCOM AR5523_NF 0x0013 AR5523 driver (no firmware) product ZCOM XM142 0x0015 XM-142 product ZCOM ZD1211B 0x001a ZD1211B product ZCOM RT2870_1 0x0022 RT2870 +product ZCOM UB81 0x0023 UB81 product ZCOM RT2870_2 0x0025 RT2870 +product ZCOM UB82 0x0026 UB82 /* Zinwell products */ product ZINWELL RT2570 0x0260 RT2570 @@ -4646,6 +4673,7 @@ product ZORAN EX20DSC 0x4343 Digital Camera EX-20 DSC /* Zydas Technology Corporation products */ product ZYDAS ZD1211 0x1211 ZD1211 WLAN abg product ZYDAS ZD1211B 0x1215 ZD1211B +product ZYDAS ZD1221 0x1221 ZD1221 /* ZyXEL Communication Co. products */ product ZYXEL OMNI56K 0x1500 Omni 56K Plus @@ -4657,6 +4685,8 @@ product ZYXEL M202 0x340a M-202 product ZYXEL G220V2 0x340f G-220 v2 product ZYXEL G202 0x3410 G-202 product ZYXEL RT2870_1 0x3416 RT2870 +product ZYXEL NWD271N 0x3417 NWD-271N +product ZYXEL NWD211AN 0x3418 NWD-211AN product ZYXEL RT2870_2 0x341a RT2870 product ZYXEL RT3070 0x341e NWD2105 product ZYXEL RTL8192CU 0x341f RTL8192CU diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c index 2337067..4fb9d85 100644 --- a/sys/dev/usb/wlan/if_rsu.c +++ b/sys/dev/usb/wlan/if_rsu.c @@ -22,13 +22,14 @@ __FBSDID("$FreeBSD$"); * Driver for Realtek RTL8188SU/RTL8191SU/RTL8192SU. * * TODO: - * o 11n HT40 support * o h/w crypto * o hostap / ibss / mesh * o sensible RSSI levels * o power-save operation */ +#include "opt_wlan.h" + #include <sys/param.h> #include <sys/endian.h> #include <sys/sockio.h> @@ -202,17 +203,18 @@ static void rsu_delete_key(struct rsu_softc *, const struct ieee80211_key *); static int rsu_site_survey(struct rsu_softc *, struct ieee80211vap *); static int rsu_join_bss(struct rsu_softc *, struct ieee80211_node *); static int rsu_disconnect(struct rsu_softc *); +static int rsu_hwrssi_to_rssi(struct rsu_softc *, int hw_rssi); static void rsu_event_survey(struct rsu_softc *, uint8_t *, int); static void rsu_event_join_bss(struct rsu_softc *, uint8_t *, int); static void rsu_rx_event(struct rsu_softc *, uint8_t, uint8_t *, int); static void rsu_rx_multi_event(struct rsu_softc *, uint8_t *, int); +#if 0 static int8_t rsu_get_rssi(struct rsu_softc *, int, void *); +#endif +static struct mbuf * rsu_rx_frame(struct rsu_softc *, uint8_t *, int); +static struct mbuf * rsu_rx_multi_frame(struct rsu_softc *, uint8_t *, int); static struct mbuf * - rsu_rx_frame(struct rsu_softc *, uint8_t *, int, int *); -static struct mbuf * - rsu_rx_multi_frame(struct rsu_softc *, uint8_t *, int, int *); -static struct mbuf * - rsu_rxeof(struct usb_xfer *, struct rsu_data *, int *); + rsu_rxeof(struct usb_xfer *, struct rsu_data *); static void rsu_txeof(struct usb_xfer *, struct rsu_data *); static int rsu_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); @@ -402,6 +404,7 @@ rsu_attach(device_t self) int error; uint8_t iface_index, bands; struct usb_interface *iface; + const char *rft; device_set_usb_desc(self); sc->sc_udev = uaa->device; @@ -461,8 +464,37 @@ rsu_attach(device_t self) device_printf(self, "could not read ROM\n"); goto fail_rom; } + + /* Figure out TX/RX streams */ + switch (sc->rom[84]) { + case 0x0: + sc->sc_rftype = RTL8712_RFCONFIG_1T1R; + sc->sc_nrxstream = 1; + sc->sc_ntxstream = 1; + rft = "1T1R"; + break; + case 0x1: + sc->sc_rftype = RTL8712_RFCONFIG_1T2R; + sc->sc_nrxstream = 2; + sc->sc_ntxstream = 1; + rft = "1T2R"; + break; + case 0x2: + sc->sc_rftype = RTL8712_RFCONFIG_2T2R; + sc->sc_nrxstream = 2; + sc->sc_ntxstream = 2; + rft = "2T2R"; + break; + default: + device_printf(sc->sc_dev, + "%s: unknown board type (rfconfig=0x%02x)\n", + __func__, + sc->rom[84]); + goto fail_rom; + } + IEEE80211_ADDR_COPY(ic->ic_macaddr, &sc->rom[0x12]); - device_printf(self, "MAC/BB RTL8712 cut %d\n", sc->cut); + device_printf(self, "MAC/BB RTL8712 cut %d %s\n", sc->cut, rft); ic->ic_softc = sc; ic->ic_name = device_get_nameunit(self); @@ -490,18 +522,11 @@ rsu_attach(device_t self) IEEE80211_HTC_AMSDU | IEEE80211_HTCAP_MAXAMSDU_3839 | IEEE80211_HTCAP_SMPS_OFF; - - /* - * XXX HT40 isn't working in this driver yet - there's - * something missing. Disable it for now. - */ -#if 0 ic->ic_htcaps |= IEEE80211_HTCAP_CHWIDTH40; -#endif /* set number of spatial streams */ - ic->ic_txstream = 1; - ic->ic_rxstream = 1; + ic->ic_txstream = sc->sc_ntxstream; + ic->ic_rxstream = sc->sc_nrxstream; } /* Set supported .11b and .11g rates. */ @@ -553,18 +578,25 @@ rsu_detach(device_t self) RSU_LOCK(sc); rsu_stop(sc); RSU_UNLOCK(sc); + usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER); + /* + * Free buffers /before/ we detach from net80211, else node + * references to destroyed vaps will lead to a panic. + */ + /* Free Tx/Rx buffers. */ + RSU_LOCK(sc); + rsu_free_tx_list(sc); + rsu_free_rx_list(sc); + RSU_UNLOCK(sc); + /* Frames are freed; detach from net80211 */ ieee80211_ifdetach(ic); taskqueue_drain_timeout(taskqueue_thread, &sc->calib_task); taskqueue_drain(taskqueue_thread, &sc->tx_task); - /* Free Tx/Rx buffers. */ - rsu_free_tx_list(sc); - rsu_free_rx_list(sc); - mtx_destroy(&sc->sc_mtx); return (0); @@ -1051,7 +1083,9 @@ static void rsu_calib_task(void *arg, int pending __unused) { struct rsu_softc *sc = arg; +#ifdef notyet uint32_t reg; +#endif RSU_DPRINTF(sc, RSU_DEBUG_CALIB, "%s: running calibration task\n", __func__); @@ -1069,9 +1103,10 @@ rsu_calib_task(void *arg, int pending __unused) #endif /* Read current signal level. */ if (rsu_fw_iocmd(sc, 0xf4000001) == 0) { - reg = rsu_read_4(sc, R92S_IOCMD_DATA); - RSU_DPRINTF(sc, RSU_DEBUG_CALIB, "%s: RSSI=%d%%\n", - __func__, reg >> 4); + sc->sc_currssi = rsu_read_4(sc, R92S_IOCMD_DATA); + RSU_DPRINTF(sc, RSU_DEBUG_CALIB, "%s: RSSI=%d (%d)\n", + __func__, sc->sc_currssi, + rsu_hwrssi_to_rssi(sc, sc->sc_currssi)); } if (sc->sc_calibrating) taskqueue_enqueue_timeout(taskqueue_thread, &sc->calib_task, hz); @@ -1378,8 +1413,10 @@ rsu_join_bss(struct rsu_softc *sc, struct ieee80211_node *ni) if ((ic->ic_flags & IEEE80211_F_WME) && (ni->ni_ies.wme_ie != NULL)) frm = ieee80211_add_wme_info(frm, &ic->ic_wme); - if (ni->ni_flags & IEEE80211_NODE_HT) + if (ni->ni_flags & IEEE80211_NODE_HT) { frm = ieee80211_add_htcap(frm, ni); + frm = ieee80211_add_htinfo(frm, ni); + } bss->ieslen = htole32(frm - (uint8_t *)fixed); bss->len = htole32(((frm - buf) + 3) & ~3); RSU_DPRINTF(sc, RSU_DEBUG_RESET | RSU_DEBUG_FWCMD, @@ -1400,6 +1437,24 @@ rsu_disconnect(struct rsu_softc *sc) return (rsu_fw_cmd(sc, R92S_CMD_DISCONNECT, &zero, sizeof(zero))); } +/* + * Map the hardware provided RSSI value to a signal level. + * For the most part it's just something we divide by and cap + * so it doesn't overflow the representation by net80211. + */ +static int +rsu_hwrssi_to_rssi(struct rsu_softc *sc, int hw_rssi) +{ + int v; + + if (hw_rssi == 0) + return (0); + v = hw_rssi >> 4; + if (v > 80) + v = 80; + return (v); +} + static void rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) { @@ -1453,8 +1508,9 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) rxs.r_flags |= IEEE80211_R_NF | IEEE80211_R_RSSI; rxs.c_ieee = le32toh(bss->config.dsconfig); rxs.c_freq = ieee80211_ieee2mhz(rxs.c_ieee, IEEE80211_CHAN_2GHZ); - rxs.rssi = le32toh(bss->rssi); - rxs.nf = 0; /* XXX */ + /* This is a number from 0..100; so let's just divide it down a bit */ + rxs.rssi = le32toh(bss->rssi) / 2; + rxs.nf = -96; /* XXX avoid a LOR */ RSU_UNLOCK(sc); @@ -1524,7 +1580,7 @@ rsu_event_addba_req_report(struct rsu_softc *sc, uint8_t *buf, int len) if (vap == NULL) return; - device_printf(sc->sc_dev, "%s: mac=%s, tid=%d, ssn=%d\n", + RSU_DPRINTF(sc, RSU_DEBUG_AMPDU, "%s: mac=%s, tid=%d, ssn=%d\n", __func__, ether_sprintf(ba->mac_addr), (int) ba->tid, @@ -1637,6 +1693,7 @@ rsu_rx_multi_event(struct rsu_softc *sc, uint8_t *buf, int len) } } +#if 0 static int8_t rsu_get_rssi(struct rsu_softc *sc, int rate, void *physt) { @@ -1657,9 +1714,10 @@ rsu_get_rssi(struct rsu_softc *sc, int rate, void *physt) } return (rssi); } +#endif static struct mbuf * -rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi) +rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen) { struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; @@ -1685,16 +1743,17 @@ rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi) rate = MS(rxdw3, R92S_RXDW3_RATE); infosz = MS(rxdw0, R92S_RXDW0_INFOSZ) * 8; +#if 0 /* Get RSSI from PHY status descriptor if present. */ if (infosz != 0) *rssi = rsu_get_rssi(sc, rate, &stat[1]); else *rssi = 0; +#endif RSU_DPRINTF(sc, RSU_DEBUG_RX, - "%s: Rx frame len=%d rate=%d infosz=%d rssi=%d\n", - __func__, - pktlen, rate, infosz, *rssi); + "%s: Rx frame len=%d rate=%d infosz=%d\n", + __func__, pktlen, rate, infosz); m = m_get2(pktlen, M_NOWAIT, MT_DATA, M_PKTHDR); if (__predict_false(m == NULL)) { @@ -1736,7 +1795,11 @@ rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi) /* Bit 7 set means HT MCS instead of rate. */ tap->wr_rate = 0x80 | (rate - 12); } +#if 0 tap->wr_dbm_antsignal = *rssi; +#endif + /* XXX not nice */ + tap->wr_dbm_antsignal = rsu_hwrssi_to_rssi(sc, sc->sc_currssi); tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); } @@ -1745,7 +1808,7 @@ rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi) } static struct mbuf * -rsu_rx_multi_frame(struct rsu_softc *sc, uint8_t *buf, int len, int *rssi) +rsu_rx_multi_frame(struct rsu_softc *sc, uint8_t *buf, int len) { struct r92s_rx_stat *stat; uint32_t rxdw0; @@ -1777,7 +1840,7 @@ rsu_rx_multi_frame(struct rsu_softc *sc, uint8_t *buf, int len, int *rssi) break; /* Process 802.11 frame. */ - m = rsu_rx_frame(sc, buf, pktlen, rssi); + m = rsu_rx_frame(sc, buf, pktlen); if (m0 == NULL) m0 = m; if (prevm == NULL) @@ -1796,7 +1859,7 @@ rsu_rx_multi_frame(struct rsu_softc *sc, uint8_t *buf, int len, int *rssi) } static struct mbuf * -rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi) +rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data) { struct rsu_softc *sc = data->sc; struct ieee80211com *ic = &sc->sc_ic; @@ -1817,7 +1880,7 @@ rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi) /* No packets to process. */ return (NULL); } else - return (rsu_rx_multi_frame(sc, data->buf, len, rssi)); + return (rsu_rx_multi_frame(sc, data->buf, len)); } static void @@ -1829,7 +1892,6 @@ rsu_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) struct ieee80211_node *ni; struct mbuf *m = NULL, *next; struct rsu_data *data; - int rssi = 1; RSU_ASSERT_LOCKED(sc); @@ -1839,11 +1901,15 @@ rsu_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) if (data == NULL) goto tr_setup; STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next); - m = rsu_rxeof(xfer, data, &rssi); + m = rsu_rxeof(xfer, data); STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: + /* + * XXX TODO: if we have an mbuf list, but then + * we hit data == NULL, what now? + */ data = STAILQ_FIRST(&sc->sc_rx_inactive); if (data == NULL) { KASSERT(m == NULL, ("mbuf isn't NULL")); @@ -1861,6 +1927,11 @@ tr_setup: */ RSU_UNLOCK(sc); while (m != NULL) { + int rssi; + + /* Cheat and get the last calibrated RSSI */ + rssi = rsu_hwrssi_to_rssi(sc, sc->sc_currssi); + next = m->m_next; m->m_next = NULL; wh = mtod(m, struct ieee80211_frame *); @@ -1869,10 +1940,10 @@ tr_setup: if (ni != NULL) { if (ni->ni_flags & IEEE80211_NODE_HT) m->m_flags |= M_AMPDU; - (void)ieee80211_input(ni, m, rssi, 0); + (void)ieee80211_input(ni, m, rssi, -96); ieee80211_free_node(ni); } else - (void)ieee80211_input_all(ic, m, rssi, 0); + (void)ieee80211_input_all(ic, m, rssi, -96); m = next; } RSU_LOCK(sc); @@ -1966,6 +2037,12 @@ tr_setup: } break; } + + /* + * XXX TODO: if the queue is low, flush out FF TX frames. + * Remember to unlock the driver for now; net80211 doesn't + * defer it for us. + */ } static void @@ -2001,6 +2078,11 @@ rsu_bulk_tx_callback_h2c(struct usb_xfer *xfer, usb_error_t error) rsu_start(sc); } +/* + * Transmit the given frame. + * + * This doesn't free the node or mbuf upon failure. + */ static int rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, struct rsu_data *data) @@ -2031,7 +2113,6 @@ rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni, device_printf(sc->sc_dev, "ieee80211_crypto_encap returns NULL.\n"); /* XXX we don't expect the fragmented frames */ - m_freem(m0); return (ENOBUFS); } wh = mtod(m0, struct ieee80211_frame *); @@ -2147,6 +2228,11 @@ rsu_transmit(struct ieee80211com *ic, struct mbuf *m) RSU_UNLOCK(sc); return (ENXIO); } + + /* + * XXX TODO: ensure that we treat 'm' as a list of frames + * to transmit! + */ error = mbufq_enqueue(&sc->sc_snd, m); if (error) { RSU_DPRINTF(sc, RSU_DEBUG_TX, @@ -2207,6 +2293,7 @@ _rsu_start(struct rsu_softc *sc) IFCOUNTER_OERRORS, 1); rsu_freebuf(sc, bf); ieee80211_free_node(ni); + m_freem(m); break; } } @@ -2647,8 +2734,7 @@ rsu_load_firmware(struct rsu_softc *sc) dmem->hci_sel = R92S_HCI_SEL_USB | R92S_HCI_SEL_8172; dmem->nendpoints = sc->sc_nendpoints; dmem->chip_version = sc->cut; - /* XXX TODO: rf_config should come from ROM */ - dmem->rf_config = 0x11; /* 1T1R */ + dmem->rf_config = sc->sc_rftype; dmem->vcs_type = R92S_VCS_TYPE_AUTO; dmem->vcs_mode = R92S_VCS_MODE_RTS_CTS; dmem->turbo_mode = 0; @@ -2720,6 +2806,7 @@ rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, } if (rsu_tx_start(sc, ni, m, bf) != 0) { ieee80211_free_node(ni); + m_freem(m); rsu_freebuf(sc, bf); RSU_UNLOCK(sc); return (EIO); @@ -2809,19 +2896,6 @@ rsu_init(struct rsu_softc *sc) goto fail; } - if (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) { - /* Enable 40MHz mode. */ - error = rsu_fw_iocmd(sc, - SM(R92S_IOCMD_CLASS, 0xf4) | - SM(R92S_IOCMD_INDEX, 0x00) | - SM(R92S_IOCMD_VALUE, 0x0007)); - if (error != 0) { - device_printf(sc->sc_dev, - "could not enable 40MHz mode\n"); - goto fail; - } - } - sc->sc_scan_pass = 0; usbd_transfer_start(sc->sc_xfer[RSU_BULK_RX]); diff --git a/sys/dev/usb/wlan/if_rsureg.h b/sys/dev/usb/wlan/if_rsureg.h index 4929c80..ddb29a3 100644 --- a/sys/dev/usb/wlan/if_rsureg.h +++ b/sys/dev/usb/wlan/if_rsureg.h @@ -158,6 +158,20 @@ (((var) & ~field##_M) | SM(field, val)) /* + * ROM field with RF config. + */ +enum { + RTL8712_RFCONFIG_1T = 0x10, + RTL8712_RFCONFIG_2T = 0x20, + RTL8712_RFCONFIG_1R = 0x01, + RTL8712_RFCONFIG_2R = 0x02, + RTL8712_RFCONFIG_1T1R = 0x11, + RTL8712_RFCONFIG_1T2R = 0x12, + RTL8712_RFCONFIG_TURBO = 0x92, + RTL8712_RFCONFIG_2T2R = 0x22 +}; + +/* * Firmware image header. */ struct r92s_fw_priv { @@ -173,6 +187,7 @@ struct r92s_fw_priv { uint8_t chip_version; uint16_t custid; uint8_t rf_config; +//0x11: 1T1R, 0x12: 1T2R, 0x92: 1T2R turbo, 0x22: 2T2R uint8_t nendpoints; /* QWORD1 */ uint32_t regulatory; @@ -749,12 +764,16 @@ struct rsu_softc { int sc_ht; int sc_nendpoints; int sc_curpwrstate; + int sc_currssi; u_int sc_running:1, sc_calibrating:1, sc_scanning:1, sc_scan_pass:1; u_int cut; + uint8_t sc_rftype; + int8_t sc_nrxstream; + int8_t sc_ntxstream; struct rsu_host_cmd_ring cmdq; struct rsu_data sc_rx[RSU_RX_LIST_COUNT]; struct rsu_data sc_tx[RSU_TX_LIST_COUNT]; diff --git a/sys/dev/usb/wlan/if_urtwn.c b/sys/dev/usb/wlan/if_urtwn.c index 42365d1..b1e3804 100644 --- a/sys/dev/usb/wlan/if_urtwn.c +++ b/sys/dev/usb/wlan/if_urtwn.c @@ -24,6 +24,8 @@ __FBSDID("$FreeBSD$"); * Driver for Realtek RTL8188CE-VAU/RTL8188CUS/RTL8188EU/RTL8188RU/RTL8192CU. */ +#include "opt_wlan.h" + #include <sys/param.h> #include <sys/sockio.h> #include <sys/sysctl.h> @@ -169,6 +171,7 @@ static device_detach_t urtwn_detach; static usb_callback_t urtwn_bulk_tx_callback; static usb_callback_t urtwn_bulk_rx_callback; +static void urtwn_drain_mbufq(struct urtwn_softc *sc); static usb_error_t urtwn_do_request(struct urtwn_softc *, struct usb_device_request *, void *); static struct ieee80211vap *urtwn_vap_create(struct ieee80211com *, @@ -467,6 +470,20 @@ detach: return (ENXIO); /* failure */ } +static void +urtwn_drain_mbufq(struct urtwn_softc *sc) +{ + struct mbuf *m; + struct ieee80211_node *ni; + URTWN_ASSERT_LOCKED(sc); + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { + ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; + m->m_pkthdr.rcvif = NULL; + ieee80211_free_node(ni); + m_freem(m); + } +} + static int urtwn_detach(device_t self) { @@ -482,6 +499,9 @@ urtwn_detach(device_t self) callout_drain(&sc->sc_watchdog_ch); + /* stop all USB transfers */ + usbd_transfer_unsetup(sc->sc_xfer, URTWN_N_TRANSFER); + /* Prevent further allocations from RX/TX data lists. */ URTWN_LOCK(sc); STAILQ_INIT(&sc->sc_tx_active); @@ -502,10 +522,7 @@ urtwn_detach(device_t self) urtwn_free_rx_list(sc); URTWN_UNLOCK(sc); - /* stop all USB transfers */ - usbd_transfer_unsetup(sc->sc_xfer, URTWN_N_TRANSFER); ieee80211_ifdetach(ic); - mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); @@ -879,13 +896,12 @@ tr_setup: data = STAILQ_FIRST(&sc->sc_tx_pending); if (data == NULL) { DPRINTF("%s: empty pending queue\n", __func__); - return; + goto finish; } STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next); STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next); usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen); usbd_transfer_submit(xfer); - urtwn_start(sc); break; default: data = STAILQ_FIRST(&sc->sc_tx_active); @@ -903,6 +919,9 @@ tr_setup: } break; } +finish: + /* Kick-start more transmit */ + urtwn_start(sc); } static struct urtwn_data * @@ -1778,7 +1797,6 @@ urtwn_tx_start(struct urtwn_softc *sc, struct ieee80211_node *ni, device_printf(sc->sc_dev, "ieee80211_crypto_encap returns NULL.\n"); /* XXX we don't expect the fragmented frames */ - m_freem(m0); return (ENOBUFS); } @@ -1931,6 +1949,7 @@ urtwn_start(struct urtwn_softc *sc) if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); + m_freem(m); ieee80211_free_node(ni); break; } @@ -3417,6 +3436,8 @@ urtwn_stop(struct urtwn_softc *sc) sc->sc_flags &= ~URTWN_RUNNING; callout_stop(&sc->sc_watchdog_ch); urtwn_abort_xfers(sc); + + urtwn_drain_mbufq(sc); } static void @@ -3455,14 +3476,15 @@ urtwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, } if (urtwn_tx_start(sc, ni, m, bf) != 0) { + m_freem(m); ieee80211_free_node(ni); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); URTWN_UNLOCK(sc); return (EIO); } + sc->sc_txtimer = 5; URTWN_UNLOCK(sc); - sc->sc_txtimer = 5; return (0); } diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c index e77d42d..abb3bd5 100644 --- a/sys/dev/wpi/if_wpi.c +++ b/sys/dev/wpi/if_wpi.c @@ -3954,14 +3954,6 @@ wpi_config(struct wpi_softc *sc) sc->rxon.cck_mask = 0x0f; /* not yet negotiated */ sc->rxon.ofdm_mask = 0xff; /* not yet negotiated */ - /* XXX Current configuration may be unusable. */ - if (IEEE80211_IS_CHAN_NOADHOC(c) && sc->rxon.mode == WPI_MODE_IBSS) { - device_printf(sc->sc_dev, - "%s: invalid channel (%d) selected for IBSS mode\n", - __func__, ieee80211_chan2ieee(ic, c)); - return EINVAL; - } - if ((error = wpi_send_rxon(sc, 0, 0)) != 0) { device_printf(sc->sc_dev, "%s: could not send RXON\n", __func__); diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 9b8b2ff..270845b 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -2312,7 +2312,7 @@ free_pv_chunk(struct pv_chunk *pc) /* entire chunk is free, return it */ m = PHYS_TO_VM_PAGE(pmap_kextract((vm_offset_t)pc)); pmap_qremove((vm_offset_t)pc, 1); - vm_page_unwire(m, PQ_INACTIVE); + vm_page_unwire(m, PQ_NONE); vm_page_free(m); pmap_ptelist_free(&pv_vafree, (vm_offset_t)pc); } diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index a3fd830b..fb78adf 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -418,7 +418,7 @@ do_execve(td, args, mac_p) | AUDITVNODE1, UIO_SYSSPACE, args->fname, td); } - SDT_PROBE(proc, kernel, , exec, args->fname, 0, 0, 0, 0 ); + SDT_PROBE1(proc, kernel, , exec, args->fname); interpret: if (args->fname != NULL) { @@ -846,7 +846,7 @@ interpret: vfs_mark_atime(imgp->vp, td->td_ucred); - SDT_PROBE(proc, kernel, , exec__success, args->fname, 0, 0, 0, 0); + SDT_PROBE1(proc, kernel, , exec__success, args->fname); VOP_UNLOCK(imgp->vp, 0); done1: @@ -918,7 +918,7 @@ exec_fail: p->p_flag &= ~P_INEXEC; PROC_UNLOCK(p); - SDT_PROBE(proc, kernel, , exec__failure, error, 0, 0, 0, 0); + SDT_PROBE1(proc, kernel, , exec__failure, error); done2: #ifdef MAC diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index d84c26f..53ae14e 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -569,7 +569,7 @@ exit1(struct thread *td, int rval, int signo) reason = CLD_DUMPED; else if (WIFSIGNALED(signo)) reason = CLD_KILLED; - SDT_PROBE(proc, kernel, , exit, reason, 0, 0, 0, 0); + SDT_PROBE1(proc, kernel, , exit, reason); #endif /* diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 4aa5314..b2727bc 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -753,7 +753,7 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2, * Tell any interested parties about the new process. */ knote_fork(&p1->p_klist, p2->p_pid); - SDT_PROBE(proc, kernel, , create, p2, p1, flags, 0, 0); + SDT_PROBE3(proc, kernel, , create, p2, p1, flags); /* * Wait until debugger is attached to child. diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 02ece28..8f53306 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -181,9 +181,9 @@ proc_ctor(void *mem, int size, void *arg, int flags) struct proc *p; p = (struct proc *)mem; - SDT_PROBE(proc, kernel, ctor , entry, p, size, arg, flags, 0); + SDT_PROBE4(proc, kernel, ctor , entry, p, size, arg, flags); EVENTHANDLER_INVOKE(process_ctor, p); - SDT_PROBE(proc, kernel, ctor , return, p, size, arg, flags, 0); + SDT_PROBE4(proc, kernel, ctor , return, p, size, arg, flags); return (0); } @@ -199,7 +199,7 @@ proc_dtor(void *mem, int size, void *arg) /* INVARIANTS checks go here */ p = (struct proc *)mem; td = FIRST_THREAD_IN_PROC(p); - SDT_PROBE(proc, kernel, dtor, entry, p, size, arg, td, 0); + SDT_PROBE4(proc, kernel, dtor, entry, p, size, arg, td); if (td != NULL) { #ifdef INVARIANTS KASSERT((p->p_numthreads == 1), @@ -212,7 +212,7 @@ proc_dtor(void *mem, int size, void *arg) EVENTHANDLER_INVOKE(process_dtor, p); if (p->p_ksi != NULL) KASSERT(! KSI_ONQ(p->p_ksi), ("SIGCHLD queue")); - SDT_PROBE(proc, kernel, dtor, return, p, size, arg, 0, 0); + SDT_PROBE3(proc, kernel, dtor, return, p, size, arg); } /* @@ -224,7 +224,7 @@ proc_init(void *mem, int size, int flags) struct proc *p; p = (struct proc *)mem; - SDT_PROBE(proc, kernel, init, entry, p, size, flags, 0, 0); + SDT_PROBE3(proc, kernel, init, entry, p, size, flags); p->p_sched = (struct p_sched *)&p[1]; mtx_init(&p->p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK | MTX_NEW); mtx_init(&p->p_slock, "process slock", NULL, MTX_SPIN | MTX_NEW); @@ -236,7 +236,7 @@ proc_init(void *mem, int size, int flags) TAILQ_INIT(&p->p_threads); /* all threads in proc */ EVENTHANDLER_INVOKE(process_init, p); p->p_stats = pstats_alloc(); - SDT_PROBE(proc, kernel, init, return, p, size, flags, 0, 0); + SDT_PROBE3(proc, kernel, init, return, p, size, flags); return (0); } diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c index 2a10790..d32b432 100644 --- a/sys/kern/kern_racct.c +++ b/sys/kern/kern_racct.c @@ -445,7 +445,7 @@ racct_create(struct racct **racctp) if (!racct_enable) return; - SDT_PROBE(racct, kernel, racct, create, racctp, 0, 0, 0, 0); + SDT_PROBE1(racct, kernel, racct, create, racctp); KASSERT(*racctp == NULL, ("racct already allocated")); @@ -460,7 +460,7 @@ racct_destroy_locked(struct racct **racctp) ASSERT_RACCT_ENABLED(); - SDT_PROBE(racct, kernel, racct, destroy, racctp, 0, 0, 0, 0); + SDT_PROBE1(racct, kernel, racct, destroy, racctp); mtx_assert(&racct_lock, MA_OWNED); KASSERT(racctp != NULL, ("NULL racctp")); @@ -538,7 +538,7 @@ racct_add_locked(struct proc *p, int resource, uint64_t amount) ASSERT_RACCT_ENABLED(); - SDT_PROBE(racct, kernel, rusage, add, p, resource, amount, 0, 0); + SDT_PROBE3(racct, kernel, rusage, add, p, resource, amount); /* * We need proc lock to dereference p->p_ucred. @@ -548,8 +548,8 @@ racct_add_locked(struct proc *p, int resource, uint64_t amount) #ifdef RCTL error = rctl_enforce(p, resource, amount); if (error && RACCT_IS_DENIABLE(resource)) { - SDT_PROBE(racct, kernel, rusage, add__failure, p, resource, - amount, 0, 0); + SDT_PROBE3(racct, kernel, rusage, add__failure, p, resource, + amount); return (error); } #endif @@ -584,8 +584,7 @@ racct_add_cred_locked(struct ucred *cred, int resource, uint64_t amount) ASSERT_RACCT_ENABLED(); - SDT_PROBE(racct, kernel, rusage, add__cred, cred, resource, amount, - 0, 0); + SDT_PROBE3(racct, kernel, rusage, add__cred, cred, resource, amount); racct_adjust_resource(cred->cr_ruidinfo->ui_racct, resource, amount); for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) @@ -623,7 +622,7 @@ racct_add_force(struct proc *p, int resource, uint64_t amount) if (!racct_enable) return; - SDT_PROBE(racct, kernel, rusage, add__force, p, resource, amount, 0, 0); + SDT_PROBE3(racct, kernel, rusage, add__force, p, resource, amount); /* * We need proc lock to dereference p->p_ucred. @@ -647,7 +646,7 @@ racct_set_locked(struct proc *p, int resource, uint64_t amount) ASSERT_RACCT_ENABLED(); - SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0); + SDT_PROBE3(racct, kernel, rusage, set, p, resource, amount); /* * We need proc lock to dereference p->p_ucred. @@ -679,8 +678,8 @@ racct_set_locked(struct proc *p, int resource, uint64_t amount) if (diff_proc > 0) { error = rctl_enforce(p, resource, diff_proc); if (error && RACCT_IS_DENIABLE(resource)) { - SDT_PROBE(racct, kernel, rusage, set__failure, p, - resource, amount, 0, 0); + SDT_PROBE3(racct, kernel, rusage, set__failure, p, + resource, amount); return (error); } } @@ -723,7 +722,7 @@ racct_set_force_locked(struct proc *p, int resource, uint64_t amount) ASSERT_RACCT_ENABLED(); - SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0); + SDT_PROBE3(racct, kernel, rusage, set, p, resource, amount); /* * We need proc lock to dereference p->p_ucred. @@ -834,7 +833,7 @@ racct_sub(struct proc *p, int resource, uint64_t amount) if (!racct_enable) return; - SDT_PROBE(racct, kernel, rusage, sub, p, resource, amount, 0, 0); + SDT_PROBE3(racct, kernel, rusage, sub, p, resource, amount); /* * We need proc lock to dereference p->p_ucred. @@ -861,8 +860,7 @@ racct_sub_cred_locked(struct ucred *cred, int resource, uint64_t amount) ASSERT_RACCT_ENABLED(); - SDT_PROBE(racct, kernel, rusage, sub__cred, cred, resource, amount, - 0, 0); + SDT_PROBE3(racct, kernel, rusage, sub__cred, cred, resource, amount); #ifdef notyet KASSERT(RACCT_CAN_DROP(resource), diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index 29ea693..87e7d63 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -137,6 +137,10 @@ static int show_busybufs = 1; SYSCTL_INT(_kern_shutdown, OID_AUTO, show_busybufs, CTLFLAG_RW, &show_busybufs, 0, ""); +int suspend_blocked = 0; +SYSCTL_INT(_kern, OID_AUTO, suspend_blocked, CTLFLAG_RW, + &suspend_blocked, 0, "Block suspend due to a pending shutdown"); + /* * Variable panicstr contains argument to first call to panic; used as flag * to indicate that the kernel has already called panic. diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index b57f6b6..767eff0 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1308,7 +1308,7 @@ kern_sigtimedwait(struct thread *td, sigset_t waitset, ksiginfo_t *ksi, reschedule_signals(p, new_block, 0); if (error == 0) { - SDT_PROBE(proc, kernel, , signal__clear, sig, ksi, 0, 0, 0); + SDT_PROBE2(proc, kernel, , signal__clear, sig, ksi); if (ksi->ksi_code == SI_TIMER) itimer_accept(p, ksi->ksi_timerid, ksi); @@ -2121,7 +2121,7 @@ tdsendsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi) } else sigqueue = &td->td_sigqueue; - SDT_PROBE(proc, kernel, , signal__send, td, p, sig, 0, 0 ); + SDT_PROBE3(proc, kernel, , signal__send, td, p, sig); /* * If the signal is being ignored, @@ -2132,7 +2132,7 @@ tdsendsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi) */ mtx_lock(&ps->ps_mtx); if (SIGISMEMBER(ps->ps_sigignore, sig)) { - SDT_PROBE(proc, kernel, , signal__discard, td, p, sig, 0, 0 ); + SDT_PROBE3(proc, kernel, , signal__discard, td, p, sig); mtx_unlock(&ps->ps_mtx); if (ksi && (ksi->ksi_flags & KSI_INS)) diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index 432e38a..d4a1a53 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -1924,20 +1924,27 @@ SYSINIT(timecounter, SI_SUB_CLOCKS, SI_ORDER_SECOND, inittimecounter, NULL); static int cpu_tick_variable; static uint64_t cpu_tick_frequency; +static DPCPU_DEFINE(uint64_t, tc_cpu_ticks_base); +static DPCPU_DEFINE(unsigned, tc_cpu_ticks_last); + static uint64_t tc_cpu_ticks(void) { - static uint64_t base; - static unsigned last; - unsigned u; struct timecounter *tc; + uint64_t res, *base; + unsigned u, *last; + critical_enter(); + base = DPCPU_PTR(tc_cpu_ticks_base); + last = DPCPU_PTR(tc_cpu_ticks_last); tc = timehands->th_counter; u = tc->tc_get_timecount(tc) & tc->tc_counter_mask; - if (u < last) - base += (uint64_t)tc->tc_counter_mask + 1; - last = u; - return (u + base); + if (u < *last) + *base += (uint64_t)tc->tc_counter_mask + 1; + *last = u; + res = u + *base; + critical_exit(); + return (res); } void diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c index 71c88e0..01cf176 100644 --- a/sys/kern/kern_timeout.c +++ b/sys/kern/kern_timeout.c @@ -718,9 +718,9 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc, sbt1 = sbinuptime(); #endif THREAD_NO_SLEEPING(); - SDT_PROBE(callout_execute, kernel, , callout__start, c, 0, 0, 0, 0); + SDT_PROBE1(callout_execute, kernel, , callout__start, c); c_func(c_arg); - SDT_PROBE(callout_execute, kernel, , callout__end, c, 0, 0, 0, 0); + SDT_PROBE1(callout_execute, kernel, , callout__end, c); THREAD_SLEEPING_OK(); #if defined(DIAGNOSTIC) || defined(CALLOUT_PROFILING) sbt2 = sbinuptime(); diff --git a/sys/kern/subr_sbuf.c b/sys/kern/subr_sbuf.c index 3b5660e..3c36b28 100644 --- a/sys/kern/subr_sbuf.c +++ b/sys/kern/subr_sbuf.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include <sys/ctype.h> #include <sys/errno.h> #include <sys/kernel.h> +#include <sys/limits.h> #include <sys/malloc.h> #include <sys/systm.h> #include <sys/uio.h> @@ -42,6 +43,7 @@ __FBSDID("$FreeBSD$"); #else /* _KERNEL */ #include <ctype.h> #include <errno.h> +#include <limits.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -383,34 +385,51 @@ sbuf_drain(struct sbuf *s) } /* - * Append a byte to an sbuf. This is the core function for appending + * Append bytes to an sbuf. This is the core function for appending * to an sbuf and is the main place that deals with extending the * buffer and marking overflow. */ static void -sbuf_put_byte(struct sbuf *s, int c) +sbuf_put_bytes(struct sbuf *s, const char *buf, size_t len) { + size_t n; assert_sbuf_integrity(s); assert_sbuf_state(s, 0); if (s->s_error != 0) return; - if (SBUF_FREESPACE(s) <= 0) { - /* - * If there is a drain, use it, otherwise extend the - * buffer. - */ - if (s->s_drain_func != NULL) - (void)sbuf_drain(s); - else if (sbuf_extend(s, 1) < 0) - s->s_error = ENOMEM; - if (s->s_error != 0) - return; + while (len > 0) { + if (SBUF_FREESPACE(s) <= 0) { + /* + * If there is a drain, use it, otherwise extend the + * buffer. + */ + if (s->s_drain_func != NULL) + (void)sbuf_drain(s); + else if (sbuf_extend(s, len > INT_MAX ? INT_MAX : len) + < 0) + s->s_error = ENOMEM; + if (s->s_error != 0) + return; + } + n = SBUF_FREESPACE(s); + if (len < n) + n = len; + memcpy(&s->s_buf[s->s_len], buf, n); + s->s_len += n; + if (SBUF_ISSECTION(s)) + s->s_sect_len += n; + len -= n; + buf += n; } - s->s_buf[s->s_len++] = c; - if (SBUF_ISSECTION(s)) - s->s_sect_len++; +} + +static void +sbuf_put_byte(struct sbuf *s, char c) +{ + + sbuf_put_bytes(s, &c, 1); } /* @@ -419,19 +438,10 @@ sbuf_put_byte(struct sbuf *s, int c) int sbuf_bcat(struct sbuf *s, const void *buf, size_t len) { - const char *str = buf; - const char *end = str + len; - - assert_sbuf_integrity(s); - assert_sbuf_state(s, 0); + sbuf_put_bytes(s, buf, len); if (s->s_error != 0) return (-1); - for (; str < end; str++) { - sbuf_put_byte(s, *str); - if (s->s_error != 0) - return (-1); - } return (0); } @@ -485,18 +495,12 @@ sbuf_bcpy(struct sbuf *s, const void *buf, size_t len) int sbuf_cat(struct sbuf *s, const char *str) { + size_t n; - assert_sbuf_integrity(s); - assert_sbuf_state(s, 0); - + n = strlen(str); + sbuf_put_bytes(s, str, n); if (s->s_error != 0) return (-1); - - while (*str != '\0') { - sbuf_put_byte(s, *str++); - if (s->s_error != 0) - return (-1); - } return (0); } diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 5053fd1..0fab000 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -111,7 +111,6 @@ static void vfs_page_set_validclean(struct buf *bp, vm_ooffset_t off, static void vfs_clean_pages_dirty_buf(struct buf *bp); static void vfs_setdirty_locked_object(struct buf *bp); static void vfs_vmio_invalidate(struct buf *bp); -static void vfs_vmio_release(struct buf *bp); static void vfs_vmio_truncate(struct buf *bp, int npages); static void vfs_vmio_extend(struct buf *bp, int npages, int size); static int vfs_bio_clcheck(struct vnode *vp, int size, @@ -1786,6 +1785,8 @@ brelse(struct buf *bp) bp, bp->b_vp, bp->b_flags); KASSERT(!(bp->b_flags & (B_CLUSTER|B_PAGING)), ("brelse: inappropriate B_PAGING or B_CLUSTER bp %p", bp)); + KASSERT((bp->b_flags & B_VMIO) != 0 || (bp->b_flags & B_NOREUSE) == 0, + ("brelse: non-VMIO buffer marked NOREUSE")); if (BUF_LOCKRECURSED(bp)) { /* @@ -1830,20 +1831,19 @@ brelse(struct buf *bp) bdirtysub(); bp->b_flags &= ~(B_DELWRI | B_CACHE); if ((bp->b_flags & B_VMIO) == 0) { - if (bp->b_bufsize) - allocbuf(bp, 0); + allocbuf(bp, 0); if (bp->b_vp) brelvp(bp); } } /* - * We must clear B_RELBUF if B_DELWRI is set. If vfs_vmio_release() + * We must clear B_RELBUF if B_DELWRI is set. If vfs_vmio_truncate() * is called with B_DELWRI set, the underlying pages may wind up * getting freed causing a previous write (bdwrite()) to get 'lost' * because pages associated with a B_DELWRI bp are marked clean. * - * We still allow the B_INVAL case to call vfs_vmio_release(), even + * We still allow the B_INVAL case to call vfs_vmio_truncate(), even * if B_DELWRI is set. */ if (bp->b_flags & B_DELWRI) @@ -1870,14 +1870,15 @@ brelse(struct buf *bp) (bp->b_ioflags & BIO_ERROR && bp->b_iocmd == BIO_READ)) && !(bp->b_vp->v_mount != NULL && (bp->b_vp->v_mount->mnt_vfc->vfc_flags & VFCF_NETWORK) != 0 && - !vn_isdisk(bp->b_vp, NULL) && (bp->b_flags & B_DELWRI))) + !vn_isdisk(bp->b_vp, NULL) && (bp->b_flags & B_DELWRI))) { vfs_vmio_invalidate(bp); + allocbuf(bp, 0); + } - if ((bp->b_flags & (B_INVAL | B_RELBUF)) != 0) { - if (bp->b_flags & B_VMIO) - vfs_vmio_release(bp); - if (bp->b_bufsize != 0) - allocbuf(bp, 0); + if ((bp->b_flags & (B_INVAL | B_RELBUF)) != 0 || + (bp->b_flags & (B_DELWRI | B_NOREUSE)) == B_NOREUSE) { + allocbuf(bp, 0); + bp->b_flags &= ~B_NOREUSE; if (bp->b_vp != NULL) brelvp(bp); } @@ -1972,6 +1973,10 @@ bqrelse(struct buf *bp) if ((bp->b_flags & B_DELWRI) == 0 && (bp->b_xflags & BX_VNDIRTY)) panic("bqrelse: not dirty"); + if ((bp->b_flags & B_NOREUSE) != 0) { + brelse(bp); + return; + } qindex = QUEUE_CLEAN; } binsfree(bp, qindex); @@ -2059,8 +2064,46 @@ vfs_vmio_iodone(struct buf *bp) } /* + * Unwire a page held by a buf and place it on the appropriate vm queue. + */ +static void +vfs_vmio_unwire(struct buf *bp, vm_page_t m) +{ + bool freed; + + vm_page_lock(m); + if (vm_page_unwire(m, PQ_NONE)) { + /* + * Determine if the page should be freed before adding + * it to the inactive queue. + */ + if (m->valid == 0) { + freed = !vm_page_busied(m); + if (freed) + vm_page_free(m); + } else if ((bp->b_flags & B_DIRECT) != 0) + freed = vm_page_try_to_free(m); + else + freed = false; + if (!freed) { + /* + * If the page is unlikely to be reused, let the + * VM know. Otherwise, maintain LRU page + * ordering and put the page at the tail of the + * inactive queue. + */ + if ((bp->b_flags & B_NOREUSE) != 0) + vm_page_deactivate_noreuse(m); + else + vm_page_deactivate(m); + } + } + vm_page_unlock(m); +} + +/* * Perform page invalidation when a buffer is released. The fully invalid - * pages will be reclaimed later in vfs_vmio_release(). + * pages will be reclaimed later in vfs_vmio_truncate(). */ static void vfs_vmio_invalidate(struct buf *bp) @@ -2069,6 +2112,11 @@ vfs_vmio_invalidate(struct buf *bp) vm_page_t m; int i, resid, poffset, presid; + if (buf_mapped(bp)) { + BUF_CHECK_MAPPED(bp); + pmap_qremove(trunc_page((vm_offset_t)bp->b_data), bp->b_npages); + } else + BUF_CHECK_UNMAPPED(bp); /* * Get the base offset and length of the buffer. Note that * in the VMIO case if the buffer block size is not @@ -2089,6 +2137,7 @@ vfs_vmio_invalidate(struct buf *bp) m = bp->b_pages[i]; if (m == bogus_page) panic("vfs_vmio_invalidate: Unexpected bogus page."); + bp->b_pages[i] = NULL; presid = resid > (PAGE_SIZE - poffset) ? (PAGE_SIZE - poffset) : resid; @@ -2101,63 +2150,12 @@ vfs_vmio_invalidate(struct buf *bp) } if (pmap_page_wired_mappings(m) == 0) vm_page_set_invalid(m, poffset, presid); + vfs_vmio_unwire(bp, m); resid -= presid; poffset = 0; } VM_OBJECT_WUNLOCK(obj); -} - -/* Give pages used by the bp back to the VM system (where possible) */ -static void -vfs_vmio_release(struct buf *bp) -{ - vm_object_t obj; - vm_page_t m; - int i; - bool freed; - - if (buf_mapped(bp)) { - BUF_CHECK_MAPPED(bp); - pmap_qremove(trunc_page((vm_offset_t)bp->b_data), bp->b_npages); - } else - BUF_CHECK_UNMAPPED(bp); - obj = bp->b_bufobj->bo_object; - if (obj != NULL) - VM_OBJECT_WLOCK(obj); - for (i = 0; i < bp->b_npages; i++) { - m = bp->b_pages[i]; - bp->b_pages[i] = NULL; - vm_page_lock(m); - if (vm_page_unwire(m, PQ_NONE)) { - /* - * Determine if the page should be freed before adding - * it to the inactive queue. - */ - if ((bp->b_flags & B_ASYNC) == 0 && m->valid == 0) { - freed = !vm_page_busied(m); - if (freed) - vm_page_free(m); - } else if ((bp->b_flags & B_DIRECT) != 0) - freed = vm_page_try_to_free(m); - else - freed = false; - if (!freed) { - /* - * In order to maintain LRU page ordering, put - * the page at the tail of the inactive queue. - */ - vm_page_deactivate(m); - } - } - vm_page_unlock(m); - } - if (obj != NULL) - VM_OBJECT_WUNLOCK(obj); - - if (bp->b_bufsize) - bufspaceadjust(bp, 0); bp->b_npages = 0; - bp->b_flags &= ~B_VMIO; } /* @@ -2166,6 +2164,7 @@ vfs_vmio_release(struct buf *bp) static void vfs_vmio_truncate(struct buf *bp, int desiredpages) { + vm_object_t obj; vm_page_t m; int i; @@ -2178,22 +2177,17 @@ vfs_vmio_truncate(struct buf *bp, int desiredpages) (desiredpages << PAGE_SHIFT), bp->b_npages - desiredpages); } else BUF_CHECK_UNMAPPED(bp); - VM_OBJECT_WLOCK(bp->b_bufobj->bo_object); + obj = bp->b_bufobj->bo_object; + if (obj != NULL) + VM_OBJECT_WLOCK(obj); for (i = desiredpages; i < bp->b_npages; i++) { - /* - * The page is not freed here -- it is the responsibility of - * vnode_pager_setsize. - */ m = bp->b_pages[i]; KASSERT(m != bogus_page, ("allocbuf: bogus page found")); - while (vm_page_sleep_if_busy(m, "biodep")) - continue; bp->b_pages[i] = NULL; - vm_page_lock(m); - vm_page_unwire(m, PQ_INACTIVE); - vm_page_unlock(m); + vfs_vmio_unwire(bp, m); } - VM_OBJECT_WUNLOCK(bp->b_bufobj->bo_object); + if (obj != NULL) + VM_OBJECT_WUNLOCK(obj); bp->b_npages = desiredpages; } @@ -2475,14 +2469,16 @@ getnewbuf_reuse_bp(struct buf *bp, int qindex) * Note: we no longer distinguish between VMIO and non-VMIO * buffers. */ - KASSERT((bp->b_flags & B_DELWRI) == 0, - ("delwri buffer %p found in queue %d", bp, qindex)); + KASSERT((bp->b_flags & (B_DELWRI | B_NOREUSE)) == 0, + ("invalid buffer %p flags %#x found in queue %d", bp, bp->b_flags, + qindex)); + /* + * When recycling a clean buffer we have to truncate it and + * release the vnode. + */ if (qindex == QUEUE_CLEAN) { - if (bp->b_flags & B_VMIO) { - bp->b_flags &= ~B_ASYNC; - vfs_vmio_release(bp); - } + allocbuf(bp, 0); if (bp->b_vp != NULL) brelvp(bp); } @@ -2491,7 +2487,6 @@ getnewbuf_reuse_bp(struct buf *bp, int qindex) * Get the rest of the buffer freed up. b_kva* is still valid * after this operation. */ - if (bp->b_rcred != NOCRED) { crfree(bp->b_rcred); bp->b_rcred = NOCRED; @@ -2508,9 +2503,8 @@ getnewbuf_reuse_bp(struct buf *bp, int qindex) bp, bp->b_vp, qindex)); KASSERT((bp->b_xflags & (BX_VNCLEAN|BX_VNDIRTY)) == 0, ("bp: %p still on a buffer list. xflags %X", bp, bp->b_xflags)); - - if (bp->b_bufsize) - allocbuf(bp, 0); + KASSERT(bp->b_npages == 0, + ("bp: %p still has %d vm pages\n", bp, bp->b_npages)); bp->b_flags = 0; bp->b_ioflags = 0; @@ -3426,8 +3420,7 @@ loop: * cleared. If the size has not changed, B_CACHE remains * unchanged from its previous state. */ - if (bp->b_bcount != size) - allocbuf(bp, size); + allocbuf(bp, size); KASSERT(bp->b_offset != NOOFFSET, ("getblk: no buffer offset")); @@ -3678,6 +3671,9 @@ allocbuf(struct buf *bp, int size) BUF_ASSERT_HELD(bp); + if (bp->b_bcount == size) + return (1); + if (bp->b_kvasize != 0 && bp->b_kvasize < size) panic("allocbuf: buffer too small"); @@ -3716,7 +3712,7 @@ allocbuf(struct buf *bp, int size) bufspaceadjust(bp, newbsize); } bp->b_bcount = size; /* requested buffer size. */ - return 1; + return (1); } extern int inflight_transient_maps; diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index 5fe0382..ca9f054 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -419,11 +419,11 @@ cache_zap(ncp) CTR2(KTR_VFS, "cache_zap(%p) vp %p", ncp, ncp->nc_vp); #ifdef KDTRACE_HOOKS if (ncp->nc_vp != NULL) { - SDT_PROBE(vfs, namecache, zap, done, ncp->nc_dvp, - nc_get_name(ncp), ncp->nc_vp, 0, 0); + SDT_PROBE3(vfs, namecache, zap, done, ncp->nc_dvp, + nc_get_name(ncp), ncp->nc_vp); } else { - SDT_PROBE(vfs, namecache, zap_negative, done, ncp->nc_dvp, - nc_get_name(ncp), 0, 0, 0); + SDT_PROBE2(vfs, namecache, zap_negative, done, ncp->nc_dvp, + nc_get_name(ncp)); } #endif vp = NULL; @@ -498,8 +498,7 @@ retry_wlocked: CTR2(KTR_VFS, "cache_lookup(%p, %s) found via .", dvp, cnp->cn_nameptr); dothits++; - SDT_PROBE(vfs, namecache, lookup, hit, dvp, ".", - *vpp, 0, 0); + SDT_PROBE3(vfs, namecache, lookup, hit, dvp, ".", *vpp); if (tsp != NULL) timespecclear(tsp); if (ticksp != NULL) @@ -509,8 +508,8 @@ retry_wlocked: if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') { dotdothits++; if (dvp->v_cache_dd == NULL) { - SDT_PROBE(vfs, namecache, lookup, miss, dvp, - "..", NULL, 0, 0); + SDT_PROBE3(vfs, namecache, lookup, miss, dvp, + "..", NULL); goto unlock; } if ((cnp->cn_flags & MAKEENTRY) == 0) { @@ -532,8 +531,8 @@ retry_wlocked: goto negative_success; CTR3(KTR_VFS, "cache_lookup(%p, %s) found %p via ..", dvp, cnp->cn_nameptr, *vpp); - SDT_PROBE(vfs, namecache, lookup, hit, dvp, "..", - *vpp, 0, 0); + SDT_PROBE3(vfs, namecache, lookup, hit, dvp, "..", + *vpp); cache_out_ts(ncp, tsp, ticksp); if ((ncp->nc_flag & (NCF_ISDOTDOT | NCF_DTS)) == NCF_DTS && tsp != NULL) @@ -554,8 +553,8 @@ retry_wlocked: /* We failed to find an entry */ if (ncp == NULL) { - SDT_PROBE(vfs, namecache, lookup, miss, dvp, cnp->cn_nameptr, - NULL, 0, 0); + SDT_PROBE3(vfs, namecache, lookup, miss, dvp, cnp->cn_nameptr, + NULL); if ((cnp->cn_flags & MAKEENTRY) == 0) { nummisszap++; } else { @@ -583,8 +582,8 @@ retry_wlocked: *vpp = ncp->nc_vp; CTR4(KTR_VFS, "cache_lookup(%p, %s) found %p via ncp %p", dvp, cnp->cn_nameptr, *vpp, ncp); - SDT_PROBE(vfs, namecache, lookup, hit, dvp, nc_get_name(ncp), - *vpp, 0, 0); + SDT_PROBE3(vfs, namecache, lookup, hit, dvp, nc_get_name(ncp), + *vpp); cache_out_ts(ncp, tsp, ticksp); goto success; } @@ -615,8 +614,8 @@ negative_success: nchstats.ncs_neghits++; if (ncp->nc_flag & NCF_WHITE) cnp->cn_flags |= ISWHITEOUT; - SDT_PROBE(vfs, namecache, lookup, hit__negative, dvp, nc_get_name(ncp), - 0, 0, 0); + SDT_PROBE2(vfs, namecache, lookup, hit__negative, dvp, + nc_get_name(ncp)); cache_out_ts(ncp, tsp, ticksp); CACHE_WUNLOCK(); return (ENOENT); @@ -769,8 +768,7 @@ cache_enter_time(dvp, vp, cnp, tsp, dtsp) return; } dvp->v_cache_dd = NULL; - SDT_PROBE(vfs, namecache, enter, done, dvp, "..", vp, - 0, 0); + SDT_PROBE3(vfs, namecache, enter, done, dvp, "..", vp); CACHE_WUNLOCK(); flag = NCF_ISDOTDOT; } @@ -890,12 +888,12 @@ cache_enter_time(dvp, vp, cnp, tsp, dtsp) */ if (vp) { TAILQ_INSERT_HEAD(&vp->v_cache_dst, ncp, nc_dst); - SDT_PROBE(vfs, namecache, enter, done, dvp, nc_get_name(ncp), - vp, 0, 0); + SDT_PROBE3(vfs, namecache, enter, done, dvp, nc_get_name(ncp), + vp); } else { TAILQ_INSERT_TAIL(&ncneg, ncp, nc_dst); - SDT_PROBE(vfs, namecache, enter_negative, done, dvp, - nc_get_name(ncp), 0, 0, 0); + SDT_PROBE2(vfs, namecache, enter_negative, done, dvp, + nc_get_name(ncp)); } if (numneg * ncnegfactor > numcache) { ncp = TAILQ_FIRST(&ncneg); @@ -984,7 +982,7 @@ cache_purge(vp) { CTR1(KTR_VFS, "cache_purge(%p)", vp); - SDT_PROBE(vfs, namecache, purge, done, vp, 0, 0, 0, 0); + SDT_PROBE1(vfs, namecache, purge, done, vp); CACHE_WLOCK(); while (!LIST_EMPTY(&vp->v_cache_src)) cache_zap(LIST_FIRST(&vp->v_cache_src)); @@ -1009,7 +1007,7 @@ cache_purge_negative(vp) struct namecache *cp, *ncp; CTR1(KTR_VFS, "cache_purge_negative(%p)", vp); - SDT_PROBE(vfs, namecache, purge_negative, done, vp, 0, 0, 0, 0); + SDT_PROBE1(vfs, namecache, purge_negative, done, vp); CACHE_WLOCK(); LIST_FOREACH_SAFE(cp, &vp->v_cache_src, nc_src, ncp) { if (cp->nc_vp == NULL) @@ -1029,7 +1027,7 @@ cache_purgevfs(mp) struct namecache *ncp, *nnp; /* Scan hash tables for applicable entries */ - SDT_PROBE(vfs, namecache, purgevfs, done, mp, 0, 0, 0, 0); + SDT_PROBE1(vfs, namecache, purgevfs, done, mp); CACHE_WLOCK(); for (ncpp = &nchashtbl[nchash]; ncpp >= nchashtbl; ncpp--) { LIST_FOREACH_SAFE(ncp, ncpp, nc_hash, nnp) { @@ -1253,14 +1251,14 @@ vn_vptocnp_locked(struct vnode **vp, struct ucred *cred, char *buf, vrele(*vp); numfullpathfail4++; error = ENOMEM; - SDT_PROBE(vfs, namecache, fullpath, return, error, - vp, NULL, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, error, + vp, NULL); return (error); } *buflen -= ncp->nc_nlen; memcpy(buf + *buflen, nc_get_name(ncp), ncp->nc_nlen); - SDT_PROBE(vfs, namecache, fullpath, hit, ncp->nc_dvp, - nc_get_name(ncp), vp, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, hit, ncp->nc_dvp, + nc_get_name(ncp), vp); dvp = *vp; *vp = ncp->nc_dvp; vref(*vp); @@ -1269,7 +1267,7 @@ vn_vptocnp_locked(struct vnode **vp, struct ucred *cred, char *buf, CACHE_RLOCK(); return (0); } - SDT_PROBE(vfs, namecache, fullpath, miss, vp, 0, 0, 0, 0); + SDT_PROBE1(vfs, namecache, fullpath, miss, vp); CACHE_RUNLOCK(); vn_lock(*vp, LK_SHARED | LK_RETRY); @@ -1277,8 +1275,7 @@ vn_vptocnp_locked(struct vnode **vp, struct ucred *cred, char *buf, vput(*vp); if (error) { numfullpathfail2++; - SDT_PROBE(vfs, namecache, fullpath, return, error, vp, - NULL, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, error, vp, NULL); return (error); } @@ -1289,8 +1286,7 @@ vn_vptocnp_locked(struct vnode **vp, struct ucred *cred, char *buf, CACHE_RUNLOCK(); vrele(dvp); error = ENOENT; - SDT_PROBE(vfs, namecache, fullpath, return, error, vp, - NULL, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, error, vp, NULL); return (error); } /* @@ -1318,7 +1314,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, error = 0; slash_prefixed = 0; - SDT_PROBE(vfs, namecache, fullpath, entry, vp, 0, 0, 0, 0); + SDT_PROBE1(vfs, namecache, fullpath, entry, vp); numfullpathcalls++; vref(vp); CACHE_RLOCK(); @@ -1340,8 +1336,8 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, CACHE_RUNLOCK(); vrele(vp); error = ENOENT; - SDT_PROBE(vfs, namecache, fullpath, return, - error, vp, NULL, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, + error, vp, NULL); break; } vp1 = vp->v_mount->mnt_vnodecovered; @@ -1357,8 +1353,8 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, vrele(vp); numfullpathfail1++; error = ENOTDIR; - SDT_PROBE(vfs, namecache, fullpath, return, - error, vp, NULL, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, + error, vp, NULL); break; } error = vn_vptocnp_locked(&vp, td->td_ucred, buf, &buflen); @@ -1368,8 +1364,8 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, CACHE_RUNLOCK(); vrele(vp); error = ENOMEM; - SDT_PROBE(vfs, namecache, fullpath, return, error, - startvp, NULL, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, error, + startvp, NULL); break; } buf[--buflen] = '/'; @@ -1382,8 +1378,8 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, CACHE_RUNLOCK(); vrele(vp); numfullpathfail4++; - SDT_PROBE(vfs, namecache, fullpath, return, ENOMEM, - startvp, NULL, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, ENOMEM, + startvp, NULL); return (ENOMEM); } buf[--buflen] = '/'; @@ -1392,8 +1388,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, CACHE_RUNLOCK(); vrele(vp); - SDT_PROBE(vfs, namecache, fullpath, return, 0, startvp, buf + buflen, - 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, 0, startvp, buf + buflen); *retbuf = buf + buflen; return (0); } diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index d70b685..6ee094b 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -1034,9 +1034,12 @@ vop_stdallocate(struct vop_allocate_args *ap) int vop_stdadvise(struct vop_advise_args *ap) { + struct buf *bp; + struct buflists *bl; struct vnode *vp; + daddr_t bn, startn, endn; off_t start, end; - int error; + int bsize, error; vp = ap->a_vp; switch (ap->a_advice) { @@ -1049,28 +1052,58 @@ vop_stdadvise(struct vop_advise_args *ap) error = 0; break; case POSIX_FADV_DONTNEED: - /* - * Flush any open FS buffers and then remove pages - * from the backing VM object. Using vinvalbuf() here - * is a bit heavy-handed as it flushes all buffers for - * the given vnode, not just the buffers covering the - * requested range. - */ error = 0; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); if (vp->v_iflag & VI_DOOMED) { VOP_UNLOCK(vp, 0); break; } - vinvalbuf(vp, V_CLEANONLY, 0, 0); + + /* + * Deactivate pages in the specified range from the backing VM + * object. Pages that are resident in the buffer cache will + * remain wired until their corresponding buffers are released + * below. + */ if (vp->v_object != NULL) { start = trunc_page(ap->a_start); end = round_page(ap->a_end); VM_OBJECT_WLOCK(vp->v_object); - vm_object_page_cache(vp->v_object, OFF_TO_IDX(start), + vm_object_page_noreuse(vp->v_object, OFF_TO_IDX(start), OFF_TO_IDX(end)); VM_OBJECT_WUNLOCK(vp->v_object); } + + BO_RLOCK(&vp->v_bufobj); + bsize = vp->v_bufobj.bo_bsize; + startn = ap->a_start / bsize; + endn = -1; + bl = &vp->v_bufobj.bo_clean.bv_hd; + if (!TAILQ_EMPTY(bl)) + endn = TAILQ_LAST(bl, buflists)->b_lblkno; + bl = &vp->v_bufobj.bo_dirty.bv_hd; + if (!TAILQ_EMPTY(bl) && + endn < TAILQ_LAST(bl, buflists)->b_lblkno) + endn = TAILQ_LAST(bl, buflists)->b_lblkno; + if (ap->a_end != OFF_MAX && endn != -1) + endn = ap->a_end / bsize; + BO_RUNLOCK(&vp->v_bufobj); + /* + * In the VMIO case, use the B_NOREUSE flag to hint that the + * pages backing each buffer in the range are unlikely to be + * reused. Dirty buffers will have the hint applied once + * they've been written. + */ + for (bn = startn; bn <= endn; bn++) { + bp = getblk(vp, bn, bsize, 0, 0, GB_NOCREAT | + GB_UNMAPPED); + if (bp == NULL) + continue; + bp->b_flags |= B_RELBUF; + if (vp->v_object != NULL) + bp->b_flags |= B_NOREUSE; + brelse(bp); + } VOP_UNLOCK(vp, 0); break; default: diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index d52d622..9a2a1db 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -299,16 +299,15 @@ namei(struct nameidata *ndp) namei_cleanup_cnp(cnp); return (error); } - SDT_PROBE(vfs, namei, lookup, entry, dp, cnp->cn_pnbuf, - cnp->cn_flags, 0, 0); + SDT_PROBE3(vfs, namei, lookup, entry, dp, cnp->cn_pnbuf, + cnp->cn_flags); for (;;) { ndp->ni_startdir = dp; error = lookup(ndp); if (error != 0) { vrele(ndp->ni_rootdir); namei_cleanup_cnp(cnp); - SDT_PROBE(vfs, namei, lookup, return, error, NULL, 0, - 0, 0); + SDT_PROBE2(vfs, namei, lookup, return, error, NULL); return (error); } /* @@ -321,8 +320,7 @@ namei(struct nameidata *ndp) } else cnp->cn_flags |= HASBUF; - SDT_PROBE(vfs, namei, lookup, return, 0, ndp->ni_vp, - 0, 0, 0); + SDT_PROBE2(vfs, namei, lookup, return, 0, ndp->ni_vp); return (0); } if (ndp->ni_loopcnt++ >= MAXSYMLINKS) { @@ -397,7 +395,7 @@ namei(struct nameidata *ndp) vput(ndp->ni_vp); ndp->ni_vp = NULL; vrele(ndp->ni_dvp); - SDT_PROBE(vfs, namei, lookup, return, error, NULL, 0, 0, 0); + SDT_PROBE2(vfs, namei, lookup, return, error, NULL); return (error); } diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 29ca5b1..6976c3b 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1429,11 +1429,6 @@ flushbuflist(struct bufv *bufv, int flags, struct bufobj *bo, int slpflag, KASSERT(bp->b_bufobj == bo, ("bp %p wrong b_bufobj %p should be %p", bp, bp->b_bufobj, bo)); - if (bp->b_bufobj != bo) { /* XXX: necessary ? */ - BUF_UNLOCK(bp); - BO_LOCK(bo); - return (EAGAIN); - } /* * XXX Since there are no node locks for NFS, I * believe there is a slight chance that a delayed @@ -3071,8 +3066,8 @@ vn_printf(struct vnode *vp, const char *fmt, ...) "cleanbuf %d dirtybuf %d\n", vp->v_object, vp->v_object->ref_count, vp->v_object->resident_page_count, - vp->v_bufobj.bo_dirty.bv_cnt, - vp->v_bufobj.bo_clean.bv_cnt); + vp->v_bufobj.bo_clean.bv_cnt, + vp->v_bufobj.bo_dirty.bv_cnt); printf(" "); lockmgr_printinfo(vp->v_vnlock); if (vp->v_data != NULL) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 76b83e3..ce4436a 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -2160,9 +2160,9 @@ kern_statat(struct thread *td, int flag, int fd, char *path, return (error); error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); if (error == 0) { - SDT_PROBE(vfs, , stat, mode, path, sb.st_mode, 0, 0, 0); + SDT_PROBE2(vfs, , stat, mode, path, sb.st_mode); if (S_ISREG(sb.st_mode)) - SDT_PROBE(vfs, , stat, reg, path, pathseg, 0, 0, 0); + SDT_PROBE2(vfs, , stat, reg, path, pathseg); if (__predict_false(hook != NULL)) hook(nd.ni_vp, &sb); } @@ -4610,8 +4610,6 @@ kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len, new->fa_advice = advice; new->fa_start = offset; new->fa_end = end; - new->fa_prevstart = 0; - new->fa_prevend = 0; fp->f_advice = new; new = fa; } diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 18a9ac3..f07df31 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -770,10 +770,9 @@ vn_read(fp, uio, active_cred, flags, td) struct thread *td; { struct vnode *vp; - struct mtx *mtxp; + off_t orig_offset; int error, ioflag; int advice; - off_t offset, start, end; KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td)); @@ -797,7 +796,7 @@ vn_read(fp, uio, active_cred, flags, td) /* Disable read-ahead for random I/O. */ break; } - offset = uio->uio_offset; + orig_offset = uio->uio_offset; #ifdef MAC error = mac_vnode_check_read(active_cred, fp->f_cred, vp); @@ -807,39 +806,14 @@ vn_read(fp, uio, active_cred, flags, td) fp->f_nextoff = uio->uio_offset; VOP_UNLOCK(vp, 0); if (error == 0 && advice == POSIX_FADV_NOREUSE && - offset != uio->uio_offset) { + orig_offset != uio->uio_offset) /* - * Use POSIX_FADV_DONTNEED to flush clean pages and - * buffers for the backing file after a - * POSIX_FADV_NOREUSE read(2). To optimize the common - * case of using POSIX_FADV_NOREUSE with sequential - * access, track the previous implicit DONTNEED - * request and grow this request to include the - * current read(2) in addition to the previous - * DONTNEED. With purely sequential access this will - * cause the DONTNEED requests to continously grow to - * cover all of the previously read regions of the - * file. This allows filesystem blocks that are - * accessed by multiple calls to read(2) to be flushed - * once the last read(2) finishes. + * Use POSIX_FADV_DONTNEED to flush pages and buffers + * for the backing file after a POSIX_FADV_NOREUSE + * read(2). */ - start = offset; - end = uio->uio_offset - 1; - mtxp = mtx_pool_find(mtxpool_sleep, fp); - mtx_lock(mtxp); - if (fp->f_advice != NULL && - fp->f_advice->fa_advice == POSIX_FADV_NOREUSE) { - if (start != 0 && fp->f_advice->fa_prevend + 1 == start) - start = fp->f_advice->fa_prevstart; - else if (fp->f_advice->fa_prevstart != 0 && - fp->f_advice->fa_prevstart == end + 1) - end = fp->f_advice->fa_prevend; - fp->f_advice->fa_prevstart = start; - fp->f_advice->fa_prevend = end; - } - mtx_unlock(mtxp); - error = VOP_ADVISE(vp, start, end, POSIX_FADV_DONTNEED); - } + error = VOP_ADVISE(vp, orig_offset, uio->uio_offset - 1, + POSIX_FADV_DONTNEED); return (error); } @@ -856,10 +830,9 @@ vn_write(fp, uio, active_cred, flags, td) { struct vnode *vp; struct mount *mp; - struct mtx *mtxp; + off_t orig_offset; int error, ioflag, lock_flags; int advice; - off_t offset, start, end; KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td)); @@ -902,7 +875,7 @@ vn_write(fp, uio, active_cred, flags, td) /* XXX: Is this correct? */ break; } - offset = uio->uio_offset; + orig_offset = uio->uio_offset; #ifdef MAC error = mac_vnode_check_write(active_cred, fp->f_cred, vp); @@ -914,55 +887,14 @@ vn_write(fp, uio, active_cred, flags, td) if (vp->v_type != VCHR) vn_finished_write(mp); if (error == 0 && advice == POSIX_FADV_NOREUSE && - offset != uio->uio_offset) { + orig_offset != uio->uio_offset) /* - * Use POSIX_FADV_DONTNEED to flush clean pages and - * buffers for the backing file after a - * POSIX_FADV_NOREUSE write(2). To optimize the - * common case of using POSIX_FADV_NOREUSE with - * sequential access, track the previous implicit - * DONTNEED request and grow this request to include - * the current write(2) in addition to the previous - * DONTNEED. With purely sequential access this will - * cause the DONTNEED requests to continously grow to - * cover all of the previously written regions of the - * file. - * - * Note that the blocks just written are almost - * certainly still dirty, so this only works when - * VOP_ADVISE() calls from subsequent writes push out - * the data written by this write(2) once the backing - * buffers are clean. However, as compared to forcing - * IO_DIRECT, this gives much saner behavior. Write - * clustering is still allowed, and clean pages are - * merely moved to the cache page queue rather than - * outright thrown away. This means a subsequent - * read(2) can still avoid hitting the disk if the - * pages have not been reclaimed. - * - * This does make POSIX_FADV_NOREUSE largely useless - * with non-sequential access. However, sequential - * access is the more common use case and the flag is - * merely advisory. + * Use POSIX_FADV_DONTNEED to flush pages and buffers + * for the backing file after a POSIX_FADV_NOREUSE + * write(2). */ - start = offset; - end = uio->uio_offset - 1; - mtxp = mtx_pool_find(mtxpool_sleep, fp); - mtx_lock(mtxp); - if (fp->f_advice != NULL && - fp->f_advice->fa_advice == POSIX_FADV_NOREUSE) { - if (start != 0 && fp->f_advice->fa_prevend + 1 == start) - start = fp->f_advice->fa_prevstart; - else if (fp->f_advice->fa_prevstart != 0 && - fp->f_advice->fa_prevstart == end + 1) - end = fp->f_advice->fa_prevend; - fp->f_advice->fa_prevstart = start; - fp->f_advice->fa_prevend = end; - } - mtx_unlock(mtxp); - error = VOP_ADVISE(vp, start, end, POSIX_FADV_DONTNEED); - } - + error = VOP_ADVISE(vp, orig_offset, uio->uio_offset - 1, + POSIX_FADV_DONTNEED); unlock: return (error); } diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 0d126e4..292ce80 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -1527,7 +1527,7 @@ free_pv_chunk(struct pv_chunk *pc) PV_STAT(pc_chunk_frees++); /* entire chunk is free, return it */ m = PHYS_TO_VM_PAGE(MIPS_DIRECT_TO_PHYS((vm_offset_t)pc)); - vm_page_unwire(m, PQ_INACTIVE); + vm_page_unwire(m, PQ_NONE); vm_page_free(m); } diff --git a/sys/modules/Makefile b/sys/modules/Makefile index df6b01a..f5f9b4c 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -270,6 +270,8 @@ SUBDIR= \ ${_nxge} \ ${_opensolaris} \ oce \ + otus \ + otusfw \ ow \ ${_padlock} \ ${_padlock_rng} \ diff --git a/sys/modules/netgraph/Makefile b/sys/modules/netgraph/Makefile index c9b5748a..1c787f6 100644 --- a/sys/modules/netgraph/Makefile +++ b/sys/modules/netgraph/Makefile @@ -62,4 +62,6 @@ _bluetooth= bluetooth _mppc= mppc .endif +SUBDIR_PARALLEL= + .include <bsd.subdir.mk> diff --git a/sys/modules/otus/Makefile b/sys/modules/otus/Makefile new file mode 100644 index 0000000..b263c06 --- /dev/null +++ b/sys/modules/otus/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/otus + +KMOD = if_otus +SRCS = if_otus.c if_otusreg.h \ + bus_if.h device_if.h \ + opt_bus.h opt_usb.h opt_wlan.h usb_if.h usbdevs.h + +.include <bsd.kmod.mk> diff --git a/sys/modules/otusfw/Makefile b/sys/modules/otusfw/Makefile new file mode 100644 index 0000000..0a47f66 --- /dev/null +++ b/sys/modules/otusfw/Makefile @@ -0,0 +1,5 @@ +# $FreeBSD$ + +SUBDIR=otusfw_init otusfw_main + +.include <bsd.subdir.mk> diff --git a/sys/modules/otusfw/otusfw_init/Makefile b/sys/modules/otusfw/otusfw_init/Makefile new file mode 100644 index 0000000..d188e9a --- /dev/null +++ b/sys/modules/otusfw/otusfw_init/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ + +KMOD= otusfw_init +FIRMWS= otusfw_init:otusfw_init:1 + +CLEANFILES= otus_init + +otusfw_init: ${.CURDIR}/../../../contrib/dev/otus/otus-init + cp ${.CURDIR}/../../../contrib/dev/otus/otus-init ${.TARGET} + +.include <bsd.kmod.mk> diff --git a/sys/modules/otusfw/otusfw_main/Makefile b/sys/modules/otusfw/otusfw_main/Makefile new file mode 100644 index 0000000..94e1aee --- /dev/null +++ b/sys/modules/otusfw/otusfw_main/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ + +KMOD= otusfw_main +FIRMWS= otusfw_main:otusfw_main:1 + +CLEANFILES= otusfw_main + +otusfw_main: ${.CURDIR}/../../../contrib/dev/otus/otus-main + cp ${.CURDIR}/../../../contrib/dev/otus/otus-main ${.TARGET} + +.include <bsd.kmod.mk> diff --git a/sys/modules/usb/rsu/Makefile b/sys/modules/usb/rsu/Makefile index 482071c..755f4b8 100644 --- a/sys/modules/usb/rsu/Makefile +++ b/sys/modules/usb/rsu/Makefile @@ -5,6 +5,6 @@ KMOD = if_rsu SRCS = if_rsu.c if_rsureg.h \ bus_if.h device_if.h \ - opt_bus.h opt_usb.h usb_if.h usbdevs.h + opt_bus.h opt_usb.h opt_wlan.h usb_if.h usbdevs.h .include <bsd.kmod.mk> diff --git a/sys/modules/usb/urtwn/Makefile b/sys/modules/usb/urtwn/Makefile index 58c409a..d965294 100644 --- a/sys/modules/usb/urtwn/Makefile +++ b/sys/modules/usb/urtwn/Makefile @@ -5,6 +5,6 @@ KMOD = if_urtwn SRCS = if_urtwn.c if_urtwnreg.h \ bus_if.h device_if.h \ - opt_bus.h opt_usb.h usb_if.h usbdevs.h + opt_bus.h opt_usb.h opt_wlan.h usb_if.h usbdevs.h .include <bsd.kmod.mk> diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c index bb43be9a..dbb9653 100644 --- a/sys/net/if_llatbl.c +++ b/sys/net/if_llatbl.c @@ -721,7 +721,6 @@ llatbl_lle_show(struct llentry_sa *la) db_printf(" la_flags=0x%04x\n", lle->la_flags); db_printf(" la_asked=%u\n", lle->la_asked); db_printf(" la_preempt=%u\n", lle->la_preempt); - db_printf(" ln_byhint=%u\n", lle->ln_byhint); db_printf(" ln_state=%d\n", lle->ln_state); db_printf(" ln_router=%u\n", lle->ln_router); db_printf(" ln_ntick=%ju\n", (uintmax_t)lle->ln_ntick); diff --git a/sys/net/if_llatbl.h b/sys/net/if_llatbl.h index 98d28f2..1415ad4 100644 --- a/sys/net/if_llatbl.h +++ b/sys/net/if_llatbl.h @@ -75,7 +75,6 @@ struct llentry { uint16_t la_flags; uint16_t la_asked; uint16_t la_preempt; - uint16_t ln_byhint; int16_t ln_state; /* IPv6 has ND6_LLINFO_NOSTATE == -2 */ uint16_t ln_router; time_t ln_ntick; diff --git a/sys/net80211/_ieee80211.h b/sys/net80211/_ieee80211.h index 5120d41..4ff395d 100644 --- a/sys/net80211/_ieee80211.h +++ b/sys/net80211/_ieee80211.h @@ -390,15 +390,14 @@ struct ieee80211_regdomain { * MIMO antenna/radio state. */ -#define IEEE80211_MAX_CHAINS 3 -#define IEEE80211_MAX_EVM_PILOTS 6 - /* * XXX This doesn't yet export both ctl/ext chain details + * XXX TODO: IEEE80211_MAX_CHAINS is defined in _freebsd.h, not here; + * figure out how to pull it in! */ struct ieee80211_mimo_info { - int8_t rssi[IEEE80211_MAX_CHAINS]; /* per-antenna rssi */ - int8_t noise[IEEE80211_MAX_CHAINS]; /* per-antenna noise floor */ + int8_t rssi[3]; /* per-antenna rssi */ + int8_t noise[3]; /* per-antenna noise floor */ uint8_t pad[2]; uint32_t evm[3]; /* EVM data */ }; diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c index 9a8e941..6fdfb5c 100644 --- a/sys/net80211/ieee80211_freebsd.c +++ b/sys/net80211/ieee80211_freebsd.c @@ -491,6 +491,43 @@ ieee80211_process_callback(struct ieee80211_node *ni, } /* + * Add RX parameters to the given mbuf. + * + * Returns 1 if OK, 0 on error. + */ +int +ieee80211_add_rx_params(struct mbuf *m, const struct ieee80211_rx_stats *rxs) +{ + struct m_tag *mtag; + struct ieee80211_rx_params *rx; + + mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS, + sizeof(struct ieee80211_rx_stats), M_NOWAIT); + if (mtag == NULL) + return (0); + + rx = (struct ieee80211_rx_params *)(mtag + 1); + memcpy(&rx->params, rxs, sizeof(*rxs)); + m_tag_prepend(m, mtag); + return (1); +} + +int +ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs) +{ + struct m_tag *mtag; + struct ieee80211_rx_params *rx; + + mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS, + NULL); + if (mtag == NULL) + return (-1); + rx = (struct ieee80211_rx_params *)(mtag + 1); + memcpy(rxs, &rx->params, sizeof(*rxs)); + return (0); +} + +/* * Transmit a frame to the parent interface. * * TODO: if the transmission fails, make sure the parent node is freed diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h index 162cf43..f660c17 100644 --- a/sys/net80211/ieee80211_freebsd.h +++ b/sys/net80211/ieee80211_freebsd.h @@ -330,6 +330,8 @@ void ieee80211_process_callback(struct ieee80211_node *, struct mbuf *, int); #define NET80211_TAG_XMIT_PARAMS 1 /* See below; this is after the bpf_params definition */ +#define NET80211_TAG_RECV_PARAMS 2 + struct ieee80211com; int ieee80211_parent_xmitpkt(struct ieee80211com *, struct mbuf *); int ieee80211_vap_xmitpkt(struct ieee80211vap *, struct mbuf *); @@ -618,6 +620,43 @@ int ieee80211_add_xmit_params(struct mbuf *m, const struct ieee80211_bpf_params *); int ieee80211_get_xmit_params(struct mbuf *m, struct ieee80211_bpf_params *); + +#define IEEE80211_MAX_CHAINS 3 +#define IEEE80211_MAX_EVM_PILOTS 6 + +#define IEEE80211_R_NF 0x0000001 /* global NF value valid */ +#define IEEE80211_R_RSSI 0x0000002 /* global RSSI value valid */ +#define IEEE80211_R_C_CHAIN 0x0000004 /* RX chain count valid */ +#define IEEE80211_R_C_NF 0x0000008 /* per-chain NF value valid */ +#define IEEE80211_R_C_RSSI 0x0000010 /* per-chain RSSI value valid */ +#define IEEE80211_R_C_EVM 0x0000020 /* per-chain EVM valid */ +#define IEEE80211_R_C_HT40 0x0000040 /* RX'ed packet is 40mhz, pilots 4,5 valid */ +#define IEEE80211_R_FREQ 0x0000080 /* Freq value populated, MHz */ +#define IEEE80211_R_IEEE 0x0000100 /* IEEE value populated */ +#define IEEE80211_R_BAND 0x0000200 /* Frequency band populated */ + +struct ieee80211_rx_stats { + uint32_t r_flags; /* IEEE80211_R_* flags */ + uint8_t c_chain; /* number of RX chains involved */ + int16_t c_nf_ctl[IEEE80211_MAX_CHAINS]; /* per-chain NF */ + int16_t c_nf_ext[IEEE80211_MAX_CHAINS]; /* per-chain NF */ + int16_t c_rssi_ctl[IEEE80211_MAX_CHAINS]; /* per-chain RSSI */ + int16_t c_rssi_ext[IEEE80211_MAX_CHAINS]; /* per-chain RSSI */ + uint8_t nf; /* global NF */ + uint8_t rssi; /* global RSSI */ + uint8_t evm[IEEE80211_MAX_CHAINS][IEEE80211_MAX_EVM_PILOTS]; + /* per-chain, per-pilot EVM values */ + uint16_t c_freq; + uint8_t c_ieee; +}; + +struct ieee80211_rx_params { + struct ieee80211_rx_stats params; +}; +int ieee80211_add_rx_params(struct mbuf *m, + const struct ieee80211_rx_stats *rxs); +int ieee80211_get_rx_params(struct mbuf *m, + struct ieee80211_rx_stats *rxs); #endif /* _KERNEL */ /* diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c index b43bc07..a850a33 100644 --- a/sys/net80211/ieee80211_ht.c +++ b/sys/net80211/ieee80211_ht.c @@ -1081,7 +1081,7 @@ ieee80211_ht_node_init(struct ieee80211_node *ni) tap = &ni->ni_tx_ampdu[tid]; tap->txa_tid = tid; tap->txa_ni = ni; - tap->txa_lastsample = ticks; + ieee80211_txampdu_init_pps(tap); /* NB: further initialization deferred */ } ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU; @@ -1251,7 +1251,7 @@ ieee80211_ht_wds_init(struct ieee80211_node *ni) for (tid = 0; tid < WME_NUM_TID; tid++) { tap = &ni->ni_tx_ampdu[tid]; tap->txa_tid = tid; - tap->txa_lastsample = ticks; + ieee80211_txampdu_init_pps(tap); } /* NB: AMPDU tx/rx governed by IEEE80211_FHT_AMPDU_{TX,RX} */ ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU; @@ -1752,8 +1752,7 @@ ampdu_tx_stop(struct ieee80211_tx_ampdu *tap) /* * Reset packet estimate. */ - tap->txa_lastsample = ticks; - tap->txa_avgpps = 0; + ieee80211_txampdu_init_pps(tap); /* NB: clearing NAK means we may re-send ADDBA */ tap->txa_flags &= ~(IEEE80211_AGGR_SETUP | IEEE80211_AGGR_NAK); diff --git a/sys/net80211/ieee80211_ht.h b/sys/net80211/ieee80211_ht.h index f099ffe..e2b3318 100644 --- a/sys/net80211/ieee80211_ht.h +++ b/sys/net80211/ieee80211_ht.h @@ -84,8 +84,19 @@ struct ieee80211_tx_ampdu { */ static __inline void +ieee80211_txampdu_init_pps(struct ieee80211_tx_ampdu *tap) +{ + /* + * Reset packet estimate. + */ + tap->txa_lastsample = ticks; + tap->txa_avgpps = 0; +} + +static __inline void ieee80211_txampdu_update_pps(struct ieee80211_tx_ampdu *tap) { + /* NB: scale factor of 2 was picked heuristically */ tap->txa_avgpps = ((tap->txa_avgpps << 2) - tap->txa_avgpps + tap->txa_pkts) >> 2; @@ -97,6 +108,7 @@ ieee80211_txampdu_update_pps(struct ieee80211_tx_ampdu *tap) static __inline void ieee80211_txampdu_count_packet(struct ieee80211_tx_ampdu *tap) { + /* XXX bound loop/do more crude estimate? */ while (ticks - tap->txa_lastsample >= hz) { ieee80211_txampdu_update_pps(tap); diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index b757ae6..0b95520 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -86,10 +86,21 @@ int ieee80211_input_mimo(struct ieee80211_node *ni, struct mbuf *m, struct ieee80211_rx_stats *rx) { + struct ieee80211_rx_stats rxs; + + if (rx) { + memcpy(&rxs, rx, sizeof(*rx)); + } else { + /* try to read from mbuf */ + bzero(&rxs, sizeof(rxs)); + ieee80211_get_rx_params(m, &rxs); + } + /* XXX should assert IEEE80211_R_NF and IEEE80211_R_RSSI are set */ - ieee80211_process_mimo(ni, rx); + ieee80211_process_mimo(ni, &rxs); + //return ieee80211_input(ni, m, rx->rssi, rx->nf); - return ni->ni_vap->iv_input(ni, m, rx, rx->rssi, rx->nf); + return ni->ni_vap->iv_input(ni, m, &rxs, rxs.rssi, rxs.nf); } int @@ -107,11 +118,20 @@ int ieee80211_input_mimo_all(struct ieee80211com *ic, struct mbuf *m, struct ieee80211_rx_stats *rx) { + struct ieee80211_rx_stats rxs; struct ieee80211vap *vap; int type = -1; m->m_flags |= M_BCAST; /* NB: mark for bpf tap'ing */ + if (rx) { + memcpy(&rxs, rx, sizeof(*rx)); + } else { + /* try to read from mbuf */ + bzero(&rxs, sizeof(rxs)); + ieee80211_get_rx_params(m, &rxs); + } + /* XXX locking */ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { struct ieee80211_node *ni; @@ -143,7 +163,7 @@ ieee80211_input_mimo_all(struct ieee80211com *ic, struct mbuf *m, m = NULL; } ni = ieee80211_ref_node(vap->iv_bss); - type = ieee80211_input_mimo(ni, mcopy, rx); + type = ieee80211_input_mimo(ni, mcopy, &rxs); ieee80211_free_node(ni); } if (m != NULL) /* no vaps, reclaim mbuf */ diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h index bb31136..e9b7393 100644 --- a/sys/net80211/ieee80211_node.h +++ b/sys/net80211/ieee80211_node.h @@ -219,6 +219,9 @@ struct ieee80211_node { struct ieee80211_tx_ampdu ni_tx_ampdu[WME_NUM_TID]; struct ieee80211_rx_ampdu ni_rx_ampdu[WME_NUM_TID]; + /* fast-frames state */ + struct mbuf * ni_tx_superg[WME_NUM_TID]; + /* others */ short ni_inact; /* inactivity mark count */ short ni_inact_reload;/* inactivity reload value */ diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index 4e061d8..27fe929 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -213,6 +213,22 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m, } } + /* + * XXX If we aren't doing AMPDU TX then we /could/ do + * fast-frames encapsulation, however right now this + * output logic doesn't handle that case. + * + * So we'll be limited to "fast-frames" xmit for non-11n STA + * and "no fast frames" xmit for 11n STAs. + * It'd be nice to eventually test fast-frames out by + * gracefully falling from failing A-MPDU transmission + * (driver says no, fail to negotiate it with peer) to + * using fast-frames. + * + * Note: we can actually put A-MSDU's inside an A-MPDU, + * so hopefully we can figure out how to make that particular + * combination work right. + */ #ifdef IEEE80211_SUPPORT_SUPERG else if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_FF)) { m = ieee80211_ff_check(ni, m); @@ -230,6 +246,11 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m, */ IEEE80211_TX_LOCK(ic); + /* + * XXX make the encap and transmit code a separate function + * so things like the FF (and later A-MSDU) path can just call + * it for flushed frames. + */ if (__predict_true((vap->iv_caps & IEEE80211_C_8023ENCAP) == 0)) { /* * Encapsulate the packet in prep for transmission. diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index 15188d8..52e92ba 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -107,6 +107,7 @@ static void update_mcast(void *, int); static void update_promisc(void *, int); static void update_channel(void *, int); static void update_chw(void *, int); +static void update_wme(void *, int); static void ieee80211_newstate_cb(void *, int); static int @@ -144,6 +145,7 @@ ieee80211_proto_attach(struct ieee80211com *ic) TASK_INIT(&ic->ic_chan_task, 0, update_channel, ic); TASK_INIT(&ic->ic_bmiss_task, 0, beacon_miss, ic); TASK_INIT(&ic->ic_chw_task, 0, update_chw, ic); + TASK_INIT(&ic->ic_wme_task, 0, update_wme, ic); ic->ic_wme.wme_hipri_switch_hysteresis = AGGRESSIVE_MODE_SWITCH_HYSTERESIS; @@ -1133,7 +1135,8 @@ ieee80211_wme_updateparams_locked(struct ieee80211vap *vap) ieee80211_beacon_notify(vap, IEEE80211_BEACON_WME); } - wme->wme_update(ic); + /* schedule the deferred WME update */ + ieee80211_runtask(ic, &ic->ic_wme_task); IEEE80211_DPRINTF(vap, IEEE80211_MSG_WME, "%s: WME params updated, cap_info 0x%x\n", __func__, @@ -1198,6 +1201,17 @@ update_chw(void *arg, int npending) ic->ic_update_chw(ic); } +static void +update_wme(void *arg, int npending) +{ + struct ieee80211com *ic = arg; + + /* + * XXX should we defer the WME configuration update until now? + */ + ic->ic_wme.wme_update(ic); +} + /* * Block until the parent is in a known state. This is * used after any operations that dispatch a task (e.g. @@ -1213,6 +1227,7 @@ ieee80211_waitfor_parent(struct ieee80211com *ic) ieee80211_draintask(ic, &ic->ic_chan_task); ieee80211_draintask(ic, &ic->ic_bmiss_task); ieee80211_draintask(ic, &ic->ic_chw_task); + ieee80211_draintask(ic, &ic->ic_wme_task); taskqueue_unblock(ic->ic_tq); } diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h index 165431b..273e759 100644 --- a/sys/net80211/ieee80211_proto.h +++ b/sys/net80211/ieee80211_proto.h @@ -62,32 +62,6 @@ void ieee80211_syncflag(struct ieee80211vap *, int flag); void ieee80211_syncflag_ht(struct ieee80211vap *, int flag); void ieee80211_syncflag_ext(struct ieee80211vap *, int flag); -#define IEEE80211_R_NF 0x0000001 /* global NF value valid */ -#define IEEE80211_R_RSSI 0x0000002 /* global RSSI value valid */ -#define IEEE80211_R_C_CHAIN 0x0000004 /* RX chain count valid */ -#define IEEE80211_R_C_NF 0x0000008 /* per-chain NF value valid */ -#define IEEE80211_R_C_RSSI 0x0000010 /* per-chain RSSI value valid */ -#define IEEE80211_R_C_EVM 0x0000020 /* per-chain EVM valid */ -#define IEEE80211_R_C_HT40 0x0000040 /* RX'ed packet is 40mhz, pilots 4,5 valid */ -#define IEEE80211_R_FREQ 0x0000080 /* Freq value populated, MHz */ -#define IEEE80211_R_IEEE 0x0000100 /* IEEE value populated */ -#define IEEE80211_R_BAND 0x0000200 /* Frequency band populated */ - -struct ieee80211_rx_stats { - uint32_t r_flags; /* IEEE80211_R_* flags */ - uint8_t c_chain; /* number of RX chains involved */ - int16_t c_nf_ctl[IEEE80211_MAX_CHAINS]; /* per-chain NF */ - int16_t c_nf_ext[IEEE80211_MAX_CHAINS]; /* per-chain NF */ - int16_t c_rssi_ctl[IEEE80211_MAX_CHAINS]; /* per-chain RSSI */ - int16_t c_rssi_ext[IEEE80211_MAX_CHAINS]; /* per-chain RSSI */ - uint8_t nf; /* global NF */ - uint8_t rssi; /* global RSSI */ - uint8_t evm[IEEE80211_MAX_CHAINS][IEEE80211_MAX_EVM_PILOTS]; - /* per-chain, per-pilot EVM values */ - uint16_t c_freq; - uint8_t c_ieee; -}; - #define ieee80211_input(ni, m, rssi, nf) \ ((ni)->ni_vap->iv_input(ni, m, NULL, rssi, nf)) int ieee80211_input_all(struct ieee80211com *, struct mbuf *, int, int); diff --git a/sys/net80211/ieee80211_superg.c b/sys/net80211/ieee80211_superg.c index 2e2bbd1..e91da01 100644 --- a/sys/net80211/ieee80211_superg.c +++ b/sys/net80211/ieee80211_superg.c @@ -530,7 +530,6 @@ ieee80211_ff_age(struct ieee80211com *ic, struct ieee80211_stageq *sq, { struct mbuf *m, *head; struct ieee80211_node *ni; - struct ieee80211_tx_ampdu *tap; #if 0 KASSERT(sq->head != NULL, ("stageq empty")); @@ -541,11 +540,10 @@ ieee80211_ff_age(struct ieee80211com *ic, struct ieee80211_stageq *sq, while ((m = sq->head) != NULL && M_AGE_GET(m) < quanta) { int tid = WME_AC_TO_TID(M_WME_GETAC(m)); - /* clear tap ref to frame */ + /* clear staging ref to frame */ ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; - tap = &ni->ni_tx_ampdu[tid]; - KASSERT(tap->txa_private == m, ("staging queue empty")); - tap->txa_private = NULL; + KASSERT(ni->ni_tx_superg[tid] == m, ("staging queue empty")); + ni->ni_tx_superg[tid] = NULL; sq->head = m->m_nextpkt; sq->depth--; @@ -658,7 +656,12 @@ ieee80211_ff_check(struct ieee80211_node *ni, struct mbuf *m) */ IEEE80211_LOCK(ic); tap = &ni->ni_tx_ampdu[WME_AC_TO_TID(pri)]; - mstaged = tap->txa_private; /* NB: we reuse AMPDU state */ + mstaged = ni->ni_tx_superg[WME_AC_TO_TID(pri)]; + /* XXX NOTE: reusing packet counter state from A-MPDU */ + /* + * XXX NOTE: this means we're double-counting; it should just + * be done in ieee80211_output.c once for both superg and A-MPDU. + */ ieee80211_txampdu_count_packet(tap); /* @@ -698,7 +701,7 @@ ieee80211_ff_check(struct ieee80211_node *ni, struct mbuf *m) "%s: txtime %u exceeds txop limit %u\n", __func__, txtime, limit); - tap->txa_private = NULL; + ni->ni_tx_superg[WME_AC_TO_TID(pri)] = NULL; if (mstaged != NULL) stageq_remove(ic, sq, mstaged); IEEE80211_UNLOCK(ic); @@ -721,7 +724,7 @@ ieee80211_ff_check(struct ieee80211_node *ni, struct mbuf *m) * hold their node reference. */ if (mstaged != NULL) { - tap->txa_private = NULL; + ni->ni_tx_superg[WME_AC_TO_TID(pri)] = NULL; stageq_remove(ic, sq, mstaged); IEEE80211_UNLOCK(ic); @@ -739,9 +742,10 @@ ieee80211_ff_check(struct ieee80211_node *ni, struct mbuf *m) mstaged->m_nextpkt = m; mstaged->m_flags |= M_FF; /* NB: mark for encap work */ } else { - KASSERT(tap->txa_private == NULL, - ("txa_private %p", tap->txa_private)); - tap->txa_private = m; + KASSERT(ni->ni_tx_superg[WME_AC_TO_TID(pri)]== NULL, + ("ni_tx_superg[]: %p", + ni->ni_tx_superg[WME_AC_TO_TID(pri)])); + ni->ni_tx_superg[WME_AC_TO_TID(pri)] = m; stageq_add(ic, sq, m); IEEE80211_UNLOCK(ic); @@ -769,7 +773,6 @@ ieee80211_ff_node_cleanup(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; struct ieee80211_superg *sg = ic->ic_superg; - struct ieee80211_tx_ampdu *tap; struct mbuf *m, *next_m, *head; int tid; @@ -777,11 +780,16 @@ ieee80211_ff_node_cleanup(struct ieee80211_node *ni) head = NULL; for (tid = 0; tid < WME_NUM_TID; tid++) { int ac = TID_TO_WME_AC(tid); - - tap = &ni->ni_tx_ampdu[tid]; - m = tap->txa_private; + /* + * XXX Initialise the packet counter. + * + * This may be double-work for 11n stations; + * but without it we never setup things. + */ + ieee80211_txampdu_init_pps(&ni->ni_tx_ampdu[tid]); + m = ni->ni_tx_superg[tid]; if (m != NULL) { - tap->txa_private = NULL; + ni->ni_tx_superg[tid] = NULL; stageq_remove(ic, &sg->ff_stageq[ac], m); m->m_nextpkt = head; head = m; diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index 8438d45..17f37d3 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -133,6 +133,7 @@ struct ieee80211com { struct task ic_chan_task; /* deferred channel change */ struct task ic_bmiss_task; /* deferred beacon miss hndlr */ struct task ic_chw_task; /* deferred HT CHW update */ + struct task ic_wme_task; /* deferred WME update */ counter_u64_t ic_ierrors; /* input errors */ counter_u64_t ic_oerrors; /* output errors */ diff --git a/sys/netinet/in.c b/sys/netinet/in.c index b582ba1..1441936 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1333,6 +1333,8 @@ in_lltable_dump_entry(struct lltable *llt, struct llentry *lle, arpc.rtm.rtm_flags |= (RTF_HOST | RTF_LLDATA); if (lle->la_flags & LLE_STATIC) arpc.rtm.rtm_flags |= RTF_STATIC; + if (lle->la_flags & LLE_IFADDR) + arpc.rtm.rtm_flags |= RTF_PINNED; arpc.rtm.rtm_index = ifp->if_index; error = SYSCTL_OUT(wr, &arpc, sizeof(arpc)); diff --git a/sys/netinet/ip_ipsec.c b/sys/netinet/ip_ipsec.c index 47f683d..546f802 100644 --- a/sys/netinet/ip_ipsec.c +++ b/sys/netinet/ip_ipsec.c @@ -199,9 +199,7 @@ ip_ipsec_output(struct mbuf **m, struct inpcb *inp, int *error) /* NB: callee frees mbuf */ *error = ipsec4_process_packet(*m, sp->req); - /* Release SP if an error occured */ - if (*error != 0) - KEY_FREESP(&sp); + KEY_FREESP(&sp); if (*error == EJUSTRETURN) { /* * We had a SP with a level of 'use' and no SA. We diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 83a7d31..5d2cac4 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -469,18 +469,6 @@ tcp_signature_verify_input(struct mbuf *m, int off0, int tlen, int optlen, } #endif -/* Neighbor Discovery, Neighbor Unreachability Detection Upper layer hint. */ -#ifdef INET6 -#define ND6_HINT(tp) \ -do { \ - if ((tp) && (tp)->t_inpcb && \ - ((tp)->t_inpcb->inp_vflag & INP_IPV6) != 0) \ - nd6_nud_hint(NULL, NULL, 0); \ -} while (0) -#else -#define ND6_HINT(tp) -#endif - /* * Indicate whether this ack should be delayed. We can delay the ack if * following conditions are met: @@ -1763,7 +1751,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, tp->snd_wl2 = th->th_ack; tp->t_dupacks = 0; m_freem(m); - ND6_HINT(tp); /* Some progress has been made. */ /* * If all outstanding data are acked, stop @@ -1822,7 +1809,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, tp->rcv_up = tp->rcv_nxt; TCPSTAT_INC(tcps_rcvpack); TCPSTAT_ADD(tcps_rcvbyte, tlen); - ND6_HINT(tp); /* Some progress has been made */ #ifdef TCPDEBUG if (so->so_options & SO_DEBUG) tcp_trace(TA_INPUT, ostate, tp, @@ -2924,7 +2910,6 @@ dodata: /* XXX */ thflags = th->th_flags & TH_FIN; TCPSTAT_INC(tcps_rcvpack); TCPSTAT_ADD(tcps_rcvbyte, tlen); - ND6_HINT(tp); SOCKBUF_LOCK(&so->so_rcv); if (so->so_rcv.sb_state & SBS_CANTRCVMORE) m_freem(m); diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index 3913ef3..4677154 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -327,7 +327,6 @@ present: tp->t_segqlen--; q = nq; } while (q && q->tqe_th->th_seq == tp->rcv_nxt); - ND6_HINT(tp); sorwakeup_locked(so); return (flags); } diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index fa278a8..a20bd81 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1541,11 +1541,6 @@ tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip) * in the route to the suggested new * value (if given) and then notify. */ - bzero(&inc, sizeof(inc)); - inc.inc_faddr = faddr; - inc.inc_fibnum = - inp->inp_inc.inc_fibnum; - mtu = ntohs(icp->icmp_nextmtu); /* * If no alternative MTU was @@ -1560,14 +1555,18 @@ tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip) mtu = V_tcp_minmss + sizeof(struct tcpiphdr); /* - * Only cache the MTU if it - * is smaller than the interface - * or route MTU. tcp_mtudisc() - * will do right thing by itself. + * Only process the offered MTU if it + * is smaller than the current one. */ - if (mtu <= tcp_maxmtu(&inc, NULL)) + if (mtu < tp->t_maxopd + + sizeof(struct tcpiphdr)) { + bzero(&inc, sizeof(inc)); + inc.inc_faddr = faddr; + inc.inc_fibnum = + inp->inp_inc.inc_fibnum; tcp_hc_updatemtu(&inc, mtu); - tcp_mtudisc(inp, mtu); + tcp_mtudisc(inp, mtu); + } } else inp = (*notify)(inp, inetctlerrmap[cmd]); diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index e0a6ed1..61fc419 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -83,18 +83,6 @@ struct tcptemp { #define tcp6cb tcpcb /* for KAME src sync over BSD*'s */ -/* Neighbor Discovery, Neighbor Unreachability Detection Upper layer hint. */ -#ifdef INET6 -#define ND6_HINT(tp) \ -do { \ - if ((tp) && (tp)->t_inpcb && \ - ((tp)->t_inpcb->inp_vflag & INP_IPV6) != 0) \ - nd6_nud_hint(NULL, NULL, 0); \ -} while (0) -#else -#define ND6_HINT(tp) -#endif - /* * Tcp control block, one per tcp; fields: * Organized for 16 byte cacheline efficiency. diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 9996dbf..af62ed1 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -2354,6 +2354,8 @@ in6_lltable_dump_entry(struct lltable *llt, struct llentry *lle, ndpc.rtm.rtm_flags |= (RTF_HOST | RTF_LLDATA); if (lle->la_flags & LLE_STATIC) ndpc.rtm.rtm_flags |= RTF_STATIC; + if (lle->la_flags & LLE_IFADDR) + ndpc.rtm.rtm_flags |= RTF_PINNED; ndpc.rtm.rtm_index = ifp->if_index; error = SYSCTL_OUT(wr, &ndpc, sizeof(ndpc)); diff --git a/sys/netinet6/ip6_ipsec.c b/sys/netinet6/ip6_ipsec.c index d7f08e9..a99f1db 100644 --- a/sys/netinet6/ip6_ipsec.c +++ b/sys/netinet6/ip6_ipsec.c @@ -200,9 +200,7 @@ ip6_ipsec_output(struct mbuf **m, struct inpcb *inp, int *error) /* NB: callee frees mbuf */ *error = ipsec6_process_packet(*m, sp->req); - /* Release SP if an error occured */ - if (*error != 0) - KEY_FREESP(&sp); + KEY_FREESP(&sp); if (*error == EJUSTRETURN) { /* * We had a SP with a level of 'use' and no SA. We diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index b842319..4098ffb 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1314,47 +1314,6 @@ nd6_free_redirect(const struct llentry *ln) } /* - * Upper-layer reachability hint for Neighbor Unreachability Detection. - * - * XXX cost-effective methods? - */ -void -nd6_nud_hint(struct rtentry *rt, struct in6_addr *dst6, int force) -{ - struct llentry *ln; - struct ifnet *ifp; - - if ((dst6 == NULL) || (rt == NULL)) - return; - - ifp = rt->rt_ifp; - IF_AFDATA_RLOCK(ifp); - ln = nd6_lookup(dst6, LLE_EXCLUSIVE, NULL); - IF_AFDATA_RUNLOCK(ifp); - if (ln == NULL) - return; - - if (ln->ln_state < ND6_LLINFO_REACHABLE) - goto done; - - /* - * if we get upper-layer reachability confirmation many times, - * it is possible we have false information. - */ - if (!force) { - ln->ln_byhint++; - if (ln->ln_byhint > V_nd6_maxnudhint) { - goto done; - } - } - - nd6_llinfo_setstate(ln, ND6_LLINFO_REACHABLE); -done: - LLE_WUNLOCK(ln); -} - - -/* * Rejuvenate this function for routing operations related * processing. */ diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h index 304b8fa..c5f0eea 100644 --- a/sys/netinet6/nd6.h +++ b/sys/netinet6/nd6.h @@ -412,7 +412,6 @@ void nd6_llinfo_settimer(struct llentry *, long); void nd6_llinfo_settimer_locked(struct llentry *, long); void nd6_timer(void *); void nd6_purge(struct ifnet *); -void nd6_nud_hint(struct rtentry *, struct in6_addr *, int); int nd6_resolve(struct ifnet *, int, struct mbuf *, const struct sockaddr *, u_char *, uint32_t *); int nd6_ioctl(u_long, caddr_t, struct ifnet *); diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 1bcd531..7c3c87c 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -768,10 +768,9 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) bcopy(lladdr, &ln->ll_addr, ifp->if_addrlen); ln->la_flags |= LLE_VALID; EVENTHANDLER_INVOKE(lle_event, ln, LLENTRY_RESOLVED); - if (is_solicited) { + if (is_solicited) nd6_llinfo_setstate(ln, ND6_LLINFO_REACHABLE); - ln->ln_byhint = 0; - } else + else nd6_llinfo_setstate(ln, ND6_LLINFO_STALE); if ((ln->ln_router = is_router) != 0) { /* @@ -844,10 +843,9 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) * If not solicited and the link-layer address was * changed, make it STALE. */ - if (is_solicited) { - ln->ln_byhint = 0; + if (is_solicited) nd6_llinfo_setstate(ln, ND6_LLINFO_REACHABLE); - } else { + else { if (lladdr != NULL && llchange) nd6_llinfo_setstate(ln, ND6_LLINFO_STALE); } diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c index a6611a7..f5cdf5a 100644 --- a/sys/netipsec/ipsec_output.c +++ b/sys/netipsec/ipsec_output.c @@ -166,10 +166,6 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr) * If this is a problem we'll need to introduce a queue * to set the packet on so we can unwind the stack before * doing further processing. - * - * If ipsec[46]_process_packet() will successfully queue - * the request, we need to take additional reference to SP, - * because xform callback will release reference. */ if (isr->next) { /* XXX-BZ currently only support same AF bundles. */ @@ -177,11 +173,7 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr) #ifdef INET case AF_INET: IPSECSTAT_INC(ips_out_bundlesa); - key_addref(isr->sp); - error = ipsec4_process_packet(m, isr->next); - if (error != 0) - KEY_FREESP(&isr->sp); - return (error); + return (ipsec4_process_packet(m, isr->next)); /* NOTREACHED */ #endif #ifdef notyet @@ -189,11 +181,7 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr) case AF_INET6: /* XXX */ IPSEC6STAT_INC(ips_out_bundlesa); - key_addref(isr->sp); - error = ipsec6_process_packet(m, isr->next); - if (error != 0) - KEY_FREESP(&isr->sp); - return (error); + return (ipsec6_process_packet(m, isr->next)); /* NOTREACHED */ #endif /* INET6 */ #endif diff --git a/sys/netipsec/xform_ah.c b/sys/netipsec/xform_ah.c index 350a735..0d39eeb 100644 --- a/sys/netipsec/xform_ah.c +++ b/sys/netipsec/xform_ah.c @@ -1068,6 +1068,7 @@ ah_output(struct mbuf *m, struct ipsecrequest *isr, struct mbuf **mp, crp->crp_opaque = (caddr_t) tc; /* These are passed as-is to the callback. */ + key_addref(isr->sp); tc->tc_isr = isr; KEY_ADDREFSA(sav); tc->tc_sav = sav; diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c index a48c038..9f645c0 100644 --- a/sys/netipsec/xform_esp.c +++ b/sys/netipsec/xform_esp.c @@ -874,6 +874,7 @@ esp_output(struct mbuf *m, struct ipsecrequest *isr, struct mbuf **mp, } /* Callback parameters */ + key_addref(isr->sp); tc->tc_isr = isr; KEY_ADDREFSA(sav); tc->tc_sav = sav; diff --git a/sys/netipsec/xform_ipcomp.c b/sys/netipsec/xform_ipcomp.c index ef460cd..122fc72 100644 --- a/sys/netipsec/xform_ipcomp.c +++ b/sys/netipsec/xform_ipcomp.c @@ -449,6 +449,7 @@ ipcomp_output(struct mbuf *m, struct ipsecrequest *isr, struct mbuf **mp, goto bad; } + key_addref(isr->sp); tc->tc_isr = isr; KEY_ADDREFSA(sav); tc->tc_sav = sav; diff --git a/sys/nfs/nfs_diskless.c b/sys/nfs/nfs_diskless.c index 3882007..864aae0 100644 --- a/sys/nfs/nfs_diskless.c +++ b/sys/nfs/nfs_diskless.c @@ -57,6 +57,8 @@ __FBSDID("$FreeBSD$"); #include <nfsclient/nfs.h> #include <nfs/nfsdiskless.h> +#define NFS_IFACE_TIMEOUT_SECS 10 /* Timeout for interface to appear. */ + static int inaddr_to_sockaddr(char *ev, struct sockaddr_in *sa); static int hwaddr_to_sockaddr(char *ev, struct sockaddr_dl *sa); static int decode_nfshandle(char *ev, u_char *fh, int maxfh); @@ -170,6 +172,7 @@ nfs_setup_diskless(void) char *cp; int cnt, fhlen, is_nfsv3; uint32_t len; + time_t timeout_at; if (nfs_diskless_valid != 0) return; @@ -214,6 +217,8 @@ nfs_setup_diskless(void) return; } ifa = NULL; + timeout_at = time_uptime + NFS_IFACE_TIMEOUT_SECS; +retry: CURVNET_SET(TD_TO_VNET(curthread)); IFNET_RLOCK(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { @@ -234,6 +239,10 @@ nfs_setup_diskless(void) } IFNET_RUNLOCK(); CURVNET_RESTORE(); + if (time_uptime < timeout_at) { + pause("nfssdl", hz / 5); + goto retry; + } printf("nfs_diskless: no interface\n"); return; /* no matching interface */ match_done: diff --git a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c index 64e691e..b3a920a 100644 --- a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c +++ b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c @@ -121,9 +121,6 @@ enum svc_rpc_gss_client_state { }; #define SVC_RPC_GSS_SEQWINDOW 128 -#ifndef RPCAUTH_UNIXGIDS -#define RPCAUTH_UNIXGIDS 16 -#endif struct svc_rpc_gss_clientid { unsigned long ci_hostid; @@ -150,7 +147,7 @@ struct svc_rpc_gss_client { int cl_rpcflavor; /* RPC pseudo sec flavor */ bool_t cl_done_callback; /* TRUE after call */ void *cl_cookie; /* user cookie from callback */ - gid_t cl_gid_storage[RPCAUTH_UNIXGIDS]; + gid_t cl_gid_storage[NGROUPS]; gss_OID cl_mech; /* mechanism */ gss_qop_t cl_qop; /* quality of protection */ uint32_t cl_seqlast; /* sequence window origin */ @@ -776,7 +773,7 @@ svc_rpc_gss_build_ucred(struct svc_rpc_gss_client *client, uc->gid = 65534; uc->gidlist = client->cl_gid_storage; - numgroups = RPCAUTH_UNIXGIDS; + numgroups = NGROUPS; maj_stat = gss_pname_to_unix_cred(&min_stat, name, client->cl_mech, &uc->uid, &uc->gid, &numgroups, &uc->gidlist[0]); if (GSS_ERROR(maj_stat)) diff --git a/sys/sys/buf.h b/sys/sys/buf.h index d5ce0e5..bdc457e 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -204,7 +204,7 @@ struct buf { #define B_PERSISTENT 0x00000100 /* Perm. ref'ed while EXT2FS mounted. */ #define B_DONE 0x00000200 /* I/O completed. */ #define B_EINTR 0x00000400 /* I/O was interrupted */ -#define B_00000800 0x00000800 /* Available flag. */ +#define B_NOREUSE 0x00000800 /* Contents not reused once released. */ #define B_00001000 0x00001000 /* Available flag. */ #define B_INVAL 0x00002000 /* Does not contain valid info. */ #define B_BARRIER 0x00004000 /* Write this and all preceeding first. */ @@ -229,7 +229,7 @@ struct buf { #define PRINT_BUF_FLAGS "\20\40remfree\37cluster\36vmio\35ram\34managed" \ "\33paging\32infreecnt\31nocopy\30b23\27relbuf\26dirty\25b20" \ "\24b19\23b18\22clusterok\21malloc\20nocache\17b14\16inval" \ - "\15b12\14b11\13eintr\12done\11persist\10delwri" \ + "\15b12\14noreuse\13eintr\12done\11persist\10delwri" \ "\7validsuspwrt\6cache\5deferred\4direct\3async\2needcommit\1age" /* diff --git a/sys/sys/file.h b/sys/sys/file.h index cb51c27..68d33e0 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -160,8 +160,6 @@ struct fadvise_info { int fa_advice; /* (f) FADV_* type. */ off_t fa_start; /* (f) Region start. */ off_t fa_end; /* (f) Region end. */ - off_t fa_prevstart; /* (f) Previous NOREUSE start. */ - off_t fa_prevend; /* (f) Previous NOREUSE end. */ }; struct file { diff --git a/sys/sys/sdt.h b/sys/sys/sdt.h index ca820f6..5dd0b67 100644 --- a/sys/sys/sdt.h +++ b/sys/sys/sdt.h @@ -398,7 +398,7 @@ struct sdt_probe { struct sdt_provider *prov; /* Ptr to the provider structure. */ TAILQ_ENTRY(sdt_probe) probe_entry; /* SDT probe list entry. */ - TAILQ_HEAD(argtype_list_head, sdt_argtype) argtype_list; + TAILQ_HEAD(, sdt_argtype) argtype_list; const char *mod; const char *func; const char *name; diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 592112a..6c68802 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -46,6 +46,7 @@ #include <sys/stdint.h> /* for people using printf mainly */ extern int cold; /* nonzero if we are doing a cold boot */ +extern int suspend_blocked; /* block suspend due to pending shutdown */ extern int rebooting; /* kern_reboot() has been called. */ extern const char *panicstr; /* panic message */ extern char version[]; /* system version */ diff --git a/sys/sys/types.h b/sys/sys/types.h index 4a66a4e..4dfd8ef 100644 --- a/sys/sys/types.h +++ b/sys/sys/types.h @@ -290,9 +290,6 @@ typedef _Bool bool; * The following are all things that really shouldn't exist in this header, * since its purpose is to provide typedefs, not miscellaneous doodads. */ -#if __BSD_VISIBLE - -#include <sys/select.h> #ifdef __POPCNT__ #define __bitcount64(x) __builtin_popcountll((__uint64_t)(x)) @@ -356,6 +353,10 @@ __bitcount64(__uint64_t _x) #define __bitcount(x) __bitcount32((unsigned int)(x)) #endif +#if __BSD_VISIBLE + +#include <sys/select.h> + /* * minor() gives a cookie instead of an index since we don't want to * change the meanings of bits 0-15 or waste time and space shifting diff --git a/sys/tools/vnode_if.awk b/sys/tools/vnode_if.awk index 7d106e7..5bb3971 100644 --- a/sys/tools/vnode_if.awk +++ b/sys/tools/vnode_if.awk @@ -359,7 +359,7 @@ while ((getline < srcfile) > 0) { printc("\t vop->"name" == NULL && vop->vop_bypass == NULL)") printc("\t\tvop = vop->vop_default;") printc("\tVNASSERT(vop != NULL, a->a_" args[0]", (\"No "name"(%p, %p)\", a->a_" args[0]", a));") - printc("\tSDT_PROBE(vfs, vop, " name ", entry, a->a_" args[0] ", a, 0, 0, 0);\n"); + printc("\tSDT_PROBE2(vfs, vop, " name ", entry, a->a_" args[0] ", a);\n"); for (i = 0; i < numargs; ++i) add_debug_code(name, args[i], "Entry", "\t"); printc("\tKTR_START" ctrstr); @@ -370,7 +370,7 @@ while ((getline < srcfile) > 0) { printc("\telse") printc("\t\trc = vop->vop_bypass(&a->a_gen);") printc("\tVFS_EPILOGUE(a->a_" args[0]"->v_mount);") - printc("\tSDT_PROBE(vfs, vop, " name ", return, a->a_" args[0] ", a, rc, 0, 0);\n"); + printc("\tSDT_PROBE3(vfs, vop, " name ", return, a->a_" args[0] ", a, rc);\n"); printc("\tif (rc == 0) {"); for (i = 0; i < numargs; ++i) add_debug_code(name, args[i], "OK", "\t\t"); diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index 2a4a2cd..8169256 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -1153,7 +1153,7 @@ noobj_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *flags, int wait) * exit. */ TAILQ_FOREACH_SAFE(p, &alloctail, listq, p_next) { - vm_page_unwire(p, PQ_INACTIVE); + vm_page_unwire(p, PQ_NONE); vm_page_free(p); } return (NULL); diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index fd16bf2..f0aacf1 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -159,11 +159,10 @@ kmem_alloc_attr(vmem_t *vmem, vm_size_t size, int flags, vm_paddr_t low, vm_paddr_t high, vm_memattr_t memattr) { vm_object_t object = vmem == kmem_arena ? kmem_object : kernel_object; - vm_offset_t addr; + vm_offset_t addr, i; vm_ooffset_t offset; vm_page_t m; int pflags, tries; - int i; size = round_page(size); if (vmem_alloc(vmem, size, M_BESTFIT | flags, &addr)) @@ -184,18 +183,7 @@ retry: tries++; goto retry; } - /* - * Unmap and free the pages. - */ - if (i != 0) - pmap_remove(kernel_pmap, addr, addr + i); - while (i != 0) { - i -= PAGE_SIZE; - m = vm_page_lookup(object, - OFF_TO_IDX(offset + i)); - vm_page_unwire(m, PQ_INACTIVE); - vm_page_free(m); - } + kmem_unback(object, addr, i); vmem_free(vmem, addr, size); return (0); } @@ -353,25 +341,13 @@ retry: * aren't on any queues. */ if (m == NULL) { + VM_OBJECT_WUNLOCK(object); if ((flags & M_NOWAIT) == 0) { - VM_OBJECT_WUNLOCK(object); VM_WAIT; VM_OBJECT_WLOCK(object); goto retry; } - /* - * Unmap and free the pages. - */ - if (i != 0) - pmap_remove(kernel_pmap, addr, addr + i); - while (i != 0) { - i -= PAGE_SIZE; - m = vm_page_lookup(object, - OFF_TO_IDX(offset + i)); - vm_page_unwire(m, PQ_INACTIVE); - vm_page_free(m); - } - VM_OBJECT_WUNLOCK(object); + kmem_unback(object, addr, i); return (KERN_NO_SPACE); } if (flags & M_ZERO && (m->flags & PG_ZERO) == 0) @@ -387,6 +363,15 @@ retry: return (KERN_SUCCESS); } +/* + * kmem_unback: + * + * Unmap and free the physical pages underlying the specified virtual + * address range. + * + * A physical page must exist within the specified object at each index + * that is being unmapped. + */ void kmem_unback(vm_object_t object, vm_offset_t addr, vm_size_t size) { diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index a4aac95..0a3c2ef 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -1963,15 +1963,15 @@ skipmemq: } /* - * vm_object_page_cache: + * vm_object_page_noreuse: * - * For the given object, attempt to move the specified clean - * pages to the cache queue. If a page is wired for any reason, - * then it will not be changed. Pages are specified by the given - * range ["start", "end"). As a special case, if "end" is zero, - * then the range extends from "start" to the end of the object. - * Any mappings to the specified pages are removed before the - * pages are moved to the cache queue. + * For the given object, attempt to move the specified pages to + * the head of the inactive queue. This bypasses regular LRU + * operation and allows the pages to be reused quickly under memory + * pressure. If a page is wired for any reason, then it will not + * be queued. Pages are specified by the range ["start", "end"). + * As a special case, if "end" is zero, then the range extends from + * "start" to the end of the object. * * This operation should only be performed on objects that * contain non-fictitious, managed pages. @@ -1979,14 +1979,14 @@ skipmemq: * The object must be locked. */ void -vm_object_page_cache(vm_object_t object, vm_pindex_t start, vm_pindex_t end) +vm_object_page_noreuse(vm_object_t object, vm_pindex_t start, vm_pindex_t end) { struct mtx *mtx, *new_mtx; vm_page_t p, next; VM_OBJECT_ASSERT_WLOCKED(object); KASSERT((object->flags & (OBJ_FICTITIOUS | OBJ_UNMANAGED)) == 0, - ("vm_object_page_cache: illegal object %p", object)); + ("vm_object_page_noreuse: illegal object %p", object)); if (object->resident_page_count == 0) return; p = vm_page_find_least(object, start); @@ -2009,7 +2009,7 @@ vm_object_page_cache(vm_object_t object, vm_pindex_t start, vm_pindex_t end) mtx = new_mtx; mtx_lock(mtx); } - vm_page_try_to_cache(p); + vm_page_deactivate_noreuse(p); } if (mtx != NULL) mtx_unlock(mtx); diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h index 7e433ae..894a8d5 100644 --- a/sys/vm/vm_object.h +++ b/sys/vm/vm_object.h @@ -304,10 +304,10 @@ void vm_object_terminate (vm_object_t); void vm_object_set_writeable_dirty (vm_object_t); void vm_object_init (void); void vm_object_madvise(vm_object_t, vm_pindex_t, vm_pindex_t, int); -void vm_object_page_cache(vm_object_t object, vm_pindex_t start, - vm_pindex_t end); boolean_t vm_object_page_clean(vm_object_t object, vm_ooffset_t start, vm_ooffset_t end, int flags); +void vm_object_page_noreuse(vm_object_t object, vm_pindex_t start, + vm_pindex_t end); void vm_object_page_remove(vm_object_t object, vm_pindex_t start, vm_pindex_t end, int options); boolean_t vm_object_populate(vm_object_t, vm_pindex_t, vm_pindex_t); diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 2aaddfb..a3a9a10 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -2589,6 +2589,19 @@ vm_page_deactivate(vm_page_t m) } /* + * Move the specified page to the inactive queue with the expectation + * that it is unlikely to be reused. + * + * The page must be locked. + */ +void +vm_page_deactivate_noreuse(vm_page_t m) +{ + + _vm_page_deactivate(m, 1); +} + +/* * vm_page_try_to_cache: * * Returns 0 on failure, 1 on success @@ -2740,8 +2753,7 @@ vm_page_cache(vm_page_t m) /* * vm_page_advise * - * Deactivate or do nothing, as appropriate. This routine is used - * by madvise() and vop_stdadvise(). + * Deactivate or do nothing, as appropriate. * * The object and page must be locked. */ diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h index fd7d3f4..dedd6ac 100644 --- a/sys/vm/vm_page.h +++ b/sys/vm/vm_page.h @@ -451,6 +451,7 @@ void vm_page_cache_transfer(vm_object_t, vm_pindex_t, vm_object_t); int vm_page_try_to_cache (vm_page_t); int vm_page_try_to_free (vm_page_t); void vm_page_deactivate (vm_page_t); +void vm_page_deactivate_noreuse(vm_page_t); void vm_page_dequeue(vm_page_t m); void vm_page_dequeue_locked(vm_page_t m); vm_page_t vm_page_find_least(vm_object_t, vm_pindex_t); diff --git a/targets/pseudo/bootstrap-tools/Makefile b/targets/pseudo/bootstrap-tools/Makefile index a267e95..1b0ebde 100644 --- a/targets/pseudo/bootstrap-tools/Makefile +++ b/targets/pseudo/bootstrap-tools/Makefile @@ -31,17 +31,15 @@ OSRELDATE?= 0 .endif # need to keep this in sync with src/Makefile.inc1 -BSARGS= \ - DESTDIR= \ - BOOTSTRAPPING=${OSRELDATE} \ - SSP_CFLAGS= \ - MK_HTML=no NO_LINT=yes MK_MAN=no \ - -DNO_PIC MK_PROFILE=no -DNO_SHARED \ - -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \ - MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \ - MK_LLDB=no MK_TESTS=no \ - MK_INCLUDES=yes - +BSARGS= DESTDIR= \ + BOOTSTRAPPING=${OSRELDATE} \ + SSP_CFLAGS= \ + MK_HTML=no NO_LINT=yes MK_MAN=no \ + -DNO_PIC MK_PROFILE=no -DNO_SHARED \ + -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \ + MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \ + MK_LLDB=no MK_TESTS=no \ + MK_INCLUDES=yes legacy: .MAKE .META mkdir -p ${LEGACY_TOOLS} diff --git a/targets/pseudo/bootstrap-tools/Makefile.depend.host b/targets/pseudo/bootstrap-tools/Makefile.depend.host index fc65dd3..aa5205f 100644 --- a/targets/pseudo/bootstrap-tools/Makefile.depend.host +++ b/targets/pseudo/bootstrap-tools/Makefile.depend.host @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = diff --git a/targets/pseudo/clang/Makefile.depend b/targets/pseudo/clang/Makefile.depend index 4dbc0af..6045f55 100644 --- a/targets/pseudo/clang/Makefile.depend +++ b/targets/pseudo/clang/Makefile.depend @@ -6,8 +6,6 @@ .include <src.opts.mk> .endif -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ lib/clang/include \ share/doc/llvm/clang \ diff --git a/targets/pseudo/gcc/Makefile.depend b/targets/pseudo/gcc/Makefile.depend index 8136da6..795a752 100644 --- a/targets/pseudo/gcc/Makefile.depend +++ b/targets/pseudo/gcc/Makefile.depend @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/usr.bin/cc/cc_tools \ gnu/usr.bin/cc/libiberty \ diff --git a/targets/pseudo/hosttools/Makefile.depend b/targets/pseudo/hosttools/Makefile.depend index 83c8848..2b46cf0 100644 --- a/targets/pseudo/hosttools/Makefile.depend +++ b/targets/pseudo/hosttools/Makefile.depend @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ lib/clang/include.host \ lib/libc++.host \ diff --git a/targets/pseudo/kernel/Makefile.depend b/targets/pseudo/kernel/Makefile.depend index 7bcff69..3ab3962 100644 --- a/targets/pseudo/kernel/Makefile.depend +++ b/targets/pseudo/kernel/Makefile.depend @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/targets/pseudo/the-lot/Makefile.depend b/targets/pseudo/the-lot/Makefile.depend index d54c59c..3e10558 100644 --- a/targets/pseudo/the-lot/Makefile.depend +++ b/targets/pseudo/the-lot/Makefile.depend @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ targets/pseudo/kernel \ targets/pseudo/toolchain \ diff --git a/targets/pseudo/toolchain/Makefile.depend b/targets/pseudo/toolchain/Makefile.depend index 0b35c07..827e3f9 100644 --- a/targets/pseudo/toolchain/Makefile.depend +++ b/targets/pseudo/toolchain/Makefile.depend @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - .if !defined(MK_CLANG) .include "${SRCTOP}/share/mk/src.opts.mk" .endif diff --git a/targets/pseudo/universe/Makefile.depend b/targets/pseudo/universe/Makefile.depend index b55179d..a7d141f 100644 --- a/targets/pseudo/universe/Makefile.depend +++ b/targets/pseudo/universe/Makefile.depend @@ -4,8 +4,6 @@ # this is not normally needed, but we are not normal .if ${.MAKE.LEVEL} == 0 -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - # our role here is to build all the host tools etc. DIRDEPS = \ targets/pseudo/hosttools.host \ diff --git a/targets/pseudo/userland/Makefile.depend b/targets/pseudo/userland/Makefile.depend index 5cedf97..0738c81 100644 --- a/targets/pseudo/userland/Makefile.depend +++ b/targets/pseudo/userland/Makefile.depend @@ -6,8 +6,6 @@ .include <src.opts.mk> .endif -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS= .if ${MK_MANDOCDB} == "no" DIRDEPS+= usr.bin/makewhatis diff --git a/targets/pseudo/userland/cddl/Makefile.depend b/targets/pseudo/userland/cddl/Makefile.depend index a4cbff7..00524e9 100644 --- a/targets/pseudo/userland/cddl/Makefile.depend +++ b/targets/pseudo/userland/cddl/Makefile.depend @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - .if !defined(MK_CTF) .include "${SRCTOP}/share/mk/src.opts.mk" .endif @@ -14,7 +12,6 @@ DIRDEPS = \ cddl/lib/libnvpair \ cddl/lib/libumem \ cddl/lib/libuutil \ - cddl/usr.bin/sgsmsg \ DIRDEPS.CTF = \ diff --git a/targets/pseudo/userland/games/Makefile.depend b/targets/pseudo/userland/games/Makefile.depend index 7f5cfa2..a9ac340 100644 --- a/targets/pseudo/userland/games/Makefile.depend +++ b/targets/pseudo/userland/games/Makefile.depend @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ games/bcd \ games/caesar \ diff --git a/targets/pseudo/userland/gnu/Makefile.depend b/targets/pseudo/userland/gnu/Makefile.depend index fb5f711..3a90fb0 100644 --- a/targets/pseudo/userland/gnu/Makefile.depend +++ b/targets/pseudo/userland/gnu/Makefile.depend @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/csu \ gnu/lib/libdialog \ diff --git a/targets/pseudo/userland/include/Makefile.depend b/targets/pseudo/userland/include/Makefile.depend index e8e6e09..73999ca 100644 --- a/targets/pseudo/userland/include/Makefile.depend +++ b/targets/pseudo/userland/include/Makefile.depend @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include/arpa \ include/gssapi \ diff --git a/targets/pseudo/userland/kerberos5/Makefile.depend b/targets/pseudo/userland/kerberos5/Makefile.depend index fe1a488..837087d 100644 --- a/targets/pseudo/userland/kerberos5/Makefile.depend +++ b/targets/pseudo/userland/kerberos5/Makefile.depend @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ kerberos5/doc \ kerberos5/lib/libasn1 \ diff --git a/targets/pseudo/userland/lib/Makefile.depend b/targets/pseudo/userland/lib/Makefile.depend index 027f820..9cfbffa 100644 --- a/targets/pseudo/userland/lib/Makefile.depend +++ b/targets/pseudo/userland/lib/Makefile.depend @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ lib/${CSU_DIR} \ lib/atf/libatf-c \ diff --git a/targets/pseudo/userland/libexec/Makefile.depend b/targets/pseudo/userland/libexec/Makefile.depend index a7c9ee4..f870b6a 100644 --- a/targets/pseudo/userland/libexec/Makefile.depend +++ b/targets/pseudo/userland/libexec/Makefile.depend @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ libexec/atf/atf-check \ libexec/atf/atf-sh \ diff --git a/targets/pseudo/userland/misc/Makefile.depend b/targets/pseudo/userland/misc/Makefile.depend index efc3bb7..0c98392 100644 --- a/targets/pseudo/userland/misc/Makefile.depend +++ b/targets/pseudo/userland/misc/Makefile.depend @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ rescue/librescue \ rescue/rescue \ diff --git a/targets/pseudo/userland/secure/Makefile.depend b/targets/pseudo/userland/secure/Makefile.depend index ab046f0..22532a9 100644 --- a/targets/pseudo/userland/secure/Makefile.depend +++ b/targets/pseudo/userland/secure/Makefile.depend @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ secure/lib/libcrypto \ secure/lib/libcrypto/engines/lib4758cca \ diff --git a/targets/pseudo/userland/share/Makefile.depend b/targets/pseudo/userland/share/Makefile.depend index 058dfd4..1417d1c 100644 --- a/targets/pseudo/userland/share/Makefile.depend +++ b/targets/pseudo/userland/share/Makefile.depend @@ -2,8 +2,6 @@ # This file is not autogenerated - take care! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ share/atf \ share/colldef \ diff --git a/tools/build/Makefile.depend b/tools/build/Makefile.depend index d14a02b..f80275d 100644 --- a/tools/build/Makefile.depend +++ b/tools/build/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index bfcec98..daa5cd9 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -189,6 +189,188 @@ OLD_FILES+=usr/bin/ld OLD_FILES+=usr/bin/objcopy .endif OLD_FILES+=usr/bin/objdump +OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.x +OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xbn +OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xc +OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xd +OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xdc +OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xdw +OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xn +OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xr +OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xs +OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xsc +OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xsw +OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xu +OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xw +OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.x +OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xbn +OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xc +OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xd +OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xdc +OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xdw +OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xn +OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xr +OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xs +OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xsc +OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xsw +OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xu +OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xw +OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.x +OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xbn +OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xc +OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xd +OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xdc +OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xdw +OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xn +OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xr +OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xs +OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xsc +OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xsw +OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xu +OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xw +OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.x +OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xbn +OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xc +OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xd +OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xdc +OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xdw +OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xn +OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xr +OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xs +OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xsc +OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xsw +OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xu +OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xw +OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.x +OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xbn +OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xc +OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xd +OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xdc +OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xdw +OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xn +OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xr +OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xs +OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xsc +OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xsw +OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xu +OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xw +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.x +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xbn +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xc +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xd +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xdc +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xdw +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xn +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xr +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xs +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xsc +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xsw +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xu +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xw +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.x +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xbn +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xc +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xd +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xdc +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xdw +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xn +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xr +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xs +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xsc +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xsw +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xu +OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xw +OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.x +OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xbn +OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xc +OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xd +OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xdc +OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xdw +OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xn +OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xr +OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xs +OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xsc +OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xsw +OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xu +OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xw +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.x +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xbn +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xc +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xd +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xdc +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xdw +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xn +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xr +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xs +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xsc +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xsw +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xu +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xw +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.x +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xbn +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xc +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xd +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xdc +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xdw +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xn +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xr +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xs +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xsc +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xsw +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xu +OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xw +OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.x +OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xbn +OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xc +OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xd +OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xdc +OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xdw +OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xn +OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xr +OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xs +OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xsc +OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xsw +OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xu +OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xw +OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.x +OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xbn +OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xc +OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xd +OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xdc +OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xdw +OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xn +OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xr +OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xs +OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xsc +OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xsw +OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xu +OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xw +OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.x +OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xbn +OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xc +OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xd +OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xdc +OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xdw +OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xn +OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xr +OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xs +OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xsc +OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xsw +OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xu +OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xw +OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.x +OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xbn +OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xc +OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xd +OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xdc +OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xdw +OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xn +OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xr +OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xs +OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xsc +OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xsw +OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xu +OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xw OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.x OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xbn OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xc @@ -728,7 +910,6 @@ OLD_LIBS+=lib/libuutil.so.2 OLD_FILES+=usr/bin/ctfconvert OLD_FILES+=usr/bin/ctfdump OLD_FILES+=usr/bin/ctfmerge -OLD_FILES+=usr/bin/sgsmsg OLD_FILES+=usr/lib/dtrace/drti.o OLD_FILES+=usr/lib/dtrace/errno.d OLD_FILES+=usr/lib/dtrace/io.d diff --git a/tools/regression/include/stdatomic/Makefile.depend b/tools/regression/include/stdatomic/Makefile.depend index abf239e..cda9eb2 100644 --- a/tools/regression/include/stdatomic/Makefile.depend +++ b/tools/regression/include/stdatomic/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/tools/tools/ath/ath_ee_9300_print/Makefile.depend b/tools/tools/ath/ath_ee_9300_print/Makefile.depend index c9ce330..f4dfeaf 100644 --- a/tools/tools/ath/ath_ee_9300_print/Makefile.depend +++ b/tools/tools/ath/ath_ee_9300_print/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/tools/tools/drm/radeon/mkregtable/Makefile.depend b/tools/tools/drm/radeon/mkregtable/Makefile.depend index abf239e..cda9eb2 100644 --- a/tools/tools/drm/radeon/mkregtable/Makefile.depend +++ b/tools/tools/drm/radeon/mkregtable/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/tools/tools/makeroot/Makefile.depend b/tools/tools/makeroot/Makefile.depend index d14a02b..f80275d 100644 --- a/tools/tools/makeroot/Makefile.depend +++ b/tools/tools/makeroot/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ diff --git a/tools/tools/usbtest/Makefile.depend b/tools/tools/usbtest/Makefile.depend index e33ad82..f1aeab0 100644 --- a/tools/tools/usbtest/Makefile.depend +++ b/tools/tools/usbtest/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.bin/lex/Makefile.depend b/usr.bin/lex/Makefile.depend index 738376b..b5b8043 100644 --- a/usr.bin/lex/Makefile.depend +++ b/usr.bin/lex/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.bin/mkcsmapper_static/Makefile.depend b/usr.bin/mkcsmapper_static/Makefile.depend index 911a48d..ffee33f 100644 --- a/usr.bin/mkcsmapper_static/Makefile.depend +++ b/usr.bin/mkcsmapper_static/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/arpa \ diff --git a/usr.bin/pamtest/Makefile.depend b/usr.bin/pamtest/Makefile.depend index 80d4de2..916227d 100644 --- a/usr.bin/pamtest/Makefile.depend +++ b/usr.bin/pamtest/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.bin/setchannel/Makefile.depend b/usr.bin/setchannel/Makefile.depend index f52ca95..79eb58b 100644 --- a/usr.bin/setchannel/Makefile.depend +++ b/usr.bin/setchannel/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.bin/smbutil/Makefile.depend b/usr.bin/smbutil/Makefile.depend index a1b4494..989cc64 100644 --- a/usr.bin/smbutil/Makefile.depend +++ b/usr.bin/smbutil/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.bin/svn/Makefile b/usr.bin/svn/Makefile index 4442117..1d2ae21 100644 --- a/usr.bin/svn/Makefile +++ b/usr.bin/svn/Makefile @@ -1,5 +1,8 @@ # $FreeBSD$ -SUBDIR = lib svn svnadmin svndumpfilter svnlook svnserve svnsync svnversion svnmucc svnrdump +SUBDIR = lib .WAIT \ + svn svnadmin svndumpfilter svnlook svnserve svnsync svnversion \ + svnmucc svnrdump +SUBDIR_PARALLEL= .include <bsd.subdir.mk> diff --git a/usr.bin/svn/lib/libapr/Makefile.depend b/usr.bin/svn/lib/libapr/Makefile.depend index 402745d..bbe68e0 100644 --- a/usr.bin/svn/lib/libapr/Makefile.depend +++ b/usr.bin/svn/lib/libapr/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/arpa \ diff --git a/usr.bin/svn/lib/libapr_util/Makefile.depend b/usr.bin/svn/lib/libapr_util/Makefile.depend index 9caf2d1..ba7abb3 100644 --- a/usr.bin/svn/lib/libapr_util/Makefile.depend +++ b/usr.bin/svn/lib/libapr_util/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/usr.bin/svn/lib/libserf/Makefile.depend b/usr.bin/svn/lib/libserf/Makefile.depend index b8e3639..044c8f7 100644 --- a/usr.bin/svn/lib/libserf/Makefile.depend +++ b/usr.bin/svn/lib/libserf/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/usr.bin/svn/lib/libsvn_client/Makefile.depend b/usr.bin/svn/lib/libsvn_client/Makefile.depend index ccd19e5..18be76b 100644 --- a/usr.bin/svn/lib/libsvn_client/Makefile.depend +++ b/usr.bin/svn/lib/libsvn_client/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/usr.bin/svn/lib/libsvn_delta/Makefile.depend b/usr.bin/svn/lib/libsvn_delta/Makefile.depend index 35add0c..b38b34e 100644 --- a/usr.bin/svn/lib/libsvn_delta/Makefile.depend +++ b/usr.bin/svn/lib/libsvn_delta/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/usr.bin/svn/lib/libsvn_diff/Makefile.depend b/usr.bin/svn/lib/libsvn_diff/Makefile.depend index ccd19e5..18be76b 100644 --- a/usr.bin/svn/lib/libsvn_diff/Makefile.depend +++ b/usr.bin/svn/lib/libsvn_diff/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/usr.bin/svn/lib/libsvn_fs/Makefile.depend b/usr.bin/svn/lib/libsvn_fs/Makefile.depend index ccd19e5..18be76b 100644 --- a/usr.bin/svn/lib/libsvn_fs/Makefile.depend +++ b/usr.bin/svn/lib/libsvn_fs/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/usr.bin/svn/lib/libsvn_fs_fs/Makefile.depend b/usr.bin/svn/lib/libsvn_fs_fs/Makefile.depend index ccd19e5..18be76b 100644 --- a/usr.bin/svn/lib/libsvn_fs_fs/Makefile.depend +++ b/usr.bin/svn/lib/libsvn_fs_fs/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/usr.bin/svn/lib/libsvn_fs_util/Makefile.depend b/usr.bin/svn/lib/libsvn_fs_util/Makefile.depend index ccd19e5..18be76b 100644 --- a/usr.bin/svn/lib/libsvn_fs_util/Makefile.depend +++ b/usr.bin/svn/lib/libsvn_fs_util/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/usr.bin/svn/lib/libsvn_ra/Makefile.depend b/usr.bin/svn/lib/libsvn_ra/Makefile.depend index ccd19e5..18be76b 100644 --- a/usr.bin/svn/lib/libsvn_ra/Makefile.depend +++ b/usr.bin/svn/lib/libsvn_ra/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/usr.bin/svn/lib/libsvn_ra_local/Makefile.depend b/usr.bin/svn/lib/libsvn_ra_local/Makefile.depend index ccd19e5..18be76b 100644 --- a/usr.bin/svn/lib/libsvn_ra_local/Makefile.depend +++ b/usr.bin/svn/lib/libsvn_ra_local/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/usr.bin/svn/lib/libsvn_ra_serf/Makefile.depend b/usr.bin/svn/lib/libsvn_ra_serf/Makefile.depend index 9caf2d1..ba7abb3 100644 --- a/usr.bin/svn/lib/libsvn_ra_serf/Makefile.depend +++ b/usr.bin/svn/lib/libsvn_ra_serf/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/usr.bin/svn/lib/libsvn_ra_svn/Makefile.depend b/usr.bin/svn/lib/libsvn_ra_svn/Makefile.depend index ccd19e5..18be76b 100644 --- a/usr.bin/svn/lib/libsvn_ra_svn/Makefile.depend +++ b/usr.bin/svn/lib/libsvn_ra_svn/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/usr.bin/svn/lib/libsvn_repos/Makefile.depend b/usr.bin/svn/lib/libsvn_repos/Makefile.depend index ccd19e5..18be76b 100644 --- a/usr.bin/svn/lib/libsvn_repos/Makefile.depend +++ b/usr.bin/svn/lib/libsvn_repos/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/usr.bin/svn/lib/libsvn_subr/Makefile.depend b/usr.bin/svn/lib/libsvn_subr/Makefile.depend index 365567e..10c0748 100644 --- a/usr.bin/svn/lib/libsvn_subr/Makefile.depend +++ b/usr.bin/svn/lib/libsvn_subr/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/usr.bin/svn/lib/libsvn_wc/Makefile.depend b/usr.bin/svn/lib/libsvn_wc/Makefile.depend index ccd19e5..18be76b 100644 --- a/usr.bin/svn/lib/libsvn_wc/Makefile.depend +++ b/usr.bin/svn/lib/libsvn_wc/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ include \ include/xlocale \ diff --git a/usr.bin/svn/svn/Makefile.depend b/usr.bin/svn/svn/Makefile.depend index ccbe233..da1efbd 100644 --- a/usr.bin/svn/svn/Makefile.depend +++ b/usr.bin/svn/svn/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.bin/svn/svnadmin/Makefile.depend b/usr.bin/svn/svnadmin/Makefile.depend index 6a83703..ae47f0b 100644 --- a/usr.bin/svn/svnadmin/Makefile.depend +++ b/usr.bin/svn/svnadmin/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.bin/svn/svndumpfilter/Makefile.depend b/usr.bin/svn/svndumpfilter/Makefile.depend index 6a83703..ae47f0b 100644 --- a/usr.bin/svn/svndumpfilter/Makefile.depend +++ b/usr.bin/svn/svndumpfilter/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.bin/svn/svnlook/Makefile.depend b/usr.bin/svn/svnlook/Makefile.depend index 327a76e..d0f5866 100644 --- a/usr.bin/svn/svnlook/Makefile.depend +++ b/usr.bin/svn/svnlook/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.bin/svn/svnmucc/Makefile.depend b/usr.bin/svn/svnmucc/Makefile.depend index eb9e68b..798e4f3 100644 --- a/usr.bin/svn/svnmucc/Makefile.depend +++ b/usr.bin/svn/svnmucc/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.bin/svn/svnrdump/Makefile.depend b/usr.bin/svn/svnrdump/Makefile.depend index ccbe233..da1efbd 100644 --- a/usr.bin/svn/svnrdump/Makefile.depend +++ b/usr.bin/svn/svnrdump/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.bin/svn/svnserve/Makefile.depend b/usr.bin/svn/svnserve/Makefile.depend index 978f241..550cd65 100644 --- a/usr.bin/svn/svnserve/Makefile.depend +++ b/usr.bin/svn/svnserve/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.bin/svn/svnsync/Makefile.depend b/usr.bin/svn/svnsync/Makefile.depend index 978f241..550cd65 100644 --- a/usr.bin/svn/svnsync/Makefile.depend +++ b/usr.bin/svn/svnsync/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.bin/svn/svnversion/Makefile.depend b/usr.bin/svn/svnversion/Makefile.depend index ca6c01c..12d0cc3 100644 --- a/usr.bin/svn/svnversion/Makefile.depend +++ b/usr.bin/svn/svnversion/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.bin/systat/Makefile b/usr.bin/systat/Makefile index bb279d5..18fd1b1 100644 --- a/usr.bin/systat/Makefile +++ b/usr.bin/systat/Makefile @@ -6,7 +6,7 @@ PROG= systat SRCS= cmds.c cmdtab.c devs.c fetch.c iostat.c keyboard.c main.c \ netcmds.c netstat.c pigs.c swap.c icmp.c \ - mode.c ip.c tcp.c \ + mode.c ip.c tcp.c zarc.c \ vmstat.c convtbl.c ifcmds.c ifstat.c .if ${MK_INET6_SUPPORT} != "no" diff --git a/usr.bin/systat/cmdtab.c b/usr.bin/systat/cmdtab.c index c9c9e7d..273dd32 100644 --- a/usr.bin/systat/cmdtab.c +++ b/usr.bin/systat/cmdtab.c @@ -75,6 +75,9 @@ struct cmdtab cmdtab[] = { { "ifstat", showifstat, fetchifstat, labelifstat, initifstat, openifstat, closeifstat, cmdifstat, 0, CF_LOADAV }, + { "zarc", showzarc, fetchzarc, labelzarc, + initzarc, openzarc, closezarc, 0, + resetzarc, CF_ZFSARC }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0 } }; struct cmdtab *curcmd = &cmdtab[0]; diff --git a/usr.bin/systat/extern.h b/usr.bin/systat/extern.h index 17fffc1..2ac5a51 100644 --- a/usr.bin/systat/extern.h +++ b/usr.bin/systat/extern.h @@ -163,3 +163,14 @@ void showtcp(void); void status(void); void suspend(int); char *sysctl_dynread(const char *, size_t *); + +#define SYSTAT_CMD(name) \ + void close ## name(WINDOW *); \ + void fetch ## name(void); \ + int init ## name(void); \ + void label ## name(void); \ + WINDOW *open ## name(void); \ + void reset ## name(void); \ + void show ## name(void) + +SYSTAT_CMD( zarc ); diff --git a/usr.bin/systat/main.c b/usr.bin/systat/main.c index fd93830..5e509ca 100644 --- a/usr.bin/systat/main.c +++ b/usr.bin/systat/main.c @@ -178,7 +178,7 @@ main(int argc, char **argv) * devices. We can now use sysctl only. */ use_kvm = 0; - kd = kvm_openfiles("/dev/null", "/dev/null", "/dev/null", + kd = kvm_openfiles(_PATH_DEVNULL, _PATH_DEVNULL, _PATH_DEVNULL, O_RDONLY, errbuf); if (kd == NULL) { error("%s", errbuf); @@ -243,6 +243,11 @@ labels(void) "/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10"); mvaddstr(1, 5, "Load Average"); } + if (curcmd->c_flags & CF_ZFSARC) { + mvaddstr(0, 20, + " Total MFU MRU Anon Hdr L2Hdr Other"); + mvaddstr(1, 5, "ZFS ARC "); + } (*curcmd->c_label)(); #ifdef notdef mvprintw(21, 25, "CPU usage on %s", hostname); @@ -276,8 +281,33 @@ display(void) if (j > 50) wprintw(wload, " %4.1f", avenrun[0]); } + if (curcmd->c_flags & CF_ZFSARC) { + uint64_t arc[7] = {}; + size_t size = sizeof(arc[0]); + if (sysctlbyname("kstat.zfs.misc.arcstats.size", + &arc[0], &size, NULL, 0) == 0 ) { + GETSYSCTL("vfs.zfs.mfu_size", arc[1]); + GETSYSCTL("vfs.zfs.mru_size", arc[2]); + GETSYSCTL("vfs.zfs.anon_size", arc[3]); + GETSYSCTL("kstat.zfs.misc.arcstats.hdr_size", arc[4]); + GETSYSCTL("kstat.zfs.misc.arcstats.l2_hdr_size", arc[5]); + GETSYSCTL("kstat.zfs.misc.arcstats.other_size", arc[6]); + wmove(wload, 0, 0); wclrtoeol(wload); + for (i = 0 ; i < sizeof(arc) / sizeof(arc[0]) ; i++) { + if (arc[i] > 10llu * 1024 * 1024 * 1024 ) { + wprintw(wload, "%7lluG", arc[i] >> 30); + } + else if (arc[i] > 10 * 1024 * 1024 ) { + wprintw(wload, "%7lluM", arc[i] >> 20); + } + else { + wprintw(wload, "%7lluK", arc[i] >> 10); + } + } + } + } (*curcmd->c_refresh)(); - if (curcmd->c_flags & CF_LOADAV) + if (curcmd->c_flags & (CF_LOADAV |CF_ZFSARC)) wrefresh(wload); wrefresh(wnd); move(CMDLINE, col); diff --git a/usr.bin/systat/systat.1 b/usr.bin/systat/systat.1 index 6b7bcb9..af996bb 100644 --- a/usr.bin/systat/systat.1 +++ b/usr.bin/systat/systat.1 @@ -98,8 +98,9 @@ to be one of: .Ic pigs , .Ic swap , .Ic tcp , +.Ic vmstat , or -.Ic vmstat . +.Ic zarc , These displays can also be requested interactively (without the .Dq Fl ) and are described in @@ -441,6 +442,8 @@ Display statistics averaged over the refresh interval (the default). .It Cm zero Reset running statistics to zero. .El +.It Ic zarc +display arc cache usage and hit/miss statistics. .It Ic netstat Display, in the lower window, network connections. By default, diff --git a/usr.bin/systat/systat.h b/usr.bin/systat/systat.h index 1b4322c..ebd409e 100644 --- a/usr.bin/systat/systat.h +++ b/usr.bin/systat/systat.h @@ -54,6 +54,7 @@ extern int use_kvm; #define CF_INIT 0x1 /* been initialized */ #define CF_LOADAV 0x2 /* display w/ load average */ +#define CF_ZFSARC 0x4 /* display w/ ZFS cache usage */ #define TCP 0x1 #define UDP 0x2 diff --git a/usr.bin/systat/zarc.c b/usr.bin/systat/zarc.c new file mode 100644 index 0000000..2a6606f --- /dev/null +++ b/usr.bin/systat/zarc.c @@ -0,0 +1,221 @@ +/*- + * Copyright (c) 2014 + * The Regents of the University of California. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/sysctl.h> + +#include <string.h> + +#include "systat.h" +#include "extern.h" + +struct zfield{ + uint64_t arcstats; + uint64_t arcstats_demand_data; + uint64_t arcstats_demand_metadata; + uint64_t arcstats_prefetch_data; + uint64_t arcstats_prefetch_metadata; + uint64_t zfetchstats; + uint64_t arcstats_l2; + uint64_t vdev_cache_stats; +}; + +static struct zarcstats { + struct zfield hits; + struct zfield misses; +} curstat, initstat, oldstat; + +static void +getinfo(struct zarcstats *ls); + +WINDOW * +openzarc(void) +{ + return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0)); +} + +void +closezarc(WINDOW *w) +{ + if (w == NULL) + return; + wclear(w); + wrefresh(w); + delwin(w); +} + +void +labelzarc(void) +{ + wmove(wnd, 0, 0); wclrtoeol(wnd); + mvwprintw(wnd, 0, 31+1, "%4.4s %7.7s %7.7s %12.12s %12.12s", + "rate", "hits", "misses", "total hits", "total misses"); +#define L(row, str) mvwprintw(wnd, row, 5, str); \ + mvwprintw(wnd, row, 31, ":"); \ + mvwprintw(wnd, row, 31+4, "%%") + L(1, "arcstats"); + L(2, "arcstats.demand_data"); + L(3, "arcstats.demand_metadata"); + L(4, "arcstats.prefetch_data"); + L(5, "arcstats.prefetch_metadata"); + L(6, "zfetchstats"); + L(7, "arcstats.l2"); + L(8, "vdev_cache_stats"); +#undef L +} + +static int calc(uint64_t hits, uint64_t misses) +{ + if( hits ) + return 100 * hits / ( hits + misses ); + else + return 0; +} + +static void +domode(struct zarcstats *delta, struct zarcstats *rate) +{ +#define DO(stat) \ + delta->hits.stat = (curstat.hits.stat - oldstat.hits.stat); \ + delta->misses.stat = (curstat.misses.stat - oldstat.misses.stat); \ + rate->hits.stat = calc(delta->hits.stat, delta->misses.stat) + DO(arcstats); + DO(arcstats_demand_data); + DO(arcstats_demand_metadata); + DO(arcstats_prefetch_data); + DO(arcstats_prefetch_metadata); + DO(zfetchstats); + DO(arcstats_l2); + DO(vdev_cache_stats); + DO(arcstats); + DO(arcstats_demand_data); + DO(arcstats_demand_metadata); + DO(arcstats_prefetch_data); + DO(arcstats_prefetch_metadata); + DO(zfetchstats); + DO(arcstats_l2); + DO(vdev_cache_stats); +#undef DO +} + +void +showzarc(void) +{ + struct zarcstats delta, rate; + + memset(&delta, 0, sizeof delta); + memset(&rate, 0, sizeof rate); + + domode(&delta, &rate); + +#define DO(stat, row, col, fmt) \ + mvwprintw(wnd, row, col, fmt, stat) +#define R(row, stat) DO(rate.hits.stat, row, 31+1, "%3lu") +#define H(row, stat) DO(delta.hits.stat, row, 31+1+5, "%7lu"); \ + DO(curstat.hits.stat, row, 31+1+5+8+8, "%12lu") +#define M(row, stat) DO(delta.misses.stat, row, 31+1+5+8, "%7lu"); \ + DO(curstat.misses.stat, row, 31+1+5+8+8+13, "%12lu") +#define E(row, stat) R(row, stat); H(row, stat); M(row, stat); + E(1, arcstats); + E(2, arcstats_demand_data); + E(3, arcstats_demand_metadata); + E(4, arcstats_prefetch_data); + E(5, arcstats_prefetch_metadata); + E(6, zfetchstats); + E(7, arcstats_l2); + E(8, vdev_cache_stats); +#undef DO +#undef E +#undef M +#undef H +#undef R +} + +int +initzarc(void) +{ + getinfo(&initstat); + curstat = oldstat = initstat; + return 1; +} + +void +resetzarc(void) +{ + initzarc(); +} + +static void +getinfo(struct zarcstats *ls) +{ + size_t size = sizeof( ls->hits.arcstats ); + if ( sysctlbyname("kstat.zfs.misc.arcstats.hits", + &ls->hits.arcstats, &size, NULL, 0 ) != 0 ) + return; + GETSYSCTL("kstat.zfs.misc.arcstats.misses", + ls->misses.arcstats); + GETSYSCTL("kstat.zfs.misc.arcstats.demand_data_hits", + ls->hits.arcstats_demand_data); + GETSYSCTL("kstat.zfs.misc.arcstats.demand_data_misses", + ls->misses.arcstats_demand_data); + GETSYSCTL("kstat.zfs.misc.arcstats.demand_metadata_hits", + ls->hits.arcstats_demand_metadata); + GETSYSCTL("kstat.zfs.misc.arcstats.demand_metadata_misses", + ls->misses.arcstats_demand_metadata); + GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_data_hits", + ls->hits.arcstats_prefetch_data); + GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_data_misses", + ls->misses.arcstats_prefetch_data); + GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_metadata_hits", + ls->hits.arcstats_prefetch_metadata); + GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_metadata_misses", + ls->misses.arcstats_prefetch_metadata); + GETSYSCTL("kstat.zfs.misc.zfetchstats.hits", + ls->hits.zfetchstats); + GETSYSCTL("kstat.zfs.misc.zfetchstats.misses", + ls->misses.zfetchstats); + GETSYSCTL("kstat.zfs.misc.arcstats.l2_hits", + ls->hits.arcstats_l2); + GETSYSCTL("kstat.zfs.misc.arcstats.l2_misses", + ls->misses.arcstats_l2); + GETSYSCTL("kstat.zfs.misc.vdev_cache_stats.hits", + ls->hits.vdev_cache_stats); + GETSYSCTL("kstat.zfs.misc.vdev_cache_stats.misses", + ls->misses.vdev_cache_stats); +} + +void +fetchzarc(void) +{ + oldstat = curstat; + getinfo(&curstat); +} diff --git a/usr.bin/truss/amd64-fbsd.c b/usr.bin/truss/amd64-fbsd.c index eeea8db..ade9322 100644 --- a/usr.bin/truss/amd64-fbsd.c +++ b/usr.bin/truss/amd64-fbsd.c @@ -29,290 +29,103 @@ * SUCH DAMAGE. */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); -/* - * FreeBSD/amd64-specific system call handling. This is probably the most - * complex part of the entire truss program, although I've got lots of - * it handled relatively cleanly now. The system call names are generated - * automatically, thanks to /usr/src/sys/kern/syscalls.master. The - * names used for the various structures are confusing, I sadly admit. - */ +/* FreeBSD/amd64-specific system call handling. */ -#include <sys/types.h> #include <sys/ptrace.h> #include <sys/syscall.h> #include <machine/reg.h> #include <machine/psl.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> #include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> #include "truss.h" -#include "syscall.h" -#include "extern.h" #include "syscalls.h" -static int nsyscalls = nitems(syscallnames); - -/* - * This is what this particular file uses to keep track of a system call. - * It is probably not quite sufficient -- I can probably use the same - * structure for the various syscall personalities, and I also probably - * need to nest system calls (for signal handlers). - * - * 'struct syscall' describes the system call; it may be NULL, however, - * if we don't know about this particular system call yet. - */ -struct freebsd_syscall { - struct syscall *sc; - const char *name; - int number; - unsigned long *args; - int nargs; /* number of arguments -- *not* number of words! */ - char **s_args; /* the printable arguments */ -}; - -static struct freebsd_syscall * -alloc_fsc(void) -{ - - return (malloc(sizeof(struct freebsd_syscall))); -} - -/* Clear up and free parts of the fsc structure. */ -static void -free_fsc(struct freebsd_syscall *fsc) -{ - int i; - - free(fsc->args); - if (fsc->s_args) { - for (i = 0; i < fsc->nargs; i++) - free(fsc->s_args[i]); - free(fsc->s_args); - } - free(fsc); -} - -/* - * Called when a process has entered a system call. nargs is the - * number of words, not number of arguments (a necessary distinction - * in some cases). Note that if the STOPEVENT() code in amd64/amd64/trap.c - * is ever changed these functions need to keep up. - */ - -void -amd64_syscall_entry(struct trussinfo *trussinfo, int nargs) +static int +amd64_fetch_args(struct trussinfo *trussinfo, u_int narg) { struct ptrace_io_desc iorequest; struct reg regs; - struct freebsd_syscall *fsc; - struct syscall *sc; + struct current_syscall *cs; lwpid_t tid; - int i, reg, syscall_num; + u_int i, reg; tid = trussinfo->curthread->tid; - + cs = &trussinfo->curthread->cs; if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; + return (-1); } /* - * FreeBSD has two special kinds of system call redirctions -- + * FreeBSD has two special kinds of system call redirections -- * SYS_syscall, and SYS___syscall. The former is the old syscall() * routine, basically; the latter is for quad-aligned arguments. + * + * The system call argument count and code from ptrace() already + * account for these, but we need to skip over %rax if it contains + * either of these values. */ reg = 0; - syscall_num = regs.r_rax; - switch (syscall_num) { + switch (regs.r_rax) { case SYS_syscall: case SYS___syscall: - syscall_num = regs.r_rdi; reg++; break; } - fsc = alloc_fsc(); - if (fsc == NULL) - return; - fsc->number = syscall_num; - fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ? - NULL : syscallnames[syscall_num]; - if (!fsc->name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", - syscall_num); - } - - if (fsc->name && (trussinfo->flags & FOLLOWFORKS) && - (strcmp(fsc->name, "fork") == 0 || - strcmp(fsc->name, "pdfork") == 0 || - strcmp(fsc->name, "rfork") == 0 || - strcmp(fsc->name, "vfork") == 0)) - trussinfo->curthread->in_fork = 1; - - if (nargs == 0) - return; - - fsc->args = malloc((1 + nargs) * sizeof(unsigned long)); - for (i = 0; i < nargs && reg < 6; i++, reg++) { + for (i = 0; i < narg && reg < 6; i++, reg++) { switch (reg) { - case 0: fsc->args[i] = regs.r_rdi; break; - case 1: fsc->args[i] = regs.r_rsi; break; - case 2: fsc->args[i] = regs.r_rdx; break; - case 3: fsc->args[i] = regs.r_rcx; break; - case 4: fsc->args[i] = regs.r_r8; break; - case 5: fsc->args[i] = regs.r_r9; break; + case 0: cs->args[i] = regs.r_rdi; break; + case 1: cs->args[i] = regs.r_rsi; break; + case 2: cs->args[i] = regs.r_rdx; break; + case 3: cs->args[i] = regs.r_rcx; break; + case 4: cs->args[i] = regs.r_r8; break; + case 5: cs->args[i] = regs.r_r9; break; } } - if (nargs > i) { + if (narg > i) { iorequest.piod_op = PIOD_READ_D; iorequest.piod_offs = (void *)(regs.r_rsp + sizeof(register_t)); - iorequest.piod_addr = &fsc->args[i]; - iorequest.piod_len = (nargs - i) * sizeof(register_t); + iorequest.piod_addr = &cs->args[i]; + iorequest.piod_len = (narg - i) * sizeof(register_t); ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); if (iorequest.piod_len == 0) - return; - } - - sc = get_syscall(fsc->name); - if (sc) - fsc->nargs = sc->nargs; - else { -#if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting " - "args to %d\n", fsc->name, nargs); -#endif - fsc->nargs = nargs; + return (-1); } - fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *)); - fsc->sc = sc; - - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ - - if (fsc->name) { -#if DEBUG - fprintf(stderr, "syscall %s(", fsc->name); -#endif - for (i = 0; i < fsc->nargs; i++) { -#if DEBUG - fprintf(stderr, "0x%lx%s", sc ? - fsc->args[sc->args[i].offset] : fsc->args[i], - i < (fsc->nargs - 1) ? "," : ""); -#endif - if (sc && !(sc->args[i].type & OUT)) { - fsc->s_args[i] = print_arg(&sc->args[i], - fsc->args, 0, trussinfo); - } - } -#if DEBUG - fprintf(stderr, ")\n"); -#endif - } - -#if DEBUG - fprintf(trussinfo->outfile, "\n"); -#endif - - trussinfo->curthread->fsc = fsc; + return (0); } -/* - * And when the system call is done, we handle it here. - * Currently, no attempt is made to ensure that the system calls - * match -- this needs to be fixed (and is, in fact, why S_SCX includes - * the system call number instead of, say, an error status). - */ - -long -amd64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) +static int +amd64_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp) { struct reg regs; - struct freebsd_syscall *fsc; - struct syscall *sc; lwpid_t tid; - long retval; - int errorp, i; - - if (trussinfo->curthread->fsc == NULL) - return (-1); tid = trussinfo->curthread->tid; - if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return (-1); } - retval = regs.r_rax; - errorp = !!(regs.r_rflags & PSL_C); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - fsc = trussinfo->curthread->fsc; - sc = fsc->sc; - if (!sc) { - for (i = 0; i < fsc->nargs; i++) - asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - - if (sc->args[i].type & OUT) { - /* - * If an error occurred, then don't bother - * getting the data; it may not be valid. - */ - if (errorp) { - asprintf(&temp, "0x%lx", - fsc->args[sc->args[i].offset]); - } else { - temp = print_arg(&sc->args[i], - fsc->args, retval, trussinfo); - } - fsc->s_args[i] = temp; - } - } - } - - if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 || - strcmp(fsc->name, "exit") == 0)) - trussinfo->curthread->in_syscall = 1; - - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ + retval[0] = regs.r_rax; + retval[1] = regs.r_rdx; + *errorp = !!(regs.r_rflags & PSL_C); + return (0); +} - print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp, - retval, fsc->sc); - free_fsc(fsc); +static struct procabi amd64_fbsd = { + "FreeBSD ELF64", + syscallnames, + nitems(syscallnames), + amd64_fetch_args, + amd64_fetch_retval +}; - return (retval); -} +PROCABI(amd64_fbsd); diff --git a/usr.bin/truss/amd64-fbsd32.c b/usr.bin/truss/amd64-fbsd32.c index 40aa152..84a4b6b 100644 --- a/usr.bin/truss/amd64-fbsd32.c +++ b/usr.bin/truss/amd64-fbsd32.c @@ -29,290 +29,109 @@ * SUCH DAMAGE. */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); -/* - * FreeBSD/i386-specific system call handling. This is probably the most - * complex part of the entire truss program, although I've got lots of - * it handled relatively cleanly now. The system call names are generated - * automatically, thanks to /usr/src/sys/kern/syscalls.master. The - * names used for the various structures are confusing, I sadly admit. - */ +/* FreeBSD/i386-specific system call handling. */ -#include <sys/types.h> #include <sys/ptrace.h> #include <sys/syscall.h> #include <machine/reg.h> #include <machine/psl.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> #include "truss.h" -#include "syscall.h" -#include "extern.h" #include "freebsd32_syscalls.h" -static int nsyscalls = nitems(freebsd32_syscallnames); - -/* - * This is what this particular file uses to keep track of a system call. - * It is probably not quite sufficient -- I can probably use the same - * structure for the various syscall personalities, and I also probably - * need to nest system calls (for signal handlers). - * - * 'struct syscall' describes the system call; it may be NULL, however, - * if we don't know about this particular system call yet. - */ -struct freebsd32_syscall { - struct syscall *sc; - const char *name; - int number; - unsigned long *args; - unsigned int *args32; - int nargs; /* number of arguments -- *not* number of words! */ - char **s_args; /* the printable arguments */ -}; - -static struct freebsd32_syscall * -alloc_fsc(void) -{ - - return (malloc(sizeof(struct freebsd32_syscall))); -} - -/* Clear up and free parts of the fsc structure. */ -static void -free_fsc(struct freebsd32_syscall *fsc) -{ - int i; - - free(fsc->args); - free(fsc->args32); - if (fsc->s_args) { - for (i = 0; i < fsc->nargs; i++) - free(fsc->s_args[i]); - free(fsc->s_args); - } - free(fsc); -} - -/* - * Called when a process has entered a system call. nargs is the - * number of words, not number of arguments (a necessary distinction - * in some cases). Note that if the STOPEVENT() code in i386/i386/trap.c - * is ever changed these functions need to keep up. - */ - -void -amd64_fbsd32_syscall_entry(struct trussinfo *trussinfo, int nargs) +static int +amd64_fbsd32_fetch_args(struct trussinfo *trussinfo, u_int narg) { struct ptrace_io_desc iorequest; struct reg regs; - struct freebsd32_syscall *fsc; - struct syscall *sc; - lwpid_t tid; + struct current_syscall *cs; + unsigned int args32[narg]; unsigned long parm_offset; - int i, syscall_num; + lwpid_t tid; + u_int i; tid = trussinfo->curthread->tid; - + cs = &trussinfo->curthread->cs; if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; + return (-1); } parm_offset = regs.r_rsp + sizeof(int); /* - * FreeBSD has two special kinds of system call redirctions -- + * FreeBSD has two special kinds of system call redirections -- * SYS_syscall, and SYS___syscall. The former is the old syscall() * routine, basically; the latter is for quad-aligned arguments. + * + * The system call argument count and code from ptrace() already + * account for these, but we need to skip over the first argument. */ - syscall_num = regs.r_rax; - switch (syscall_num) { + switch (regs.r_rax) { case SYS_syscall: - syscall_num = ptrace(PT_READ_D, tid, (caddr_t)parm_offset, 0); parm_offset += sizeof(int); break; case SYS___syscall: - syscall_num = ptrace(PT_READ_D, tid, (caddr_t)parm_offset, 0); parm_offset += sizeof(quad_t); break; } - fsc = alloc_fsc(); - if (fsc == NULL) - return; - fsc->number = syscall_num; - fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ? - NULL : freebsd32_syscallnames[syscall_num]; - if (!fsc->name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", - syscall_num); - } - - if (fsc->name && (trussinfo->flags & FOLLOWFORKS) && - (strcmp(fsc->name, "fork") == 0 || - strcmp(fsc->name, "pdfork") == 0 || - strcmp(fsc->name, "rfork") == 0 || - strcmp(fsc->name, "vfork") == 0)) - trussinfo->curthread->in_fork = 1; - - if (nargs == 0) - return; - - fsc->args32 = malloc((1 + nargs) * sizeof(unsigned int)); iorequest.piod_op = PIOD_READ_D; iorequest.piod_offs = (void *)parm_offset; - iorequest.piod_addr = fsc->args32; - iorequest.piod_len = (1 + nargs) * sizeof(unsigned int); + iorequest.piod_addr = args32; + iorequest.piod_len = sizeof(args32); ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); - if (iorequest.piod_len == 0) - return; - - fsc->args = malloc((1 + nargs) * sizeof(unsigned long)); - for (i = 0; i < nargs + 1; i++) - fsc->args[i] = fsc->args32[i]; - - sc = NULL; - if (fsc->name) - sc = get_syscall(fsc->name); - if (sc) - fsc->nargs = sc->nargs; - else { -#if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting " - "args to %d\n", fsc->name, nargs); -#endif - fsc->nargs = nargs; - } - - fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *)); - fsc->sc = sc; - - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ - - if (fsc->name) { -#if DEBUG - fprintf(stderr, "syscall %s(", fsc->name); -#endif - for (i = 0; i < fsc->nargs; i++) { -#if DEBUG - fprintf(stderr, "0x%x%s", sc ? - fsc->args[sc->args[i].offset] : fsc->args[i], - i < (fsc->nargs - 1) ? "," : ""); -#endif - if (sc && !(sc->args[i].type & OUT)) { - fsc->s_args[i] = print_arg(&sc->args[i], - fsc->args, 0, trussinfo); - } - } -#if DEBUG - fprintf(stderr, ")\n"); -#endif + if (iorequest.piod_len == 0) { + return (-1); } -#if DEBUG - fprintf(trussinfo->outfile, "\n"); -#endif - - trussinfo->curthread->fsc = fsc; + for (i = 0; i < narg; i++) + cs->args[i] = args32[i]; + return (0); } -/* - * And when the system call is done, we handle it here. - * Currently, no attempt is made to ensure that the system calls - * match -- this needs to be fixed (and is, in fact, why S_SCX includes - * the system call number instead of, say, an error status). - */ - -long -amd64_fbsd32_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) +static int +amd64_fbsd32_fetch_retval(struct trussinfo *trussinfo, long *retval, + int *errorp) { struct reg regs; - struct freebsd32_syscall *fsc; - struct syscall *sc; lwpid_t tid; - long retval; - int errorp, i; - - if (trussinfo->curthread->fsc == NULL) - return (-1); tid = trussinfo->curthread->tid; - if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return (-1); } - retval = regs.r_rax; - errorp = !!(regs.r_rflags & PSL_C); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - fsc = trussinfo->curthread->fsc; - sc = fsc->sc; - if (!sc) { - for (i = 0; i < fsc->nargs; i++) - asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - - if (sc->args[i].type & OUT) { - /* - * If an error occurred, then don't bother - * getting the data; it may not be valid. - */ - if (errorp) { - asprintf(&temp, "0x%lx", - fsc->args[sc->args[i].offset]); - } else { - temp = print_arg(&sc->args[i], - fsc->args, retval, trussinfo); - } - fsc->s_args[i] = temp; - } - } - } + retval[0] = regs.r_rax & 0xffffffff; + retval[1] = regs.r_rdx & 0xffffffff; + *errorp = !!(regs.r_rflags & PSL_C); + return (0); +} - if (fsc->name != NULL && (strcmp(fsc->name, "freebsd32_execve") == 0 || - strcmp(fsc->name, "exit") == 0)) - trussinfo->curthread->in_syscall = 1; +static struct procabi amd64_fbsd32 = { + "FreeBSD ELF32", + freebsd32_syscallnames, + nitems(freebsd32_syscallnames), + amd64_fbsd32_fetch_args, + amd64_fbsd32_fetch_retval +}; - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ +PROCABI(amd64_fbsd32); - print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp, - retval, fsc->sc); - free_fsc(fsc); +static struct procabi amd64_fbsd32_aout = { + "FreeBSD a.out", + freebsd32_syscallnames, + nitems(freebsd32_syscallnames), + amd64_fbsd32_fetch_args, + amd64_fbsd32_fetch_retval +}; - return (retval); -} +PROCABI(amd64_fbsd32_aout); diff --git a/usr.bin/truss/amd64-linux32.c b/usr.bin/truss/amd64-linux32.c index b2d0d04..4f64af3 100644 --- a/usr.bin/truss/amd64-linux32.c +++ b/usr.bin/truss/amd64-linux32.c @@ -29,123 +29,36 @@ * SUCH DAMAGE. */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); -/* - * Linux/i386-specific system call handling. Given how much of this code - * is taken from the freebsd equivalent, I can probably put even more of - * it in support routines that can be used by any personality support. - */ +/* Linux/i386-specific system call handling. */ -#include <sys/types.h> #include <sys/ptrace.h> #include <machine/reg.h> #include <machine/psl.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> #include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> #include "truss.h" -#include "syscall.h" -#include "extern.h" #include "linux32_syscalls.h" -static int nsyscalls = nitems(linux32_syscallnames); - -/* - * This is what this particular file uses to keep track of a system call. - * It is probably not quite sufficient -- I can probably use the same - * structure for the various syscall personalities, and I also probably - * need to nest system calls (for signal handlers). - * - * 'struct syscall' describes the system call; it may be NULL, however, - * if we don't know about this particular system call yet. - */ -struct linux_syscall { - struct syscall *sc; - const char *name; - int number; - unsigned long args[5]; - int nargs; /* number of arguments -- *not* number of words! */ - char **s_args; /* the printable arguments */ -}; - -static struct linux_syscall * -alloc_fsc(void) -{ - - return (malloc(sizeof(struct linux_syscall))); -} - -/* Clear up and free parts of the fsc structure. */ -static void -free_fsc(struct linux_syscall *fsc) -{ - int i; - - if (fsc->s_args) { - for (i = 0; i < fsc->nargs; i++) - free(fsc->s_args[i]); - free(fsc->s_args); - } - free(fsc); -} - -/* - * Called when a process has entered a system call. nargs is the - * number of words, not number of arguments (a necessary distinction - * in some cases). Note that if the STOPEVENT() code in i386/i386/trap.c - * is ever changed these functions need to keep up. - */ - -void -amd64_linux32_syscall_entry(struct trussinfo *trussinfo, int nargs) +static int +amd64_linux32_fetch_args(struct trussinfo *trussinfo, u_int narg) { struct reg regs; - struct linux_syscall *fsc; - struct syscall *sc; + struct current_syscall *cs; lwpid_t tid; - int i, syscall_num; tid = trussinfo->curthread->tid; - + cs = &trussinfo->curthread->cs; if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; - } - - syscall_num = regs.r_rax; - - fsc = alloc_fsc(); - if (fsc == NULL) - return; - fsc->number = syscall_num; - fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ? - NULL : linux32_syscallnames[syscall_num]; - if (!fsc->name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", - syscall_num); + return (-1); } - if (fsc->name && (trussinfo->flags & FOLLOWFORKS) && - (strcmp(fsc->name, "linux_fork") == 0 || - strcmp(fsc->name, "linux_vfork") == 0)) - trussinfo->curthread->in_fork = 1; - - if (nargs == 0) - return; - /* * Linux passes syscall arguments in registers, not * on the stack. Fortunately, we've got access to the @@ -153,60 +66,22 @@ amd64_linux32_syscall_entry(struct trussinfo *trussinfo, int nargs) * number of arguments. And what does linux do for syscalls * that have more than five arguments? */ - - fsc->args[0] = regs.r_rbx; - fsc->args[1] = regs.r_rcx; - fsc->args[2] = regs.r_rdx; - fsc->args[3] = regs.r_rsi; - fsc->args[4] = regs.r_rdi; - - sc = get_syscall(fsc->name); - if (sc) - fsc->nargs = sc->nargs; - else { -#if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting " - "args to %d\n", fsc->name, nargs); -#endif - fsc->nargs = nargs; + switch (narg) { + default: + cs->args[5] = regs.r_rbp; /* Unconfirmed */ + case 5: + cs->args[4] = regs.r_rdi; + case 4: + cs->args[3] = regs.r_rsi; + case 3: + cs->args[2] = regs.r_rdx; + case 2: + cs->args[1] = regs.r_rcx; + case 1: + cs->args[0] = regs.r_rbx; } - fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *)); - fsc->sc = sc; - - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ - - if (fsc->name) { -#if DEBUG - fprintf(stderr, "syscall %s(", fsc->name); -#endif - for (i = 0; i < fsc->nargs; i++) { -#if DEBUG - fprintf(stderr, "0x%x%s", sc ? - fsc->args[sc->args[i].offset] : fsc->args[i], - i < (fsc->nargs - 1) ? "," : ""); -#endif - if (sc && !(sc->args[i].type & OUT)) { - fsc->s_args[i] = print_arg(&sc->args[i], - fsc->args, 0, trussinfo); - } - } -#if DEBUG - fprintf(stderr, ")\n"); -#endif - } - -#if DEBUG - fprintf(trussinfo->outfile, "\n"); -#endif - - trussinfo->curthread->fsc = fsc; + return (0); } /* @@ -224,83 +99,43 @@ static const int bsd_to_linux_errno[] = { -6, }; -long -amd64_linux32_syscall_exit(struct trussinfo *trussinfo, - int syscall_num __unused) +static int +amd64_linux32_fetch_retval(struct trussinfo *trussinfo, long *retval, + int *errorp) { struct reg regs; - struct linux_syscall *fsc; - struct syscall *sc; lwpid_t tid; - long retval; - int errorp, i; - - if (trussinfo->curthread->fsc == NULL) - return (-1); + size_t i; tid = trussinfo->curthread->tid; - if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return (-1); } - retval = regs.r_rax; - errorp = !!(regs.r_rflags & PSL_C); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ + retval[0] = regs.r_rax & 0xffffffff; + retval[1] = regs.r_rdx & 0xffffffff; + *errorp = !!(regs.r_rflags & PSL_C); - fsc = trussinfo->curthread->fsc; - sc = fsc->sc; - if (!sc) { - for (i = 0; i < fsc->nargs; i++) - asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - - if (sc->args[i].type & OUT) { - /* - * If an error occurred, then don't bother - * getting the data; it may not be valid. - */ - if (errorp) { - asprintf(&temp, "0x%lx", - fsc->args[sc->args[i].offset]); - } else { - temp = print_arg(&sc->args[i], - fsc->args, retval, trussinfo); - } - fsc->s_args[i] = temp; + if (*errorp) { + for (i = 0; i < nitems(bsd_to_linux_errno); i++) { + if (retval[0] == bsd_to_linux_errno[i]) { + retval[0] = i; + return (0); } } - } - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ - if (errorp) { - for (i = 0; (size_t)i < nitems(bsd_to_linux_errno); i++) { - if (retval == bsd_to_linux_errno[i]) - break; - } + /* XXX: How to handle unknown errors? */ } + return (0); +} - if (fsc->name != NULL && (strcmp(fsc->name, "linux_execve") == 0 || - strcmp(fsc->name, "exit") == 0)) - trussinfo->curthread->in_syscall = 1; - - print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp, - errorp ? i : retval, fsc->sc); - free_fsc(fsc); +static struct procabi amd64_linux32 = { + "Linux ELF32", + linux32_syscallnames, + nitems(linux32_syscallnames), + amd64_linux32_fetch_args, + amd64_linux32_fetch_retval +}; - return (retval); -} +PROCABI(amd64_linux32); diff --git a/usr.bin/truss/arm-fbsd.c b/usr.bin/truss/arm-fbsd.c index 8dc4d5b..4b8222a 100644 --- a/usr.bin/truss/arm-fbsd.c +++ b/usr.bin/truss/arm-fbsd.c @@ -29,17 +29,11 @@ * SUCH DAMAGE. */ -/* - * FreeBSD/arm-specific system call handling. This is probably the most - * complex part of the entire truss program, although I've got lots of - * it handled relatively cleanly now. The system call names are generated - * automatically, thanks to /usr/src/sys/kern/syscalls.master. The - * names used for the various structures are confusing, I sadly admit. - */ - #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <sys/types.h> + +/* FreeBSD/arm-specific system call handling. */ + #include <sys/ptrace.h> #include <sys/syscall.h> @@ -47,303 +41,98 @@ __FBSDID("$FreeBSD$"); #include <machine/armreg.h> #include <machine/ucontext.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> #include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#include <err.h> #include "truss.h" -#include "syscall.h" -#include "extern.h" #include "syscalls.h" - -static int nsyscalls = nitems(syscallnames); - -/* - * This is what this particular file uses to keep track of a system call. - * It is probably not quite sufficient -- I can probably use the same - * structure for the various syscall personalities, and I also probably - * need to nest system calls (for signal handlers). - * - * 'struct syscall' describes the system call; it may be NULL, however, - * if we don't know about this particular system call yet. - */ -struct freebsd_syscall { - struct syscall *sc; - const char *name; - int number; - unsigned long *args; - int nargs; /* number of arguments -- *not* number of words! */ - char **s_args; /* the printable arguments */ -}; - -static struct freebsd_syscall * -alloc_fsc(void) -{ - - return (malloc(sizeof(struct freebsd_syscall))); -} - -/* Clear up and free parts of the fsc structure. */ -static void -free_fsc(struct freebsd_syscall *fsc) -{ - int i; - - free(fsc->args); - if (fsc->s_args) { - for (i = 0; i < fsc->nargs; i++) - free(fsc->s_args[i]); - free(fsc->s_args); - } - free(fsc); -} - -/* - * Called when a process has entered a system call. nargs is the - * number of words, not number of arguments (a necessary distinction - * in some cases). Note that if the STOPEVENT() code in i386/i386/trap.c - * is ever changed these functions need to keep up. - */ - -void -arm_syscall_entry(struct trussinfo *trussinfo, int nargs) +static int +arm_fetch_args(struct trussinfo *trussinfo, u_int narg) { struct ptrace_io_desc iorequest; struct reg regs; - struct freebsd_syscall *fsc; - struct syscall *sc; + struct current_syscall *cs; lwpid_t tid; - int i, syscall_num; - register_t *ap; + u_int i, reg, syscall_num; tid = trussinfo->curthread->tid; - + cs = &trussinfo->curthread->cs; if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; + return (-1); } - ap = ®s.r[0]; /* - * FreeBSD has two special kinds of system call redirctions -- + * FreeBSD has two special kinds of system call redirections -- * SYS_syscall, and SYS___syscall. The former is the old syscall() * routine, basically; the latter is for quad-aligned arguments. + * + * The system call argument count and code from ptrace() already + * account for these, but we need to skip over the first argument. */ #ifdef __ARM_EABI__ syscall_num = regs.r[7]; #else - if ((syscall_num = ptrace(PT_READ_I, tid, + if ((syscall_num = ptrace(PT_READ_I, tid, (caddr_t)(regs.r[_REG_PC] - INSN_SIZE), 0)) == -1) { fprintf(trussinfo->outfile, "-- CANNOT READ PC --\n"); - return; + return (-1); } syscall_num = syscall_num & 0x000fffff; #endif + + reg = 0; switch (syscall_num) { case SYS_syscall: - syscall_num = *ap++; - nargs--; + reg = 1; break; case SYS___syscall: - syscall_num = ap[_QUAD_LOWWORD]; - ap += 2; - nargs -= 2; + reg = 2; break; } - fsc = alloc_fsc(); - if (fsc == NULL) - return; - fsc->number = syscall_num; - fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ? - NULL : syscallnames[syscall_num]; - if (!fsc->name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", - syscall_num); - } - - if (fsc->name && (trussinfo->flags & FOLLOWFORKS) && - (strcmp(fsc->name, "fork") == 0 || - strcmp(fsc->name, "pdfork") == 0 || - strcmp(fsc->name, "rfork") == 0 || - strcmp(fsc->name, "vfork") == 0)) - trussinfo->curthread->in_fork = 1; - - if (nargs == 0) - return; - - fsc->args = malloc((1 + nargs) * sizeof(unsigned long)); - switch (nargs) { - default: - /* - * The OS doesn't seem to allow more than 10 words of - * parameters (yay!). So we shouldn't be here. - */ - warn("More than 10 words (%d) of arguments!\n", nargs); - break; - case 10: - case 9: - case 8: - case 7: - case 6: - case 5: - /* - * If there are 7-10 words of arguments, they are placed - * on the stack, as is normal for other processors. - * The fall-through for all of these is deliberate!!! - */ - // XXX BAD constant used here + for (i = 0; i < narg && reg < 4; i++, reg++) + cs->args[i] = regs.r[reg]; + if (narg > i) { iorequest.piod_op = PIOD_READ_D; iorequest.piod_offs = (void *)(regs.r_sp + 4 * sizeof(uint32_t)); - iorequest.piod_addr = &fsc->args[4]; - iorequest.piod_len = (nargs - 4) * sizeof(fsc->args[0]); + iorequest.piod_addr = &cs->args[i]; + iorequest.piod_len = (narg - i) * sizeof(cs->args[0]); ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); if (iorequest.piod_len == 0) - return; - case 4: fsc->args[3] = ap[3]; - case 3: fsc->args[2] = ap[2]; - case 2: fsc->args[1] = ap[1]; - case 1: fsc->args[0] = ap[0]; - case 0: break; + return (-1); } - sc = NULL; - if (fsc->name) - sc = get_syscall(fsc->name); - if (sc) - fsc->nargs = sc->nargs; - else { -#if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting " - "args to %d\n", fsc->name, nargs); -#endif - fsc->nargs = nargs; - } - - fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *)); - fsc->sc = sc; - - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ - - if (fsc->name) { -#if DEBUG - fprintf(stderr, "syscall %s(", fsc->name); -#endif - for (i = 0; i < fsc->nargs; i++) { -#if DEBUG - fprintf(stderr, "0x%x%s", sc ? - fsc->args[sc->args[i].offset] : fsc->args[i], - i < (fsc->nargs - 1) ? "," : ""); -#endif - if (sc && !(sc->args[i].type & OUT)) { - fsc->s_args[i] = print_arg(&sc->args[i], - fsc->args, 0, trussinfo); - } - } -#if DEBUG - fprintf(stderr, ")\n"); -#endif - } - -#if DEBUG - fprintf(trussinfo->outfile, "\n"); -#endif - - trussinfo->curthread->fsc = fsc; + return (0); } -/* - * And when the system call is done, we handle it here. - * Currently, no attempt is made to ensure that the system calls - * match -- this needs to be fixed (and is, in fact, why S_SCX includes - * the system call number instead of, say, an error status). - */ - -long -arm_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) +static int +arm_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp) { struct reg regs; - struct freebsd_syscall *fsc; - struct syscall *sc; lwpid_t tid; - long retval; - int errorp, i; - - if (trussinfo->curthread->fsc == NULL) - return (-1); tid = trussinfo->curthread->tid; - if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return (-1); } - retval = regs.r[0]; - errorp = !!(regs.r_cpsr & PSR_C); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - fsc = trussinfo->curthread->fsc; - sc = fsc->sc; - if (!sc) { - for (i = 0; i < fsc->nargs; i++) - asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - - if (sc->args[i].type & OUT) { - /* - * If an error occurred, then don't bother - * getting the data; it may not be valid. - */ - if (errorp) { - asprintf(&temp, "0x%lx", - fsc->args[sc->args[i].offset]); - } else { - temp = print_arg(&sc->args[i], - fsc->args, retval, trussinfo); - } - fsc->s_args[i] = temp; - } - } - } - - if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 || - strcmp(fsc->name, "exit") == 0)) - trussinfo->curthread->in_syscall = 1; - - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ + /* XXX: Does not have the __ARMEB__ handling for __syscall(). */ + retval[0] = regs.r[0]; + retval[1] = regs.r[1]; + *errorp = !!(regs.r_cpsr & PSR_C); + return (0); +} - print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp, - retval, fsc->sc); - free_fsc(fsc); +static struct procabi arm_fbsd = { + "FreeBSD ELF32", + syscallnames, + nitems(syscallnames), + arm_fetch_args, + arm_fetch_retval +}; - return (retval); -} +PROCABI(arm_fbsd); diff --git a/usr.bin/truss/extern.h b/usr.bin/truss/extern.h index 820f4f0..708d055 100644 --- a/usr.bin/truss/extern.h +++ b/usr.bin/truss/extern.h @@ -31,42 +31,9 @@ * $FreeBSD$ */ -extern int setup_and_wait(char **); -extern int start_tracing(pid_t); +extern void setup_and_wait(struct trussinfo *, char **); +extern void start_tracing(struct trussinfo *, pid_t); extern void restore_proc(int); -extern void waitevent(struct trussinfo *); +extern void eventloop(struct trussinfo *); extern const char *ioctlname(unsigned long val); extern char *strsig(int sig); -#ifdef __arm__ -extern void arm_syscall_entry(struct trussinfo *, int); -extern long arm_syscall_exit(struct trussinfo *, int); -#endif -#ifdef __amd64__ -extern void amd64_syscall_entry(struct trussinfo *, int); -extern long amd64_syscall_exit(struct trussinfo *, int); -extern void amd64_linux32_syscall_entry(struct trussinfo *, int); -extern long amd64_linux32_syscall_exit(struct trussinfo *, int); -extern void amd64_fbsd32_syscall_entry(struct trussinfo *, int); -extern long amd64_fbsd32_syscall_exit(struct trussinfo *, int); -#endif -#ifdef __i386__ -extern void i386_syscall_entry(struct trussinfo *, int); -extern long i386_syscall_exit(struct trussinfo *, int); -extern void i386_linux_syscall_entry(struct trussinfo *, int); -extern long i386_linux_syscall_exit(struct trussinfo *, int); -#endif -#ifdef __powerpc__ -extern void powerpc_syscall_entry(struct trussinfo *, int); -extern long powerpc_syscall_exit(struct trussinfo *, int); -extern void powerpc64_syscall_entry(struct trussinfo *, int); -extern long powerpc64_syscall_exit(struct trussinfo *, int); -#endif -#ifdef __sparc64__ -extern void sparc64_syscall_entry(struct trussinfo *, int); -extern long sparc64_syscall_exit(struct trussinfo *, int); -#endif -#ifdef __mips__ -extern void mips_syscall_entry(struct trussinfo *, int); -extern long mips_syscall_exit(struct trussinfo *, int); -#endif - diff --git a/usr.bin/truss/i386-fbsd.c b/usr.bin/truss/i386-fbsd.c index ef326f0..029815e 100644 --- a/usr.bin/truss/i386-fbsd.c +++ b/usr.bin/truss/i386-fbsd.c @@ -29,284 +29,103 @@ * SUCH DAMAGE. */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); -/* - * FreeBSD/i386-specific system call handling. This is probably the most - * complex part of the entire truss program, although I've got lots of - * it handled relatively cleanly now. The system call names are generated - * automatically, thanks to /usr/src/sys/kern/syscalls.master. The - * names used for the various structures are confusing, I sadly admit. - */ +/* FreeBSD/i386-specific system call handling. */ -#include <sys/types.h> #include <sys/ptrace.h> #include <sys/syscall.h> #include <machine/reg.h> #include <machine/psl.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> #include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> #include "truss.h" -#include "syscall.h" -#include "extern.h" #include "syscalls.h" -static int nsyscalls = nitems(syscallnames); - -/* - * This is what this particular file uses to keep track of a system call. - * It is probably not quite sufficient -- I can probably use the same - * structure for the various syscall personalities, and I also probably - * need to nest system calls (for signal handlers). - * - * 'struct syscall' describes the system call; it may be NULL, however, - * if we don't know about this particular system call yet. - */ -struct freebsd_syscall { - struct syscall *sc; - const char *name; - int number; - unsigned long *args; - int nargs; /* number of arguments -- *not* number of words! */ - char **s_args; /* the printable arguments */ -}; - -static struct freebsd_syscall * -alloc_fsc(void) -{ - - return (malloc(sizeof(struct freebsd_syscall))); -} - -/* Clear up and free parts of the fsc structure. */ -static void -free_fsc(struct freebsd_syscall *fsc) -{ - int i; - - free(fsc->args); - if (fsc->s_args) { - for (i = 0; i < fsc->nargs; i++) - free(fsc->s_args[i]); - free(fsc->s_args); - } - free(fsc); -} - -/* - * Called when a process has entered a system call. nargs is the - * number of words, not number of arguments (a necessary distinction - * in some cases). Note that if the STOPEVENT() code in i386/i386/trap.c - * is ever changed these functions need to keep up. - */ - -void -i386_syscall_entry(struct trussinfo *trussinfo, int nargs) +static int +i386_fetch_args(struct trussinfo *trussinfo, u_int narg) { struct ptrace_io_desc iorequest; struct reg regs; - struct freebsd_syscall *fsc; - struct syscall *sc; + struct current_syscall *cs; lwpid_t tid; unsigned int parm_offset; - int i, syscall_num; tid = trussinfo->curthread->tid; - + cs = &trussinfo->curthread->cs; if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; + return (-1); } parm_offset = regs.r_esp + sizeof(int); /* - * FreeBSD has two special kinds of system call redirctions -- + * FreeBSD has two special kinds of system call redirections -- * SYS_syscall, and SYS___syscall. The former is the old syscall() * routine, basically; the latter is for quad-aligned arguments. + * + * The system call argument count and code from ptrace() already + * account for these, but we need to skip over the first argument. */ - syscall_num = regs.r_eax; - switch (syscall_num) { + switch (regs.r_eax) { case SYS_syscall: - syscall_num = ptrace(PT_READ_D, tid, (caddr_t)parm_offset, 0); parm_offset += sizeof(int); break; case SYS___syscall: - syscall_num = ptrace(PT_READ_D, tid, (caddr_t)parm_offset, 0); parm_offset += sizeof(quad_t); break; } - fsc = alloc_fsc(); - if (fsc == NULL) - return; - fsc->number = syscall_num; - fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ? - NULL : syscallnames[syscall_num]; - if (!fsc->name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", - syscall_num); - } - - if (fsc->name && (trussinfo->flags & FOLLOWFORKS) && - (strcmp(fsc->name, "fork") == 0 || - strcmp(fsc->name, "pdfork") == 0 || - strcmp(fsc->name, "rfork") == 0 || - strcmp(fsc->name, "vfork") == 0)) - trussinfo->curthread->in_fork = 1; - - if (nargs == 0) - return; - - fsc->args = malloc((1 + nargs) * sizeof(unsigned long)); iorequest.piod_op = PIOD_READ_D; iorequest.piod_offs = (void *)parm_offset; - iorequest.piod_addr = fsc->args; - iorequest.piod_len = (1 + nargs) * sizeof(unsigned long); + iorequest.piod_addr = cs->args; + iorequest.piod_len = narg * sizeof(unsigned long); ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); if (iorequest.piod_len == 0) - return; - - sc = NULL; - if (fsc->name) - sc = get_syscall(fsc->name); - if (sc) - fsc->nargs = sc->nargs; - else { -#if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting " - "args to %d\n", fsc->name, nargs); -#endif - fsc->nargs = nargs; - } - - fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *)); - fsc->sc = sc; - - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ - - if (fsc->name) { -#if DEBUG - fprintf(stderr, "syscall %s(", fsc->name); -#endif - for (i = 0; i < fsc->nargs; i++) { -#if DEBUG - fprintf(stderr, "0x%x%s", sc ? - fsc->args[sc->args[i].offset] : fsc->args[i], - i < (fsc->nargs - 1) ? "," : ""); -#endif - if (sc && !(sc->args[i].type & OUT)) { - fsc->s_args[i] = print_arg(&sc->args[i], - fsc->args, 0, trussinfo); - } - } -#if DEBUG - fprintf(stderr, ")\n"); -#endif - } - -#if DEBUG - fprintf(trussinfo->outfile, "\n"); -#endif + return (-1); - trussinfo->curthread->fsc = fsc; + return (0); } -/* - * And when the system call is done, we handle it here. - * Currently, no attempt is made to ensure that the system calls - * match -- this needs to be fixed (and is, in fact, why S_SCX includes - * the system call number instead of, say, an error status). - */ - -long -i386_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) +static int +i386_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp) { struct reg regs; - struct freebsd_syscall *fsc; - struct syscall *sc; lwpid_t tid; - long retval; - int errorp, i; - - if (trussinfo->curthread->fsc == NULL) - return (-1); tid = trussinfo->curthread->tid; - if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return (-1); } - retval = regs.r_eax; - errorp = !!(regs.r_eflags & PSL_C); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - fsc = trussinfo->curthread->fsc; - sc = fsc->sc; - if (!sc) { - for (i = 0; i < fsc->nargs; i++) - asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; + retval[0] = regs.r_eax; + retval[1] = regs.r_edx; + *errorp = !!(regs.r_eflags & PSL_C); + return (0); +} - if (sc->args[i].type & OUT) { - /* - * If an error occurred, then don't bother - * getting the data; it may not be valid. - */ - if (errorp) { - asprintf(&temp, "0x%lx", - fsc->args[sc->args[i].offset]); - } else { - temp = print_arg(&sc->args[i], - fsc->args, retval, trussinfo); - } - fsc->s_args[i] = temp; - } - } - } +static struct procabi i386_fbsd = { + "FreeBSD ELF32", + syscallnames, + nitems(syscallnames), + i386_fetch_args, + i386_fetch_retval +}; - if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 || - strcmp(fsc->name, "exit") == 0)) - trussinfo->curthread->in_syscall = 1; +PROCABI(i386_fbsd); - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ +static struct procabi i386_fbsd_aout = { + "FreeBSD a.out", + syscallnames, + nitems(syscallnames), + i386_fetch_args, + i386_fetch_retval +}; - print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp, - retval, fsc->sc); - free_fsc(fsc); +PROCABI(i386_fbsd_aout); - return (retval); -} diff --git a/usr.bin/truss/i386-linux.c b/usr.bin/truss/i386-linux.c index 6bd9309..fa57af2 100644 --- a/usr.bin/truss/i386-linux.c +++ b/usr.bin/truss/i386-linux.c @@ -29,123 +29,36 @@ * SUCH DAMAGE. */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); -/* - * Linux/i386-specific system call handling. Given how much of this code - * is taken from the freebsd equivalent, I can probably put even more of - * it in support routines that can be used by any personality support. - */ +/* Linux/i386-specific system call handling. */ -#include <sys/types.h> #include <sys/ptrace.h> #include <machine/reg.h> #include <machine/psl.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> #include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> #include "truss.h" -#include "syscall.h" -#include "extern.h" #include "linux_syscalls.h" -static int nsyscalls = nitems(linux_syscallnames); - -/* - * This is what this particular file uses to keep track of a system call. - * It is probably not quite sufficient -- I can probably use the same - * structure for the various syscall personalities, and I also probably - * need to nest system calls (for signal handlers). - * - * 'struct syscall' describes the system call; it may be NULL, however, - * if we don't know about this particular system call yet. - */ -struct linux_syscall { - struct syscall *sc; - const char *name; - int number; - unsigned long args[5]; - int nargs; /* number of arguments -- *not* number of words! */ - char **s_args; /* the printable arguments */ -}; - -static struct linux_syscall * -alloc_fsc(void) -{ - - return (malloc(sizeof(struct linux_syscall))); -} - -/* Clear up and free parts of the fsc structure. */ -static void -free_fsc(struct linux_syscall *fsc) -{ - int i; - - if (fsc->s_args) { - for (i = 0; i < fsc->nargs; i++) - free(fsc->s_args[i]); - free(fsc->s_args); - } - free(fsc); -} - -/* - * Called when a process has entered a system call. nargs is the - * number of words, not number of arguments (a necessary distinction - * in some cases). Note that if the STOPEVENT() code in i386/i386/trap.c - * is ever changed these functions need to keep up. - */ - -void -i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) +static int +i386_linux_fetch_args(struct trussinfo *trussinfo, u_int narg) { struct reg regs; - struct linux_syscall *fsc; - struct syscall *sc; + struct current_syscall *cs; lwpid_t tid; - int i, syscall_num; tid = trussinfo->curthread->tid; - + cs = &trussinfo->curthread->cs; if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; - } - - syscall_num = regs.r_eax; - - fsc = alloc_fsc(); - if (fsc == NULL) - return; - fsc->number = syscall_num; - fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ? - NULL : linux_syscallnames[syscall_num]; - if (!fsc->name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", - syscall_num); + return (-1); } - if (fsc->name && (trussinfo->flags & FOLLOWFORKS) && - (strcmp(fsc->name, "linux_fork") == 0 || - strcmp(fsc->name, "linux_vfork") == 0)) - trussinfo->curthread->in_fork = 1; - - if (nargs == 0) - return; - /* * Linux passes syscall arguments in registers, not * on the stack. Fortunately, we've got access to the @@ -153,60 +66,22 @@ i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) * number of arguments. And what does linux do for syscalls * that have more than five arguments? */ - - fsc->args[0] = regs.r_ebx; - fsc->args[1] = regs.r_ecx; - fsc->args[2] = regs.r_edx; - fsc->args[3] = regs.r_esi; - fsc->args[4] = regs.r_edi; - - sc = get_syscall(fsc->name); - if (sc) - fsc->nargs = sc->nargs; - else { -#if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting " - "args to %d\n", fsc->name, nargs); -#endif - fsc->nargs = nargs; + switch (narg) { + default: + cs->args[5] = regs.r_ebp; /* Unconfirmed */ + case 5: + cs->args[4] = regs.r_edi; + case 4: + cs->args[3] = regs.r_esi; + case 3: + cs->args[2] = regs.r_edx; + case 2: + cs->args[1] = regs.r_ecx; + case 1: + cs->args[0] = regs.r_ebx; } - fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *)); - fsc->sc = sc; - - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ - - if (fsc->name) { -#if DEBUG - fprintf(stderr, "syscall %s(", fsc->name); -#endif - for (i = 0; i < fsc->nargs; i++) { -#if DEBUG - fprintf(stderr, "0x%x%s", sc ? - fsc->args[sc->args[i].offset] : fsc->args[i], - i < (fsc->nargs - 1) ? "," : ""); -#endif - if (sc && !(sc->args[i].type & OUT)) { - fsc->s_args[i] = print_arg(&sc->args[i], - fsc->args, 0, trussinfo); - } - } -#if DEBUG - fprintf(stderr, ")\n"); -#endif - } - -#if DEBUG - fprintf(trussinfo->outfile, "\n"); -#endif - - trussinfo->curthread->fsc = fsc; + return (0); } /* @@ -224,82 +99,42 @@ static const int bsd_to_linux_errno[] = { -6, }; -long -i386_linux_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) +static int +i386_linux_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp) { struct reg regs; - struct linux_syscall *fsc; - struct syscall *sc; lwpid_t tid; - long retval; - int errorp, i; - - if (trussinfo->curthread->fsc == NULL) - return (-1); + size_t i; tid = trussinfo->curthread->tid; - if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return (-1); } - retval = regs.r_eax; - errorp = !!(regs.r_eflags & PSL_C); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ + retval[0] = regs.r_eax; + retval[1] = regs.r_edx; + *errorp = !!(regs.r_eflags & PSL_C); - fsc = trussinfo->curthread->fsc; - sc = fsc->sc; - if (!sc) { - for (i = 0; i < fsc->nargs; i++) - asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - - if (sc->args[i].type & OUT) { - /* - * If an error occurred, then don't bother - * getting the data; it may not be valid. - */ - if (errorp) { - asprintf(&temp, "0x%lx", - fsc->args[sc->args[i].offset]); - } else { - temp = print_arg(&sc->args[i], - fsc->args, retval, trussinfo); - } - fsc->s_args[i] = temp; + if (*errorp) { + for (i = 0; i < nitems(bsd_to_linux_errno); i++) { + if (retval[0] == bsd_to_linux_errno[i]) { + retval[0] = i; + return (0); } } - } - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ - if (errorp) { - for (i = 0; (size_t)i < nitems(bsd_to_linux_errno); i++) { - if (retval == bsd_to_linux_errno[i]) - break; - } + /* XXX: How to handle unknown errors? */ } + return (0); +} - if (fsc->name != NULL && (strcmp(fsc->name, "linux_execve") == 0 || - strcmp(fsc->name, "exit") == 0)) - trussinfo->curthread->in_syscall = 1; - - print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp, - errorp ? i : retval, fsc->sc); - free_fsc(fsc); +static struct procabi i386_linux = { + "Linux ELF32", + linux_syscallnames, + nitems(linux_syscallnames), + i386_linux_fetch_args, + i386_linux_fetch_retval +}; - return (retval); -} +PROCABI(i386_linux); diff --git a/usr.bin/truss/main.c b/usr.bin/truss/main.c index 84ae313..55fdeda 100644 --- a/usr.bin/truss/main.c +++ b/usr.bin/truss/main.c @@ -38,21 +38,12 @@ __FBSDID("$FreeBSD$"); * do a lot of the work :). */ -#include <sys/param.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <sys/sysctl.h> -#include <sys/wait.h> +#include <sys/ptrace.h> #include <err.h> -#include <errno.h> -#include <fcntl.h> #include <signal.h> -#include <stdint.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> #include <time.h> #include <unistd.h> @@ -60,8 +51,6 @@ __FBSDID("$FreeBSD$"); #include "extern.h" #include "syscall.h" -#define MAXARGS 6 - static void usage(void) { @@ -71,82 +60,6 @@ usage(void) exit(1); } -/* - * WARNING! "FreeBSD a.out" must be first, or set_etype will not - * work correctly. - */ -static struct ex_types { - const char *type; - void (*enter_syscall)(struct trussinfo *, int); - long (*exit_syscall)(struct trussinfo *, int); -} ex_types[] = { -#ifdef __arm__ - { "FreeBSD ELF32", arm_syscall_entry, arm_syscall_exit }, -#endif -#ifdef __amd64__ - { "FreeBSD ELF64", amd64_syscall_entry, amd64_syscall_exit }, - { "FreeBSD ELF32", amd64_fbsd32_syscall_entry, amd64_fbsd32_syscall_exit }, - { "Linux ELF32", amd64_linux32_syscall_entry, amd64_linux32_syscall_exit }, -#endif -#ifdef __i386__ - { "FreeBSD a.out", i386_syscall_entry, i386_syscall_exit }, - { "FreeBSD ELF", i386_syscall_entry, i386_syscall_exit }, - { "FreeBSD ELF32", i386_syscall_entry, i386_syscall_exit }, - { "Linux ELF", i386_linux_syscall_entry, i386_linux_syscall_exit }, -#endif -#ifdef __powerpc__ - { "FreeBSD ELF", powerpc_syscall_entry, powerpc_syscall_exit }, - { "FreeBSD ELF32", powerpc_syscall_entry, powerpc_syscall_exit }, -#ifdef __powerpc64__ - { "FreeBSD ELF64", powerpc64_syscall_entry, powerpc64_syscall_exit }, -#endif -#endif -#ifdef __sparc64__ - { "FreeBSD ELF64", sparc64_syscall_entry, sparc64_syscall_exit }, -#endif -#ifdef __mips__ - { "FreeBSD ELF", mips_syscall_entry, mips_syscall_exit }, - { "FreeBSD ELF32", mips_syscall_entry, mips_syscall_exit }, - { "FreeBSD ELF64", mips_syscall_entry, mips_syscall_exit }, // XXX -#endif - { 0, 0, 0 }, -}; - -/* - * Set the execution type. This is called after every exec, and when - * a process is first monitored. - */ - -static struct ex_types * -set_etype(struct trussinfo *trussinfo) -{ - struct ex_types *funcs; - size_t len; - int error; - int mib[4]; - char progt[32]; - - len = sizeof(progt); - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_SV_NAME; - mib[3] = trussinfo->pid; - error = sysctl(mib, 4, progt, &len, NULL, 0); - if (error != 0) - err(2, "can not get etype"); - - for (funcs = ex_types; funcs->type; funcs++) - if (strcmp(funcs->type, progt) == 0) - break; - - if (funcs->type == NULL) { - funcs = &ex_types[0]; - warn("execution type %s is not supported -- using %s", - progt, funcs->type); - } - return (funcs); -} - char * strsig(int sig) { @@ -162,37 +75,32 @@ strsig(int sig) int main(int ac, char **av) { - struct timespec timediff; struct sigaction sa; - struct ex_types *funcs; struct trussinfo *trussinfo; char *fname; - char *signame; char **command; - pid_t childpid; - int c, initial_open, status; + pid_t pid; + int c; fname = NULL; - initial_open = 1; /* Initialize the trussinfo struct */ trussinfo = (struct trussinfo *)calloc(1, sizeof(struct trussinfo)); if (trussinfo == NULL) errx(1, "calloc() failed"); + pid = 0; trussinfo->outfile = stderr; trussinfo->strsize = 32; - trussinfo->pr_why = S_NONE; trussinfo->curthread = NULL; - SLIST_INIT(&trussinfo->threadlist); + LIST_INIT(&trussinfo->proclist); while ((c = getopt(ac, av, "p:o:facedDs:S")) != -1) { switch (c) { case 'p': /* specified pid */ - trussinfo->pid = atoi(optarg); + pid = atoi(optarg); /* make sure i don't trace me */ - if (trussinfo->pid == getpid()) { - fprintf(stderr, "attempt to grab self.\n"); - exit(2); + if (pid == getpid()) { + errx(2, "attempt to grab self."); } break; case 'f': /* Follow fork()'s */ @@ -228,8 +136,8 @@ main(int ac, char **av) } ac -= optind; av += optind; - if ((trussinfo->pid == 0 && ac == 0) || - (trussinfo->pid != 0 && ac != 0)) + if ((pid == 0 && ac == 0) || + (pid != 0 && ac != 0)) usage(); if (fname != NULL) { /* Use output file */ @@ -247,10 +155,10 @@ main(int ac, char **av) * exit. If, however, we are examining an already-running process, * then we restore the event mask on these same signals. */ - - if (trussinfo->pid == 0) { /* Start a command ourselves */ + if (pid == 0) { + /* Start a command ourselves */ command = av; - trussinfo->pid = setup_and_wait(command); + setup_and_wait(trussinfo, command); signal(SIGINT, SIG_IGN); signal(SIGTERM, SIG_IGN); signal(SIGQUIT, SIG_IGN); @@ -261,119 +169,37 @@ main(int ac, char **av) sigaction(SIGINT, &sa, NULL); sigaction(SIGQUIT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); - start_tracing(trussinfo->pid); + start_tracing(trussinfo, pid); } - /* * At this point, if we started the process, it is stopped waiting to * be woken up, either in exit() or in execve(). */ + if (LIST_FIRST(&trussinfo->proclist)->abi == NULL) { + /* + * If we are not able to handle this ABI, detach from the + * process and exit. If we just created a new process to + * run a command, kill the new process rather than letting + * it run untraced. + */ + if (pid == 0) + kill(LIST_FIRST(&trussinfo->proclist)->pid, SIGKILL); + ptrace(PT_DETACH, LIST_FIRST(&trussinfo->proclist)->pid, NULL, + 0); + return (1); + } + ptrace(PT_SYSCALL, LIST_FIRST(&trussinfo->proclist)->pid, (caddr_t)1, + 0); -START_TRACE: - funcs = set_etype(trussinfo); - - initial_open = 0; /* * At this point, it's a simple loop, waiting for the process to * stop, finding out why, printing out why, and then continuing it. * All of the grunt work is done in the support routines. */ - clock_gettime(CLOCK_REALTIME, &trussinfo->start_time); - do { - waitevent(trussinfo); - - switch (trussinfo->pr_why) { - case S_SCE: - funcs->enter_syscall(trussinfo, MAXARGS); - clock_gettime(CLOCK_REALTIME, - &trussinfo->curthread->before); - break; - case S_SCX: - clock_gettime(CLOCK_REALTIME, - &trussinfo->curthread->after); - - if (trussinfo->curthread->in_fork && - (trussinfo->flags & FOLLOWFORKS)) { - trussinfo->curthread->in_fork = 0; - childpid = funcs->exit_syscall(trussinfo, - trussinfo->pr_data); - - /* - * Fork a new copy of ourself to trace - * the child of the original traced - * process. - */ - if (fork() == 0) { - trussinfo->pid = childpid; - start_tracing(trussinfo->pid); - goto START_TRACE; - } - break; - } - funcs->exit_syscall(trussinfo, MAXARGS); - break; - case S_SIG: - if (trussinfo->flags & NOSIGS) - break; - if (trussinfo->flags & FOLLOWFORKS) - fprintf(trussinfo->outfile, "%5d: ", - trussinfo->pid); - if (trussinfo->flags & ABSOLUTETIMESTAMPS) { - timespecsubt(&trussinfo->curthread->after, - &trussinfo->start_time, &timediff); - fprintf(trussinfo->outfile, "%jd.%09ld ", - (intmax_t)timediff.tv_sec, - timediff.tv_nsec); - } - if (trussinfo->flags & RELATIVETIMESTAMPS) { - timespecsubt(&trussinfo->curthread->after, - &trussinfo->curthread->before, &timediff); - fprintf(trussinfo->outfile, "%jd.%09ld ", - (intmax_t)timediff.tv_sec, - timediff.tv_nsec); - } - signame = strsig(trussinfo->pr_data); - fprintf(trussinfo->outfile, - "SIGNAL %u (%s)\n", trussinfo->pr_data, - signame == NULL ? "?" : signame); - break; - case S_EXIT: - if (trussinfo->flags & COUNTONLY) - break; - if (trussinfo->flags & FOLLOWFORKS) - fprintf(trussinfo->outfile, "%5d: ", - trussinfo->pid); - if (trussinfo->flags & ABSOLUTETIMESTAMPS) { - timespecsubt(&trussinfo->curthread->after, - &trussinfo->start_time, &timediff); - fprintf(trussinfo->outfile, "%jd.%09ld ", - (intmax_t)timediff.tv_sec, - timediff.tv_nsec); - } - if (trussinfo->flags & RELATIVETIMESTAMPS) { - timespecsubt(&trussinfo->curthread->after, - &trussinfo->curthread->before, &timediff); - fprintf(trussinfo->outfile, "%jd.%09ld ", - (intmax_t)timediff.tv_sec, - timediff.tv_nsec); - } - fprintf(trussinfo->outfile, - "process exit, rval = %u\n", trussinfo->pr_data); - break; - default: - break; - } - } while (trussinfo->pr_why != S_EXIT && - trussinfo->pr_why != S_DETACHED); - - if (trussinfo->flags & FOLLOWFORKS) { - do { - childpid = wait(&status); - } while (childpid != -1); - } + eventloop(trussinfo); if (trussinfo->flags & COUNTONLY) print_summary(trussinfo); diff --git a/usr.bin/truss/mips-fbsd.c b/usr.bin/truss/mips-fbsd.c index d45241a..d488b7e 100644 --- a/usr.bin/truss/mips-fbsd.c +++ b/usr.bin/truss/mips-fbsd.c @@ -29,318 +29,113 @@ * SUCH DAMAGE. */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); -/* - * FreeBSD/sparc64-specific system call handling. This is probably the most - * complex part of the entire truss program, although I've got lots of - * it handled relatively cleanly now. The system call names are generated - * automatically, thanks to /usr/src/sys/kern/syscalls.master. The - * names used for the various structures are confusing, I sadly admit. - * - * This file is almost nothing more than a slightly-edited i386-fbsd.c. - */ +/* FreeBSD/mips-specific system call handling. */ -#include <sys/types.h> #include <sys/ptrace.h> #include <sys/syscall.h> #include <machine/frame.h> #include <machine/reg.h> -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> -#include <stddef.h> #include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> #include "truss.h" -#include "syscall.h" -#include "extern.h" #include "syscalls.h" -static int nsyscalls = nitems(syscallnames); - -/* - * This is what this particular file uses to keep track of a system call. - * It is probably not quite sufficient -- I can probably use the same - * structure for the various syscall personalities, and I also probably - * need to nest system calls (for signal handlers). - * - * 'struct syscall' describes the system call; it may be NULL, however, - * if we don't know about this particular system call yet. - */ -struct freebsd_syscall { - struct syscall *sc; - const char *name; - int number; - unsigned long *args; - int nargs; /* number of arguments -- *not* number of words! */ - char **s_args; /* the printable arguments */ -}; - -static struct freebsd_syscall * -alloc_fsc(void) -{ - - return (malloc(sizeof(struct freebsd_syscall))); -} - -/* Clear up and free parts of the fsc structure. */ -static void -free_fsc(struct freebsd_syscall *fsc) -{ - int i; - - free(fsc->args); - if (fsc->s_args) { - for (i = 0; i < fsc->nargs; i++) - free(fsc->s_args[i]); - free(fsc->s_args); - } - free(fsc); -} - -/* - * Called when a process has entered a system call. nargs is the - * number of words, not number of arguments (a necessary distinction - * in some cases). Note that if the STOPEVENT() code in sparc64/sparc64/trap.c - * is ever changed these functions need to keep up. - */ - -void -mips_syscall_entry(struct trussinfo *trussinfo, int nargs) +static int +mips_fetch_args(struct trussinfo *trussinfo, u_int narg) { struct ptrace_io_desc iorequest; struct reg regs; - struct freebsd_syscall *fsc; - struct syscall *sc; + struct current_syscall *cs; lwpid_t tid; - int i, syscall_num; - int indir; /* indirect system call */ + u_int i, reg; tid = trussinfo->curthread->tid; - + cs = &trussinfo->curthread->cs; if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; - } - - indir = 0; - syscall_num = regs.r_regs[V0]; - if (syscall_num == SYS_syscall) { - indir = 1; - syscall_num = regs.r_regs[A0]; + return (-1); } - fsc = alloc_fsc(); - if (fsc == NULL) - return; - fsc->number = syscall_num; - fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ? - NULL : syscallnames[syscall_num]; - if (!fsc->name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", - syscall_num); + /* + * FreeBSD has two special kinds of system call redirections -- + * SYS_syscall, and SYS___syscall. The former is the old syscall() + * routine, basically; the latter is for quad-aligned arguments. + * + * The system call argument count and code from ptrace() already + * account for these, but we need to skip over the first argument. + */ + reg = A0; + switch (regs.r_regs[V0]) { + case SYS_syscall: + reg = A1; + break; + case SYS___syscall: +#if defined(__mips_n32) || defined(__mips_n64) + reg = A1; +#else + reg = A2; +#endif + break; } - if (fsc->name && (trussinfo->flags & FOLLOWFORKS) && - (strcmp(fsc->name, "fork") == 0 || - strcmp(fsc->name, "pdfork") == 0 || - strcmp(fsc->name, "rfork") == 0 || - strcmp(fsc->name, "vfork") == 0)) - trussinfo->curthread->in_fork = 1; - - if (nargs == 0) - return; - - fsc->args = malloc((1 + nargs) * sizeof(unsigned long)); -#if 0 // XXX - iorequest.piod_op = PIOD_READ_D; - iorequest.piod_offs = (void *)parm_offset; - iorequest.piod_addr = fsc->args; - iorequest.piod_len = (1 + nargs) * sizeof(unsigned long); - ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); - if (iorequest.piod_len == 0) - return; +#if defined(__mips_n32) || defined(__mips_n64) +#define MAXREG A7 #else - iorequest.piod_op = PIOD_READ_D; +#define MAXREG A3 #endif - switch (nargs) { - default: - /* - * The OS doesn't seem to allow more than 10 words of - * parameters (yay!). So we shouldn't be here. - */ - warn("More than 10 words (%d) of arguments!\n", nargs); - break; - case 10: - case 9: - case 8: - case 7: - case 6: - case 5: - /* - * If there are 7-10 words of arguments, they are placed - * on the stack, as is normal for other processors. - * The fall-through for all of these is deliberate!!! - */ - // XXX BAD constant used here + for (i = 0; i < narg && reg <= MAXREG; i++, reg++) + cs->args[i] = regs.r_regs[reg]; + if (narg > i) { iorequest.piod_op = PIOD_READ_D; - iorequest.piod_offs = (void *)(regs.r_regs[SP] + - 4 * sizeof(uint32_t)); - iorequest.piod_addr = &fsc->args[4]; - iorequest.piod_len = (nargs - 4) * sizeof(fsc->args[0]); + iorequest.piod_offs = (void *)((uintptr_t)regs.r_regs[SP] + + 4 * sizeof(cs->args[0])); + iorequest.piod_addr = &cs->args[i]; + iorequest.piod_len = (narg - i) * sizeof(cs->args[0]); ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); if (iorequest.piod_len == 0) - return; - case 4: fsc->args[3] = regs.r_regs[A3]; - case 3: fsc->args[2] = regs.r_regs[A2]; - case 2: fsc->args[1] = regs.r_regs[A1]; - case 1: fsc->args[0] = regs.r_regs[A0]; - case 0: break; - } - if (indir) { - memmove(&fsc->args[0], &fsc->args[1], - (nargs - 1) * sizeof(fsc->args[0])); + return (-1); } - sc = get_syscall(fsc->name); - if (sc) - fsc->nargs = sc->nargs; - else { -#if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting " - "args to %d\n", fsc->name, nargs); -#endif - fsc->nargs = nargs; - } - - fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *)); - fsc->sc = sc; - - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ - - if (fsc->name) { -#if DEBUG - fprintf(stderr, "syscall %s(", fsc->name); -#endif - for (i = 0; i < fsc->nargs; i++) { -#if DEBUG - fprintf(stderr, "0x%x%s", sc ? - fsc->args[sc->args[i].offset] : fsc->args[i], - i < (fsc->nargs - 1) ? "," : ""); -#endif - if (sc && !(sc->args[i].type & OUT)) { - fsc->s_args[i] = print_arg(&sc->args[i], - fsc->args, 0, trussinfo); - } - } -#if DEBUG - fprintf(stderr, ")\n"); -#endif - } - -#if DEBUG - fprintf(trussinfo->outfile, "\n"); -#endif - - trussinfo->curthread->fsc = fsc; + return (0); } -/* - * And when the system call is done, we handle it here. - * Currently, no attempt is made to ensure that the system calls - * match -- this needs to be fixed (and is, in fact, why S_SCX includes - * the system call number instead of, say, an error status). - */ - -long -mips_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) +static int +mips_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp) { struct reg regs; - struct freebsd_syscall *fsc; - struct syscall *sc; lwpid_t tid; - long retval; - int errorp, i; - - if (trussinfo->curthread->fsc == NULL) - return (-1); tid = trussinfo->curthread->tid; - if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { - fprintf(trussinfo->outfile, "\n"); + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return (-1); } - retval = regs.r_regs[V0]; - errorp = !!regs.r_regs[A3]; - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - fsc = trussinfo->curthread->fsc; - sc = fsc->sc; - if (!sc) { - for (i = 0; i < fsc->nargs; i++) - asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - - if (sc->args[i].type & OUT) { - /* - * If an error occurred, then don't bother - * getting the data; it may not be valid. - */ - if (errorp) { - asprintf(&temp, "0x%lx", - fsc->args[sc->args[i].offset]); - } else { - temp = print_arg(&sc->args[i], - fsc->args, retval, trussinfo); - } - fsc->s_args[i] = temp; - } - } - } - - if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 || - strcmp(fsc->name, "exit") == 0)) - trussinfo->curthread->in_syscall = 1; + /* XXX: Does not have special handling for __syscall(). */ + retval[0] = regs.r_regs[V0]; + retval[1] = regs.r_regs[V1]; + *errorp = !!regs.r_regs[A3]; + return (0); +} - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ - print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp, - retval, fsc->sc); - free_fsc(fsc); +static struct procabi mips_fbsd = { +#ifdef __mips_n64 + "FreeBSD ELF64", +#else + "FreeBSD ELF32", +#endif + syscallnames, + nitems(syscallnames), + mips_fetch_args, + mips_fetch_retval +}; - return (retval); -} +PROCABI(mips_fbsd); diff --git a/usr.bin/truss/powerpc-fbsd.c b/usr.bin/truss/powerpc-fbsd.c index cdbd133..4a11459 100644 --- a/usr.bin/truss/powerpc-fbsd.c +++ b/usr.bin/truss/powerpc-fbsd.c @@ -25,41 +25,20 @@ * SUCH DAMAGE. */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); -/* - * FreeBSD/powerpc-specific system call handling. This is probably the most - * complex part of the entire truss program, although I've got lots of - * it handled relatively cleanly now. The system call names are generated - * automatically, thanks to /usr/src/sys/kern/syscalls.master. The - * names used for the various structures are confusing, I sadly admit. - * - * This file is almost nothing more than a slightly-edited i386-fbsd.c. - */ +/* FreeBSD/powerpc-specific system call handling. */ -#include <sys/types.h> #include <sys/ptrace.h> #include <sys/syscall.h> #include <machine/reg.h> #include <machine/frame.h> -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> #include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> #include "truss.h" -#include "syscall.h" -#include "extern.h" #ifdef __powerpc64__ /* 32-bit compatibility */ #include "freebsd32_syscalls.h" @@ -68,264 +47,104 @@ static const char rcsid[] = #include "syscalls.h" #endif -static int nsyscalls = nitems(syscallnames); - -/* - * This is what this particular file uses to keep track of a system call. - * It is probably not quite sufficient -- I can probably use the same - * structure for the various syscall personalities, and I also probably - * need to nest system calls (for signal handlers). - * - * 'struct syscall' describes the system call; it may be NULL, however, - * if we don't know about this particular system call yet. - */ -struct freebsd_syscall { - struct syscall *sc; - const char *name; - int number; - unsigned long *args; - int nargs; /* number of arguments -- *not* number of words! */ - char **s_args; /* the printable arguments */ -}; - -static struct freebsd_syscall * -alloc_fsc(void) -{ - - return (malloc(sizeof(struct freebsd_syscall))); -} - -/* Clear up and free parts of the fsc structure. */ -static void -free_fsc(struct freebsd_syscall *fsc) -{ - int i; - - free(fsc->args); - if (fsc->s_args) { - for (i = 0; i < fsc->nargs; i++) - free(fsc->s_args[i]); - free(fsc->s_args); - } - free(fsc); -} - -/* - * Called when a process has entered a system call. nargs is the - * number of words, not number of arguments (a necessary distinction - * in some cases). Note that if the STOPEVENT() code in powerpc/powerpc/trap.c - * is ever changed these functions need to keep up. - */ - -void -powerpc_syscall_entry(struct trussinfo *trussinfo, int nargs) +static int +powerpc_fetch_args(struct trussinfo *trussinfo, u_int narg) { struct ptrace_io_desc iorequest; struct reg regs; - struct freebsd_syscall *fsc; - struct syscall *sc; - void *args; + struct current_syscall *cs; lwpid_t tid; - int i, regargs, syscall_num; - - /* Account for a 64-bit argument with corresponding alignment. */ - nargs += 2; + u_int i, reg; tid = trussinfo->curthread->tid; - + cs = &trussinfo->curthread->cs; if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; + return (-1); } /* - * FreeBSD has two special kinds of system call redirctions -- + * FreeBSD has two special kinds of system call redirections -- * SYS_syscall, and SYS___syscall. The former is the old syscall() * routine, basically; the latter is for quad-aligned arguments. + * + * The system call argument count and code from ptrace() already + * account for these, but we need to skip over the first argument. */ - regargs = NARGREG; - syscall_num = regs.fixreg[0]; - args = ®s.fixreg[3]; - if (syscall_num == SYS_syscall) { - args = ®s.fixreg[4]; - regargs -= 1; - syscall_num = regs.fixreg[3]; - } else if (syscall_num == SYS___syscall) { - args = ®s.fixreg[5]; - regargs -= 2; - syscall_num = regs.fixreg[4]; + reg = 0; + switch (regs.fixreg[0]) { + case SYS_syscall: + reg += 1; + break; + case SYS___syscall: + reg += 2; + break; } - fsc = alloc_fsc(); - if (fsc == NULL) - return; - fsc->number = syscall_num; - fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ? - NULL : syscallnames[syscall_num]; - if (!fsc->name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", - syscall_num); + for (i = 0; i < narg && reg < NARGREG; i++, reg++) { +#ifdef __powerpc64__ + cs->args[i] = regs.fixreg[FIRSTARG + reg] & 0xffffffff; +#else + cs->args[i] = regs.fixreg[FIRSTARG + reg]; +#endif } + if (narg > i) { +#ifdef __powerpc64__ + uint32_t args32[narg - i]; + u_int j; - if (fsc->name && (trussinfo->flags & FOLLOWFORKS) && - (strcmp(fsc->name, "fork") == 0 || - strcmp(fsc->name, "pdfork") == 0 || - strcmp(fsc->name, "rfork") == 0 || - strcmp(fsc->name, "vfork") == 0)) - trussinfo->curthread->in_fork = 1; - - if (nargs == 0) - return; - - fsc->args = malloc((1 + nargs) * sizeof(unsigned long)); - - if (nargs > regargs) { - memmove(&fsc->args[0], args, regargs * sizeof(fsc->args[0])); - +#endif iorequest.piod_op = PIOD_READ_D; iorequest.piod_offs = (void *)(regs.fixreg[1] + 8); - iorequest.piod_addr = &fsc->args[regargs]; - iorequest.piod_len = (nargs - regargs) * sizeof(fsc->args[0]); +#ifdef __powerpc64__ + iorequest.piod_addr = args32; + iorequest.piod_len = sizeof(args32); +#else + iorequest.piod_addr = &cs->args[i]; + iorequest.piod_len = (narg - i) * sizeof(cs->args[0]); +#endif ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); if (iorequest.piod_len == 0) - return; - } else - memmove(&fsc->args[0], args, nargs * sizeof(fsc->args[0])); - - sc = get_syscall(fsc->name); - if (sc) - fsc->nargs = sc->nargs; - else { -#if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting " - "args to %d\n", fsc->name, nargs); + return (-1); +#ifdef __powerpc64__ + for (j = 0; j < narg - i; j++) + cs->args[i + j] = args32[j]; #endif - fsc->nargs = nargs; } - fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *)); - fsc->sc = sc; - - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ - - if (fsc->name) { -#if DEBUG - fprintf(stderr, "syscall %s(", fsc->name); -#endif - for (i = 0; i < fsc->nargs; i++) { -#if DEBUG - fprintf(stderr, "0x%x%s", sc ? - fsc->args[sc->args[i].offset] : fsc->args[i], - i < (fsc->nargs - 1) ? "," : ""); -#endif - if (sc && !(sc->args[i].type & OUT)) { - fsc->s_args[i] = print_arg(&sc->args[i], - fsc->args, 0, trussinfo); - } - } -#if DEBUG - fprintf(stderr, ")\n"); -#endif - } - -#if DEBUG - fprintf(trussinfo->outfile, "\n"); -#endif - - trussinfo->curthread->fsc = fsc; + return (0); } -/* - * And when the system call is done, we handle it here. - * Currently, no attempt is made to ensure that the system calls - * match -- this needs to be fixed (and is, in fact, why S_SCX includes - * the system call number instead of, say, an error status). - */ - -long -powerpc_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) +static int +powerpc_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp) { struct reg regs; - struct freebsd_syscall *fsc; - struct syscall *sc; lwpid_t tid; - long retval; - int errorp, i; - - if (trussinfo->curthread->fsc == NULL) - return (-1); tid = trussinfo->curthread->tid; - if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { - fprintf(trussinfo->outfile, "\n"); + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return (-1); } - retval = regs.fixreg[3]; - errorp = !!(regs.cr & 0x10000000); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - fsc = trussinfo->curthread->fsc; - sc = fsc->sc; - if (!sc) { - for (i = 0; i < fsc->nargs; i++) - asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]); - } else { - /* - * On 32-bit big-endian, the low word of a 64-bit return is - * in the greater address. Switch to this. XXX note that - * print_syscall_ret can't handle 64-bit return values (llseek) - */ - if (sc->ret_type == 2) - retval = regs.fixreg[4]; - - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - - if (sc->args[i].type & OUT) { - /* - * If an error occurred, then don't bother - * getting the data; it may not be valid. - */ - if (errorp) { - asprintf(&temp, "0x%lx", - fsc->args[sc->args[i].offset]); - } else { - temp = print_arg(&sc->args[i], - fsc->args, retval, trussinfo); - } - fsc->s_args[i] = temp; - } - } - } - - if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 || - strcmp(fsc->name, "exit") == 0)) - trussinfo->curthread->in_syscall = 1; - - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ + /* XXX: Does not have fixup for __syscall(). */ +#ifdef __powerpc64__ + retval[0] = regs.fixreg[3] & 0xffffffff; + retval[1] = regs.fixreg[4] & 0xffffffff; +#else + retval[0] = regs.fixreg[3]; + retval[1] = regs.fixreg[4]; +#endif + *errorp = !!(regs.cr & 0x10000000); + return (0); +} - print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp, - retval, fsc->sc); - free_fsc(fsc); +static struct procabi powerpc_fbsd = { + "FreeBSD ELF32", + syscallnames, + nitems(syscallnames), + powerpc_fetch_args, + powerpc_fetch_retval +}; - return (retval); -} +PROCABI(powerpc_fbsd); diff --git a/usr.bin/truss/powerpc64-fbsd.c b/usr.bin/truss/powerpc64-fbsd.c index 1f50429..5ca5c22 100644 --- a/usr.bin/truss/powerpc64-fbsd.c +++ b/usr.bin/truss/powerpc64-fbsd.c @@ -25,287 +25,94 @@ * SUCH DAMAGE. */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); -/* - * FreeBSD/powerpc-specific system call handling. This is probably the most - * complex part of the entire truss program, although I've got lots of - * it handled relatively cleanly now. The system call names are generated - * automatically, thanks to /usr/src/sys/kern/syscalls.master. The - * names used for the various structures are confusing, I sadly admit. - * - * This file is almost nothing more than a slightly-edited i386-fbsd.c. - */ +/* FreeBSD/powerpc64-specific system call handling. */ -#include <sys/types.h> #include <sys/ptrace.h> #include <sys/syscall.h> #include <machine/reg.h> #include <machine/frame.h> -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> #include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> #include "truss.h" -#include "syscall.h" -#include "extern.h" #include "syscalls.h" -static int nsyscalls = nitems(syscallnames); - -/* - * This is what this particular file uses to keep track of a system call. - * It is probably not quite sufficient -- I can probably use the same - * structure for the various syscall personalities, and I also probably - * need to nest system calls (for signal handlers). - * - * 'struct syscall' describes the system call; it may be NULL, however, - * if we don't know about this particular system call yet. - */ -struct freebsd_syscall { - struct syscall *sc; - const char *name; - int number; - unsigned long *args; - int nargs; /* number of arguments -- *not* number of words! */ - char **s_args; /* the printable arguments */ -}; - -static struct freebsd_syscall * -alloc_fsc(void) -{ - - return (malloc(sizeof(struct freebsd_syscall))); -} - -/* Clear up and free parts of the fsc structure. */ -static void -free_fsc(struct freebsd_syscall *fsc) -{ - int i; - - free(fsc->args); - if (fsc->s_args) { - for (i = 0; i < fsc->nargs; i++) - free(fsc->s_args[i]); - free(fsc->s_args); - } - free(fsc); -} - -/* - * Called when a process has entered a system call. nargs is the - * number of words, not number of arguments (a necessary distinction - * in some cases). Note that if the STOPEVENT() code in powerpc/powerpc/trap.c - * is ever changed these functions need to keep up. - */ - -void -powerpc64_syscall_entry(struct trussinfo *trussinfo, int nargs) +static int +powerpc64_fetch_args(struct trussinfo *trussinfo, u_int narg) { struct ptrace_io_desc iorequest; struct reg regs; - struct freebsd_syscall *fsc; - struct syscall *sc; - void *args; + struct current_syscall *cs; lwpid_t tid; - int i, regargs, syscall_num; + u_int i, reg; tid = trussinfo->curthread->tid; - + cs = &trussinfo->curthread->cs; if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; + return (-1); } /* - * FreeBSD has two special kinds of system call redirctions -- + * FreeBSD has two special kinds of system call redirections -- * SYS_syscall, and SYS___syscall. The former is the old syscall() * routine, basically; the latter is for quad-aligned arguments. + * + * The system call argument count and code from ptrace() already + * account for these, but we need to skip over the first argument. */ - regargs = NARGREG; - syscall_num = regs.fixreg[0]; - args = ®s.fixreg[3]; - if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) { - args = ®s.fixreg[4]; - regargs -= 1; - syscall_num = regs.fixreg[3]; - } - - fsc = alloc_fsc(); - if (fsc == NULL) - return; - fsc->number = syscall_num; - fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ? - NULL : syscallnames[syscall_num]; - if (!fsc->name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", - syscall_num); + reg = 0; + switch (regs.fixreg[0]) { + case SYS_syscall: + case SYS___syscall: + reg += 1; + break; } - if (fsc->name && (trussinfo->flags & FOLLOWFORKS) && - (strcmp(fsc->name, "fork") == 0 || - strcmp(fsc->name, "pdfork") == 0 || - strcmp(fsc->name, "rfork") == 0 || - strcmp(fsc->name, "vfork") == 0)) - trussinfo->curthread->in_fork = 1; - - if (nargs == 0) - return; - - fsc->args = malloc((1 + nargs) * sizeof(unsigned long)); - - if (nargs > regargs) { - memmove(&fsc->args[0], args, regargs * sizeof(fsc->args[0])); - + for (i = 0; i < narg && reg < NARGREG; i++, reg++) + cs->args[i] = regs.fixreg[FIRSTARG + reg]; + if (narg > i) { iorequest.piod_op = PIOD_READ_D; iorequest.piod_offs = (void *)(regs.fixreg[1] + 48); - iorequest.piod_addr = &fsc->args[regargs]; - iorequest.piod_len = (nargs - regargs) * sizeof(fsc->args[0]); + iorequest.piod_addr = &cs->args[i]; + iorequest.piod_len = (narg - i) * sizeof(cs->args[0]); ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); if (iorequest.piod_len == 0) - return; - } else - memmove(&fsc->args[0], args, nargs * sizeof(fsc->args[0])); - - sc = get_syscall(fsc->name); - if (sc) - fsc->nargs = sc->nargs; - else { -#if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting " - "args to %d\n", fsc->name, nargs); -#endif - fsc->nargs = nargs; - } - - fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *)); - fsc->sc = sc; - - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ - - if (fsc->name) { -#if DEBUG - fprintf(stderr, "syscall %s(", fsc->name); -#endif - for (i = 0; i < fsc->nargs; i++) { -#if DEBUG - fprintf(stderr, "0x%x%s", sc ? - fsc->args[sc->args[i].offset] : fsc->args[i], - i < (fsc->nargs - 1) ? "," : ""); -#endif - if (sc && !(sc->args[i].type & OUT)) { - fsc->s_args[i] = print_arg(&sc->args[i], - fsc->args, 0, trussinfo); - } - } -#if DEBUG - fprintf(stderr, ")\n"); -#endif + return (-1); } -#if DEBUG - fprintf(trussinfo->outfile, "\n"); -#endif - - trussinfo->curthread->fsc = fsc; + return (0); } -/* - * And when the system call is done, we handle it here. - * Currently, no attempt is made to ensure that the system calls - * match -- this needs to be fixed (and is, in fact, why S_SCX includes - * the system call number instead of, say, an error status). - */ - -long -powerpc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) +static int +powerpc64_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp) { struct reg regs; - struct freebsd_syscall *fsc; - struct syscall *sc; lwpid_t tid; - long retval; - int errorp, i; - - if (trussinfo->curthread->fsc == NULL) - return (-1); tid = trussinfo->curthread->tid; - if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { - fprintf(trussinfo->outfile, "\n"); + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return (-1); } - retval = regs.fixreg[3]; - errorp = !!(regs.cr & 0x10000000); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - fsc = trussinfo->curthread->fsc; - sc = fsc->sc; - if (!sc) { - for (i = 0; i < fsc->nargs; i++) - asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - - if (sc->args[i].type & OUT) { - /* - * If an error occurred, then don't bother - * getting the data; it may not be valid. - */ - if (errorp) { - asprintf(&temp, "0x%lx", - fsc->args[sc->args[i].offset]); - } else { - temp = print_arg(&sc->args[i], - fsc->args, retval, trussinfo); - } - fsc->s_args[i] = temp; - } - } - } - - if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 || - strcmp(fsc->name, "exit") == 0)) - trussinfo->curthread->in_syscall = 1; - - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ + retval[0] = regs.fixreg[3]; + retval[1] = regs.fixreg[4]; + *errorp = !!(regs.cr & 0x10000000); + return (0); +} - print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp, - retval, fsc->sc); - free_fsc(fsc); +static struct procabi powerpc64_fbsd = { + "FreeBSD ELF64", + syscallnames, + nitems(syscallnames), + powerpc64_fetch_args, + powerpc64_fetch_retval +}; - return (retval); -} +PROCABI(powerpc64_fbsd); diff --git a/usr.bin/truss/setup.c b/usr.bin/truss/setup.c index d6e4300..4452f9f 100644 --- a/usr.bin/truss/setup.c +++ b/usr.bin/truss/setup.c @@ -37,37 +37,39 @@ __FBSDID("$FreeBSD$"); * I'm afraid. */ -#include <sys/param.h> -#include <sys/types.h> #include <sys/ptrace.h> +#include <sys/sysctl.h> #include <sys/wait.h> +#include <assert.h> #include <err.h> #include <errno.h> -#include <fcntl.h> #include <signal.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <unistd.h> -#include <machine/reg.h> - #include "truss.h" +#include "syscall.h" #include "extern.h" +SET_DECLARE(procabi, struct procabi); + static sig_atomic_t detaching; +static void new_proc(struct trussinfo *, pid_t); + /* * setup_and_wait() is called to start a process. All it really does - * is fork(), set itself up to stop on exec or exit, and then exec - * the given command. At that point, the child process stops, and - * the parent can wake up and deal with it. + * is fork(), enable tracing in the child, and then exec the given + * command. At that point, the child process stops, and the parent + * can wake up and deal with it. */ - -int -setup_and_wait(char *command[]) +void +setup_and_wait(struct trussinfo *info, char *command[]) { pid_t pid; @@ -84,17 +86,14 @@ setup_and_wait(char *command[]) if (waitpid(pid, NULL, 0) < 0) err(1, "unexpect stop in waitpid"); - return (pid); + new_proc(info, pid); } /* - * start_tracing picks up where setup_and_wait() dropped off -- namely, - * it sets the event mask for the given process id. Called for both - * monitoring an existing process and when we create our own. + * start_tracing is called to attach to an existing process. */ - -int -start_tracing(pid_t pid) +void +start_tracing(struct trussinfo *info, pid_t pid) { int ret, retry; @@ -109,7 +108,7 @@ start_tracing(pid_t pid) if (waitpid(pid, NULL, 0) < 0) err(1, "Unexpect stop in waitpid"); - return (0); + new_proc(info, pid); } /* @@ -118,7 +117,6 @@ start_tracing(pid_t pid) * applies if truss was told to monitor an already-existing * process. */ - void restore_proc(int signo __unused) { @@ -126,116 +124,485 @@ restore_proc(int signo __unused) detaching = 1; } -static int +static void detach_proc(pid_t pid) { - int waitval; /* stop the child so that we can detach */ kill(pid, SIGSTOP); - if (waitpid(pid, &waitval, 0) < 0) + if (waitpid(pid, NULL, 0) < 0) err(1, "Unexpected stop in waitpid"); if (ptrace(PT_DETACH, pid, (caddr_t)1, 0) < 0) err(1, "Can not detach the process"); kill(pid, SIGCONT); +} + +/* + * Determine the ABI. This is called after every exec, and when + * a process is first monitored. + */ +static struct procabi * +find_abi(pid_t pid) +{ + struct procabi **pabi; + size_t len; + int error; + int mib[4]; + char progt[32]; + + len = sizeof(progt); + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_SV_NAME; + mib[3] = pid; + error = sysctl(mib, 4, progt, &len, NULL, 0); + if (error != 0) + err(2, "can not get sysvec name"); + + SET_FOREACH(pabi, procabi) { + if (strcmp((*pabi)->type, progt) == 0) + return (*pabi); + } + warnx("ABI %s for pid %ld is not supported", progt, (long)pid); + return (NULL); +} + +static void +new_proc(struct trussinfo *info, pid_t pid) +{ + struct procinfo *np; + + /* + * If this happens it means there is a bug in truss. Unfortunately + * this will kill any processes are attached to. + */ + LIST_FOREACH(np, &info->proclist, entries) { + if (np->pid == pid) + errx(1, "Duplicate process for pid %ld", (long)pid); + } - return (waitval); + if (info->flags & FOLLOWFORKS) + if (ptrace(PT_FOLLOW_FORK, pid, NULL, 1) == -1) + err(1, "Unable to follow forks for pid %ld", (long)pid); + np = calloc(1, sizeof(struct procinfo)); + np->pid = pid; + np->abi = find_abi(pid); + SLIST_INIT(&np->threadlist); + LIST_INSERT_HEAD(&info->proclist, np, entries); +} + +static void +free_proc(struct procinfo *p) +{ + struct threadinfo *t, *t2; + + SLIST_FOREACH_SAFE(t, &p->threadlist, entries, t2) { + free(t); + } + LIST_REMOVE(p, entries); + free(p); +} + +static void +detach_all_procs(struct trussinfo *info) +{ + struct procinfo *p, *p2; + + LIST_FOREACH_SAFE(p, &info->proclist, entries, p2) { + detach_proc(p->pid); + free_proc(p); + } +} + +static struct procinfo * +find_proc(struct trussinfo *info, pid_t pid) +{ + struct procinfo *np; + + LIST_FOREACH(np, &info->proclist, entries) { + if (np->pid == pid) + return (np); + } + + return (NULL); } /* - * Change curthread member based on lwpid. - * If it is a new thread, create a threadinfo structure + * Change curthread member based on (pid, lwpid). + * If it is a new thread, create a threadinfo structure. */ static void -find_thread(struct trussinfo *info, lwpid_t lwpid) +find_thread(struct trussinfo *info, pid_t pid, lwpid_t lwpid) { - struct threadinfo *np; + struct procinfo *np; + struct threadinfo *nt; - info->curthread = NULL; - SLIST_FOREACH(np, &info->threadlist, entries) { - if (np->tid == lwpid) { - info->curthread = np; + np = find_proc(info, pid); + assert(np != NULL); + + SLIST_FOREACH(nt, &np->threadlist, entries) { + if (nt->tid == lwpid) { + info->curthread = nt; return; } } - np = (struct threadinfo *)calloc(1, sizeof(struct threadinfo)); - if (np == NULL) + nt = calloc(1, sizeof(struct threadinfo)); + if (nt == NULL) err(1, "calloc() failed"); - np->tid = lwpid; - SLIST_INSERT_HEAD(&info->threadlist, np, entries); - info->curthread = np; + nt->proc = np; + nt->tid = lwpid; + SLIST_INSERT_HEAD(&np->threadlist, nt, entries); + info->curthread = nt; } /* - * Start the traced process and wait until it stoped. - * Fill trussinfo structure. - * When this even returns, the traced process is in stop state. + * When a process exits, it no longer has any threads left. However, + * the main loop expects a valid curthread. In cases when a thread + * triggers the termination (e.g. calling exit or triggering a fault) + * we would ideally use that thread. However, if a process is killed + * by a signal sent from another process then there is no "correct" + * thread. We just punt and use the first thread. */ -void -waitevent(struct trussinfo *info) +static void +find_exit_thread(struct trussinfo *info, pid_t pid) { - struct ptrace_lwpinfo lwpinfo; - static int pending_signal = 0; - int waitval; + struct procinfo *np; + struct threadinfo *nt; + + np = find_proc(info, pid); + assert(np != NULL); + + if (SLIST_EMPTY(&np->threadlist)) { + /* + * If an existing process exits right after we attach + * to it but before it posts any events, there won't + * be any threads. Create a dummy thread and set its + * "before" time to the global start time. + */ + nt = calloc(1, sizeof(struct threadinfo)); + if (nt == NULL) + err(1, "calloc() failed"); + nt->proc = np; + nt->tid = 0; + SLIST_INSERT_HEAD(&np->threadlist, nt, entries); + nt->before = info->start_time; + } + info->curthread = SLIST_FIRST(&np->threadlist); +} - ptrace(PT_SYSCALL, info->pid, (caddr_t)1, pending_signal); - pending_signal = 0; +static void +alloc_syscall(struct threadinfo *t, struct ptrace_lwpinfo *pl) +{ + u_int i; + + assert(t->in_syscall == 0); + assert(t->cs.number == 0); + assert(t->cs.name == NULL); + assert(t->cs.nargs == 0); + for (i = 0; i < nitems(t->cs.s_args); i++) + assert(t->cs.s_args[i] == NULL); + memset(t->cs.args, 0, sizeof(t->cs.args)); + t->cs.number = pl->pl_syscall_code; + t->in_syscall = 1; +} -detach: - if (detaching) { - waitval = detach_proc(info->pid); - info->pr_why = S_DETACHED; - info->pr_data = WEXITSTATUS(waitval); +static void +free_syscall(struct threadinfo *t) +{ + u_int i; + + for (i = 0; i < t->cs.nargs; i++) + free(t->cs.s_args[i]); + memset(&t->cs, 0, sizeof(t->cs)); + t->in_syscall = 0; +} + +static void +enter_syscall(struct trussinfo *info, struct ptrace_lwpinfo *pl) +{ + struct threadinfo *t; + struct syscall *sc; + u_int i, narg; + + t = info->curthread; + alloc_syscall(t, pl); + narg = MIN(pl->pl_syscall_narg, nitems(t->cs.args)); + if (narg != 0 && t->proc->abi->fetch_args(info, narg) != 0) { + free_syscall(t); return; } - if (waitpid(info->pid, &waitval, 0) == -1) { - if (errno == EINTR) - goto detach; - err(1, "Unexpected stop in waitpid"); + if (t->cs.number >= 0 && t->cs.number < t->proc->abi->nsyscalls) + t->cs.name = t->proc->abi->syscallnames[t->cs.number]; + if (t->cs.name == NULL) + fprintf(info->outfile, "-- UNKNOWN %s SYSCALL %d --\n", + t->proc->abi->type, t->cs.number); + + sc = get_syscall(t->cs.name); + if (sc) { + t->cs.nargs = sc->nargs; + assert(sc->nargs <= nitems(t->cs.s_args)); + } else { +#if DEBUG + fprintf(stderr, "unknown syscall %s -- setting " + "args to %d\n", t->cs.name, t->cs.nargs); +#endif + t->cs.nargs = narg; } - if (WIFCONTINUED(waitval)) { - info->pr_why = S_NONE; - return; + t->cs.sc = sc; + + /* + * At this point, we set up the system call arguments. + * We ignore any OUT ones, however -- those are arguments that + * are set by the system call, and so are probably meaningless + * now. This doesn't currently support arguments that are + * passed in *and* out, however. + */ + if (t->cs.name != NULL) { +#if DEBUG + fprintf(stderr, "syscall %s(", t->cs.name); +#endif + for (i = 0; i < t->cs.nargs; i++) { +#if DEBUG + fprintf(stderr, "0x%lx%s", sc ? + t->cs.args[sc->args[i].offset] : t->cs.args[i], + i < (t->cs.nargs - 1) ? "," : ""); +#endif + if (sc && !(sc->args[i].type & OUT)) { + t->cs.s_args[i] = print_arg(&sc->args[i], + t->cs.args, 0, info); + } + } +#if DEBUG + fprintf(stderr, ")\n"); +#endif } - if (WIFEXITED(waitval)) { - info->pr_why = S_EXIT; - info->pr_data = WEXITSTATUS(waitval); + + clock_gettime(CLOCK_REALTIME, &t->before); +} + +static void +exit_syscall(struct trussinfo *info, struct ptrace_lwpinfo *pl) +{ + struct threadinfo *t; + struct procinfo *p; + struct syscall *sc; + long retval[2]; + u_int i; + int errorp; + + t = info->curthread; + if (!t->in_syscall) + return; + + clock_gettime(CLOCK_REALTIME, &t->after); + p = t->proc; + if (p->abi->fetch_retval(info, retval, &errorp) < 0) { + free_syscall(t); return; } - if (WIFSTOPPED(waitval)) { - ptrace(PT_LWPINFO, info->pid, (caddr_t)&lwpinfo, - sizeof(lwpinfo)); - find_thread(info, lwpinfo.pl_lwpid); - switch (WSTOPSIG(waitval)) { - case SIGTRAP: - if (lwpinfo.pl_flags & PL_FLAG_SCE) { - info->pr_why = S_SCE; - info->curthread->in_syscall = 1; - break; - } else if (lwpinfo.pl_flags & PL_FLAG_SCX) { - info->pr_why = S_SCX; - info->curthread->in_syscall = 0; - break; - } else { - errx(1, + + sc = t->cs.sc; + if (sc == NULL) { + for (i = 0; i < t->cs.nargs; i++) + asprintf(&t->cs.s_args[i], "0x%lx", t->cs.args[i]); + } else { + /* + * Here, we only look for arguments that have OUT masked in -- + * otherwise, they were handled in enter_syscall(). + */ + for (i = 0; i < sc->nargs; i++) { + char *temp; + + if (sc->args[i].type & OUT) { + /* + * If an error occurred, then don't bother + * getting the data; it may not be valid. + */ + if (errorp) { + asprintf(&temp, "0x%lx", + t->cs.args[sc->args[i].offset]); + } else { + temp = print_arg(&sc->args[i], + t->cs.args, retval, info); + } + t->cs.s_args[i] = temp; + } + } + } + + print_syscall_ret(info, t->cs.name, t->cs.nargs, t->cs.s_args, + errorp, retval, sc); + free_syscall(t); + + /* + * If the process executed a new image, check the ABI. If the + * new ABI isn't supported, stop tracing this process. + */ + if (pl->pl_flags & PL_FLAG_EXEC) { + p->abi = find_abi(p->pid); + if (p->abi == NULL) { + if (ptrace(PT_DETACH, p->pid, (caddr_t)1, 0) < 0) + err(1, "Can not detach the process"); + free_proc(p); + } + } +} + +static void +report_exit(struct trussinfo *info, siginfo_t *si) +{ + struct timespec timediff; + + if (info->flags & FOLLOWFORKS) + fprintf(info->outfile, "%5d: ", si->si_pid); + clock_gettime(CLOCK_REALTIME, &info->curthread->after); + if (info->flags & ABSOLUTETIMESTAMPS) { + timespecsubt(&info->curthread->after, &info->start_time, + &timediff); + fprintf(info->outfile, "%jd.%09ld ", (intmax_t)timediff.tv_sec, + timediff.tv_nsec); + } + if (info->flags & RELATIVETIMESTAMPS) { + timespecsubt(&info->curthread->after, &info->curthread->before, + &timediff); + fprintf(info->outfile, "%jd.%09ld ", (intmax_t)timediff.tv_sec, + timediff.tv_nsec); + } + if (si->si_code == CLD_EXITED) + fprintf(info->outfile, "process exit, rval = %u\n", + si->si_status); + else + fprintf(info->outfile, "process killed, signal = %u%s\n", + si->si_status, si->si_code == CLD_DUMPED ? + " (core dumped)" : ""); +} + +static void +report_new_child(struct trussinfo *info, pid_t pid) +{ + struct timespec timediff; + + clock_gettime(CLOCK_REALTIME, &info->curthread->after); + assert(info->flags & FOLLOWFORKS); + fprintf(info->outfile, "%5d: ", pid); + if (info->flags & ABSOLUTETIMESTAMPS) { + timespecsubt(&info->curthread->after, &info->start_time, + &timediff); + fprintf(info->outfile, "%jd.%09ld ", (intmax_t)timediff.tv_sec, + timediff.tv_nsec); + } + if (info->flags & RELATIVETIMESTAMPS) { + timediff.tv_sec = 0; + timediff.tv_nsec = 0; + fprintf(info->outfile, "%jd.%09ld ", (intmax_t)timediff.tv_sec, + timediff.tv_nsec); + } + fprintf(info->outfile, "<new process>\n"); +} + +static void +report_signal(struct trussinfo *info, siginfo_t *si) +{ + struct timespec timediff; + char *signame; + + if (info->flags & FOLLOWFORKS) + fprintf(info->outfile, "%5d: ", si->si_pid); + if (info->flags & ABSOLUTETIMESTAMPS) { + timespecsubt(&info->curthread->after, &info->start_time, + &timediff); + fprintf(info->outfile, "%jd.%09ld ", (intmax_t)timediff.tv_sec, + timediff.tv_nsec); + } + if (info->flags & RELATIVETIMESTAMPS) { + timespecsubt(&info->curthread->after, &info->curthread->before, + &timediff); + fprintf(info->outfile, "%jd.%09ld ", (intmax_t)timediff.tv_sec, + timediff.tv_nsec); + } + signame = strsig(si->si_status); + fprintf(info->outfile, "SIGNAL %u (%s)\n", si->si_status, + signame == NULL ? "?" : signame); +} + +/* + * Wait for events until all the processes have exited or truss has been + * asked to stop. + */ +void +eventloop(struct trussinfo *info) +{ + struct ptrace_lwpinfo pl; + siginfo_t si; + int pending_signal; + + while (!LIST_EMPTY(&info->proclist)) { + if (detaching) { + detach_all_procs(info); + return; + } + + if (waitid(P_ALL, 0, &si, WTRAPPED | WEXITED) == -1) { + if (errno == EINTR) + continue; + err(1, "Unexpected error from waitid"); + } + + assert(si.si_signo == SIGCHLD); + + switch (si.si_code) { + case CLD_EXITED: + case CLD_KILLED: + case CLD_DUMPED: + find_exit_thread(info, si.si_pid); + if ((info->flags & COUNTONLY) == 0) + report_exit(info, &si); + free_proc(info->curthread->proc); + info->curthread = NULL; + break; + case CLD_TRAPPED: + if (ptrace(PT_LWPINFO, si.si_pid, (caddr_t)&pl, + sizeof(pl)) == -1) + err(1, "ptrace(PT_LWPINFO)"); + + if (pl.pl_flags & PL_FLAG_CHILD) { + new_proc(info, si.si_pid); + assert(LIST_FIRST(&info->proclist)->abi != + NULL); + } + find_thread(info, si.si_pid, pl.pl_lwpid); + + if (si.si_status == SIGTRAP) { + if (pl.pl_flags & PL_FLAG_SCE) + enter_syscall(info, &pl); + else if (pl.pl_flags & PL_FLAG_SCX) + exit_syscall(info, &pl); + else + errx(1, "pl_flags %x contains neither PL_FLAG_SCE nor PL_FLAG_SCX", - lwpinfo.pl_flags); + pl.pl_flags); + pending_signal = 0; + } else if (pl.pl_flags & PL_FLAG_CHILD) { + if ((info->flags & COUNTONLY) == 0) + report_new_child(info, si.si_pid); + pending_signal = 0; + } else { + if ((info->flags & NOSIGS) == 0) + report_signal(info, &si); + pending_signal = si.si_status; } - default: - info->pr_why = S_SIG; - info->pr_data = WSTOPSIG(waitval); - pending_signal = info->pr_data; + ptrace(PT_SYSCALL, si.si_pid, (caddr_t)1, + pending_signal); + break; + case CLD_STOPPED: + errx(1, "waitid reported CLD_STOPPED"); + case CLD_CONTINUED: break; } } - if (WIFSIGNALED(waitval)) { - info->pr_why = S_EXIT; - info->pr_data = 0; - return; - } } diff --git a/usr.bin/truss/sparc64-fbsd.c b/usr.bin/truss/sparc64-fbsd.c index 4e64c70..c8c1e8c 100644 --- a/usr.bin/truss/sparc64-fbsd.c +++ b/usr.bin/truss/sparc64-fbsd.c @@ -29,22 +29,11 @@ * SUCH DAMAGE. */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); -/* - * FreeBSD/sparc64-specific system call handling. This is probably the most - * complex part of the entire truss program, although I've got lots of - * it handled relatively cleanly now. The system call names are generated - * automatically, thanks to /usr/src/sys/kern/syscalls.master. The - * names used for the various structures are confusing, I sadly admit. - * - * This file is almost nothing more than a slightly-edited i386-fbsd.c. - */ +/* FreeBSD/sparc64-specific system call handling. */ -#include <sys/types.h> #include <sys/ptrace.h> #include <sys/syscall.h> @@ -52,289 +41,85 @@ static const char rcsid[] = #include <machine/reg.h> #include <machine/tstate.h> -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> #include <stddef.h> #include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> #include "truss.h" -#include "syscall.h" -#include "extern.h" #include "syscalls.h" -static int nsyscalls = nitems(syscallnames); - -/* - * This is what this particular file uses to keep track of a system call. - * It is probably not quite sufficient -- I can probably use the same - * structure for the various syscall personalities, and I also probably - * need to nest system calls (for signal handlers). - * - * 'struct syscall' describes the system call; it may be NULL, however, - * if we don't know about this particular system call yet. - */ -struct freebsd_syscall { - struct syscall *sc; - const char *name; - int number; - unsigned long *args; - int nargs; /* number of arguments -- *not* number of words! */ - char **s_args; /* the printable arguments */ -}; - -static struct freebsd_syscall * -alloc_fsc(void) -{ - - return (malloc(sizeof(struct freebsd_syscall))); -} - -/* Clear up and free parts of the fsc structure. */ -static void -free_fsc(struct freebsd_syscall *fsc) -{ - int i; - - free(fsc->args); - if (fsc->s_args) { - for (i = 0; i < fsc->nargs; i++) - free(fsc->s_args[i]); - free(fsc->s_args); - } - free(fsc); -} - -/* - * Called when a process has entered a system call. nargs is the - * number of words, not number of arguments (a necessary distinction - * in some cases). Note that if the STOPEVENT() code in sparc64/sparc64/trap.c - * is ever changed these functions need to keep up. - */ - -void -sparc64_syscall_entry(struct trussinfo *trussinfo, int nargs) +static int +sparc64_fetch_args(struct trussinfo *trussinfo, u_int narg) { struct ptrace_io_desc iorequest; struct reg regs; - struct freebsd_syscall *fsc; - struct syscall *sc; + struct current_syscall *cs; lwpid_t tid; - int i, syscall_num; - int indir; /* indirect system call */ + u_int i, reg; tid = trussinfo->curthread->tid; - + cs = &trussinfo->curthread->cs; if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; + return (-1); } /* - * FreeBSD has two special kinds of system call redirctions -- + * FreeBSD has two special kinds of system call redirections -- * SYS_syscall, and SYS___syscall. The former is the old syscall() * routine, basically; the latter is for quad-aligned arguments. + * + * The system call argument count and code from ptrace() already + * account for these, but we need to skip over the first argument. */ - indir = 0; - syscall_num = regs.r_global[1]; - if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) { - indir = 1; - syscall_num = regs.r_out[0]; - } - - fsc = alloc_fsc(); - if (fsc == NULL) - return; - fsc->number = syscall_num; - fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ? - NULL : syscallnames[syscall_num]; - if (!fsc->name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", - syscall_num); + reg = 0; + switch (regs.r_global[1]) { + case SYS_syscall: + case SYS___syscall: + reg = 1; + break; } - if (fsc->name && (trussinfo->flags & FOLLOWFORKS) && - (strcmp(fsc->name, "fork") == 0 || - strcmp(fsc->name, "pdfork") == 0 || - strcmp(fsc->name, "rfork") == 0 || - strcmp(fsc->name, "vfork") == 0)) - trussinfo->curthread->in_fork = 1; - - if (nargs == 0) - return; - - fsc->args = malloc((1 + nargs) * sizeof(unsigned long)); - switch (nargs) { - default: - /* - * The OS doesn't seem to allow more than 10 words of - * parameters (yay!). So we shouldn't be here. - */ - warn("More than 10 words (%d) of arguments!\n", nargs); - break; - case 10: - case 9: - case 8: - case 7: - /* - * If there are 7-10 words of arguments, they are placed - * on the stack, as is normal for other processors. - * The fall-through for all of these is deliberate!!! - */ + for (i = 0; i < narg && reg < 6; i++, reg++) + cs->args[i] = regs.r_out[reg]; + if (narg > i) { iorequest.piod_op = PIOD_READ_D; iorequest.piod_offs = (void *)(regs.r_out[6] + SPOFF + offsetof(struct frame, fr_pad[6])); - iorequest.piod_addr = &fsc->args[6]; - iorequest.piod_len = (nargs - 6) * sizeof(fsc->args[0]); + iorequest.piod_addr = &cs->args[i]; + iorequest.piod_len = (narg - i) * sizeof(cs->args[0]); ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); if (iorequest.piod_len == 0) - return; - case 6: fsc->args[5] = regs.r_out[5]; - case 5: fsc->args[4] = regs.r_out[4]; - case 4: fsc->args[3] = regs.r_out[3]; - case 3: fsc->args[2] = regs.r_out[2]; - case 2: fsc->args[1] = regs.r_out[1]; - case 1: fsc->args[0] = regs.r_out[0]; - case 0: - break; + return (-1); } - if (indir) - memmove(&fsc->args[0], &fsc->args[1], (nargs - 1) * - sizeof(fsc->args[0])); - - sc = get_syscall(fsc->name); - if (sc) - fsc->nargs = sc->nargs; - else { -#if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting " - "args to %d\n", fsc->name, nargs); -#endif - fsc->nargs = nargs; - } - - fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *)); - fsc->sc = sc; - - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ - - if (fsc->name) { -#if DEBUG - fprintf(stderr, "syscall %s(", fsc->name); -#endif - for (i = 0; i < fsc->nargs; i++) { -#if DEBUG - fprintf(stderr, "0x%x%s", sc ? - fsc->args[sc->args[i].offset] : fsc->args[i], - i < (fsc->nargs - 1) ? "," : ""); -#endif - if (sc && !(sc->args[i].type & OUT)) { - fsc->s_args[i] = print_arg(&sc->args[i], - fsc->args, 0, trussinfo); - } - } -#if DEBUG - fprintf(stderr, ")\n"); -#endif - } - -#if DEBUG - fprintf(trussinfo->outfile, "\n"); -#endif - - trussinfo->curthread->fsc = fsc; + return (0); } -/* - * And when the system call is done, we handle it here. - * Currently, no attempt is made to ensure that the system calls - * match -- this needs to be fixed (and is, in fact, why S_SCX includes - * the system call number instead of, say, an error status). - */ - -long -sparc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) +static int +sparc64_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp) { struct reg regs; - struct freebsd_syscall *fsc; - struct syscall *sc; lwpid_t tid; - long retval; - int errorp, i; - - if (trussinfo->curthread->fsc == NULL) - return (-1); tid = trussinfo->curthread->tid; - if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { - fprintf(trussinfo->outfile, "\n"); + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return (-1); } - retval = regs.r_out[0]; - errorp = !!(regs.r_tstate & TSTATE_XCC_C); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - fsc = trussinfo->curthread->fsc; - sc = fsc->sc; - if (!sc) { - for (i = 0; i < fsc->nargs; i++) - asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - - if (sc->args[i].type & OUT) { - /* - * If an error occurred, then don't bother - * getting the data; it may not be valid. - */ - if (errorp) { - asprintf(&temp, "0x%lx", - fsc->args[sc->args[i].offset]); - } else { - temp = print_arg(&sc->args[i], - fsc->args, retval, trussinfo); - } - fsc->s_args[i] = temp; - } - } - } - - if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 || - strcmp(fsc->name, "exit") == 0)) - trussinfo->curthread->in_syscall = 1; - - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ + retval[0] = regs.r_out[0]; + retval[1] = regs.r_out[1]; + *errorp = !!(regs.r_tstate & TSTATE_XCC_C); + return (0); +} - print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp, - retval, fsc->sc); - free_fsc(fsc); +static struct procabi sparc64_fbsd = { + "FreeBSD ELF64", + syscallnames, + nitems(syscallnames), + sparc64_fetch_args, + sparc64_fetch_retval +}; - return (retval); -} +PROCABI(sparc64_fbsd); diff --git a/usr.bin/truss/syscall.h b/usr.bin/truss/syscall.h index 6f4d9a3..ee35214 100644 --- a/usr.bin/truss/syscall.h +++ b/usr.bin/truss/syscall.h @@ -42,7 +42,7 @@ enum Argtype { None = 1, Hex, Octal, Int, LongHex, Name, Ptr, Stat, Ioctl, Quad, Fcntlflag, Rusage, BinString, Shutdown, Resource, Rlimit, Timeval2, Pathconf, Rforkflags, ExitStatus, Waitoptions, Idtype, Procctl, LinuxSockArgs, Umtxop, Atfd, Atflags, Timespec2, Accessmode, Long, - Sysarch, ExecArgs, ExecEnv }; + Sysarch, ExecArgs, ExecEnv, PipeFds, QuadHex }; #define ARG_MASK 0xff #define OUT 0x100 @@ -55,8 +55,8 @@ struct syscall_args { struct syscall { const char *name; - int ret_type; /* 0, 1, or 2 return values */ - int nargs; /* actual number of meaningful arguments */ + u_int ret_type; /* 0, 1, or 2 return values */ + u_int nargs; /* actual number of meaningful arguments */ /* Hopefully, no syscalls with > 10 args */ struct syscall_args args[10]; struct timespec time; /* Time spent for this call */ @@ -65,7 +65,7 @@ struct syscall { }; struct syscall *get_syscall(const char*); -char *print_arg(struct syscall_args *, unsigned long*, long, struct trussinfo *); +char *print_arg(struct syscall_args *, unsigned long*, long *, struct trussinfo *); /* * Linux Socket defines @@ -86,11 +86,11 @@ char *print_arg(struct syscall_args *, unsigned long*, long, struct trussinfo *) #define LINUX_SETSOCKOPT 14 #define LINUX_GETSOCKOPT 15 #define LINUX_SENDMSG 16 -#define LINUX_RECVMSG 17 +#define LINUX_RECVMSG 17 #define PAD_(t) (sizeof(register_t) <= sizeof(t) ? \ 0 : sizeof(register_t) - sizeof(t)) - + #if BYTE_ORDER == LITTLE_ENDIAN #define PADL_(t) 0 #define PADR_(t) PAD_(t) @@ -109,5 +109,5 @@ struct linux_socketcall_args { void print_syscall(struct trussinfo *, const char *, int, char **); void print_syscall_ret(struct trussinfo *, const char *, int, char **, int, - long, struct syscall *); + long *, struct syscall *); void print_summary(struct trussinfo *trussinfo); diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index fac47f4..ab163d8 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -29,10 +29,8 @@ * SUCH DAMAGE. */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); /* * This file has routines used to print out system calls and their @@ -40,29 +38,27 @@ static const char rcsid[] = */ #include <sys/types.h> +#include <sys/event.h> +#include <sys/ioccom.h> #include <sys/mman.h> #include <sys/procctl.h> #include <sys/ptrace.h> +#include <sys/resource.h> #include <sys/socket.h> -#include <sys/time.h> +#include <sys/stat.h> +#include <sys/umtx.h> #include <sys/un.h> #include <sys/wait.h> +#include <machine/sysarch.h> #include <netinet/in.h> #include <arpa/inet.h> -#include <sys/ioccom.h> -#include <machine/atomic.h> -#include <errno.h> -#include <sys/umtx.h> -#include <sys/event.h> -#include <sys/stat.h> -#include <sys/resource.h> -#include <machine/sysarch.h> #include <ctype.h> #include <err.h> #include <fcntl.h> #include <poll.h> #include <signal.h> +#include <stddef.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -76,7 +72,7 @@ static const char rcsid[] = #include "syscall.h" /* 64-bit alignment on 32-bit platforms. */ -#ifdef __powerpc__ +#if !defined(__LP64__) && defined(__powerpc__) #define QUAD_ALIGN 1 #else #define QUAD_ALIGN 0 @@ -95,39 +91,29 @@ static const char rcsid[] = static struct syscall syscalls[] = { { .name = "fcntl", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { Fcntl, 1 }, { Fcntlflag, 2 } } }, - { .name = "fork", .ret_type = 1, .nargs = 0 }, - { .name = "vfork", .ret_type = 1, .nargs = 0 }, { .name = "rfork", .ret_type = 1, .nargs = 1, .args = { { Rforkflags, 0 } } }, - { .name = "getegid", .ret_type = 1, .nargs = 0 }, - { .name = "geteuid", .ret_type = 1, .nargs = 0 }, { .name = "linux_readlink", .ret_type = 1, .nargs = 3, .args = { { Name, 0 }, { Name | OUT, 1 }, { Int, 2 } } }, { .name = "linux_socketcall", .ret_type = 1, .nargs = 2, .args = { { Int, 0 }, { LinuxSockArgs, 1 } } }, - { .name = "getgid", .ret_type = 1, .nargs = 0 }, - { .name = "getpid", .ret_type = 1, .nargs = 0 }, { .name = "getpgid", .ret_type = 1, .nargs = 1, .args = { { Int, 0 } } }, - { .name = "getpgrp", .ret_type = 1, .nargs = 0 }, - { .name = "getppid", .ret_type = 1, .nargs = 0 }, { .name = "getsid", .ret_type = 1, .nargs = 1, .args = { { Int, 0 } } }, - { .name = "getuid", .ret_type = 1, .nargs = 0 }, - { .name = "issetugid", .ret_type = 1, .nargs = 0 }, { .name = "readlink", .ret_type = 1, .nargs = 3, .args = { { Name, 0 }, { Readlinkres | OUT, 1 }, { Int, 2 } } }, { .name = "readlinkat", .ret_type = 1, .nargs = 4, .args = { { Atfd, 0 }, { Name, 1 }, { Readlinkres | OUT, 2 }, { Int, 3 } } }, { .name = "lseek", .ret_type = 2, .nargs = 3, - .args = { { Int, 0 }, { Quad, 1 + QUAD_ALIGN }, + .args = { { Int, 0 }, { QuadHex, 1 + QUAD_ALIGN }, { Whence, 1 + QUAD_SLOTS + QUAD_ALIGN } } }, { .name = "linux_lseek", .ret_type = 2, .nargs = 3, .args = { { Int, 0 }, { Int, 1 }, { Whence, 2 } } }, - { .name = "mmap", .ret_type = 2, .nargs = 6, + { .name = "mmap", .ret_type = 1, .nargs = 6, .args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 }, { Mmapflags, 3 }, - { Int, 4 }, { Quad, 5 + QUAD_ALIGN } } }, + { Int, 4 }, { QuadHex, 5 + QUAD_ALIGN } } }, { .name = "linux_mkdir", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Int, 1 } } }, { .name = "mprotect", .ret_type = 1, .nargs = 3, @@ -145,49 +131,49 @@ static struct syscall syscalls[] = { .args = { { Name, 0 }, { Hex, 1 }, { Octal, 2 } } }, { .name = "close", .ret_type = 1, .nargs = 1, .args = { { Int, 0 } } }, - { .name = "link", .ret_type = 0, .nargs = 2, + { .name = "link", .ret_type = 1, .nargs = 2, .args = { { Name, 0 }, { Name, 1 } } }, - { .name = "linkat", .ret_type = 0, .nargs = 5, + { .name = "linkat", .ret_type = 1, .nargs = 5, .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 }, { Atflags, 4 } } }, - { .name = "unlink", .ret_type = 0, .nargs = 1, + { .name = "unlink", .ret_type = 1, .nargs = 1, .args = { { Name, 0 } } }, - { .name = "unlinkat", .ret_type = 0, .nargs = 3, + { .name = "unlinkat", .ret_type = 1, .nargs = 3, .args = { { Atfd, 0 }, { Name, 1 }, { Atflags, 2 } } }, - { .name = "chdir", .ret_type = 0, .nargs = 1, + { .name = "chdir", .ret_type = 1, .nargs = 1, .args = { { Name, 0 } } }, - { .name = "chroot", .ret_type = 0, .nargs = 1, + { .name = "chroot", .ret_type = 1, .nargs = 1, .args = { { Name, 0 } } }, - { .name = "mkfifo", .ret_type = 0, .nargs = 2, + { .name = "mkfifo", .ret_type = 1, .nargs = 2, .args = { { Name, 0 }, { Octal, 1 } } }, - { .name = "mkfifoat", .ret_type = 0, .nargs = 3, + { .name = "mkfifoat", .ret_type = 1, .nargs = 3, .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 } } }, - { .name = "mknod", .ret_type = 0, .nargs = 3, + { .name = "mknod", .ret_type = 1, .nargs = 3, .args = { { Name, 0 }, { Octal, 1 }, { Int, 2 } } }, - { .name = "mknodat", .ret_type = 0, .nargs = 4, + { .name = "mknodat", .ret_type = 1, .nargs = 4, .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Int, 3 } } }, - { .name = "chmod", .ret_type = 0, .nargs = 2, + { .name = "chmod", .ret_type = 1, .nargs = 2, .args = { { Name, 0 }, { Octal, 1 } } }, - { .name = "fchmod", .ret_type = 0, .nargs = 2, + { .name = "fchmod", .ret_type = 1, .nargs = 2, .args = { { Int, 0 }, { Octal, 1 } } }, - { .name = "lchmod", .ret_type = 0, .nargs = 2, + { .name = "lchmod", .ret_type = 1, .nargs = 2, .args = { { Name, 0 }, { Octal, 1 } } }, - { .name = "fchmodat", .ret_type = 0, .nargs = 4, + { .name = "fchmodat", .ret_type = 1, .nargs = 4, .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Atflags, 3 } } }, - { .name = "chown", .ret_type = 0, .nargs = 3, + { .name = "chown", .ret_type = 1, .nargs = 3, .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } }, - { .name = "fchown", .ret_type = 0, .nargs = 3, + { .name = "fchown", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { Int, 1 }, { Int, 2 } } }, - { .name = "lchown", .ret_type = 0, .nargs = 3, + { .name = "lchown", .ret_type = 1, .nargs = 3, .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } }, - { .name = "fchownat", .ret_type = 0, .nargs = 5, + { .name = "fchownat", .ret_type = 1, .nargs = 5, .args = { { Atfd, 0 }, { Name, 1 }, { Int, 2 }, { Int, 3 }, { Atflags, 4 } } }, { .name = "linux_stat64", .ret_type = 1, .nargs = 3, .args = { { Name | IN, 0 }, { Ptr | OUT, 1 }, { Ptr | IN, 1 } } }, - { .name = "mount", .ret_type = 0, .nargs = 4, + { .name = "mount", .ret_type = 1, .nargs = 4, .args = { { Name, 0 }, { Name, 1 }, { Int, 2 }, { Ptr, 3 } } }, - { .name = "umount", .ret_type = 0, .nargs = 2, + { .name = "umount", .ret_type = 1, .nargs = 2, .args = { { Name, 0 }, { Int, 2 } } }, { .name = "fstat", .ret_type = 1, .nargs = 2, .args = { { Int, 0 }, { Stat | OUT, 1 } } }, @@ -250,19 +236,19 @@ static struct syscall syscalls[] = { { .name = "linux_execve", .ret_type = 1, .nargs = 3, .args = { { Name | IN, 0 }, { ExecArgs | IN, 1 }, { ExecEnv | IN, 2 } } }, - { .name = "kldload", .ret_type = 0, .nargs = 1, + { .name = "kldload", .ret_type = 1, .nargs = 1, .args = { { Name | IN, 0 } } }, - { .name = "kldunload", .ret_type = 0, .nargs = 1, + { .name = "kldunload", .ret_type = 1, .nargs = 1, .args = { { Int, 0 } } }, - { .name = "kldfind", .ret_type = 0, .nargs = 1, + { .name = "kldfind", .ret_type = 1, .nargs = 1, .args = { { Name | IN, 0 } } }, - { .name = "kldnext", .ret_type = 0, .nargs = 1, + { .name = "kldnext", .ret_type = 1, .nargs = 1, .args = { { Int, 0 } } }, - { .name = "kldstat", .ret_type = 0, .nargs = 2, + { .name = "kldstat", .ret_type = 1, .nargs = 2, .args = { { Int, 0 }, { Ptr, 1 } } }, - { .name = "kldfirstmod", .ret_type = 0, .nargs = 1, + { .name = "kldfirstmod", .ret_type = 1, .nargs = 1, .args = { { Int, 0 } } }, - { .name = "nanosleep", .ret_type = 0, .nargs = 1, + { .name = "nanosleep", .ret_type = 1, .nargs = 1, .args = { { Timespec, 0 } } }, { .name = "select", .ret_type = 1, .nargs = 5, .args = { { Int, 0 }, { Fd_set, 1 }, { Fd_set, 2 }, { Fd_set, 3 }, @@ -279,18 +265,18 @@ static struct syscall syscalls[] = { .args = { { Int, 0 }, { Itimerval, 1 }, { Itimerval | OUT, 2 } } }, { .name = "kse_release", .ret_type = 0, .nargs = 1, .args = { { Timespec, 0 } } }, - { .name = "kevent", .ret_type = 0, .nargs = 6, + { .name = "kevent", .ret_type = 1, .nargs = 6, .args = { { Int, 0 }, { Kevent, 1 }, { Int, 2 }, { Kevent | OUT, 3 }, { Int, 4 }, { Timespec, 5 } } }, - { .name = "sigpending", .ret_type = 0, .nargs = 1, + { .name = "sigpending", .ret_type = 1, .nargs = 1, .args = { { Sigset | OUT, 0 } } }, - { .name = "sigprocmask", .ret_type = 0, .nargs = 3, + { .name = "sigprocmask", .ret_type = 1, .nargs = 3, .args = { { Sigprocmask, 0 }, { Sigset, 1 }, { Sigset | OUT, 2 } } }, - { .name = "sigqueue", .ret_type = 0, .nargs = 3, + { .name = "sigqueue", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { Signal, 1 }, { LongHex, 2 } } }, - { .name = "sigreturn", .ret_type = 0, .nargs = 1, + { .name = "sigreturn", .ret_type = 1, .nargs = 1, .args = { { Ptr, 0 } } }, - { .name = "sigsuspend", .ret_type = 0, .nargs = 1, + { .name = "sigsuspend", .ret_type = 1, .nargs = 1, .args = { { Sigset | IN, 0 } } }, { .name = "sigtimedwait", .ret_type = 1, .nargs = 3, .args = { { Sigset | IN, 0 }, { Ptr, 1 }, { Timespec | IN, 2 } } }, @@ -332,13 +318,13 @@ static struct syscall syscalls[] = { { .name = "pathconf", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Pathconf, 1 } } }, { .name = "pipe", .ret_type = 1, .nargs = 1, - .args = { { Ptr, 0 } } }, + .args = { { PipeFds | OUT, 0 } } }, { .name = "pipe2", .ret_type = 1, .nargs = 2, .args = { { Ptr, 0 }, { Open, 1 } } }, - { .name = "truncate", .ret_type = 1, .nargs = 3, - .args = { { Name | IN, 0 }, { Int | IN, 1 }, { Quad | IN, 2 } } }, - { .name = "ftruncate", .ret_type = 1, .nargs = 3, - .args = { { Int | IN, 0 }, { Int | IN, 1 }, { Quad | IN, 2 } } }, + { .name = "truncate", .ret_type = 1, .nargs = 2, + .args = { { Name | IN, 0 }, { QuadHex | IN, 1 + QUAD_ALIGN } } }, + { .name = "ftruncate", .ret_type = 1, .nargs = 2, + .args = { { Int | IN, 0 }, { QuadHex | IN, 1 + QUAD_ALIGN } } }, { .name = "kill", .ret_type = 1, .nargs = 2, .args = { { Int | IN, 0 }, { Signal | IN, 1 } } }, { .name = "munmap", .ret_type = 1, .nargs = 2, @@ -359,18 +345,23 @@ static struct syscall syscalls[] = { .args = { { Int, 0 }, { ExitStatus | OUT, 1 }, { Waitoptions, 2 }, { Rusage | OUT, 3 } } }, { .name = "wait6", .ret_type = 1, .nargs = 6, - .args = { { Idtype, 0 }, { Int, 1 }, { ExitStatus | OUT, 2 }, - { Waitoptions, 3 }, { Rusage | OUT, 4 }, { Ptr, 5 } } }, + .args = { { Idtype, 0 }, { Quad, 1 + QUAD_ALIGN }, + { ExitStatus | OUT, 1 + QUAD_ALIGN + QUAD_SLOTS }, + { Waitoptions, 2 + QUAD_ALIGN + QUAD_SLOTS }, + { Rusage | OUT, 3 + QUAD_ALIGN + QUAD_SLOTS }, + { Ptr, 4 + QUAD_ALIGN + QUAD_SLOTS } } }, { .name = "procctl", .ret_type = 1, .nargs = 4, - .args = { { Idtype, 0 }, { Int, 1 }, { Procctl, 2 }, { Ptr, 3 } } }, + .args = { { Idtype, 0 }, { Quad, 1 + QUAD_ALIGN }, + { Procctl, 1 + QUAD_ALIGN + QUAD_SLOTS }, + { Ptr, 2 + QUAD_ALIGN + QUAD_SLOTS } } }, { .name = "sysarch", .ret_type = 1, .nargs = 2, .args = { { Sysarch, 0 }, { Ptr, 1 } } }, { .name = "_umtx_op", .ret_type = 1, .nargs = 5, .args = { { Ptr, 0 }, { Umtxop, 1 }, { LongHex, 2 }, { Ptr, 3 }, { Ptr, 4 } } }, - { .name = "thr_kill", .ret_type = 0, .nargs = 2, + { .name = "thr_kill", .ret_type = 1, .nargs = 2, .args = { { Long, 0 }, { Signal, 1 } } }, - { .name = "thr_self", .ret_type = 0, .nargs = 1, + { .name = "thr_self", .ret_type = 1, .nargs = 1, .args = { { Ptr, 0 } } }, { .name = 0 }, }; @@ -534,7 +525,9 @@ static struct xlat idtype_arg[] = { }; static struct xlat procctl_arg[] = { - X(PROC_SPROTECT) XEND + X(PROC_SPROTECT) X(PROC_REAP_ACQUIRE) X(PROC_REAP_RELEASE) + X(PROC_REAP_STATUS) X(PROC_REAP_GETPIDS) X(PROC_REAP_KILL) + X(PROC_TRACE_CTL) X(PROC_TRACE_STATUS) XEND }; static struct xlat umtx_ops[] = { @@ -809,7 +802,7 @@ print_kevent(FILE *fp, struct kevent *ke, int input) int ctrl, data; ctrl = ke->fflags & NOTE_FFCTRLMASK; - data = ke->fflags & NOTE_FFLAGSMASK; + data = ke->fflags & NOTE_FFLAGSMASK; if (input) { fputs(xlookup(kevent_user_ffctrl, ctrl), fp); if (ke->fflags & NOTE_TRIGGER) @@ -834,7 +827,7 @@ print_kevent(FILE *fp, struct kevent *ke, int input) * an array of all of the system call arguments. */ char * -print_arg(struct syscall_args *sc, unsigned long *args, long retval, +print_arg(struct syscall_args *sc, unsigned long *args, long *retval, struct trussinfo *trussinfo) { FILE *fp; @@ -843,7 +836,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, pid_t pid; fp = open_memstream(&tmp, &tmplen); - pid = trussinfo->pid; + pid = trussinfo->curthread->proc->pid; switch (sc->type & ARG_MASK) { case Hex: fprintf(fp, "0x%x", (int)args[sc->offset]); @@ -882,7 +875,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, int truncated = 0; if (sc->type & OUT) - len = retval; + len = retval[0]; else len = args[sc->offset + 1]; @@ -922,7 +915,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, } u; char *string; size_t len; - int first, i; + u_int first, i; /* * Only parse argv[] and environment arrays from exec calls @@ -935,7 +928,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, fprintf(fp, "0x%lx", args[sc->offset]); break; } - + /* * Read a page of pointers at a time. Punt if the top-level * pointer is not aligned. Note that the first read is of @@ -979,14 +972,27 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, } #ifdef __LP64__ case Quad: + fprintf(fp, "%ld", args[sc->offset]); + break; + case QuadHex: fprintf(fp, "0x%lx", args[sc->offset]); break; #else - case Quad: { + case Quad: + case QuadHex: { unsigned long long ll; - ll = *(unsigned long long *)(args + sc->offset); - fprintf(fp, "0x%llx", ll); +#if _BYTE_ORDER == _LITTLE_ENDIAN + ll = (unsigned long long)args[sc->offset + 1] << 32 | + args[sc->offset]; +#else + ll = (unsigned long long)args[sc->offset] << 32 | + args[sc->offset + 1]; +#endif + if ((sc->type & ARG_MASK) == Quad) + fprintf(fp, "%lld", ll); + else + fprintf(fp, "0x%llx", ll); break; } #endif @@ -996,9 +1002,9 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, case Readlinkres: { char *tmp2; - if (retval == -1) + if (retval[0] == -1) break; - tmp2 = get_string(pid, (void*)args[sc->offset], retval); + tmp2 = get_string(pid, (void*)args[sc->offset], retval[0]); fprintf(fp, "\"%s\"", tmp2); free(tmp2); break; @@ -1283,12 +1289,12 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, fputs(xlookup_bits(rfork_flags, args[sc->offset]), fp); break; case Sockaddr: { - struct sockaddr_storage ss; char addr[64]; struct sockaddr_in *lsin; struct sockaddr_in6 *lsin6; struct sockaddr_un *sun; struct sockaddr *sa; + socklen_t len; u_char *q; if (args[sc->offset] == 0) { @@ -1296,70 +1302,71 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, break; } - /* yuck: get ss_len */ - if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, - sizeof(ss.ss_len) + sizeof(ss.ss_family)) == -1) { - fprintf(fp, "0x%lx", args[sc->offset]); - break; - } - /* - * If ss_len is 0, then try to guess from the sockaddr type. - * AF_UNIX may be initialized incorrectly, so always frob - * it by using the "right" size. + * Extract the address length from the next argument. If + * this is an output sockaddr (OUT is set), then the + * next argument is a pointer to a socklen_t. Otherwise + * the next argument contains a socklen_t by value. */ - if (ss.ss_len == 0 || ss.ss_family == AF_UNIX) { - switch (ss.ss_family) { - case AF_INET: - ss.ss_len = sizeof(*lsin); - break; - case AF_INET6: - ss.ss_len = sizeof(*lsin6); - break; - case AF_UNIX: - ss.ss_len = sizeof(*sun); - break; - default: + if (sc->type & OUT) { + if (get_struct(pid, (void *)args[sc->offset + 1], + &len, sizeof(len)) == -1) { + fprintf(fp, "0x%lx", args[sc->offset]); break; } + } else + len = args[sc->offset + 1]; + + /* If the length is too small, just bail. */ + if (len < sizeof(*sa)) { + fprintf(fp, "0x%lx", args[sc->offset]); + break; } - if (ss.ss_len != 0 && - get_struct(pid, (void *)args[sc->offset], (void *)&ss, - ss.ss_len) == -1) { + + sa = calloc(1, len); + if (get_struct(pid, (void *)args[sc->offset], sa, len) == -1) { + free(sa); fprintf(fp, "0x%lx", args[sc->offset]); break; } - switch (ss.ss_family) { + switch (sa->sa_family) { case AF_INET: - lsin = (struct sockaddr_in *)&ss; + if (len < sizeof(*lsin)) + goto sockaddr_short; + lsin = (struct sockaddr_in *)(void *)sa; inet_ntop(AF_INET, &lsin->sin_addr, addr, sizeof(addr)); fprintf(fp, "{ AF_INET %s:%d }", addr, htons(lsin->sin_port)); break; case AF_INET6: - lsin6 = (struct sockaddr_in6 *)&ss; + if (len < sizeof(*lsin6)) + goto sockaddr_short; + lsin6 = (struct sockaddr_in6 *)(void *)sa; inet_ntop(AF_INET6, &lsin6->sin6_addr, addr, sizeof(addr)); fprintf(fp, "{ AF_INET6 [%s]:%d }", addr, htons(lsin6->sin6_port)); break; case AF_UNIX: - sun = (struct sockaddr_un *)&ss; - fprintf(fp, "{ AF_UNIX \"%s\" }", sun->sun_path); + sun = (struct sockaddr_un *)sa; + fprintf(fp, "{ AF_UNIX \"%.*s\" }", + (int)(len - offsetof(struct sockaddr_un, sun_path)), + sun->sun_path); break; default: - sa = (struct sockaddr *)&ss; + sockaddr_short: fprintf(fp, "{ sa_len = %d, sa_family = %d, sa_data = {", (int)sa->sa_len, (int)sa->sa_family); for (q = (u_char *)sa->sa_data; - q < (u_char *)sa + sa->sa_len; q++) + q < (u_char *)sa + len; q++) fprintf(fp, "%s 0x%02x", q == (u_char *)sa->sa_data ? "" : ",", *q); fputs(" } }", fp); } + free(sa); break; } case Sigaction: { @@ -1395,8 +1402,8 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, if (sc->offset == 1) numevents = args[sc->offset+1]; - else if (sc->offset == 3 && retval != -1) - numevents = retval; + else if (sc->offset == 3 && retval[0] != -1) + numevents = retval[0]; if (numevents >= 0) { bytes = sizeof(struct kevent) * numevents; @@ -1515,6 +1522,21 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, case Sysarch: fputs(xlookup(sysarch_ops, args[sc->offset]), fp); break; + case PipeFds: + /* + * The pipe() system call in the kernel returns its + * two file descriptors via return values. However, + * the interface exposed by libc is that pipe() + * accepts a pointer to an array of descriptors. + * Format the output to match the libc API by printing + * the returned file descriptors as a fake argument. + * + * Overwrite the first retval to signal a successful + * return as well. + */ + fprintf(fp, "{ %ld, %ld }", retval[0], retval[1]); + retval[0] = 0; + break; default: errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK); } @@ -1536,7 +1558,8 @@ print_syscall(struct trussinfo *trussinfo, const char *name, int nargs, len = 0; if (trussinfo->flags & FOLLOWFORKS) - len += fprintf(trussinfo->outfile, "%5d: ", trussinfo->pid); + len += fprintf(trussinfo->outfile, "%5d: ", + trussinfo->curthread->proc->pid); if (name != NULL && (strcmp(name, "execve") == 0 || strcmp(name, "exit") == 0)) { @@ -1575,7 +1598,7 @@ print_syscall(struct trussinfo *trussinfo, const char *name, int nargs, void print_syscall_ret(struct trussinfo *trussinfo, const char *name, int nargs, - char **s_args, int errorp, long retval, struct syscall *sc) + char **s_args, int errorp, long *retval, struct syscall *sc) { struct timespec timediff; @@ -1595,17 +1618,24 @@ print_syscall_ret(struct trussinfo *trussinfo, const char *name, int nargs, print_syscall(trussinfo, name, nargs, s_args); fflush(trussinfo->outfile); if (errorp) - fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval, - strerror(retval)); - else { - /* - * Because pipe(2) has a special assembly glue to provide the - * libc API, we have to adjust retval. - */ - if (name != NULL && strcmp(name, "pipe") == 0) - retval = 0; - fprintf(trussinfo->outfile, " = %ld (0x%lx)\n", retval, retval); + fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval[0], + strerror(retval[0])); +#ifndef __LP64__ + else if (sc != NULL && sc->ret_type == 2) { + off_t off; + +#if _BYTE_ORDER == _LITTLE_ENDIAN + off = (off_t)retval[1] << 32 | retval[0]; +#else + off = (off_t)retval[0] << 32 | retval[1]; +#endif + fprintf(trussinfo->outfile, " = %jd (0x%jx)\n", (intmax_t)off, + (intmax_t)off); } +#endif + else + fprintf(trussinfo->outfile, " = %ld (0x%lx)\n", retval[0], + retval[0]); } void diff --git a/usr.bin/truss/truss.h b/usr.bin/truss/truss.h index dcc86a5..0f58bd8 100644 --- a/usr.bin/truss/truss.h +++ b/usr.bin/truss/truss.h @@ -25,6 +25,7 @@ * $FreeBSD$ */ +#include <sys/linker_set.h> #include <sys/queue.h> #define FOLLOWFORKS 0x00000001 @@ -35,23 +36,63 @@ #define EXECVEENVS 0x00000020 #define COUNTONLY 0x00000040 +struct procinfo; +struct trussinfo; + +struct procabi { + const char *type; + const char **syscallnames; + int nsyscalls; + int (*fetch_args)(struct trussinfo *, u_int); + int (*fetch_retval)(struct trussinfo *, long *, int *); +}; + +#define PROCABI(abi) DATA_SET(procabi, abi) + +/* + * This is confusingly named. It holds per-thread state about the + * currently executing system call. syscalls.h defines a struct + * syscall that holds metadata used to format system call arguments. + * + * NB: args[] stores the raw argument values (e.g. from registers) + * passed to the system call. s_args[] stores a string representation + * of a system call's arguments. These do not necessarily map one to + * one. A system call description may omit individual arguments + * (padding) or combine adjacent arguments (e.g. when passing an off_t + * argument on a 32-bit system). The nargs member contains the count + * of valid pointers in s_args[], not args[]. + */ +struct current_syscall { + struct syscall *sc; + const char *name; + int number; + unsigned long args[10]; + unsigned int nargs; + char *s_args[10]; /* the printable arguments */ +}; + struct threadinfo { SLIST_ENTRY(threadinfo) entries; + struct procinfo *proc; lwpid_t tid; int in_syscall; - int in_fork; - void *fsc; + struct current_syscall cs; struct timespec before; struct timespec after; }; +struct procinfo { + LIST_ENTRY(procinfo) entries; + pid_t pid; + struct procabi *abi; + + SLIST_HEAD(, threadinfo) threadlist; +}; + struct trussinfo { - pid_t pid; int flags; - int pr_why; - int pr_data; int strsize; FILE *outfile; @@ -59,7 +100,7 @@ struct trussinfo struct threadinfo *curthread; - SLIST_HEAD(, threadinfo) threadlist; + LIST_HEAD(, procinfo) proclist; }; #define timespecsubt(tvp, uvp, vvp) \ @@ -81,11 +122,3 @@ struct trussinfo (vvp)->tv_nsec -= 1000000000; \ } \ } while (0) - -#define S_NONE 0 -#define S_SCE 1 -#define S_SCX 2 -#define S_EXIT 3 -#define S_SIG 4 -#define S_EXEC 5 -#define S_DETACHED 6 diff --git a/usr.bin/usbhidaction/usbhidaction.c b/usr.bin/usbhidaction/usbhidaction.c index 876dbca..49cf0af 100644 --- a/usr.bin/usbhidaction/usbhidaction.c +++ b/usr.bin/usbhidaction/usbhidaction.c @@ -166,17 +166,15 @@ main(int argc, char **argv) if (demon) { fp = open(pidfile, O_WRONLY|O_CREAT, S_IRUSR|S_IRGRP|S_IROTH); - if (fp >= 0) { - sz1 = snprintf(buf, sizeof buf, "%ld\n", - (long)getpid()); - if (sz1 > sizeof buf) - sz1 = sizeof buf; - write(fp, buf, sz1); - close(fp); - } else + if (fp < 0) err(1, "%s", pidfile); if (daemon(0, 0) < 0) err(1, "daemon()"); + snprintf(buf, sizeof(buf), "%ld\n", (long)getpid()); + sz1 = strlen(buf); + if (write(fp, buf, sz1) < 0) + err(1, "%s", pidfile); + close(fp); isdemon = 1; } diff --git a/usr.bin/vgrind/RETEST/Makefile.depend b/usr.bin/vgrind/RETEST/Makefile.depend index f52ca95..79eb58b 100644 --- a/usr.bin/vgrind/RETEST/Makefile.depend +++ b/usr.bin/vgrind/RETEST/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.bin/xinstall/install.1 b/usr.bin/xinstall/install.1 index 60d48c6..a0afebe 100644 --- a/usr.bin/xinstall/install.1 +++ b/usr.bin/xinstall/install.1 @@ -9,7 +9,7 @@ .\" 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. -.\" 4. Neither the name of the University nor the names of its contributors +.\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c index 33e818a..30cc6c7 100644 --- a/usr.bin/xinstall/xinstall.c +++ b/usr.bin/xinstall/xinstall.c @@ -11,7 +11,7 @@ * 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. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/usr.bin/yacc/tests/Makefile b/usr.bin/yacc/tests/Makefile index c8125a6..2e157ec 100644 --- a/usr.bin/yacc/tests/Makefile +++ b/usr.bin/yacc/tests/Makefile @@ -17,6 +17,8 @@ TEST_METADATA.yacc_tests+= required_user="unprivileged" SCRIPTS= run_test SCRIPTSDIR= ${TESTSDIR} +CLEANFILES= run_test + FILESGROUPS= FILES FILEStest FILEStest_yacc FILEStestDIR= ${TESTSDIR} diff --git a/usr.sbin/Makefile.arm64 b/usr.sbin/Makefile.arm64 new file mode 100644 index 0000000..8987110 --- /dev/null +++ b/usr.sbin/Makefile.arm64 @@ -0,0 +1,3 @@ +# $FreeBSD$ + +SUBDIR+= ofwdump diff --git a/usr.sbin/Makefile.mips b/usr.sbin/Makefile.mips index 99fd0a2..b56992b 100644 --- a/usr.sbin/Makefile.mips +++ b/usr.sbin/Makefile.mips @@ -1,5 +1,6 @@ # $FreeBSD$ +SUBDIR+= ofwdump # uathload broken for n32 and n64 due to toolchain issues, only build for o32 .if ${MACHINE_ARCH} != "mips" && ${MACHINE_ARCH} != "mipsel" SUBDIR:= ${SUBDIR:Nuathload} diff --git a/usr.sbin/amd/Makefile b/usr.sbin/amd/Makefile index 2255f14..77c5a4c 100644 --- a/usr.sbin/amd/Makefile +++ b/usr.sbin/amd/Makefile @@ -5,7 +5,9 @@ # # $FreeBSD$ -SUBDIR= include libamu amd amq fixmount fsinfo hlfsd mk-amd-map pawd \ +SUBDIR= include libamu .WAIT \ + amd amq fixmount fsinfo hlfsd mk-amd-map pawd \ scripts wire-test +SUBDIR_PARALLEL= .include <bsd.subdir.mk> diff --git a/usr.sbin/apmd/Makefile.depend b/usr.sbin/apmd/Makefile.depend index 6596113..bae339a 100644 --- a/usr.sbin/apmd/Makefile.depend +++ b/usr.sbin/apmd/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.sbin/arp/arp.c b/usr.sbin/arp/arp.c index 60f776f..eefde75 100644 --- a/usr.sbin/arp/arp.c +++ b/usr.sbin/arp/arp.c @@ -673,10 +673,13 @@ print_entry(struct sockaddr_dl *sdl, */ static void nuke_entry(struct sockaddr_dl *sdl __unused, - struct sockaddr_in *addr, struct rt_msghdr *rtm __unused) + struct sockaddr_in *addr, struct rt_msghdr *rtm) { char ip[20]; + if (rtm->rtm_flags & RTF_PINNED) + return; + snprintf(ip, sizeof(ip), "%s", inet_ntoa(addr->sin_addr)); delete(ip); } diff --git a/usr.sbin/boot98cfg/Makefile.depend b/usr.sbin/boot98cfg/Makefile.depend index 4c7271b..2df49d0 100644 --- a/usr.sbin/boot98cfg/Makefile.depend +++ b/usr.sbin/boot98cfg/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.sbin/bsdconfig/packages/Makefile.depend b/usr.sbin/bsdconfig/packages/Makefile.depend index d14a02b..f80275d 100644 --- a/usr.sbin/bsdconfig/packages/Makefile.depend +++ b/usr.sbin/bsdconfig/packages/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ diff --git a/usr.sbin/bsdconfig/packages/include/Makefile.depend b/usr.sbin/bsdconfig/packages/include/Makefile.depend index d14a02b..f80275d 100644 --- a/usr.sbin/bsdconfig/packages/include/Makefile.depend +++ b/usr.sbin/bsdconfig/packages/include/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ diff --git a/usr.sbin/bsdconfig/share/packages/Makefile.depend b/usr.sbin/bsdconfig/share/packages/Makefile.depend index d14a02b..f80275d 100644 --- a/usr.sbin/bsdconfig/share/packages/Makefile.depend +++ b/usr.sbin/bsdconfig/share/packages/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ diff --git a/usr.sbin/bsdinstall/Makefile b/usr.sbin/bsdinstall/Makefile index e72b5d3..4e3b7ef 100644 --- a/usr.sbin/bsdinstall/Makefile +++ b/usr.sbin/bsdinstall/Makefile @@ -1,6 +1,7 @@ # $FreeBSD$ SUBDIR= distextract distfetch partedit scripts +SUBDIR_PARALLEL= SCRIPTS= bsdinstall MAN= bsdinstall.8 diff --git a/usr.sbin/bsdinstall/Makefile.depend b/usr.sbin/bsdinstall/Makefile.depend index 3af2d7f..f80275d 100644 --- a/usr.sbin/bsdinstall/Makefile.depend +++ b/usr.sbin/bsdinstall/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ diff --git a/usr.sbin/bsnmpd/modules/snmp_hast/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_hast/Makefile.depend index 419cddd..ccb3d83 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hast/Makefile.depend +++ b/usr.sbin/bsnmpd/modules/snmp_hast/Makefile.depend @@ -1,8 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.sbin/ctladm/ctladm.8 b/usr.sbin/ctladm/ctladm.8 index 61b6d42..0c30db3 100644 --- a/usr.sbin/ctladm/ctladm.8 +++ b/usr.sbin/ctladm/ctladm.8 @@ -35,7 +35,7 @@ .\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $ .\" $FreeBSD$ .\" -.Dd September 12, 2015 +.Dd September 26, 2015 .Dt CTLADM 8 .Os .Sh NAME @@ -118,12 +118,6 @@ .Op Fl i .Op Fl c Ar cdbsize .Nm -.Ic shutdown -.Op general options -.Nm -.Ic startup -.Op general options -.Nm .Ic lunlist .Nm .Ic delay @@ -132,15 +126,6 @@ .Aq Fl t Ar secs .Op Fl T Ar oneshot|cont .Nm -.Ic realsync Aq on|off|query -.Nm -.Ic setsync interval -.Aq lun -.Aq Fl i Ar interval -.Nm -.Ic getsync -.Aq lun -.Nm .Ic inject .Aq Fl i Ar action .Aq Fl p Ar pattern @@ -176,14 +161,11 @@ .Op Fl x .Nm .Ic port -.Op Fl l .Op Fl o Ar on|off .Op Fl w Ar wwpn .Op Fl W Ar wwnn .Op Fl p Ar targ_port .Op Fl t Ar fe_type -.Op Fl q -.Op Fl x .Nm .Ic portlist .Op Fl f Ar frontend @@ -418,17 +400,6 @@ bit set. Set the immediate bit in the CDB. Note that CTL does not support the immediate bit, so this is primarily useful for making sure that CTL returns the proper error. -.It Fl o -Set the Copan proprietary on/offline bit in the CDB. When this flag is -used, the LUN will be marked online again (see the description of the -.Ic shutdown -and -.Ic startup -commands). When this flag is used with a -start command, the LUN will NOT be spun up. You need to use a start -command without the -.Fl o -flag to spin up the disks in the LUN. .El .It Ic stop Send the @@ -444,14 +415,6 @@ sends an ordered tag for completeness.) Set the immediate bit in the CDB. Note that CTL does not support the immediate bit, so this is primarily useful for making sure that CTL returns the proper error. -.It Fl o -Set the Copan proprietary on/offline bit in the CDB. When this flag is -used, the LUN will be spun down and taken offline ("Logical unit not ready, -manual intervention required"). See the description of the -.Ic shutdown -and -.Ic startup -options. .El .It Ic synccache Send the @@ -483,32 +446,6 @@ support this bit. .It Fl c Ar cdbsize Specify the minimum CDB size. Valid values are 10 and 16 bytes. .El -.It Ic shutdown -Issue a -.Tn SCSI -START STOP UNIT command with the start bit cleared and the on/offline bit -set to all direct access LUNs. This will spin down all direct access LUNs, -and mark them offline ("Logical unit not ready, manual intervention -required"). Once marked offline, the state can only be cleared by sending -a START STOP UNIT command with the start bit set and the on/offline bit -set. The -.Nm -commands -.Ic startup -and -.Ic start -will accomplish this. Note that the -on/offline bit is a non-standard Copan extension to the -.Tn SCSI -START STOP UNIT command, so merely sending a normal start command from an -initiator will not clear the condition. (This is by design.) -.It Ic startup -Issue a -.Tn SCSI -START STOP UNIT command with the start bit set and the on/offline bit set -to all direct access LUNs. This will mark all direct access LUNs "online" -again. It will not cause any LUNs to start up. A separate start command -without the on/offline bit set is necessary for that. .It Ic lunlist List all LUNs registered with CTL. Because this command uses the ioctl port, it will only work when the FETDs @@ -549,39 +486,6 @@ the next command sent to the given LUN will be delayed and all subsequent commands will be completed normally. This is the default. .El -.It Ic realsync -Query and control CTL's SYNCHRONIZE CACHE behavior. The -.Sq query -argument -will show whether SYNCHRONIZE CACHE commands are being sent to the backend -or not. -The default is to send SYNCHRONIZE CACHE commands to the backend. -The -.Sq on -argument will cause all SYNCHRONIZE CACHE commands sent to all LUNs to be -sent to the backend. -The -.Sq off -argument will cause all SYNCHRONIZE CACHE commands sent to all LUNs to be -immediately returned to the initiator with successful status. -.It Ic setsync -For a given lun, only actually service every Nth SYNCHRONIZE CACHE command -that is sent. This can be used for debugging the optimal time period for -sending SYNCHRONIZE cache commands. An interval of 0 means that the cache -will be flushed for this LUN every time a SYNCHRONIZE CACHE command is -received. -.Pp -You must specify the LUN you want to modify. -.It Ic getsync -Get the interval at which we actually service the SYNCHRONIZE CACHE -command, as set by the -.Ic setsync -command above. -The reported number means that we will actually flush the cache on every -Nth SYNCHRONIZE CACHE command. A value of 0 means that we will flush the -cache every time. -.Pp -You must specify the LUN you want to query. .It Ic inject Inject the specified type of error for the LUN specified, when a command that matches the given pattern is seen. @@ -689,8 +593,6 @@ must be specified. The WWNN and WWPN may both be specified at the same time, but cannot be combined with enabling/disabling or listing ports. .Bl -tag -width 12n -.It Fl l -List all CTL frontend ports or a specific port type or number. .It Fl o Ar on|off Turn the specified CTL frontend ports off or on. If no port number or port type is specified, all ports are turned on or @@ -698,8 +600,6 @@ off. .It Fl p Ar targ_port Specify the frontend port number. The port numbers can be found in the frontend port list. -.It Fl q -Omit the header in the port list output. .It Fl t Ar fe_type Specify the frontend type. Currently defined port types are @@ -727,8 +627,6 @@ The argument must be specified, since this is only possible to implement on a single port. As a general rule, the WWPN must be different for every port in the system. -.It Fl x -Output the port list in XML format. .El .It Ic portlist List CTL frontend ports. @@ -819,11 +717,10 @@ Specify the serial number to be used in the INQUIRY VPD page 0x80 data. .It Fl t Ar device_type Specify the numeric SCSI device type to use when creating the LUN. -For example, the Direct Access type is 0. If this flag is not used, the type of LUN created is backend-specific. Not all LUN types are supported. -Currently CTL only supports Direct Access (type 0) and Processor (type 3) -LUNs. +Currently CTL supports Direct Access (type 0), Processor (type 3) +and CD/DVD (type 5) LUNs. The backend requested may or may not support all of the LUN types that CTL supports. .El @@ -978,6 +875,8 @@ Set to "off", disables read caching for the LUN, if supported by the backend. .It Va readonly Set to "on", blocks all media write operations to the LUN, reporting it as write protected. +.It Va removable +Set to "on", makes LUN removable. .It Va reordering Set to "unrestricted", allows target to process commands with SIMPLE task attribute in arbitrary order. Any data integrity exposures related to diff --git a/usr.sbin/ctladm/ctladm.c b/usr.sbin/ctladm/ctladm.c index 4e5b084..2e5817b 100644 --- a/usr.sbin/ctladm/ctladm.c +++ b/usr.sbin/ctladm/ctladm.c @@ -101,13 +101,8 @@ typedef enum { CTLADM_CMD_START, CTLADM_CMD_STOP, CTLADM_CMD_SYNC_CACHE, - CTLADM_CMD_SHUTDOWN, - CTLADM_CMD_STARTUP, CTLADM_CMD_LUNLIST, CTLADM_CMD_DELAY, - CTLADM_CMD_REALSYNC, - CTLADM_CMD_SETSYNC, - CTLADM_CMD_GETSYNC, CTLADM_CMD_ERR_INJECT, CTLADM_CMD_PRES_IN, CTLADM_CMD_PRES_OUT, @@ -163,7 +158,7 @@ typedef enum { } ctladm_optret; static const char rw_opts[] = "Nb:c:d:f:l:"; -static const char startstop_opts[] = "io"; +static const char startstop_opts[] = "i"; static struct ctladm_opts option_table[] = { {"adddev", CTLADM_CMD_ADDDEV, CTLADM_ARG_NONE, NULL}, @@ -173,7 +168,6 @@ static struct ctladm_opts option_table[] = { {"devlist", CTLADM_CMD_DEVLIST, CTLADM_ARG_NONE, "b:vx"}, {"dumpooa", CTLADM_CMD_DUMPOOA, CTLADM_ARG_NONE, NULL}, {"dumpstructs", CTLADM_CMD_DUMPSTRUCTS, CTLADM_ARG_NONE, NULL}, - {"getsync", CTLADM_CMD_GETSYNC, CTLADM_ARG_NEED_TL, NULL}, {"help", CTLADM_CMD_HELP, CTLADM_ARG_NONE, NULL}, {"inject", CTLADM_CMD_ERR_INJECT, CTLADM_ARG_NEED_TL, "cd:i:p:r:s:"}, {"inquiry", CTLADM_CMD_INQUIRY, CTLADM_ARG_NEED_TL, NULL}, @@ -190,15 +184,11 @@ static struct ctladm_opts option_table[] = { {"prout", CTLADM_CMD_PRES_OUT, CTLADM_ARG_NEED_TL, "a:k:r:s:"}, {"read", CTLADM_CMD_READ, CTLADM_ARG_NEED_TL, rw_opts}, {"readcapacity", CTLADM_CMD_READCAPACITY, CTLADM_ARG_NEED_TL, "c:"}, - {"realsync", CTLADM_CMD_REALSYNC, CTLADM_ARG_NONE, NULL}, {"remove", CTLADM_CMD_RM, CTLADM_ARG_NONE, "b:l:o:"}, {"reportluns", CTLADM_CMD_REPORT_LUNS, CTLADM_ARG_NEED_TL, NULL}, {"reqsense", CTLADM_CMD_REQ_SENSE, CTLADM_ARG_NEED_TL, NULL}, {"rtpg", CTLADM_CMD_RTPG, CTLADM_ARG_NEED_TL, NULL}, - {"setsync", CTLADM_CMD_SETSYNC, CTLADM_ARG_NEED_TL, "i:"}, - {"shutdown", CTLADM_CMD_SHUTDOWN, CTLADM_ARG_NONE, NULL}, {"start", CTLADM_CMD_START, CTLADM_ARG_NEED_TL, startstop_opts}, - {"startup", CTLADM_CMD_STARTUP, CTLADM_ARG_NONE, NULL}, {"stop", CTLADM_CMD_STOP, CTLADM_ARG_NEED_TL, startstop_opts}, {"synccache", CTLADM_CMD_SYNC_CACHE, CTLADM_ARG_NEED_TL, "b:c:il:r"}, {"tur", CTLADM_CMD_TUR, CTLADM_ARG_NEED_TL, NULL}, @@ -212,15 +202,11 @@ static struct ctladm_opts option_table[] = { ctladm_optret getoption(struct ctladm_opts *table, char *arg, uint32_t *cmdnum, ctladm_cmdargs *argnum, const char **subopt); static int cctl_dump_ooa(int fd, int argc, char **argv); -static int cctl_port_dump(int fd, int quiet, int xml, int32_t fe_num, - ctl_port_type port_type); static int cctl_port(int fd, int argc, char **argv, char *combinedopt); static int cctl_do_io(int fd, int retries, union ctl_io *io, const char *func); static int cctl_delay(int fd, int lun, int argc, char **argv, char *combinedopt); static int cctl_lunlist(int fd); -static int cctl_startup_shutdown(int fd, int lun, int iid, - ctladm_cmdfunction command); static int cctl_sync_cache(int fd, int lun, int iid, int retries, int argc, char **argv, char *combinedopt); static int cctl_start_stop(int fd, int lun, int iid, int retries, @@ -253,6 +239,7 @@ static int cctl_create_lun(int fd, int argc, char **argv, char *combinedopt); static int cctl_inquiry_vpd_devid(int fd, int lun, int initiator); static int cctl_report_target_port_group(int fd, int lun, int initiator); static int cctl_modify_lun(int fd, int argc, char **argv, char *combinedopt); +static int cctl_portlist(int fd, int argc, char **argv, char *combinedopt); ctladm_optret getoption(struct ctladm_opts *table, char *arg, uint32_t *cmdnum, @@ -287,9 +274,7 @@ cctl_dump_ooa(int fd, int argc, char **argv) { struct ctl_ooa ooa; long double cmd_latency; - int num_entries, len; - int lun = -1; - int retval; + int num_entries, len, lun = -1, retval = 0; unsigned int i; num_entries = 104; @@ -299,21 +284,16 @@ cctl_dump_ooa(int fd, int argc, char **argv) retry: len = num_entries * sizeof(struct ctl_ooa_entry); - bzero(&ooa, sizeof(ooa)); - ooa.entries = malloc(len); - if (ooa.entries == NULL) { warn("%s: error mallocing %d bytes", __func__, len); return (1); } - - if (argc > 2) { + if (lun >= 0) { ooa.lun_num = lun; } else ooa.flags |= CTL_OOA_FLAG_ALL_LUNS; - ooa.alloc_len = len; ooa.alloc_num = num_entries; if (ioctl(fd, CTL_GET_OOA, &ooa) == -1) { @@ -368,17 +348,10 @@ retry: cmd_latency); } fprintf(stdout, "OOA queues dump done\n"); -#if 0 - if (ioctl(fd, CTL_DUMP_OOA) == -1) { - warn("%s: CTL_DUMP_OOA ioctl failed", __func__); - return (1); - } -#endif bailout: free(ooa.entries); - - return (0); + return (retval); } static int @@ -391,152 +364,6 @@ cctl_dump_structs(int fd, ctladm_cmdargs cmdargs __unused) return (0); } -static int -cctl_port_dump(int fd, int quiet, int xml, int32_t targ_port, - ctl_port_type port_type) -{ - struct ctl_port_list port_list; - struct ctl_port_entry *entries; - struct sbuf *sb = NULL; - int num_entries; - int did_print = 0; - unsigned int i; - - num_entries = 16; - -retry: - - entries = malloc(sizeof(*entries) * num_entries); - bzero(&port_list, sizeof(port_list)); - port_list.entries = entries; - port_list.alloc_num = num_entries; - port_list.alloc_len = num_entries * sizeof(*entries); - if (ioctl(fd, CTL_GET_PORT_LIST, &port_list) != 0) { - warn("%s: CTL_GET_PORT_LIST ioctl failed", __func__); - return (1); - } - if (port_list.status == CTL_PORT_LIST_NEED_MORE_SPACE) { - printf("%s: allocated %d, need %d, retrying\n", __func__, - num_entries, port_list.fill_num + port_list.dropped_num); - free(entries); - num_entries = port_list.fill_num + port_list.dropped_num; - goto retry; - } - - if ((quiet == 0) - && (xml == 0)) - printf("Port Online Type Name pp vp %-18s %-18s\n", - "WWNN", "WWPN"); - - if (xml != 0) { - sb = sbuf_new_auto(); - sbuf_printf(sb, "<ctlfelist>\n"); - } - for (i = 0; i < port_list.fill_num; i++) { - struct ctl_port_entry *entry; - const char *type; - - entry = &entries[i]; - - switch (entry->port_type) { - case CTL_PORT_FC: - type = "FC"; - break; - case CTL_PORT_SCSI: - type = "SCSI"; - break; - case CTL_PORT_IOCTL: - type = "IOCTL"; - break; - case CTL_PORT_INTERNAL: - type = "INTERNAL"; - break; - case CTL_PORT_ISC: - type = "ISC"; - break; - case CTL_PORT_ISCSI: - type = "ISCSI"; - break; - case CTL_PORT_SAS: - type = "SAS"; - break; - default: - type = "UNKNOWN"; - break; - } - - /* - * If the user specified a frontend number or a particular - * frontend type, only print out that particular frontend - * or frontend type. - */ - if ((targ_port != -1) - && (targ_port != entry->targ_port)) - continue; - else if ((port_type != CTL_PORT_NONE) - && ((port_type & entry->port_type) == 0)) - continue; - - did_print = 1; - -#if 0 - printf("Num: %ju Type: %s (%#x) Name: %s Physical Port: %d " - "Virtual Port: %d\n", (uintmax_t)entry->fe_num, type, - entry->port_type, entry->fe_name, entry->physical_port, - entry->virtual_port); - printf("WWNN %#jx WWPN %#jx Online: %s\n", - (uintmax_t)entry->wwnn, (uintmax_t)entry->wwpn, - (entry->online) ? "YES" : "NO" ); -#endif - if (xml == 0) { - printf("%-4d %-6s %-8s %-12s %-2d %-2d %#-18jx " - "%#-18jx\n", - entry->targ_port, (entry->online) ? "YES" : "NO", - type, entry->port_name, entry->physical_port, - entry->virtual_port, (uintmax_t)entry->wwnn, - (uintmax_t)entry->wwpn); - } else { - sbuf_printf(sb, "<targ_port id=\"%d\">\n", - entry->targ_port); - sbuf_printf(sb, "<online>%s</online>\n", - (entry->online) ? "YES" : "NO"); - sbuf_printf(sb, "<port_type>%s</port_type>\n", type); - sbuf_printf(sb, "<port_name>%s</port_name>\n", - entry->port_name); - sbuf_printf(sb, "<physical_port>%d</physical_port>\n", - entry->physical_port); - sbuf_printf(sb, "<virtual_port>%d</virtual_port>\n", - entry->virtual_port); - sbuf_printf(sb, "<wwnn>%#jx</wwnn>\n", - (uintmax_t)entry->wwnn); - sbuf_printf(sb, "<wwpn>%#jx</wwpn>\n", - (uintmax_t)entry->wwpn); - sbuf_printf(sb, "</targ_port>\n"); - } - - } - if (xml != 0) { - sbuf_printf(sb, "</ctlfelist>\n"); - if (sbuf_finish(sb) != 0) - err(1, "%s: sbuf_finish", __func__); - printf("%s", sbuf_data(sb)); - sbuf_delete(sb); - } - - /* - * Give some indication that we didn't find the frontend or - * frontend type requested by the user. We could print something - * out, but it would probably be better to hide that behind a - * verbose flag. - */ - if ((did_print == 0) - && ((targ_port != -1) - || (port_type != CTL_PORT_NONE))) - return (1); - else - return (0); -} - typedef enum { CCTL_PORT_MODE_NONE, CCTL_PORT_MODE_LIST, @@ -672,9 +499,22 @@ cctl_port(int fd, int argc, char **argv, char *combinedopt) entry.targ_port = targ_port; switch (port_mode) { - case CCTL_PORT_MODE_LIST: - cctl_port_dump(fd, quiet, xml, targ_port, port_type); + case CCTL_PORT_MODE_LIST: { + char opts[] = "xq"; + char argx[] = "-x"; + char argq[] = "-q"; + char *argvx[2]; + int argcx = 0; + + optind = 0; + optreset = 1; + if (xml) + argvx[argcx++] = argx; + if (quiet) + argvx[argcx++] = argq; + cctl_portlist(fd, argcx, argvx, opts); break; + } case CCTL_PORT_MODE_SET: if (targ_port == -1) { warnx("%s: -w and -W require -n", __func__); @@ -839,136 +679,10 @@ cctl_delay(int fd, int lun, int argc, char **argv, retval = 1; break; } -bailout: - - /* delayloc should never be NULL, but just in case...*/ - if (delayloc != NULL) - free(delayloc); - - return (retval); -} - -static int -cctl_realsync(int fd, int argc, char **argv) -{ - int syncstate; - int retval; - char *syncarg; - - retval = 0; - - if (argc != 3) { - warnx("%s %s takes exactly one argument", argv[0], argv[1]); - retval = 1; - goto bailout; - } - - syncarg = argv[2]; - - if (strncasecmp(syncarg, "query", min(strlen(syncarg), - strlen("query"))) == 0) { - if (ioctl(fd, CTL_REALSYNC_GET, &syncstate) == -1) { - warn("%s: CTL_REALSYNC_GET ioctl failed", __func__); - retval = 1; - goto bailout; - } - fprintf(stdout, "SYNCHRONIZE CACHE support is: "); - switch (syncstate) { - case 0: - fprintf(stdout, "OFF\n"); - break; - case 1: - fprintf(stdout, "ON\n"); - break; - default: - fprintf(stdout, "unknown (%d)\n", syncstate); - break; - } - goto bailout; - } else if (strcasecmp(syncarg, "on") == 0) { - syncstate = 1; - } else if (strcasecmp(syncarg, "off") == 0) { - syncstate = 0; - } else { - warnx("%s: invalid realsync argument %s", __func__, syncarg); - retval = 1; - goto bailout; - } - - if (ioctl(fd, CTL_REALSYNC_SET, &syncstate) == -1) { - warn("%s: CTL_REALSYNC_SET ioctl failed", __func__); - retval = 1; - goto bailout; - } -bailout: - return (retval); -} - -static int -cctl_getsetsync(int fd, int lun, ctladm_cmdfunction command, - int argc, char **argv, char *combinedopt) -{ - struct ctl_sync_info sync_info; - uint32_t ioctl_cmd; - int sync_interval = -1; - int retval; - int c; - - retval = 0; - - memset(&sync_info, 0, sizeof(sync_info)); - sync_info.lun_id = lun; - - while ((c = getopt(argc, argv, combinedopt)) != -1) { - switch (c) { - case 'i': - sync_interval = strtoul(optarg, NULL, 0); - break; - default: - break; - } - } - - if (command == CTLADM_CMD_SETSYNC) { - if (sync_interval == -1) { - warnx("%s: you must specify the sync interval with -i", - __func__); - retval = 1; - goto bailout; - } - sync_info.sync_interval = sync_interval; - ioctl_cmd = CTL_SETSYNC; - } else { - ioctl_cmd = CTL_GETSYNC; - } - - if (ioctl(fd, ioctl_cmd, &sync_info) == -1) { - warn("%s: CTL_%sSYNC ioctl failed", __func__, - (command == CTLADM_CMD_SETSYNC) ? "SET" : "GET"); - retval = 1; - goto bailout; - } - switch (sync_info.status) { - case CTL_GS_SYNC_OK: - if (command == CTLADM_CMD_GETSYNC) { - fprintf(stdout, "%d: sync interval: %d\n", - lun, sync_info.sync_interval); - } - break; - case CTL_GS_SYNC_NO_LUN: - warnx("%s: unknown LUN %d", __func__, lun); - retval = 1; - break; - case CTL_GS_SYNC_NONE: - default: - warnx("%s: unknown CTL_%sSYNC status %d", __func__, - (command == CTLADM_CMD_SETSYNC) ? "SET" : "GET", - sync_info.status); - retval = 1; - break; - } bailout: + free(delayloc); + free(delaytype); return (retval); } @@ -1225,9 +939,7 @@ cctl_lunlist(int fd) unsigned int i; int retval; - retval = 0; inq_data = NULL; - initid = 7; /* @@ -1292,160 +1004,6 @@ bailout: } static int -cctl_startup_shutdown(int fd, int lun, int iid, - ctladm_cmdfunction command) -{ - union ctl_io *io; - struct scsi_report_luns_data *lun_data; - struct scsi_inquiry_data *inq_data; - uint32_t num_luns; - unsigned int i; - int retval; - - retval = 0; - inq_data = NULL; - - /* - * - report luns - * - step through each lun, do an inquiry - * - check OOA queue on direct access luns - * - send stop with offline bit to each direct access device with a - * clear OOA queue - * - if we get a reservation conflict, reset the LUN to clear it - * and reissue the stop with the offline bit set - */ - - io = ctl_scsi_alloc_io(iid); - if (io == NULL) { - warnx("%s: can't allocate memory", __func__); - return (1); - } - - if ((retval = cctl_get_luns(fd, lun, iid, /*retries*/ 2, - &lun_data, &num_luns)) != 0) - goto bailout; - - inq_data = malloc(sizeof(*inq_data)); - if (inq_data == NULL) { - warn("%s: couldn't allocate memory for inquiry data\n", - __func__); - retval = 1; - goto bailout; - } - for (i = 0; i < num_luns; i++) { - char scsi_path[40]; - int lun_val; - - /* - * XXX KDM figure out a way to share this code with - * cctl_lunlist()? - */ - switch (lun_data->luns[i].lundata[0] & RPL_LUNDATA_ATYP_MASK) { - case RPL_LUNDATA_ATYP_PERIPH: - lun_val = lun_data->luns[i].lundata[1]; - break; - case RPL_LUNDATA_ATYP_FLAT: - lun_val = (lun_data->luns[i].lundata[0] & - RPL_LUNDATA_FLAT_LUN_MASK) | - (lun_data->luns[i].lundata[1] << - RPL_LUNDATA_FLAT_LUN_BITS); - break; - case RPL_LUNDATA_ATYP_LUN: - case RPL_LUNDATA_ATYP_EXTLUN: - default: - fprintf(stdout, "Unsupported LUN format %d\n", - lun_data->luns[i].lundata[0] & - RPL_LUNDATA_ATYP_MASK); - lun_val = -1; - break; - } - if (lun_val == -1) - continue; - - if ((retval = cctl_get_inquiry(fd, lun_val, iid, - /*retries*/ 2, scsi_path, - sizeof(scsi_path), - inq_data)) != 0) { - goto bailout; - } - printf("%s", scsi_path); - scsi_print_inquiry(inq_data); - /* - * We only want to shutdown direct access devices. - */ - if (SID_TYPE(inq_data) != T_DIRECT) { - printf("%s LUN is not direct access, skipped\n", - scsi_path); - continue; - } - - if (command == CTLADM_CMD_SHUTDOWN) { - struct ctl_ooa_info ooa_info; - - ooa_info.lun_id = lun_val; - - if (ioctl(fd, CTL_CHECK_OOA, &ooa_info) == -1) { - printf("%s CTL_CHECK_OOA ioctl failed\n", - scsi_path); - continue; - } - - if (ooa_info.status != CTL_OOA_SUCCESS) { - printf("%s CTL_CHECK_OOA returned status %d\n", - scsi_path, ooa_info.status); - continue; - } - if (ooa_info.num_entries != 0) { - printf("%s %d entr%s in the OOA queue, " - "skipping shutdown\n", scsi_path, - ooa_info.num_entries, - (ooa_info.num_entries > 1)?"ies" : "y" ); - continue; - } - } - - ctl_scsi_start_stop(/*io*/ io, - /*start*/(command == CTLADM_CMD_STARTUP) ? - 1 : 0, - /*load_eject*/ 0, - /*immediate*/ 0, - /*power_conditions*/ SSS_PC_START_VALID, - /*onoffline*/ 1, - /*ctl_tag_type*/ - (command == CTLADM_CMD_STARTUP) ? - CTL_TAG_SIMPLE :CTL_TAG_ORDERED, - /*control*/ 0); - - io->io_hdr.nexus.targ_lun = lun_val; - io->io_hdr.nexus.initid = iid; - - if (cctl_do_io(fd, /*retries*/ 3, io, __func__) != 0) { - retval = 1; - goto bailout; - } - - if ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_SUCCESS) - ctl_io_error_print(io, inq_data, stderr); - else { - printf("%s LUN is now %s\n", scsi_path, - (command == CTLADM_CMD_STARTUP) ? "online" : - "offline"); - } - } -bailout: - if (lun_data != NULL) - free(lun_data); - - if (inq_data != NULL) - free(inq_data); - - if (io != NULL) - ctl_scsi_free_io(io); - - return (retval); -} - -static int cctl_sync_cache(int fd, int lun, int iid, int retries, int argc, char **argv, char *combinedopt) { @@ -1535,7 +1093,7 @@ cctl_start_stop(int fd, int lun, int iid, int retries, int start, { union ctl_io *io; char scsi_path[40]; - int immed = 0, onoffline = 0; + int immed = 0; int retval, c; retval = 0; @@ -1551,9 +1109,6 @@ cctl_start_stop(int fd, int lun, int iid, int retries, int start, case 'i': immed = 1; break; - case 'o': - onoffline = 1; - break; default: break; } @@ -1570,7 +1125,6 @@ cctl_start_stop(int fd, int lun, int iid, int retries, int start, /*load_eject*/ 0, /*immediate*/ immed, /*power_conditions*/ SSS_PC_START_VALID, - /*onoffline*/ onoffline, /*ctl_tag_type*/ start ? CTL_TAG_SIMPLE : CTL_TAG_ORDERED, /*control*/ 0); @@ -2319,8 +1873,6 @@ cctl_inquiry(int fd, int lun, int iid, int retries) char scsi_path[40]; int retval; - retval = 0; - inq_data = malloc(sizeof(*inq_data)); if (inq_data == NULL) { warnx("%s: can't allocate inquiry data", __func__); @@ -2586,8 +2138,6 @@ cctl_persistent_reserve_in(int fd, int lun, int iid, if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS) { int returned_len, used_len; - returned_len = 0; - switch (action) { case 0: returned_len = scsi_4btoul(&dataptr[4]) + 8; @@ -4303,19 +3853,14 @@ usage(int error) " ctladm remove <-b backend> <-l lun_id> [-o name=value]\n" " ctladm modify <-b backend> <-l lun_id> <-s size_bytes>\n" " ctladm devlist [-b backend] [-v] [-x]\n" -" ctladm shutdown\n" -" ctladm startup\n" " ctladm lunlist\n" " ctladm lunmap -p targ_port [-l pLUN] [-L cLUN]\n" " ctladm delay [dev_id] <-l datamove|done> [-T oneshot|cont]\n" " [-t secs]\n" -" ctladm realsync <on|off|query>\n" -" ctladm setsync [dev_id] <-i interval>\n" -" ctladm getsync [dev_id]\n" " ctladm inject [dev_id] <-i action> <-p pattern> [-r lba,len]\n" " [-s len fmt [args]] [-c] [-d delete_id]\n" -" ctladm port <-l | -o <on|off> | [-w wwnn][-W wwpn]>\n" -" [-p targ_port] [-t port_type] [-q] [-x]\n" +" ctladm port <-o <on|off> | [-w wwnn][-W wwpn]>\n" +" [-p targ_port] [-t port_type]\n" " ctladm portlist [-f frontend] [-i] [-p targ_port] [-q] [-v] [-x]\n" " ctladm islist [-v | -x]\n" " ctladm islogout <-a | -c connection-id | -i name | -p portal>\n" @@ -4655,25 +4200,12 @@ main(int argc, char **argv) retval = cctl_sync_cache(fd, lun, initid, retries, argc, argv, combinedopt); break; - case CTLADM_CMD_SHUTDOWN: - case CTLADM_CMD_STARTUP: - retval = cctl_startup_shutdown(fd, lun, initid, - command); - break; case CTLADM_CMD_LUNLIST: retval = cctl_lunlist(fd); break; case CTLADM_CMD_DELAY: retval = cctl_delay(fd, lun, argc, argv, combinedopt); break; - case CTLADM_CMD_REALSYNC: - retval = cctl_realsync(fd, argc, argv); - break; - case CTLADM_CMD_SETSYNC: - case CTLADM_CMD_GETSYNC: - retval = cctl_getsetsync(fd, lun, command, - argc, argv, combinedopt); - break; case CTLADM_CMD_ERR_INJECT: retval = cctl_error_inject(fd, lun, argc, argv, combinedopt); diff --git a/usr.sbin/ctld/ctl.conf.5 b/usr.sbin/ctld/ctl.conf.5 index ea1d07a..24c4c85 100644 --- a/usr.sbin/ctld/ctl.conf.5 +++ b/usr.sbin/ctld/ctl.conf.5 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 15, 2015 +.Dd September 27, 2015 .Dt CTL.CONF 5 .Os .Sh NAME @@ -394,6 +394,10 @@ By default CTL allocates those IDs dynamically, but explicit specification may be needed for consistency in HA configurations. .It Ic device-id Ar string The SCSI Device Identification string presented to the initiator. +.It Ic device-type Ar type +Specify the SCSI device type to use when creating the LUN. +Currently CTL supports Direct Access (type 0), Processor (type 3) +and CD/DVD (type 5) LUNs. .It Ic option Ar name Ar value The CTL-specific options passed to the kernel. All CTL-specific options are documented in the diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c index 143f2e3..12474ea 100644 --- a/usr.sbin/ctld/ctld.c +++ b/usr.sbin/ctld/ctld.c @@ -1149,7 +1149,7 @@ valid_iscsi_name(const char *name) } } else { log_warnx("invalid target name \"%s\"; should start with " - "either \".iqn\", \"eui.\", or \"naa.\"", + "either \"iqn.\", \"eui.\", or \"naa.\"", name); } return (true); @@ -1456,6 +1456,13 @@ lun_set_blocksize(struct lun *lun, size_t value) } void +lun_set_device_type(struct lun *lun, uint8_t value) +{ + + lun->l_device_type = value; +} + +void lun_set_device_id(struct lun *lun, const char *value) { free(lun->l_device_id); diff --git a/usr.sbin/ctld/ctld.h b/usr.sbin/ctld/ctld.h index 782db15..6eb878c 100644 --- a/usr.sbin/ctld/ctld.h +++ b/usr.sbin/ctld/ctld.h @@ -164,6 +164,7 @@ struct lun { TAILQ_HEAD(, lun_option) l_options; char *l_name; char *l_backend; + uint8_t l_device_type; int l_blocksize; char *l_device_id; char *l_path; @@ -375,6 +376,7 @@ struct lun *lun_new(struct conf *conf, const char *name); void lun_delete(struct lun *lun); struct lun *lun_find(const struct conf *conf, const char *name); void lun_set_backend(struct lun *lun, const char *value); +void lun_set_device_type(struct lun *lun, uint8_t value); void lun_set_blocksize(struct lun *lun, size_t value); void lun_set_device_id(struct lun *lun, const char *value); void lun_set_path(struct lun *lun, const char *value); diff --git a/usr.sbin/ctld/kernel.c b/usr.sbin/ctld/kernel.c index 6826e95..b9658b5 100644 --- a/usr.sbin/ctld/kernel.c +++ b/usr.sbin/ctld/kernel.c @@ -108,6 +108,7 @@ struct cctl_lun_nv { struct cctl_lun { uint64_t lun_id; char *backend_type; + uint8_t device_type; uint64_t size_blocks; uint32_t blocksize; char *serial_number; @@ -221,6 +222,8 @@ cctl_end_element(void *user_data, const char *name) if (strcmp(name, "backend_type") == 0) { cur_lun->backend_type = str; str = NULL; + } else if (strcmp(name, "lun_type") == 0) { + cur_lun->device_type = strtoull(str, NULL, 0); } else if (strcmp(name, "size") == 0) { cur_lun->size_blocks = strtoull(str, NULL, 0); } else if (strcmp(name, "blocksize") == 0) { @@ -475,7 +478,7 @@ retry_port: return (NULL); } - if (list.status == CTL_PORT_LIST_ERROR) { + if (list.status == CTL_LUN_LIST_ERROR) { log_warnx("error returned from CTL_PORT_LIST ioctl: %s", list.error_str); free(str); @@ -610,6 +613,7 @@ retry_port: continue; } lun_set_backend(cl, lun->backend_type); + lun_set_device_type(cl, lun->device_type); lun_set_blocksize(cl, lun->blocksize); lun_set_device_id(cl, lun->device_id); lun_set_serial(cl, lun->serial_number); @@ -668,7 +672,7 @@ kernel_lun_add(struct lun *lun) } req.reqdata.create.flags |= CTL_LUN_FLAG_DEV_TYPE; - req.reqdata.create.device_type = T_DIRECT; + req.reqdata.create.device_type = lun->l_device_type; if (lun->l_serial != NULL) { strncpy(req.reqdata.create.serial_num, lun->l_serial, diff --git a/usr.sbin/ctld/parse.y b/usr.sbin/ctld/parse.y index 6907b48..03a511f 100644 --- a/usr.sbin/ctld/parse.y +++ b/usr.sbin/ctld/parse.y @@ -57,8 +57,8 @@ extern void yyrestart(FILE *); %} %token ALIAS AUTH_GROUP AUTH_TYPE BACKEND BLOCKSIZE CHAP CHAP_MUTUAL -%token CLOSING_BRACKET CTL_LUN DEBUG DEVICE_ID DISCOVERY_AUTH_GROUP -%token DISCOVERY_FILTER FOREIGN +%token CLOSING_BRACKET CTL_LUN DEBUG DEVICE_ID DEVICE_TYPE +%token DISCOVERY_AUTH_GROUP DISCOVERY_FILTER FOREIGN %token INITIATOR_NAME INITIATOR_PORTAL ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT %token LISTEN LISTEN_ISER LUN MAXPROC OFFLOAD OPENING_BRACKET OPTION %token PATH PIDFILE PORT PORTAL_GROUP REDIRECT SEMICOLON SERIAL SIZE STR @@ -855,6 +855,8 @@ lun_entry: | lun_device_id | + lun_device_type + | lun_ctl_lun | lun_option @@ -914,6 +916,31 @@ lun_device_id: DEVICE_ID STR } ; +lun_device_type: DEVICE_TYPE STR + { + uint64_t tmp; + + if (strcasecmp($2, "disk") == 0 || + strcasecmp($2, "direct") == 0) + tmp = 0; + else if (strcasecmp($2, "processor") == 0) + tmp = 3; + else if (strcasecmp($2, "cd") == 0 || + strcasecmp($2, "cdrom") == 0 || + strcasecmp($2, "dvd") == 0 || + strcasecmp($2, "dvdrom") == 0) + tmp = 5; + else if (expand_number($2, &tmp) != 0 || + tmp > 15) { + yyerror("invalid numeric value"); + free($2); + return (1); + } + + lun_set_device_type(lun, tmp); + } + ; + lun_ctl_lun: CTL_LUN STR { uint64_t tmp; diff --git a/usr.sbin/ctld/token.l b/usr.sbin/ctld/token.l index 37989ce..e8cbf3b 100644 --- a/usr.sbin/ctld/token.l +++ b/usr.sbin/ctld/token.l @@ -57,6 +57,7 @@ chap-mutual { return CHAP_MUTUAL; } ctl-lun { return CTL_LUN; } debug { return DEBUG; } device-id { return DEVICE_ID; } +device-type { return DEVICE_TYPE; } discovery-auth-group { return DISCOVERY_AUTH_GROUP; } discovery-filter { return DISCOVERY_FILTER; } foreign { return FOREIGN; } diff --git a/usr.sbin/eeprom/Makefile.depend b/usr.sbin/eeprom/Makefile.depend index f52ca95..79eb58b 100644 --- a/usr.sbin/eeprom/Makefile.depend +++ b/usr.sbin/eeprom/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.sbin/etcupdate/etcupdate.8 b/usr.sbin/etcupdate/etcupdate.8 index c5a74f3..381d4ab 100644 --- a/usr.sbin/etcupdate/etcupdate.8 +++ b/usr.sbin/etcupdate/etcupdate.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 29, 2014 +.Dd September 29, 2015 .Dt ETCUPDATE 8 .Os .Sh NAME @@ -233,6 +233,16 @@ is changed, is invoked if .Pa /etc/mail/aliases is changed, +.Xr services_mkdb 8 +is invoked if +.Pa /etc/services +is changed, +.Xr tzsetup 8 +is invoked if +.Pa /etc/localtime +is changed and if +.Fa /var/db/zoneinfo +exists, and .Pa /etc/rc.d/motd is invoked if @@ -843,7 +853,9 @@ but it has been removed in the destination directory. .Xr make 1 , .Xr newaliases 1 , .Xr sh 1 , -.Xr pwd_mkdb 8 +.Xr pwd_mkdb 8 , +.Xr services_mkdb 8 , +.Xr tzsetup 8 .Sh HISTORY The .Nm diff --git a/usr.sbin/fifolog/Makefile b/usr.sbin/fifolog/Makefile index 59ac9fe..fbaaa89 100644 --- a/usr.sbin/fifolog/Makefile +++ b/usr.sbin/fifolog/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ -SUBDIR= lib fifolog_create fifolog_writer fifolog_reader +SUBDIR= lib .WAIT \ + fifolog_create fifolog_writer fifolog_reader +SUBDIR_PARALLEL= .include <bsd.subdir.mk> diff --git a/usr.sbin/gssd/gssd.c b/usr.sbin/gssd/gssd.c index 2540161..e85dfd7 100644 --- a/usr.sbin/gssd/gssd.c +++ b/usr.sbin/gssd/gssd.c @@ -751,8 +751,8 @@ gssd_pname_to_uid_1_svc(pname_to_uid_args *argp, pname_to_uid_res *result, struc buflen_hint = buflen; } if (pw) { - int len = NGRPS; - int groups[NGRPS]; + int len = NGROUPS; + int groups[NGROUPS]; result->gid = pw->pw_gid; getgrouplist(pw->pw_name, pw->pw_gid, groups, &len); diff --git a/usr.sbin/kgzip/Makefile.depend b/usr.sbin/kgzip/Makefile.depend index f52ca95..79eb58b 100644 --- a/usr.sbin/kgzip/Makefile.depend +++ b/usr.sbin/kgzip/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.sbin/lpr/Makefile b/usr.sbin/lpr/Makefile index 043ed8b..5873c07 100644 --- a/usr.sbin/lpr/Makefile +++ b/usr.sbin/lpr/Makefile @@ -1,7 +1,9 @@ # $FreeBSD$ -SUBDIR= common_source chkprintcap lp lpc lpd lpq lpr lprm lptest pac \ +SUBDIR= common_source .WAIT \ + chkprintcap lp lpc lpd lpq lpr lprm lptest pac \ filters filters.ru +SUBDIR_PARALLEL= # Questions/ideas for lpr & friends could also be sent to: # freebsd-print@bostonradio.org diff --git a/usr.sbin/lpr/filters.ru/Makefile.depend b/usr.sbin/lpr/filters.ru/Makefile.depend index 3af2d7f..f80275d 100644 --- a/usr.sbin/lpr/filters.ru/Makefile.depend +++ b/usr.sbin/lpr/filters.ru/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ diff --git a/usr.sbin/mergemaster/mergemaster.8 b/usr.sbin/mergemaster/mergemaster.8 index c3e22a0..d88bdd0 100644 --- a/usr.sbin/mergemaster/mergemaster.8 +++ b/usr.sbin/mergemaster/mergemaster.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 1, 2011 +.Dd September 29, 2015 .Dt MERGEMASTER 8 .Os .Sh NAME @@ -257,14 +257,13 @@ Specify the path to the directory where you want to do the .Xr make 1 . (In other words, where your sources are, but -s was already taken.) -In previous versions of +In older versions of .Nm -you needed to specify the path all the way to -.Pa src/etc . -Starting with r186678 you only need to specify the path to -.Pa src . +the path to +.Pa src/etc +was required. .Nm -will convert the path for you if you use the old method. +will convert the path if this older method is used. .It Fl t Ar /path/to/temp/root Create the temporary root environment in .Pa /path/to/temp/root diff --git a/usr.sbin/mount_smbfs/Makefile.depend b/usr.sbin/mount_smbfs/Makefile.depend index 179190c..4e37118 100644 --- a/usr.sbin/mount_smbfs/Makefile.depend +++ b/usr.sbin/mount_smbfs/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c index 4837b06..a14520c 100644 --- a/usr.sbin/ndp/ndp.c +++ b/usr.sbin/ndp/ndp.c @@ -649,6 +649,8 @@ again:; if (rtm->rtm_flags & RTF_CLONED) delete(host_buf); #else + if (rtm->rtm_flags & RTF_PINNED) + continue; delete(host_buf); #endif continue; diff --git a/usr.sbin/nmtree/Makefile.depend b/usr.sbin/nmtree/Makefile.depend index d8f68b0..87dbfec 100644 --- a/usr.sbin/nmtree/Makefile.depend +++ b/usr.sbin/nmtree/Makefile.depend @@ -1,12 +1,17 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - DIRDEPS = \ - tools/c/sjg/work/FreeBSD/projects-bmake/src/lib/libnetbsd.host \ - tools/legacy/usr/include.host \ - tools/legacy/usr/lib.host \ + gnu/lib/csu \ + gnu/lib/libgcc \ + include \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + lib/libmd \ + lib/libnetbsd \ + lib/libutil \ .include <dirdeps.mk> diff --git a/usr.sbin/ofwdump/Makefile.depend b/usr.sbin/ofwdump/Makefile.depend index f52ca95..79eb58b 100644 --- a/usr.sbin/ofwdump/Makefile.depend +++ b/usr.sbin/ofwdump/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.sbin/pc-sysinstall/Makefile b/usr.sbin/pc-sysinstall/Makefile index aba8db7..d079e16 100644 --- a/usr.sbin/pc-sysinstall/Makefile +++ b/usr.sbin/pc-sysinstall/Makefile @@ -1,5 +1,6 @@ # $FreeBSD$ SUBDIR=backend backend-partmanager backend-query conf doc examples SUBDIR+=pc-sysinstall +SUBDIR_PARALLEL= .include <bsd.subdir.mk> diff --git a/usr.sbin/pnpinfo/Makefile.depend b/usr.sbin/pnpinfo/Makefile.depend index f52ca95..79eb58b 100644 --- a/usr.sbin/pnpinfo/Makefile.depend +++ b/usr.sbin/pnpinfo/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.sbin/rpcbind/rpcb_svc_com.c b/usr.sbin/rpcbind/rpcb_svc_com.c index a362c85..a88f619 100644 --- a/usr.sbin/rpcbind/rpcb_svc_com.c +++ b/usr.sbin/rpcbind/rpcb_svc_com.c @@ -47,6 +47,7 @@ #include <rpc/rpc.h> #include <rpc/rpcb_prot.h> #include <rpc/svc_dg.h> +#include <assert.h> #include <netconfig.h> #include <errno.h> #include <syslog.h> @@ -1047,19 +1048,31 @@ netbufcmp(struct netbuf *n1, struct netbuf *n2) return ((n1->len != n2->len) || memcmp(n1->buf, n2->buf, n1->len)); } +static bool_t +netbuf_copybuf(struct netbuf *dst, const struct netbuf *src) +{ + + assert(dst->buf == NULL); + + if ((dst->buf = malloc(src->len)) == NULL) + return (FALSE); + + dst->maxlen = dst->len = src->len; + memcpy(dst->buf, src->buf, src->len); + return (TRUE); +} + static struct netbuf * netbufdup(struct netbuf *ap) { struct netbuf *np; - if ((np = malloc(sizeof(struct netbuf))) == NULL) + if ((np = calloc(1, sizeof(struct netbuf))) == NULL) return (NULL); - if ((np->buf = malloc(ap->len)) == NULL) { + if (netbuf_copybuf(np, ap) == FALSE) { free(np); return (NULL); } - np->maxlen = np->len = ap->len; - memcpy(np->buf, ap->buf, ap->len); return (np); } @@ -1067,6 +1080,7 @@ static void netbuffree(struct netbuf *ap) { free(ap->buf); + ap->buf = NULL; free(ap); } @@ -1184,7 +1198,7 @@ xprt_set_caller(SVCXPRT *xprt, struct finfo *fi) { u_int32_t *xidp; - *(svc_getrpccaller(xprt)) = *(fi->caller_addr); + netbuf_copybuf(svc_getrpccaller(xprt), fi->caller_addr); xidp = __rpcb_get_dg_xidp(xprt); *xidp = fi->caller_xid; } diff --git a/usr.sbin/unbound/Makefile b/usr.sbin/unbound/Makefile index 3eb12fe..94cfdc3 100644 --- a/usr.sbin/unbound/Makefile +++ b/usr.sbin/unbound/Makefile @@ -2,5 +2,6 @@ SUBDIR= daemon anchor checkconf control SUBDIR+= local-setup +SUBDIR_PARALLEL= .include <bsd.subdir.mk> diff --git a/usr.sbin/vigr/Makefile b/usr.sbin/vigr/Makefile index d71998b..52b548e 100644 --- a/usr.sbin/vigr/Makefile +++ b/usr.sbin/vigr/Makefile @@ -2,5 +2,6 @@ SCRIPTS= vigr MAN= vigr.8 +CLEANFILES= vigr .include <bsd.prog.mk> diff --git a/usr.sbin/wlconfig/Makefile.depend b/usr.sbin/wlconfig/Makefile.depend index f52ca95..79eb58b 100644 --- a/usr.sbin/wlconfig/Makefile.depend +++ b/usr.sbin/wlconfig/Makefile.depend @@ -1,10 +1,6 @@ # $FreeBSD$ # Autogenerated - do NOT edit! -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DEP_MACHINE := ${.PARSEFILE:E} - DIRDEPS = \ gnu/lib/libgcc \ include \ diff --git a/usr.sbin/wpa/Makefile b/usr.sbin/wpa/Makefile index 5d746e9..ae07ec0 100644 --- a/usr.sbin/wpa/Makefile +++ b/usr.sbin/wpa/Makefile @@ -3,5 +3,6 @@ SUBDIR= wpa_supplicant wpa_cli wpa_passphrase SUBDIR+= hostapd hostapd_cli SUBDIR+= ndis_events +SUBDIR_PARALLEL= .include <bsd.subdir.mk> |