From 62b042bedd273c65645b987848e62d2af6a6f0dd Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Fri, 6 Jan 2017 21:08:19 +0000 Subject: [PATCH 01/55] Carry over r311520 to tools/build/options/WITHOUT_USB_GADGET_EXAMPLES Discussed with: wblock r311520: Fix src.conf(5) description of WITHOUT_USB_GADGET_EXAMPLES. PR: 215831 Submitted by: p5B2E9A8F@t-online.de MFC after: 1 week X-MFC with: r311520 Sponsored by: iXsystems --- tools/build/options/WITHOUT_USB_GADGET_EXAMPLES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build/options/WITHOUT_USB_GADGET_EXAMPLES b/tools/build/options/WITHOUT_USB_GADGET_EXAMPLES index 2ecbdb72c00..154ebb550c0 100644 --- a/tools/build/options/WITHOUT_USB_GADGET_EXAMPLES +++ b/tools/build/options/WITHOUT_USB_GADGET_EXAMPLES @@ -1,2 +1,2 @@ .\" $FreeBSD$ -Set to build USB gadget kernel modules. +Set to not build USB gadget kernel modules. From d60571b4a95433bcefe5ae97e9fd15f65ef1d5d4 Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Fri, 6 Jan 2017 21:14:07 +0000 Subject: [PATCH 02/55] Regenerate src.conf(5) after r311548 MFC after: 1 week --- share/man/man5/src.conf.5 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5 index ca677971335..971a36951b5 100644 --- a/share/man/man5/src.conf.5 +++ b/share/man/man5/src.conf.5 @@ -1,7 +1,7 @@ .\" DO NOT EDIT-- this file is automatically generated. .\" from FreeBSD: head/tools/build/options/makeman 306729 2016-10-05 20:12:00Z emaste .\" $FreeBSD$ -.Dd January 2, 2017 +.Dd January 6, 2017 .Dt SRC.CONF 5 .Os .Sh NAME @@ -1628,7 +1628,7 @@ and related programs. .\" from FreeBSD: head/tools/build/options/WITHOUT_USB 156932 2006-03-21 07:50:50Z ru Set to not build USB-related programs and libraries. .It Va WITHOUT_USB_GADGET_EXAMPLES -.\" from FreeBSD: head/tools/build/options/WITHOUT_USB_GADGET_EXAMPLES 274665 2014-11-18 17:06:50Z imp +.\" from FreeBSD: head/tools/build/options/WITHOUT_USB_GADGET_EXAMPLES 311548 2017-01-06 21:08:19Z ngie Set to not build USB gadget kernel modules. .It Va WITHOUT_UTMPX .\" from FreeBSD: head/tools/build/options/WITHOUT_UTMPX 231530 2012-02-11 20:28:42Z ed From dba092b1097884ae8e928c9b5409a95d279d7f04 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Fri, 6 Jan 2017 21:40:30 +0000 Subject: [PATCH 03/55] After r311459, some ports can break, because a few of the newly added prototypes in use FILE. Pull in a minimal forward declaration of FILE from to minimize impact. Sorry for the breakage. Reported by: Shawn Webb X-MFC-With: r311459 --- contrib/tcp_wrappers/tcpd.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contrib/tcp_wrappers/tcpd.h b/contrib/tcp_wrappers/tcpd.h index 09e42ba6ee8..1078073c8e3 100644 --- a/contrib/tcp_wrappers/tcpd.h +++ b/contrib/tcp_wrappers/tcpd.h @@ -12,6 +12,11 @@ #define TCPD_SOCKADDR struct sockaddr_in #endif +#ifndef _STDFILE_DECLARED +#define _STDFILE_DECLARED +typedef struct __sFILE FILE; +#endif + /* Structure to describe one communications endpoint. */ #define STRING_LENGTH 128 /* hosts, users, processes */ From dc6e1047cec530d25eab3af163ad9c70d0124f62 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Fri, 6 Jan 2017 23:05:29 +0000 Subject: [PATCH 04/55] Link llvm-ar to llvm-ranlib, if WITH_CLANG_EXTRAS is enabled. When invoked as llvm-ranlib, it can create an archive symbol table for archives of objects compiled for LTO by an LLVM compiler. Submitted by: Dan McGregor MFC after: 3 days --- tools/build/mk/OptionalObsoleteFiles.inc | 1 + usr.bin/clang/llvm-ar/Makefile | 2 ++ 2 files changed, 3 insertions(+) diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index c99a146a564..a7708cc08c7 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -1489,6 +1489,7 @@ OLD_FILES+=usr/bin/llvm-lto OLD_FILES+=usr/bin/llvm-mc OLD_FILES+=usr/bin/llvm-nm OLD_FILES+=usr/bin/llvm-pdbdump +OLD_FILES+=usr/bin/llvm-ranlib OLD_FILES+=usr/bin/llvm-rtdyld OLD_FILES+=usr/bin/llvm-symbolizer OLD_FILES+=usr/bin/opt diff --git a/usr.bin/clang/llvm-ar/Makefile b/usr.bin/clang/llvm-ar/Makefile index 54688212749..f6116ecefcc 100644 --- a/usr.bin/clang/llvm-ar/Makefile +++ b/usr.bin/clang/llvm-ar/Makefile @@ -7,4 +7,6 @@ SRCS+= llvm-ar.cpp LIBADD+= z +LINKS+= ${BINDIR}/llvm-ar ${BINDIR}/llvm-ranlib + .include "../llvm.prog.mk" From 452a3101674c96bc97913f2e7b38be13c7ee7f20 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 6 Jan 2017 23:20:59 +0000 Subject: [PATCH 05/55] Set -m32 in MD LIB32CPUCFLAGS rather than MI LIB32CFLAGS. Both amd64 and powerpc64 use -m32 to compile 32-bit binaries, but not all platforms follow this convention. Move the -m32 compile flag into the per-architecture flags to accomodate other architectures. Sponsored by: DARPA / AFRL --- Makefile.libcompat | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile.libcompat b/Makefile.libcompat index a2a25cfd2bb..b1aa86249aa 100644 --- a/Makefile.libcompat +++ b/Makefile.libcompat @@ -15,6 +15,7 @@ LIB32CPUFLAGS= -march=i686 -mmmx -msse -msse2 .else LIB32CPUFLAGS= -march=${TARGET_CPUTYPE} .endif +LIB32CPUFLAGS+= -m32 LIB32WMAKEENV= MACHINE=i386 MACHINE_ARCH=i386 \ MACHINE_CPU="i686 mmx sse sse2" LIB32WMAKEFLAGS= \ @@ -28,6 +29,7 @@ LIB32CPUFLAGS= -mcpu=powerpc .else LIB32CPUFLAGS= -mcpu=${TARGET_CPUTYPE} .endif +LIB32CPUFLAGS+= -m32 LIB32WMAKEENV= MACHINE=powerpc MACHINE_ARCH=powerpc LIB32WMAKEFLAGS= \ LD="${XLD} -m elf32ppc_fbsd" \ @@ -35,7 +37,7 @@ LIB32WMAKEFLAGS= \ .endif -LIB32CFLAGS= -m32 -DCOMPAT_32BIT +LIB32CFLAGS= -DCOMPAT_32BIT LIB32DTRACE= ${DTRACE} -32 LIB32WMAKEFLAGS+= -DCOMPAT_32BIT From 69b4d461bef57a2b7a4dcd20c2c0faff4f25eb85 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 6 Jan 2017 23:30:54 +0000 Subject: [PATCH 06/55] Enable /usr/lib32 for o32 binaries on mips64. Build and install an o32 set of libraries on mips64 suitable for running o32 binaries via COMPAT_FREEBSD32. Enable COMPAT_FREEBSD32 in MALTA64. Reviewed by: jmallett, imp Sponsored by: DARPA / AFRL Differential Revision: https://reviews.freebsd.org/D9032 --- Makefile.inc1 | 2 +- Makefile.libcompat | 18 ++++++++++++++++-- gnu/lib/libgcc/Makefile | 3 ++- gnu/usr.bin/binutils/ld/Makefile.mips | 1 + sys/mips/conf/MALTA64 | 2 ++ 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 5631d2c61f0..dfa8e1e57b0 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -606,7 +606,7 @@ XCFLAGS+= ${BFLAGS} .endif .if ${MK_LIB32} != "no" && (${TARGET_ARCH} == "amd64" || \ - ${TARGET_ARCH} == "powerpc64") + ${TARGET_ARCH} == "powerpc64") || ${TARGET_ARCH:Mmips64*} != "" LIBCOMPAT= 32 .include "Makefile.libcompat" .elif ${MK_LIBSOFT} != "no" && ${TARGET_ARCH} == "armv6" diff --git a/Makefile.libcompat b/Makefile.libcompat index b1aa86249aa..ea2a2e69d94 100644 --- a/Makefile.libcompat +++ b/Makefile.libcompat @@ -4,8 +4,7 @@ __<${_this:T}>__: # Makefile for the compatibility libraries. -# - 32-bit compat libraries on PowerPC and AMD64. -# could also be for mips, but that doesn't work today. +# - 32-bit compat libraries on MIPS, PowerPC, and AMD64. # ------------------------------------------------------------------- # 32 bit world @@ -34,6 +33,21 @@ LIB32WMAKEENV= MACHINE=powerpc MACHINE_ARCH=powerpc LIB32WMAKEFLAGS= \ LD="${XLD} -m elf32ppc_fbsd" \ OBJCOPY="${XOBJCOPY}" + +.elif ${TARGET_ARCH:Mmips64*} != "" +.if empty(TARGET_CPUTYPE) +LIB32CPUFLAGS= -march=mips3 +.else +LIB32CPUFLAGS= -march=${TARGET_CPUTYPE} +.endif +LIB32CPUFLAGS+= -mabi=32 +LIB32WMAKEENV= MACHINE=mips MACHINE_ARCH=mips +.if ${TARGET_ARCH:Mmips64el*} != "" +LIB32WMAKEFLAGS= LD="${XLD} -m elf32ltsmip_fbsd" +.else +LIB32WMAKEFLAGS= LD="${XLD} -m elf32btsmip_fbsd" +.endif +LIB32WMAKEFLAGS+= OBJCOPY="${XOBJCOPY}" .endif diff --git a/gnu/lib/libgcc/Makefile b/gnu/lib/libgcc/Makefile index 0d53c12c843..157495368c7 100644 --- a/gnu/lib/libgcc/Makefile +++ b/gnu/lib/libgcc/Makefile @@ -133,7 +133,8 @@ LIBADD+= compiler_rt .if ${TARGET_CPUARCH} == mips LIB2FUNCS_EXTRA = floatunsidf.c floatunsisf.c # ABIs other than o32 need this -.if ${TARGET_ARCH:Mmips64*} != "" || ${TARGET_ARCH:Mmipsn32*} != "" +.if (${TARGET_ARCH:Mmips64*} != "" || ${TARGET_ARCH:Mmipsn32*} != "") && \ + !defined(COMPAT_32BIT) LIB2FUNCS_EXTRA+= floatdidf.c fixunsdfsi.c LIB2FUNCS_EXTRA+= floatdisf.c floatundidf.c LIB2FUNCS_EXTRA+= fixsfdi.c floatundisf.c diff --git a/gnu/usr.bin/binutils/ld/Makefile.mips b/gnu/usr.bin/binutils/ld/Makefile.mips index afc651cfca9..7ed3a56059f 100644 --- a/gnu/usr.bin/binutils/ld/Makefile.mips +++ b/gnu/usr.bin/binutils/ld/Makefile.mips @@ -8,6 +8,7 @@ _EMULATION_ENDIAN=b .if ${TARGET_ARCH:Mmips64*} != "" NATIVE_EMULATION=elf64${_EMULATION_ENDIAN}tsmip_fbsd +LIBSEARCHPATH.elf32${_EMULATION_ENDIAN}tsmip_fbsd=\"=/usr/lib32\" .elif ${TARGET_ARCH:Mmipsn32*} != "" NATIVE_EMULATION=elf32${_EMULATION_ENDIAN}tsmipn32_fbsd .else diff --git a/sys/mips/conf/MALTA64 b/sys/mips/conf/MALTA64 index c1f7d7ed1d4..73857547b15 100644 --- a/sys/mips/conf/MALTA64 +++ b/sys/mips/conf/MALTA64 @@ -11,3 +11,5 @@ machine mips mips64 makeoptions ARCH_FLAGS="-march=mips64 -mabi=64" makeoptions KERNLOADADDR=0xffffffff80100000 + +options COMPAT_FREEBSD32 # Compatible with o32 binaries From 14da48cbe4b8ef075bb1a5d8e25941699eb8d6bf Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 6 Jan 2017 23:41:45 +0000 Subject: [PATCH 07/55] Set MORETOCOME for AIO write requests on a socket. Add a MSG_MOREOTOCOME message flag. When this flag is set, sosend* set PRUS_MOREOTOCOME when invoking the protocol send method. The aio worker tasks for sending on a socket set this flag when there are additional write jobs waiting on the socket buffer. Reviewed by: adrian MFC after: 1 month Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D8955 --- sys/kern/sys_socket.c | 2 ++ sys/kern/uipc_socket.c | 2 ++ sys/sys/socket.h | 1 + 3 files changed, 5 insertions(+) diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index aab972b06e3..441a628b7f7 100644 --- a/sys/kern/sys_socket.c +++ b/sys/kern/sys_socket.c @@ -604,6 +604,8 @@ retry: if (td->td_ru.ru_msgrcv != ru_before) job->msgrcv = 1; } else { + if (!TAILQ_EMPTY(&sb->sb_aiojobq)) + flags |= MSG_MORETOCOME; uio.uio_rw = UIO_WRITE; ru_before = td->td_ru.ru_msgsnd; #ifdef MAC diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 7cd2a75ff68..23910c5bc1d 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1182,6 +1182,7 @@ sosend_dgram(struct socket *so, struct sockaddr *addr, struct uio *uio, (resid <= 0)) ? PRUS_EOF : /* If there is more to send set PRUS_MORETOCOME */ + (flags & MSG_MORETOCOME) || (resid > 0 && space > 0) ? PRUS_MORETOCOME : 0, top, addr, control, td); if (dontroute) { @@ -1368,6 +1369,7 @@ restart: (resid <= 0)) ? PRUS_EOF : /* If there is more to send set PRUS_MORETOCOME. */ + (flags & MSG_MORETOCOME) || (resid > 0 && space > 0) ? PRUS_MORETOCOME : 0, top, addr, control, td); if (dontroute) { diff --git a/sys/sys/socket.h b/sys/sys/socket.h index ea3d9b6bee3..9429f5a1f07 100644 --- a/sys/sys/socket.h +++ b/sys/sys/socket.h @@ -435,6 +435,7 @@ struct msghdr { #endif #ifdef _KERNEL #define MSG_SOCALLBCK 0x10000 /* for use by socket callbacks - soreceive (TCP) */ +#define MSG_MORETOCOME 0x20000 /* additional data pending */ #endif /* From e4612db2cdad3284aef5ff79805c21d25a7eeedf Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Sat, 7 Jan 2017 00:08:55 +0000 Subject: [PATCH 08/55] Fix comment in t4_tom. No functional change. MFC after: 3 days --- sys/dev/cxgbe/tom/t4_connect.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/dev/cxgbe/tom/t4_connect.c b/sys/dev/cxgbe/tom/t4_connect.c index 7ad1fb6fcea..4db64102c31 100644 --- a/sys/dev/cxgbe/tom/t4_connect.c +++ b/sys/dev/cxgbe/tom/t4_connect.c @@ -107,7 +107,7 @@ free_atid(struct adapter *sc, int atid) } /* - * Active open failed. + * Active open succeeded. */ static int do_act_establish(struct sge_iq *iq, const struct rss_header *rss, @@ -187,6 +187,9 @@ act_open_failure_cleanup(struct adapter *sc, u_int atid, u_int status) INP_INFO_RUNLOCK(&V_tcbinfo); } +/* + * Active open failed. + */ static int do_act_open_rpl(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) From 05ea86b0c0acef00e6ff4f42470b9fe7a1e865e4 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sat, 7 Jan 2017 00:17:01 +0000 Subject: [PATCH 09/55] In tcpdump's print-tcp.c, avoid increasing alignment when taking the addresses of members of struct ip, which is packed. Since the pointers are only used for memcmp'ing, they can be pointing to void instead. Note that upstream has removed the src and dst variables, in the mean time. MFC after: 3 days --- contrib/tcpdump/print-tcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/tcpdump/print-tcp.c b/contrib/tcpdump/print-tcp.c index bc200e2f8e2..a5c70477a8f 100644 --- a/contrib/tcpdump/print-tcp.c +++ b/contrib/tcpdump/print-tcp.c @@ -253,7 +253,7 @@ tcp_print(netdissect_options *ndo, if (ip6) { register struct tcp_seq_hash6 *th; struct tcp_seq_hash6 *tcp_seq_hash; - const struct in6_addr *src, *dst; + const void *src, *dst; struct tha6 tha; tcp_seq_hash = tcp_seq_hash6; @@ -309,7 +309,7 @@ tcp_print(netdissect_options *ndo, #endif /*INET6*/ register struct tcp_seq_hash *th; struct tcp_seq_hash *tcp_seq_hash; - const struct in_addr *src, *dst; + const void *src, *dst; struct tha tha; tcp_seq_hash = tcp_seq_hash4; From 4e354796e9ce6ec7ca510678c1b9299577ff38b0 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Sat, 7 Jan 2017 00:59:06 +0000 Subject: [PATCH 10/55] Fix file descriptor leaks in cmp(1) Also, add a few test cases Reported by: Coverity CID: 271624 275338 Reviewed by: ngie MFC after: 4 weeks Sponsored by: Spectra Logic Corp Differential Revision: https://reviews.freebsd.org/D9074 --- usr.bin/cmp/special.c | 2 + usr.bin/cmp/tests/Makefile | 1 + usr.bin/cmp/tests/cmp_test2.sh | 67 ++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100755 usr.bin/cmp/tests/cmp_test2.sh diff --git a/usr.bin/cmp/special.c b/usr.bin/cmp/special.c index 8225185f00f..edb641c8e7b 100644 --- a/usr.bin/cmp/special.c +++ b/usr.bin/cmp/special.c @@ -99,6 +99,8 @@ eof: if (ferror(fp1)) } else if (feof(fp2)) eofmsg(file2); + fclose(fp2); + fclose(fp1); if (dfound) exit(DIFF_EXIT); } diff --git a/usr.bin/cmp/tests/Makefile b/usr.bin/cmp/tests/Makefile index bfae46c8a2a..087f32f4185 100644 --- a/usr.bin/cmp/tests/Makefile +++ b/usr.bin/cmp/tests/Makefile @@ -2,6 +2,7 @@ .include +ATF_TESTS_SH+= cmp_test2 NETBSD_ATF_TESTS_SH= cmp_test .include diff --git a/usr.bin/cmp/tests/cmp_test2.sh b/usr.bin/cmp/tests/cmp_test2.sh new file mode 100755 index 00000000000..2221e623888 --- /dev/null +++ b/usr.bin/cmp/tests/cmp_test2.sh @@ -0,0 +1,67 @@ +# Copyright (c) 2017 Alan Somers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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$ + +atf_test_case special +special_head() { + atf_set "descr" "Test cmp(1)'s handling of non-regular files" +} +special_body() { + echo 0123456789abcdef > a + echo 0123456789abcdeg > b + cat a | atf_check -s exit:0 cmp a - + cat a | atf_check -s exit:0 cmp - a + cat b | atf_check -s not-exit:0 cmp a - + cat b | atf_check -s not-exit:0 cmp - a + true +} + +atf_test_case symlink +symlink_head() { + atf_set "descr" "Test cmp(1)'s handling of symlinks" +} +symlink_body() { + echo 0123456789abcdef > a + echo 0123456789abcdeg > b + ln -s a a.lnk + ln -s b b.lnk + ln -s a a2.lnk + cp a adup + ln -s adup adup.lnk + atf_check -s exit:0 cmp a a.lnk + atf_check -s exit:0 cmp a.lnk a + atf_check -s not-exit:0 -o ignore cmp a b.lnk + atf_check -s not-exit:0 -o ignore cmp b.lnk a + atf_check -s not-exit:0 -o ignore -e ignore cmp -h a a.lnk + atf_check -s not-exit:0 -o ignore -e ignore cmp -h a.lnk a + atf_check -s exit:0 cmp -h a.lnk a2.lnk + atf_check -s not-exit:0 -o ignore -e ignore cmp -h a.lnk adup.lnk +} + +atf_init_test_cases() +{ + atf_add_test_case special + atf_add_test_case symlink +} From efda3f5684e9e3ab773f50fc8367953713155db1 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 Jan 2017 01:49:34 +0000 Subject: [PATCH 11/55] [net80211] Remove duplicate VHTOPMODE configuration bits. These came from Linux mac80211 headers and are configuration bits, not VHTOPMODE field parameters. Whilst here, add the field names for the VHTCAP bits. Tested: * ath10k, 11ac STA mode --- sys/net80211/ieee80211.h | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h index 1fcff34cd37..7140aedf5d5 100644 --- a/sys/net80211/ieee80211.h +++ b/sys/net80211/ieee80211.h @@ -737,16 +737,6 @@ struct ieee80211_ie_htinfo { * 802.11ac definitions - 802.11ac-2013 . */ -/* VHT opmode bits */ -#define IEEE80211_VHT_OPMODE_CHANWIDTH_MASK 3 -#define IEEE80211_VHT_OPMODE_CHANWIDTH_20MHZ 0 -#define IEEE80211_VHT_OPMODE_CHANWIDTH_40MHZ 1 -#define IEEE80211_VHT_OPMODE_CHANWIDTH_80MHZ 2 -#define IEEE80211_VHT_OPMODE_CHANWIDTH_160MHZ 3 -#define IEEE80211_VHT_OPMODE_RX_NSS_MASK 0x70 -#define IEEE80211_VHT_OPMODE_RX_NSS_SHIFT 4 -#define IEEE80211_VHT_OPMODE_RX_NSS_TYPE_BF 0x80 - /* * Maximum length of A-MPDU that the STA can RX in VHT. * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) @@ -787,6 +777,7 @@ struct ieee80211_ie_vhtcap { struct ieee80211_vht_mcs_info supp_mcs; } __packed; +/* VHT operation mode subfields - 802.11ac-2013 Table 8.183x */ #define IEEE80211_VHT_CHANWIDTH_USE_HT 0 /* Use HT IE for chw */ #define IEEE80211_VHT_CHANWIDTH_80MHZ 1 /* 80MHz */ #define IEEE80211_VHT_CHANWIDTH_160MHZ 2 /* 160MHz */ @@ -839,6 +830,11 @@ struct ieee80211_ie_vht_operation { #define IEEE80211_VHTCAP_RX_ANTENNA_PATTERN 0x10000000 #define IEEE80211_VHTCAP_TX_ANTENNA_PATTERN 0x20000000 +#define IEEE80211_VHTCAP_BITS \ + "\20\1MPDU7991\2MPDU11454\3CHAN160\4CHAN8080\5RXLDPC\6SHORTGI80" \ + "\7SHORTGI160\10RXSTBC1\11RXSTBC2\12RXSTBC3\13RXSTBC4\14BFERCAP" \ + "\15BFEECAP\27VHT" + /* * VHT Transmit Power Envelope element - 802.11ac-2013 8.4.2.164 * From 02527029a565be1d161cd9669740340831256e3d Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 Jan 2017 01:51:54 +0000 Subject: [PATCH 12/55] [net80211] add FVHT flags for channel widths. The 11n code uses these bits for both configuration /and/ controlling the channel width on softmac chips - it uses it to find the widest width for all VAPs (eg a HT20 vap and a HT40 vap) to know what to configure the ic_curchan. For fullmac devices it isn't /as/ important, as each virtual device exposed by the firmware will likely have its own configuration and the firmware figures out what to do to enable it. --- sys/net80211/ieee80211_var.h | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index 5238893fe95..bd13997a57f 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -653,8 +653,12 @@ MALLOC_DECLARE(M_80211_VAP); #define IEEE80211_FVEN_BITS "\20" #define IEEE80211_FVHT_VHT 0x000000001 /* CONF: VHT supported */ +#define IEEE80211_FVHT_USEVHT40 0x000000002 /* CONF: Use VHT40 */ +#define IEEE80211_FVHT_USEVHT80 0x000000004 /* CONF: Use VHT80 */ +#define IEEE80211_FVHT_USEVHT80P80 0x000000008 /* CONF: Use VHT 80+80 */ +#define IEEE80211_FVHT_USEVHT160 0x000000010 /* CONF: Use VHT160 */ #define IEEE80211_VFHT_BITS \ - "\20\1VHT" + "\20\1VHT\2VHT40\3VHT80\4VHT80P80\5VHT160" int ic_printf(struct ieee80211com *, const char *, ...) __printflike(2, 3); void ieee80211_ifattach(struct ieee80211com *); @@ -829,6 +833,27 @@ ieee80211_htchanflags(const struct ieee80211_channel *c) IEEE80211_IS_CHAN_HT(c) ? IEEE80211_FHT_HT : 0; } +/* + * Calculate VHT channel promotion flags for a channel. + * XXX belongs in ieee80211_vht.h but needs IEEE80211_FVHT_* + */ +static __inline int +ieee80211_vhtchanflags(const struct ieee80211_channel *c) +{ + + if (IEEE80211_IS_CHAN_VHT160(c)) + return IEEE80211_FVHT_USEVHT160; + if (IEEE80211_IS_CHAN_VHT80_80(c)) + return IEEE80211_FVHT_USEVHT80P80; + if (IEEE80211_IS_CHAN_VHT80(c)) + return IEEE80211_FVHT_USEVHT80; + if (IEEE80211_IS_CHAN_VHT40(c)) + return IEEE80211_FVHT_USEVHT40; + if (IEEE80211_IS_CHAN_VHT(c)) + return IEEE80211_FVHT_VHT; + return (0); +} + /* * Fetch the current TX power (cap) for the given node. * From 6d0ef1b905b798c5ac4992dd77788386aa01ebcc Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 Jan 2017 01:53:27 +0000 Subject: [PATCH 13/55] [net80211] add VHT node flag; parsed chanwidth. The VHT operational element (VHTOPMODE) isn't a uint32_t - it's the MCS sets, freq1/freq2 parameters and channel width. So, store the channel width too in lieu of just storing the IE struct. This changes the VHT parameter layout in ieee80211_node but it doesn't change ABI at all. --- sys/net80211/ieee80211_node.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h index 7a706731bb6..7ca24c1862f 100644 --- a/sys/net80211/ieee80211_node.h +++ b/sys/net80211/ieee80211_node.h @@ -142,6 +142,7 @@ struct ieee80211_node { #define IEEE80211_NODE_ASSOCID 0x020000 /* xmit requires associd */ #define IEEE80211_NODE_AMSDU_RX 0x040000 /* AMSDU rx enabled */ #define IEEE80211_NODE_AMSDU_TX 0x080000 /* AMSDU tx enabled */ +#define IEEE80211_NODE_VHT 0x100000 /* VHT enabled */ uint16_t ni_associd; /* association ID */ uint16_t ni_vlan; /* vlan tag */ uint16_t ni_txpower; /* current transmit power */ @@ -226,11 +227,13 @@ struct ieee80211_node { /* VHT state */ uint32_t ni_vhtcap; - uint32_t ni_vhtinfo; + uint16_t ni_vht_basicmcs; + uint16_t ni_vht_pad2; struct ieee80211_vht_mcs_info ni_vht_mcsinfo; uint8_t ni_vht_chan1; /* 20/40/80/160 - VHT chan1 */ uint8_t ni_vht_chan2; /* 80+80 - VHT chan2 */ - uint16_t ni_vht_pad1; + uint8_t ni_vht_chanwidth; /* IEEE80211_VHT_CHANWIDTH_ */ + uint8_t ni_vht_pad1; uint32_t ni_vht_spare[8]; /* fast-frames state */ From 55c68c64a48b5ad0cfa574e90c25cc951df5537e Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 Jan 2017 01:54:32 +0000 Subject: [PATCH 14/55] [net80211] add VHT IEs to scan elements. In preparation for VHT station support, we need to store VHT IEs when scanning so we can choose to upgrade to VHT. This doesn't change the ABI - it just steals spare[] entries. --- sys/net80211/ieee80211_scan.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211_scan.h b/sys/net80211/ieee80211_scan.h index f568b651151..a3c873df4eb 100644 --- a/sys/net80211/ieee80211_scan.h +++ b/sys/net80211/ieee80211_scan.h @@ -250,7 +250,9 @@ struct ieee80211_scanparams { uint8_t *quiet; uint8_t *meshid; uint8_t *meshconf; - uint8_t *spare[3]; + uint8_t *vhtcap; + uint8_t *vhtopmode; + uint8_t *spare[1]; }; /* From 36ea5759aa7ab12082cfb112cff56fa2d22a1fb9 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 Jan 2017 01:56:10 +0000 Subject: [PATCH 15/55] [lib80211] add VHT bands and channel flags. This is preparation work for 11ac support. The regulatory database needs to know about VHT channel flags and 80MHz (and later 160MHz) available channel bands. Whilst here, add the 2GHz VHT band (which is a terrible, terrible vendor extension that almost all vendors do) just in preparation, even though I don't (yet) plan on supporting it. --- lib/lib80211/lib80211_regdomain.c | 32 +++++++++++++++++++++++++++++++ lib/lib80211/lib80211_regdomain.h | 2 ++ 2 files changed, 34 insertions(+) diff --git a/lib/lib80211/lib80211_regdomain.c b/lib/lib80211/lib80211_regdomain.c index 32901a6b56e..35cc865efb5 100644 --- a/lib/lib80211/lib80211_regdomain.c +++ b/lib/lib80211/lib80211_regdomain.c @@ -123,6 +123,10 @@ start_element(void *data, const char *name, const char **attr) mt->curband = &mt->rd->bands_11ng; else if (iseq(mode, "11na")) mt->curband = &mt->rd->bands_11na; + else if (iseq(mode, "11ac")) + mt->curband = &mt->rd->bands_11ac; + else if (iseq(mode, "11acg")) + mt->curband = &mt->rd->bands_11acg; else warnx("unknown mode \"%s\" at line %ld", __DECONST(char *, mode), @@ -184,6 +188,14 @@ decode_flag(struct mystate *mt, const char *p, int len) FLAG(IEEE80211_CHAN_G), FLAG(IEEE80211_CHAN_HT20), FLAG(IEEE80211_CHAN_HT40), + FLAG(IEEE80211_CHAN_VHT20), + FLAG(IEEE80211_CHAN_VHT40), + FLAG(IEEE80211_CHAN_VHT80), + /* + * XXX VHT80_80? This likely should be done by + * 80MHz chan logic in net80211 / ifconfig. + */ + FLAG(IEEE80211_CHAN_VHT160), FLAG(IEEE80211_CHAN_ST), FLAG(IEEE80211_CHAN_TURBO), FLAG(IEEE80211_CHAN_PASSIVE), @@ -515,6 +527,24 @@ lib80211_regdomain_readconfig(struct regdata *rdp, const void *p, size_t len) } nb->band = id; } + LIST_FOREACH(nb, &dp->bands_11ac, next) { + id = findid(rdp, nb->band, FREQBAND); + if (id == NULL) { + warnx("undefined 11ac band \"%s\"", + __DECONST(char *, nb->band)); + errors++; + } + nb->band = id; + } + LIST_FOREACH(nb, &dp->bands_11acg, next) { + id = findid(rdp, nb->band, FREQBAND); + if (id == NULL) { + warnx("undefined 11acg band \"%s\"", + __DECONST(char *, nb->band)); + errors++; + } + nb->band = id; + } } LIST_FOREACH(cp, &rdp->countries, next) { id = cp->rd; @@ -562,6 +592,8 @@ lib80211_regdomain_cleanup(struct regdata *rdp) cleanup_bands(&dp->bands_11a); cleanup_bands(&dp->bands_11ng); cleanup_bands(&dp->bands_11na); + cleanup_bands(&dp->bands_11ac); + cleanup_bands(&dp->bands_11acg); if (dp->name != NULL) free(__DECONST(char *, dp->name)); } diff --git a/lib/lib80211/lib80211_regdomain.h b/lib/lib80211/lib80211_regdomain.h index d1803c25584..a8a4207c98a 100644 --- a/lib/lib80211/lib80211_regdomain.h +++ b/lib/lib80211/lib80211_regdomain.h @@ -75,6 +75,8 @@ struct regdomain { netband_head bands_11a; /* 11a operation */ netband_head bands_11ng;/* 11ng operation */ netband_head bands_11na;/* 11na operation */ + netband_head bands_11ac;/* 11ac 5GHz operation */ + netband_head bands_11acg;/* 11ac 2GHz operation */ LIST_ENTRY(regdomain) next; }; From 35bcfd1c7065be6b07b350a0ef3f1f41a10a2e5e Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 Jan 2017 01:59:39 +0000 Subject: [PATCH 16/55] [net80211] add VHT ioctl parameters and driver capabilities * Add the VHT capability element to the driver capabilities so ifconfig can see if VHT is available * Add ioctl plumbing for enabling/disabling VHT and each of the VHT widths. Note: this DOES change the ABI (the driver caps ioctl struct size, sigh) so this will require a recompile of at least ifconfig. --- sys/net80211/ieee80211_ioctl.c | 84 +++++++++++++++++++++++++++++++++- sys/net80211/ieee80211_ioctl.h | 4 ++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c index c8d640d0670..4675291d9da 100644 --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -710,6 +710,7 @@ ieee80211_ioctl_getdevcaps(struct ieee80211com *ic, dc->dc_drivercaps = ic->ic_caps; dc->dc_cryptocaps = ic->ic_cryptocaps; dc->dc_htcaps = ic->ic_htcaps; + dc->dc_vhtcaps = ic->ic_vhtcaps; ci = &dc->dc_chaninfo; ic->ic_getradiocaps(ic, maxchans, &ci->ic_nchans, ci->ic_chans); KASSERT(ci->ic_nchans <= maxchans, @@ -1135,6 +1136,22 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd, if (vap->iv_flags_ht & IEEE80211_FHT_STBC_RX) ireq->i_val |= 2; break; + + /* VHT */ + case IEEE80211_IOC_VHTCONF: + ireq->i_val = 0; + if (vap->iv_flags_vht & IEEE80211_FVHT_VHT) + ireq->i_val |= 1; + if (vap->iv_flags_vht & IEEE80211_FVHT_USEVHT40) + ireq->i_val |= 2; + if (vap->iv_flags_vht & IEEE80211_FVHT_USEVHT80) + ireq->i_val |= 4; + if (vap->iv_flags_vht & IEEE80211_FVHT_USEVHT80P80) + ireq->i_val |= 8; + if (vap->iv_flags_vht & IEEE80211_FVHT_USEVHT160) + ireq->i_val |= 16; + break; + default: error = ieee80211_ioctl_getdefault(vap, ireq); break; @@ -1869,6 +1886,8 @@ findchannel(struct ieee80211com *ic, int ieee, int mode) /* NB: handled specially below */ [IEEE80211_MODE_11NA] = IEEE80211_CHAN_A, [IEEE80211_MODE_11NG] = IEEE80211_CHAN_G, + [IEEE80211_MODE_VHT_5GHZ] = IEEE80211_CHAN_A, + [IEEE80211_MODE_VHT_2GHZ] = IEEE80211_CHAN_G, }; u_int modeflags; int i; @@ -1893,11 +1912,27 @@ findchannel(struct ieee80211com *ic, int ieee, int mode) !find11gchannel(ic, i, c->ic_freq)) return c; } else { - /* must check HT specially */ + /* must check VHT specifically */ + if ((mode == IEEE80211_MODE_VHT_5GHZ || + mode == IEEE80211_MODE_VHT_2GHZ) && + !IEEE80211_IS_CHAN_VHT(c)) + continue; + + /* + * Must check HT specially - only match on HT, + * not HT+VHT channels + */ if ((mode == IEEE80211_MODE_11NA || mode == IEEE80211_MODE_11NG) && !IEEE80211_IS_CHAN_HT(c)) continue; + + if ((mode == IEEE80211_MODE_11NA || + mode == IEEE80211_MODE_11NG) && + IEEE80211_IS_CHAN_VHT(c)) + continue; + + /* Check that the modeflags above match */ if ((c->ic_flags & modeflags) == modeflags) return c; } @@ -2021,6 +2056,7 @@ ieee80211_ioctl_setchannel(struct ieee80211vap *vap, if (c == NULL) return EINVAL; } + /* * Fine tune channel selection based on desired mode: * if 11b is requested, find the 11b version of any @@ -2031,6 +2067,9 @@ ieee80211_ioctl_setchannel(struct ieee80211vap *vap, * 11a channel returned, * if 11ng is requested, find the ht version of any * 11g channel returned, + * if 11ac is requested, find the 11ac version + * of any 11a/11na channel returned, + * (TBD) 11acg (2GHz VHT) * otherwise we should be ok with what we've got. */ switch (vap->iv_des_mode) { @@ -2067,6 +2106,17 @@ ieee80211_ioctl_setchannel(struct ieee80211vap *vap, c = c2; } break; + case IEEE80211_MODE_VHT_2GHZ: + printf("%s: TBD\n", __func__); + break; + case IEEE80211_MODE_VHT_5GHZ: + if (IEEE80211_IS_CHAN_A(c)) { + c2 = findchannel(ic, ireq->i_val, + IEEE80211_MODE_VHT_5GHZ); + if (c2 != NULL) + c = c2; + } + break; default: /* NB: no static turboG */ break; } @@ -2092,6 +2142,7 @@ ieee80211_ioctl_setcurchan(struct ieee80211vap *vap, error = copyin(ireq->i_data, &chan, sizeof(chan)); if (error != 0) return error; + /* XXX 0xffff overflows 16-bit signed */ if (chan.ic_freq == 0 || chan.ic_freq == IEEE80211_CHAN_ANY) { c = IEEE80211_CHAN_ANYC; @@ -3321,6 +3372,37 @@ ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211r if (isvapht(vap)) error = ERESTART; break; + + /* VHT */ + case IEEE80211_IOC_VHTCONF: + if (ireq->i_val & 1) + ieee80211_syncflag_vht(vap, IEEE80211_FVHT_VHT); + else + ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_VHT); + + if (ireq->i_val & 2) + ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT40); + else + ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT40); + + if (ireq->i_val & 4) + ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT80); + else + ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT80); + + if (ireq->i_val & 8) + ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT80P80); + else + ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT80P80); + + if (ireq->i_val & 16) + ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT160); + else + ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT160); + + error = ENETRESET; + break; + default: error = ieee80211_ioctl_setdefault(vap, ireq); break; diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h index 4b1605518ae..7d472bc64c8 100644 --- a/sys/net80211/ieee80211_ioctl.h +++ b/sys/net80211/ieee80211_ioctl.h @@ -556,6 +556,7 @@ struct ieee80211_devcaps_req { uint32_t dc_drivercaps; /* general driver caps */ uint32_t dc_cryptocaps; /* hardware crypto support */ uint32_t dc_htcaps; /* HT/802.11n support */ + uint32_t dc_vhtcaps; /* VHT/802.11ac capabilities */ struct ieee80211req_chaninfo dc_chaninfo; }; #define IEEE80211_DEVCAPS_SIZE(_nchan) \ @@ -704,6 +705,9 @@ struct ieee80211req { #define IEEE80211_IOC_STBC 113 /* STBC Tx/RX (on, off) */ #define IEEE80211_IOC_LDPC 114 /* LDPC Tx/RX (on, off) */ +/* VHT */ +#define IEEE80211_IOC_VHTCONF 130 /* VHT config (off, on; widths) */ + #define IEEE80211_IOC_MESH_ID 170 /* mesh identifier */ #define IEEE80211_IOC_MESH_AP 171 /* accepting peerings */ #define IEEE80211_IOC_MESH_FWRD 172 /* forward frames */ From e9bb7f9aa1b4f57f248165e3a685222b447d3b90 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 Jan 2017 02:07:05 +0000 Subject: [PATCH 17/55] [ifconfig] add initial VHT (802.11ac) configuration and channel support to ifconfig. This is very preliminary and mostly enough for me (with other patches) to work on VHT support. It adds: * VHT20, VHT40 and VHT80 regulatory/band awareness * VHT20, VHT40 and VHT80 channel configuration / population * Parses vht channel specifications (eg ifconfig wlan0 create wlandev athp0 wlanmode monitor channel 36:vht/80) * Configuration of VHT, VHT40, VHT80, VHT80+80, VHT160 channel width (IEEE80211_FVHT_VHT* flags in net80211) TODO: * No VHT80+80 or VHT160 channels yet - I don't yet have hardware, and I'm not yet sure how to support/populate VHT80+80 channels. * No, I won't update the manpage until this is "more done", lest someone tries using vht and gets upset with me. * No, I won't commit the regulatory database I'm testing with, so you'll just end up with no VHT channels ever populated. Which is good, as there isn't an 11ac driver in-tree yet to try it with. --- sbin/ifconfig/ifieee80211.c | 227 +++++++++++++++++++++++++++++++++++- 1 file changed, 223 insertions(+), 4 deletions(-) diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c index 5b1a79c6fb7..8ff16323274 100644 --- a/sbin/ifconfig/ifieee80211.c +++ b/sbin/ifconfig/ifieee80211.c @@ -119,6 +119,7 @@ #define IEEE80211_NODE_ASSOCID 0x020000 /* xmit requires associd */ #define IEEE80211_NODE_AMSDU_RX 0x040000 /* AMSDU rx enabled */ #define IEEE80211_NODE_AMSDU_TX 0x080000 /* AMSDU tx enabled */ +#define IEEE80211_NODE_VHT 0x100000 /* VHT enabled */ #endif #define MAXCHAN 1536 /* max 1.5K channels */ @@ -143,7 +144,9 @@ static const char *modename[IEEE80211_MODE_MAX] = { [IEEE80211_MODE_11NA] = "11na", [IEEE80211_MODE_11NG] = "11ng", [IEEE80211_MODE_HALF] = "half", - [IEEE80211_MODE_QUARTER] = "quarter" + [IEEE80211_MODE_QUARTER] = "quarter", + [IEEE80211_MODE_VHT_2GHZ] = "11acg", + [IEEE80211_MODE_VHT_5GHZ] = "11ac", }; static void set80211(int s, int type, int val, int len, void *data); @@ -183,6 +186,20 @@ gethtconf(int s) gothtconf = 1; } +/* VHT */ +static int vhtconf = 0; +static int gotvhtconf = 0; + +static void +getvhtconf(int s) +{ + if (gotvhtconf) + return; + if (get80211val(s, IEEE80211_IOC_VHTCONF, &vhtconf) < 0) + warn("unable to get VHT configuration information"); + gotvhtconf = 1; +} + /* * Collect channel info from the kernel. We use this (mostly) * to handle mapping between frequency and IEEE channel number. @@ -200,6 +217,7 @@ getchaninfo(int s) err(1, "unable to get channel information"); ifmr = ifmedia_getstate(s); gethtconf(s); + getvhtconf(s); } static struct regdata * @@ -255,6 +273,9 @@ canpromote(int i, int from, int to) * channe list (e.g. mode 11a); we want to honor that to avoid * confusing behaviour. */ +/* + * XXX VHT + */ static int promote(int i) { @@ -361,6 +382,10 @@ getcurchan(int s) static enum ieee80211_phymode chan2mode(const struct ieee80211_channel *c) { + if (IEEE80211_IS_CHAN_VHTA(c)) + return IEEE80211_MODE_VHT_5GHZ; + if (IEEE80211_IS_CHAN_VHTG(c)) + return IEEE80211_MODE_VHT_2GHZ; if (IEEE80211_IS_CHAN_HTA(c)) return IEEE80211_MODE_11NA; if (IEEE80211_IS_CHAN_HTG(c)) @@ -502,9 +527,12 @@ setregdomain_cb(int s, void *arg) printf("drivercaps: 0x%x\n", dc->dc_drivercaps); printf("cryptocaps: 0x%x\n", dc->dc_cryptocaps); printf("htcaps : 0x%x\n", dc->dc_htcaps); + printf("vhtcaps : 0x%x\n", dc->dc_vhtcaps); +#if 0 memcpy(chaninfo, &dc->dc_chaninfo, IEEE80211_CHANINFO_SPACE(&dc->dc_chaninfo)); print_channels(s, &dc->dc_chaninfo, 1/*allchans*/, 1/*verbose*/); +#endif } #endif req = malloc(IEEE80211_REGDOMAIN_SIZE(dc->dc_chaninfo.ic_nchans)); @@ -616,6 +644,7 @@ getchannelflags(const char *val, int freq) #define _CHAN_HT 0x80000000 const char *cp; int flags; + int is_vht = 0; flags = 0; @@ -636,6 +665,9 @@ getchannelflags(const char *val, int freq) case 'g': /* 802.11g */ flags |= IEEE80211_CHAN_G; break; + case 'v': /* vht: 802.11ac */ + is_vht = 1; + /* Fallthrough */ case 'h': /* ht = 802.11n */ case 'n': /* 802.11n */ flags |= _CHAN_HT; /* NB: private */ @@ -674,6 +706,15 @@ getchannelflags(const char *val, int freq) flags |= IEEE80211_CHAN_HT20; break; case 40: + case 80: + case 160: + /* Handle the 80/160 VHT flag */ + if (cw == 80) + flags |= IEEE80211_CHAN_VHT80; + else if (cw == 160) + flags |= IEEE80211_CHAN_VHT160; + + /* Fallthrough */ if (ep != NULL && *ep == '+') flags |= IEEE80211_CHAN_HT40U; else if (ep != NULL && *ep == '-') @@ -683,6 +724,7 @@ getchannelflags(const char *val, int freq) errx(-1, "%s: Invalid channel width\n", val); } } + /* * Cleanup specifications. */ @@ -695,6 +737,7 @@ getchannelflags(const char *val, int freq) * are also usable for legacy operation; e.g. freq:n/40. */ flags &= ~IEEE80211_CHAN_HT; + flags &= ~IEEE80211_CHAN_VHT; } else { /* * Remove private indicator that this is an HT channel @@ -714,6 +757,25 @@ getchannelflags(const char *val, int freq) mapchan(&chan, freq, 0); flags |= (chan.ic_flags & IEEE80211_CHAN_HT); } + + /* + * If VHT is enabled, then also set the VHT flag and the + * relevant channel up/down. + */ + if (is_vht && (flags & IEEE80211_CHAN_HT)) { + /* + * XXX yes, maybe we should just have VHT, and reuse + * HT20/HT40U/HT40D + */ + if (flags & IEEE80211_CHAN_VHT80) + ; + else if (flags & IEEE80211_CHAN_HT20) + flags |= IEEE80211_CHAN_VHT20; + else if (flags & IEEE80211_CHAN_HT40U) + flags |= IEEE80211_CHAN_VHT40U; + else if (flags & IEEE80211_CHAN_HT40D) + flags |= IEEE80211_CHAN_VHT40D; + } } return flags; #undef _CHAN_HT @@ -1447,6 +1509,10 @@ getmodeflags(const char *val) case 'q': /* 1/4-width channels */ flags |= IEEE80211_CHAN_QUARTER; break; + case 'v': + /* XXX set HT too? */ + flags |= IEEE80211_CHAN_VHT; + break; default: errx(-1, "%s: Invalid mode attribute %c\n", val, *cp); @@ -1863,6 +1929,21 @@ set80211rifs(const char *val, int d, int s, const struct afswtch *rafp) set80211(s, IEEE80211_IOC_RIFS, d, 0, NULL); } +static void +set80211vhtconf(const char *val, int d, int s, const struct afswtch *rafp) +{ + if (get80211val(s, IEEE80211_IOC_VHTCONF, &vhtconf) < 0) + errx(-1, "cannot set VHT setting"); + printf("%s: vhtconf=0x%08x, d=%d\n", __func__, vhtconf, d); + if (d < 0) { + d = -d; + vhtconf &= ~d; + } else + vhtconf |= d; + printf("%s: vhtconf is now 0x%08x\n", __func__, vhtconf); + set80211(s, IEEE80211_IOC_VHTCONF, vhtconf, 0, NULL); +} + static DECL_CMD_FUNC(set80211tdmaslot, val, d) { @@ -2035,6 +2116,7 @@ regdomain_addchans(struct ieee80211req_chaninfo *ci, hi_adj = (chanFlags & IEEE80211_CHAN_HT40U) ? -20 : 0; lo_adj = (chanFlags & IEEE80211_CHAN_HT40D) ? 20 : 0; channelSep = (chanFlags & IEEE80211_CHAN_2GHZ) ? 0 : 40; + LIST_FOREACH(nb, bands, next) { b = nb->band; if (verbose) { @@ -2045,6 +2127,7 @@ regdomain_addchans(struct ieee80211req_chaninfo *ci, putchar('\n'); } prev = NULL; + for (freq = b->freqStart + lo_adj; freq <= b->freqEnd + hi_adj; freq += b->chanSep) { /* @@ -2055,6 +2138,40 @@ regdomain_addchans(struct ieee80211req_chaninfo *ci, * then constrained according by channel separation. */ flags = nb->flags | b->flags; + + /* + * VHT first - HT is a subset. + * + * XXX TODO: VHT80p80, VHT160 is not yet done. + */ + if (flags & IEEE80211_CHAN_VHT) { + if ((chanFlags & IEEE80211_CHAN_VHT20) && + (flags & IEEE80211_CHAN_VHT20) == 0) { + if (verbose) + printf("%u: skip, not a " + "VHT20 channel\n", freq); + continue; + } + if ((chanFlags & IEEE80211_CHAN_VHT40) && + (flags & IEEE80211_CHAN_VHT40) == 0) { + if (verbose) + printf("%u: skip, not a " + "VHT40 channel\n", freq); + continue; + } + if ((chanFlags & IEEE80211_CHAN_VHT80) && + (flags & IEEE80211_CHAN_VHT80) == 0) { + if (verbose) + printf("%u: skip, not a " + "VHT80 channel\n", freq); + continue; + } + + flags &= ~IEEE80211_CHAN_VHT; + flags |= chanFlags & IEEE80211_CHAN_VHT; + } + + /* Now, constrain HT */ if (flags & IEEE80211_CHAN_HT) { /* * HT channels are generated specially; we're @@ -2127,7 +2244,7 @@ regdomain_addchans(struct ieee80211req_chaninfo *ci, memset(c, 0, sizeof(*c)); c->ic_freq = freq; c->ic_flags = flags; - if (c->ic_flags & IEEE80211_CHAN_DFS) + if (c->ic_flags & IEEE80211_CHAN_DFS) c->ic_maxregpower = nb->maxPowerDFS; else c->ic_maxregpower = nb->maxPower; @@ -2204,6 +2321,40 @@ regdomain_makechannels( &dc->dc_chaninfo); } } + if (!LIST_EMPTY(&rd->bands_11ac) && dc->dc_vhtcaps != 0) { + regdomain_addchans(ci, &rd->bands_11ac, reg, + IEEE80211_CHAN_A | IEEE80211_CHAN_HT20 | + IEEE80211_CHAN_VHT20, + &dc->dc_chaninfo); + + /* VHT40 is a function of HT40.. */ + if (dc->dc_htcaps & IEEE80211_HTCAP_CHWIDTH40) { + regdomain_addchans(ci, &rd->bands_11ac, reg, + IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U | + IEEE80211_CHAN_VHT40U, + &dc->dc_chaninfo); + regdomain_addchans(ci, &rd->bands_11ac, reg, + IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D | + IEEE80211_CHAN_VHT40D, + &dc->dc_chaninfo); + } + + /* VHT80 */ + /* XXX dc_vhtcap? */ + if (1) { + regdomain_addchans(ci, &rd->bands_11ac, reg, + IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U | + IEEE80211_CHAN_VHT80, + &dc->dc_chaninfo); + regdomain_addchans(ci, &rd->bands_11ac, reg, + IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D | + IEEE80211_CHAN_VHT80, + &dc->dc_chaninfo); + } + + /* XXX TODO: VHT80_80, VHT160 */ + } + if (!LIST_EMPTY(&rd->bands_11ng) && dc->dc_htcaps != 0) { regdomain_addchans(ci, &rd->bands_11ng, reg, IEEE80211_CHAN_G | IEEE80211_CHAN_HT20, @@ -2435,6 +2586,8 @@ getflags(int flags) if (flags & IEEE80211_NODE_HTCOMPAT) *cp++ = '+'; } + if (flags & IEEE80211_NODE_VHT) + *cp++ = 'V'; if (flags & IEEE80211_NODE_WPS) *cp++ = 'W'; if (flags & IEEE80211_NODE_TSN) @@ -3574,14 +3727,31 @@ get_chaninfo(const struct ieee80211_channel *c, int precise, if (IEEE80211_IS_CHAN_TURBO(c)) strlcat(buf, " Turbo", bsize); if (precise) { - if (IEEE80211_IS_CHAN_HT20(c)) + /* XXX should make VHT80U, VHT80D */ + if (IEEE80211_IS_CHAN_VHT80(c) && + IEEE80211_IS_CHAN_HT40D(c)) + strlcat(buf, " vht/80-", bsize); + else if (IEEE80211_IS_CHAN_VHT80(c) && + IEEE80211_IS_CHAN_HT40U(c)) + strlcat(buf, " vht/80+", bsize); + else if (IEEE80211_IS_CHAN_VHT80(c)) + strlcat(buf, " vht/80", bsize); + else if (IEEE80211_IS_CHAN_VHT40D(c)) + strlcat(buf, " vht/40-", bsize); + else if (IEEE80211_IS_CHAN_VHT40U(c)) + strlcat(buf, " vht/40+", bsize); + else if (IEEE80211_IS_CHAN_VHT20(c)) + strlcat(buf, " vht/20", bsize); + else if (IEEE80211_IS_CHAN_HT20(c)) strlcat(buf, " ht/20", bsize); else if (IEEE80211_IS_CHAN_HT40D(c)) strlcat(buf, " ht/40-", bsize); else if (IEEE80211_IS_CHAN_HT40U(c)) strlcat(buf, " ht/40+", bsize); } else { - if (IEEE80211_IS_CHAN_HT(c)) + if (IEEE80211_IS_CHAN_VHT(c)) + strlcat(buf, " vht", bsize); + else if (IEEE80211_IS_CHAN_HT(c)) strlcat(buf, " ht", bsize); } return buf; @@ -3612,6 +3782,16 @@ print_chaninfo(const struct ieee80211_channel *c, int verb) static int chanpref(const struct ieee80211_channel *c) { + if (IEEE80211_IS_CHAN_VHT160(c)) + return 80; + if (IEEE80211_IS_CHAN_VHT80_80(c)) + return 75; + if (IEEE80211_IS_CHAN_VHT80(c)) + return 70; + if (IEEE80211_IS_CHAN_VHT40(c)) + return 60; + if (IEEE80211_IS_CHAN_VHT20(c)) + return 50; if (IEEE80211_IS_CHAN_HT40(c)) return 40; if (IEEE80211_IS_CHAN_HT20(c)) @@ -3807,6 +3987,11 @@ list_capabilities(int s) putchar('\n'); printb("htcaps", dc->dc_htcaps, IEEE80211_HTCAP_BITS); } + if (dc->dc_vhtcaps != 0 || verbose) { + putchar('\n'); + printb("vhtcaps", dc->dc_vhtcaps, IEEE80211_VHTCAP_BITS); + } + putchar('\n'); if (verbose) { chaninfo = &dc->dc_chaninfo; /* XXX */ @@ -4847,6 +5032,30 @@ end: } } + if (IEEE80211_IS_CHAN_VHT(c) || verbose) { + getvhtconf(s); + if (vhtconf & 0x1) + LINE_CHECK("vht"); + else + LINE_CHECK("-vht"); + if (vhtconf & 0x2) + LINE_CHECK("vht40"); + else + LINE_CHECK("-vht40"); + if (vhtconf & 0x4) + LINE_CHECK("vht80"); + else + LINE_CHECK("-vht80"); + if (vhtconf & 0x8) + LINE_CHECK("vht80p80"); + else + LINE_CHECK("-vht80p80"); + if (vhtconf & 0x10) + LINE_CHECK("vht160"); + else + LINE_CHECK("-vht160"); + } + if (get80211val(s, IEEE80211_IOC_WME, &wme) != -1) { if (wme) LINE_CHECK("wme"); @@ -5426,6 +5635,16 @@ static struct cmd ieee80211_cmds[] = { DEF_CMD("-ht40", 0, set80211htconf), DEF_CMD("ht", 3, set80211htconf), /* NB: 20+40 */ DEF_CMD("-ht", 0, set80211htconf), + DEF_CMD("vht", 1, set80211vhtconf), + DEF_CMD("-vht", 0, set80211vhtconf), + DEF_CMD("vht40", 2, set80211vhtconf), + DEF_CMD("-vht40", -2, set80211vhtconf), + DEF_CMD("vht80", 4, set80211vhtconf), + DEF_CMD("-vht80", -4, set80211vhtconf), + DEF_CMD("vht80p80", 8, set80211vhtconf), + DEF_CMD("-vht80p80", -8, set80211vhtconf), + DEF_CMD("vht160", 16, set80211vhtconf), + DEF_CMD("-vht160", -16, set80211vhtconf), DEF_CMD("rifs", 1, set80211rifs), DEF_CMD("-rifs", 0, set80211rifs), DEF_CMD("smps", IEEE80211_HTCAP_SMPS_ENA, set80211smps), From 4222790f35cd9eb36c3d2cf29be201e1b7db62b2 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 Jan 2017 02:16:48 +0000 Subject: [PATCH 18/55] [net80211] add some more bits. --- sys/net80211/ieee80211.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h index 7140aedf5d5..aa2ddb0968e 100644 --- a/sys/net80211/ieee80211.h +++ b/sys/net80211/ieee80211.h @@ -830,10 +830,13 @@ struct ieee80211_ie_vht_operation { #define IEEE80211_VHTCAP_RX_ANTENNA_PATTERN 0x10000000 #define IEEE80211_VHTCAP_TX_ANTENNA_PATTERN 0x20000000 +/* + * XXX TODO: add the rest of the bits + */ #define IEEE80211_VHTCAP_BITS \ "\20\1MPDU7991\2MPDU11454\3CHAN160\4CHAN8080\5RXLDPC\6SHORTGI80" \ "\7SHORTGI160\10RXSTBC1\11RXSTBC2\12RXSTBC3\13RXSTBC4\14BFERCAP" \ - "\15BFEECAP\27VHT" + "\15BFEECAP\27VHT\37RXANTPTN\40TXANTPTN" /* * VHT Transmit Power Envelope element - 802.11ac-2013 8.4.2.164 From 47312af69a0198ef49ada365cab260398b0f5d70 Mon Sep 17 00:00:00 2001 From: Allan Jude Date: Sat, 7 Jan 2017 04:57:21 +0000 Subject: [PATCH 19/55] Capsicum: add capability mode to users binary Submitted by: Tyler Littlefield Reviewed by: cem, oshogbo Differential Revision: https://reviews.freebsd.org/D9046 --- usr.bin/users/users.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/usr.bin/users/users.cc b/usr.bin/users/users.cc index 914888d9887..2d47786d46a 100644 --- a/usr.bin/users/users.cc +++ b/usr.bin/users/users.cc @@ -27,9 +27,12 @@ * SUCH DAMAGE. */ +#include #include __FBSDID("$FreeBSD$"); +#include +#include #include #include @@ -51,6 +54,10 @@ main(int argc, char **) } setutxent(); + + if (cap_enter() < 0 && errno != ENOSYS) + err(1, "Failed to enter capability mode."); + while ((ut = getutxent()) != NULL) if (ut->ut_type == USER_PROCESS) names.insert(ut->ut_user); From 8e71a4aa83f856a79c264b77f338b22763dbdcf1 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 Jan 2017 07:35:27 +0000 Subject: [PATCH 20/55] [net80211] add syncflags methods for the VHT flags configuration. I missed this in my last commit. Pointy hat to me. --- sys/net80211/ieee80211.c | 54 ++++++++++++++++++++++++++++++++++ sys/net80211/ieee80211_proto.h | 4 ++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c index bb2a02471f5..e4990868f06 100644 --- a/sys/net80211/ieee80211.c +++ b/sys/net80211/ieee80211.c @@ -90,6 +90,7 @@ const uint8_t ieee80211broadcastaddr[IEEE80211_ADDR_LEN] = static void ieee80211_syncflag_locked(struct ieee80211com *ic, int flag); static void ieee80211_syncflag_ht_locked(struct ieee80211com *ic, int flag); static void ieee80211_syncflag_ext_locked(struct ieee80211com *ic, int flag); +static void ieee80211_syncflag_vht_locked(struct ieee80211com *ic, int flag); static int ieee80211_media_setup(struct ieee80211com *ic, struct ifmedia *media, int caps, int addsta, ifm_change_cb_t media_change, ifm_stat_cb_t media_stat); @@ -652,6 +653,12 @@ ieee80211_vap_attach(struct ieee80211vap *vap, ifm_change_cb_t media_change, ieee80211_syncflag_locked(ic, IEEE80211_F_BURST); ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT); ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40); + + ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_VHT); + ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT40); + ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT80); + ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT80P80); + ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT160); IEEE80211_UNLOCK(ic); return 1; @@ -699,6 +706,13 @@ ieee80211_vap_detach(struct ieee80211vap *vap) ieee80211_syncflag_locked(ic, IEEE80211_F_BURST); ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT); ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40); + + ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_VHT); + ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT40); + ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT80); + ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT80P80); + ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT160); + /* NB: this handles the bpfdetach done below */ ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_BPF); if (vap->iv_ifflags & IFF_PROMISC) @@ -852,6 +866,46 @@ ieee80211_syncflag_ht(struct ieee80211vap *vap, int flag) IEEE80211_UNLOCK(ic); } +/* + * Synchronize flags_vht bit state in the com structure + * according to the state of all vap's. This is used, + * for example, to handle state changes via ioctls. + */ +static void +ieee80211_syncflag_vht_locked(struct ieee80211com *ic, int flag) +{ + struct ieee80211vap *vap; + int bit; + + IEEE80211_LOCK_ASSERT(ic); + + bit = 0; + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) + if (vap->iv_flags_vht & flag) { + bit = 1; + break; + } + if (bit) + ic->ic_flags_vht |= flag; + else + ic->ic_flags_vht &= ~flag; +} + +void +ieee80211_syncflag_vht(struct ieee80211vap *vap, int flag) +{ + struct ieee80211com *ic = vap->iv_ic; + + IEEE80211_LOCK(ic); + if (flag < 0) { + flag = -flag; + vap->iv_flags_vht &= ~flag; + } else + vap->iv_flags_vht |= flag; + ieee80211_syncflag_vht_locked(ic, flag); + IEEE80211_UNLOCK(ic); +} + /* * Synchronize flags_ext bit state in the com structure * according to the state of all vap's. This is used, diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h index 0b3a8f748b3..c4d5e7b0ebd 100644 --- a/sys/net80211/ieee80211_proto.h +++ b/sys/net80211/ieee80211_proto.h @@ -77,6 +77,7 @@ void ieee80211_promisc(struct ieee80211vap *, bool); void ieee80211_allmulti(struct ieee80211vap *, bool); void ieee80211_syncflag(struct ieee80211vap *, int flag); void ieee80211_syncflag_ht(struct ieee80211vap *, int flag); +void ieee80211_syncflag_vht(struct ieee80211vap *, int flag); void ieee80211_syncflag_ext(struct ieee80211vap *, int flag); #define ieee80211_input(ni, m, rssi, nf) \ @@ -361,7 +362,8 @@ struct ieee80211_beacon_offsets { uint8_t *bo_csa; /* start of CSA element */ uint8_t *bo_quiet; /* start of Quiet element */ uint8_t *bo_meshconf; /* start of MESHCONF element */ - uint8_t *bo_spare[3]; + uint8_t *bo_vhtinfo; /* start of VHT info element (XXX VHTCAP?) */ + uint8_t *bo_spare[2]; }; struct mbuf *ieee80211_beacon_alloc(struct ieee80211_node *); From 73f14b50b293ca153f288f7be4dce2e2863d5b9f Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Sat, 7 Jan 2017 07:54:23 +0000 Subject: [PATCH 21/55] Unbreak lib/libsysdecode after r311568 by decoding MSG_MORETOCOME flag in msgflags MFC after: 1 month X-MFC with: r311568 Pointyhat to: jhb Reported by: cy Submitted by: Michael Butler Sponsored by: Dell EMC Isilon --- lib/libsysdecode/mktables | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libsysdecode/mktables b/lib/libsysdecode/mktables index 563bd187b1a..6c44a054107 100644 --- a/lib/libsysdecode/mktables +++ b/lib/libsysdecode/mktables @@ -142,7 +142,7 @@ gen_table "seekwhence" "SEEK_[A-Z]+[[:space:]]+[0-9]+" "sys/ gen_table "fcntlcmd" "F_[A-Z0-9_]+[[:space:]]+[0-9]+[[:space:]]+" "sys/fcntl.h" "F_CANCEL|F_..LCK" gen_table "mmapflags" "MAP_[A-Z_]+[[:space:]]+0x[0-9A-Fa-f]+" "sys/mman.h" gen_table "rtpriofuncs" "RTP_[A-Z]+[[:space:]]+[0-9]+" "sys/rtprio.h" -gen_table "msgflags" "MSG_[A-Z]+[[:space:]]+0x[0-9]+" "sys/socket.h" "MSG_SOCALLBCK" +gen_table "msgflags" "MSG_[A-Z]+[[:space:]]+0x[0-9]+" "sys/socket.h" "MSG_SOCALLBCK|MSG_MORETOCOME" gen_table "sigcode" "SI_[A-Z]+[[:space:]]+0(x[0-9abcdef]+)?" "sys/signal.h" gen_table "umtxcvwaitflags" "CVWAIT_[A-Z_]+[[:space:]]+0x[0-9]+" "sys/umtx.h" gen_table "umtxrwlockflags" "URWLOCK_PREFER_READER[[:space:]]+0x[0-9]+" "sys/umtx.h" From 233932cc2a60f2cfc775839787f52ebb794eddf2 Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Sat, 7 Jan 2017 08:08:35 +0000 Subject: [PATCH 22/55] Conditionalize building libwrap support into sshd Only build libwrap support into sshd if MK_TCP_WRAPPERS != no This will unbreak the build if libwrap has been removed from the system MFC after: 2 weeks PR: 210141 Submitted by: kpect@protonmail.com Differential Revision: D9049 --- crypto/openssh/config.h | 2 +- secure/usr.sbin/sshd/Makefile | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/crypto/openssh/config.h b/crypto/openssh/config.h index 364ebe33e2e..ca1ce8e3852 100644 --- a/crypto/openssh/config.h +++ b/crypto/openssh/config.h @@ -1408,7 +1408,7 @@ /* #undef LASTLOG_WRITE_PUTUTXLINE */ /* Define if you want TCP Wrappers support */ -#define LIBWRAP 1 +/* #undef LIBWRAP */ /* Define to whatever link() returns for "not supported" if it doesn't return EOPNOTSUPP. */ diff --git a/secure/usr.sbin/sshd/Makefile b/secure/usr.sbin/sshd/Makefile index a3c645494a3..5fb1e23a2a4 100644 --- a/secure/usr.sbin/sshd/Makefile +++ b/secure/usr.sbin/sshd/Makefile @@ -27,7 +27,7 @@ CFLAGS+=-I${SSHDIR} -include ssh_namespace.h SRCS+= ssh_namespace.h # pam should always happen before ssh here for static linking -LIBADD= pam ssh util wrap +LIBADD= pam ssh util .if ${MK_LDNS} != "no" CFLAGS+= -DHAVE_LDNS=1 @@ -53,6 +53,11 @@ SRCS+= krb5_config.h LIBADD+= gssapi_krb5 gssapi krb5 .endif +.if ${MK_TCP_WRAPPERS} != "no" +CFLAGS+= -DLIBWRAP +LIBADD+= wrap +.endif + LIBADD+= crypto .if defined(LOCALBASE) From 3bc6f09c7b773fd8c267879531d160d6780ccb46 Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Sat, 7 Jan 2017 09:03:40 +0000 Subject: [PATCH 23/55] Move the mibII module up so uncommenting the bridge module works Add a note about how module ordering and dependent modules MFC after: 1 week --- etc/snmpd.config | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/etc/snmpd.config b/etc/snmpd.config index bd2b38253a6..7ffa58bd86b 100644 --- a/etc/snmpd.config +++ b/etc/snmpd.config @@ -122,6 +122,14 @@ snmpEnableAuthenTraps = 2 # order to use the enclosed variables, e.g. `usmUserStatus.$(engine).$(user1)` # can only be used if %usm is uncommented. # +# Modules are loaded in the order listed, so they must be before any +# dependent modules, e.g. "mibII" vs "bridge". +# + +# +# MIB-2 module +# +begemotSnmpdModulePath."mibII" = "/usr/lib/snmp_mibII.so" # # Bridge module @@ -140,11 +148,6 @@ snmpEnableAuthenTraps = 2 # #begemotSnmpdModulePath."lm75" = "/usr/lib/snmp_lm75.so" -# -# MIB-2 module -# -begemotSnmpdModulePath."mibII" = "/usr/lib/snmp_mibII.so" - # # Netgraph module # From 26b1288f5ad5b549bd29939751bc11f1fb77783b Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 7 Jan 2017 09:33:11 +0000 Subject: [PATCH 24/55] Make do_buff_decode() not read past the end of the buffer. Abort format processing as soon as we have no enough data. MFC after: 2 weeks --- lib/libcam/scsi_cmdparse.c | 74 ++++++++++++++++++++------------------ sbin/camcontrol/modeedit.c | 9 ++++- 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/lib/libcam/scsi_cmdparse.c b/lib/libcam/scsi_cmdparse.c index 4a322ba549e..8b43066bfa6 100644 --- a/lib/libcam/scsi_cmdparse.c +++ b/lib/libcam/scsi_cmdparse.c @@ -100,10 +100,11 @@ __FBSDID("$FreeBSD$"); */ static int -do_buff_decode(u_int8_t *databuf, size_t len, +do_buff_decode(u_int8_t *buff, size_t len, void (*arg_put)(void *, int , void *, int, char *), void *puthook, const char *fmt, va_list *ap) { + int ind = 0; int assigned = 0; int width; int suppress; @@ -112,21 +113,17 @@ do_buff_decode(u_int8_t *databuf, size_t len, static u_char mask[] = {0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; int value; - u_char *base = databuf; char *intendp; char letter; char field_name[80]; -# define ARG_PUT(ARG) \ - do \ - { \ - if (!suppress) \ - { \ +#define ARG_PUT(ARG) \ + do { \ + if (!suppress) { \ if (arg_put) \ - (*arg_put)(puthook, (letter == 't' ? \ - 'b' : letter), \ - (void *)((long)(ARG)), width, \ - field_name); \ + (*arg_put)(puthook, (letter == 't' ? 'b' : \ + letter), (void *)((long)(ARG)), width, \ + field_name); \ else \ *(va_arg(*ap, int *)) = (ARG); \ assigned++; \ @@ -187,7 +184,11 @@ do_buff_decode(u_int8_t *databuf, size_t len, done = 1; else { if (shift <= 0) { - bits = *databuf++; + if (ind >= len) { + done = 1; + break; + } + bits = buff[ind++]; shift = 8; } value = (bits >> (shift - width)) & @@ -209,29 +210,31 @@ do_buff_decode(u_int8_t *databuf, size_t len, fmt++; width = strtol(fmt, &intendp, 10); fmt = intendp; + if (ind + width > len) { + done = 1; + break; + } switch(width) { case 1: - ARG_PUT(*databuf); - databuf++; + ARG_PUT(buff[ind]); + ind++; break; case 2: - ARG_PUT((*databuf) << 8 | *(databuf + 1)); - databuf += 2; + ARG_PUT(buff[ind] << 8 | buff[ind + 1]); + ind += 2; break; case 3: - ARG_PUT((*databuf) << 16 | - (*(databuf + 1)) << 8 | *(databuf + 2)); - databuf += 3; + ARG_PUT(buff[ind] << 16 | + buff[ind + 1] << 8 | buff[ind + 2]); + ind += 3; break; case 4: - ARG_PUT((*databuf) << 24 | - (*(databuf + 1)) << 16 | - (*(databuf + 2)) << 8 | - *(databuf + 3)); - databuf += 4; + ARG_PUT(buff[ind] << 24 | buff[ind + 1] << 16 | + buff[ind + 2] << 8 | buff[ind + 3]); + ind += 4; break; default: @@ -242,32 +245,35 @@ do_buff_decode(u_int8_t *databuf, size_t len, break; case 'c': /* Characters (i.e., not swapped) */ - case 'z': /* Characters with zeroed trailing - spaces */ + case 'z': /* Characters with zeroed trailing spaces */ shift = 0; fmt++; width = strtol(fmt, &intendp, 10); fmt = intendp; + if (ind + width > len) { + done = 1; + break; + } if (!suppress) { if (arg_put) (*arg_put)(puthook, - (letter == 't' ? 'b' : letter), - databuf, width, field_name); + (letter == 't' ? 'b' : letter), + &buff[ind], width, field_name); else { char *dest; dest = va_arg(*ap, char *); - bcopy(databuf, dest, width); + bcopy(&buff[ind], dest, width); if (letter == 'z') { char *p; for (p = dest + width - 1; - (p >= (char *)dest) - && (*p == ' '); p--) + p >= dest && *p == ' '; + p--) *p = 0; } } assigned++; } - databuf += width; + ind += width; field_name[0] = 0; suppress = 0; break; @@ -295,9 +301,9 @@ do_buff_decode(u_int8_t *databuf, size_t len, } if (plus) - databuf += width; /* Relative seek */ + ind += width; /* Relative seek */ else - databuf = base + width; /* Absolute seek */ + ind = width; /* Absolute seek */ break; diff --git a/sbin/camcontrol/modeedit.c b/sbin/camcontrol/modeedit.c index 8262c3ca5a4..c98e0c58ef0 100644 --- a/sbin/camcontrol/modeedit.c +++ b/sbin/camcontrol/modeedit.c @@ -193,7 +193,14 @@ editentry_save(void *hook __unused, char *name) struct editentry *src; /* Entry value to save. */ src = editentry_lookup(name); - assert(src != NULL); + if (src == 0) { + /* + * This happens if field does not fit into read page size. + * It also means that this field won't be written, so the + * returned value does not really matter. + */ + return (0); + } switch (src->type) { case 'i': /* Byte-sized integral type. */ From 54644e21e8a23184e6cb673bfba1a85af70b558a Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 7 Jan 2017 09:56:12 +0000 Subject: [PATCH 25/55] Make 'camcontrol modepage' support subpages. MFC after: 2 weeks --- sbin/camcontrol/camcontrol.8 | 11 +- sbin/camcontrol/camcontrol.c | 58 ++++---- sbin/camcontrol/camcontrol.h | 8 +- sbin/camcontrol/modeedit.c | 247 ++++++++++++++++++++--------------- share/misc/scsi_modes | 160 +++++++++++++++++------ sys/cam/scsi/scsi_all.c | 42 +++--- sys/cam/scsi/scsi_all.h | 29 ++-- sys/cam/scsi/scsi_ch.c | 6 +- 8 files changed, 350 insertions(+), 211 deletions(-) diff --git a/sbin/camcontrol/camcontrol.8 b/sbin/camcontrol/camcontrol.8 index ee44d55772c..86975640781 100644 --- a/sbin/camcontrol/camcontrol.8 +++ b/sbin/camcontrol/camcontrol.8 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 30, 2016 +.Dd January 6, 2017 .Dt CAMCONTROL 8 .Os .Sh NAME @@ -121,7 +121,7 @@ .Ic modepage .Op device id .Op generic args -.Aq Fl m Ar page | Fl l +.Aq Fl m Ar page[,subpage] | Fl l .Op Fl P Ar pgctl .Op Fl b | Fl e .Op Fl d @@ -702,9 +702,10 @@ The editor will be invoked if detects that standard input is terminal. .It Fl l Lists all available mode pages. -.It Fl m Ar mode_page -This specifies the number of the mode page the user would like to view -and/or edit. +If specified more then once, also lists subpages. +.It Fl m Ar page[,subpage] +This specifies the number of the mode page and optionally subpage the user +would like to view and/or edit. This argument is mandatory unless .Fl l is specified. diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index 8fdb45ca9cf..5184fee9436 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -125,12 +125,9 @@ typedef enum { CAM_ARG_GET_STDINQ = 0x00002000, CAM_ARG_GET_XFERRATE = 0x00004000, CAM_ARG_INQ_MASK = 0x00007000, - CAM_ARG_MODE_EDIT = 0x00008000, - CAM_ARG_PAGE_CNTL = 0x00010000, CAM_ARG_TIMEOUT = 0x00020000, CAM_ARG_CMD_IN = 0x00040000, CAM_ARG_CMD_OUT = 0x00080000, - CAM_ARG_DBD = 0x00100000, CAM_ARG_ERR_RECOVER = 0x00200000, CAM_ARG_RETRIES = 0x00400000, CAM_ARG_START_UNIT = 0x00800000, @@ -3987,8 +3984,8 @@ reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks) #ifndef MINIMALISTIC void -mode_sense(struct cam_device *device, int mode_page, int page_control, - int dbd, int retry_count, int timeout, u_int8_t *data, int datalen) +mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage, + int retry_count, int timeout, u_int8_t *data, int datalen) { union ccb *ccb; int retval; @@ -4000,15 +3997,17 @@ mode_sense(struct cam_device *device, int mode_page, int page_control, CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); - scsi_mode_sense(&ccb->csio, + scsi_mode_sense_subpage(&ccb->csio, /* retries */ retry_count, /* cbfcnp */ NULL, /* tag_action */ MSG_SIMPLE_Q_TAG, /* dbd */ dbd, - /* page_code */ page_control << 6, - /* page */ mode_page, + /* pc */ pc << 6, + /* page */ page, + /* subpage */ subpage, /* param_buf */ data, /* param_len */ datalen, + /* minimum_cmd_size */ 0, /* sense_len */ SSD_FULL_SIZE, /* timeout */ timeout ? timeout : 5000); @@ -4089,8 +4088,9 @@ void modepage(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout) { - int c, mode_page = -1, page_control = 0; - int binary = 0, list = 0; + char *str_subpage; + int c, page = -1, subpage = -1, pc = 0; + int binary = 0, dbd = 0, edit = 0, list = 0; while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c) { @@ -4098,40 +4098,44 @@ modepage(struct cam_device *device, int argc, char **argv, char *combinedopt, binary = 1; break; case 'd': - arglist |= CAM_ARG_DBD; + dbd = 1; break; case 'e': - arglist |= CAM_ARG_MODE_EDIT; + edit = 1; break; case 'l': - list = 1; + list++; break; case 'm': - mode_page = strtol(optarg, NULL, 0); - if (mode_page < 0) - errx(1, "invalid mode page %d", mode_page); + str_subpage = optarg; + strsep(&str_subpage, ","); + page = strtol(optarg, NULL, 0); + if (str_subpage) + subpage = strtol(str_subpage, NULL, 0); + else + subpage = 0; + if (page < 0) + errx(1, "invalid mode page %d", page); + if (subpage < 0) + errx(1, "invalid mode subpage %d", subpage); break; case 'P': - page_control = strtol(optarg, NULL, 0); - if ((page_control < 0) || (page_control > 3)) - errx(1, "invalid page control field %d", - page_control); - arglist |= CAM_ARG_PAGE_CNTL; + pc = strtol(optarg, NULL, 0); + if ((pc < 0) || (pc > 3)) + errx(1, "invalid page control field %d", pc); break; default: break; } } - if (mode_page == -1 && list == 0) + if (page == -1 && list == 0) errx(1, "you must specify a mode page!"); - if (list) { - mode_list(device, page_control, arglist & CAM_ARG_DBD, - retry_count, timeout); + if (list != 0) { + mode_list(device, dbd, pc, list > 1, retry_count, timeout); } else { - mode_edit(device, mode_page, page_control, - arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary, + mode_edit(device, dbd, pc, page, subpage, edit, binary, retry_count, timeout); } } diff --git a/sbin/camcontrol/camcontrol.h b/sbin/camcontrol/camcontrol.h index a9a661e728a..9ea16761b2b 100644 --- a/sbin/camcontrol/camcontrol.h +++ b/sbin/camcontrol/camcontrol.h @@ -84,14 +84,14 @@ int epc(struct cam_device *device, int argc, char **argv, char *combinedopt, int timestamp(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout, int verbosemode); -void mode_sense(struct cam_device *device, int mode_page, int page_control, - int dbd, int retry_count, int timeout, u_int8_t *data, +void mode_sense(struct cam_device *device, int dbd, int pc, int page, + int subpage, int retry_count, int timeout, uint8_t *data, int datalen); void mode_select(struct cam_device *device, int save_pages, int retry_count, int timeout, u_int8_t *data, int datalen); -void mode_edit(struct cam_device *device, int page, int page_control, int dbd, +void mode_edit(struct cam_device *device, int dbd, int pc, int page, int subpage, int edit, int binary, int retry_count, int timeout); -void mode_list(struct cam_device *device, int page_control, int dbd, +void mode_list(struct cam_device *device, int dbd, int pc, int subpages, int retry_count, int timeout); int scsidoinquiry(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); diff --git a/sbin/camcontrol/modeedit.c b/sbin/camcontrol/modeedit.c index c98e0c58ef0..cbc138caf39 100644 --- a/sbin/camcontrol/modeedit.c +++ b/sbin/camcontrol/modeedit.c @@ -66,9 +66,6 @@ __FBSDID("$FreeBSD$"); #define MODE_PAGE_HEADER(mh) \ (struct scsi_mode_page_header *)find_mode_page_6(mh) -#define MODE_PAGE_DATA(mph) \ - (u_int8_t *)(mph) + sizeof(struct scsi_mode_page_header) - struct editentry { STAILQ_ENTRY(editentry) link; @@ -86,7 +83,8 @@ static int editlist_changed = 0; /* Whether any entries were changed. */ struct pagename { SLIST_ENTRY(pagename) link; - int pagenum; + int page; + int subpage; char *name; }; static SLIST_HEAD(, pagename) namelist; /* Page number to name mappings. */ @@ -106,21 +104,22 @@ static int editentry_save(void *hook, char *name); static struct editentry *editentry_lookup(char *name); static int editentry_set(char *name, char *newvalue, int editonly); -static void editlist_populate(struct cam_device *device, - int modepage, int page_control, - int dbd, int retries, int timeout); -static void editlist_save(struct cam_device *device, int modepage, - int page_control, int dbd, int retries, - int timeout); -static void nameentry_create(int pagenum, char *name); -static struct pagename *nameentry_lookup(int pagenum); -static int load_format(const char *pagedb_path, int page); +static void editlist_populate(struct cam_device *device, int dbd, + int pc, int page, int subpage, + int retries, int timeout); +static void editlist_save(struct cam_device *device, int dbd, + int pc, int page, int subpage, + int retries, int timeout); +static void nameentry_create(int page, int subpage, char *name); +static struct pagename *nameentry_lookup(int page, int subpage); +static int load_format(const char *pagedb_path, int lpage, + int lsubpage); static int modepage_write(FILE *file, int editonly); static int modepage_read(FILE *file); static void modepage_edit(void); -static void modepage_dump(struct cam_device *device, int page, - int page_control, int dbd, int retries, - int timeout); +static void modepage_dump(struct cam_device *device, int dbd, + int pc, int page, int subpage, int retries, + int timeout); static void cleanup_editfile(void); @@ -325,10 +324,10 @@ editentry_set(char *name, char *newvalue, int editonly) } static void -nameentry_create(int pagenum, char *name) { +nameentry_create(int page, int subpage, char *name) { struct pagename *newentry; - if (pagenum < 0 || name == NULL || name[0] == '\0') + if (page < 0 || subpage < 0 || name == NULL || name[0] == '\0') return; /* Allocate memory for the new entry and a copy of the entry name. */ @@ -339,16 +338,17 @@ nameentry_create(int pagenum, char *name) { /* Trim any trailing whitespace for the page name. */ RTRIM(newentry->name); - newentry->pagenum = pagenum; + newentry->page = page; + newentry->subpage = subpage; SLIST_INSERT_HEAD(&namelist, newentry, link); } static struct pagename * -nameentry_lookup(int pagenum) { +nameentry_lookup(int page, int subpage) { struct pagename *scan; SLIST_FOREACH(scan, &namelist, link) { - if (pagenum == scan->pagenum) + if (page == scan->page && subpage == scan->subpage) return (scan); } @@ -357,12 +357,14 @@ nameentry_lookup(int pagenum) { } static int -load_format(const char *pagedb_path, int page) +load_format(const char *pagedb_path, int lpage, int lsubpage) { FILE *pagedb; - char str_pagenum[MAX_PAGENUM_LEN]; + char str_page[MAX_PAGENUM_LEN]; + char *str_subpage; char str_pagename[MAX_PAGENAME_LEN]; - int pagenum; + int page; + int subpage; int depth; /* Quoting depth. */ int found; int lineno; @@ -371,9 +373,10 @@ load_format(const char *pagedb_path, int page) char c; #define SETSTATE_LOCATE do { \ - str_pagenum[0] = '\0'; \ + str_page[0] = '\0'; \ str_pagename[0] = '\0'; \ - pagenum = -1; \ + page = -1; \ + subpage = -1; \ state = LOCATE; \ } while (0) @@ -450,32 +453,46 @@ load_format(const char *pagedb_path, int page) * modes without providing a mode definition). */ /* Record the name of this page. */ - pagenum = strtol(str_pagenum, NULL, 0); - nameentry_create(pagenum, str_pagename); + str_subpage = str_page; + strsep(&str_subpage, ","); + page = strtol(str_page, NULL, 0); + if (str_subpage) + subpage = strtol(str_subpage, NULL, 0); + else + subpage = 0; + nameentry_create(page, subpage, str_pagename); SETSTATE_LOCATE; } else if (depth == 0 && c == PAGENAME_START) { SETSTATE_PAGENAME; } else if (c == PAGEDEF_START) { - pagenum = strtol(str_pagenum, NULL, 0); + str_subpage = str_page; + strsep(&str_subpage, ","); + page = strtol(str_page, NULL, 0); + if (str_subpage) + subpage = strtol(str_subpage, NULL, 0); + else + subpage = 0; if (depth == 1) { /* Record the name of this page. */ - nameentry_create(pagenum, str_pagename); + nameentry_create(page, subpage, + str_pagename); /* * Only record the format if this is * the page we are interested in. */ - if (page == pagenum && !found) + if (lpage == page && + lsubpage == subpage && !found) SETSTATE_PAGEDEF; } } else if (c == PAGEDEF_END) { /* Reset the processor state. */ SETSTATE_LOCATE; - } else if (depth == 0 && ! BUFFERFULL(str_pagenum)) { - strncat(str_pagenum, &c, 1); + } else if (depth == 0 && ! BUFFERFULL(str_page)) { + strncat(str_page, &c, 1); } else if (depth == 0) { errx(EX_OSFILE, "%s:%d: %s %zd %s", pagedb_path, lineno, "page identifier exceeds", - sizeof(str_pagenum) - 1, "characters"); + sizeof(str_page) - 1, "characters"); } break; @@ -491,7 +508,7 @@ load_format(const char *pagedb_path, int page) } else { errx(EX_OSFILE, "%s:%d: %s %zd %s", pagedb_path, lineno, "page name exceeds", - sizeof(str_pagenum) - 1, "characters"); + sizeof(str_page) - 1, "characters"); } break; @@ -532,88 +549,95 @@ load_format(const char *pagedb_path, int page) } static void -editlist_populate(struct cam_device *device, int modepage, int page_control, - int dbd, int retries, int timeout) +editlist_populate(struct cam_device *device, int dbd, int pc, int page, + int subpage, int retries, int timeout) { u_int8_t data[MAX_COMMAND_SIZE];/* Buffer to hold sense data. */ u_int8_t *mode_pars; /* Pointer to modepage params. */ struct scsi_mode_header_6 *mh; /* Location of mode header. */ struct scsi_mode_page_header *mph; + struct scsi_mode_page_header_sp *mphsp; + int len; STAILQ_INIT(&editlist); /* Fetch changeable values; use to build initial editlist. */ - mode_sense(device, modepage, 1, dbd, retries, timeout, data, + mode_sense(device, dbd, 1, page, subpage, retries, timeout, data, sizeof(data)); mh = (struct scsi_mode_header_6 *)data; mph = MODE_PAGE_HEADER(mh); - mode_pars = MODE_PAGE_DATA(mph); + if ((mph->page_code & SMPH_SPF) == 0) { + mode_pars = (uint8_t *)(mph + 1); + len = mph->page_length; + } else { + mphsp = (struct scsi_mode_page_header_sp *)mph; + mode_pars = (uint8_t *)(mphsp + 1); + len = scsi_2btoul(mphsp->page_length); + } /* Decode the value data, creating edit_entries for each value. */ - buff_decode_visit(mode_pars, mh->data_length, format, - editentry_create, 0); + buff_decode_visit(mode_pars, len, format, editentry_create, 0); /* Fetch the current/saved values; use to set editentry values. */ - mode_sense(device, modepage, page_control, dbd, retries, timeout, data, - sizeof(data)); - buff_decode_visit(mode_pars, mh->data_length, format, - editentry_update, 0); + mode_sense(device, dbd, pc, page, subpage, retries, timeout, + data, sizeof(data)); + buff_decode_visit(mode_pars, len, format, editentry_update, 0); } static void -editlist_save(struct cam_device *device, int modepage, int page_control, - int dbd, int retries, int timeout) +editlist_save(struct cam_device *device, int dbd, int pc, int page, + int subpage, int retries, int timeout) { u_int8_t data[MAX_COMMAND_SIZE];/* Buffer to hold sense data. */ u_int8_t *mode_pars; /* Pointer to modepage params. */ struct scsi_mode_header_6 *mh; /* Location of mode header. */ struct scsi_mode_page_header *mph; + struct scsi_mode_page_header_sp *mphsp; + int len, hlen; /* Make sure that something changed before continuing. */ if (! editlist_changed) return; - /* - * Preload the CDB buffer with the current mode page data. - * XXX If buff_encode_visit would return the number of bytes encoded - * we *should* use that to build a header from scratch. As it is - * now, we need mode_sense to find out the page length. - */ - mode_sense(device, modepage, page_control, dbd, retries, timeout, data, - sizeof(data)); + /* Preload the CDB buffer with the current mode page data. */ + mode_sense(device, dbd, pc, page, subpage, retries, timeout, + data, sizeof(data)); /* Initial headers & offsets. */ mh = (struct scsi_mode_header_6 *)data; mph = MODE_PAGE_HEADER(mh); - mode_pars = MODE_PAGE_DATA(mph); + if ((mph->page_code & SMPH_SPF) == 0) { + hlen = sizeof(*mph); + mode_pars = (uint8_t *)(mph + 1); + len = mph->page_length; + } else { + mphsp = (struct scsi_mode_page_header_sp *)mph; + hlen = sizeof(*mphsp); + mode_pars = (uint8_t *)(mphsp + 1); + len = scsi_2btoul(mphsp->page_length); + } /* Encode the value data to be passed back to the device. */ - buff_encode_visit(mode_pars, mh->data_length, format, - editentry_save, 0); + buff_encode_visit(mode_pars, len, format, editentry_save, 0); /* Eliminate block descriptors. */ - bcopy(mph, ((u_int8_t *)mh) + sizeof(*mh), - sizeof(*mph) + mph->page_length); + bcopy(mph, mh + 1, hlen + len); /* Recalculate headers & offsets. */ - mh->blk_desc_len = 0; /* No block descriptors. */ - mh->dev_spec = 0; /* Clear device-specific parameters. */ - mph = MODE_PAGE_HEADER(mh); - mode_pars = MODE_PAGE_DATA(mph); - - mph->page_code &= SMS_PAGE_CODE;/* Isolate just the page code. */ mh->data_length = 0; /* Reserved for MODE SELECT command. */ + mh->dev_spec = 0; /* Clear device-specific parameters. */ + mh->blk_desc_len = 0; /* No block descriptors. */ + mph = MODE_PAGE_HEADER(mh); + mph->page_code &= ~SMPH_PS; /* Reserved for MODE SELECT command. */ /* * Write the changes back to the device. If the user editted control * page 3 (saved values) then request the changes be permanently * recorded. */ - mode_select(device, - (page_control << PAGE_CTRL_SHIFT == SMS_PAGE_CTRL_SAVED), - retries, timeout, (u_int8_t *)mh, - sizeof(*mh) + mh->blk_desc_len + sizeof(*mph) + mph->page_length); + mode_select(device, (pc << PAGE_CTRL_SHIFT == SMS_PAGE_CTRL_SAVED), + retries, timeout, (u_int8_t *)mh, sizeof(*mh) + hlen + len); } static int @@ -782,24 +806,32 @@ modepage_edit(void) } static void -modepage_dump(struct cam_device *device, int page, int page_control, int dbd, +modepage_dump(struct cam_device *device, int dbd, int pc, int page, int subpage, int retries, int timeout) { u_int8_t data[MAX_COMMAND_SIZE];/* Buffer to hold sense data. */ u_int8_t *mode_pars; /* Pointer to modepage params. */ struct scsi_mode_header_6 *mh; /* Location of mode header. */ struct scsi_mode_page_header *mph; - int indx; /* Index for scanning mode params. */ + struct scsi_mode_page_header_sp *mphsp; + int indx, len; - mode_sense(device, page, page_control, dbd, retries, timeout, data, - sizeof(data)); + mode_sense(device, dbd, pc, page, subpage, retries, timeout, + data, sizeof(data)); mh = (struct scsi_mode_header_6 *)data; mph = MODE_PAGE_HEADER(mh); - mode_pars = MODE_PAGE_DATA(mph); + if ((mph->page_code & SMPH_SPF) == 0) { + mode_pars = (uint8_t *)(mph + 1); + len = mph->page_length; + } else { + mphsp = (struct scsi_mode_page_header_sp *)mph; + mode_pars = (uint8_t *)(mphsp + 1); + len = scsi_2btoul(mphsp->page_length); + } /* Print the raw mode page data with newlines each 8 bytes. */ - for (indx = 0; indx < mph->page_length; indx++) { + for (indx = 0; indx < len; indx++) { printf("%02x%c",mode_pars[indx], (((indx + 1) % 8) == 0) ? '\n' : ' '); } @@ -817,7 +849,7 @@ cleanup_editfile(void) } void -mode_edit(struct cam_device *device, int page, int page_control, int dbd, +mode_edit(struct cam_device *device, int dbd, int pc, int page, int subpage, int edit, int binary, int retry_count, int timeout) { const char *pagedb_path; /* Path to modepage database. */ @@ -829,15 +861,17 @@ mode_edit(struct cam_device *device, int page, int page_control, int dbd, if ((pagedb_path = getenv("SCSI_MODES")) == NULL) pagedb_path = DEFAULT_SCSI_MODE_DB; - if (load_format(pagedb_path, page) != 0 && (edit || verbose)) { + if (load_format(pagedb_path, page, subpage) != 0 && + (edit || verbose)) { if (errno == ENOENT) { /* Modepage database file not found. */ warn("cannot open modepage database \"%s\"", pagedb_path); } else if (errno == ESRCH) { /* Modepage entry not found in database. */ - warnx("modepage %d not found in database" - "\"%s\"", page, pagedb_path); + warnx("modepage 0x%02x,0x%02x not found in " + "database \"%s\"", page, subpage, + pagedb_path); } /* We can recover in display mode, otherwise we exit. */ if (!edit) { @@ -847,22 +881,20 @@ mode_edit(struct cam_device *device, int page, int page_control, int dbd, exit(EX_OSFILE); } - editlist_populate(device, page, page_control, dbd, retry_count, + editlist_populate(device, dbd, pc, page, subpage, retry_count, timeout); } if (edit) { - if (page_control << PAGE_CTRL_SHIFT != SMS_PAGE_CTRL_CURRENT && - page_control << PAGE_CTRL_SHIFT != SMS_PAGE_CTRL_SAVED) + if (pc << PAGE_CTRL_SHIFT != SMS_PAGE_CTRL_CURRENT && + pc << PAGE_CTRL_SHIFT != SMS_PAGE_CTRL_SAVED) errx(EX_USAGE, "it only makes sense to edit page 0 " "(current) or page 3 (saved values)"); modepage_edit(); - editlist_save(device, page, page_control, dbd, retry_count, - timeout); + editlist_save(device, dbd, pc, page, subpage, retry_count, timeout); } else if (binary || STAILQ_EMPTY(&editlist)) { /* Display without formatting information. */ - modepage_dump(device, page, page_control, dbd, retry_count, - timeout); + modepage_dump(device, dbd, pc, page, subpage, retry_count, timeout); } else { /* Display with format. */ modepage_write(stdout, 0); @@ -870,44 +902,55 @@ mode_edit(struct cam_device *device, int page, int page_control, int dbd, } void -mode_list(struct cam_device *device, int page_control, int dbd, +mode_list(struct cam_device *device, int dbd, int pc, int subpages, int retry_count, int timeout) { u_int8_t data[MAX_COMMAND_SIZE];/* Buffer to hold sense data. */ struct scsi_mode_header_6 *mh; /* Location of mode header. */ struct scsi_mode_page_header *mph; + struct scsi_mode_page_header_sp *mphsp; struct pagename *nameentry; const char *pagedb_path; - int len; + int len, page, subpage; if ((pagedb_path = getenv("SCSI_MODES")) == NULL) pagedb_path = DEFAULT_SCSI_MODE_DB; - if (load_format(pagedb_path, 0) != 0 && verbose && errno == ENOENT) { + if (load_format(pagedb_path, 0, 0) != 0 && verbose && errno == ENOENT) { /* Modepage database file not found. */ warn("cannot open modepage database \"%s\"", pagedb_path); } /* Build the list of all mode pages by querying the "all pages" page. */ - mode_sense(device, SMS_ALL_PAGES_PAGE, page_control, dbd, retry_count, - timeout, data, sizeof(data)); + mode_sense(device, dbd, pc, SMS_ALL_PAGES_PAGE, + subpages ? SMS_SUBPAGE_ALL : 0, + retry_count, timeout, data, sizeof(data)); mh = (struct scsi_mode_header_6 *)data; len = sizeof(*mh) + mh->blk_desc_len; /* Skip block descriptors. */ /* Iterate through the pages in the reply. */ while (len < mh->data_length) { /* Locate the next mode page header. */ - mph = (struct scsi_mode_page_header *) - ((intptr_t)mh + len); + mph = (struct scsi_mode_page_header *)((intptr_t)mh + len); - mph->page_code &= SMS_PAGE_CODE; - nameentry = nameentry_lookup(mph->page_code); + if ((mph->page_code & SMPH_SPF) == 0) { + page = mph->page_code & SMS_PAGE_CODE; + subpage = 0; + len += sizeof(*mph) + mph->page_length; + } else { + mphsp = (struct scsi_mode_page_header_sp *)mph; + page = mphsp->page_code & SMS_PAGE_CODE; + subpage = mphsp->subpage; + len += sizeof(*mphsp) + scsi_2btoul(mphsp->page_length); + } - if (nameentry == NULL || nameentry->name == NULL) - printf("0x%02x\n", mph->page_code); - else - printf("0x%02x\t%s\n", mph->page_code, - nameentry->name); - len += mph->page_length + sizeof(*mph); + nameentry = nameentry_lookup(page, subpage); + if (subpage == 0) { + printf("0x%02x\t%s\n", page, + nameentry ? nameentry->name : ""); + } else { + printf("0x%02x,0x%02x\t%s\n", page, subpage, + nameentry ? nameentry->name : ""); + } } } diff --git a/share/misc/scsi_modes b/share/misc/scsi_modes index ec791c7f64a..4a5939cb0e8 100644 --- a/share/misc/scsi_modes +++ b/share/misc/scsi_modes @@ -49,7 +49,11 @@ # ALL DEVICE TYPES -0x0a "Control Mode Page" { +0x0a,0x03 "Command Duration Limit A"; + +0x0a,0x04 "Command Duration Limit B"; + +0x0a "Control" { {TST} t3 {TMF_ONLY} t1 {DPICZ} t1 @@ -78,7 +82,18 @@ {Extended Self-Test Completion Time} i2 } -0x02 "Disconnect-Reconnect Page" { +0x0a,0x01 "Control Extension" { + {Reserved} *t4 + {DLC} t1 + {TCMOS} t1 + {SCSIP} t1 + {IALUAE} t1 + {Reserved} *t4 + {Initial Command Priority} t4 + {Maximum Sense Data Length} i1 +} + +0x02 "Disconnect-Reconnect" { {Buffer Full Ratio} i1 {Buffer Empty Ratio} i1 {Bus Inactivity Limit} i2 @@ -92,26 +107,11 @@ {Reserved} *i1 } -0x15 "Extended Page"; +0x15 "Extended"; -0x16 "Extended Device-Type Specific Page"; +0x16 "Extended Device-Type Specific"; -0x1c "Informational Exceptions Control Page" { - {PERF} t1 - {Reserved} *t1 - {EBF} t1 - {EWasc} t1 - {DExcpt} t1 - {TEST} t1 - {EBACKERR} t1 - {LogErr} t1 - {Reserved} *t4 - {MRIE} t4 - {Interval Timer} i4 - {Report Count} i4 -} - -0x09 "Peripheral Device Page" { +0x09 "Peripheral Device" { {Interface Identifier} i2 {Reserved} *i1 {Reserved} *i1 @@ -119,21 +119,69 @@ {Reserved} *i1 } -0x1a "Power Condition Page" { - {Reserved} *i1 +0x1a "Power Condition" { + {PM_BG_PRECEDENCE} t1 {Reserved} *t6 - {Idle} t1 - {Standby} t1 - {Idle Condition Timer} i4 - {Standby Condition Timer} i4 + {STANDBY_Y} t1 + {Reserved} *t4 + {IDLE_C} t1 + {IDLE_B} t1 + {IDLE_A} t1 + {STANDBY_Z} t1 + {IDLE_A Condition Timer} i4 + {STANDBY_Z Condition Timer} i4 + {IDLE_B Condition Timer} i4 + {IDLE_C Condition Timer} i4 + {STANDBY_Y Condition Timer} i4 + {Reserved} *i4 + {Reserved} *i4 + {Reserved} *i4 + {Reserved} *i3 + {CCF Idle} t2 + {CCF Standby} t2 + {CCF Stopped} t2 + {Reserved} *t2 } -0x18 "Protocol-Specific LUN Page"; +0x1a,0x01 "Power Consumption" { + {Reserved} *i2 + {Reserved} *t6 + {Active Level} t2 + {Power Consumption Identifier} i1 + {Reserved} *i4 + {Reserved} *i4 +} -0x19 "Protocol-Specific Port Page"; +0x18 "Protocol-Specific Logical Unit"; + +0x19 "Protocol-Specific Port"; # DIRECT ACCESS DEVICES -0x08 "Caching Page" { + +0x0a,0x02 "Application Tag"; + +0x1a,0xf1 "ATA Power Condition"; + +0x1c,0x01 "Background Control" { + {Reserved} *t5 + {S_L_FULL} *t1 + {LOWIR} *t1 + {EN_BMS} *t1 + {Reserved} *t7 + {EN_PS} *t1 + {Background Medium Scan Interval Time} i2 + {Background Pre-Scan Time Limit} i2 + {Minimum Idle Time Before Background Scan} i2 + {Maximum Time To Suspend Background Scan} i2 + {Reserved} *i2 +} + +0x0a,0x06 "Background Operation Control" { + {BO_MODE} t2 + {Reserved} *t6 +} + +0x08 "Caching" { {IC} t1 {ABPF} t1 {CAP} t1 @@ -159,7 +207,7 @@ {Reserved} *t4 } -0x05 "Flexible Disk Page" { +0x05 "Flexible Disk" { {Transfer rate} i2 {Number of heads} i1 {Sectors per track} i1 @@ -190,7 +238,7 @@ {Reserved} *i1 } -0x03 "Format Device Page" { +0x03 "Format Device" { {Tracks per Zone} i2 {Alternate Sectors per Zone} i2 {Alternate Tracks per Zone} i2 @@ -207,7 +255,34 @@ {Reserved} *t4 } -0x0b "Medium Types Supported Page" { +0x0a,0x05 "I/O Advice Hints Grouping"; + +0x1c "Informational Exceptions Control" { + {PERF} t1 + {Reserved} *t1 + {EBF} t1 + {EWasc} t1 + {DExcpt} t1 + {TEST} t1 + {EBACKERR} t1 + {LogErr} t1 + {Reserved} *t4 + {MRIE} t4 + {Interval Timer} i4 + {Report Count} i4 +} + +0x1c,0x02 "Logical Block Provisioning" { + {Reserved} *t7 + {SITUA} t1 + {Reserved} *i1 + {Reserved} *i1 + {Reserved} *i1 + {Reserved} *i4 + {Reserved} *i4 +} + +0x0b "Medium Types Supported" { {Reserved} *i1 {Reserved} *i1 {Medium type one supported} i1 @@ -216,10 +291,11 @@ {Medium type four supported} i1 } -# Notch page (0x0c) -0x0c "Notch and Partition Page"; +0x0c "Notch and Partition"; -0x01 "Read-Write Error Recovery Page" { +0x0a,0xf1 "PATA Control"; + +0x01 "Read-Write Error Recovery" { {AWRE (Auto Write Reallocation Enbld)} t1 {ARRE (Auto Read Reallocation Enbld)} t1 {TB (Transfer Block)} t1 @@ -240,7 +316,7 @@ {Recovery Time Limit} i2 } -0x04 "Rigid Disk Drive Geometry Page" { +0x04 "Rigid Disk Drive Geometry" { {Number of Cylinders} i3 {Number of Heads} i1 {Starting Cylinder-Write Precompensation} i3 @@ -256,7 +332,7 @@ {Reserved} *i1 } -0x07 "Verify Error Recovery Page" { +0x07 "Verify Error Recovery" { {Reserved} *t4 {EER} t1 {PER} t1 @@ -272,7 +348,7 @@ {Verify Recovery Time Limit} i2 } -0x0E "CD-ROM Audio Control Parameters Page" { +0x0E "CD-ROM Audio Control Parameters" { {Reserved} *t5 {Immed} t1 {SOTC} t1 @@ -297,7 +373,7 @@ } # SEQUENTIAL ACCESS DEVICES -0x10 "Device Configuration Page" { +0x10 "Device Configuration" { {Reserved} *t1 {Change Active Partition} t1 {Change Active Format} t1 @@ -326,7 +402,7 @@ {SCSI-3 Permanent Write Protect} t1 } -0x0f "Data Compression Page" { +0x0f "Data Compression" { {Data Compression Enabled} t1 {Date Compression Capable} t1 {Reserved} *t6 @@ -339,7 +415,7 @@ } # Removable devices -0x1b "Removable Block Access Capacities Page" { +0x1b "Removable Block Access Capacities" { {System Floppy Type Device} t1 {Supports Reporting Format Progress} t1 {Reserved} *t6 @@ -351,7 +427,7 @@ } # CD-ROM (and CD-R[W]) devices -0x2a "CD capabilities and mechanical status page" { +0x2a "CD capabilities and mechanical status" { {Reserved} *t4 {Method 2} t1 {CD-RW Read} t1 diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c index 4c58e222b09..192a8d4a5ee 100644 --- a/sys/cam/scsi/scsi_all.c +++ b/sys/cam/scsi/scsi_all.c @@ -7622,24 +7622,34 @@ scsi_inquiry(struct ccb_scsiio *csio, u_int32_t retries, } void -scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries, - void (*cbfcnp)(struct cam_periph *, union ccb *), - u_int8_t tag_action, int dbd, u_int8_t page_code, - u_int8_t page, u_int8_t *param_buf, u_int32_t param_len, - u_int8_t sense_len, u_int32_t timeout) +scsi_mode_sense(struct ccb_scsiio *csio, uint32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, + int dbd, uint8_t pc, uint8_t page, uint8_t *param_buf, uint32_t param_len, + uint8_t sense_len, uint32_t timeout) { - scsi_mode_sense_len(csio, retries, cbfcnp, tag_action, dbd, - page_code, page, param_buf, param_len, 0, - sense_len, timeout); + scsi_mode_sense_subpage(csio, retries, cbfcnp, tag_action, dbd, + pc, page, 0, param_buf, param_len, 0, sense_len, timeout); } void -scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries, - void (*cbfcnp)(struct cam_periph *, union ccb *), - u_int8_t tag_action, int dbd, u_int8_t page_code, - u_int8_t page, u_int8_t *param_buf, u_int32_t param_len, - int minimum_cmd_size, u_int8_t sense_len, u_int32_t timeout) +scsi_mode_sense_len(struct ccb_scsiio *csio, uint32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, + int dbd, uint8_t pc, uint8_t page, uint8_t *param_buf, uint32_t param_len, + int minimum_cmd_size, uint8_t sense_len, uint32_t timeout) +{ + + scsi_mode_sense_subpage(csio, retries, cbfcnp, tag_action, dbd, + pc, page, 0, param_buf, param_len, minimum_cmd_size, + sense_len, timeout); +} + +void +scsi_mode_sense_subpage(struct ccb_scsiio *csio, uint32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, + int dbd, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t *param_buf, + uint32_t param_len, int minimum_cmd_size, uint8_t sense_len, + uint32_t timeout) { u_int8_t cdb_len; @@ -7658,7 +7668,8 @@ scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries, scsi_cmd->opcode = MODE_SENSE_6; if (dbd != 0) scsi_cmd->byte2 |= SMS_DBD; - scsi_cmd->page = page_code | page; + scsi_cmd->page = pc | page; + scsi_cmd->subpage = subpage; scsi_cmd->length = param_len; cdb_len = sizeof(*scsi_cmd); } else { @@ -7672,7 +7683,8 @@ scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries, scsi_cmd->opcode = MODE_SENSE_10; if (dbd != 0) scsi_cmd->byte2 |= SMS_DBD; - scsi_cmd->page = page_code | page; + scsi_cmd->page = pc | page; + scsi_cmd->subpage = subpage; scsi_ulto2b(param_len, scsi_cmd->length); cdb_len = sizeof(*scsi_cmd); } diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h index b90f7e594e9..64c45fb26a4 100644 --- a/sys/cam/scsi/scsi_all.h +++ b/sys/cam/scsi/scsi_all.h @@ -3977,21 +3977,24 @@ void scsi_inquiry(struct ccb_scsiio *csio, u_int32_t retries, u_int8_t sense_len, u_int32_t timeout); void scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries, - void (*cbfcnp)(struct cam_periph *, - union ccb *), - u_int8_t tag_action, int dbd, - u_int8_t page_code, u_int8_t page, - u_int8_t *param_buf, u_int32_t param_len, - u_int8_t sense_len, u_int32_t timeout); + void (*cbfcnp)(struct cam_periph *, union ccb *), + uint8_t tag_action, int dbd, uint8_t pc, uint8_t page, + uint8_t *param_buf, uint32_t param_len, + uint8_t sense_len, uint32_t timeout); void scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries, - void (*cbfcnp)(struct cam_periph *, - union ccb *), - u_int8_t tag_action, int dbd, - u_int8_t page_code, u_int8_t page, - u_int8_t *param_buf, u_int32_t param_len, - int minimum_cmd_size, u_int8_t sense_len, - u_int32_t timeout); + void (*cbfcnp)(struct cam_periph *, union ccb *), + uint8_t tag_action, int dbd, uint8_t pc, uint8_t page, + uint8_t *param_buf, uint32_t param_len, + int minimum_cmd_size, uint8_t sense_len, uint32_t timeout); + +void scsi_mode_sense_subpage(struct ccb_scsiio *csio, + uint32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + uint8_t tag_action, int dbd, uint8_t pc, + uint8_t page, uint8_t subpage, + uint8_t *param_buf, uint32_t param_len, + int minimum_cmd_size, uint8_t sense_len, uint32_t timeout); void scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, diff --git a/sys/cam/scsi/scsi_ch.c b/sys/cam/scsi/scsi_ch.c index 59ec6aa5bd3..d3be675c673 100644 --- a/sys/cam/scsi/scsi_ch.c +++ b/sys/cam/scsi/scsi_ch.c @@ -586,7 +586,7 @@ chstart(struct cam_periph *periph, union ccb *start_ccb) /* tag_action */ MSG_SIMPLE_Q_TAG, /* dbd */ (softc->quirks & CH_Q_NO_DBD) ? FALSE : TRUE, - /* page_code */ SMS_PAGE_CTRL_CURRENT, + /* pc */ SMS_PAGE_CTRL_CURRENT, /* page */ CH_ELEMENT_ADDR_ASSIGN_PAGE, /* param_buf */ (u_int8_t *)mode_buffer, /* param_len */ mode_buffer_len, @@ -1587,7 +1587,7 @@ chgetparams(struct cam_periph *periph) /* cbfcnp */ chdone, /* tag_action */ MSG_SIMPLE_Q_TAG, /* dbd */ dbd, - /* page_code */ SMS_PAGE_CTRL_CURRENT, + /* pc */ SMS_PAGE_CTRL_CURRENT, /* page */ CH_ELEMENT_ADDR_ASSIGN_PAGE, /* param_buf */ (u_int8_t *)mode_buffer, /* param_len */ mode_buffer_len, @@ -1650,7 +1650,7 @@ chgetparams(struct cam_periph *periph) /* cbfcnp */ chdone, /* tag_action */ MSG_SIMPLE_Q_TAG, /* dbd */ dbd, - /* page_code */ SMS_PAGE_CTRL_CURRENT, + /* pc */ SMS_PAGE_CTRL_CURRENT, /* page */ CH_DEVICE_CAP_PAGE, /* param_buf */ (u_int8_t *)mode_buffer, /* param_len */ mode_buffer_len, From f788eb2dd63e387af7efbd8728ea29d0667aaadf Mon Sep 17 00:00:00 2001 From: Andrew Rybchenko Date: Sat, 7 Jan 2017 10:51:12 +0000 Subject: [PATCH 26/55] sfxge(4): use SFXGE_LINK_UP() to report link up state Reviewed by: philip Sponsored by: Solarflare Communications, Inc. MFC after: 2 days Differential Revision: https://reviews.freebsd.org/D9059 --- sys/dev/sfxge/sfxge_port.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/dev/sfxge/sfxge_port.c b/sys/dev/sfxge/sfxge_port.c index 2ebc521b572..58793ca54ef 100644 --- a/sys/dev/sfxge/sfxge_port.c +++ b/sys/dev/sfxge/sfxge_port.c @@ -311,8 +311,7 @@ sfxge_mac_link_update(struct sfxge_softc *sc, efx_link_mode_t mode) port->link_mode = mode; /* Push link state update to the OS */ - link_state = (port->link_mode != EFX_LINK_DOWN ? - LINK_STATE_UP : LINK_STATE_DOWN); + link_state = (SFXGE_LINK_UP(sc) ? LINK_STATE_UP : LINK_STATE_DOWN); sc->ifnet->if_baudrate = sfxge_link_baudrate[port->link_mode]; if_link_state_change(sc->ifnet, link_state); } From 1eec14756f9019ab50d687c9a5d7d868f9e80636 Mon Sep 17 00:00:00 2001 From: Andrew Rybchenko Date: Sat, 7 Jan 2017 10:52:02 +0000 Subject: [PATCH 27/55] sfxge(4): treat EFX_LINK_UNKOWN as link down It is safer to consider EFX_LINK_UNKNOWN as link down. link_mode is set to EFX_LINK_UNKNOWN on port stop and fini. Reviewed by: philip Sponsored by: Solarflare Communications, Inc. MFC after: 2 days Differential Revision: https://reviews.freebsd.org/D9060 --- sys/dev/sfxge/sfxge.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/dev/sfxge/sfxge.h b/sys/dev/sfxge/sfxge.h index 667e2e7d8ba..2000652974d 100644 --- a/sys/dev/sfxge/sfxge.h +++ b/sys/dev/sfxge/sfxge.h @@ -326,7 +326,9 @@ struct sfxge_softc { #endif }; -#define SFXGE_LINK_UP(sc) ((sc)->port.link_mode != EFX_LINK_DOWN) +#define SFXGE_LINK_UP(sc) \ + ((sc)->port.link_mode != EFX_LINK_DOWN && \ + (sc)->port.link_mode != EFX_LINK_UNKNOWN) #define SFXGE_RUNNING(sc) ((sc)->ifnet->if_drv_flags & IFF_DRV_RUNNING) #define SFXGE_PARAM(_name) "hw.sfxge." #_name From 6a09b206559ba5d40622944c4f086179d47c0229 Mon Sep 17 00:00:00 2001 From: Andrew Rybchenko Date: Sat, 7 Jan 2017 10:55:38 +0000 Subject: [PATCH 28/55] sfxge(4): allow DMA descs to cross 4k boundary on EF10 Siena has limitation on maximum byte count and 4k boundary crosssing (which is stricter than maximum byte count). EF10 has limitation on maximum byte count only. Reviewed by: philip Sponsored by: Solarflare Communications, Inc. MFC after: 2 days Differential Revision: https://reviews.freebsd.org/D9061 --- sys/dev/sfxge/common/ef10_tx.c | 9 +++++---- sys/dev/sfxge/common/efx.h | 7 +++++++ sys/dev/sfxge/common/efx_tx.c | 16 ++++++++++++---- sys/dev/sfxge/common/hunt_nic.c | 4 ++++ sys/dev/sfxge/common/medford_nic.c | 4 ++++ sys/dev/sfxge/common/siena_nic.c | 4 ++++ sys/dev/sfxge/sfxge_tx.c | 7 +++++-- 7 files changed, 41 insertions(+), 10 deletions(-) diff --git a/sys/dev/sfxge/common/ef10_tx.c b/sys/dev/sfxge/common/ef10_tx.c index 2b0ec5ea9c7..e39b271660f 100755 --- a/sys/dev/sfxge/common/ef10_tx.c +++ b/sys/dev/sfxge/common/ef10_tx.c @@ -438,8 +438,9 @@ ef10_tx_qpost( size_t offset; efx_qword_t qword; - /* Fragments must not span 4k boundaries. */ - EFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= (addr + size)); + /* No limitations on boundary crossing */ + EFSYS_ASSERT(size <= + etp->et_enp->en_nic_cfg.enc_tx_dma_desc_size_max); id = added++ & etp->et_mask; offset = id * sizeof (efx_qword_t); @@ -584,8 +585,8 @@ ef10_tx_qdesc_dma_create( __in boolean_t eop, __out efx_desc_t *edp) { - /* Fragments must not span 4k boundaries. */ - EFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= addr + size); + /* No limitations on boundary crossing */ + EFSYS_ASSERT(size <= etp->et_enp->en_nic_cfg.enc_tx_dma_desc_size_max); EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index, efsys_dma_addr_t, addr, diff --git a/sys/dev/sfxge/common/efx.h b/sys/dev/sfxge/common/efx.h index 53c7a15b3bb..0f91b4fa620 100644 --- a/sys/dev/sfxge/common/efx.h +++ b/sys/dev/sfxge/common/efx.h @@ -1154,6 +1154,13 @@ typedef struct efx_nic_cfg_s { uint32_t enc_rx_batch_max; /* Number of rx descriptors the hardware requires for a push. */ uint32_t enc_rx_push_align; + /* Maximum amount of data in DMA descriptor */ + uint32_t enc_tx_dma_desc_size_max; + /* + * Boundary which DMA descriptor data must not cross or 0 if no + * limitation. + */ + uint32_t enc_tx_dma_desc_boundary; /* * Maximum number of bytes into the packet the TCP header can start for * the hardware to apply TSO packet edits. diff --git a/sys/dev/sfxge/common/efx_tx.c b/sys/dev/sfxge/common/efx_tx.c index 8c06d4f7df0..cb976af2c56 100644 --- a/sys/dev/sfxge/common/efx_tx.c +++ b/sys/dev/sfxge/common/efx_tx.c @@ -748,8 +748,12 @@ siena_tx_qpost( size_t size = ebp->eb_size; efsys_dma_addr_t end = start + size; - /* Fragments must not span 4k boundaries. */ - EFSYS_ASSERT(P2ROUNDUP(start + 1, 4096) >= end); + /* + * Fragments must not span 4k boundaries. + * Here it is a stricter requirement than the maximum length. + */ + EFSYS_ASSERT(P2ROUNDUP(start + 1, + etp->et_enp->en_nic_cfg.enc_tx_dma_desc_boundary) >= end); EFX_TX_DESC(etp, start, size, ebp->eb_eop, added); } @@ -1009,8 +1013,12 @@ siena_tx_qdesc_dma_create( __in boolean_t eop, __out efx_desc_t *edp) { - /* Fragments must not span 4k boundaries. */ - EFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= addr + size); + /* + * Fragments must not span 4k boundaries. + * Here it is a stricter requirement than the maximum length. + */ + EFSYS_ASSERT(P2ROUNDUP(addr + 1, + etp->et_enp->en_nic_cfg.enc_tx_dma_desc_boundary) >= addr + size); EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index, efsys_dma_addr_t, addr, diff --git a/sys/dev/sfxge/common/hunt_nic.c b/sys/dev/sfxge/common/hunt_nic.c index 14d6c1fb7b8..477fa76da05 100644 --- a/sys/dev/sfxge/common/hunt_nic.c +++ b/sys/dev/sfxge/common/hunt_nic.c @@ -304,6 +304,10 @@ hunt_board_cfg( /* Alignment for WPTR updates */ encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN; + encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_DZ_RX_KER_BYTE_CNT); + /* No boundary crossing limits */ + encp->enc_tx_dma_desc_boundary = 0; + /* * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available diff --git a/sys/dev/sfxge/common/medford_nic.c b/sys/dev/sfxge/common/medford_nic.c index ea937e47a10..f883bf7af21 100644 --- a/sys/dev/sfxge/common/medford_nic.c +++ b/sys/dev/sfxge/common/medford_nic.c @@ -301,6 +301,10 @@ medford_board_cfg( /* Alignment for WPTR updates */ encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN; + encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_DZ_RX_KER_BYTE_CNT); + /* No boundary crossing limits */ + encp->enc_tx_dma_desc_boundary = 0; + /* * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available diff --git a/sys/dev/sfxge/common/siena_nic.c b/sys/dev/sfxge/common/siena_nic.c index 331d5a5aec5..39922a7ddcf 100644 --- a/sys/dev/sfxge/common/siena_nic.c +++ b/sys/dev/sfxge/common/siena_nic.c @@ -138,6 +138,10 @@ siena_board_cfg( /* Alignment for WPTR updates */ encp->enc_rx_push_align = 1; + encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT); + /* Fragments must not span 4k boundaries. */ + encp->enc_tx_dma_desc_boundary = 4096; + /* Resource limits */ rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq); if (rc != 0) { diff --git a/sys/dev/sfxge/sfxge_tx.c b/sys/dev/sfxge/sfxge_tx.c index 68a91c4eaa4..4e31aeccbb2 100644 --- a/sys/dev/sfxge/sfxge_tx.c +++ b/sys/dev/sfxge/sfxge_tx.c @@ -1720,6 +1720,7 @@ static int sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index, enum sfxge_txq_type type, unsigned int evq_index) { + const efx_nic_cfg_t *encp = efx_nic_cfg_get(sc->enp); char name[16]; struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); struct sysctl_oid *txq_node; @@ -1750,9 +1751,11 @@ sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index, &txq->buf_base_id); /* Create a DMA tag for packet mappings. */ - if (bus_dma_tag_create(sc->parent_dma_tag, 1, 0x1000, + if (bus_dma_tag_create(sc->parent_dma_tag, 1, + encp->enc_tx_dma_desc_boundary, MIN(0x3FFFFFFFFFFFUL, BUS_SPACE_MAXADDR), BUS_SPACE_MAXADDR, NULL, - NULL, 0x11000, SFXGE_TX_MAPPING_MAX_SEG, 0x1000, 0, NULL, NULL, + NULL, 0x11000, SFXGE_TX_MAPPING_MAX_SEG, + encp->enc_tx_dma_desc_size_max, 0, NULL, NULL, &txq->packet_dma_tag) != 0) { device_printf(sc->dev, "Couldn't allocate txq DMA tag\n"); rc = ENOMEM; From c9eddd660c6b85a8c43e6e96c2e2185947a4556c Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 7 Jan 2017 12:24:45 +0000 Subject: [PATCH 29/55] Define _POSIX_PRIORITY_SCHEDULING as 0. sched_*(2) syscalls might be not available at runtime. Defining this constant as zero directs POSIX-compliant code to call sysconf(3) to detect the feature at runtime, and forces libc sysconf(3) to ask kernel. Noted by: ngie Reviewed by: jilles, ngie Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D9055 --- sys/sys/unistd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/sys/unistd.h b/sys/sys/unistd.h index 24291349185..0875509ad85 100644 --- a/sys/sys/unistd.h +++ b/sys/sys/unistd.h @@ -65,7 +65,7 @@ #define _POSIX_MONOTONIC_CLOCK 200112L #define _POSIX_NO_TRUNC 1 #define _POSIX_PRIORITIZED_IO (-1) -#define _POSIX_PRIORITY_SCHEDULING 200112L +#define _POSIX_PRIORITY_SCHEDULING 0 #define _POSIX_RAW_SOCKETS 200112L #define _POSIX_REALTIME_SIGNALS 200112L #define _POSIX_SEMAPHORES 200112L From d4cd50b494d679d68851a8a02e22cd9a7cd11f7b Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Sat, 7 Jan 2017 14:40:58 +0000 Subject: [PATCH 30/55] libunwind: add noexec stack annotation Reported by: vangyzen Reviewed by: kib MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D9075 --- contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S | 2 ++ contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S | 2 ++ 2 files changed, 4 insertions(+) diff --git a/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S b/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S index 8e37c13036f..34b7429d012 100644 --- a/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S +++ b/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S @@ -527,3 +527,5 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv) ret // jump to ra #endif + + .section .note.GNU-stack,"",@progbits diff --git a/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S b/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S index ebc9d538e7f..cebcd760df1 100644 --- a/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S +++ b/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S @@ -469,3 +469,5 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) /* RISCVTODO */ #endif + + .section .note.GNU-stack,"",@progbits From 00742f6ced54eb680e7cd1dffc7c73e703958ca6 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sat, 7 Jan 2017 15:57:12 +0000 Subject: [PATCH 31/55] Fix the following clang 4.0.0 warning in ngatm's snmp_atm.c: contrib/ngatm/snmp_atm/snmp_atm.c:173:6: error: logical not is only applied to the left hand side of this bitwise operator [-Werror,-Wlogical-not-parentheses] if (!ifmr.ifm_status & IFM_AVALID) { ^ ~ Obviously, the masking needs to be done before the logical not operation. Add parentheses to make it so. MFC after: 3 days --- contrib/ngatm/snmp_atm/snmp_atm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/ngatm/snmp_atm/snmp_atm.c b/contrib/ngatm/snmp_atm/snmp_atm.c index c922c6f3dd7..a2590aeb4dd 100644 --- a/contrib/ngatm/snmp_atm/snmp_atm.c +++ b/contrib/ngatm/snmp_atm/snmp_atm.c @@ -170,7 +170,7 @@ atmif_check_carrier(struct atmif_priv *aif) aif->pub.carrier = ATMIF_CARRIER_UNKNOWN; return; } - if (!ifmr.ifm_status & IFM_AVALID) { + if (!(ifmr.ifm_status & IFM_AVALID)) { aif->pub.carrier = ATMIF_CARRIER_UNKNOWN; return; } From 1c1cb6e0872f5754adac81ab124c646b29d4836f Mon Sep 17 00:00:00 2001 From: Nikolai Lifanov Date: Sat, 7 Jan 2017 15:58:57 +0000 Subject: [PATCH 32/55] Restore priority value for OGIO_KEYMAP PR: 206678 Submitted by: ecturt@gmail.com Reviewed by: cem Approved by: cem, matthew (mentor) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D5095 --- sys/dev/kbd/kbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/kbd/kbd.c b/sys/dev/kbd/kbd.c index 74c5a56f087..24dc9bbe48e 100644 --- a/sys/dev/kbd/kbd.c +++ b/sys/dev/kbd/kbd.c @@ -884,7 +884,7 @@ genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) omapp->key[i].spcl = mapp->key[i].spcl; omapp->key[i].flgs = mapp->key[i].flgs; } - return (0); + break; case PIO_KEYMAP: /* set keyboard translation table */ case OPIO_KEYMAP: /* set keyboard translation table (compat) */ #ifndef KBD_DISABLE_KEYMAP_LOAD From b7c7684ae2754d4ef865bb62ce2c502b0d22ad62 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 7 Jan 2017 16:05:19 +0000 Subject: [PATCH 33/55] Export __cxa_thread_atexit_impl as an alias for __cxa_thread_atexit. libstdc++ before gcc r244057 expected that libc provided __cxa_thread_atexit_impl, and libstdc++ implemented __cxa_thread_atexit, by forwarding the calls to _impl. Mentioned gcc revision checks for __cxa_thread_atexit in libc and does not provide the symbol from libstdc++ if found. This change helps older gcc, in particular, all released versions which implement thread_local, by consolidating the implementation into libc. For that versions, if configured with the current libc, the __cxa_thread_atexit is exported from libstdc++ as a trivial wrapper around libc::__cxa_thread_atexit_impl. The __cxa_thread_atexit implementation is put into separate source file to allow for static linking with older libstdc++.a. gcc bugzilla: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78968 Reported by: Hannes Hauswedell PR: 215709 Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- lib/libc/include/libc_private.h | 2 + lib/libc/stdlib/Makefile.inc | 4 +- lib/libc/stdlib/Symbol.map | 1 + lib/libc/stdlib/cxa_thread_atexit.c | 110 +--------------- lib/libc/stdlib/cxa_thread_atexit_impl.c | 153 +++++++++++++++++++++++ 5 files changed, 164 insertions(+), 106 deletions(-) create mode 100644 lib/libc/stdlib/cxa_thread_atexit_impl.c diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h index 972eb2938ed..74a7e3a841b 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -272,6 +272,8 @@ void _malloc_thread_cleanup(void); * thread is exiting, so its thread-local dtors should be called. */ void __cxa_thread_call_dtors(void); +int __cxa_thread_atexit_hidden(void (*dtor_func)(void *), void *obj, + void *dso_symbol) __hidden; /* * These functions are used by the threading libraries in order to protect diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index 935f3ffb35f..00f90e2f81e 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -5,7 +5,9 @@ .PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/stdlib ${LIBC_SRCTOP}/stdlib MISRCS+=C99_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \ - bsearch.c cxa_thread_atexit.c div.c exit.c getenv.c getopt.c getopt_long.c \ + bsearch.c \ + cxa_thread_atexit.c cxa_thread_atexit_impl.c \ + div.c exit.c getenv.c getopt.c getopt_long.c \ getsubopt.c hcreate.c hcreate_r.c hdestroy_r.c heapsort.c heapsort_b.c \ hsearch_r.c imaxabs.c imaxdiv.c \ insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \ diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map index 6cdc38e8a68..a239a42018d 100644 --- a/lib/libc/stdlib/Symbol.map +++ b/lib/libc/stdlib/Symbol.map @@ -118,6 +118,7 @@ FBSD_1.4 { FBSD_1.5 { __cxa_thread_atexit; + __cxa_thread_atexit_impl; }; FBSDprivate_1.0 { diff --git a/lib/libc/stdlib/cxa_thread_atexit.c b/lib/libc/stdlib/cxa_thread_atexit.c index c9667313670..6f03ef0d323 100644 --- a/lib/libc/stdlib/cxa_thread_atexit.c +++ b/lib/libc/stdlib/cxa_thread_atexit.c @@ -1,7 +1,10 @@ /*- - * Copyright (c) 2016 Mahdi Mokhtari + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -27,114 +30,11 @@ #include __FBSDID("$FreeBSD$"); -#include -#include "namespace.h" -#include -#include -#include -#include -#include -#include -#include "un-namespace.h" #include "libc_private.h" -/* - * C++11 introduces the thread_local scope (like __thread with some - * additions). As a key-feature it should support non-trivial - * destructors, registered with __cxa_thread_atexit() to be executed - * at the thread termination. - * - * The implemention keeps a _Thread_local list of destructors per each - * thread, and calls __cxa_thread_call_dtors() on each thread's exit - * to do cleanup. For a thread calling exit(3), in particular, for - * the initial thread returning from main(), we call - * __cxa_thread_call_dtors() inside exit(). - * - * It could be possible that a dynamically loaded library, use - * thread_local variable but is dlclose()'d before thread exit. The - * destructor of this variable will then try to access the address, - * for calling it but it's unloaded, so it'll crash. We're using - * __elf_phdr_match_addr() to detect and prevent such cases and so - * prevent the crash. - */ - -#define CXA_DTORS_ITERATIONS 4 - -struct cxa_thread_dtor { - void *obj; - void (*func)(void *); - void *dso; - LIST_ENTRY(cxa_thread_dtor) entry; -}; -static _Thread_local LIST_HEAD(dtor_list, cxa_thread_dtor) dtors = - LIST_HEAD_INITIALIZER(dtors); - int __cxa_thread_atexit(void (*dtor_func)(void *), void *obj, void *dso_symbol) { - struct cxa_thread_dtor *new_dtor; - new_dtor = malloc(sizeof(*new_dtor)); - if (new_dtor == NULL) { - errno = ENOMEM; /* forcibly override malloc(3) error */ - return (-1); - } - - new_dtor->obj = obj; - new_dtor->func = dtor_func; - new_dtor->dso = dso_symbol; - LIST_INSERT_HEAD(&dtors, new_dtor, entry); - return (0); -} - -static void -walk_cb_call(struct cxa_thread_dtor *dtor) -{ - struct dl_phdr_info phdr_info; - - if (_rtld_addr_phdr(dtor->dso, &phdr_info) && - __elf_phdr_match_addr(&phdr_info, dtor->func)) - dtor->func(dtor->obj); - else - fprintf(stderr, "__cxa_thread_call_dtors: dtr %p from " - "unloaded dso, skipping\n", (void *)(dtor->func)); -} - -static void -walk_cb_nocall(struct cxa_thread_dtor *dtor __unused) -{ -} - -static void -cxa_thread_walk(void (*cb)(struct cxa_thread_dtor *)) -{ - struct cxa_thread_dtor *dtor, *tdtor; - - LIST_FOREACH_SAFE(dtor, &dtors, entry, tdtor) { - LIST_REMOVE(dtor, entry); - cb(dtor); - free(dtor); - } -} - -/* - * This is the callback function we use to call destructors, once for - * each thread. It is called in exit(3) in libc/stdlib/exit.c and - * before exit_thread() in libthr/thread/thr_exit.c. - */ -void -__cxa_thread_call_dtors(void) -{ - int i; - - for (i = 0; i < CXA_DTORS_ITERATIONS && !LIST_EMPTY(&dtors); i++) - cxa_thread_walk(walk_cb_call); - - if (!LIST_EMPTY(&dtors)) { - fprintf(stderr, "Thread %p is exiting with more " - "thread-specific dtors created after %d iterations " - "of destructor calls\n", - _pthread_self(), i); - cxa_thread_walk(walk_cb_nocall); - } + return (__cxa_thread_atexit_hidden(dtor_func, obj, dso_symbol)); } diff --git a/lib/libc/stdlib/cxa_thread_atexit_impl.c b/lib/libc/stdlib/cxa_thread_atexit_impl.c new file mode 100644 index 00000000000..0f0a7a314fa --- /dev/null +++ b/lib/libc/stdlib/cxa_thread_atexit_impl.c @@ -0,0 +1,153 @@ +/*- + * Copyright (c) 2016 Mahdi Mokhtari + * Copyright (c) 2016, 2017 The FreeBSD Foundation + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" + +/* + * C++11 introduces the thread_local scope (like __thread with some + * additions). As a key-feature it should support non-trivial + * destructors, registered with __cxa_thread_atexit() to be executed + * at the thread termination. + * + * The implemention keeps a _Thread_local list of destructors per each + * thread, and calls __cxa_thread_call_dtors() on each thread's exit + * to do cleanup. For a thread calling exit(3), in particular, for + * the initial thread returning from main(), we call + * __cxa_thread_call_dtors() inside exit(). + * + * It could be possible that a dynamically loaded library, use + * thread_local variable but is dlclose()'d before thread exit. The + * destructor of this variable will then try to access the address, + * for calling it but it's unloaded, so it'll crash. We're using + * __elf_phdr_match_addr() to detect and prevent such cases and so + * prevent the crash. + */ + +#define CXA_DTORS_ITERATIONS 4 + +struct cxa_thread_dtor { + void *obj; + void (*func)(void *); + void *dso; + LIST_ENTRY(cxa_thread_dtor) entry; +}; +static _Thread_local LIST_HEAD(dtor_list, cxa_thread_dtor) dtors = + LIST_HEAD_INITIALIZER(dtors); + +int +__cxa_thread_atexit_impl(void (*dtor_func)(void *), void *obj, + void *dso_symbol) +{ + + return (__cxa_thread_atexit_hidden(dtor_func, obj, dso_symbol)); +} + +int +__cxa_thread_atexit_hidden(void (*dtor_func)(void *), void *obj, + void *dso_symbol) +{ + struct cxa_thread_dtor *new_dtor; + + new_dtor = malloc(sizeof(*new_dtor)); + if (new_dtor == NULL) { + errno = ENOMEM; /* forcibly override malloc(3) error */ + return (-1); + } + + new_dtor->obj = obj; + new_dtor->func = dtor_func; + new_dtor->dso = dso_symbol; + LIST_INSERT_HEAD(&dtors, new_dtor, entry); + return (0); +} + +static void +walk_cb_call(struct cxa_thread_dtor *dtor) +{ + struct dl_phdr_info phdr_info; + + if (_rtld_addr_phdr(dtor->dso, &phdr_info) && + __elf_phdr_match_addr(&phdr_info, dtor->func)) + dtor->func(dtor->obj); + else + fprintf(stderr, "__cxa_thread_call_dtors: dtr %p from " + "unloaded dso, skipping\n", (void *)(dtor->func)); +} + +static void +walk_cb_nocall(struct cxa_thread_dtor *dtor __unused) +{ +} + +static void +cxa_thread_walk(void (*cb)(struct cxa_thread_dtor *)) +{ + struct cxa_thread_dtor *dtor, *tdtor; + + LIST_FOREACH_SAFE(dtor, &dtors, entry, tdtor) { + LIST_REMOVE(dtor, entry); + cb(dtor); + free(dtor); + } +} + +/* + * This is the callback function we use to call destructors, once for + * each thread. It is called in exit(3) in libc/stdlib/exit.c and + * before exit_thread() in libthr/thread/thr_exit.c. + */ +void +__cxa_thread_call_dtors(void) +{ + int i; + + for (i = 0; i < CXA_DTORS_ITERATIONS && !LIST_EMPTY(&dtors); i++) + cxa_thread_walk(walk_cb_call); + + if (!LIST_EMPTY(&dtors)) { + fprintf(stderr, "Thread %p is exiting with more " + "thread-specific dtors created after %d iterations " + "of destructor calls\n", + _pthread_self(), i); + cxa_thread_walk(walk_cb_nocall); + } +} From 2c7c36f99309aa88c808694734fb1dd52c88e119 Mon Sep 17 00:00:00 2001 From: Allan Jude Date: Sat, 7 Jan 2017 17:37:39 +0000 Subject: [PATCH 34/55] style(9) fix Submitted by: jmallett --- usr.bin/users/users.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/usr.bin/users/users.cc b/usr.bin/users/users.cc index 2d47786d46a..9be354d6635 100644 --- a/usr.bin/users/users.cc +++ b/usr.bin/users/users.cc @@ -27,10 +27,11 @@ * SUCH DAMAGE. */ -#include #include __FBSDID("$FreeBSD$"); +#include + #include #include #include From cd03a7b7cedd60d7e0a014dbfb1e00aea4fb2a6e Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Sat, 7 Jan 2017 19:26:25 +0000 Subject: [PATCH 35/55] libmd: add noexec stack annotation in skein_block_asm.s MFC after: 1 week Sponsored by: The FreeBSD Foundation --- sys/crypto/skein/amd64/skein_block_asm.s | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/crypto/skein/amd64/skein_block_asm.s b/sys/crypto/skein/amd64/skein_block_asm.s index 84cb47005e4..b1458e5794b 100644 --- a/sys/crypto/skein/amd64/skein_block_asm.s +++ b/sys/crypto/skein/amd64/skein_block_asm.s @@ -1326,4 +1326,6 @@ _SP_OFFS_ = _SP_OFFS_-8 ret .endif #---------------------------------------------------------------- + .section .note.GNU-stack,"",@progbits + .end From 40d3e536c58398f9df5cde4a62000c0529ba528e Mon Sep 17 00:00:00 2001 From: Allan Jude Date: Sat, 7 Jan 2017 19:43:40 +0000 Subject: [PATCH 36/55] Add skein(3) front ends to the md5 manpage Reported by: emaste --- sbin/md5/md5.1 | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/sbin/md5/md5.1 b/sbin/md5/md5.1 index 6fa039377b4..f877c1e1ace 100644 --- a/sbin/md5/md5.1 +++ b/sbin/md5/md5.1 @@ -1,9 +1,10 @@ .\" $FreeBSD$ -.Dd April 22, 2016 +.Dd January 7, 2017 .Dt MD5 1 .Os .Sh NAME -.Nm md5 , sha1 , sha256 , sha384 , sha512, sha512t256, rmd160 +.Nm md5 , sha1 , sha256 , sha384 , sha512 , sha512t256 , rmd160 , +.Nm skein256 , skein512 , skein1024 .Nd calculate a message-digest fingerprint (checksum) for a file .Sh SYNOPSIS .Nm md5 @@ -41,11 +42,27 @@ .Op Fl c Ar string .Op Fl s Ar string .Op Ar +.Nm skein256 +.Op Fl pqrtx +.Op Fl c Ar string +.Op Fl s Ar string +.Op Ar +.Nm skein512 +.Op Fl pqrtx +.Op Fl c Ar string +.Op Fl s Ar string +.Op Ar +.Nm skein1024 +.Op Fl pqrtx +.Op Fl c Ar string +.Op Fl s Ar string +.Op Ar .Sh DESCRIPTION The -.Nm md5 , sha1 , sha256 , sha384 , sha512, sha512t256 +.Nm md5 , sha1 , sha256 , sha384 , sha512, sha512t256, rmd160, +.Nm skein256, skein512, and -.Nm rmd160 +.Nm skein1024 utilities take as input a message of arbitrary length and produce as output a .Dq fingerprint @@ -56,9 +73,9 @@ It is conjectured that it is computationally infeasible to produce two messages having the same message digest, or to produce any message having a given prespecified target message digest. The -.Tn MD5 , SHA-1 , SHA-256 , SHA-384 , SHA-512 +.Tn MD5 , SHA-1 , SHA-256 , SHA-384 , SHA-512, RIPEMD-160, and -.Tn RIPEMD-160 +.Tn SKEIN algorithms are intended for digital signature applications, where a large file must be .Dq compressed @@ -128,9 +145,10 @@ Run a built-in test script. .El .Sh EXIT STATUS The -.Nm md5 , sha1 , sha256 , sha512, sha512t256 +.Nm md5 , sha1 , sha256 , sha512, sha512t256, rmd160, +.Nm skein256, skein512, and -.Nm rmd160 +.Nm skein1024 utilities exit 0 on success, 1 if at least one of the input files could not be read, and 2 if at least one file does not have the same hash as the @@ -143,7 +161,8 @@ option. .Xr sha 3 , .Xr sha256 3 , .Xr sha384 3 , -.Xr sha512 3 +.Xr sha512 3 , +.Xr skein 3 .Rs .%A R. Rivest .%T The MD5 Message-Digest Algorithm From d663d5ca23d3a0af921d424b6568b6a892bb4da0 Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Sat, 7 Jan 2017 20:26:19 +0000 Subject: [PATCH 37/55] cxgbe/t4_tom: Fix tid accounting. An offloaded IPv6 connection uses 2 tids, not 1, in the hardware. MFC after: 3 days Sponsored by: Chelsio Communications --- sys/dev/cxgbe/tom/t4_connect.c | 2 +- sys/dev/cxgbe/tom/t4_listen.c | 14 ++++++++++---- sys/dev/cxgbe/tom/t4_tom.c | 10 +++++----- sys/dev/cxgbe/tom/t4_tom.h | 4 ++-- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/sys/dev/cxgbe/tom/t4_connect.c b/sys/dev/cxgbe/tom/t4_connect.c index 4db64102c31..f2e4ad456ef 100644 --- a/sys/dev/cxgbe/tom/t4_connect.c +++ b/sys/dev/cxgbe/tom/t4_connect.c @@ -128,7 +128,7 @@ do_act_establish(struct sge_iq *iq, const struct rss_header *rss, INP_WLOCK(inp); toep->tid = tid; - insert_tid(sc, tid, toep); + insert_tid(sc, tid, toep, inp->inp_vflag & INP_IPV6 ? 2 : 1); if (inp->inp_flags & INP_DROPPED) { /* socket closed by the kernel before hw told us it connected */ diff --git a/sys/dev/cxgbe/tom/t4_listen.c b/sys/dev/cxgbe/tom/t4_listen.c index 472c9a5a9e4..bdb93ac9a42 100644 --- a/sys/dev/cxgbe/tom/t4_listen.c +++ b/sys/dev/cxgbe/tom/t4_listen.c @@ -824,14 +824,16 @@ done_with_synqe(struct adapter *sc, struct synq_entry *synqe) struct inpcb *inp = lctx->inp; struct vi_info *vi = synqe->syn->m_pkthdr.rcvif->if_softc; struct l2t_entry *e = &sc->l2t->l2tab[synqe->l2e_idx]; + int ntids; INP_WLOCK_ASSERT(inp); + ntids = inp->inp_vflag & INP_IPV6 ? 2 : 1; TAILQ_REMOVE(&lctx->synq, synqe, link); inp = release_lctx(sc, lctx); if (inp) INP_WUNLOCK(inp); - remove_tid(sc, synqe->tid); + remove_tid(sc, synqe->tid, ntids); release_tid(sc, synqe->tid, &sc->sge.ctrlq[vi->pi->port_id]); t4_l2t_release(e); release_synqe(synqe); /* removed from synq list */ @@ -1180,7 +1182,7 @@ do_pass_accept_req(struct sge_iq *iq, const struct rss_header *rss, struct l2t_entry *e = NULL; int rscale, mtu_idx, rx_credits, rxqid, ulp_mode; struct synq_entry *synqe = NULL; - int reject_reason, v; + int reject_reason, v, ntids; uint16_t vid; #ifdef INVARIANTS unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl))); @@ -1254,6 +1256,8 @@ found: */ if (!in6_ifhasaddr(ifp, &inc.inc6_laddr)) REJECT_PASS_ACCEPT(); + + ntids = 2; } else { /* Don't offload if the ifcap isn't enabled */ @@ -1266,6 +1270,8 @@ found: */ if (!in_ifhasaddr(ifp, inc.inc_laddr)) REJECT_PASS_ACCEPT(); + + ntids = 1; } e = get_l2te_for_nexthop(pi, ifp, &inc); @@ -1343,7 +1349,7 @@ found: synqe->rcv_bufsize = rx_credits; atomic_store_rel_ptr(&synqe->wr, (uintptr_t)wr); - insert_tid(sc, tid, synqe); + insert_tid(sc, tid, synqe, ntids); TAILQ_INSERT_TAIL(&lctx->synq, synqe, link); hold_synqe(synqe); /* hold for the duration it's in the synq */ hold_lctx(lctx); /* A synqe on the list has a ref on its lctx */ @@ -1372,7 +1378,7 @@ found: if (m) m->m_pkthdr.rcvif = hw_ifp; - remove_tid(sc, synqe->tid); + remove_tid(sc, synqe->tid, ntids); free(wr, M_CXGBE); /* Yank the synqe out of the lctx synq. */ diff --git a/sys/dev/cxgbe/tom/t4_tom.c b/sys/dev/cxgbe/tom/t4_tom.c index 3df2313fa99..5445e265f7d 100644 --- a/sys/dev/cxgbe/tom/t4_tom.c +++ b/sys/dev/cxgbe/tom/t4_tom.c @@ -307,7 +307,7 @@ release_offload_resources(struct toepcb *toep) t4_l2t_release(toep->l2te); if (tid >= 0) { - remove_tid(sc, tid); + remove_tid(sc, tid, toep->ce ? 2 : 1); release_tid(sc, tid, toep->ctrlq); } @@ -420,12 +420,12 @@ final_cpl_received(struct toepcb *toep) } void -insert_tid(struct adapter *sc, int tid, void *ctx) +insert_tid(struct adapter *sc, int tid, void *ctx, int ntids) { struct tid_info *t = &sc->tids; t->tid_tab[tid] = ctx; - atomic_add_int(&t->tids_in_use, 1); + atomic_add_int(&t->tids_in_use, ntids); } void * @@ -445,12 +445,12 @@ update_tid(struct adapter *sc, int tid, void *ctx) } void -remove_tid(struct adapter *sc, int tid) +remove_tid(struct adapter *sc, int tid, int ntids) { struct tid_info *t = &sc->tids; t->tid_tab[tid] = NULL; - atomic_subtract_int(&t->tids_in_use, 1); + atomic_subtract_int(&t->tids_in_use, ntids); } void diff --git a/sys/dev/cxgbe/tom/t4_tom.h b/sys/dev/cxgbe/tom/t4_tom.h index 48223b0d95d..c0a5288e9ad 100644 --- a/sys/dev/cxgbe/tom/t4_tom.h +++ b/sys/dev/cxgbe/tom/t4_tom.h @@ -306,10 +306,10 @@ void free_toepcb(struct toepcb *); void offload_socket(struct socket *, struct toepcb *); void undo_offload_socket(struct socket *); void final_cpl_received(struct toepcb *); -void insert_tid(struct adapter *, int, void *); +void insert_tid(struct adapter *, int, void *, int); void *lookup_tid(struct adapter *, int); void update_tid(struct adapter *, int, void *); -void remove_tid(struct adapter *, int); +void remove_tid(struct adapter *, int, int); void release_tid(struct adapter *, int, struct sge_wrq *); int find_best_mtu_idx(struct adapter *, struct in_conninfo *, int); u_long select_rcv_wnd(struct socket *); From ee2c73e559e04e3e2b7c62c0ae86712c65ca8310 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sat, 7 Jan 2017 22:55:23 +0000 Subject: [PATCH 38/55] Only write to *active once, even when GPIO_ACTIVE_LOW is set. --- sys/dev/gpio/ofw_gpiobus.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/dev/gpio/ofw_gpiobus.c b/sys/dev/gpio/ofw_gpiobus.c index f8fcbea9507..1f98d7cad2a 100644 --- a/sys/dev/gpio/ofw_gpiobus.c +++ b/sys/dev/gpio/ofw_gpiobus.c @@ -178,9 +178,10 @@ gpio_pin_is_active(gpio_pin_t pin, bool *active) return (rv); } - *active = tmp != 0; if (pin->flags & GPIO_ACTIVE_LOW) - *active = !(*active); + *active = tmp == 0; + else + *active = tmp != 0; return (0); } From 0922cf8d3230e21da0a9374115c3871c1bf14eb4 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 7 Jan 2017 23:42:17 +0000 Subject: [PATCH 39/55] remove network mask calculation for Classful network Nowadays it's not necessary to compute network mask from the IP address and compare to given by DHCP. Submitted by: kczekirda Reviewed by: glebius, bapt MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D8740 --- lib/libstand/bootp.c | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/lib/libstand/bootp.c b/lib/libstand/bootp.c index 0c48748ddd1..0bd37b17780 100644 --- a/lib/libstand/bootp.c +++ b/lib/libstand/bootp.c @@ -62,8 +62,6 @@ __FBSDID("$FreeBSD$"); struct in_addr servip; -static n_long nmask, smask; - static time_t bot; static char vm_rfc1048[4] = VM_RFC1048; @@ -223,30 +221,19 @@ bootp(sock, flag) bcopy(rbuf.rbootp.bp_file, bootfile, sizeof(bootfile)); bootfile[sizeof(bootfile) - 1] = '\0'; - if (IN_CLASSA(ntohl(myip.s_addr))) - nmask = htonl(IN_CLASSA_NET); - else if (IN_CLASSB(ntohl(myip.s_addr))) - nmask = htonl(IN_CLASSB_NET); - else - nmask = htonl(IN_CLASSC_NET); -#ifdef BOOTP_DEBUG - if (debug) - printf("'native netmask' is %s\n", intoa(nmask)); -#endif - - /* Check subnet mask against net mask; toss if bogus */ - if ((nmask & smask) != nmask) { + if (!netmask) { + if (IN_CLASSA(ntohl(myip.s_addr))) + netmask = htonl(IN_CLASSA_NET); + else if (IN_CLASSB(ntohl(myip.s_addr))) + netmask = htonl(IN_CLASSB_NET); + else + netmask = htonl(IN_CLASSC_NET); #ifdef BOOTP_DEBUG if (debug) - printf("subnet mask (%s) bad\n", intoa(smask)); + printf("'native netmask' is %s\n", intoa(netmask)); #endif - smask = 0; } - /* Get subnet (or natural net) mask */ - netmask = nmask; - if (smask) - netmask = smask; #ifdef BOOTP_DEBUG if (debug) printf("mask: %s\n", intoa(netmask)); @@ -385,7 +372,7 @@ vend_rfc1048(cp, len) break; if (tag == TAG_SUBNET_MASK) { - bcopy(cp, &smask, sizeof(smask)); + bcopy(cp, &netmask, sizeof(netmask)); } if (tag == TAG_GATEWAY) { bcopy(cp, &gateip.s_addr, sizeof(gateip.s_addr)); @@ -445,7 +432,7 @@ vend_cmu(cp) vp = (struct cmu_vend *)cp; if (vp->v_smask.s_addr != 0) { - smask = vp->v_smask.s_addr; + netmask = vp->v_smask.s_addr; } if (vp->v_dgate.s_addr != 0) { gateip = vp->v_dgate; From 6e37fb2b62bc25bc70d165512251dce67336226b Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sun, 8 Jan 2017 02:32:53 +0000 Subject: [PATCH 40/55] Add a new sdhci interface method, get_card_present(). Many embedded SoC controllers that are (more or less) sdhci-compatible don't implement card detect, and the related values in the PRESENT_STATE register aren't useful. A bridge driver can now implement get_card_present() to read a gpio pin or whatever else is necessary for that system. The default implementation reads the CARD_PRESENT bit from the PRESENT_STATE register, so existing drivers will keep working (or keep not-fully-working, since many drivers right now can't detect card insert/remove). --- sys/dev/sdhci/sdhci.c | 16 +++++++++++----- sys/dev/sdhci/sdhci.h | 1 + sys/dev/sdhci/sdhci_if.m | 6 ++++++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c index 9ea85adba55..07828a3690c 100644 --- a/sys/dev/sdhci/sdhci.c +++ b/sys/dev/sdhci/sdhci.c @@ -164,8 +164,7 @@ sdhci_reset(struct sdhci_slot *slot, uint8_t mask) int timeout; if (slot->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { - if (!(RD4(slot, SDHCI_PRESENT_STATE) & - SDHCI_CARD_PRESENT)) + if (!SDHCI_GET_CARD_PRESENT(slot->bus, slot)) return; } @@ -489,7 +488,7 @@ sdhci_card_task(void *arg, int pending) struct sdhci_slot *slot = arg; SDHCI_LOCK(slot); - if (RD4(slot, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT) { + if (SDHCI_GET_CARD_PRESENT(slot->bus, slot)) { if (slot->dev == NULL) { /* If card is present - attach mmc bus. */ slot->dev = device_add_child(slot->bus, "mmc", -1); @@ -718,6 +717,13 @@ sdhci_generic_min_freq(device_t brdev, struct sdhci_slot *slot) return (slot->max_clk / SDHCI_200_MAX_DIVIDER); } +bool +sdhci_generic_get_card_present(device_t brdev, struct sdhci_slot *slot) +{ + + return (RD4(slot, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT); +} + int sdhci_generic_update_ios(device_t brdev, device_t reqdev) { @@ -834,7 +840,7 @@ sdhci_start_command(struct sdhci_slot *slot, struct mmc_command *cmd) state = RD4(slot, SDHCI_PRESENT_STATE); /* Do not issue command if there is no card, clock or power. * Controller will not detect timeout without clock active. */ - if ((state & SDHCI_CARD_PRESENT) == 0 || + if (!SDHCI_GET_CARD_PRESENT(slot->bus, slot) || slot->power == 0 || slot->clock == 0) { cmd->error = MMC_ERR_FAILED; @@ -1323,7 +1329,7 @@ sdhci_generic_intr(struct sdhci_slot *slot) /* Handle card presence interrupts. */ if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) { - present = RD4(slot, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT; + present = SDHCI_GET_CARD_PRESENT(slot->bus, slot); slot->intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE); slot->intmask |= present ? SDHCI_INT_CARD_REMOVE : diff --git a/sys/dev/sdhci/sdhci.h b/sys/dev/sdhci/sdhci.h index 2638b4ff975..ecee9ed3d94 100644 --- a/sys/dev/sdhci/sdhci.h +++ b/sys/dev/sdhci/sdhci.h @@ -322,5 +322,6 @@ int sdhci_generic_acquire_host(device_t brdev, device_t reqdev); int sdhci_generic_release_host(device_t brdev, device_t reqdev); void sdhci_generic_intr(struct sdhci_slot *slot); uint32_t sdhci_generic_min_freq(device_t brdev, struct sdhci_slot *slot); +bool sdhci_generic_get_card_present(device_t brdev, struct sdhci_slot *slot); #endif /* __SDHCI_H__ */ diff --git a/sys/dev/sdhci/sdhci_if.m b/sys/dev/sdhci/sdhci_if.m index b33cdcf0c8a..da02d31bfca 100644 --- a/sys/dev/sdhci/sdhci_if.m +++ b/sys/dev/sdhci/sdhci_if.m @@ -152,3 +152,9 @@ METHOD uint32_t min_freq { device_t brdev; struct sdhci_slot *slot; } DEFAULT sdhci_generic_min_freq; + +METHOD bool get_card_present { + device_t brdev; + struct sdhci_slot *slot; +} DEFAULT sdhci_generic_get_card_present; + From cb4319e3b4ad5e292fdba4a4dbdfa9853debd06e Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 8 Jan 2017 04:23:05 +0000 Subject: [PATCH 41/55] [net80211] add a "is VHT available" macro. We have run out of config bits, sigh, so until I expand the ic config bits, just use this macro as a substitute. --- sys/net80211/ieee80211_var.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index bd13997a57f..1b73d392962 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -87,6 +87,14 @@ /* XXX TODO: cap this at 1, in case hz is not 1000 */ #define IEEE80211_TU_TO_TICKS(x)(((uint64_t)(x) * 1024 * hz) / (1000 * 1000)) +/* + * Technically, vhtflags may be 0 /and/ 11ac is enabled. + * At some point ic should just grow a flag somewhere that + * says that VHT is supported - and then this macro can be + * changed. + */ +#define IEEE80211_CONF_VHT(ic) ((ic)->ic_vhtcaps != 0) + /* * 802.11 control state is split into a common portion that maps * 1-1 to a physical device and one or more "Virtual AP's" (VAP) From b6fec8d603916736a1c5c4ebe573d36981551380 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 8 Jan 2017 04:25:41 +0000 Subject: [PATCH 42/55] [net80211] Add initial VHT support routines. This is a skeleton set based on ieee80211_ht.c. It implements some IE parsing, some basic unfinished negotiation, and channel promotion/demotion. However, by itself it's not enough to do VHT - notably, the actual channel promotion for STA mode at least is done in ieee80211_ht.c as part of htinfo_update_chw(). I was .. quite amused when I found that out. I'm checking this in so others can see progress rather than one huge commit when VHT is "done" (which will likely be quite a while.) --- sys/net80211/ieee80211_vht.c | 469 +++++++++++++++++++++++++++++++++++ sys/net80211/ieee80211_vht.h | 63 +++++ 2 files changed, 532 insertions(+) create mode 100644 sys/net80211/ieee80211_vht.c create mode 100644 sys/net80211/ieee80211_vht.h diff --git a/sys/net80211/ieee80211_vht.c b/sys/net80211/ieee80211_vht.c new file mode 100644 index 00000000000..3cc5f165ed5 --- /dev/null +++ b/sys/net80211/ieee80211_vht.c @@ -0,0 +1,469 @@ +/*- + * Copyright (c) 2017 Adrian Chadd + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#ifdef __FreeBSD__ +__FBSDID("$FreeBSD$"); +#endif + +/* + * IEEE 802.11ac-2013 protocol support. + */ + +#include "opt_inet.h" +#include "opt_wlan.h" + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +/* define here, used throughout file */ +#define MS(_v, _f) (((_v) & _f) >> _f##_S) +#define SM(_v, _f) (((_v) << _f##_S) & _f) + +#define ADDSHORT(frm, v) do { \ + frm[0] = (v) & 0xff; \ + frm[1] = (v) >> 8; \ + frm += 2; \ +} while (0) +#define ADDWORD(frm, v) do { \ + frm[0] = (v) & 0xff; \ + frm[1] = ((v) >> 8) & 0xff; \ + frm[2] = ((v) >> 16) & 0xff; \ + frm[3] = ((v) >> 24) & 0xff; \ + frm += 4; \ +} while (0) + +/* + * XXX TODO: handle WLAN_ACTION_VHT_OPMODE_NOTIF + * + * Look at mac80211/vht.c:ieee80211_vht_handle_opmode() for further details. + */ + +static void +ieee80211_vht_init(void) +{ +} + +SYSINIT(wlan_vht, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_vht_init, NULL); + +void +ieee80211_vht_attach(struct ieee80211com *ic) +{ +} + +void +ieee80211_vht_detach(struct ieee80211com *ic) +{ +} + +void +ieee80211_vht_vattach(struct ieee80211vap *vap) +{ + struct ieee80211com *ic = vap->iv_ic; + + if (! IEEE80211_CONF_VHT(ic)) + return; + + vap->iv_vhtcaps = ic->ic_vhtcaps; + vap->iv_vhtextcaps = ic->ic_vhtextcaps; + + /* XXX assume VHT80 support; should really check vhtcaps */ + vap->iv_flags_vht = + IEEE80211_FVHT_VHT + | IEEE80211_FVHT_USEVHT40 + | IEEE80211_FVHT_USEVHT80; + /* XXX TODO: enable VHT80+80, VHT160 capabilities */ + + memcpy(&vap->iv_vht_mcsinfo, &ic->ic_vht_mcsinfo, + sizeof(struct ieee80211_vht_mcs_info)); +} + +void +ieee80211_vht_vdetach(struct ieee80211vap *vap) +{ +} + +#if 0 +static void +vht_announce(struct ieee80211com *ic, enum ieee80211_phymode mode) +{ +} +#endif + +static int +vht_mcs_to_num(int m) +{ + + switch (m) { + case IEEE80211_VHT_MCS_SUPPORT_0_7: + return (7); + case IEEE80211_VHT_MCS_SUPPORT_0_8: + return (8); + case IEEE80211_VHT_MCS_SUPPORT_0_9: + return (9); + default: + return (0); + } +} + +void +ieee80211_vht_announce(struct ieee80211com *ic) +{ + int i, tx, rx; + + if (! IEEE80211_CONF_VHT(ic)) + return; + + /* Channel width */ + ic_printf(ic, "[VHT] Channel Widths: 20MHz, 40MHz, 80MHz"); + if (ic->ic_vhtcaps & IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) + printf(" 80+80MHz"); + if (ic->ic_vhtcaps & IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160MHZ) + printf(" 160MHz"); + printf("\n"); + + /* Features */ + ic_printf(ic, "[VHT] Features: %b\n", ic->ic_vhtcaps, + IEEE80211_VHTCAP_BITS); + + /* For now, just 5GHz VHT. Worry about 2GHz VHT later */ + for (i = 0; i < 7; i++) { + /* Each stream is 2 bits */ + tx = (ic->ic_vht_mcsinfo.tx_mcs_map >> (2*i)) & 0x3; + rx = (ic->ic_vht_mcsinfo.rx_mcs_map >> (2*i)) & 0x3; + if (tx == 3 && rx == 3) + continue; + ic_printf(ic, "[VHT] NSS %d: TX MCS 0..%d, RX MCS 0..%d\n", + i + 1, + vht_mcs_to_num(tx), + vht_mcs_to_num(rx)); + } +} + +void +ieee80211_vht_node_init(struct ieee80211_node *ni) +{ + + IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, + "%s: called", __func__); + ni->ni_flags |= IEEE80211_NODE_VHT; +} + +void +ieee80211_vht_node_cleanup(struct ieee80211_node *ni) +{ + + IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, + "%s: called", __func__); + ni->ni_flags &= ~IEEE80211_NODE_VHT; + ni->ni_vhtcap = 0; + bzero(&ni->ni_vht_mcsinfo, sizeof(struct ieee80211_vht_mcs_info)); +} + +/* + * Parse an 802.11ac VHT operation IE. + */ +void +ieee80211_parse_vhtopmode(struct ieee80211_node *ni, const uint8_t *ie) +{ + /* vht operation */ + ni->ni_vht_chanwidth = ie[2]; + ni->ni_vht_chan1 = ie[3]; + ni->ni_vht_chan2 = ie[4]; + ni->ni_vht_basicmcs = le16dec(ie + 5); + +#if 0 + printf("%s: chan1=%d, chan2=%d, chanwidth=%d, basicmcs=0x%04x\n", + __func__, + ni->ni_vht_chan1, + ni->ni_vht_chan2, + ni->ni_vht_chanwidth, + ni->ni_vht_basicmcs); +#endif +} + +/* + * Parse an 802.11ac VHT capability IE. + */ +void +ieee80211_parse_vhtcap(struct ieee80211_node *ni, const uint8_t *ie) +{ + + /* vht capability */ + ni->ni_vhtcap = le32dec(ie + 2); + + /* suppmcs */ + ni->ni_vht_mcsinfo.rx_mcs_map = le16dec(ie + 6); + ni->ni_vht_mcsinfo.rx_highest = le16dec(ie + 8); + ni->ni_vht_mcsinfo.tx_mcs_map = le16dec(ie + 10); + ni->ni_vht_mcsinfo.tx_highest = le16dec(ie + 12); +} + +int +ieee80211_vht_updateparams(struct ieee80211_node *ni, + const uint8_t *vhtcap_ie, + const uint8_t *vhtop_ie) +{ + + //printf("%s: called\n", __func__); + + ieee80211_parse_vhtcap(ni, vhtcap_ie); + ieee80211_parse_vhtopmode(ni, vhtop_ie); + return (0); +} + +void +ieee80211_setup_vht_rates(struct ieee80211_node *ni, + const uint8_t *vhtcap_ie, + const uint8_t *vhtop_ie) +{ + + //printf("%s: called\n", __func__); + /* XXX TODO */ +} + +void +ieee80211_vht_timeout(struct ieee80211com *ic) +{ +} + +void +ieee80211_vht_node_join(struct ieee80211_node *ni) +{ + + IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, + "%s: called", __func__); +} + +void +ieee80211_vht_node_leave(struct ieee80211_node *ni) +{ + + IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, + "%s: called", __func__); +} + +uint8_t * +ieee80211_add_vhtcap(uint8_t *frm, struct ieee80211_node *ni) +{ + uint32_t cap; + + memset(frm, '\0', sizeof(struct ieee80211_ie_vhtcap)); + + frm[0] = IEEE80211_ELEMID_VHT_CAP; + frm[1] = sizeof(struct ieee80211_ie_vhtcap) - 2; + frm += 2; + + /* + * For now, don't do any configuration. + * Just populate the node configuration. + * We can worry about making it configurable later. + */ + + cap = ni->ni_vhtcap; + + /* + * XXX TODO: any capability changes required by + * configuration. + */ + + /* 32-bit VHT capability */ + ADDWORD(frm, cap); + + /* suppmcs */ + ADDSHORT(frm, ni->ni_vht_mcsinfo.rx_mcs_map); + ADDSHORT(frm, ni->ni_vht_mcsinfo.rx_highest); + ADDSHORT(frm, ni->ni_vht_mcsinfo.tx_mcs_map); + ADDSHORT(frm, ni->ni_vht_mcsinfo.tx_highest); + + return (frm); +} + +static uint8_t +ieee80211_vht_get_chwidth_ie(struct ieee80211_channel *c) +{ + + /* + * XXX TODO: look at the node configuration as + * well? + */ + + if (IEEE80211_IS_CHAN_VHT160(c)) { + return IEEE80211_VHT_CHANWIDTH_160MHZ; + } + if (IEEE80211_IS_CHAN_VHT80_80(c)) { + return IEEE80211_VHT_CHANWIDTH_80P80MHZ; + } + if (IEEE80211_IS_CHAN_VHT80(c)) { + return IEEE80211_VHT_CHANWIDTH_80MHZ; + } + if (IEEE80211_IS_CHAN_VHT40(c)) { + return IEEE80211_VHT_CHANWIDTH_USE_HT; + } + if (IEEE80211_IS_CHAN_VHT20(c)) { + return IEEE80211_VHT_CHANWIDTH_USE_HT; + } + + /* We shouldn't get here */ + printf("%s: called on a non-VHT channel (freq=%d, flags=0x%08x\n", + __func__, + (int) c->ic_freq, + c->ic_flags); + return IEEE80211_VHT_CHANWIDTH_USE_HT; +} + +/* + * Note: this just uses the current channel information; + * it doesn't use the node info after parsing. + */ +uint8_t * +ieee80211_add_vhtinfo(uint8_t *frm, struct ieee80211_node *ni) +{ + memset(frm, '\0', sizeof(struct ieee80211_ie_vht_operation)); + + frm[0] = IEEE80211_ELEMID_VHT_OPMODE; + frm[1] = sizeof(struct ieee80211_ie_vht_operation) - 2; + frm += 2; + + /* + * XXX if it's a station, then see if we have a node + * channel or ANYC. If it's ANYC then assume we're + * scanning, and announce our capabilities. + * + * This should set the "20/40/80/160MHz wide config"; + * the 80/80 or 160MHz wide config is done in VHTCAP. + * + * Other modes - just limit it to the channel. + */ + + /* 8-bit chanwidth */ + *frm++ = ieee80211_vht_get_chwidth_ie(ni->ni_chan); + + /* 8-bit freq1 */ + *frm++ = ni->ni_chan->ic_vht_ch_freq1; + + /* 8-bit freq2 */ + *frm++ = ni->ni_chan->ic_vht_ch_freq1; + + /* 16-bit basic MCS set - just MCS0..7 for NSS=1 for now */ + ADDSHORT(frm, 0xfffc); + + return (frm); +} + +void +ieee80211_vht_update_cap(struct ieee80211_node *ni, const uint8_t *vhtcap_ie, + const uint8_t *vhtop_ie) +{ + + ieee80211_parse_vhtcap(ni, vhtcap_ie); + ieee80211_parse_vhtopmode(ni, vhtop_ie); +} + +static struct ieee80211_channel * +findvhtchan(struct ieee80211com *ic, struct ieee80211_channel *c, int vhtflags) +{ + + return (ieee80211_find_channel(ic, c->ic_freq, + (c->ic_flags & ~IEEE80211_CHAN_VHT) | vhtflags)); +} + +/* + * Handle channel promotion to VHT, similar to ieee80211_ht_adjust_channel(). + */ +struct ieee80211_channel * +ieee80211_vht_adjust_channel(struct ieee80211com *ic, + struct ieee80211_channel *chan, int flags) +{ + struct ieee80211_channel *c; + + /* First case - handle channel demotion - if VHT isn't set */ + if ((flags & IEEE80211_FVHT_VHT) == 0) { +#if 0 + printf("%s: demoting channel %d/0x%08x\n", __func__, + chan->ic_ieee, chan->ic_flags); +#endif + c = ieee80211_find_channel(ic, chan->ic_freq, + chan->ic_flags & ~IEEE80211_CHAN_VHT); + if (c == NULL) + c = chan; +#if 0 + printf("%s: .. to %d/0x%08x\n", __func__, + c->ic_ieee, c->ic_flags); +#endif + return (c); + } + + /* + * We can upgrade to VHT - attempt to do so + * + * Note: we don't clear the HT flags, these are the hints + * for HT40U/HT40D when selecting VHT40 or larger channels. + */ + /* Start with VHT80 */ + c = NULL; + if ((c == NULL) && (flags & IEEE80211_FVHT_USEVHT160)) + c = findvhtchan(ic, chan, IEEE80211_CHAN_VHT80); + + if ((c == NULL) && (flags & IEEE80211_FVHT_USEVHT80P80)) + c = findvhtchan(ic, chan, IEEE80211_CHAN_VHT80_80); + + if ((c == NULL) && (flags & IEEE80211_FVHT_USEVHT80)) + c = findvhtchan(ic, chan, IEEE80211_CHAN_VHT80); + + if ((c == NULL) && (flags & IEEE80211_FVHT_USEVHT40)) + c = findvhtchan(ic, chan, IEEE80211_CHAN_VHT40U); + if ((c == NULL) && (flags & IEEE80211_FVHT_USEVHT40)) + c = findvhtchan(ic, chan, IEEE80211_CHAN_VHT40D); + /* + * If we get here, VHT20 is always possible because we checked + * for IEEE80211_FVHT_VHT above. + */ + if (c == NULL) + c = findvhtchan(ic, chan, IEEE80211_CHAN_VHT20); + + if (c != NULL) + chan = c; + +#if 0 + printf("%s: selected %d/0x%08x\n", __func__, c->ic_ieee, c->ic_flags); +#endif + return (chan); +} diff --git a/sys/net80211/ieee80211_vht.h b/sys/net80211/ieee80211_vht.h new file mode 100644 index 00000000000..9e68e7d258d --- /dev/null +++ b/sys/net80211/ieee80211_vht.h @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2016 Adrian Chadd + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ +#ifndef _NET80211_IEEE80211_VHT_H_ +#define _NET80211_IEEE80211_VHT_H_ + +void ieee80211_vht_attach(struct ieee80211com *); +void ieee80211_vht_detach(struct ieee80211com *); +void ieee80211_vht_vattach(struct ieee80211vap *); +void ieee80211_vht_vdetach(struct ieee80211vap *); + +void ieee80211_vht_announce(struct ieee80211com *); + +void ieee80211_vht_node_init(struct ieee80211_node *); +void ieee80211_vht_node_cleanup(struct ieee80211_node *); + +void ieee80211_parse_vhtopmode(struct ieee80211_node *, const uint8_t *); +void ieee80211_parse_vhtcap(struct ieee80211_node *, const uint8_t *); + +int ieee80211_vht_updateparams(struct ieee80211_node *, + const uint8_t *, const uint8_t *); +void ieee80211_setup_vht_rates(struct ieee80211_node *, + const uint8_t *, const uint8_t *); + +void ieee80211_vht_timeout(struct ieee80211com *ic); + +void ieee80211_vht_node_join(struct ieee80211_node *ni); +void ieee80211_vht_node_leave(struct ieee80211_node *ni); + +uint8_t * ieee80211_add_vhtcap(uint8_t *frm, struct ieee80211_node *); +uint8_t * ieee80211_add_vhtinfo(uint8_t *frm, struct ieee80211_node *); + +void ieee80211_vht_update_cap(struct ieee80211_node *, + const uint8_t *, const uint8_t *); + +struct ieee80211_channel * + ieee80211_vht_adjust_channel(struct ieee80211com *, + struct ieee80211_channel *, int); + +#endif /* _NET80211_IEEE80211_VHT_H_ */ From b092fd69a89894ff471c748b0e54bf7cfc9e54b8 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 8 Jan 2017 04:27:08 +0000 Subject: [PATCH 43/55] [net80211] include the prototype VHT code into the build. Note: it isn't called anywhere yet! --- sys/conf/files | 1 + sys/modules/wlan/Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/conf/files b/sys/conf/files index 7d1d77de7bf..2f208e6c51c 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3965,6 +3965,7 @@ net80211/ieee80211_sta.c optional wlan \ net80211/ieee80211_superg.c optional wlan ieee80211_support_superg net80211/ieee80211_scan_sw.c optional wlan net80211/ieee80211_tdma.c optional wlan ieee80211_support_tdma +net80211/ieee80211_vht.c optional wlan net80211/ieee80211_wds.c optional wlan net80211/ieee80211_xauth.c optional wlan wlan_xauth net80211/ieee80211_alq.c optional wlan ieee80211_alq diff --git a/sys/modules/wlan/Makefile b/sys/modules/wlan/Makefile index 344ff4e8a31..25f2fdc7503 100644 --- a/sys/modules/wlan/Makefile +++ b/sys/modules/wlan/Makefile @@ -12,7 +12,7 @@ SRCS= ieee80211.c ieee80211_action.c ieee80211_ageq.c \ ieee80211_ratectl_none.c ieee80211_regdomain.c \ ieee80211_ht.c ieee80211_hwmp.c ieee80211_adhoc.c ieee80211_hostap.c \ ieee80211_monitor.c ieee80211_sta.c ieee80211_wds.c ieee80211_ddb.c \ - ieee80211_tdma.c ieee80211_superg.c + ieee80211_tdma.c ieee80211_superg.c ieee80211_vht.c SRCS+= bus_if.h device_if.h opt_ddb.h opt_inet.h opt_inet6.h \ opt_tdma.h opt_wlan.h From 0c6393a265bfbf26e8337d123c5839de409da0ac Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sun, 8 Jan 2017 06:20:21 +0000 Subject: [PATCH 44/55] mmc: Accept even lower voltage for Cherryview And HP x2 210, per DragonFlyBSD 240bd9cd58f8259c12c14a8006837e698. Submitted by: Johannes Lundberg No objection: gonzo@ Obtained from: DragonFlyBSD --- sys/dev/mmc/mmcreg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/mmc/mmcreg.h b/sys/dev/mmc/mmcreg.h index f25c0f63e36..ba4ca93a178 100644 --- a/sys/dev/mmc/mmcreg.h +++ b/sys/dev/mmc/mmcreg.h @@ -355,8 +355,8 @@ struct mmc_request { */ #define MMC_OCR_VOLTAGE 0x3fffffffU /* Vdd Voltage mask */ #define MMC_OCR_LOW_VOLTAGE (1u << 7) /* Low Voltage Range -- tbd */ +#define MMC_OCR_MIN_VOLTAGE_SHIFT 7 #define MMC_OCR_200_210 (1U << 8) /* Vdd voltage 2.00 ~ 2.10 */ -#define MMC_OCR_MIN_VOLTAGE_SHIFT 8 #define MMC_OCR_210_220 (1U << 9) /* Vdd voltage 2.10 ~ 2.20 */ #define MMC_OCR_220_230 (1U << 10) /* Vdd voltage 2.20 ~ 2.30 */ #define MMC_OCR_230_240 (1U << 11) /* Vdd voltage 2.30 ~ 2.40 */ From dbaab6e66f856662798722aa992a1641300d989d Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sun, 8 Jan 2017 06:21:49 +0000 Subject: [PATCH 45/55] cd9660: Expand internal inum size to 64 bits Inums in cd9660 refer to byte offsets on the media. DVD and BD media can have entries above 4GB, especially with multi-session images. PR: 190655 Reported by: Thomas Schmitt --- sys/fs/cd9660/cd9660_lookup.c | 6 +++--- sys/fs/cd9660/cd9660_node.c | 4 ++-- sys/fs/cd9660/cd9660_node.h | 2 +- sys/fs/cd9660/cd9660_rrip.c | 2 +- sys/fs/cd9660/cd9660_vfsops.c | 27 +++++++++++++++++++++++---- sys/fs/cd9660/cd9660_vnops.c | 11 +++++++---- sys/fs/cd9660/iso.h | 17 +++++++++++------ sys/fs/cd9660/iso_rrip.h | 4 ++-- 8 files changed, 50 insertions(+), 23 deletions(-) diff --git a/sys/fs/cd9660/cd9660_lookup.c b/sys/fs/cd9660/cd9660_lookup.c index 274fb3e05c2..498e33fc61e 100644 --- a/sys/fs/cd9660/cd9660_lookup.c +++ b/sys/fs/cd9660/cd9660_lookup.c @@ -51,8 +51,8 @@ __FBSDID("$FreeBSD$"); #include struct cd9660_ino_alloc_arg { - ino_t ino; - ino_t i_ino; + cd_ino_t ino; + cd_ino_t i_ino; struct iso_directory_record *ep; }; @@ -124,7 +124,7 @@ cd9660_lookup(ap) struct cd9660_ino_alloc_arg dd_arg; u_long bmask; /* block offset mask */ int error; - ino_t ino, i_ino; + cd_ino_t ino, i_ino; int ltype, reclen; u_short namelen; int isoflags; diff --git a/sys/fs/cd9660/cd9660_node.c b/sys/fs/cd9660/cd9660_node.c index 19d723e1e6e..359a30445f3 100644 --- a/sys/fs/cd9660/cd9660_node.c +++ b/sys/fs/cd9660/cd9660_node.c @@ -309,12 +309,12 @@ cd9660_tstamp_conv17(pi,pu) return cd9660_tstamp_conv7(buf, pu, ISO_FTYPE_DEFAULT); } -ino_t +cd_ino_t isodirino(isodir, imp) struct iso_directory_record *isodir; struct iso_mnt *imp; { - ino_t ino; + cd_ino_t ino; ino = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length)) << imp->im_bshift; diff --git a/sys/fs/cd9660/cd9660_node.h b/sys/fs/cd9660/cd9660_node.h index 80e233e769b..cd8f90caca8 100644 --- a/sys/fs/cd9660/cd9660_node.h +++ b/sys/fs/cd9660/cd9660_node.h @@ -58,7 +58,7 @@ typedef struct { struct iso_node { struct vnode *i_vnode; /* vnode associated with this inode */ - ino_t i_number; /* the identity of the inode */ + cd_ino_t i_number; /* the identity of the inode */ /* we use the actual starting block of the file */ struct iso_mnt *i_mnt; /* filesystem associated with this inode */ struct lockf *i_lockf; /* head of byte-level lock list */ diff --git a/sys/fs/cd9660/cd9660_rrip.c b/sys/fs/cd9660/cd9660_rrip.c index a6880393c01..7ddb7db0f21 100644 --- a/sys/fs/cd9660/cd9660_rrip.c +++ b/sys/fs/cd9660/cd9660_rrip.c @@ -628,7 +628,7 @@ cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp) struct iso_directory_record *isodir; char *outbuf; u_short *outlen; - ino_t *inump; + cd_ino_t *inump; struct iso_mnt *imp; { ISO_RRIP_ANALYZE analyze; diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c index a5584640331..7473f97dcee 100644 --- a/sys/fs/cd9660/cd9660_vfsops.c +++ b/sys/fs/cd9660/cd9660_vfsops.c @@ -540,7 +540,7 @@ cd9660_root(mp, flags, vpp) struct iso_mnt *imp = VFSTOISOFS(mp); struct iso_directory_record *dp = (struct iso_directory_record *)imp->root; - ino_t ino = isodirino(dp, imp); + cd_ino_t ino = isodirino(dp, imp); /* * With RRIP we must use the `.' entry of the root directory. @@ -617,6 +617,11 @@ cd9660_fhtovp(mp, fhp, flags, vpp) return (0); } +/* + * Conform to standard VFS interface; can't vget arbitrary inodes beyond 4GB + * into media with current inode scheme and 32-bit ino_t. This shouldn't be + * needed for anything other than nfsd, and who exports a mounted DVD over NFS? + */ static int cd9660_vget(mp, ino, flags, vpp) struct mount *mp; @@ -640,10 +645,22 @@ cd9660_vget(mp, ino, flags, vpp) (struct iso_directory_record *)0)); } +/* Use special comparator for full 64-bit ino comparison. */ +static int +cd9660_vfs_hash_cmp(vp, pino) + struct vnode *vp; + cd_ino_t *pino; +{ + struct iso_node *ip; + + ip = VTOI(vp); + return (ip->i_number != *pino); +} + int cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir) struct mount *mp; - ino_t ino; + cd_ino_t ino; int flags; struct vnode **vpp; int relocated; @@ -658,7 +675,8 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir) struct thread *td; td = curthread; - error = vfs_hash_get(mp, ino, flags, td, vpp, NULL, NULL); + error = vfs_hash_get(mp, ino, flags, td, vpp, cd9660_vfs_hash_cmp, + &ino); if (error || *vpp != NULL) return (error); @@ -699,7 +717,8 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir) *vpp = NULLVP; return (error); } - error = vfs_hash_insert(vp, ino, flags, td, vpp, NULL, NULL); + error = vfs_hash_insert(vp, ino, flags, td, vpp, cd9660_vfs_hash_cmp, + &ino); if (error || *vpp != NULL) return (error); diff --git a/sys/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c index 04c0ff5ceeb..59d8dc106be 100644 --- a/sys/fs/cd9660/cd9660_vnops.c +++ b/sys/fs/cd9660/cd9660_vnops.c @@ -481,6 +481,7 @@ cd9660_readdir(ap) u_short namelen; int ncookies = 0; u_long *cookies = NULL; + cd_ino_t ino; dp = VTOI(vdp); imp = dp->i_mnt; @@ -576,8 +577,10 @@ cd9660_readdir(ap) switch (imp->iso_ftype) { case ISO_FTYPE_RRIP: - cd9660_rrip_getname(ep,idp->current.d_name, &namelen, - &idp->current.d_fileno,imp); + ino = idp->current.d_fileno; + cd9660_rrip_getname(ep, idp->current.d_name, &namelen, + &ino, imp); + idp->current.d_fileno = ino; idp->current.d_namlen = (u_char)namelen; if (idp->current.d_namlen) error = iso_uiodir(idp,&idp->current,idp->curroff); @@ -831,8 +834,8 @@ cd9660_vptofh(ap) memcpy(ap->a_fhp, &ifh, sizeof(ifh)); #ifdef ISOFS_DBG - printf("vptofh: ino %d, start %ld\n", - ifh.ifid_ino, ifh.ifid_start); + printf("vptofh: ino %jd, start %ld\n", + (uintmax_t)ifh.ifid_ino, ifh.ifid_start); #endif return (0); diff --git a/sys/fs/cd9660/iso.h b/sys/fs/cd9660/iso.h index a831d7b881c..53f005c870f 100644 --- a/sys/fs/cd9660/iso.h +++ b/sys/fs/cd9660/iso.h @@ -219,6 +219,11 @@ enum ISO_FTYPE { ISO_FTYPE_DEFAULT, ISO_FTYPE_9660, ISO_FTYPE_RRIP, #define ISOFSMNT_ROOT 0 #endif +/* + * When ino_t becomes 64-bit, we can remove this definition in favor of ino_t. + */ +#define cd_ino_t uint64_t + struct iso_mnt { uint64_t im_flags; @@ -250,10 +255,10 @@ struct iso_mnt { }; struct ifid { - u_short ifid_len; - u_short ifid_pad; - int ifid_ino; - long ifid_start; + u_short ifid_len; + u_short ifid_pad; + cd_ino_t ifid_ino; + long ifid_start; }; #define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data)) @@ -263,7 +268,7 @@ struct ifid { #define lblkno(imp, loc) ((loc) >> (imp)->im_bshift) #define blksize(imp, ip, lbn) ((imp)->logical_block_size) -int cd9660_vget_internal(struct mount *, ino_t, int, struct vnode **, int, +int cd9660_vget_internal(struct mount *, cd_ino_t, int, struct vnode **, int, struct iso_directory_record *); #define cd9660_sysctl ((int (*)(int *, u_int, void *, size_t *, void *, \ size_t, struct proc *))eopnotsupp) @@ -274,7 +279,7 @@ extern struct vop_vector cd9660_fifoops; int isochar(u_char *, u_char *, int, u_short *, int *, int, void *); int isofncmp(u_char *, int, u_char *, int, int, int, void *, void *); void isofntrans(u_char *, int, u_char *, u_short *, int, int, int, int, void *); -ino_t isodirino(struct iso_directory_record *, struct iso_mnt *); +cd_ino_t isodirino(struct iso_directory_record *, struct iso_mnt *); u_short sgetrune(const char *, size_t, char const **, int, void *); #endif /* _KERNEL */ diff --git a/sys/fs/cd9660/iso_rrip.h b/sys/fs/cd9660/iso_rrip.h index 75c004c40b6..f3aafe00ec2 100644 --- a/sys/fs/cd9660/iso_rrip.h +++ b/sys/fs/cd9660/iso_rrip.h @@ -61,7 +61,7 @@ typedef struct { off_t iso_ce_off; /* offset of continuation area */ int iso_ce_len; /* length of continuation area */ struct iso_mnt *imp; /* mount structure */ - ino_t *inump; /* inode number pointer */ + cd_ino_t *inump; /* inode number pointer */ char *outbuf; /* name/symbolic link output area */ u_short *outlen; /* length of above */ u_short maxlen; /* maximum length of above */ @@ -74,7 +74,7 @@ int cd9660_rrip_analyze(struct iso_directory_record *isodir, struct iso_node *inop, struct iso_mnt *imp); int cd9660_rrip_getname(struct iso_directory_record *isodir, char *outbuf, u_short *outlen, - ino_t *inump, struct iso_mnt *imp); + cd_ino_t *inump, struct iso_mnt *imp); int cd9660_rrip_getsymname(struct iso_directory_record *isodir, char *outbuf, u_short *outlen, struct iso_mnt *imp); From c8227de25f5d4ddf088b15f3c6c2fde287f73ba9 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sun, 8 Jan 2017 06:22:35 +0000 Subject: [PATCH 46/55] Do not truncate inode calculation from ISO9660 block offset PR: 190655 Reported by: Thomas Schmitt Obtained from: NetBSD sys/fs/cd9660/cd9660_node.c,r1.31 --- sys/fs/cd9660/cd9660_node.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sys/fs/cd9660/cd9660_node.c b/sys/fs/cd9660/cd9660_node.c index 359a30445f3..14a06b70528 100644 --- a/sys/fs/cd9660/cd9660_node.c +++ b/sys/fs/cd9660/cd9660_node.c @@ -316,7 +316,14 @@ isodirino(isodir, imp) { cd_ino_t ino; - ino = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length)) - << imp->im_bshift; - return (ino); + /* + * Note there is an inverse calculation in + * cd9660_vfsops.c:cd9660_vget_internal(): + * ip->iso_start = ino >> imp->im_bshift; + * and also a calculation of the isodir pointer + * from an inode in cd9660_vnops.c:cd9660_readlink() + */ + ino = ((cd_ino_t)isonum_733(isodir->extent) + + isonum_711(isodir->ext_attr_length)) << imp->im_bshift; + return ino; } From 8436bcc87d2e28790a861c28a4dd1b94832f1032 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sun, 8 Jan 2017 06:26:33 +0000 Subject: [PATCH 47/55] Add some additional ACPI methods for DRM Add AcpiGetDataFull and AcpiGetTableWithSize. Submitted by: Matt Macy --- .../acpica/components/namespace/nsxfeval.c | 40 +++++++++++++++---- .../dev/acpica/components/tables/tbxface.c | 38 ++++++++++++++++-- sys/contrib/dev/acpica/include/acpixf.h | 16 ++++++++ 3 files changed, 83 insertions(+), 11 deletions(-) diff --git a/sys/contrib/dev/acpica/components/namespace/nsxfeval.c b/sys/contrib/dev/acpica/components/namespace/nsxfeval.c index 6467d7e2f54..4c50040156e 100644 --- a/sys/contrib/dev/acpica/components/namespace/nsxfeval.c +++ b/sys/contrib/dev/acpica/components/namespace/nsxfeval.c @@ -1022,23 +1022,25 @@ ACPI_EXPORT_SYMBOL (AcpiDetachData) /******************************************************************************* * - * FUNCTION: AcpiGetData + * FUNCTION: AcpiGetDataFull * * PARAMETERS: ObjHandle - Namespace node - * Handler - Handler used in call to AttachData + * Handle - Handler used in call to attach_data * Data - Where the data is returned + * Callback - function to execute before returning * * RETURN: Status * - * DESCRIPTION: Retrieve data that was previously attached to a namespace node. + * DESCRIPTION: Retrieve data that was previously attached to a namespace node + * and execute a callback before returning. * ******************************************************************************/ - ACPI_STATUS -AcpiGetData ( +AcpiGetDataFull ( ACPI_HANDLE ObjHandle, ACPI_OBJECT_HANDLER Handler, - void **Data) + void **Data, + void (*Callback)(void *)) { ACPI_NAMESPACE_NODE *Node; ACPI_STATUS Status; @@ -1069,10 +1071,34 @@ AcpiGetData ( } Status = AcpiNsGetAttachedData (Node, Handler, Data); - + if (ACPI_SUCCESS(Status) && Callback) { + Callback(*Data); + } UnlockAndExit: (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); return (Status); } +ACPI_EXPORT_SYMBOL (AcpiGetDataFull) +/******************************************************************************* + * + * FUNCTION: AcpiGetData + * + * PARAMETERS: ObjHandle - Namespace node + * Handler - Handler used in call to AttachData + * Data - Where the data is returned + * + * RETURN: Status + * + * DESCRIPTION: Retrieve data that was previously attached to a namespace node. + * + ******************************************************************************/ +ACPI_STATUS +AcpiGetData ( + ACPI_HANDLE ObjHandle, + ACPI_OBJECT_HANDLER Handler, + void **Data) +{ + return (AcpiGetDataFull(ObjHandle, Handler, Data, NULL)); +} ACPI_EXPORT_SYMBOL (AcpiGetData) diff --git a/sys/contrib/dev/acpica/components/tables/tbxface.c b/sys/contrib/dev/acpica/components/tables/tbxface.c index 6e231cd8fce..254958bd492 100644 --- a/sys/contrib/dev/acpica/components/tables/tbxface.c +++ b/sys/contrib/dev/acpica/components/tables/tbxface.c @@ -314,11 +314,12 @@ ACPI_EXPORT_SYMBOL (AcpiGetTableHeader) /******************************************************************************* * - * FUNCTION: AcpiGetTable + * FUNCTION: AcpiGetTableWithSize * * PARAMETERS: Signature - ACPI signature of needed table * Instance - Which instance (for SSDTs) * OutTable - Where the pointer to the table is returned + * TblSize - Size of the table * * RETURN: Status and pointer to the requested table * @@ -333,10 +334,11 @@ ACPI_EXPORT_SYMBOL (AcpiGetTableHeader) ******************************************************************************/ ACPI_STATUS -AcpiGetTable ( +AcpiGetTableWithSize ( char *Signature, UINT32 Instance, - ACPI_TABLE_HEADER **OutTable) + ACPI_TABLE_HEADER **OutTable, + ACPI_SIZE *TblSize) { UINT32 i; UINT32 j; @@ -434,10 +436,38 @@ AcpiPutTable ( (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); return_VOID; } - ACPI_EXPORT_SYMBOL (AcpiPutTable) +/******************************************************************************* + * + * FUNCTION: AcpiGetTable + * + * PARAMETERS: Signature - ACPI signature of needed table + * Instance - Which instance (for SSDTs) + * OutTable - Where the pointer to the table is returned + * + * RETURN: Status and pointer to the requested table + * + * DESCRIPTION: Finds and verifies an ACPI table. Table must be in the + * RSDT/XSDT. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiGetTable ( + char *Signature, + UINT32 Instance, + ACPI_TABLE_HEADER **OutTable) +{ + ACPI_SIZE Size; + + return (AcpiGetTableWithSize(Signature, Instance, OutTable, &Size)); +} + +ACPI_EXPORT_SYMBOL (AcpiGetTable) + + /******************************************************************************* * * FUNCTION: AcpiGetTableByIndex diff --git a/sys/contrib/dev/acpica/include/acpixf.h b/sys/contrib/dev/acpica/include/acpixf.h index 7234ae8e331..7a0edc091dd 100644 --- a/sys/contrib/dev/acpica/include/acpixf.h +++ b/sys/contrib/dev/acpica/include/acpixf.h @@ -584,6 +584,14 @@ AcpiGetTableHeader ( UINT32 Instance, ACPI_TABLE_HEADER *OutTableHeader)) +ACPI_EXTERNAL_RETURN_STATUS ( +ACPI_STATUS +AcpiGetTableWithSize ( + ACPI_STRING Signature, + UINT32 Instance, + ACPI_TABLE_HEADER **OutTable, + ACPI_SIZE *TblSize)) + ACPI_EXTERNAL_RETURN_STATUS ( ACPI_STATUS AcpiGetTable ( @@ -670,6 +678,14 @@ AcpiGetData ( ACPI_OBJECT_HANDLER Handler, void **Data)) +ACPI_EXTERNAL_RETURN_STATUS ( +ACPI_STATUS +AcpiGetDataFull ( + ACPI_HANDLE Object, + ACPI_OBJECT_HANDLER Handler, + void **Data, + void (*Callback)(void *))) + ACPI_EXTERNAL_RETURN_STATUS ( ACPI_STATUS AcpiDebugTrace ( From a758566cb8920e2146aad829a91c700594de4fb0 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sun, 8 Jan 2017 06:50:53 +0000 Subject: [PATCH 48/55] chmod: Add SIGINFO handler PR: 191884 Submitted by: Dan McGregor Reviewed by: mjg@ (earlier version) --- bin/chmod/chmod.1 | 12 +++++++++++- bin/chmod/chmod.c | 17 +++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/bin/chmod/chmod.1 b/bin/chmod/chmod.1 index 7efaabcdefc..9eec706e743 100644 --- a/bin/chmod/chmod.1 +++ b/bin/chmod/chmod.1 @@ -32,7 +32,7 @@ .\" @(#)chmod.1 8.4 (Berkeley) 3/31/94 .\" $FreeBSD$ .\" -.Dd April 20, 2015 +.Dd January 7, 2017 .Dt CHMOD 1 .Os .Sh NAME @@ -106,6 +106,16 @@ option is specified. In addition, these options override each other and the command's actions are determined by the last one specified. .Pp +If +.Nm +receives a +.Dv SIGINFO +signal (see the +.Cm status +argument for +.Xr stty 1 ) , +then the current filename as well as the old and new modes are displayed. +.Pp Only the owner of a file or the super-user is permitted to change the mode of a file. .Sh EXIT STATUS diff --git a/bin/chmod/chmod.c b/bin/chmod/chmod.c index a6f625b11e6..d6875f07332 100644 --- a/bin/chmod/chmod.c +++ b/bin/chmod/chmod.c @@ -49,14 +49,24 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include #include +static volatile sig_atomic_t siginfo; + static void usage(void); static int may_have_nfs4acl(const FTSENT *ent, int hflag); +static void +siginfo_handler(int sig __unused) +{ + + siginfo = 1; +} + int main(int argc, char *argv[]) { @@ -125,6 +135,8 @@ done: argv += optind; if (argc < 2) usage(); + (void)signal(SIGINFO, siginfo_handler); + if (Rflag) { if (hflag) errx(1, "the -R and -h options may not be " @@ -192,10 +204,10 @@ done: argv += optind; && !fflag) { warn("%s", p->fts_path); rval = 1; - } else if (vflag) { + } else if (vflag || siginfo) { (void)printf("%s", p->fts_path); - if (vflag > 1) { + if (vflag > 1 || siginfo) { char m1[12], m2[12]; strmode(p->fts_statp->st_mode, m1); @@ -207,6 +219,7 @@ done: argv += optind; newmode, m2); } (void)printf("\n"); + siginfo = 0; } } if (errno) From bb577bb6998be6b5a4853c203c8308bc9b84be60 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sun, 8 Jan 2017 06:58:42 +0000 Subject: [PATCH 49/55] chown/chgrp: Add SIGINFO handler PR: 191884 Submitted by: Dan McGregor Reviewed by: mjg@ (earlier version) --- usr.sbin/chown/chgrp.1 | 13 +++++++- usr.sbin/chown/chown.8 | 13 +++++++- usr.sbin/chown/chown.c | 70 +++++++++++++++++++++++++----------------- 3 files changed, 65 insertions(+), 31 deletions(-) diff --git a/usr.sbin/chown/chgrp.1 b/usr.sbin/chown/chgrp.1 index 6fb0a31283e..a9a4f641053 100644 --- a/usr.sbin/chown/chgrp.1 +++ b/usr.sbin/chown/chgrp.1 @@ -31,7 +31,7 @@ .\" @(#)chgrp.1 8.3 (Berkeley) 3/31/94 .\" $FreeBSD$ .\" -.Dd April 20, 2015 +.Dd January 7, 2017 .Dt CHGRP 1 .Os .Sh NAME @@ -120,6 +120,17 @@ The user invoking .Nm must belong to the specified group and be the owner of the file, or be the super-user. +.Pp +If +.Nm +receives a +.Dv SIGINFO +signal (see the +.Cm status +argument for +.Xr stty 1 ) , +then the current filename as well as the old and new group names are +displayed. .Sh FILES .Bl -tag -width /etc/group -compact .It Pa /etc/group diff --git a/usr.sbin/chown/chown.8 b/usr.sbin/chown/chown.8 index 6b827284f9d..0f508089b5c 100644 --- a/usr.sbin/chown/chown.8 +++ b/usr.sbin/chown/chown.8 @@ -28,7 +28,7 @@ .\" @(#)chown.8 8.3 (Berkeley) 3/31/94 .\" $FreeBSD$ .\" -.Dd April 20, 2015 +.Dd January 7, 2017 .Dt CHOWN 8 .Os .Sh NAME @@ -135,6 +135,17 @@ group name. .Pp The ownership of a file may only be altered by a super-user for obvious security reasons. +.Pp +If +.Nm +receives a +.Dv SIGINFO +signal (see the +.Cm status +argument for +.Xr stty 1 ) , +then the current filename as well as the old and new file owner and group +are displayed. .Sh EXIT STATUS .Ex -std .Sh COMPATIBILITY diff --git a/usr.sbin/chown/chown.c b/usr.sbin/chown/chown.c index e0698dcc0fb..850b600c084 100644 --- a/usr.sbin/chown/chown.c +++ b/usr.sbin/chown/chown.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -63,11 +64,20 @@ static void a_uid(const char *); static void chownerr(const char *); static uid_t id(const char *, const char *); static void usage(void); +static void print_info(const FTSENT *, int); static uid_t uid; static gid_t gid; static int ischown; static const char *gname; +static volatile sig_atomic_t siginfo; + +static void +siginfo_handler(int sig __unused) +{ + + siginfo = 1; +} int main(int argc, char **argv) @@ -119,6 +129,8 @@ main(int argc, char **argv) if (argc < 2) usage(); + (void)signal(SIGINFO, siginfo_handler); + if (Rflag) { if (hflag && (Hflag || Lflag)) errx(1, "the -R%c and -h options may not be " @@ -189,6 +201,10 @@ main(int argc, char **argv) default: break; } + if (siginfo) { + print_info(p, 2); + siginfo = 0; + } if ((uid == (uid_t)-1 || uid == p->fts_statp->st_uid) && (gid == (gid_t)-1 || gid == p->fts_statp->st_gid)) continue; @@ -196,35 +212,8 @@ main(int argc, char **argv) == -1 && !fflag) { chownerr(p->fts_path); rval = 1; - } else if (vflag) { - printf("%s", p->fts_path); - if (vflag > 1) { - if (ischown) { - printf(": %ju:%ju -> %ju:%ju", - (uintmax_t) - p->fts_statp->st_uid, - (uintmax_t) - p->fts_statp->st_gid, - (uid == (uid_t)-1) ? - (uintmax_t) - p->fts_statp->st_uid : - (uintmax_t)uid, - (gid == (gid_t)-1) ? - (uintmax_t) - p->fts_statp->st_gid : - (uintmax_t)gid); - } else { - printf(": %ju -> %ju", - (uintmax_t) - p->fts_statp->st_gid, - (gid == (gid_t)-1) ? - (uintmax_t) - p->fts_statp->st_gid : - (uintmax_t)gid); - } - } - printf("\n"); - } + } else if (vflag) + print_info(p, vflag); } if (errno) err(1, "fts_read"); @@ -315,3 +304,26 @@ usage(void) "usage: chgrp [-fhvx] [-R [-H | -L | -P]] group file ..."); exit(1); } + +static void +print_info(const FTSENT *p, int vflag) +{ + + printf("%s", p->fts_path); + if (vflag > 1) { + if (ischown) { + printf(": %ju:%ju -> %ju:%ju", + (uintmax_t)p->fts_statp->st_uid, + (uintmax_t)p->fts_statp->st_gid, + (uid == (uid_t)-1) ? + (uintmax_t)p->fts_statp->st_uid : (uintmax_t)uid, + (gid == (gid_t)-1) ? + (uintmax_t)p->fts_statp->st_gid : (uintmax_t)gid); + } else { + printf(": %ju -> %ju", (uintmax_t)p->fts_statp->st_gid, + (gid == (gid_t)-1) ? + (uintmax_t)p->fts_statp->st_gid : (uintmax_t)gid); + } + } + printf("\n"); +} From f9d593d771a171cfef46a435fa21b95e6b3f3180 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sun, 8 Jan 2017 08:36:37 +0000 Subject: [PATCH 50/55] libprocstat: Include cd9660 headers in the same order as the kernel Fix userspace build after r311665. --- lib/libprocstat/cd9660.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libprocstat/cd9660.c b/lib/libprocstat/cd9660.c index ab95e2a04c3..cc3c363f7be 100644 --- a/lib/libprocstat/cd9660.c +++ b/lib/libprocstat/cd9660.c @@ -53,10 +53,10 @@ __FBSDID("$FreeBSD$"); #include -#include #define _KERNEL #include #undef _KERNEL +#include #include #include From 55cfad428bbffb1e5a779943a7cda223a269241a Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sun, 8 Jan 2017 09:16:07 +0000 Subject: [PATCH 51/55] iso_rrip.h: Hide kernel definitions from makefs(8) Reported by: O. Hartmann --- sys/fs/cd9660/iso_rrip.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/fs/cd9660/iso_rrip.h b/sys/fs/cd9660/iso_rrip.h index f3aafe00ec2..ebf39b79d7e 100644 --- a/sys/fs/cd9660/iso_rrip.h +++ b/sys/fs/cd9660/iso_rrip.h @@ -54,6 +54,7 @@ #define ISO_SUSP_STOP 0x1000 #define ISO_SUSP_UNKNOWN 0x8000 +#ifdef _KERNEL typedef struct { struct iso_node *inop; int fields; /* interesting fields in this analysis */ @@ -80,3 +81,4 @@ int cd9660_rrip_getsymname(struct iso_directory_record *isodir, struct iso_mnt *imp); int cd9660_rrip_offset(struct iso_directory_record *isodir, struct iso_mnt *imp); +#endif /* _KERNEL */ From 72ad0cc6be0084902ef1756b1083a777bbef1a8f Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 8 Jan 2017 10:07:54 +0000 Subject: [PATCH 52/55] [net80211] use the correct freq2 field when populating VHT operation element. Whilst here, leave a TODO comment so I revisit this routine in the context of hostap operation probe requests for IBSS/mesh. --- sys/net80211/ieee80211_vht.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211_vht.c b/sys/net80211/ieee80211_vht.c index 3cc5f165ed5..274d94b2520 100644 --- a/sys/net80211/ieee80211_vht.c +++ b/sys/net80211/ieee80211_vht.c @@ -352,6 +352,14 @@ ieee80211_vht_get_chwidth_ie(struct ieee80211_channel *c) /* * Note: this just uses the current channel information; * it doesn't use the node info after parsing. + * + * XXX TODO: need to make the basic MCS set configurable. + * XXX TODO: read 802.11-2013 to determine what to set + * chwidth to when scanning. I have a feeling + * it isn't involved in scanning and we shouldn't + * be sending it; and I don't yet know what to set + * it to for IBSS or hostap where the peer may be + * a completely different channel width to us. */ uint8_t * ieee80211_add_vhtinfo(uint8_t *frm, struct ieee80211_node *ni) @@ -380,7 +388,7 @@ ieee80211_add_vhtinfo(uint8_t *frm, struct ieee80211_node *ni) *frm++ = ni->ni_chan->ic_vht_ch_freq1; /* 8-bit freq2 */ - *frm++ = ni->ni_chan->ic_vht_ch_freq1; + *frm++ = ni->ni_chan->ic_vht_ch_freq2; /* 16-bit basic MCS set - just MCS0..7 for NSS=1 for now */ ADDSHORT(frm, 0xfffc); From a1dce3c0a33fb8e202a61581bd6d10184451253f Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 8 Jan 2017 10:13:05 +0000 Subject: [PATCH 53/55] [net80211] add roaming parameters for 11ac. These are mostly placeholders for now. --- sys/net80211/ieee80211_scan.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sys/net80211/ieee80211_scan.c b/sys/net80211/ieee80211_scan.c index c972e82b6fd..e4bac691c53 100644 --- a/sys/net80211/ieee80211_scan.c +++ b/sys/net80211/ieee80211_scan.c @@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$"); #define ROAM_RATE_HALF_DEFAULT 2*6 /* half-width 11a/g bss */ #define ROAM_RATE_QUARTER_DEFAULT 2*3 /* quarter-width 11a/g bss */ #define ROAM_MCS_11N_DEFAULT (1 | IEEE80211_RATE_MCS) /* 11n bss */ +#define ROAM_MCS_11AC_DEFAULT (1 | IEEE80211_RATE_MCS) /* 11ac bss; XXX not used yet */ void ieee80211_scan_attach(struct ieee80211com *ic) @@ -116,6 +117,11 @@ static const struct ieee80211_roamparam defroam[IEEE80211_MODE_MAX] = { .rate = ROAM_MCS_11N_DEFAULT }, [IEEE80211_MODE_11NG] = { .rssi = ROAM_RSSI_11B_DEFAULT, .rate = ROAM_MCS_11N_DEFAULT }, + [IEEE80211_MODE_VHT_2GHZ] = { .rssi = ROAM_RSSI_11B_DEFAULT, + .rate = ROAM_MCS_11AC_DEFAULT }, + [IEEE80211_MODE_VHT_5GHZ] = { .rssi = ROAM_RSSI_11A_DEFAULT, + .rate = ROAM_MCS_11AC_DEFAULT }, + }; void From 18b105c27ba4949530574a8e9ed9225015382b0b Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Sun, 8 Jan 2017 12:40:07 +0000 Subject: [PATCH 54/55] Add direction argument to ipsec_setspidx_inpcb() function. This function is used only by ipsec_getpolicybysock() to fill security policy index selector for locally generated packets (that have INPCB). The function incorrectly assumes that spidx is the same for both directions. Fix this by using new direction argument to specify correct INPCB security policy - sp_in or sp_out. There is no need to fill both policy indeces, because they are overwritten for each packet. This fixes security policy matching for outbound packets when user has specified TCP/UDP ports in the security policy upperspec. PR: 213869 MFC after: 1 week --- sys/netipsec/ipsec.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c index 2e735393f10..dd7be14cb5f 100644 --- a/sys/netipsec/ipsec.c +++ b/sys/netipsec/ipsec.c @@ -241,7 +241,7 @@ SYSCTL_VNET_PCPUSTAT(_net_inet6_ipsec6, IPSECCTL_STATS, ipsecstats, #endif /* INET6 */ static int ipsec_in_reject(struct secpolicy *, const struct mbuf *); -static int ipsec_setspidx_inpcb(const struct mbuf *, struct inpcb *); +static int ipsec_setspidx_inpcb(const struct mbuf *, struct inpcb *, u_int); static int ipsec_setspidx(const struct mbuf *, struct secpolicyindex *, int); static void ipsec4_get_ulp(const struct mbuf *m, struct secpolicyindex *, int); static int ipsec4_setspidx_ipaddr(const struct mbuf *, struct secpolicyindex *); @@ -343,7 +343,7 @@ ipsec_getpolicybysock(const struct mbuf *m, u_int dir, struct inpcb *inp, } /* Set spidx in pcb. */ - *error = ipsec_setspidx_inpcb(m, inp); + *error = ipsec_setspidx_inpcb(m, inp, dir); if (*error) return (NULL); @@ -500,8 +500,9 @@ ipsec4_checkpolicy(const struct mbuf *m, u_int dir, int *error, } static int -ipsec_setspidx_inpcb(const struct mbuf *m, struct inpcb *inp) +ipsec_setspidx_inpcb(const struct mbuf *m, struct inpcb *inp, u_int dir) { + struct secpolicyindex *spidx; int error; IPSEC_ASSERT(inp != NULL, ("null inp")); @@ -509,11 +510,13 @@ ipsec_setspidx_inpcb(const struct mbuf *m, struct inpcb *inp) IPSEC_ASSERT(inp->inp_sp->sp_out != NULL && inp->inp_sp->sp_in != NULL, ("null sp_in || sp_out")); - error = ipsec_setspidx(m, &inp->inp_sp->sp_in->spidx, 1); + if (dir == IPSEC_DIR_INBOUND) + spidx = &inp->inp_sp->sp_in->spidx; + else + spidx = &inp->inp_sp->sp_out->spidx; + error = ipsec_setspidx(m, spidx, 1); if (error == 0) { - inp->inp_sp->sp_in->spidx.dir = IPSEC_DIR_INBOUND; - inp->inp_sp->sp_out->spidx = inp->inp_sp->sp_in->spidx; - inp->inp_sp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND; + spidx->dir = dir; } else { bzero(&inp->inp_sp->sp_in->spidx, sizeof (inp->inp_sp->sp_in->spidx)); From 81241f28284a6cb0589238d5a46bf48531da2b10 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 8 Jan 2017 13:26:34 +0000 Subject: [PATCH 55/55] Make CTL_GETSTATS ioctl return partial data if buffer is small. MFC after: 2 weeks --- sys/cam/ctl/ctl.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index d4f0ab710b5..1164b131576 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -2779,32 +2779,29 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, break; } case CTL_GETSTATS: { - struct ctl_stats *stats; + struct ctl_stats *stats = (struct ctl_stats *)addr; int i; - stats = (struct ctl_stats *)addr; - - if ((sizeof(struct ctl_lun_io_stats) * softc->num_luns) > - stats->alloc_len) { - stats->status = CTL_SS_NEED_MORE_SPACE; - stats->num_luns = softc->num_luns; - break; - } /* * XXX KDM no locking here. If the LUN list changes, * things can blow up. */ i = 0; + stats->status = CTL_SS_OK; + stats->fill_len = 0; STAILQ_FOREACH(lun, &softc->lun_list, links) { + if (stats->fill_len + sizeof(lun->stats) > + stats->alloc_len) { + stats->status = CTL_SS_NEED_MORE_SPACE; + break; + } retval = copyout(&lun->stats, &stats->lun_stats[i++], sizeof(lun->stats)); if (retval != 0) break; + stats->fill_len += sizeof(lun->stats); } stats->num_luns = softc->num_luns; - stats->fill_len = sizeof(struct ctl_lun_io_stats) * - softc->num_luns; - stats->status = CTL_SS_OK; #ifdef CTL_TIME_IO stats->flags = CTL_STATS_FLAG_TIME_VALID; #else