diff --git a/Makefile.inc1 b/Makefile.inc1 index dfa8e1e57b0..3decab02b85 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1694,11 +1694,10 @@ _kerberos5_bootstrap_tools= \ .endif # r283777 makewhatis(1) replaced with mandoc version which builds a database. -.if ${MK_MANDOCDB} != "no" && ${BOOTSTRAPPING} < 1100075 +.if ${MK_MANDOCDB} != "no" _libopenbsd?= lib/libopenbsd -_makewhatis= lib/libsqlite3 \ - usr.bin/mandoc -${_bt}-usr.bin/mandoc: ${_bt}-lib/libopenbsd ${_bt}-lib/libsqlite3 +_makewhatis= usr.bin/mandoc +${_bt}-usr.bin/mandoc: ${_bt}-lib/libopenbsd .endif bootstrap-tools: .PHONY diff --git a/cddl/usr.sbin/zfsd/case_file.cc b/cddl/usr.sbin/zfsd/case_file.cc index 86c74b12230..0cd659622e9 100644 --- a/cddl/usr.sbin/zfsd/case_file.cc +++ b/cddl/usr.sbin/zfsd/case_file.cc @@ -656,8 +656,11 @@ CaseFile::DeSerializeFile(const char *fileName) uint64_t vdevGUID; nvlist_t *vdevConf; - sscanf(fileName, "pool_%" PRIu64 "_vdev_%" PRIu64 ".case", - &poolGUID, &vdevGUID); + if (sscanf(fileName, "pool_%" PRIu64 "_vdev_%" PRIu64 ".case", + &poolGUID, &vdevGUID) != 2) { + throw ZfsdException("CaseFile::DeSerialize: " + "Unintelligible CaseFile filename %s.\n", fileName); + } existingCaseFile = Find(Guid(poolGUID), Guid(vdevGUID)); if (existingCaseFile != NULL) { /* diff --git a/contrib/bsnmp/snmpd/trans_udp.c b/contrib/bsnmp/snmpd/trans_udp.c index f8b74df0685..5c9a7fd470a 100644 --- a/contrib/bsnmp/snmpd/trans_udp.c +++ b/contrib/bsnmp/snmpd/trans_udp.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -119,13 +120,15 @@ udp_init_port(struct tport *tp) addr.sin_port = htons(p->port); addr.sin_family = AF_INET; addr.sin_len = sizeof(addr); - if (addr.sin_addr.s_addr == INADDR_ANY && - setsockopt(p->input.fd, IPPROTO_IP, IP_RECVDSTADDR, &on, - sizeof(on)) == -1) { - syslog(LOG_ERR, "setsockopt(IP_RECVDSTADDR): %m"); - close(p->input.fd); - p->input.fd = -1; - return (SNMP_ERR_GENERR); + if (addr.sin_addr.s_addr == INADDR_ANY) { + if (setsockopt(p->input.fd, IPPROTO_IP, IP_RECVDSTADDR, &on, + sizeof(on)) == -1) { + syslog(LOG_ERR, "setsockopt(IP_RECVDSTADDR): %m"); + close(p->input.fd); + p->input.fd = -1; + return (SNMP_ERR_GENERR); + } + p->recvdstaddr = true; } if (bind(p->input.fd, (struct sockaddr *)&addr, sizeof(addr))) { if (errno == EADDRNOTAVAIL) { @@ -218,7 +221,6 @@ udp_send(struct tport *tp, const u_char *buf, size_t len, { struct udp_port *p = (struct udp_port *)tp; struct cmsghdr *cmsg; - struct in_addr *src_addr; struct msghdr msg; char cbuf[CMSG_SPACE(sizeof(struct in_addr))]; struct iovec iov; @@ -231,15 +233,20 @@ udp_send(struct tport *tp, const u_char *buf, size_t len, msg.msg_iovlen = 1; msg.msg_name = __DECONST(void *, addr); msg.msg_namelen = addrlen; - msg.msg_control = cbuf; - msg.msg_controllen = sizeof(cbuf); - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = IPPROTO_IP; - cmsg->cmsg_type = IP_SENDSRCADDR; - cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); - src_addr = (struct in_addr *)(void*)CMSG_DATA(cmsg); - memcpy(src_addr, &p->recv_addr, sizeof(struct in_addr)); + if (p->recvdstaddr) { + msg.msg_control = cbuf; + msg.msg_controllen = sizeof(cbuf); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_SENDSRCADDR; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); + memcpy(CMSG_DATA(cmsg), &p->dstaddr, sizeof(struct in_addr)); + } else { + msg.msg_control = NULL; + msg.msg_controllen = 0; + } return (sendmsg(p->input.fd, &msg, 0)); } @@ -260,11 +267,12 @@ check_priv_dgram(struct port_input *pi, struct sockcred *cred) * Each receive should return one datagram. */ static ssize_t -recv_dgram(struct port_input *pi, struct in_addr *laddr) +udp_recv(struct tport *tp, struct port_input *pi) { u_char embuf[1000]; char cbuf[CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX)) + CMSG_SPACE(sizeof(struct in_addr))]; + struct udp_port *p = (struct udp_port *)tp; struct msghdr msg; struct iovec iov[1]; ssize_t len; @@ -316,7 +324,8 @@ recv_dgram(struct port_input *pi, struct in_addr *laddr) cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) - memcpy(laddr, CMSG_DATA(cmsg), sizeof(struct in_addr)); + memcpy(&p->dstaddr, CMSG_DATA(cmsg), + sizeof(struct in_addr)); if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDS) cred = (struct sockcred *)CMSG_DATA(cmsg); @@ -328,42 +337,6 @@ recv_dgram(struct port_input *pi, struct in_addr *laddr) return (0); } -/* - * Receive something - */ -static ssize_t -udp_recv(struct tport *tp, struct port_input *pi) -{ - struct udp_port *p = (struct udp_port *)tp; - struct cmsghdr *cmsgp; - struct in_addr *laddr; - struct msghdr msg; - char cbuf[CMSG_SPACE(sizeof(struct in_addr))]; - ssize_t ret; - - memset(cbuf, 0, sizeof(cbuf)); - - msg.msg_control = cbuf; - msg.msg_controllen = sizeof(cbuf); - - cmsgp = CMSG_FIRSTHDR(&msg); - cmsgp->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); - cmsgp->cmsg_level = IPPROTO_IP; - cmsgp->cmsg_type = IP_SENDSRCADDR; - laddr = (struct in_addr *)CMSG_DATA(cmsgp); - - ret = recv_dgram(pi, laddr); - - memcpy(&p->recv_addr, laddr, sizeof(struct in_addr)); - - if (laddr->s_addr == INADDR_ANY) { - msg.msg_control = NULL; - msg.msg_controllen = 0; - } - - return (ret); -} - /* * Port table */ diff --git a/contrib/bsnmp/snmpd/trans_udp.h b/contrib/bsnmp/snmpd/trans_udp.h index ac8ab826015..2f50e2a3956 100644 --- a/contrib/bsnmp/snmpd/trans_udp.h +++ b/contrib/bsnmp/snmpd/trans_udp.h @@ -39,7 +39,9 @@ struct udp_port { struct port_input input; /* common input stuff */ struct sockaddr_in ret; /* the return address */ - struct in_addr recv_addr; /* the address the request was sent to */ + + bool recvdstaddr; /* IP_RECVDSTADDR is on */ + struct in_addr dstaddr; /* address the request was sent to */ }; /* argument for open call */ diff --git a/contrib/mdocml/INSTALL b/contrib/mdocml/INSTALL index 58bef6a7358..115d1600643 100644 --- a/contrib/mdocml/INSTALL +++ b/contrib/mdocml/INSTALL @@ -1,4 +1,4 @@ -$Id: INSTALL,v 1.15 2016/07/14 11:09:06 schwarze Exp $ +$Id: INSTALL,v 1.17 2016/07/19 22:40:33 schwarze Exp $ About mdocml, the portable mandoc distribution ---------------------------------------------- @@ -35,7 +35,11 @@ To install mandoc manually, the following steps are needed: command "echo BUILD_CGI=1 > configure.local". Then run "cp cgi.h.examples cgi.h" and edit cgi.h as desired. -2. Run "./configure". +2. Define MANPATH_DEFAULT in configure.local +if /usr/share/man:/usr/X11R6/man:/usr/local/man is not appropriate +for your operating system. + +3. Run "./configure". This script attempts autoconfiguration of mandoc for your system. Read both its standard output and the file "Makefile.local" it generates. If anything looks wrong or different from what you @@ -45,28 +49,21 @@ result seems right to you. On Solaris 10 and earlier, you may have to run "ksh ./configure" because the native /bin/sh lacks some POSIX features. -3. Run "make". +4. Run "make". Any POSIX-compatible make, in particular both BSD make and GNU make, should work. If the build fails, look at "configure.local.example" and go back to step 2. -4. Run "make -n install" and check whether everything will be +5. Run "make -n install" and check whether everything will be installed to the intended places. Otherwise, put some *DIR or *NM* -variables into "configure.local" and go back to step 2. +variables into "configure.local" and go back to step 3. -5. Run "sudo make install". If you intend to build a binary +6. Run "sudo make install". If you intend to build a binary package using some kind of fake root mechanism, you may need a command like "make DESTDIR=... install". Read the *-install targets in the "Makefile" to understand how DESTDIR is used. -6. If you want to use the integrated man(1) and your system uses -manpath(1), make sure it is configured correctly, in particular, -it returns all directory trees where manual pages are installed. -Otherwise, if your system uses man.conf(5), make sure it contains -a "manpath" line for each directory tree, and the order of these -lines meets your wishes. - -7. If you compiled with database support, run the command "sudo +7. Run the command "sudo makewhatis" to build mandoc.db(5) databases in all the directory trees configured in step 6. Whenever installing new manual pages, re-run makewhatis(8) to update the databases, or apropos(1) will @@ -84,20 +81,9 @@ manual page source. Understanding mandoc dependencies --------------------------------- -The mandoc(1), man(1), and demandoc(1) utilities only depend -on the zlib library for decompressing gzipped manual pages, -but makewhatis(8) and apropos(1) depend on the following -additional software: +The following libraries are required: -1. The SQLite database system, see . -The recommended version of SQLite is 3.8.4.3 or newer. The mandoc -toolset is known to work with version 3.7.5 or newer. Versions -older than 3.8.3 may not achieve full performance due to the -missing SQLITE_DETERMINISTIC optimization flag. Versions older -than 3.8.0 may not show full error information if opening a database -fails due to the missing sqlite3_errstr() API. Both are very minor -problems, apropos(1) is fully usable with SQLite 3.7.5. Versions -older than 3.7.5 may or may not work, they have not been tested. +1. zlib for decompressing gzipped manual pages. 2. The fts(3) directory traversion functions. If your system does not have them, the bundled compatibility version diff --git a/contrib/mdocml/LICENSE b/contrib/mdocml/LICENSE index 57e5656ba73..1dec04b9f4a 100644 --- a/contrib/mdocml/LICENSE +++ b/contrib/mdocml/LICENSE @@ -1,4 +1,4 @@ -$Id: LICENSE,v 1.12 2016/07/07 23:46:36 schwarze Exp $ +$Id: LICENSE,v 1.13 2016/10/18 14:15:33 schwarze Exp $ With the exceptions noted below, all code and documentation contained in the mdocml toolkit is protected by the Copyright @@ -8,7 +8,8 @@ Copyright (c) 2008-2012, 2014 Kristaps Dzonsons Copyright (c) 2010-2016 Ingo Schwarze Copyright (c) 2009, 2010, 2011, 2012 Joerg Sonnenberger Copyright (c) 2013 Franco Fichtner -Copyright (c) 2014 Baptiste Daroussin +Copyright (c) 2014 Baptiste Daroussin +Copyright (c) 2016 Ed Maste Copyright (c) 1999, 2004 Marc Espie Copyright (c) 1998, 2004, 2010 Todd C. Miller Copyright (c) 2008 Otto Moerbeek @@ -41,7 +42,7 @@ other people's Copyright and are distributed under various 2-clause and 3-clause BSD licenses; see these individual files for details. soelim.c, soelim.1: -Copyright (c) 2014 Baptiste Daroussin +Copyright (c) 2014 Baptiste Daroussin compat_err.c, compat_fts.c, compat_fts.h, compat_getsubopt.c, compat_strcasestr.c, compat_strsep.c, diff --git a/contrib/mdocml/Makefile b/contrib/mdocml/Makefile index f76b1376313..5c2657c39a9 100644 --- a/contrib/mdocml/Makefile +++ b/contrib/mdocml/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.488 2016/07/12 05:18:38 kristaps Exp $ +# $Id: Makefile,v 1.493 2016/11/19 15:24:51 schwarze Exp $ # # Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons # Copyright (c) 2011, 2013-2016 Ingo Schwarze @@ -15,27 +15,29 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -VERSION = 1.13.4 +VERSION = 1.14.0 # === LIST OF FILES ==================================================== -TESTSRCS = test-dirent-namlen.c \ +TESTSRCS = test-be32toh.c \ + test-dirent-namlen.c \ + test-EFTYPE.c \ test-err.c \ test-fts.c \ test-getline.c \ test-getsubopt.c \ test-isblank.c \ test-mkdtemp.c \ - test-mmap.c \ + test-nanosleep.c \ + test-ntohl.c \ test-ohash.c \ + test-PATH_MAX.c \ test-pledge.c \ test-progname.c \ test-reallocarray.c \ test-rewb-bsd.c \ test-rewb-sysv.c \ test-sandbox_init.c \ - test-sqlite3.c \ - test-sqlite3_errstr.c \ test-strcasestr.c \ test-stringlist.c \ test-strlcat.c \ @@ -58,7 +60,6 @@ SRCS = att.c \ compat_ohash.c \ compat_progname.c \ compat_reallocarray.c \ - compat_sqlite3_errstr.c \ compat_strcasestr.c \ compat_stringlist.c \ compat_strlcat.c \ @@ -66,6 +67,12 @@ SRCS = att.c \ compat_strsep.c \ compat_strtonum.c \ compat_vasprintf.c \ + dba.c \ + dba_array.c \ + dba_read.c \ + dba_write.c \ + dbm.c \ + dbm_map.c \ demandoc.c \ eqn.c \ eqn_html.c \ @@ -86,7 +93,6 @@ SRCS = att.c \ manpage.c \ manpath.c \ mansearch.c \ - mansearch_const.c \ mdoc.c \ mdoc_argv.c \ mdoc_hash.c \ @@ -128,6 +134,11 @@ DISTFILES = INSTALL \ compat_stringlist.h \ configure \ configure.local.example \ + dba.h \ + dba_array.h \ + dba_write.h \ + dbm.h \ + dbm_map.h \ demandoc.1 \ eqn.7 \ gmdiff \ @@ -220,7 +231,6 @@ COMPAT_OBJS = compat_err.o \ compat_ohash.o \ compat_progname.o \ compat_reallocarray.o \ - compat_sqlite3_errstr.o \ compat_strcasestr.o \ compat_strlcat.o \ compat_strlcpy.o \ @@ -244,28 +254,35 @@ MANDOC_TERM_OBJS = eqn_term.o \ term_ps.o \ tbl_term.o -BASE_OBJS = $(MANDOC_HTML_OBJS) \ +DBM_OBJS = dbm.o \ + dbm_map.o \ + mansearch.o + +DBA_OBJS = dba.o \ + dba_array.o \ + dba_read.o \ + dba_write.o \ + mandocdb.o + +MAIN_OBJS = $(MANDOC_HTML_OBJS) \ $(MANDOC_MAN_OBJS) \ $(MANDOC_TERM_OBJS) \ + $(DBM_OBJS) \ + $(DBA_OBJS) \ main.o \ manpath.o \ out.o \ tag.o \ tree.o -MAIN_OBJS = $(BASE_OBJS) - -DB_OBJS = mandocdb.o \ - mansearch.o \ - mansearch_const.o - CGI_OBJS = $(MANDOC_HTML_OBJS) \ + $(DBM_OBJS) \ cgi.o \ - mansearch.o \ - mansearch_const.o \ out.o -MANPAGE_OBJS = manpage.o mansearch.o mansearch_const.o manpath.o +MANPAGE_OBJS = $(DBM_OBJS) \ + manpage.o \ + manpath.o DEMANDOC_OBJS = demandoc.o @@ -329,7 +346,7 @@ www: $(WWW_OBJS) $(WWW_MANS) $(WWW_MANS): mandoc -.PHONY: base-install cgi-install db-install install www-install +.PHONY: base-install cgi-install install www-install .PHONY: clean distclean depend include Makefile.depend @@ -341,7 +358,7 @@ distclean: clean clean: rm -f libmandoc.a $(LIBMANDOC_OBJS) $(COMPAT_OBJS) - rm -f mandoc $(BASE_OBJS) $(DB_OBJS) + rm -f mandoc $(MAIN_OBJS) rm -f man.cgi $(CGI_OBJS) rm -f manpage $(MANPAGE_OBJS) rm -f demandoc $(DEMANDOC_OBJS) @@ -351,50 +368,45 @@ clean: base-install: base-build mkdir -p $(DESTDIR)$(BINDIR) - mkdir -p $(DESTDIR)$(LIBDIR) - mkdir -p $(DESTDIR)$(INCLUDEDIR) + mkdir -p $(DESTDIR)$(SBINDIR) mkdir -p $(DESTDIR)$(MANDIR)/man1 - mkdir -p $(DESTDIR)$(MANDIR)/man3 mkdir -p $(DESTDIR)$(MANDIR)/man5 mkdir -p $(DESTDIR)$(MANDIR)/man7 + mkdir -p $(DESTDIR)$(MANDIR)/man8 $(INSTALL_PROGRAM) mandoc demandoc $(DESTDIR)$(BINDIR) $(INSTALL_PROGRAM) soelim $(DESTDIR)$(BINDIR)/$(BINM_SOELIM) ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_MAN) - $(INSTALL_LIB) libmandoc.a $(DESTDIR)$(LIBDIR) - $(INSTALL_LIB) man.h mandoc.h mandoc_aux.h mdoc.h roff.h \ - $(DESTDIR)$(INCLUDEDIR) + ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_APROPOS) + ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_WHATIS) + ln -f $(DESTDIR)$(BINDIR)/mandoc \ + $(DESTDIR)$(SBINDIR)/$(BINM_MAKEWHATIS) $(INSTALL_MAN) mandoc.1 demandoc.1 $(DESTDIR)$(MANDIR)/man1 $(INSTALL_MAN) soelim.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_SOELIM).1 $(INSTALL_MAN) man.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_MAN).1 - $(INSTALL_MAN) mandoc.3 mandoc_escape.3 mandoc_malloc.3 \ - mchars_alloc.3 tbl.3 $(DESTDIR)$(MANDIR)/man3 + $(INSTALL_MAN) apropos.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1 + ln -f $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1 \ + $(DESTDIR)$(MANDIR)/man1/$(BINM_WHATIS).1 $(INSTALL_MAN) man.conf.5 $(DESTDIR)$(MANDIR)/man5/${MANM_MANCONF}.5 + $(INSTALL_MAN) mandoc.db.5 $(DESTDIR)$(MANDIR)/man5 $(INSTALL_MAN) man.7 $(DESTDIR)$(MANDIR)/man7/${MANM_MAN}.7 $(INSTALL_MAN) mdoc.7 $(DESTDIR)$(MANDIR)/man7/${MANM_MDOC}.7 $(INSTALL_MAN) roff.7 $(DESTDIR)$(MANDIR)/man7/${MANM_ROFF}.7 $(INSTALL_MAN) eqn.7 $(DESTDIR)$(MANDIR)/man7/${MANM_EQN}.7 $(INSTALL_MAN) tbl.7 $(DESTDIR)$(MANDIR)/man7/${MANM_TBL}.7 $(INSTALL_MAN) mandoc_char.7 $(DESTDIR)$(MANDIR)/man7 - -db-install: base-build - mkdir -p $(DESTDIR)$(BINDIR) - mkdir -p $(DESTDIR)$(SBINDIR) - mkdir -p $(DESTDIR)$(MANDIR)/man1 - mkdir -p $(DESTDIR)$(MANDIR)/man3 - mkdir -p $(DESTDIR)$(MANDIR)/man5 - mkdir -p $(DESTDIR)$(MANDIR)/man8 - ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_APROPOS) - ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_WHATIS) - ln -f $(DESTDIR)$(BINDIR)/mandoc \ - $(DESTDIR)$(SBINDIR)/$(BINM_MAKEWHATIS) - $(INSTALL_MAN) apropos.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1 - ln -f $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1 \ - $(DESTDIR)$(MANDIR)/man1/$(BINM_WHATIS).1 - $(INSTALL_MAN) mansearch.3 $(DESTDIR)$(MANDIR)/man3 - $(INSTALL_MAN) mandoc.db.5 $(DESTDIR)$(MANDIR)/man5 $(INSTALL_MAN) makewhatis.8 \ $(DESTDIR)$(MANDIR)/man8/$(BINM_MAKEWHATIS).8 +lib-install: base-build + mkdir -p $(DESTDIR)$(LIBDIR) + mkdir -p $(DESTDIR)$(INCLUDEDIR) + mkdir -p $(DESTDIR)$(MANDIR)/man3 + $(INSTALL_LIB) libmandoc.a $(DESTDIR)$(LIBDIR) + $(INSTALL_LIB) man.h mandoc.h mandoc_aux.h mdoc.h roff.h \ + $(DESTDIR)$(INCLUDEDIR) + $(INSTALL_MAN) mandoc.3 mandoc_escape.3 mandoc_malloc.3 \ + mansearch.3 mchars_alloc.3 tbl.3 $(DESTDIR)$(MANDIR)/man3 + cgi-install: cgi-build mkdir -p $(DESTDIR)$(CGIBINDIR) mkdir -p $(DESTDIR)$(HTDOCDIR) diff --git a/contrib/mdocml/Makefile.depend b/contrib/mdocml/Makefile.depend index 98a1928b7a9..af1255defdf 100644 --- a/contrib/mdocml/Makefile.depend +++ b/contrib/mdocml/Makefile.depend @@ -10,7 +10,6 @@ compat_mkdtemp.o: compat_mkdtemp.c config.h compat_ohash.o: compat_ohash.c config.h compat_ohash.h compat_progname.o: compat_progname.c config.h compat_reallocarray.o: compat_reallocarray.c config.h -compat_sqlite3_errstr.o: compat_sqlite3_errstr.c config.h compat_strcasestr.o: compat_strcasestr.c config.h compat_stringlist.o: compat_stringlist.c config.h compat_stringlist.h compat_strlcat.o: compat_strlcat.c config.h @@ -18,6 +17,12 @@ compat_strlcpy.o: compat_strlcpy.c config.h compat_strsep.o: compat_strsep.c config.h compat_strtonum.o: compat_strtonum.c config.h compat_vasprintf.o: compat_vasprintf.c config.h +dba.o: dba.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mansearch.h dba_write.h dba_array.h dba.h +dba_array.o: dba_array.c mandoc_aux.h dba_write.h dba_array.h +dba_read.o: dba_read.c mandoc_aux.h mansearch.h dba_array.h dba.h dbm.h +dba_write.o: dba_write.c config.h dba_write.h +dbm.o: dbm.c config.h mansearch.h dbm_map.h dbm.h +dbm_map.o: dbm_map.c config.h mansearch.h dbm_map.h dbm.h demandoc.o: demandoc.c config.h roff.h man.h mdoc.h mandoc.h eqn.o: eqn.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h eqn_html.o: eqn_html.c config.h mandoc.h out.h html.h @@ -26,7 +31,7 @@ html.o: html.c config.h mandoc.h mandoc_aux.h out.h html.h manconf.h main.h lib.o: lib.c config.h roff.h mdoc.h libmdoc.h lib.in main.o: main.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h tag.h main.h manconf.h mansearch.h man.o: man.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h -man_hash.o: man_hash.c config.h roff.h man.h libman.h +man_hash.o: man_hash.c config.h mandoc.h roff.h man.h libmandoc.h libman.h man_html.o: man_html.c config.h mandoc_aux.h roff.h man.h out.h html.h main.h man_macro.o: man_macro.c config.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h man_term.o: man_term.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h term.h main.h @@ -34,14 +39,13 @@ man_validate.o: man_validate.c config.h mandoc_aux.h mandoc.h roff.h man.h libma mandoc.o: mandoc.c config.h mandoc.h mandoc_aux.h libmandoc.h mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h mandoc_ohash.o: mandoc_ohash.c mandoc_aux.h mandoc_ohash.h compat_ohash.h -mandocdb.o: mandocdb.c config.h compat_fts.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h mdoc.h man.h manconf.h mansearch.h +mandocdb.o: mandocdb.c config.h compat_fts.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h mdoc.h man.h manconf.h mansearch.h dba_array.h dba.h manpage.o: manpage.c config.h manconf.h mansearch.h manpath.o: manpath.c config.h mandoc_aux.h manconf.h -mansearch.o: mansearch.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h manconf.h mansearch.h -mansearch_const.o: mansearch_const.c config.h mansearch.h +mansearch.o: mansearch.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h manconf.h mansearch.h dbm.h mdoc.o: mdoc.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h -mdoc_argv.o: mdoc_argv.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h libmdoc.h -mdoc_hash.o: mdoc_hash.c config.h roff.h mdoc.h libmdoc.h +mdoc_argv.o: mdoc_argv.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h +mdoc_hash.o: mdoc_hash.c config.h mandoc.h roff.h mdoc.h libmandoc.h libmdoc.h mdoc_html.o: mdoc_html.c config.h mandoc_aux.h roff.h mdoc.h out.h html.h main.h mdoc_macro.o: mdoc_macro.c config.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h mdoc_man.o: mdoc_man.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h out.h main.h diff --git a/contrib/mdocml/TODO b/contrib/mdocml/TODO index 99a16a9e62a..181c43100ab 100644 --- a/contrib/mdocml/TODO +++ b/contrib/mdocml/TODO @@ -1,6 +1,6 @@ ************************************************************************ * Official mandoc TODO. -* $Id: TODO,v 1.218 2016/06/05 21:06:04 schwarze Exp $ +* $Id: TODO,v 1.223 2017/01/17 15:32:43 schwarze Exp $ ************************************************************************ Many issues are annotated for difficulty as follows: @@ -32,15 +32,6 @@ Many issues are annotated for difficulty as follows: Obviously, as the issues have not been solved yet, these annotations are mere guesses, and some may be wrong. -************************************************************************ -* crashes -************************************************************************ - -- The abort() in bufcat(), html.c, can be triggered via buffmt_includes() - by running -Thtml -Oincludes on a file containing a long .In argument. - Fixing this will probably require reworking the whole bufcat() concept. - loc ** exist * algo * size ** imp ** - ************************************************************************ * missing features ************************************************************************ @@ -213,6 +204,13 @@ are mere guesses, and some may be wrong. synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400 loc ** exist ** algo ** size ** imp *** +- break long text into lines inside cells + net/lftp(1) from jirib via bentley@ Sep 13, 2016 + +- layout l1 for a column of max text width 3 reduces the following + inter-column spacing for groff, but not for mandoc + net/lftp(1) from jirib via bentley@ Sep 13, 2016 + - the "w" layout option is ignored synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400 loc * exist * algo * size * imp ** @@ -528,16 +526,6 @@ are mere guesses, and some may be wrong. in dig(1). loc ** exist ** algo ** size * imp ** -************************************************************************ -* portability -************************************************************************ - -- systems having UTF-8 but not en_US.UTF-8 - call locale(1) from ./configure, select a UTF-8-locale, - and use that for test-wchar.c and term_ascii.c - to Markus Waldeck Sat, 18 Jul 2015 01:55:37 +0200 - loc * exist * algo * size * imp * - ************************************************************************ * warning issues ************************************************************************ @@ -612,7 +600,6 @@ are mere guesses, and some may be wrong. ************************************************************************ - Why are we using MAP_SHARED, not MAP_PRIVATE for mmap(2)? - How does SQLITE_CONFIG_PAGECACHE actually work? Document it! from kristaps@ Sat, 09 Aug 2014 13:51:36 +0200 Several areas can be cleaned up to make mandoc even faster. These are @@ -631,6 +618,13 @@ Several areas can be cleaned up to make mandoc even faster. These are * structural issues ************************************************************************ +- POSIX says in the documentation of sysconf(3) that PATH_MAX + is allowed to be so large that it is a bad idea to use it + for sizing static buffers. So use dynamic buffers throughout. + See the file test-PATH_MAX.c for details. + Found by Aaron M. Ucko in the GNU Hurd via Bdale Garbee, + https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=829624 + - We use the input line number at several places to distinguish same-line from different-line input. That plainly doesn't work with user-defined macros, leading to random breakage. @@ -646,11 +640,6 @@ Several areas can be cleaned up to make mandoc even faster. These are - struct mparse refactoring Steffen Nurpmeso Thu, 04 Sep 2014 12:50:00 +0200 -- Consider creating some views that will make the database more - readable from the sqlite3 shell. Consider using them to - abstract from the database structure, too. - suggested by espie@ Sat, 19 Apr 2014 14:52:57 +0200 - ************************************************************************ * CGI issues ************************************************************************ diff --git a/contrib/mdocml/cgi.c b/contrib/mdocml/cgi.c index f8497b588d9..06beca3fce5 100644 --- a/contrib/mdocml/cgi.c +++ b/contrib/mdocml/cgi.c @@ -1,7 +1,7 @@ -/* $Id: cgi.c,v 1.135 2016/07/11 22:48:37 schwarze Exp $ */ +/* $Id: cgi.c,v 1.144 2017/01/21 01:20:31 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons - * Copyright (c) 2014, 2015, 2016 Ingo Schwarze + * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -113,17 +113,18 @@ static const char *const sec_names[] = { static const int sec_MAX = sizeof(sec_names) / sizeof(char *); static const char *const arch_names[] = { - "amd64", "alpha", "armish", "armv7", - "hppa", "hppa64", "i386", "landisk", + "amd64", "alpha", "armv7", + "hppa", "i386", "landisk", "loongson", "luna88k", "macppc", "mips64", - "octeon", "sgi", "socppc", "sparc", - "sparc64", "zaurus", - "amiga", "arc", "arm32", "atari", - "aviion", "beagle", "cats", "hp300", + "octeon", "sgi", "socppc", "sparc64", + "amiga", "arc", "armish", "arm32", + "atari", "aviion", "beagle", "cats", + "hppa64", "hp300", "ia64", "mac68k", "mvme68k", "mvme88k", "mvmeppc", "palm", "pc532", "pegasos", - "pmax", "powerpc", "solbourne", "sun3", - "vax", "wgrisc", "x68k" + "pmax", "powerpc", "solbourne", "sparc", + "sun3", "vax", "wgrisc", "x68k", + "zaurus" }; static const int arch_MAX = sizeof(arch_names) / sizeof(char *); @@ -137,7 +138,7 @@ html_putchar(char c) switch (c) { case ('"'): - printf(""e;"); + printf("""); break; case ('&'): printf("&"); @@ -337,6 +338,7 @@ resp_copy(const char *filename) fflush(stdout); while ((sz = read(fd, buf, sizeof(buf))) > 0) write(STDOUT_FILENO, buf, sz); + close(fd); } } @@ -349,13 +351,12 @@ resp_begin_html(int code, const char *msg) printf("\n" "\n" "\n" - "\n" - "\n" + " \n" - "%s\n" + " %s\n" "\n" - "\n" - "\n", + "\n", CSS_DIR, CUSTOMIZE_TITLE); resp_copy(MAN_DIR "/header.html"); @@ -376,16 +377,14 @@ resp_searchform(const struct req *req, enum focus focus) { int i; - puts(""); - printf("
\n" - "
\n" - "
\n" - "Manual Page Search Parameters\n", + printf("\n" + "
\n" + " Manual Page Search Parameters\n", scriptname); /* Write query input box. */ - printf("q.query != NULL) html_print(req->q.query); printf( "\" size=\"40\""); @@ -395,45 +394,46 @@ resp_searchform(const struct req *req, enum focus focus) /* Write submission buttons. */ - printf( "\n" - "\n
\n"); + " \n" + "
\n"); /* Write section selector. */ - puts(""); for (i = 0; i < sec_MAX; i++) { - printf("\n", sec_names[i]); } - puts(""); + puts(" "); /* Write architecture selector. */ - printf( ""); + puts(" "); /* Write manpath selector. */ if (req->psz > 1) { - puts(""); for (i = 0; i < (int)req->psz; i++) { - printf(""); } - puts(""); + puts(" "); } - puts("
\n" - "\n" - "
"); - puts(""); + puts(" \n" + ""); } static int @@ -496,9 +494,9 @@ pg_index(const struct req *req) resp_searchform(req, FOCUS_QUERY); printf("

\n" "This web interface is documented in the\n" - "man.cgi(8)\n" + "man.cgi(8)\n" "manual, and the\n" - "apropos(1)\n" + "apropos(1)\n" "manual explains the query syntax.\n" "

\n", scriptname, *scriptname == '\0' ? "" : "/", @@ -578,27 +576,21 @@ pg_searchres(const struct req *req, struct manpage *r, size_t sz) req->q.equal || sz == 1 ? FOCUS_NONE : FOCUS_QUERY); if (sz > 1) { - puts("
"); - puts(""); - + puts("
"); for (i = 0; i < sz; i++) { - printf("\n" - "\n" - "\n" + " \n" - ""); + puts("\n" + " "); } - - puts("
\n" - "\n" + " " + "", scriptname, *scriptname == '\0' ? "" : "/", req->q.manpath, r[i].file); - printf("\">"); html_print(r[i].names); - printf("\n" - ""); + printf(""); html_print(r[i].output); - puts("
\n" - "
"); + puts(""); } /* @@ -800,7 +792,8 @@ resp_format(const struct req *req, const char *file) } mchars_alloc(); - mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, req->q.manpath); + mp = mparse_alloc(MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1, + MANDOCLEVEL_BADARG, NULL, req->q.manpath); mparse_readfd(mp, fd, file); close(fd); diff --git a/contrib/mdocml/compat_fts.c b/contrib/mdocml/compat_fts.c index ed95854666a..c2cc9570c54 100644 --- a/contrib/mdocml/compat_fts.c +++ b/contrib/mdocml/compat_fts.c @@ -6,8 +6,8 @@ int dummy; #else -/* $Id: compat_fts.c,v 1.9 2015/03/18 19:29:48 schwarze Exp $ */ -/* $OpenBSD: fts.c,v 1.50 2015/01/16 16:48:51 deraadt Exp $ */ +/* $Id: compat_fts.c,v 1.12 2016/10/18 23:58:12 schwarze Exp $ */ +/* $OpenBSD: fts.c,v 1.56 2016/09/21 04:38:56 guenther Exp $ */ /*- * Copyright (c) 1990, 1993, 1994 @@ -59,6 +59,7 @@ static void fts_load(FTS *, FTSENT *); static size_t fts_maxarglen(char * const *); static void fts_padjust(FTS *, FTSENT *); static int fts_palloc(FTS *, size_t); +static FTSENT *fts_sort(FTS *, FTSENT *, int); static unsigned short fts_stat(FTS *, FTSENT *); #define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) @@ -68,19 +69,22 @@ static unsigned short fts_stat(FTS *, FTSENT *); #ifndef O_CLOEXEC #define O_CLOEXEC 0 #endif +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif #define CLR(opt) (sp->fts_options &= ~(opt)) #define ISSET(opt) (sp->fts_options & (opt)) #define SET(opt) (sp->fts_options |= (opt)) FTS * -fts_open(char * const *argv, int options, void *dummy) +fts_open(char * const *argv, int options, + int (*compar)(const FTSENT **, const FTSENT **)) { FTS *sp; FTSENT *p, *root; int nitems; FTSENT *parent, *tmp; - size_t len; /* Options check. */ if (options & ~FTS_OPTIONMASK) { @@ -88,9 +92,16 @@ fts_open(char * const *argv, int options, void *dummy) return (NULL); } + /* At least one path must be specified. */ + if (*argv == NULL) { + errno = EINVAL; + return (NULL); + } + /* Allocate/initialize the stream */ if ((sp = calloc(1, sizeof(FTS))) == NULL) return (NULL); + sp->fts_compar = compar; sp->fts_options = options; /* @@ -107,13 +118,7 @@ fts_open(char * const *argv, int options, void *dummy) /* Allocate/initialize root(s). */ for (root = NULL, nitems = 0; *argv; ++argv, ++nitems) { - /* Don't allow zero-length paths. */ - if ((len = strlen(*argv)) == 0) { - errno = ENOENT; - goto mem3; - } - - if ((p = fts_alloc(sp, *argv, len)) == NULL) + if ((p = fts_alloc(sp, *argv, strlen(*argv))) == NULL) goto mem3; p->fts_level = FTS_ROOTLEVEL; p->fts_parent = parent; @@ -124,14 +129,25 @@ fts_open(char * const *argv, int options, void *dummy) if (p->fts_info == FTS_DOT) p->fts_info = FTS_D; - p->fts_link = NULL; - if (root == NULL) - tmp = root = p; - else { - tmp->fts_link = p; - tmp = p; + /* + * If comparison routine supplied, traverse in sorted + * order; otherwise traverse in the order specified. + */ + if (compar) { + p->fts_link = root; + root = p; + } else { + p->fts_link = NULL; + if (root == NULL) + tmp = root = p; + else { + tmp->fts_link = p; + tmp = p; + } } } + if (compar && nitems > 1) + root = fts_sort(sp, root, nitems); /* * Allocate a dummy pointer and make fts_read think that we've just @@ -201,6 +217,7 @@ fts_close(FTS *sp) /* Free up child linked list, sort array, path buffer, stream ptr.*/ if (sp->fts_child) fts_lfree(sp->fts_child); + free(sp->fts_array); free(sp->fts_path); free(sp); @@ -317,7 +334,6 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent); * semantics to fts using fts_set. An error return is allowed for similar * reasons. */ -/* ARGSUSED */ int fts_set(FTS *sp, FTSENT *p, int instr) { @@ -416,8 +432,7 @@ fts_build(FTS *sp) * structures already allocated. */ mem1: saved_errno = errno; - if (p) - free(p); + free(p); fts_lfree(head); (void)closedir(dirp); cur->fts_info = FTS_ERR; @@ -490,6 +505,10 @@ mem1: saved_errno = errno; cur->fts_info = FTS_DP; return (NULL); } + + /* Sort the entries. */ + if (sp->fts_compar && nitems > 1) + head = fts_sort(sp, head, nitems); return (head); } @@ -546,6 +565,40 @@ fts_stat(FTS *sp, FTSENT *p) return (FTS_DEFAULT); } +static FTSENT * +fts_sort(FTS *sp, FTSENT *head, int nitems) +{ + FTSENT **ap, *p; + + /* + * Construct an array of pointers to the structures and call qsort(3). + * Reassemble the array in the order returned by qsort. If unable to + * sort for memory reasons, return the directory entries in their + * current order. Allocate enough space for the current needs plus + * 40 so don't realloc one entry at a time. + */ + if (nitems > sp->fts_nitems) { + struct _ftsent **a; + + sp->fts_nitems = nitems + 40; + if ((a = reallocarray(sp->fts_array, + sp->fts_nitems, sizeof(FTSENT *))) == NULL) { + free(sp->fts_array); + sp->fts_array = NULL; + sp->fts_nitems = 0; + return (head); + } + sp->fts_array = a; + } + for (ap = sp->fts_array, p = head; p; p = p->fts_link) + *ap++ = p; + qsort(sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar); + for (head = *(ap = sp->fts_array); --nitems; ++ap) + ap[0]->fts_link = ap[1]; + ap[0]->fts_link = NULL; + return (head); +} + static FTSENT * fts_alloc(FTS *sp, const char *name, size_t namelen) { @@ -597,8 +650,7 @@ fts_palloc(FTS *sp, size_t more) */ more += 256; if (sp->fts_pathlen + more < sp->fts_pathlen) { - if (sp->fts_path) - free(sp->fts_path); + free(sp->fts_path); sp->fts_path = NULL; errno = ENAMETOOLONG; return (1); @@ -606,8 +658,7 @@ fts_palloc(FTS *sp, size_t more) sp->fts_pathlen += more; p = realloc(sp->fts_path, sp->fts_pathlen); if (p == NULL) { - if (sp->fts_path) - free(sp->fts_path); + free(sp->fts_path); sp->fts_path = NULL; return (1); } diff --git a/contrib/mdocml/compat_fts.h b/contrib/mdocml/compat_fts.h index 1eed2ae380f..f4a97a4c3a5 100644 --- a/contrib/mdocml/compat_fts.h +++ b/contrib/mdocml/compat_fts.h @@ -38,9 +38,12 @@ typedef struct { struct _ftsent *fts_cur; /* current node */ struct _ftsent *fts_child; /* linked list of children */ + struct _ftsent **fts_array; /* sort array */ dev_t fts_dev; /* starting device # */ char *fts_path; /* path for this descent */ size_t fts_pathlen; /* sizeof(path) */ + int fts_nitems; /* elements in the sort array */ + int (*fts_compar)(); /* compare function */ #define FTS_NOCHDIR 0x0004 /* don't change directories */ #define FTS_PHYSICAL 0x0010 /* physical walk */ @@ -94,7 +97,8 @@ typedef struct _ftsent { int fts_close(FTS *); -FTS *fts_open(char * const *, int, void *); +FTS *fts_open(char * const *, int, + int (*)(const FTSENT **, const FTSENT **)); FTSENT *fts_read(FTS *); int fts_set(FTS *, FTSENT *, int); diff --git a/contrib/mdocml/compat_sqlite3_errstr.c b/contrib/mdocml/compat_sqlite3_errstr.c deleted file mode 100644 index 8a6ace28e8c..00000000000 --- a/contrib/mdocml/compat_sqlite3_errstr.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "config.h" - -#if HAVE_SQLITE3_ERRSTR - -int dummy; - -#else - -const char * -sqlite3_errstr(int rc) -{ - - return rc ? "unknown error" : "not an error"; -} - -#endif diff --git a/contrib/mdocml/config.h b/contrib/mdocml/config.h index 6252b8acb1f..22b9a38dca3 100644 --- a/contrib/mdocml/config.h +++ b/contrib/mdocml/config.h @@ -2,30 +2,33 @@ #error "Do not use C++. See the INSTALL file." #endif -#ifndef MANDOC_CONFIG_H -#define MANDOC_CONFIG_H +#if !defined(__GNUC__) || (__GNUC__ < 4) +#define __attribute__(x) +#endif #if defined(__linux__) || defined(__MINT__) #define _GNU_SOURCE /* See test-*.c what needs this. */ #endif -#include -#include #define MAN_CONF_FILE "/etc/man.conf" +#define MANPATH_DEFAULT "/usr/share/man:/usr/local/man" +#define UTF8_LOCALE "en_US.UTF-8" #define HAVE_DIRENT_NAMLEN 1 +#define HAVE_ENDIAN 0 #define HAVE_ERR 1 #define HAVE_FTS 1 #define HAVE_GETLINE 1 #define HAVE_GETSUBOPT 1 #define HAVE_ISBLANK 1 #define HAVE_MKDTEMP 1 -#define HAVE_MMAP 1 +#define HAVE_NTOHL 1 #define HAVE_PLEDGE 0 #define HAVE_PROGNAME 1 #define HAVE_REALLOCARRAY 1 -#define HAVE_REWB_BSD 0 -#define HAVE_REWB_SYSV 0 +#define HAVE_REWB_BSD 1 +#define HAVE_REWB_SYSV 1 +#define HAVE_SANDBOX_INIT 0 #define HAVE_STRCASESTR 1 #define HAVE_STRINGLIST 1 #define HAVE_STRLCAT 1 @@ -33,20 +36,14 @@ #define HAVE_STRPTIME 1 #define HAVE_STRSEP 1 #define HAVE_STRTONUM 1 +#define HAVE_SYS_ENDIAN 1 #define HAVE_VASPRINTF 1 #define HAVE_WCHAR 1 -#define HAVE_SQLITE3 1 -#define HAVE_SQLITE3_ERRSTR 0 #define HAVE_OHASH 1 -#define HAVE_MANPATH 1 +#define HAVE_FTS_COMPARE_CONST 1 #define BINM_APROPOS "apropos" #define BINM_MAKEWHATIS "makewhatis" #define BINM_MAN "man" #define BINM_SOELIM "soelim" #define BINM_WHATIS "whatis" - -extern ssize_t getline(char **, size_t *, FILE *); -extern const char *sqlite3_errstr(int); - -#endif /* MANDOC_CONFIG_H */ diff --git a/contrib/mdocml/config.log b/contrib/mdocml/config.log deleted file mode 100644 index 1f7e11600d3..00000000000 --- a/contrib/mdocml/config.log +++ /dev/null @@ -1,210 +0,0 @@ -configure.local: no (fully automatic configuration) - -dirent-namlen: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-dirent-namlen test-dirent-namlen.c -dirent-namlen: cc succeeded -dirent-namlen: yes - -err: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-err test-err.c -err: cc succeeded -test-err: 1. warnx -test-err: 2. warn: No error: 0 -test-err: 3. err: No error: 0 -err: yes - -fts: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-fts test-fts.c -fts: cc succeeded -fts: yes - -getline: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-getline test-getline.c -test-getline.c:12:9: error: implicit declaration of function 'getline' is invalid in C99 [-Werror,-Wimplicit-function-declaration] - return getline(&line, &linesz, stdin) != -1; - ^ -1 error generated. -getline: cc failed with 1 - -getsubopt: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-getsubopt test-getsubopt.c -getsubopt: cc succeeded -getsubopt: yes - -isblank: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-isblank test-isblank.c -isblank: cc succeeded -isblank: yes - -mkdtemp: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-mkdtemp test-mkdtemp.c -mkdtemp: cc succeeded -mkdtemp: yes - -mmap: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-mmap test-mmap.c -mmap: cc succeeded -mmap: yes - -pledge: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-pledge test-pledge.c -test-pledge.c:6:11: error: implicit declaration of function 'pledge' is invalid in C99 [-Werror,-Wimplicit-function-declaration] - return !!pledge("stdio", NULL); - ^ -1 error generated. -pledge: cc failed with 1 - -progname: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-progname test-progname.c -progname: cc succeeded -progname: yes - -reallocarray: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-reallocarray test-reallocarray.c -reallocarray: cc succeeded -reallocarray: yes - -rewb-bsd: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-rewb-bsd test-rewb-bsd.c -test-rewb-bsd.c:11:42: error: use of undeclared identifier 'NULL' - if (regexec(&re, "the word is here", 0, NULL, 0)) - ^ -test-rewb-bsd.c:13:35: error: use of undeclared identifier 'NULL' - if (regexec(&re, "same word", 0, NULL, 0)) - ^ -test-rewb-bsd.c:15:36: error: use of undeclared identifier 'NULL' - if (regexec(&re, "word again", 0, NULL, 0)) - ^ -test-rewb-bsd.c:17:30: error: use of undeclared identifier 'NULL' - if (regexec(&re, "word", 0, NULL, 0)) - ^ -test-rewb-bsd.c:19:31: error: use of undeclared identifier 'NULL' - if (regexec(&re, "wordy", 0, NULL, 0) != REG_NOMATCH) - ^ -test-rewb-bsd.c:21:31: error: use of undeclared identifier 'NULL' - if (regexec(&re, "sword", 0, NULL, 0) != REG_NOMATCH) - ^ -test-rewb-bsd.c:23:34: error: use of undeclared identifier 'NULL' - if (regexec(&re, "reworded", 0, NULL, 0) != REG_NOMATCH) - ^ -7 errors generated. -rewb-bsd: cc failed with 1 - -rewb-sysv: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-rewb-sysv test-rewb-sysv.c -test-rewb-sysv.c:11:42: error: use of undeclared identifier 'NULL' - if (regexec(&re, "the word is here", 0, NULL, 0)) - ^ -test-rewb-sysv.c:13:35: error: use of undeclared identifier 'NULL' - if (regexec(&re, "same word", 0, NULL, 0)) - ^ -test-rewb-sysv.c:15:36: error: use of undeclared identifier 'NULL' - if (regexec(&re, "word again", 0, NULL, 0)) - ^ -test-rewb-sysv.c:17:30: error: use of undeclared identifier 'NULL' - if (regexec(&re, "word", 0, NULL, 0)) - ^ -test-rewb-sysv.c:19:31: error: use of undeclared identifier 'NULL' - if (regexec(&re, "wordy", 0, NULL, 0) != REG_NOMATCH) - ^ -test-rewb-sysv.c:21:31: error: use of undeclared identifier 'NULL' - if (regexec(&re, "sword", 0, NULL, 0) != REG_NOMATCH) - ^ -test-rewb-sysv.c:23:34: error: use of undeclared identifier 'NULL' - if (regexec(&re, "reworded", 0, NULL, 0) != REG_NOMATCH) - ^ -7 errors generated. -rewb-sysv: cc failed with 1 - -strcasestr: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strcasestr test-strcasestr.c -strcasestr: cc succeeded -strcasestr: yes - -stringlist: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-stringlist test-stringlist.c -test-stringlist.c:26:26: error: use of undeclared identifier 'NULL' - if ((sl = sl_init()) == NULL) - ^ -1 error generated. -stringlist: cc failed with 1 - -strlcat: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strlcat test-strlcat.c -strlcat: cc succeeded -strlcat: yes - -strlcpy: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strlcpy test-strlcpy.c -strlcpy: cc succeeded -strlcpy: yes - -strptime: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strptime test-strptime.c -strptime: cc succeeded -strptime: yes - -strsep: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strsep test-strsep.c -strsep: cc succeeded -strsep: yes - -strtonum: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strtonum test-strtonum.c -strtonum: cc succeeded -strtonum: yes - -vasprintf: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-vasprintf test-vasprintf.c -vasprintf: cc succeeded -vasprintf: yes - -wchar: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-wchar test-wchar.c -wchar: cc succeeded -*wchar: yes - -sqlite3: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -lsqlite3 -o test-sqlite3 test-sqlite3.c -test-sqlite3.c:20:10: fatal error: 'sqlite3.h' file not found -#include - ^ -1 error generated. -sqlite3: cc failed with 1 - -sqlite3: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -I/usr/local/include -L/usr/local/lib -lsqlite3 -o test-sqlite3 test-sqlite3.c -sqlite3: cc succeeded -sqlite3: yes - -sqlite3_errstr: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -L/usr/local/lib -lsqlite3 -o test-sqlite3_errstr test-sqlite3_errstr.c -test-sqlite3_errstr.c:2:10: fatal error: 'sqlite3.h' file not found -#include - ^ -1 error generated. -sqlite3_errstr: cc failed with 1 - -ohash: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-ohash test-ohash.c -test-ohash.c:4:10: fatal error: 'ohash.h' file not found -#include - ^ -1 error generated. -ohash: cc failed with 1 - -ohash: testing... -cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -lutil -o test-ohash test-ohash.c -test-ohash.c:4:10: fatal error: 'ohash.h' file not found -#include - ^ -1 error generated. -ohash: cc failed with 1 - -DBLIB="-L/usr/local/lib -lsqlite3 -lz" - -/usr/share/man:/usr/local/man:/usr/share/openssl/man:/usr/local/lib/perl5/site_perl/man:/usr/local/lib/perl5/5.20/perl/man:/usr/local/share/xpdf/man -manpath: yes - -config.h: written -Makefile.local: written diff --git a/contrib/mdocml/configure b/contrib/mdocml/configure index 6f2c4116bf3..1b810158282 100755 --- a/contrib/mdocml/configure +++ b/contrib/mdocml/configure @@ -1,5 +1,7 @@ #!/bin/sh # +# $Id: configure,v 1.55 2017/01/12 15:45:05 schwarze Exp $ +# # Copyright (c) 2014, 2015, 2016 Ingo Schwarze # # Permission to use, copy, modify, and distribute this software for any @@ -33,26 +35,34 @@ echo "config.log: writing..." MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man" OSNAME= +UTF8_LOCALE= -CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | make -f -` -CFLAGS="-g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings" +CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | env -i make -sf -` +CFLAGS="-g -W -Wall -Wmissing-prototypes -Wstrict-prototypes -Wwrite-strings" +CFLAGS="${CFLAGS} -Wno-unused-parameter" LDADD= LDFLAGS= +LD_NANOSLEEP= LD_OHASH= -LD_SQLITE3= STATIC="-static" -BUILD_DB=1 BUILD_CGI=0 +INSTALL_LIBMANDOC=0 HAVE_DIRENT_NAMLEN= +HAVE_EFTYPE= +HAVE_ENDIAN= HAVE_ERR= HAVE_FTS= +HAVE_FTS_COMPARE_CONST= HAVE_GETLINE= HAVE_GETSUBOPT= HAVE_ISBLANK= HAVE_MKDTEMP= -HAVE_MMAP= +HAVE_NANOSLEEP= +HAVE_NTOHL= +HAVE_OHASH= +HAVE_PATH_MAX= HAVE_PLEDGE= HAVE_PROGNAME= HAVE_REALLOCARRAY= @@ -66,14 +76,10 @@ HAVE_STRLCPY= HAVE_STRPTIME= HAVE_STRSEP= HAVE_STRTONUM= +HAVE_SYS_ENDIAN= HAVE_VASPRINTF= HAVE_WCHAR= -HAVE_SQLITE3= -HAVE_SQLITE3_ERRSTR= -HAVE_OHASH= -HAVE_MANPATH= - PREFIX="/usr/local" BINDIR= SBINDIR= @@ -125,9 +131,9 @@ COMP="${CC} ${CFLAGS} -Wno-unused -Werror" # If yes, use the override, if no, do not decide anything yet. # Arguments: lower-case test name, manual value ismanual() { - [ -z "${2}" ] && return 1 - echo "${1}: manual (${2})" 1>&2 - echo "${1}: manual (${2})" 1>&3 + [ -z "${3}" ] && return 1 + echo "${1}: manual (HAVE_${2}=${3})" 1>&2 + echo "${1}: manual (HAVE_${2}=${3})" 1>&3 echo 1>&3 return 0 } @@ -138,27 +144,27 @@ ismanual() { # Arguments: lower-case test name, upper-case test name, additional CFLAGS singletest() { cat 1>&3 << __HEREDOC__ -${1}: testing... -${COMP} ${3} -o test-${1} test-${1}.c +${1}${3}: testing... +${COMP} -o test-${1} test-${1}.c ${3} __HEREDOC__ - if ${COMP} ${3} -o "test-${1}" "test-${1}.c" 1>&3 2>&3; then - echo "${1}: ${CC} succeeded" 1>&3 + if ${COMP} -o "test-${1}" "test-${1}.c" ${3} 1>&3 2>&3; then + echo "${1}${3}: ${CC} succeeded" 1>&3 else - echo "${1}: ${CC} failed with $?" 1>&3 + echo "${1}${3}: ${CC} failed with $?" 1>&3 echo 1>&3 return 1 fi if ./test-${1} 1>&3 2>&3; then - echo "${1}: yes" 1>&2 - echo "${1}: yes" 1>&3 + echo "${1}${3}: yes" 1>&2 + echo "${1}${3}: yes" 1>&3 echo 1>&3 eval HAVE_${2}=1 rm "test-${1}" return 0 else - echo "${1}: execution failed with $?" 1>&3 + echo "${1}${3}: execution failed with $?" 1>&3 echo 1>&3 rm "test-${1}" return 1 @@ -170,22 +176,42 @@ __HEREDOC__ # Arguments: lower case name, upper case name, additional CFLAGS runtest() { eval _manual=\${HAVE_${2}} - ismanual "${1}" "${_manual}" && return 0 + ismanual "${1}" "${2}" "${_manual}" && return 0 singletest "${1}" "${2}" "${3}" && return 0 - echo "${1}: no" 1>&2 + echo "${1}${3}: no" 1>&2 eval HAVE_${2}=0 return 1 } +# Select a UTF-8 locale. +get_locale() { + [ -n "${HAVE_WCHAR}" ] && [ "${HAVE_WCHAR}" -eq 0 ] && return 0 + ismanual UTF8_LOCALE UTF8_LOCALE "$UTF8_LOCALE" && return 0 + echo "UTF8_LOCALE: testing..." 1>&3 + UTF8_LOCALE=`locale -a | grep -i '^en_US\.UTF-*8$' | head -n 1` + if [ -z "${UTF8_LOCALE}" ]; then + UTF8_LOCALE=`locale -a | grep -i '\.UTF-*8' | head -n 1` + [ -n "${UTF8_LOCALE}" ] || return 1 + fi + echo "UTF8_LOCALE=${UTF8_LOCALE}" 1>&2 + echo "UTF8_LOCALE=${UTF8_LOCALE}" 1>&3 + echo 1>&3 + return 0; +} + + # --- library functions --- runtest dirent-namlen DIRENT_NAMLEN || true +runtest be32toh ENDIAN || true +runtest be32toh SYS_ENDIAN -DSYS_ENDIAN || true +runtest EFTYPE EFTYPE || true runtest err ERR || true -runtest fts FTS || true runtest getline GETLINE || true runtest getsubopt GETSUBOPT || true runtest isblank ISBLANK || true runtest mkdtemp MKDTEMP || true -runtest mmap MMAP || true +runtest ntohl NTOHL || true +runtest PATH_MAX PATH_MAX || true runtest pledge PLEDGE || true runtest sandbox_init SANDBOX_INIT || true runtest progname PROGNAME || true @@ -200,48 +226,48 @@ runtest strptime STRPTIME || true runtest strsep STRSEP || true runtest strtonum STRTONUM || true runtest vasprintf VASPRINTF || true -runtest wchar WCHAR || true -# --- sqlite3 --- -if [ ${BUILD_DB} -eq 0 ]; then - echo "BUILD_DB=0 (manual)" 1>&2 - echo "BUILD_DB=0 (manual)" 1>&3 - echo 1>&3 - HAVE_SQLITE3=0 -elif ismanual sqlite3 "${HAVE_SQLITE3}"; then - if [ -z "${LD_SQLITE3}" ]; then - LD_SQLITE3="-lsqlite3" - fi -elif [ -n "${LD_SQLITE3}" ]; then - runtest sqlite3 SQLITE3 "${LD_SQLITE3}" || true -elif singletest sqlite3 SQLITE3 "-lsqlite3"; then - LD_SQLITE3="-lsqlite3" -elif runtest sqlite3 SQLITE3 \ - "-I/usr/local/include -L/usr/local/lib -lsqlite3"; then - LD_SQLITE3="-L/usr/local/lib -lsqlite3" - CFLAGS="${CFLAGS} -I/usr/local/include" -fi -if [ ${HAVE_SQLITE3} -eq 0 ]; then - LD_SQLITE3= - if [ ${BUILD_DB} -gt 0 ]; then - echo "BUILD_DB=0 (no sqlite3)" 1>&2 - echo "BUILD_DB=0 (no sqlite3)" 1>&3 - echo 1>&3 - BUILD_DB=0 - fi +if [ ${HAVE_ENDIAN} -eq 0 -a \ + ${HAVE_SYS_ENDIAN} -eq 0 -a \ + ${HAVE_NTOHL} -eq 0 ]; then + echo "FATAL: no endian conversion functions found" 1>&2 + echo "FATAL: no endian conversion functions found" 1>&3 + exit 1 fi -# --- sqlite3_errstr --- -if [ ${BUILD_DB} -eq 0 ]; then - HAVE_SQLITE3_ERRSTR=1 -elif ismanual sqlite3_errstr "${HAVE_SQLITE3_ERRSTR}"; then - : +if ismanual fts FTS ${HAVE_FTS}; then + HAVE_FTS_COMPARE_CONST=0 +elif runtest fts FTS_COMPARE_CONST -DFTS_COMPARE_CONST; then + HAVE_FTS=1 else - runtest sqlite3_errstr SQLITE3_ERRSTR "${LD_SQLITE3}" || true + runtest fts FTS || true +fi + +# --- wide character and locale support --- +if get_locale; then + runtest wchar WCHAR -DUTF8_LOCALE=\"${UTF8_LOCALE}\" || true +else + HAVE_WCHAR=0 + echo "wchar: no (no UTF8_LOCALE)" 1>&2 + echo "wchar: no (no UTF8_LOCALE)" 1>&3 +fi + +# --- nanosleep --- +if [ -n "${LD_NANOSLEEP}" ]; then + runtest nanosleep NANOSLEEP "${LD_NANOSLEEP}" || true +elif singletest nanosleep NANOSLEEP; then + : +elif runtest nanosleep NANOSLEEP "-lrt"; then + LD_NANOSLEEP="-lrt" +fi +if [ "${HAVE_NANOSLEEP}" -eq 0 ]; then + echo "FATAL: nanosleep: no" 1>&2 + echo "FATAL: nanosleep: no" 1>&3 + exit 1 fi # --- ohash --- -if ismanual ohash "${HAVE_OHASH}"; then +if ismanual ohash OHASH "${HAVE_OHASH}"; then : elif [ -n "${LD_OHASH}" ]; then runtest ohash OHASH "${LD_OHASH}" || true @@ -255,26 +281,11 @@ if [ "${HAVE_OHASH}" -eq 0 ]; then fi # --- LDADD --- -LDADD="${LDADD} ${LD_SQLITE3} ${LD_OHASH} -lz" +LDADD="${LDADD} ${LD_NANOSLEEP} ${LD_OHASH} -lz" echo "LDADD=\"${LDADD}\"" 1>&2 echo "LDADD=\"${LDADD}\"" 1>&3 echo 1>&3 -# --- manpath --- -if ismanual manpath "${HAVE_MANPATH}"; then - : -elif manpath 1>&3 2>&3; then - echo "manpath: yes" 1>&2 - echo "manpath: yes" 1>&3 - echo 1>&3 - HAVE_MANPATH=1 -else - echo "manpath: no" 1>&2 - echo "manpath: no" 1>&3 - echo 1>&3 - HAVE_MANPATH=0 -fi - # --- write config.h --- exec > config.h @@ -284,8 +295,9 @@ cat << __HEREDOC__ #error "Do not use C++. See the INSTALL file." #endif -#ifndef MANDOC_CONFIG_H -#define MANDOC_CONFIG_H +#if !defined(__GNUC__) || (__GNUC__ < 4) +#define __attribute__(x) +#endif #if defined(__linux__) || defined(__MINT__) #define _GNU_SOURCE /* See test-*.c what needs this. */ @@ -303,17 +315,26 @@ echo echo "#define MAN_CONF_FILE \"/etc/${MANM_MANCONF}\"" echo "#define MANPATH_DEFAULT \"${MANPATH_DEFAULT}\"" [ -n "${OSNAME}" ] && echo "#define OSNAME \"${OSNAME}\"" +[ -n "${UTF8_LOCALE}" ] && echo "#define UTF8_LOCALE \"${UTF8_LOCALE}\"" [ -n "${HOMEBREWDIR}" ] && echo "#define HOMEBREWDIR \"${HOMEBREWDIR}\"" +[ ${HAVE_EFTYPE} -eq 0 ] && echo "#define EFTYPE EINVAL" +[ ${HAVE_PATH_MAX} -eq 0 ] && echo "#define PATH_MAX 4096" +if [ ${HAVE_ENDIAN} -eq 0 -a ${HAVE_SYS_ENDIAN} -eq 0 ]; then + echo "#define be32toh ntohl" + echo "#define htobe32 htonl" +fi cat << __HEREDOC__ #define HAVE_DIRENT_NAMLEN ${HAVE_DIRENT_NAMLEN} +#define HAVE_ENDIAN ${HAVE_ENDIAN} #define HAVE_ERR ${HAVE_ERR} #define HAVE_FTS ${HAVE_FTS} +#define HAVE_FTS_COMPARE_CONST ${HAVE_FTS_COMPARE_CONST} #define HAVE_GETLINE ${HAVE_GETLINE} #define HAVE_GETSUBOPT ${HAVE_GETSUBOPT} #define HAVE_ISBLANK ${HAVE_ISBLANK} #define HAVE_MKDTEMP ${HAVE_MKDTEMP} -#define HAVE_MMAP ${HAVE_MMAP} +#define HAVE_NTOHL ${HAVE_NTOHL} #define HAVE_PLEDGE ${HAVE_PLEDGE} #define HAVE_PROGNAME ${HAVE_PROGNAME} #define HAVE_REALLOCARRAY ${HAVE_REALLOCARRAY} @@ -327,12 +348,10 @@ cat << __HEREDOC__ #define HAVE_STRPTIME ${HAVE_STRPTIME} #define HAVE_STRSEP ${HAVE_STRSEP} #define HAVE_STRTONUM ${HAVE_STRTONUM} +#define HAVE_SYS_ENDIAN ${HAVE_SYS_ENDIAN} #define HAVE_VASPRINTF ${HAVE_VASPRINTF} #define HAVE_WCHAR ${HAVE_WCHAR} -#define HAVE_SQLITE3 ${HAVE_SQLITE3} -#define HAVE_SQLITE3_ERRSTR ${HAVE_SQLITE3_ERRSTR} #define HAVE_OHASH ${HAVE_OHASH} -#define HAVE_MANPATH ${HAVE_MANPATH} #define BINM_APROPOS "${BINM_APROPOS}" #define BINM_MAKEWHATIS "${BINM_MAKEWHATIS}" @@ -369,9 +388,6 @@ fi [ ${HAVE_REALLOCARRAY} -eq 0 ] && \ echo "extern void *reallocarray(void *, size_t, size_t);" -[ ${BUILD_DB} -gt 0 -a ${HAVE_SQLITE3_ERRSTR} -eq 0 ] && - echo "extern const char *sqlite3_errstr(int);" - [ ${HAVE_STRCASESTR} -eq 0 ] && \ echo "extern char *strcasestr(const char *, const char *);" @@ -390,9 +406,6 @@ fi [ ${HAVE_VASPRINTF} -eq 0 ] && \ echo "extern int vasprintf(char **, const char *, va_list);" -echo -echo "#endif /* MANDOC_CONFIG_H */" - echo "config.h: written" 1>&2 echo "config.h: written" 1>&3 @@ -414,16 +427,10 @@ exec > Makefile.local [ -z "${INSTALL_MAN}" ] && INSTALL_MAN="${INSTALL} -m 0444" [ -z "${INSTALL_DATA}" ] && INSTALL_DATA="${INSTALL} -m 0444" -if [ ${BUILD_DB} -eq 0 -a ${BUILD_CGI} -gt 0 ]; then - echo "BUILD_CGI=0 (no BUILD_DB)" 1>&2 - echo "BUILD_CGI=0 (no BUILD_DB)" 1>&3 - BUILD_CGI=0 -fi - -BUILD_TARGETS="base-build" -[ ${BUILD_CGI} -gt 0 ] && BUILD_TARGETS="${BUILD_TARGETS} cgi-build" -INSTALL_TARGETS="base-install" -[ ${BUILD_DB} -gt 0 ] && INSTALL_TARGETS="${INSTALL_TARGETS} db-install" +BUILD_TARGETS= +[ ${BUILD_CGI} -gt 0 ] && BUILD_TARGETS="cgi-build" +INSTALL_TARGETS= +[ ${INSTALL_LIBMANDOC} -gt 0 ] && INSTALL_TARGETS="lib-install" [ ${BUILD_CGI} -gt 0 ] && INSTALL_TARGETS="${INSTALL_TARGETS} cgi-install" cat << __HEREDOC__ @@ -461,9 +468,6 @@ INSTALL_MAN = ${INSTALL_MAN} INSTALL_DATA = ${INSTALL_DATA} __HEREDOC__ -[ ${BUILD_DB} -gt 0 ] && \ - echo "MAIN_OBJS = \$(BASE_OBJS) \$(DB_OBJS)" - echo "Makefile.local: written" 1>&2 echo "Makefile.local: written" 1>&3 diff --git a/contrib/mdocml/configure.local.example b/contrib/mdocml/configure.local.example index c955a80a386..d5799a5a9e5 100644 --- a/contrib/mdocml/configure.local.example +++ b/contrib/mdocml/configure.local.example @@ -1,4 +1,4 @@ -# $Id: configure.local.example,v 1.13 2016/07/14 11:09:06 schwarze Exp $ +# $Id: configure.local.example,v 1.22 2016/11/19 15:24:51 schwarze Exp $ # # Copyright (c) 2014, 2015, 2016 Ingo Schwarze # @@ -48,10 +48,17 @@ HAVE_WCHAR=1 HAVE_WCHAR=0 +# For -Tutf8 mode, mandoc needs to set an arbitrary locale having +# a UTF-8 character set. If autodetection of a suitable locale +# fails or selects an undesirable locale, you can manually choose +# the locale for -Tutf8 mode: + +UTF8_LOCALE=en_US.UTF-8 + # When man(1) or apropos(1) is called without -m and -M options, -# MANPATH is not set in the environment, man.conf(5) is not available -# and manpath(1) not used, manuals are searched for in the following -# directory trees by default. +# MANPATH is not set in the environment, and man.conf(5) is not +# available, manuals are searched for in the following directory +# trees by default. MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man" @@ -65,7 +72,7 @@ MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man" # If you do not want uname(3) to be called but instead want a fixed # string to be used, use the following line: -OSNAME="OpenBSD 5.9" +OSNAME="OpenBSD 6.0" # The following installation directories are used. # It is possible to set only one or a few of these variables, @@ -76,25 +83,8 @@ OSNAME="OpenBSD 5.9" PREFIX="/usr/local" BINDIR="${PREFIX}/bin" SBINDIR="${PREFIX}/sbin" -INCLUDEDIR="${PREFIX}/include/mandoc" -LIBDIR="${PREFIX}/lib/mandoc" MANDIR="${PREFIX}/man" -# The man(1) utility needs to know where the manuals reside. -# We know of two ways to tell it: via manpath(1) or man.conf(5). -# The latter is used by OpenBSD and NetBSD, the former by most -# other systems. - -# Force usage of manpath(1). -# If it is not installed or not operational, -# man(1), makewhatis(8), and apropos(1) will not work properly. -HAVE_MANPATH=1 - -# Force usage of man.conf(5). -# If it does not exist or contains no valid configuration, -# man(1), makewhatis(8), and apropos(1) will not work properly. -HAVE_MANPATH=0 - # Some distributions may want to avoid naming conflicts # with the configuration files of other man(1) implementations. # This changes the name of the installed section 5 manual page as well. @@ -113,14 +103,20 @@ MANM_ROFF="mandoc_roff" # default is "roff" MANM_EQN="mandoc_eqn" # default is "eqn" MANM_TBL="mandoc_tbl" # default is "tbl" -# Some distributions may want to avoid naming conflicts -# with other man(1) and soelim(1) utilities. +# Some distributions may want to avoid naming conflicts with +# other man(1), apropos(1), makewhatis(8), or soelim(1) utilities. # If you want to change the names of binary programs, # the following alternative names are suggested. # Using different names is possible as well. -# This changes the names of the installed section 1 manual pages as well. +# This changes the names of the installed section 1 and section 8 +# manual pages as well. +# It is possible to set only one or two of these variables, +# there is no need to copy the whole block. BINM_MAN=mman # default is "man" +BINM_APROPOS=mapropos # default is "apropos" +BINM_WHATIS=mwhatis # default is "whatis" +BINM_MAKEWHATIS=mandocdb # default is "makewhatis" BINM_SOELIM=msoelim # default is "soelim" # Before falling back to the bundled version of the ohash(3) hashing @@ -131,11 +127,24 @@ BINM_SOELIM=msoelim # default is "soelim" LD_OHASH="-lutil" -# Some platforms may need additional linker flags to link against libmandoc -# that are not autodetected. -# For example, Solaris 9 and 10 need -lrt for nanosleep(2). +# When library autodetection decides to use -L/usr/local/lib, +# -I/usr/local/include is automatically added to CFLAGS. +# If you manually set LD_OHASH to something including -L/usr/local/lib, +# chances are you will also need the following line: -LDADD="-lrt" +CFLAGS="${CFLAGS} -I/usr/local/include" + +# Some platforms may need an additional linker flag for nanosleep(2). +# If none is needed or it is -lrt, it is autodetected. +# Otherwise, set the following variable. + +LD_NANOSLEEP="-lrt" + +# Some platforms might need additional linker flags to link against +# libmandoc that are not autodetected, though no such cases are +# currently known. + +LDADD="-lm" # Some systems may want to set additional linker flags for all the # binaries, not only for those using libmandoc, for example for @@ -152,43 +161,6 @@ INSTALL_LIB="${INSTALL} -m 0444" INSTALL_MAN="${INSTALL} -m 0444" INSTALL_DATA="${INSTALL} -m 0444" -# --- user settings related to database support ------------------------ - -# By default, building makewhatis(8) and apropos(1) is enabled. -# To disable it, for example to avoid the dependency on SQLite3, -# use the following line. It that case, the remaining settings -# in this section are irrelevant. - -BUILD_DB=0 - -# Autoconfiguration tries the following linker flags to find the -# SQLite3 library installed on your system. If none of these work, -# set the following variable to specify the required linker flags. - -LD_SQLITE3="-lsqlite3" -LD_SQLITE3="-L/usr/local/lib -lsqlite3" - -# When library autodetection decides to use -L/usr/local/lib, -# -I/usr/local/include is automatically added to CFLAGS. -# If you manually set LD_SQLITE3 to something including -L/usr/local/lib, -# chances are you will also need the following line: - -CFLAGS="${CFLAGS} -I/usr/local/include" - -# Some distributions may want to avoid naming conflicts -# with another implementation of apropos(1) and makewhatis(8). -# If you want to change the names of the binary programs, -# the following alternative names are suggested. -# Using other names is possible as well. -# This changes the names of the installed section 1 and section 8 -# manual pages as well. -# It is possible to set only one or two of these variables, -# there is no need to copy the whole block. - -BINM_APROPOS=mapropos # default is "apropos" -BINM_WHATIS=mwhatis # default is "whatis" -BINM_MAKEWHATIS=mandocdb # default is "makewhatis" - # When using the "homebrew" package manager on Mac OS X, the actual # manuals are located in a so-called "cellar" and only symlinked # into the manual trees. To allow mandoc to follow such symlinks, @@ -198,11 +170,25 @@ BINM_MAKEWHATIS=mandocdb # default is "makewhatis" PREFIX="/usr/local" HOMEBREWDIR="${PREFIX}/Cellar" -# --- user settings related man.cgi ------------------------------------ +# --- user settings for the mandoc(3) library -------------------------- + +# By default, libmandoc.a is not installed. It is almost never needed +# because there is almost no non-mandoc software out there using this +# library. The one notable exception is NetBSD apropos(1). +# So, when building for the NetBSD base system - but not for NetBSD +# ports nor for pkgsrc! - you may want the following: + +INSTALL_LIBMANDOC=1 + +# The following settings are only used when INSTALL_LIBMANDOC is set. + +INCLUDEDIR="${PREFIX}/include/mandoc" +LIBDIR="${PREFIX}/lib/mandoc" + +# --- user settings related to man.cgi --------------------------------- # By default, building man.cgi(8) is disabled. To enable it, copy # cgi.h.example to cgi.h, edit it, and use the following line. -# Obviously, this requires that BUILD_DB is enabled, too. BUILD_CGI=1 @@ -254,13 +240,18 @@ CFLAGS="-g" # be regarded as successful). HAVE_DIRENT_NAMLEN=0 +HAVE_ENDIAN=0 +HAVE_EFTYPE=0 HAVE_ERR=0 -HAVE_FTS=0 +HAVE_FTS=0 # Setting this implies HAVE_FTS_COMPARE_CONST=0. +HAVE_FTS_COMPARE_CONST=0 # Setting this implies HAVE_FTS=1. HAVE_GETLINE=0 HAVE_GETSUBOPT=0 HAVE_ISBLANK=0 HAVE_MKDTEMP=0 -HAVE_MMAP=0 +HAVE_NTOHL=0 +HAVE_OHASH=0 +HAVE_PATH_MAX=0 HAVE_PLEDGE=0 HAVE_PROGNAME=0 HAVE_REALLOCARRAY=0 @@ -273,9 +264,6 @@ HAVE_STRLCPY=0 HAVE_STRPTIME=0 HAVE_STRSEP=0 HAVE_STRTONUM=0 +HAVE_SYS_ENDIAN=0 HAVE_VASPRINTF=0 HAVE_WCHAR=0 - -HAVE_SQLITE3=0 -HAVE_SQLITE3_ERRSTR=0 -HAVE_OHASH=0 diff --git a/contrib/mdocml/dba.c b/contrib/mdocml/dba.c new file mode 100644 index 00000000000..bb1539b741e --- /dev/null +++ b/contrib/mdocml/dba.c @@ -0,0 +1,508 @@ +/* $Id: dba.c,v 1.9 2017/01/15 15:28:55 schwarze Exp $ */ +/* + * Copyright (c) 2016, 2017 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Allocation-based version of the mandoc database, for read-write access. + * The interface is defined in "dba.h". + */ +#include "config.h" + +#include +#if HAVE_ENDIAN +#include +#elif HAVE_SYS_ENDIAN +#include +#elif HAVE_NTOHL +#include +#endif +#include +#include +#include +#include +#include +#include + +#include "mandoc_aux.h" +#include "mandoc_ohash.h" +#include "mansearch.h" +#include "dba_write.h" +#include "dba_array.h" +#include "dba.h" + +struct macro_entry { + struct dba_array *pages; + char value[]; +}; + +static void *prepend(const char *, char); +static void dba_pages_write(struct dba_array *); +static int compare_names(const void *, const void *); +static int compare_strings(const void *, const void *); + +static struct macro_entry + *get_macro_entry(struct ohash *, const char *, int32_t); +static void dba_macros_write(struct dba_array *); +static void dba_macro_write(struct ohash *); +static int compare_entries(const void *, const void *); + + +/*** top-level functions **********************************************/ + +struct dba * +dba_new(int32_t npages) +{ + struct dba *dba; + struct ohash *macro; + int32_t im; + + dba = mandoc_malloc(sizeof(*dba)); + dba->pages = dba_array_new(npages, DBA_GROW); + dba->macros = dba_array_new(MACRO_MAX, 0); + for (im = 0; im < MACRO_MAX; im++) { + macro = mandoc_malloc(sizeof(*macro)); + mandoc_ohash_init(macro, 4, + offsetof(struct macro_entry, value)); + dba_array_set(dba->macros, im, macro); + } + return dba; +} + +void +dba_free(struct dba *dba) +{ + struct dba_array *page; + struct ohash *macro; + struct macro_entry *entry; + unsigned int slot; + + dba_array_FOREACH(dba->macros, macro) { + for (entry = ohash_first(macro, &slot); entry != NULL; + entry = ohash_next(macro, &slot)) { + dba_array_free(entry->pages); + free(entry); + } + ohash_delete(macro); + free(macro); + } + dba_array_free(dba->macros); + + dba_array_undel(dba->pages); + dba_array_FOREACH(dba->pages, page) { + dba_array_free(dba_array_get(page, DBP_NAME)); + dba_array_free(dba_array_get(page, DBP_SECT)); + dba_array_free(dba_array_get(page, DBP_ARCH)); + free(dba_array_get(page, DBP_DESC)); + dba_array_free(dba_array_get(page, DBP_FILE)); + dba_array_free(page); + } + dba_array_free(dba->pages); + + free(dba); +} + +/* + * Write the complete mandoc database to disk; the format is: + * - One integer each for magic and version. + * - One pointer each to the macros table and to the final magic. + * - The pages table. + * - The macros table. + * - And at the very end, the magic integer again. + */ +int +dba_write(const char *fname, struct dba *dba) +{ + int save_errno; + int32_t pos_end, pos_macros, pos_macros_ptr; + + if (dba_open(fname) == -1) + return -1; + dba_int_write(MANDOCDB_MAGIC); + dba_int_write(MANDOCDB_VERSION); + pos_macros_ptr = dba_skip(1, 2); + dba_pages_write(dba->pages); + pos_macros = dba_tell(); + dba_macros_write(dba->macros); + pos_end = dba_tell(); + dba_int_write(MANDOCDB_MAGIC); + dba_seek(pos_macros_ptr); + dba_int_write(pos_macros); + dba_int_write(pos_end); + if (dba_close() == -1) { + save_errno = errno; + unlink(fname); + errno = save_errno; + return -1; + } + return 0; +} + + +/*** functions for handling pages *************************************/ + +/* + * Create a new page and append it to the pages table. + */ +struct dba_array * +dba_page_new(struct dba_array *pages, const char *arch, + const char *desc, const char *file, enum form form) +{ + struct dba_array *page, *entry; + + page = dba_array_new(DBP_MAX, 0); + entry = dba_array_new(1, DBA_STR | DBA_GROW); + dba_array_add(page, entry); + entry = dba_array_new(1, DBA_STR | DBA_GROW); + dba_array_add(page, entry); + if (arch != NULL && *arch != '\0') { + entry = dba_array_new(1, DBA_STR | DBA_GROW); + dba_array_add(entry, (void *)arch); + } else + entry = NULL; + dba_array_add(page, entry); + dba_array_add(page, mandoc_strdup(desc)); + entry = dba_array_new(1, DBA_STR | DBA_GROW); + dba_array_add(entry, prepend(file, form)); + dba_array_add(page, entry); + dba_array_add(pages, page); + return page; +} + +/* + * Add a section, architecture, or file name to an existing page. + * Passing the NULL pointer for the architecture makes the page MI. + * In that case, any earlier or later architectures are ignored. + */ +void +dba_page_add(struct dba_array *page, int32_t ie, const char *str) +{ + struct dba_array *entries; + char *entry; + + entries = dba_array_get(page, ie); + if (ie == DBP_ARCH) { + if (entries == NULL) + return; + if (str == NULL || *str == '\0') { + dba_array_free(entries); + dba_array_set(page, DBP_ARCH, NULL); + return; + } + } + if (*str == '\0') + return; + dba_array_FOREACH(entries, entry) { + if (ie == DBP_FILE && *entry < ' ') + entry++; + if (strcmp(entry, str) == 0) + return; + } + dba_array_add(entries, (void *)str); +} + +/* + * Add an additional name to an existing page. + */ +void +dba_page_alias(struct dba_array *page, const char *name, uint64_t mask) +{ + struct dba_array *entries; + char *entry; + char maskbyte; + + if (*name == '\0') + return; + maskbyte = mask & NAME_MASK; + entries = dba_array_get(page, DBP_NAME); + dba_array_FOREACH(entries, entry) { + if (strcmp(entry + 1, name) == 0) { + *entry |= maskbyte; + return; + } + } + dba_array_add(entries, prepend(name, maskbyte)); +} + +/* + * Return a pointer to a temporary copy of instr with inbyte prepended. + */ +static void * +prepend(const char *instr, char inbyte) +{ + static char *outstr = NULL; + static size_t outlen = 0; + size_t newlen; + + newlen = strlen(instr) + 1; + if (newlen > outlen) { + outstr = mandoc_realloc(outstr, newlen + 1); + outlen = newlen; + } + *outstr = inbyte; + memcpy(outstr + 1, instr, newlen); + return outstr; +} + +/* + * Write the pages table to disk; the format is: + * - One integer containing the number of pages. + * - For each page, five pointers to the names, sections, + * architectures, description, and file names of the page. + * MI pages write 0 instead of the architecture pointer. + * - One list each for names, sections, architectures, descriptions and + * file names. The description for each page ends with a NUL byte. + * For all the other lists, each string ends with a NUL byte, + * and the last string for a page ends with two NUL bytes. + * - To assure alignment of following integers, + * the end is padded with NUL bytes up to a multiple of four bytes. + */ +static void +dba_pages_write(struct dba_array *pages) +{ + struct dba_array *page, *entry; + int32_t pos_pages, pos_end; + + pos_pages = dba_array_writelen(pages, 5); + dba_array_FOREACH(pages, page) { + dba_array_setpos(page, DBP_NAME, dba_tell()); + entry = dba_array_get(page, DBP_NAME); + dba_array_sort(entry, compare_names); + dba_array_writelst(entry); + } + dba_array_FOREACH(pages, page) { + dba_array_setpos(page, DBP_SECT, dba_tell()); + entry = dba_array_get(page, DBP_SECT); + dba_array_sort(entry, compare_strings); + dba_array_writelst(entry); + } + dba_array_FOREACH(pages, page) { + if ((entry = dba_array_get(page, DBP_ARCH)) != NULL) { + dba_array_setpos(page, DBP_ARCH, dba_tell()); + dba_array_sort(entry, compare_strings); + dba_array_writelst(entry); + } else + dba_array_setpos(page, DBP_ARCH, 0); + } + dba_array_FOREACH(pages, page) { + dba_array_setpos(page, DBP_DESC, dba_tell()); + dba_str_write(dba_array_get(page, DBP_DESC)); + } + dba_array_FOREACH(pages, page) { + dba_array_setpos(page, DBP_FILE, dba_tell()); + dba_array_writelst(dba_array_get(page, DBP_FILE)); + } + pos_end = dba_align(); + dba_seek(pos_pages); + dba_array_FOREACH(pages, page) + dba_array_writepos(page); + dba_seek(pos_end); +} + +static int +compare_names(const void *vp1, const void *vp2) +{ + const char *cp1, *cp2; + int diff; + + cp1 = *(char **)vp1; + cp2 = *(char **)vp2; + return (diff = *cp2 - *cp1) ? diff : + strcasecmp(cp1 + 1, cp2 + 1); +} + +static int +compare_strings(const void *vp1, const void *vp2) +{ + const char *cp1, *cp2; + + cp1 = *(char **)vp1; + cp2 = *(char **)vp2; + return strcmp(cp1, cp2); +} + +/*** functions for handling macros ************************************/ + +/* + * In the hash table for a single macro, look up an entry by + * the macro value or add an empty one if it doesn't exist yet. + */ +static struct macro_entry * +get_macro_entry(struct ohash *macro, const char *value, int32_t np) +{ + struct macro_entry *entry; + size_t len; + unsigned int slot; + + slot = ohash_qlookup(macro, value); + if ((entry = ohash_find(macro, slot)) == NULL) { + len = strlen(value) + 1; + entry = mandoc_malloc(sizeof(*entry) + len); + memcpy(&entry->value, value, len); + entry->pages = dba_array_new(np, DBA_GROW); + ohash_insert(macro, slot, entry); + } + return entry; +} + +/* + * In addition to get_macro_entry(), add multiple page references, + * converting them from the on-disk format (byte offsets in the file) + * to page pointers in memory. + */ +void +dba_macro_new(struct dba *dba, int32_t im, const char *value, + const int32_t *pp) +{ + struct macro_entry *entry; + const int32_t *ip; + int32_t np; + + np = 0; + for (ip = pp; *ip; ip++) + np++; + + entry = get_macro_entry(dba_array_get(dba->macros, im), value, np); + for (ip = pp; *ip; ip++) + dba_array_add(entry->pages, dba_array_get(dba->pages, + be32toh(*ip) / 5 / sizeof(*ip) - 1)); +} + +/* + * In addition to get_macro_entry(), add one page reference, + * directly taking the in-memory page pointer as an argument. + */ +void +dba_macro_add(struct dba_array *macros, int32_t im, const char *value, + struct dba_array *page) +{ + struct macro_entry *entry; + + if (*value == '\0') + return; + entry = get_macro_entry(dba_array_get(macros, im), value, 1); + dba_array_add(entry->pages, page); +} + +/* + * Write the macros table to disk; the format is: + * - The number of macro tables (actually, MACRO_MAX). + * - That number of pointers to the individual macro tables. + * - The individual macro tables. + */ +static void +dba_macros_write(struct dba_array *macros) +{ + struct ohash *macro; + int32_t im, pos_macros, pos_end; + + pos_macros = dba_array_writelen(macros, 1); + im = 0; + dba_array_FOREACH(macros, macro) { + dba_array_setpos(macros, im++, dba_tell()); + dba_macro_write(macro); + } + pos_end = dba_tell(); + dba_seek(pos_macros); + dba_array_writepos(macros); + dba_seek(pos_end); +} + +/* + * Write one individual macro table to disk; the format is: + * - The number of entries in the table. + * - For each entry, two pointers, the first one to the value + * and the second one to the list of pages. + * - A list of values, each ending in a NUL byte. + * - To assure alignment of following integers, + * padding with NUL bytes up to a multiple of four bytes. + * - A list of pointers to pages, each list ending in a 0 integer. + */ +static void +dba_macro_write(struct ohash *macro) +{ + struct macro_entry **entries, *entry; + struct dba_array *page; + int32_t *kpos, *dpos; + unsigned int ie, ne, slot; + int use; + int32_t addr, pos_macro, pos_end; + + /* Temporary storage for filtering and sorting. */ + + ne = ohash_entries(macro); + entries = mandoc_reallocarray(NULL, ne, sizeof(*entries)); + kpos = mandoc_reallocarray(NULL, ne, sizeof(*kpos)); + dpos = mandoc_reallocarray(NULL, ne, sizeof(*dpos)); + + /* Build a list of non-empty entries and sort it. */ + + ne = 0; + for (entry = ohash_first(macro, &slot); entry != NULL; + entry = ohash_next(macro, &slot)) { + use = 0; + dba_array_FOREACH(entry->pages, page) + if (dba_array_getpos(page)) + use = 1; + if (use) + entries[ne++] = entry; + } + qsort(entries, ne, sizeof(*entries), compare_entries); + + /* Number of entries, and space for the pointer pairs. */ + + dba_int_write(ne); + pos_macro = dba_skip(2, ne); + + /* String table. */ + + for (ie = 0; ie < ne; ie++) { + kpos[ie] = dba_tell(); + dba_str_write(entries[ie]->value); + } + dba_align(); + + /* Pages table. */ + + for (ie = 0; ie < ne; ie++) { + dpos[ie] = dba_tell(); + dba_array_FOREACH(entries[ie]->pages, page) + if ((addr = dba_array_getpos(page))) + dba_int_write(addr); + dba_int_write(0); + } + pos_end = dba_tell(); + + /* Fill in the pointer pairs. */ + + dba_seek(pos_macro); + for (ie = 0; ie < ne; ie++) { + dba_int_write(kpos[ie]); + dba_int_write(dpos[ie]); + } + dba_seek(pos_end); + + free(entries); + free(kpos); + free(dpos); +} + +static int +compare_entries(const void *vp1, const void *vp2) +{ + const struct macro_entry *ep1, *ep2; + + ep1 = *(struct macro_entry **)vp1; + ep2 = *(struct macro_entry **)vp2; + return strcmp(ep1->value, ep2->value); +} diff --git a/contrib/mdocml/dba.h b/contrib/mdocml/dba.h new file mode 100644 index 00000000000..67a2759a207 --- /dev/null +++ b/contrib/mdocml/dba.h @@ -0,0 +1,50 @@ +/* $Id: dba.h,v 1.2 2016/08/17 20:46:56 schwarze Exp $ */ +/* + * Copyright (c) 2016 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Public interface of the allocation-based version + * of the mandoc database, for read-write access. + * To be used by dba.c, dba_read.c, and makewhatis(8). + */ + +#define DBP_NAME 0 +#define DBP_SECT 1 +#define DBP_ARCH 2 +#define DBP_DESC 3 +#define DBP_FILE 4 +#define DBP_MAX 5 + +struct dba_array; + +struct dba { + struct dba_array *pages; + struct dba_array *macros; +}; + + +struct dba *dba_new(int32_t); +void dba_free(struct dba *); +struct dba *dba_read(const char *); +int dba_write(const char *, struct dba *); + +struct dba_array *dba_page_new(struct dba_array *, const char *, + const char *, const char *, enum form); +void dba_page_add(struct dba_array *, int32_t, const char *); +void dba_page_alias(struct dba_array *, const char *, uint64_t); + +void dba_macro_new(struct dba *, int32_t, + const char *, const int32_t *); +void dba_macro_add(struct dba_array *, int32_t, + const char *, struct dba_array *); diff --git a/contrib/mdocml/dba_array.c b/contrib/mdocml/dba_array.c new file mode 100644 index 00000000000..18c9f09f1a2 --- /dev/null +++ b/contrib/mdocml/dba_array.c @@ -0,0 +1,188 @@ +/* $Id: dba_array.c,v 1.1 2016/07/19 21:31:55 schwarze Exp $ */ +/* + * Copyright (c) 2016 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Allocation-based arrays for the mandoc database, for read-write access. + * The interface is defined in "dba_array.h". + */ +#include +#include +#include +#include + +#include "mandoc_aux.h" +#include "dba_write.h" +#include "dba_array.h" + +struct dba_array { + void **ep; /* Array of entries. */ + int32_t *em; /* Array of map positions. */ + int flags; + int32_t ea; /* Entries allocated. */ + int32_t eu; /* Entries used (including deleted). */ + int32_t ed; /* Entries deleted. */ + int32_t ec; /* Currently active entry. */ + int32_t pos; /* Map position of this array. */ +}; + + +struct dba_array * +dba_array_new(int32_t ea, int flags) +{ + struct dba_array *array; + + assert(ea > 0); + array = mandoc_malloc(sizeof(*array)); + array->ep = mandoc_reallocarray(NULL, ea, sizeof(*array->ep)); + array->em = mandoc_reallocarray(NULL, ea, sizeof(*array->em)); + array->ea = ea; + array->eu = 0; + array->ed = 0; + array->ec = 0; + array->flags = flags; + array->pos = 0; + return array; +} + +void +dba_array_free(struct dba_array *array) +{ + int32_t ie; + + if (array == NULL) + return; + if (array->flags & DBA_STR) + for (ie = 0; ie < array->eu; ie++) + free(array->ep[ie]); + free(array->ep); + free(array->em); + free(array); +} + +void +dba_array_set(struct dba_array *array, int32_t ie, void *entry) +{ + assert(ie >= 0); + assert(ie < array->ea); + assert(ie <= array->eu); + if (ie == array->eu) + array->eu++; + if (array->flags & DBA_STR) + entry = mandoc_strdup(entry); + array->ep[ie] = entry; + array->em[ie] = 0; +} + +void +dba_array_add(struct dba_array *array, void *entry) +{ + if (array->eu == array->ea) { + assert(array->flags & DBA_GROW); + array->ep = mandoc_reallocarray(array->ep, + 2, sizeof(*array->ep) * array->ea); + array->em = mandoc_reallocarray(array->em, + 2, sizeof(*array->em) * array->ea); + array->ea *= 2; + } + dba_array_set(array, array->eu, entry); +} + +void * +dba_array_get(struct dba_array *array, int32_t ie) +{ + if (ie < 0 || ie >= array->eu || array->em[ie] == -1) + return NULL; + return array->ep[ie]; +} + +void +dba_array_start(struct dba_array *array) +{ + array->ec = array->eu; +} + +void * +dba_array_next(struct dba_array *array) +{ + if (array->ec < array->eu) + array->ec++; + else + array->ec = 0; + while (array->ec < array->eu && array->em[array->ec] == -1) + array->ec++; + return array->ec < array->eu ? array->ep[array->ec] : NULL; +} + +void +dba_array_del(struct dba_array *array) +{ + if (array->ec < array->eu && array->em[array->ec] != -1) { + array->em[array->ec] = -1; + array->ed++; + } +} + +void +dba_array_undel(struct dba_array *array) +{ + memset(array->em, 0, sizeof(*array->em) * array->eu); +} + +void +dba_array_setpos(struct dba_array *array, int32_t ie, int32_t pos) +{ + array->em[ie] = pos; +} + +int32_t +dba_array_getpos(struct dba_array *array) +{ + return array->pos; +} + +void +dba_array_sort(struct dba_array *array, dba_compare_func func) +{ + assert(array->ed == 0); + qsort(array->ep, array->eu, sizeof(*array->ep), func); +} + +int32_t +dba_array_writelen(struct dba_array *array, int32_t nmemb) +{ + dba_int_write(array->eu - array->ed); + return dba_skip(nmemb, array->eu - array->ed); +} + +void +dba_array_writepos(struct dba_array *array) +{ + int32_t ie; + + array->pos = dba_tell(); + for (ie = 0; ie < array->eu; ie++) + if (array->em[ie] != -1) + dba_int_write(array->em[ie]); +} + +void +dba_array_writelst(struct dba_array *array) +{ + const char *str; + + dba_array_FOREACH(array, str) + dba_str_write(str); + dba_char_write('\0'); +} diff --git a/contrib/mdocml/dba_array.h b/contrib/mdocml/dba_array.h new file mode 100644 index 00000000000..d9a6ee6b1a4 --- /dev/null +++ b/contrib/mdocml/dba_array.h @@ -0,0 +1,47 @@ +/* $Id: dba_array.h,v 1.1 2016/07/19 21:31:55 schwarze Exp $ */ +/* + * Copyright (c) 2016 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Public interface for allocation-based arrays + * for the mandoc database, for read-write access. + * To be used by dba*.c and by makewhatis(8). + */ + +struct dba_array; + +#define DBA_STR 0x01 /* Map contains strings, not pointers. */ +#define DBA_GROW 0x02 /* Allow the array to grow. */ + +#define dba_array_FOREACH(a, e) \ + dba_array_start(a); \ + while (((e) = dba_array_next(a)) != NULL) + +typedef int dba_compare_func(const void *, const void *); + +struct dba_array *dba_array_new(int32_t, int); +void dba_array_free(struct dba_array *); +void dba_array_set(struct dba_array *, int32_t, void *); +void dba_array_add(struct dba_array *, void *); +void *dba_array_get(struct dba_array *, int32_t); +void dba_array_start(struct dba_array *); +void *dba_array_next(struct dba_array *); +void dba_array_del(struct dba_array *); +void dba_array_undel(struct dba_array *); +void dba_array_setpos(struct dba_array *, int32_t, int32_t); +int32_t dba_array_getpos(struct dba_array *); +void dba_array_sort(struct dba_array *, dba_compare_func); +int32_t dba_array_writelen(struct dba_array *, int32_t); +void dba_array_writepos(struct dba_array *); +void dba_array_writelst(struct dba_array *); diff --git a/contrib/mdocml/dba_read.c b/contrib/mdocml/dba_read.c new file mode 100644 index 00000000000..e976057064a --- /dev/null +++ b/contrib/mdocml/dba_read.c @@ -0,0 +1,72 @@ +/* $Id: dba_read.c,v 1.4 2016/08/17 20:46:56 schwarze Exp $ */ +/* + * Copyright (c) 2016 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Function to read the mandoc database from disk into RAM, + * such that data can be added or removed. + * The interface is defined in "dba.h". + * This file is seperate from dba.c because this also uses "dbm.h". + */ +#include +#include +#include +#include +#include + +#include "mandoc_aux.h" +#include "mansearch.h" +#include "dba_array.h" +#include "dba.h" +#include "dbm.h" + + +struct dba * +dba_read(const char *fname) +{ + struct dba *dba; + struct dba_array *page; + struct dbm_page *pdata; + struct dbm_macro *mdata; + const char *cp; + int32_t im, ip, iv, npages; + + if (dbm_open(fname) == -1) + return NULL; + npages = dbm_page_count(); + dba = dba_new(npages < 128 ? 128 : npages); + for (ip = 0; ip < npages; ip++) { + pdata = dbm_page_get(ip); + page = dba_page_new(dba->pages, pdata->arch, + pdata->desc, pdata->file + 1, *pdata->file); + for (cp = pdata->name; *cp != '\0'; cp = strchr(cp, '\0') + 1) + dba_page_add(page, DBP_NAME, cp); + for (cp = pdata->sect; *cp != '\0'; cp = strchr(cp, '\0') + 1) + dba_page_add(page, DBP_SECT, cp); + if ((cp = pdata->arch) != NULL) + while (*(cp = strchr(cp, '\0') + 1) != '\0') + dba_page_add(page, DBP_ARCH, cp); + cp = pdata->file; + while (*(cp = strchr(cp, '\0') + 1) != '\0') + dba_page_add(page, DBP_FILE, cp); + } + for (im = 0; im < MACRO_MAX; im++) { + for (iv = 0; iv < dbm_macro_count(im); iv++) { + mdata = dbm_macro_get(im, iv); + dba_macro_new(dba, im, mdata->value, mdata->pp); + } + } + dbm_close(); + return dba; +} diff --git a/contrib/mdocml/dba_write.c b/contrib/mdocml/dba_write.c new file mode 100644 index 00000000000..89883b87c1e --- /dev/null +++ b/contrib/mdocml/dba_write.c @@ -0,0 +1,127 @@ +/* $Id: dba_write.c,v 1.3 2016/08/05 23:15:08 schwarze Exp $ */ +/* + * Copyright (c) 2016 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Low-level functions for serializing allocation-based data to disk. + * The interface is defined in "dba_write.h". + */ +#include "config.h" + +#include +#if HAVE_ENDIAN +#include +#elif HAVE_SYS_ENDIAN +#include +#elif HAVE_NTOHL +#include +#endif +#if HAVE_ERR +#include +#endif +#include +#include +#include +#include + +#include "dba_write.h" + +static FILE *ofp; + + +int +dba_open(const char *fname) +{ + ofp = fopen(fname, "w"); + return ofp == NULL ? -1 : 0; +} + +int +dba_close(void) +{ + return fclose(ofp) == EOF ? -1 : 0; +} + +int32_t +dba_tell(void) +{ + long pos; + + if ((pos = ftell(ofp)) == -1) + err(1, "ftell"); + if (pos >= INT32_MAX) { + errno = EOVERFLOW; + err(1, "ftell = %ld", pos); + } + return pos; +} + +void +dba_seek(int32_t pos) +{ + if (fseek(ofp, pos, SEEK_SET) == -1) + err(1, "fseek(%d)", pos); +} + +int32_t +dba_align(void) +{ + int32_t pos; + + pos = dba_tell(); + while (pos & 3) { + dba_char_write('\0'); + pos++; + } + return pos; +} + +int32_t +dba_skip(int32_t nmemb, int32_t sz) +{ + const int32_t out[5] = {0, 0, 0, 0, 0}; + int32_t i, pos; + + assert(sz >= 0); + assert(nmemb > 0); + assert(nmemb <= 5); + pos = dba_tell(); + for (i = 0; i < sz; i++) + if (nmemb - fwrite(&out, sizeof(out[0]), nmemb, ofp)) + err(1, "fwrite"); + return pos; +} + +void +dba_char_write(int c) +{ + if (putc(c, ofp) == EOF) + err(1, "fputc"); +} + +void +dba_str_write(const char *str) +{ + if (fputs(str, ofp) == EOF) + err(1, "fputs"); + dba_char_write('\0'); +} + +void +dba_int_write(int32_t i) +{ + i = htobe32(i); + if (fwrite(&i, sizeof(i), 1, ofp) != 1) + err(1, "fwrite"); +} diff --git a/contrib/mdocml/dba_write.h b/contrib/mdocml/dba_write.h new file mode 100644 index 00000000000..6adda05b650 --- /dev/null +++ b/contrib/mdocml/dba_write.h @@ -0,0 +1,30 @@ +/* $Id: dba_write.h,v 1.1 2016/07/19 21:31:55 schwarze Exp $ */ +/* + * Copyright (c) 2016 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Internal interface to low-level functions + * for serializing allocation-based data to disk. + * For use by dba_array.c and dba.c only. + */ + +int dba_open(const char *); +int dba_close(void); +int32_t dba_tell(void); +void dba_seek(int32_t); +int32_t dba_align(void); +int32_t dba_skip(int32_t, int32_t); +void dba_char_write(int); +void dba_str_write(const char *); +void dba_int_write(int32_t); diff --git a/contrib/mdocml/dbm.c b/contrib/mdocml/dbm.c new file mode 100644 index 00000000000..4aedf66d136 --- /dev/null +++ b/contrib/mdocml/dbm.c @@ -0,0 +1,480 @@ +/* $Id: dbm.c,v 1.5 2016/10/18 22:27:25 schwarze Exp $ */ +/* + * Copyright (c) 2016 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Map-based version of the mandoc database, for read-only access. + * The interface is defined in "dbm.h". + */ +#include "config.h" + +#include +#if HAVE_ENDIAN +#include +#elif HAVE_SYS_ENDIAN +#include +#elif HAVE_NTOHL +#include +#endif +#if HAVE_ERR +#include +#endif +#include +#include +#include +#include +#include +#include + +#include "mansearch.h" +#include "dbm_map.h" +#include "dbm.h" + +struct macro { + int32_t value; + int32_t pages; +}; + +struct page { + int32_t name; + int32_t sect; + int32_t arch; + int32_t desc; + int32_t file; +}; + +enum iter { + ITER_NONE = 0, + ITER_NAME, + ITER_SECT, + ITER_ARCH, + ITER_DESC, + ITER_MACRO +}; + +static struct macro *macros[MACRO_MAX]; +static int32_t nvals[MACRO_MAX]; +static struct page *pages; +static int32_t npages; +static enum iter iteration; + +static struct dbm_res page_bytitle(enum iter, const struct dbm_match *); +static struct dbm_res page_byarch(const struct dbm_match *); +static struct dbm_res page_bymacro(int32_t, const struct dbm_match *); +static char *macro_bypage(int32_t, int32_t); + + +/*** top level functions **********************************************/ + +/* + * Open a disk-based mandoc database for read-only access. + * Map the pages and macros[] arrays. + * Return 0 on success. Return -1 and set errno on failure. + */ +int +dbm_open(const char *fname) +{ + const int32_t *mp, *ep; + int32_t im; + + if (dbm_map(fname) == -1) + return -1; + + if ((npages = be32toh(*dbm_getint(4))) < 0) { + warnx("dbm_open(%s): Invalid number of pages: %d", + fname, npages); + goto fail; + } + pages = (struct page *)dbm_getint(5); + + if ((mp = dbm_get(*dbm_getint(2))) == NULL) { + warnx("dbm_open(%s): Invalid offset of macros array", fname); + goto fail; + } + if (be32toh(*mp) != MACRO_MAX) { + warnx("dbm_open(%s): Invalid number of macros: %d", + fname, be32toh(*mp)); + goto fail; + } + for (im = 0; im < MACRO_MAX; im++) { + if ((ep = dbm_get(*++mp)) == NULL) { + warnx("dbm_open(%s): Invalid offset of macro %d", + fname, im); + goto fail; + } + nvals[im] = be32toh(*ep); + macros[im] = (struct macro *)++ep; + } + return 0; + +fail: + dbm_unmap(); + errno = EFTYPE; + return -1; +} + +void +dbm_close(void) +{ + dbm_unmap(); +} + + +/*** functions for handling pages *************************************/ + +int32_t +dbm_page_count(void) +{ + return npages; +} + +/* + * Give the caller pointers to the data for one manual page. + */ +struct dbm_page * +dbm_page_get(int32_t ip) +{ + static struct dbm_page res; + + assert(ip >= 0); + assert(ip < npages); + res.name = dbm_get(pages[ip].name); + if (res.name == NULL) + res.name = "(NULL)"; + res.sect = dbm_get(pages[ip].sect); + if (res.sect == NULL) + res.sect = "(NULL)"; + res.arch = pages[ip].arch ? dbm_get(pages[ip].arch) : NULL; + res.desc = dbm_get(pages[ip].desc); + if (res.desc == NULL) + res.desc = "(NULL)"; + res.file = dbm_get(pages[ip].file); + if (res.file == NULL) + res.file = " (NULL)"; + res.addr = dbm_addr(pages + ip); + return &res; +} + +/* + * Functions to start filtered iterations over manual pages. + */ +void +dbm_page_byname(const struct dbm_match *match) +{ + assert(match != NULL); + page_bytitle(ITER_NAME, match); +} + +void +dbm_page_bysect(const struct dbm_match *match) +{ + assert(match != NULL); + page_bytitle(ITER_SECT, match); +} + +void +dbm_page_byarch(const struct dbm_match *match) +{ + assert(match != NULL); + page_byarch(match); +} + +void +dbm_page_bydesc(const struct dbm_match *match) +{ + assert(match != NULL); + page_bytitle(ITER_DESC, match); +} + +void +dbm_page_bymacro(int32_t im, const struct dbm_match *match) +{ + assert(im >= 0); + assert(im < MACRO_MAX); + assert(match != NULL); + page_bymacro(im, match); +} + +/* + * Return the number of the next manual page in the current iteration. + */ +struct dbm_res +dbm_page_next(void) +{ + struct dbm_res res = {-1, 0}; + + switch(iteration) { + case ITER_NONE: + return res; + case ITER_ARCH: + return page_byarch(NULL); + case ITER_MACRO: + return page_bymacro(0, NULL); + default: + return page_bytitle(iteration, NULL); + } +} + +/* + * Functions implementing the iteration over manual pages. + */ +static struct dbm_res +page_bytitle(enum iter arg_iter, const struct dbm_match *arg_match) +{ + static const struct dbm_match *match; + static const char *cp; + static int32_t ip; + struct dbm_res res = {-1, 0}; + + assert(arg_iter == ITER_NAME || arg_iter == ITER_DESC || + arg_iter == ITER_SECT); + + /* Initialize for a new iteration. */ + + if (arg_match != NULL) { + iteration = arg_iter; + match = arg_match; + switch (iteration) { + case ITER_NAME: + cp = dbm_get(pages[0].name); + break; + case ITER_SECT: + cp = dbm_get(pages[0].sect); + break; + case ITER_DESC: + cp = dbm_get(pages[0].desc); + break; + default: + abort(); + } + if (cp == NULL) { + iteration = ITER_NONE; + match = NULL; + cp = NULL; + ip = npages; + } else + ip = 0; + return res; + } + + /* Search for a name. */ + + while (ip < npages) { + if (iteration == ITER_NAME) + cp++; + if (dbm_match(match, cp)) + break; + cp = strchr(cp, '\0') + 1; + if (iteration == ITER_DESC) + ip++; + else if (*cp == '\0') { + cp++; + ip++; + } + } + + /* Reached the end without a match. */ + + if (ip == npages) { + iteration = ITER_NONE; + match = NULL; + cp = NULL; + return res; + } + + /* Found a match; save the quality for later retrieval. */ + + res.page = ip; + res.bits = iteration == ITER_NAME ? cp[-1] : 0; + + /* Skip the remaining names of this page. */ + + if (++ip < npages) { + do { + cp++; + } while (cp[-1] != '\0' || + (iteration != ITER_DESC && cp[-2] != '\0')); + } + return res; +} + +static struct dbm_res +page_byarch(const struct dbm_match *arg_match) +{ + static const struct dbm_match *match; + struct dbm_res res = {-1, 0}; + static int32_t ip; + const char *cp; + + /* Initialize for a new iteration. */ + + if (arg_match != NULL) { + iteration = ITER_ARCH; + match = arg_match; + ip = 0; + return res; + } + + /* Search for an architecture. */ + + for ( ; ip < npages; ip++) + if (pages[ip].arch) + for (cp = dbm_get(pages[ip].arch); + *cp != '\0'; + cp = strchr(cp, '\0') + 1) + if (dbm_match(match, cp)) { + res.page = ip++; + return res; + } + + /* Reached the end without a match. */ + + iteration = ITER_NONE; + match = NULL; + return res; +} + +static struct dbm_res +page_bymacro(int32_t arg_im, const struct dbm_match *arg_match) +{ + static const struct dbm_match *match; + static const int32_t *pp; + static const char *cp; + static int32_t im, iv; + struct dbm_res res = {-1, 0}; + + assert(im >= 0); + assert(im < MACRO_MAX); + + /* Initialize for a new iteration. */ + + if (arg_match != NULL) { + iteration = ITER_MACRO; + match = arg_match; + im = arg_im; + cp = nvals[im] ? dbm_get(macros[im]->value) : NULL; + pp = NULL; + iv = -1; + return res; + } + if (iteration != ITER_MACRO) + return res; + + /* Find the next matching macro value. */ + + while (pp == NULL || *pp == 0) { + if (++iv == nvals[im]) { + iteration = ITER_NONE; + return res; + } + if (iv) + cp = strchr(cp, '\0') + 1; + if (dbm_match(match, cp)) + pp = dbm_get(macros[im][iv].pages); + } + + /* Found a matching page. */ + + res.page = (struct page *)dbm_get(*pp++) - pages; + return res; +} + + +/*** functions for handling macros ************************************/ + +int32_t +dbm_macro_count(int32_t im) +{ + assert(im >= 0); + assert(im < MACRO_MAX); + return nvals[im]; +} + +struct dbm_macro * +dbm_macro_get(int32_t im, int32_t iv) +{ + static struct dbm_macro macro; + + assert(im >= 0); + assert(im < MACRO_MAX); + assert(iv >= 0); + assert(iv < nvals[im]); + macro.value = dbm_get(macros[im][iv].value); + macro.pp = dbm_get(macros[im][iv].pages); + return ¯o; +} + +/* + * Filtered iteration over macro entries. + */ +void +dbm_macro_bypage(int32_t im, int32_t ip) +{ + assert(im >= 0); + assert(im < MACRO_MAX); + assert(ip != 0); + macro_bypage(im, ip); +} + +char * +dbm_macro_next(void) +{ + return macro_bypage(MACRO_MAX, 0); +} + +static char * +macro_bypage(int32_t arg_im, int32_t arg_ip) +{ + static const int32_t *pp; + static int32_t im, ip, iv; + + /* Initialize for a new iteration. */ + + if (arg_im < MACRO_MAX && arg_ip != 0) { + im = arg_im; + ip = arg_ip; + pp = dbm_get(macros[im]->pages); + iv = 0; + return NULL; + } + if (im >= MACRO_MAX) + return NULL; + + /* Search for the next value. */ + + while (iv < nvals[im]) { + if (*pp == ip) + break; + if (*pp == 0) + iv++; + pp++; + } + + /* Reached the end without a match. */ + + if (iv == nvals[im]) { + im = MACRO_MAX; + ip = 0; + pp = NULL; + return NULL; + } + + /* Found a match; skip the remaining pages of this entry. */ + + if (++iv < nvals[im]) + while (*pp++ != 0) + continue; + + return dbm_get(macros[im][iv - 1].value); +} diff --git a/contrib/mdocml/dbm.h b/contrib/mdocml/dbm.h new file mode 100644 index 00000000000..ec2cd479a73 --- /dev/null +++ b/contrib/mdocml/dbm.h @@ -0,0 +1,68 @@ +/* $Id: dbm.h,v 1.1 2016/07/19 21:31:55 schwarze Exp $ */ +/* + * Copyright (c) 2016 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Public interface for the map-based version + * of the mandoc database, for read-only access. + * To be used by dbm*.c, dba_read.c, and man(1) and apropos(1). + */ + +enum dbm_mtype { + DBM_EXACT = 0, + DBM_SUB, + DBM_REGEX +}; + +struct dbm_match { + regex_t *re; + const char *str; + enum dbm_mtype type; +}; + +struct dbm_res { + int32_t page; + int32_t bits; +}; + +struct dbm_page { + const char *name; + const char *sect; + const char *arch; + const char *desc; + const char *file; + int32_t addr; +}; + +struct dbm_macro { + const char *value; + const int32_t *pp; +}; + +int dbm_open(const char *); +void dbm_close(void); + +int32_t dbm_page_count(void); +struct dbm_page *dbm_page_get(int32_t); +void dbm_page_byname(const struct dbm_match *); +void dbm_page_bysect(const struct dbm_match *); +void dbm_page_byarch(const struct dbm_match *); +void dbm_page_bydesc(const struct dbm_match *); +void dbm_page_bymacro(int32_t, const struct dbm_match *); +struct dbm_res dbm_page_next(void); + +int32_t dbm_macro_count(int32_t); +struct dbm_macro *dbm_macro_get(int32_t, int32_t); +void dbm_macro_bypage(int32_t, int32_t); +char *dbm_macro_next(void); diff --git a/contrib/mdocml/dbm_map.c b/contrib/mdocml/dbm_map.c new file mode 100644 index 00000000000..d158302bad6 --- /dev/null +++ b/contrib/mdocml/dbm_map.c @@ -0,0 +1,194 @@ +/* $Id: dbm_map.c,v 1.7 2016/10/22 10:09:27 schwarze Exp $ */ +/* + * Copyright (c) 2016 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Low-level routines for the map-based version + * of the mandoc database, for read-only access. + * The interface is defined in "dbm_map.h". + */ +#include "config.h" + +#include +#include +#include + +#if HAVE_ENDIAN +#include +#elif HAVE_SYS_ENDIAN +#include +#elif HAVE_NTOHL +#include +#endif +#if HAVE_ERR +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +#include "mansearch.h" +#include "dbm_map.h" +#include "dbm.h" + +static struct stat st; +static char *dbm_base; +static int ifd; +static int32_t max_offset; + +/* + * Open a disk-based database for read-only access. + * Validate the file format as far as it is not mandoc-specific. + * Return 0 on success. Return -1 and set errno on failure. + */ +int +dbm_map(const char *fname) +{ + int save_errno; + const int32_t *magic; + + if ((ifd = open(fname, O_RDONLY)) == -1) + return -1; + if (fstat(ifd, &st) == -1) + goto fail; + if (st.st_size < 5) { + warnx("dbm_map(%s): File too short", fname); + errno = EFTYPE; + goto fail; + } + if (st.st_size > INT32_MAX) { + errno = EFBIG; + goto fail; + } + if ((dbm_base = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, + ifd, 0)) == MAP_FAILED) + goto fail; + magic = dbm_getint(0); + if (be32toh(*magic) != MANDOCDB_MAGIC) { + if (strncmp(dbm_base, "SQLite format 3", 15)) + warnx("dbm_map(%s): " + "Bad initial magic %x (expected %x)", + fname, be32toh(*magic), MANDOCDB_MAGIC); + else + warnx("dbm_map(%s): " + "Obsolete format based on SQLite 3", + fname); + errno = EFTYPE; + goto fail; + } + magic = dbm_getint(1); + if (be32toh(*magic) != MANDOCDB_VERSION) { + warnx("dbm_map(%s): Bad version number %d (expected %d)", + fname, be32toh(*magic), MANDOCDB_VERSION); + errno = EFTYPE; + goto fail; + } + max_offset = be32toh(*dbm_getint(3)) + sizeof(int32_t); + if (st.st_size != max_offset) { + warnx("dbm_map(%s): Inconsistent file size %lld (expected %d)", + fname, (long long)st.st_size, max_offset); + errno = EFTYPE; + goto fail; + } + if ((magic = dbm_get(*dbm_getint(3))) == NULL) { + errno = EFTYPE; + goto fail; + } + if (be32toh(*magic) != MANDOCDB_MAGIC) { + warnx("dbm_map(%s): Bad final magic %x (expected %x)", + fname, be32toh(*magic), MANDOCDB_MAGIC); + errno = EFTYPE; + goto fail; + } + return 0; + +fail: + save_errno = errno; + close(ifd); + errno = save_errno; + return -1; +} + +void +dbm_unmap(void) +{ + if (munmap(dbm_base, st.st_size) == -1) + warn("dbm_unmap: munmap"); + if (close(ifd) == -1) + warn("dbm_unmap: close"); + dbm_base = (char *)-1; +} + +/* + * Take a raw integer as it was read from the database. + * Interpret it as an offset into the database file + * and return a pointer to that place in the file. + */ +void * +dbm_get(int32_t offset) +{ + offset = be32toh(offset); + if (offset < 0) { + warnx("dbm_get: Database corrupt: offset %d", offset); + return NULL; + } + if (offset >= max_offset) { + warnx("dbm_get: Database corrupt: offset %d > %d", + offset, max_offset); + return NULL; + } + return dbm_base + offset; +} + +/* + * Assume the database starts with some integers. + * Assume they are numbered starting from 0, increasing. + * Get a pointer to one with the number "offset". + */ +int32_t * +dbm_getint(int32_t offset) +{ + return (int32_t *)dbm_base + offset; +} + +/* + * The reverse of dbm_get(). + * Take pointer into the database file + * and convert it to the raw integer + * that would be used to refer to that place in the file. + */ +int32_t +dbm_addr(const void *p) +{ + return htobe32((char *)p - dbm_base); +} + +int +dbm_match(const struct dbm_match *match, const char *str) +{ + switch (match->type) { + case DBM_EXACT: + return strcmp(str, match->str) == 0; + case DBM_SUB: + return strcasestr(str, match->str) != NULL; + case DBM_REGEX: + return regexec(match->re, str, 0, NULL, 0) == 0; + default: + abort(); + } +} diff --git a/contrib/mdocml/mansearch_const.c b/contrib/mdocml/dbm_map.h similarity index 57% rename from contrib/mdocml/mansearch_const.c rename to contrib/mdocml/dbm_map.h index 61351c3c2a4..9768fc5f2dc 100644 --- a/contrib/mdocml/mansearch_const.c +++ b/contrib/mdocml/dbm_map.h @@ -1,6 +1,6 @@ -/* $Id: mansearch_const.c,v 1.7 2014/12/01 08:05:52 schwarze Exp $ */ +/* $Id: dbm_map.h,v 1.1 2016/07/19 21:31:55 schwarze Exp $ */ /* - * Copyright (c) 2014 Ingo Schwarze + * Copyright (c) 2016 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -13,21 +13,17 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Private interface for low-level routines for the map-based version + * of the mandoc database, for read-only access. + * To be used by dbm*.c only. */ -#include "config.h" -#include +struct dbm_match; -#include - -#include "mansearch.h" - -const int mansearch_keymax = 40; - -const char *const mansearch_keynames[40] = { - "arch", "sec", "Xr", "Ar", "Fa", "Fl", "Dv", "Fn", - "Ic", "Pa", "Cm", "Li", "Em", "Cd", "Va", "Ft", - "Tn", "Er", "Ev", "Sy", "Sh", "In", "Ss", "Ox", - "An", "Mt", "St", "Bx", "At", "Nx", "Fx", "Lk", - "Ms", "Bsx", "Dx", "Rs", "Vt", "Lb", "Nm", "Nd" -}; +int dbm_map(const char *); +void dbm_unmap(void); +void *dbm_get(int32_t); +int32_t *dbm_getint(int32_t); +int32_t dbm_addr(const void *); +int dbm_match(const struct dbm_match *, const char *); diff --git a/contrib/mdocml/demandoc.c b/contrib/mdocml/demandoc.c index c33fd89169a..acddf5a19ff 100644 --- a/contrib/mdocml/demandoc.c +++ b/contrib/mdocml/demandoc.c @@ -1,4 +1,4 @@ -/* $Id: demandoc.c,v 1.27 2016/07/09 15:24:19 schwarze Exp $ */ +/* $Id: demandoc.c,v 1.28 2017/01/10 13:47:00 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * @@ -239,7 +239,7 @@ pmdoc(const struct roff_node *p, int *line, int *col, int list) { for ( ; p; p = p->next) { - if (MDOC_LINE & p->flags) + if (NODE_LINE & p->flags) pline(p->line, line, col, list); if (ROFFT_TEXT == p->type) pstring(p->string, p->pos, col, list); @@ -253,7 +253,7 @@ pman(const struct roff_node *p, int *line, int *col, int list) { for ( ; p; p = p->next) { - if (MAN_LINE & p->flags) + if (NODE_LINE & p->flags) pline(p->line, line, col, list); if (ROFFT_TEXT == p->type) pstring(p->string, p->pos, col, list); diff --git a/contrib/mdocml/eqn_html.c b/contrib/mdocml/eqn_html.c index f29733613bb..b6e7d914b86 100644 --- a/contrib/mdocml/eqn_html.c +++ b/contrib/mdocml/eqn_html.c @@ -1,6 +1,7 @@ -/* $Id: eqn_html.c,v 1.10 2014/10/12 19:31:41 schwarze Exp $ */ +/* $Id: eqn_html.c,v 1.11 2017/01/17 01:47:51 schwarze Exp $ */ /* * Copyright (c) 2011, 2014 Kristaps Dzonsons + * Copyright (c) 2017 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -31,7 +32,6 @@ static void eqn_box(struct html *p, const struct eqn_box *bp) { struct tag *post, *row, *cell, *t; - struct htmlpair tag[2]; const struct eqn_box *child, *parent; size_t i, j, rows; @@ -59,10 +59,10 @@ eqn_box(struct html *p, const struct eqn_box *bp) for (rows = 0; NULL != child; rows++) child = child->next; /* Print row-by-row. */ - post = print_otag(p, TAG_MTABLE, 0, NULL); + post = print_otag(p, TAG_MTABLE, ""); for (i = 0; i < rows; i++) { parent = bp->first->first; - row = print_otag(p, TAG_MTR, 0, NULL); + row = print_otag(p, TAG_MTR, ""); while (NULL != parent) { child = parent->first; for (j = 0; j < i; j++) { @@ -70,8 +70,7 @@ eqn_box(struct html *p, const struct eqn_box *bp) break; child = child->next; } - cell = print_otag - (p, TAG_MTD, 0, NULL); + cell = print_otag(p, TAG_MTD, ""); /* * If we have no data for this * particular cell, then print a @@ -89,28 +88,28 @@ eqn_box(struct html *p, const struct eqn_box *bp) switch (bp->pos) { case (EQNPOS_TO): - post = print_otag(p, TAG_MOVER, 0, NULL); + post = print_otag(p, TAG_MOVER, ""); break; case (EQNPOS_SUP): - post = print_otag(p, TAG_MSUP, 0, NULL); + post = print_otag(p, TAG_MSUP, ""); break; case (EQNPOS_FROM): - post = print_otag(p, TAG_MUNDER, 0, NULL); + post = print_otag(p, TAG_MUNDER, ""); break; case (EQNPOS_SUB): - post = print_otag(p, TAG_MSUB, 0, NULL); + post = print_otag(p, TAG_MSUB, ""); break; case (EQNPOS_OVER): - post = print_otag(p, TAG_MFRAC, 0, NULL); + post = print_otag(p, TAG_MFRAC, ""); break; case (EQNPOS_FROMTO): - post = print_otag(p, TAG_MUNDEROVER, 0, NULL); + post = print_otag(p, TAG_MUNDEROVER, ""); break; case (EQNPOS_SUBSUP): - post = print_otag(p, TAG_MSUBSUP, 0, NULL); + post = print_otag(p, TAG_MSUBSUP, ""); break; case (EQNPOS_SQRT): - post = print_otag(p, TAG_MSQRT, 0, NULL); + post = print_otag(p, TAG_MSQRT, ""); break; default: break; @@ -119,52 +118,49 @@ eqn_box(struct html *p, const struct eqn_box *bp) if (bp->top || bp->bottom) { assert(NULL == post); if (bp->top && NULL == bp->bottom) - post = print_otag(p, TAG_MOVER, 0, NULL); + post = print_otag(p, TAG_MOVER, ""); else if (bp->top && bp->bottom) - post = print_otag(p, TAG_MUNDEROVER, 0, NULL); + post = print_otag(p, TAG_MUNDEROVER, ""); else if (bp->bottom) - post = print_otag(p, TAG_MUNDER, 0, NULL); + post = print_otag(p, TAG_MUNDER, ""); } if (EQN_PILE == bp->type) { assert(NULL == post); if (bp->first != NULL && bp->first->type == EQN_LIST) - post = print_otag(p, TAG_MTABLE, 0, NULL); + post = print_otag(p, TAG_MTABLE, ""); } else if (bp->type == EQN_LIST && bp->parent && bp->parent->type == EQN_PILE) { assert(NULL == post); - post = print_otag(p, TAG_MTR, 0, NULL); - print_otag(p, TAG_MTD, 0, NULL); + post = print_otag(p, TAG_MTR, ""); + print_otag(p, TAG_MTD, ""); } if (NULL != bp->text) { assert(NULL == post); - post = print_otag(p, TAG_MI, 0, NULL); + post = print_otag(p, TAG_MI, ""); print_text(p, bp->text); } else if (NULL == post) { - if (NULL != bp->left || NULL != bp->right) { - PAIR_INIT(&tag[0], ATTR_OPEN, - NULL == bp->left ? "" : bp->left); - PAIR_INIT(&tag[1], ATTR_CLOSE, - NULL == bp->right ? "" : bp->right); - post = print_otag(p, TAG_MFENCED, 2, tag); - } + if (NULL != bp->left || NULL != bp->right) + post = print_otag(p, TAG_MFENCED, "??", + "open", bp->left == NULL ? "" : bp->left, + "close", bp->right == NULL ? "" : bp->right); if (NULL == post) - post = print_otag(p, TAG_MROW, 0, NULL); + post = print_otag(p, TAG_MROW, ""); else - print_otag(p, TAG_MROW, 0, NULL); + print_otag(p, TAG_MROW, ""); } eqn_box(p, bp->first); out: if (NULL != bp->bottom) { - t = print_otag(p, TAG_MO, 0, NULL); + t = print_otag(p, TAG_MO, ""); print_text(p, bp->bottom); print_tagq(p, t); } if (NULL != bp->top) { - t = print_otag(p, TAG_MO, 0, NULL); + t = print_otag(p, TAG_MO, ""); print_text(p, bp->top); print_tagq(p, t); } @@ -178,11 +174,9 @@ out: void print_eqn(struct html *p, const struct eqn *ep) { - struct htmlpair tag; struct tag *t; - PAIR_CLASS_INIT(&tag, "eqn"); - t = print_otag(p, TAG_MATH, 1, &tag); + t = print_otag(p, TAG_MATH, "c", "eqn"); p->flags |= HTML_NONOSPACE; eqn_box(p, ep->root); diff --git a/contrib/mdocml/html.c b/contrib/mdocml/html.c index adff053c1a0..24fd6f471f6 100644 --- a/contrib/mdocml/html.c +++ b/contrib/mdocml/html.c @@ -1,7 +1,7 @@ -/* $Id: html.c,v 1.192 2016/01/04 12:45:29 schwarze Exp $ */ +/* $Id: html.c,v 1.200 2017/01/21 02:29:57 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons - * Copyright (c) 2011-2015 Ingo Schwarze + * Copyright (c) 2011-2015, 2017 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -38,74 +38,65 @@ struct htmldata { const char *name; int flags; -#define HTML_CLRLINE (1 << 0) -#define HTML_NOSTACK (1 << 1) -#define HTML_AUTOCLOSE (1 << 2) /* Tag has auto-closure. */ +#define HTML_NOSTACK (1 << 0) +#define HTML_AUTOCLOSE (1 << 1) +#define HTML_NLBEFORE (1 << 2) +#define HTML_NLBEGIN (1 << 3) +#define HTML_NLEND (1 << 4) +#define HTML_NLAFTER (1 << 5) +#define HTML_NLAROUND (HTML_NLBEFORE | HTML_NLAFTER) +#define HTML_NLINSIDE (HTML_NLBEGIN | HTML_NLEND) +#define HTML_NLALL (HTML_NLAROUND | HTML_NLINSIDE) +#define HTML_INDENT (1 << 6) +#define HTML_NOINDENT (1 << 7) }; static const struct htmldata htmltags[TAG_MAX] = { - {"html", HTML_CLRLINE}, /* TAG_HTML */ - {"head", HTML_CLRLINE}, /* TAG_HEAD */ - {"body", HTML_CLRLINE}, /* TAG_BODY */ - {"meta", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_META */ - {"title", HTML_CLRLINE}, /* TAG_TITLE */ - {"div", HTML_CLRLINE}, /* TAG_DIV */ - {"h1", 0}, /* TAG_H1 */ - {"h2", 0}, /* TAG_H2 */ - {"span", 0}, /* TAG_SPAN */ - {"link", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_LINK */ - {"br", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_BR */ - {"a", 0}, /* TAG_A */ - {"table", HTML_CLRLINE}, /* TAG_TABLE */ - {"tbody", HTML_CLRLINE}, /* TAG_TBODY */ - {"col", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_COL */ - {"tr", HTML_CLRLINE}, /* TAG_TR */ - {"td", HTML_CLRLINE}, /* TAG_TD */ - {"li", HTML_CLRLINE}, /* TAG_LI */ - {"ul", HTML_CLRLINE}, /* TAG_UL */ - {"ol", HTML_CLRLINE}, /* TAG_OL */ - {"dl", HTML_CLRLINE}, /* TAG_DL */ - {"dt", HTML_CLRLINE}, /* TAG_DT */ - {"dd", HTML_CLRLINE}, /* TAG_DD */ - {"blockquote", HTML_CLRLINE}, /* TAG_BLOCKQUOTE */ - {"pre", HTML_CLRLINE }, /* TAG_PRE */ - {"b", 0 }, /* TAG_B */ - {"i", 0 }, /* TAG_I */ - {"code", 0 }, /* TAG_CODE */ - {"small", 0 }, /* TAG_SMALL */ - {"style", HTML_CLRLINE}, /* TAG_STYLE */ - {"math", HTML_CLRLINE}, /* TAG_MATH */ - {"mrow", 0}, /* TAG_MROW */ - {"mi", 0}, /* TAG_MI */ - {"mo", 0}, /* TAG_MO */ - {"msup", 0}, /* TAG_MSUP */ - {"msub", 0}, /* TAG_MSUB */ - {"msubsup", 0}, /* TAG_MSUBSUP */ - {"mfrac", 0}, /* TAG_MFRAC */ - {"msqrt", 0}, /* TAG_MSQRT */ - {"mfenced", 0}, /* TAG_MFENCED */ - {"mtable", 0}, /* TAG_MTABLE */ - {"mtr", 0}, /* TAG_MTR */ - {"mtd", 0}, /* TAG_MTD */ - {"munderover", 0}, /* TAG_MUNDEROVER */ - {"munder", 0}, /* TAG_MUNDER*/ - {"mover", 0}, /* TAG_MOVER*/ -}; - -static const char *const htmlattrs[ATTR_MAX] = { - "name", /* ATTR_NAME */ - "rel", /* ATTR_REL */ - "href", /* ATTR_HREF */ - "type", /* ATTR_TYPE */ - "media", /* ATTR_MEDIA */ - "class", /* ATTR_CLASS */ - "style", /* ATTR_STYLE */ - "id", /* ATTR_ID */ - "colspan", /* ATTR_COLSPAN */ - "charset", /* ATTR_CHARSET */ - "open", /* ATTR_OPEN */ - "close", /* ATTR_CLOSE */ - "mathvariant", /* ATTR_MATHVARIANT */ + {"html", HTML_NLALL}, + {"head", HTML_NLALL | HTML_INDENT}, + {"body", HTML_NLALL}, + {"meta", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL}, + {"title", HTML_NLAROUND}, + {"div", HTML_NLAROUND}, + {"h1", HTML_NLAROUND}, + {"h2", HTML_NLAROUND}, + {"span", 0}, + {"link", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL}, + {"br", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL}, + {"a", 0}, + {"table", HTML_NLALL | HTML_INDENT}, + {"tbody", HTML_NLALL | HTML_INDENT}, + {"col", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL}, + {"tr", HTML_NLALL | HTML_INDENT}, + {"td", HTML_NLAROUND}, + {"li", HTML_NLAROUND | HTML_INDENT}, + {"ul", HTML_NLALL | HTML_INDENT}, + {"ol", HTML_NLALL | HTML_INDENT}, + {"dl", HTML_NLALL | HTML_INDENT}, + {"dt", HTML_NLAROUND}, + {"dd", HTML_NLAROUND | HTML_INDENT}, + {"pre", HTML_NLALL | HTML_NOINDENT}, + {"b", 0}, + {"i", 0}, + {"code", 0}, + {"small", 0}, + {"style", HTML_NLALL | HTML_INDENT}, + {"math", HTML_NLALL | HTML_INDENT}, + {"mrow", 0}, + {"mi", 0}, + {"mo", 0}, + {"msup", 0}, + {"msub", 0}, + {"msubsup", 0}, + {"mfrac", 0}, + {"msqrt", 0}, + {"mfenced", 0}, + {"mtable", 0}, + {"mtr", 0}, + {"mtd", 0}, + {"munderover", 0}, + {"munder", 0}, + {"mover", 0}, }; static const char *const roffscales[SCALE_MAX] = { @@ -121,12 +112,18 @@ static const char *const roffscales[SCALE_MAX] = { "ex", /* SCALE_FS */ }; -static void bufncat(struct html *, const char *, size_t); +static void a2width(const char *, struct roffsu *); +static void print_byte(struct html *, char); +static void print_endline(struct html *); +static void print_endword(struct html *); +static void print_indent(struct html *); +static void print_word(struct html *, const char *); + static void print_ctag(struct html *, struct tag *); -static int print_escape(char); -static int print_encode(struct html *, const char *, int); +static int print_escape(struct html *, char); +static int print_encode(struct html *, const char *, const char *, int); +static void print_href(struct html *, const char *, const char *, int); static void print_metaf(struct html *, enum mandoc_esc); -static void print_attr(struct html *, const char *, const char *); void * @@ -165,36 +162,27 @@ html_free(void *p) void print_gen_head(struct html *h) { - struct htmlpair tag[4]; struct tag *t; - tag[0].key = ATTR_CHARSET; - tag[0].val = "utf-8"; - print_otag(h, TAG_META, 1, tag); + print_otag(h, TAG_META, "?", "charset", "utf-8"); /* * Print a default style-sheet. */ - t = print_otag(h, TAG_STYLE, 0, NULL); - print_text(h, "table.head, table.foot { width: 100%; }\n" - "td.head-rtitle, td.foot-os { text-align: right; }\n" - "td.head-vol { text-align: center; }\n" - "table.foot td { width: 50%; }\n" - "table.head td { width: 33%; }\n" - "div.spacer { margin: 1em 0; }\n"); + + t = print_otag(h, TAG_STYLE, ""); + print_text(h, "table.head, table.foot { width: 100%; }"); + print_endline(h); + print_text(h, "td.head-rtitle, td.foot-os { text-align: right; }"); + print_endline(h); + print_text(h, "td.head-vol { text-align: center; }"); + print_endline(h); + print_text(h, "div.Pp { margin: 1ex 0ex; }"); print_tagq(h, t); - if (h->style) { - tag[0].key = ATTR_REL; - tag[0].val = "stylesheet"; - tag[1].key = ATTR_HREF; - tag[1].val = h->style; - tag[2].key = ATTR_TYPE; - tag[2].val = "text/css"; - tag[3].key = ATTR_MEDIA; - tag[3].val = "all"; - print_otag(h, TAG_LINK, 4, tag); - } + if (h->style) + print_otag(h, TAG_LINK, "?h??", "rel", "stylesheet", + h->style, "type", "text/css", "media", "all"); } static void @@ -233,14 +221,14 @@ print_metaf(struct html *h, enum mandoc_esc deco) switch (font) { case HTMLFONT_ITALIC: - h->metaf = print_otag(h, TAG_I, 0, NULL); + h->metaf = print_otag(h, TAG_I, ""); break; case HTMLFONT_BOLD: - h->metaf = print_otag(h, TAG_B, 0, NULL); + h->metaf = print_otag(h, TAG_B, ""); break; case HTMLFONT_BI: - h->metaf = print_otag(h, TAG_B, 0, NULL); - print_otag(h, TAG_I, 0, NULL); + h->metaf = print_otag(h, TAG_B, ""); + print_otag(h, TAG_I, ""); break; default: break; @@ -299,27 +287,27 @@ html_strlen(const char *cp) } static int -print_escape(char c) +print_escape(struct html *h, char c) { switch (c) { case '<': - printf("<"); + print_word(h, "<"); break; case '>': - printf(">"); + print_word(h, ">"); break; case '&': - printf("&"); + print_word(h, "&"); break; case '"': - printf("""); + print_word(h, """); break; case ASCII_NBRSP: - printf(" "); + print_word(h, " "); break; case ASCII_HYPH: - putchar('-'); + print_byte(h, '-'); break; case ASCII_BREAK: break; @@ -330,8 +318,9 @@ print_escape(char c) } static int -print_encode(struct html *h, const char *p, int norecurse) +print_encode(struct html *h, const char *p, const char *pend, int norecurse) { + char numbuf[16]; size_t sz; int c, len, nospace; const char *seq; @@ -339,24 +328,28 @@ print_encode(struct html *h, const char *p, int norecurse) static const char rejs[9] = { '\\', '<', '>', '&', '"', ASCII_NBRSP, ASCII_HYPH, ASCII_BREAK, '\0' }; + if (pend == NULL) + pend = strchr(p, '\0'); + nospace = 0; - while ('\0' != *p) { + while (p < pend) { if (HTML_SKIPCHAR & h->flags && '\\' != *p) { h->flags &= ~HTML_SKIPCHAR; p++; continue; } - sz = strcspn(p, rejs); + for (sz = strcspn(p, rejs); sz-- && p < pend; p++) + if (*p == ' ') + print_endword(h); + else + print_byte(h, *p); - fwrite(p, 1, sz, stdout); - p += (int)sz; - - if ('\0' == *p) + if (p >= pend) break; - if (print_escape(*p++)) + if (print_escape(h, *p++)) continue; esc = mandoc_escape(&p, &seq, &len); @@ -415,33 +408,57 @@ print_encode(struct html *h, const char *p, int norecurse) if ((c < 0x20 && c != 0x09) || (c > 0x7E && c < 0xA0)) c = 0xFFFD; - if (c > 0x7E) - printf("&#%d;", c); - else if ( ! print_escape(c)) - putchar(c); + if (c > 0x7E) { + (void)snprintf(numbuf, sizeof(numbuf), "&#%d;", c); + print_word(h, numbuf); + } else if (print_escape(h, c) == 0) + print_byte(h, c); } return nospace; } static void -print_attr(struct html *h, const char *key, const char *val) +print_href(struct html *h, const char *name, const char *sec, int man) { - printf(" %s=\"", key); - (void)print_encode(h, val, 1); - putchar('\"'); + const char *p, *pp; + + pp = man ? h->base_man : h->base_includes; + while ((p = strchr(pp, '%')) != NULL) { + print_encode(h, pp, p, 1); + if (man && p[1] == 'S') { + if (sec == NULL) + print_byte(h, '1'); + else + print_encode(h, sec, NULL, 1); + } else if ((man && p[1] == 'N') || + (man == 0 && p[1] == 'I')) + print_encode(h, name, NULL, 1); + else + print_encode(h, p, p + 2, 1); + pp = p + 2; + } + if (*pp != '\0') + print_encode(h, pp, NULL, 1); } struct tag * -print_otag(struct html *h, enum htmltag tag, - int sz, const struct htmlpair *p) +print_otag(struct html *h, enum htmltag tag, const char *fmt, ...) { - int i; + va_list ap; + struct roffsu mysu, *su; + char numbuf[16]; struct tag *t; + const char *attr; + char *s; + double v; + int i, have_style, tflags; + + tflags = htmltags[tag].flags; /* Push this tags onto the stack of open scopes. */ - if ( ! (HTML_NOSTACK & htmltags[tag].flags)) { + if ((tflags & HTML_NOSTACK) == 0) { t = mandoc_malloc(sizeof(struct tag)); t->tag = tag; t->next = h->tags.head; @@ -449,16 +466,19 @@ print_otag(struct html *h, enum htmltag tag, } else t = NULL; - if ( ! (HTML_NOSPACE & h->flags)) - if ( ! (HTML_CLRLINE & htmltags[tag].flags)) { - /* Manage keeps! */ - if ( ! (HTML_KEEP & h->flags)) { - if (HTML_PREKEEP & h->flags) - h->flags |= HTML_KEEP; - putchar(' '); - } else - printf(" "); + if (tflags & HTML_NLBEFORE) + print_endline(h); + if (h->col == 0) + print_indent(h); + else if ((h->flags & HTML_NOSPACE) == 0) { + if (h->flags & HTML_KEEP) + print_word(h, " "); + else { + if (h->flags & HTML_PREKEEP) + h->flags |= HTML_KEEP; + print_endword(h); } + } if ( ! (h->flags & HTML_NONOSPACE)) h->flags &= ~HTML_NOSPACE; @@ -467,21 +487,164 @@ print_otag(struct html *h, enum htmltag tag, /* Print out the tag name and attributes. */ - printf("<%s", htmltags[tag].name); - for (i = 0; i < sz; i++) - print_attr(h, htmlattrs[p[i].key], p[i].val); + print_byte(h, '<'); + print_word(h, htmltags[tag].name); + + va_start(ap, fmt); + + have_style = 0; + while (*fmt != '\0') { + if (*fmt == 's') { + print_word(h, " style=\""); + have_style = 1; + fmt++; + break; + } + s = va_arg(ap, char *); + switch (*fmt++) { + case 'c': + attr = "class"; + break; + case 'h': + attr = "href"; + break; + case 'i': + attr = "id"; + break; + case '?': + attr = s; + s = va_arg(ap, char *); + break; + default: + abort(); + } + print_byte(h, ' '); + print_word(h, attr); + print_byte(h, '='); + print_byte(h, '"'); + switch (*fmt) { + case 'M': + print_href(h, s, va_arg(ap, char *), 1); + fmt++; + break; + case 'I': + print_href(h, s, NULL, 0); + fmt++; + break; + case 'R': + print_byte(h, '#'); + fmt++; + /* FALLTHROUGH */ + default: + print_encode(h, s, NULL, 1); + break; + } + print_byte(h, '"'); + } + + /* Print out styles. */ + + s = NULL; + su = &mysu; + while (*fmt != '\0') { + + /* First letter: input argument type. */ + + switch (*fmt++) { + case 'h': + i = va_arg(ap, int); + SCALE_HS_INIT(su, i); + break; + case 's': + s = va_arg(ap, char *); + break; + case 'u': + su = va_arg(ap, struct roffsu *); + break; + case 'v': + i = va_arg(ap, int); + SCALE_VS_INIT(su, i); + break; + case 'w': + s = va_arg(ap, char *); + a2width(s, su); + break; + default: + abort(); + } + + /* Second letter: style name. */ + + switch (*fmt++) { + case 'b': + attr = "margin-bottom"; + break; + case 'h': + attr = "height"; + break; + case 'i': + attr = "text-indent"; + break; + case 'l': + attr = "margin-left"; + break; + case 't': + attr = "margin-top"; + break; + case 'w': + attr = "width"; + break; + case 'W': + attr = "min-width"; + break; + case '?': + print_word(h, s); + print_byte(h, ':'); + print_byte(h, ' '); + print_word(h, va_arg(ap, char *)); + print_byte(h, ';'); + if (*fmt != '\0') + print_byte(h, ' '); + continue; + default: + abort(); + } + v = su->scale; + if (su->unit == SCALE_MM && (v /= 100.0) == 0.0) + v = 1.0; + else if (su->unit == SCALE_BU) + v /= 24.0; + print_word(h, attr); + print_byte(h, ':'); + print_byte(h, ' '); + (void)snprintf(numbuf, sizeof(numbuf), "%.2f", v); + print_word(h, numbuf); + print_word(h, roffscales[su->unit]); + print_byte(h, ';'); + if (*fmt != '\0') + print_byte(h, ' '); + } + if (have_style) + print_byte(h, '"'); + + va_end(ap); /* Accommodate for "well-formed" singleton escaping. */ if (HTML_AUTOCLOSE & htmltags[tag].flags) - putchar('/'); + print_byte(h, '/'); - putchar('>'); + print_byte(h, '>'); - h->flags |= HTML_NOSPACE; + if (tflags & HTML_NLBEGIN) + print_endline(h); + else + h->flags |= HTML_NOSPACE; - if ((HTML_AUTOCLOSE | HTML_CLRLINE) & htmltags[tag].flags) - putchar('\n'); + if (tflags & HTML_INDENT) + h->indent++; + if (tflags & HTML_NOINDENT) + h->noindent++; return t; } @@ -489,6 +652,7 @@ print_otag(struct html *h, enum htmltag tag, static void print_ctag(struct html *h, struct tag *tag) { + int tflags; /* * Remember to close out and nullify the current @@ -499,11 +663,21 @@ print_ctag(struct html *h, struct tag *tag) if (tag == h->tblt) h->tblt = NULL; - printf("", htmltags[tag->tag].name); - if (HTML_CLRLINE & htmltags[tag->tag].flags) { - h->flags |= HTML_NOSPACE; - putchar('\n'); - } + tflags = htmltags[tag->tag].flags; + + if (tflags & HTML_INDENT) + h->indent--; + if (tflags & HTML_NOINDENT) + h->noindent--; + if (tflags & HTML_NLEND) + print_endline(h); + print_indent(h); + print_byte(h, '<'); + print_byte(h, '/'); + print_word(h, htmltags[tag->tag].name); + print_byte(h, '>'); + if (tflags & HTML_NLAFTER) + print_endline(h); h->tags.head = tag->next; free(tag); @@ -512,42 +686,41 @@ print_ctag(struct html *h, struct tag *tag) void print_gen_decls(struct html *h) { - - puts(""); + print_word(h, ""); + print_endline(h); } void print_text(struct html *h, const char *word) { - - if ( ! (HTML_NOSPACE & h->flags)) { - /* Manage keeps! */ + if (h->col && (h->flags & HTML_NOSPACE) == 0) { if ( ! (HTML_KEEP & h->flags)) { if (HTML_PREKEEP & h->flags) h->flags |= HTML_KEEP; - putchar(' '); + print_endword(h); } else - printf(" "); + print_word(h, " "); } assert(NULL == h->metaf); switch (h->metac) { case HTMLFONT_ITALIC: - h->metaf = print_otag(h, TAG_I, 0, NULL); + h->metaf = print_otag(h, TAG_I, ""); break; case HTMLFONT_BOLD: - h->metaf = print_otag(h, TAG_B, 0, NULL); + h->metaf = print_otag(h, TAG_B, ""); break; case HTMLFONT_BI: - h->metaf = print_otag(h, TAG_B, 0, NULL); - print_otag(h, TAG_I, 0, NULL); + h->metaf = print_otag(h, TAG_B, ""); + print_otag(h, TAG_I, ""); break; default: + print_indent(h); break; } assert(word); - if ( ! print_encode(h, word, 0)) { + if ( ! print_encode(h, word, NULL, 0)) { if ( ! (h->flags & HTML_NONOSPACE)) h->flags &= ~HTML_NOSPACE; h->flags &= ~HTML_NONEWLINE; @@ -590,138 +763,136 @@ void print_paragraph(struct html *h) { struct tag *t; - struct htmlpair tag; - PAIR_CLASS_INIT(&tag, "spacer"); - t = print_otag(h, TAG_DIV, 1, &tag); + t = print_otag(h, TAG_DIV, "c", "Pp"); print_tagq(h, t); } -void -bufinit(struct html *h) -{ - - h->buf[0] = '\0'; - h->buflen = 0; -} - -void -bufcat_style(struct html *h, const char *key, const char *val) -{ - - bufcat(h, key); - bufcat(h, ":"); - bufcat(h, val); - bufcat(h, ";"); -} - -void -bufcat(struct html *h, const char *p) -{ - - /* - * XXX This is broken and not easy to fix. - * When using the -Oincludes option, buffmt_includes() - * may pass in strings overrunning BUFSIZ, causing a crash. - */ - - h->buflen = strlcat(h->buf, p, BUFSIZ); - assert(h->buflen < BUFSIZ); -} - -void -bufcat_fmt(struct html *h, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - (void)vsnprintf(h->buf + (int)h->buflen, - BUFSIZ - h->buflen - 1, fmt, ap); - va_end(ap); - h->buflen = strlen(h->buf); -} +/*********************************************************************** + * Low level output functions. + * They implement line breaking using a short static buffer. + ***********************************************************************/ +/* + * Buffer one HTML output byte. + * If the buffer is full, flush and deactivate it and start a new line. + * If the buffer is inactive, print directly. + */ static void -bufncat(struct html *h, const char *p, size_t sz) +print_byte(struct html *h, char c) { - - assert(h->buflen + sz + 1 < BUFSIZ); - strncat(h->buf, p, sz); - h->buflen += sz; -} - -void -buffmt_includes(struct html *h, const char *name) -{ - const char *p, *pp; - - pp = h->base_includes; - - bufinit(h); - while (NULL != (p = strchr(pp, '%'))) { - bufncat(h, pp, (size_t)(p - pp)); - switch (*(p + 1)) { - case'I': - bufcat(h, name); - break; - default: - bufncat(h, p, 2); - break; - } - pp = p + 2; + if ((h->flags & HTML_BUFFER) == 0) { + putchar(c); + h->col++; + return; } - if (pp) - bufcat(h, pp); -} -void -buffmt_man(struct html *h, const char *name, const char *sec) -{ - const char *p, *pp; - - pp = h->base_man; - - bufinit(h); - while (NULL != (p = strchr(pp, '%'))) { - bufncat(h, pp, (size_t)(p - pp)); - switch (*(p + 1)) { - case 'S': - bufcat(h, sec ? sec : "1"); - break; - case 'N': - bufcat_fmt(h, "%s", name); - break; - default: - bufncat(h, p, 2); - break; - } - pp = p + 2; + if (h->col + h->bufcol < sizeof(h->buf)) { + h->buf[h->bufcol++] = c; + return; } - if (pp) - bufcat(h, pp); + + putchar('\n'); + h->col = 0; + print_indent(h); + putchar(' '); + putchar(' '); + fwrite(h->buf, h->bufcol, 1, stdout); + putchar(c); + h->col = (h->indent + 1) * 2 + h->bufcol + 1; + h->bufcol = 0; + h->flags &= ~HTML_BUFFER; } -void -bufcat_su(struct html *h, const char *p, const struct roffsu *su) +/* + * If something was printed on the current output line, end it. + * Not to be called right after print_indent(). + */ +static void +print_endline(struct html *h) { - double v; + if (h->col == 0) + return; - v = su->scale; - if (SCALE_MM == su->unit && 0.0 == (v /= 100.0)) - v = 1.0; - else if (SCALE_BU == su->unit) - v /= 24.0; - - bufcat_fmt(h, "%s: %.2f%s;", p, v, roffscales[su->unit]); + if (h->bufcol) { + putchar(' '); + fwrite(h->buf, h->bufcol, 1, stdout); + h->bufcol = 0; + } + putchar('\n'); + h->col = 0; + h->flags |= HTML_NOSPACE; + h->flags &= ~HTML_BUFFER; } -void -bufcat_id(struct html *h, const char *src) +/* + * Flush the HTML output buffer. + * If it is inactive, activate it. + */ +static void +print_endword(struct html *h) { + if (h->noindent) { + print_byte(h, ' '); + return; + } - /* Cf. . */ - - for (; '\0' != *src; src++) - bufncat(h, *src == ' ' ? "_" : src, 1); + if ((h->flags & HTML_BUFFER) == 0) { + h->col++; + h->flags |= HTML_BUFFER; + } else if (h->bufcol) { + putchar(' '); + fwrite(h->buf, h->bufcol, 1, stdout); + h->col += h->bufcol + 1; + } + h->bufcol = 0; +} + +/* + * If at the beginning of a new output line, + * perform indentation and mark the line as containing output. + * Make sure to really produce some output right afterwards, + * but do not use print_otag() for producing it. + */ +static void +print_indent(struct html *h) +{ + size_t i; + + if (h->col) + return; + + if (h->noindent == 0) { + h->col = h->indent * 2; + for (i = 0; i < h->col; i++) + putchar(' '); + } + h->flags &= ~HTML_NOSPACE; +} + +/* + * Print or buffer some characters + * depending on the current HTML output buffer state. + */ +static void +print_word(struct html *h, const char *cp) +{ + while (*cp != '\0') + print_byte(h, *cp++); +} + +/* + * Calculate the scaling unit passed in a `-width' argument. This uses + * either a native scaling unit (e.g., 1i, 2m) or the string length of + * the value. + */ +static void +a2width(const char *p, struct roffsu *su) +{ + if (a2roffsu(p, su, SCALE_MAX) < 2) { + su->unit = SCALE_EN; + su->scale = html_strlen(p); + } else if (su->scale < 0.0) + su->scale = 0.0; } diff --git a/contrib/mdocml/html.h b/contrib/mdocml/html.h index 27dc140185d..19532c49d93 100644 --- a/contrib/mdocml/html.h +++ b/contrib/mdocml/html.h @@ -1,6 +1,7 @@ -/* $Id: html.h,v 1.72 2015/11/07 14:01:16 schwarze Exp $ */ +/* $Id: html.h,v 1.78 2017/01/19 16:59:30 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons + * Copyright (c) 2017 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -39,7 +40,6 @@ enum htmltag { TAG_DL, TAG_DT, TAG_DD, - TAG_BLOCKQUOTE, TAG_PRE, TAG_B, TAG_I, @@ -65,23 +65,6 @@ enum htmltag { TAG_MAX }; -enum htmlattr { - ATTR_NAME, - ATTR_REL, - ATTR_HREF, - ATTR_TYPE, - ATTR_MEDIA, - ATTR_CLASS, - ATTR_STYLE, - ATTR_ID, - ATTR_COLSPAN, - ATTR_CHARSET, - ATTR_OPEN, - ATTR_CLOSE, - ATTR_MATHVARIANT, - ATTR_MAX -}; - enum htmlfont { HTMLFONT_NONE = 0, HTMLFONT_BOLD, @@ -99,22 +82,6 @@ struct tagq { struct tag *head; }; -struct htmlpair { - enum htmlattr key; - const char *val; -}; - -#define PAIR_INIT(p, t, v) \ - do { \ - (p)->key = (t); \ - (p)->val = (v); \ - } while (/* CONSTCOND */ 0) - -#define PAIR_ID_INIT(p, v) PAIR_INIT(p, ATTR_ID, v) -#define PAIR_CLASS_INIT(p, v) PAIR_INIT(p, ATTR_CLASS, v) -#define PAIR_HREF_INIT(p, v) PAIR_INIT(p, ATTR_HREF, v) -#define PAIR_STYLE_INIT(p, h) PAIR_INIT(p, ATTR_STYLE, (h)->buf) - struct html { int flags; #define HTML_NOSPACE (1 << 0) /* suppress next space */ @@ -127,14 +94,18 @@ struct html { #define HTML_NOSPLIT (1 << 7) /* do not break line before .An */ #define HTML_SPLIT (1 << 8) /* break line before .An */ #define HTML_NONEWLINE (1 << 9) /* No line break in nofill mode. */ +#define HTML_BUFFER (1 << 10) /* Collect a word to see if it fits. */ + size_t indent; /* current output indentation level */ + int noindent; /* indent disabled by
 */
+	size_t		  col; /* current output byte position */
+	size_t		  bufcol; /* current buf byte position */
+	char		  buf[80]; /* output buffer */
 	struct tagq	  tags; /* stack of open tags */
 	struct rofftbl	  tbl; /* current table */
 	struct tag	 *tblt; /* current open table scope */
 	char		 *base_man; /* base for manpage href */
 	char		 *base_includes; /* base for include href */
 	char		 *style; /* style-sheet URI */
-	char		  buf[BUFSIZ]; /* see bufcat and friends */
-	size_t		  buflen;
 	struct tag	 *metaf; /* current open font scope */
 	enum htmlfont	  metal; /* last used font */
 	enum htmlfont	  metac; /* current font mode */
@@ -148,8 +119,7 @@ struct	eqn;
 
 void		  print_gen_decls(struct html *);
 void		  print_gen_head(struct html *);
-struct tag	 *print_otag(struct html *, enum htmltag,
-				int, const struct htmlpair *);
+struct tag	 *print_otag(struct html *, enum htmltag, const char *, ...);
 void		  print_tagq(struct html *, const struct tag *);
 void		  print_stagq(struct html *, const struct tag *);
 void		  print_text(struct html *, const char *);
@@ -158,19 +128,4 @@ void		  print_tbl(struct html *, const struct tbl_span *);
 void		  print_eqn(struct html *, const struct eqn *);
 void		  print_paragraph(struct html *);
 
-#if __GNUC__ - 0 >= 4
-__attribute__((__format__ (__printf__, 2, 3)))
-#endif
-void		  bufcat_fmt(struct html *, const char *, ...);
-void		  bufcat(struct html *, const char *);
-void		  bufcat_id(struct html *, const char *);
-void		  bufcat_style(struct html *,
-			const char *, const char *);
-void		  bufcat_su(struct html *, const char *,
-			const struct roffsu *);
-void		  bufinit(struct html *);
-void		  buffmt_man(struct html *,
-			const char *, const char *);
-void		  buffmt_includes(struct html *, const char *);
-
 int		  html_strlen(const char *);
diff --git a/contrib/mdocml/lib.in b/contrib/mdocml/lib.in
index dec561af672..e3e1af2aecd 100644
--- a/contrib/mdocml/lib.in
+++ b/contrib/mdocml/lib.in
@@ -1,4 +1,4 @@
-/*	$Id: lib.in,v 1.18 2014/01/06 00:53:33 schwarze Exp $ */
+/*	$Id: lib.in,v 1.19 2016/11/23 20:22:13 schwarze Exp $ */
 /*
  * Copyright (c) 2009 Kristaps Dzonsons 
  * Copyright (c) 2009, 2012 Joerg Sonnenberger 
@@ -85,7 +85,8 @@ LINE("libnpf",		"NPF Packet Filter Library (libnpf, \\-lnpf)")
 LINE("libnv",		"Name/value pairs library (libnv, \\-lnv)")
 LINE("libossaudio",	"OSS Audio Emulation Library (libossaudio, \\-lossaudio)")
 LINE("libpam",		"Pluggable Authentication Module Library (libpam, \\-lpam)")
-LINE("libpcap",		"Packet Capture Library (libpcap, \\-lpcap)")
+LINE("libpanel",	"Z-order for curses windows (libpanel, \\-lpanel)")
+LINE("libpcap",		"Packet capture Library (libpcap, \\-lpcap)")
 LINE("libpci",		"PCI Bus Access Library (libpci, \\-lpci)")
 LINE("libpmc",		"Performance Counters Library (libpmc, \\-lpmc)")
 LINE("libppath",	"Property-List Paths Library (libppath, \\-lppath)")
@@ -96,6 +97,7 @@ LINE("libproc",		"Processor Monitoring and Analysis Library (libproc, \\-lproc)"
 LINE("libprocstat",	"Process and Files Information Retrieval (libprocstat, \\-lprocstat)")
 LINE("libprop",		"Property Container Object Library (libprop, \\-lprop)")
 LINE("libpthread",	"POSIX Threads Library (libpthread, \\-lpthread)")
+LINE("libpthread_dbg",	"POSIX Debug Threads Library (libpthread_dbg, \\-lpthread_dbg)")
 LINE("libpuffs",	"puffs Convenience Library (libpuffs, \\-lpuffs)")
 LINE("libquota",	"Disk Quota Access and Control Library (libquota, \\-lquota)")
 LINE("libradius",	"RADIUS Client Library (libradius, \\-lradius)")
@@ -104,7 +106,8 @@ LINE("libresolv",	"DNS Resolver Library (libresolv, \\-lresolv)")
 LINE("librpcsec_gss",	"RPC GSS-API Authentication Library (librpcsec_gss, \\-lrpcsec_gss)")
 LINE("librpcsvc",	"RPC Service Library (librpcsvc, \\-lrpcsvc)")
 LINE("librt",		"POSIX Real\\-time Library (librt, \\-lrt)")
-LINE("librtld_db",	"Run-time Linker Debugging Library (librtld_db, \\-lrtld_db)")
+LINE("librtld_db",	"Debugging interface to the runtime linker Library (librtld_db, \\-lrtld_db)")
+LINE("librumpclient",	"Clientside Stubs for rump Kernel Remote Protocols (librumpclient, \\-lrumpclient)")
 LINE("libsaslc",	"Simple Authentication and Security Layer client library (libsaslc, \\-lsaslc)")
 LINE("libsbuf",		"Safe String Composition Library (libsbuf, \\-lsbuf)")
 LINE("libsdp",		"Bluetooth Service Discovery Protocol User Library (libsdp, \\-lsdp)")
diff --git a/contrib/mdocml/libmandoc.h b/contrib/mdocml/libmandoc.h
index 9ed8f15049f..96e726cbce7 100644
--- a/contrib/mdocml/libmandoc.h
+++ b/contrib/mdocml/libmandoc.h
@@ -1,4 +1,4 @@
-/*	$Id: libmandoc.h,v 1.63 2016/07/07 19:19:01 schwarze Exp $ */
+/*	$Id: libmandoc.h,v 1.64 2016/07/19 13:36:13 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons 
  * Copyright (c) 2013, 2014, 2015 Ingo Schwarze 
@@ -41,11 +41,9 @@ struct	roff_man;
 
 void		 mandoc_msg(enum mandocerr, struct mparse *,
 			int, int, const char *);
-#if __GNUC__ - 0 >= 4
-__attribute__((__format__ (__printf__, 5, 6)))
-#endif
 void		 mandoc_vmsg(enum mandocerr, struct mparse *,
-			int, int, const char *, ...);
+			int, int, const char *, ...)
+			__attribute__((__format__ (printf, 5, 6)));
 char		*mandoc_getarg(struct mparse *, char **, int, int *);
 char		*mandoc_normdate(struct mparse *, char *, int, int);
 int		 mandoc_eos(const char *, size_t);
diff --git a/contrib/mdocml/main.c b/contrib/mdocml/main.c
index 527db244283..b64b3be1150 100644
--- a/contrib/mdocml/main.c
+++ b/contrib/mdocml/main.c
@@ -1,7 +1,7 @@
-/*	$Id: main.c,v 1.269 2016/07/12 05:18:38 kristaps Exp $ */
+/*	$Id: main.c,v 1.279 2017/01/09 17:49:57 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons 
- * Copyright (c) 2010-2012, 2014-2016 Ingo Schwarze 
+ * Copyright (c) 2010-2012, 2014-2017 Ingo Schwarze 
  * Copyright (c) 2010 Joerg Sonnenberger 
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -51,12 +51,6 @@
 #include "manconf.h"
 #include "mansearch.h"
 
-#if !defined(__GNUC__) || (__GNUC__ < 2)
-# if !defined(lint)
-#  define __attribute__(x)
-# endif
-#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */
-
 enum	outmode {
 	OUTMODE_DEF = 0,
 	OUTMODE_FLN,
@@ -87,6 +81,9 @@ struct	curparse {
 	struct manoutput *outopts;	/* output options */
 };
 
+
+int			  mandocdb(int, char *[]);
+
 static	int		  fs_lookup(const struct manpaths *,
 				size_t ipath, const char *,
 				const char *, const char *,
@@ -95,12 +92,10 @@ static	void		  fs_search(const struct mansearch *,
 				const struct manpaths *, int, char**,
 				struct manpage **, size_t *);
 static	int		  koptions(int *, char *);
-#if HAVE_SQLITE3
-int			  mandocdb(int, char**);
-#endif
 static	int		  moptions(int *, char *);
 static	void		  mmsg(enum mandocerr, enum mandoclevel,
 				const char *, int, int, const char *);
+static	void		  outdata_alloc(struct curparse *);
 static	void		  parse(struct curparse *, int, const char *);
 static	void		  passthrough(const char *, int, int);
 static	pid_t		  spawn_pager(struct tag_files *);
@@ -151,11 +146,9 @@ main(int argc, char *argv[])
 	setprogname(progname);
 #endif
 
-#if HAVE_SQLITE3
 	if (strncmp(progname, "mandocdb", 8) == 0 ||
 	    strcmp(progname, BINM_MAKEWHATIS) == 0)
 		return mandocdb(argc, argv);
-#endif
 
 #if HAVE_PLEDGE
 	if (pledge("stdio rpath tmppath tty proc exec flock", NULL) == -1)
@@ -353,9 +346,6 @@ main(int argc, char *argv[])
 	/* man(1), whatis(1), apropos(1) */
 
 	if (search.argmode != ARG_FILE) {
-		if (argc == 0)
-			usage(search.argmode);
-
 		if (search.argmode == ARG_NAME &&
 		    outmode == OUTMODE_ONE)
 			search.firstmatch = 1;
@@ -363,19 +353,9 @@ main(int argc, char *argv[])
 		/* Access the mandoc database. */
 
 		manconf_parse(&conf, conf_file, defpaths, auxpaths);
-#if HAVE_SQLITE3
-		mansearch_setup(1);
 		if ( ! mansearch(&search, &conf.manpath,
 		    argc, argv, &res, &sz))
 			usage(search.argmode);
-#else
-		if (search.argmode != ARG_NAME) {
-			fputs("mandoc: database support not compiled in\n",
-			    stderr);
-			return (int)MANDOCLEVEL_BADARG;
-		}
-		sz = 0;
-#endif
 
 		if (sz == 0) {
 			if (search.argmode == ARG_NAME)
@@ -478,7 +458,7 @@ main(int argc, char *argv[])
 
 			if (resp == NULL)
 				parse(&curp, fd, *argv);
-			else if (resp->form & FORM_SRC) {
+			else if (resp->form == FORM_SRC) {
 				/* For .so only; ignore failure. */
 				chdir(conf.manpath.paths[resp->ipath]);
 				parse(&curp, fd, resp->file);
@@ -486,8 +466,11 @@ main(int argc, char *argv[])
 				passthrough(resp->file, fd,
 				    conf.output.synopsisonly);
 
-			if (argc > 1 && curp.outtype <= OUTT_UTF8)
+			if (argc > 1 && curp.outtype <= OUTT_UTF8) {
+				if (curp.outdata == NULL)
+					outdata_alloc(&curp);
 				terminal_sepline(curp.outdata);
+			}
 		} else if (rc < MANDOCLEVEL_ERROR)
 			rc = MANDOCLEVEL_ERROR;
 
@@ -526,10 +509,7 @@ main(int argc, char *argv[])
 out:
 	if (search.argmode != ARG_FILE) {
 		manconf_free(&conf);
-#if HAVE_SQLITE3
 		mansearch_free(res, sz);
-		mansearch_setup(0);
-#endif
 	}
 
 	free(defos);
@@ -551,10 +531,10 @@ out:
 
 			/* Stop here until moved to the foreground. */
 
-			tc_pgid = tcgetpgrp(STDIN_FILENO);
+			tc_pgid = tcgetpgrp(tag_files->ofd);
 			if (tc_pgid != man_pgid) {
 				if (tc_pgid == pager_pid) {
-					(void)tcsetpgrp(STDIN_FILENO,
+					(void)tcsetpgrp(tag_files->ofd,
 					    man_pgid);
 					if (signum == SIGTTIN)
 						continue;
@@ -567,7 +547,7 @@ out:
 			/* Once in the foreground, activate the pager. */
 
 			if (pager_pid) {
-				(void)tcsetpgrp(STDIN_FILENO, pager_pid);
+				(void)tcsetpgrp(tag_files->ofd, pager_pid);
 				kill(pager_pid, SIGCONT);
 			} else
 				pager_pid = spawn_pager(tag_files);
@@ -633,7 +613,8 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
 	glob_t		 globinfo;
 	struct manpage	*page;
 	char		*file;
-	int		 form, globres;
+	int		 globres;
+	enum form	 form;
 
 	form = FORM_SRC;
 	mandoc_asprintf(&file, "%s/man%s/%s.%s",
@@ -671,10 +652,8 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
 		return 0;
 
 found:
-#if HAVE_SQLITE3
 	warnx("outdated mandoc.db lacks %s(%s) entry, run %s %s",
 	    name, sec, BINM_MAKEWHATIS, paths->paths[ipath]);
-#endif
 	*res = mandoc_reallocarray(*res, ++*ressz, sizeof(struct manpage));
 	page = *res + (*ressz - 1);
 	page->file = file;
@@ -747,32 +726,8 @@ parse(struct curparse *curp, int fd, const char *file)
 	if (rctmp != MANDOCLEVEL_OK && curp->wstop)
 		return;
 
-	/* If unset, allocate output dev now (if applicable). */
-
-	if (curp->outdata == NULL) {
-		switch (curp->outtype) {
-		case OUTT_HTML:
-			curp->outdata = html_alloc(curp->outopts);
-			break;
-		case OUTT_UTF8:
-			curp->outdata = utf8_alloc(curp->outopts);
-			break;
-		case OUTT_LOCALE:
-			curp->outdata = locale_alloc(curp->outopts);
-			break;
-		case OUTT_ASCII:
-			curp->outdata = ascii_alloc(curp->outopts);
-			break;
-		case OUTT_PDF:
-			curp->outdata = pdf_alloc(curp->outopts);
-			break;
-		case OUTT_PS:
-			curp->outdata = ps_alloc(curp->outopts);
-			break;
-		default:
-			break;
-		}
-	}
+	if (curp->outdata == NULL)
+		outdata_alloc(curp);
 
 	mparse_result(curp->mp, &man, NULL);
 
@@ -826,6 +781,34 @@ parse(struct curparse *curp, int fd, const char *file)
 			break;
 		}
 	}
+	mparse_updaterc(curp->mp, &rc);
+}
+
+static void
+outdata_alloc(struct curparse *curp)
+{
+	switch (curp->outtype) {
+	case OUTT_HTML:
+		curp->outdata = html_alloc(curp->outopts);
+		break;
+	case OUTT_UTF8:
+		curp->outdata = utf8_alloc(curp->outopts);
+		break;
+	case OUTT_LOCALE:
+		curp->outdata = locale_alloc(curp->outopts);
+		break;
+	case OUTT_ASCII:
+		curp->outdata = ascii_alloc(curp->outopts);
+		break;
+	case OUTT_PDF:
+		curp->outdata = pdf_alloc(curp->outopts);
+		break;
+	case OUTT_PS:
+		curp->outdata = ps_alloc(curp->outopts);
+		break;
+	default:
+		break;
+	}
 }
 
 static void
@@ -838,11 +821,17 @@ passthrough(const char *file, int fd, int synopsis_only)
 	const char	*syscall;
 	char		*line, *cp;
 	size_t		 linesz;
+	ssize_t		 len, written;
 	int		 print;
 
 	line = NULL;
 	linesz = 0;
 
+	if (fflush(stdout) == EOF) {
+		syscall = "fflush";
+		goto fail;
+	}
+
 	if ((stream = fdopen(fd, "r")) == NULL) {
 		close(fd);
 		syscall = "fdopen";
@@ -850,14 +839,16 @@ passthrough(const char *file, int fd, int synopsis_only)
 	}
 
 	print = 0;
-	while (getline(&line, &linesz, stream) != -1) {
+	while ((len = getline(&line, &linesz, stream)) != -1) {
 		cp = line;
 		if (synopsis_only) {
 			if (print) {
 				if ( ! isspace((unsigned char)*cp))
 					goto done;
-				while (isspace((unsigned char)*cp))
+				while (isspace((unsigned char)*cp)) {
 					cp++;
+					len--;
+				}
 			} else {
 				if (strcmp(cp, synb) == 0 ||
 				    strcmp(cp, synr) == 0)
@@ -865,9 +856,11 @@ passthrough(const char *file, int fd, int synopsis_only)
 				continue;
 			}
 		}
-		if (fputs(cp, stdout)) {
+		for (; len > 0; len -= written) {
+			if ((written = write(STDOUT_FILENO, cp, len)) != -1)
+				continue;
 			fclose(stream);
-			syscall = "fputs";
+			syscall = "write";
 			goto fail;
 		}
 	}
@@ -978,7 +971,7 @@ woptions(struct curparse *curp, char *arg)
 
 	while (*arg) {
 		o = arg;
-		switch (getsubopt(&arg, UNCONST(toks), &v)) {
+		switch (getsubopt(&arg, (char * const *)toks, &v)) {
 		case 0:
 			curp->wstop = 1;
 			break;
@@ -1010,7 +1003,8 @@ mmsg(enum mandocerr t, enum mandoclevel lvl,
 {
 	const char	*mparse_msg;
 
-	fprintf(stderr, "%s: %s:", getprogname(), file);
+	fprintf(stderr, "%s: %s:", getprogname(),
+	    file == NULL ? "" : file);
 
 	if (line)
 		fprintf(stderr, "%d:%d:", line, col + 1);
@@ -1082,7 +1076,7 @@ spawn_pager(struct tag_files *tag_files)
 		break;
 	default:
 		(void)setpgid(pager_pid, 0);
-		(void)tcsetpgrp(STDIN_FILENO, pager_pid);
+		(void)tcsetpgrp(tag_files->ofd, pager_pid);
 #if HAVE_PLEDGE
 		if (pledge("stdio rpath tmppath tty proc", NULL) == -1)
 			err((int)MANDOCLEVEL_SYSERR, "pledge");
@@ -1100,7 +1094,7 @@ spawn_pager(struct tag_files *tag_files)
 
 	/* Do not start the pager before controlling the terminal. */
 
-	while (tcgetpgrp(STDIN_FILENO) != getpid())
+	while (tcgetpgrp(STDOUT_FILENO) != getpid())
 		nanosleep(&timeout, NULL);
 
 	execvp(argv[0], argv);
diff --git a/contrib/mdocml/main.h b/contrib/mdocml/main.h
index a53df93c38f..f12f3e4c3a0 100644
--- a/contrib/mdocml/main.h
+++ b/contrib/mdocml/main.h
@@ -1,4 +1,4 @@
-/*	$Id: main.h,v 1.25 2016/07/08 22:29:05 schwarze Exp $ */
+/*	$Id: main.h,v 1.26 2016/07/15 19:33:01 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons 
  * Copyright (c) 2014, 2015 Ingo Schwarze 
@@ -16,8 +16,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define	UNCONST(a)	((void *)(uintptr_t)(const void *)(a))
-
 struct	roff_man;
 struct	manoutput;
 
diff --git a/contrib/mdocml/makewhatis.8 b/contrib/mdocml/makewhatis.8
index 8a5de938fd7..945c05361b3 100644
--- a/contrib/mdocml/makewhatis.8
+++ b/contrib/mdocml/makewhatis.8
@@ -1,4 +1,4 @@
-.\"	$Id: makewhatis.8,v 1.3 2014/08/17 21:03:06 schwarze Exp $
+.\"	$Id: makewhatis.8,v 1.4 2016/07/19 22:40:33 schwarze Exp $
 .\"
 .\" Copyright (c) 2011, 2012 Kristaps Dzonsons 
 .\" Copyright (c) 2011, 2012 Ingo Schwarze 
@@ -15,7 +15,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: August 17 2014 $
+.Dd $Mdocdate: July 19 2016 $
 .Dt MAKEWHATIS 8
 .Os
 .Sh NAME
@@ -79,8 +79,6 @@ If
 is not provided,
 .Nm
 uses the default paths stipulated by
-.Xr manpath 1 ,
-or
 .Xr man.conf 5 .
 .Pp
 The arguments are as follows:
diff --git a/contrib/mdocml/man.1 b/contrib/mdocml/man.1
index 0a7ae6d904f..191bc9594cc 100644
--- a/contrib/mdocml/man.1
+++ b/contrib/mdocml/man.1
@@ -1,4 +1,4 @@
-.\"	$Id: man.1,v 1.17 2016/07/01 20:24:04 schwarze Exp $
+.\"	$Id: man.1,v 1.20 2017/01/06 01:34:57 schwarze Exp $
 .\"
 .\" Copyright (c) 1989, 1990, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -31,7 +31,7 @@
 .\"
 .\"     @(#)man.1	8.2 (Berkeley) 1/2/94
 .\"
-.Dd $Mdocdate: July 1 2016 $
+.Dd $Mdocdate: January 6 2017 $
 .Dt MAN 1
 .Os
 .Sh NAME
@@ -69,12 +69,8 @@ machine architecture
 The options are as follows:
 .Bl -tag -width Ds
 .It Fl a
-Display all of the manual pages for a specified
-.Ar section
-and
-.Ar name
-combination.
-Normally, only the first manual page found is displayed.
+Display all matching manual pages.
+Normally, only the first page found is displayed.
 .It Fl C Ar file
 Use the specified
 .Ar file
@@ -100,6 +96,12 @@ This overrides any earlier
 and
 .Fl l
 options.
+.It Fl h
+Display only the SYNOPSIS lines of the requested manual pages.
+Implies
+.Fl a
+and
+.Fl c .
 .It Fl I Cm os Ns = Ns Ar name
 Override the default operating system
 .Ar name
@@ -110,12 +112,6 @@ and for the
 .Xr man 7
 .Ic \&TH
 macro.
-.It Fl h
-Display only the SYNOPSIS lines of the requested manual pages.
-Implies
-.Fl a
-and
-.Fl c .
 .It Fl K Ar encoding
 Specify the input encoding.
 The supported
@@ -330,7 +326,19 @@ is used, the interactive
 .Ic :t
 command can be used to go to the definitions of various terms, for
 example command line options, command modifiers, internal commands,
-and environment variables.
+environment variables, function names, preprocessor macros,
+.Xr errno 2
+values, and some other emphasized words.
+Some terms may have defining text at more than one place.
+In that case, the
+.Xr less 1
+interactive commands
+.Ic t
+and
+.Ic T
+can be used to move to the next and to the previous place providing
+information about the term last searched for with
+.Ic :t .
 .It Ev MANPATH
 The standard search path used by
 .Nm
diff --git a/contrib/mdocml/man.c b/contrib/mdocml/man.c
index 31c094e8d62..a2db05fbaa3 100644
--- a/contrib/mdocml/man.c
+++ b/contrib/mdocml/man.c
@@ -1,4 +1,4 @@
-/*	$Id: man.c,v 1.166 2015/10/22 21:54:23 schwarze Exp $ */
+/*	$Id: man.c,v 1.167 2017/01/10 13:47:00 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons 
  * Copyright (c) 2013, 2014, 2015 Ingo Schwarze 
@@ -149,7 +149,7 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs)
 
 	assert(i);
 	if (mandoc_eos(buf, (size_t)i))
-		man->last->flags |= MAN_EOS;
+		man->last->flags |= NODE_EOS;
 
 	man_descope(man, line, offs);
 	return 1;
@@ -340,7 +340,7 @@ man_state(struct roff_man *man, struct roff_node *n)
 	switch(n->tok) {
 	case MAN_nf:
 	case MAN_EX:
-		if (man->flags & MAN_LITERAL && ! (n->flags & MAN_VALID))
+		if (man->flags & MAN_LITERAL && ! (n->flags & NODE_VALID))
 			mandoc_msg(MANDOCERR_NF_SKIP, man->parse,
 			    n->line, n->pos, "nf");
 		man->flags |= MAN_LITERAL;
@@ -348,7 +348,7 @@ man_state(struct roff_man *man, struct roff_node *n)
 	case MAN_fi:
 	case MAN_EE:
 		if ( ! (man->flags & MAN_LITERAL) &&
-		     ! (n->flags & MAN_VALID))
+		     ! (n->flags & NODE_VALID))
 			mandoc_msg(MANDOCERR_FI_SKIP, man->parse,
 			    n->line, n->pos, "fi");
 		man->flags &= ~MAN_LITERAL;
@@ -356,7 +356,7 @@ man_state(struct roff_man *man, struct roff_node *n)
 	default:
 		break;
 	}
-	man->last->flags |= MAN_VALID;
+	man->last->flags |= NODE_VALID;
 }
 
 void
diff --git a/contrib/mdocml/man.conf.5 b/contrib/mdocml/man.conf.5
index 9cfeca761d3..425895c1dc8 100644
--- a/contrib/mdocml/man.conf.5
+++ b/contrib/mdocml/man.conf.5
@@ -1,4 +1,4 @@
-.\"	$Id: man.conf.5,v 1.3 2015/03/27 21:33:20 schwarze Exp $
+.\"	$Id: man.conf.5,v 1.4 2016/12/28 22:52:17 schwarze Exp $
 .\"
 .\" Copyright (c) 2015 Ingo Schwarze 
 .\"
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: March 27 2015 $
+.Dd $Mdocdate: December 28 2016 $
 .Dt MAN.CONF 5
 .Os
 .Sh NAME
@@ -91,7 +91,7 @@ manual.
 .It Ic fragment Ta none     Ta Cm html Ta print only body
 .It Ic includes Ta string   Ta Cm html Ta path to header files
 .It Ic indent   Ta integer  Ta Cm ascii , utf8 Ta left margin
-.It Ic man      Ta string   Ta Cm html Ta path for Xr links
+.It Ic man      Ta string   Ta Cm html Ta path for \&Xr links
 .It Ic paper    Ta string   Ta Cm ps , pdf Ta paper size
 .It Ic style    Ta string   Ta Cm html Ta CSS file
 .It Ic width    Ta integer  Ta Cm ascii , utf8 Ta right margin
diff --git a/contrib/mdocml/man_hash.c b/contrib/mdocml/man_hash.c
index 8573994e5d5..bb7b4665b34 100644
--- a/contrib/mdocml/man_hash.c
+++ b/contrib/mdocml/man_hash.c
@@ -1,4 +1,4 @@
-/*	$Id: man_hash.c,v 1.34 2015/10/06 18:32:19 schwarze Exp $ */
+/*	$Id: man_hash.c,v 1.35 2016/07/15 18:03:45 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons 
  * Copyright (c) 2015 Ingo Schwarze 
@@ -24,8 +24,10 @@
 #include 
 #include 
 
+#include "mandoc.h"
 #include "roff.h"
 #include "man.h"
+#include "libmandoc.h"
 #include "libman.h"
 
 #define	HASH_DEPTH	 6
diff --git a/contrib/mdocml/man_html.c b/contrib/mdocml/man_html.c
index d71eb382379..641e0e336ea 100644
--- a/contrib/mdocml/man_html.c
+++ b/contrib/mdocml/man_html.c
@@ -1,7 +1,7 @@
-/*	$Id: man_html.c,v 1.120 2016/01/08 17:48:09 schwarze Exp $ */
+/*	$Id: man_html.c,v 1.129 2017/01/21 01:20:32 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons 
- * Copyright (c) 2013, 2014, 2015 Ingo Schwarze 
+ * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -147,40 +147,39 @@ void
 html_man(void *arg, const struct roff_man *man)
 {
 	struct mhtml	 mh;
-	struct htmlpair	 tag;
 	struct html	*h;
-	struct tag	*t, *tt;
+	struct tag	*t;
 
 	memset(&mh, 0, sizeof(mh));
-	PAIR_CLASS_INIT(&tag, "mandoc");
 	h = (struct html *)arg;
 
-	if ( ! (HTML_FRAGMENT & h->oflags)) {
+	if ((h->oflags & HTML_FRAGMENT) == 0) {
 		print_gen_decls(h);
-		t = print_otag(h, TAG_HTML, 0, NULL);
-		tt = print_otag(h, TAG_HEAD, 0, NULL);
+		print_otag(h, TAG_HTML, "");
+		t = print_otag(h, TAG_HEAD, "");
 		print_man_head(&man->meta, man->first, &mh, h);
-		print_tagq(h, tt);
-		print_otag(h, TAG_BODY, 0, NULL);
-		print_otag(h, TAG_DIV, 1, &tag);
-	} else
-		t = print_otag(h, TAG_DIV, 1, &tag);
+		print_tagq(h, t);
+		print_otag(h, TAG_BODY, "");
+	}
 
-	print_man_nodelist(&man->meta, man->first, &mh, h);
+	man_root_pre(&man->meta, man->first, &mh, h);
+	t = print_otag(h, TAG_DIV, "c", "manual-text");
+	print_man_nodelist(&man->meta, man->first->child, &mh, h);
 	print_tagq(h, t);
-	putchar('\n');
+	man_root_post(&man->meta, man->first, &mh, h);
+	print_tagq(h, NULL);
 }
 
 static void
 print_man_head(MAN_ARGS)
 {
+	char	*cp;
 
 	print_gen_head(h);
-	assert(man->title);
-	assert(man->msec);
-	bufcat_fmt(h, "%s(%s)", man->title, man->msec);
-	print_otag(h, TAG_TITLE, 0, NULL);
-	print_text(h, h->buf);
+	mandoc_asprintf(&cp, "%s(%s)", man->title, man->msec);
+	print_otag(h, TAG_TITLE, "");
+	print_text(h, cp);
+	free(cp);
 }
 
 static void
@@ -203,23 +202,18 @@ print_man_node(MAN_ARGS)
 	t = h->tags.head;
 
 	switch (n->type) {
-	case ROFFT_ROOT:
-		man_root_pre(man, n, mh, h);
-		break;
 	case ROFFT_TEXT:
 		if ('\0' == *n->string) {
 			print_paragraph(h);
 			return;
 		}
-		if (n->flags & MAN_LINE && (*n->string == ' ' ||
+		if (n->flags & NODE_LINE && (*n->string == ' ' ||
 		    (n->prev != NULL && mh->fl & MANH_LITERAL &&
 		     ! (h->flags & HTML_NONEWLINE))))
-			print_otag(h, TAG_BR, 0, NULL);
+			print_otag(h, TAG_BR, "");
 		print_text(h, n->string);
 		return;
 	case ROFFT_EQN:
-		if (n->flags & MAN_LINE)
-			putchar('\n');
 		print_eqn(h, n->eqn);
 		break;
 	case ROFFT_TBL:
@@ -261,9 +255,6 @@ print_man_node(MAN_ARGS)
 	print_stagq(h, t);
 
 	switch (n->type) {
-	case ROFFT_ROOT:
-		man_root_post(man, n, mh, h);
-		break;
 	case ROFFT_EQN:
 		break;
 	default:
@@ -288,7 +279,6 @@ a2width(const struct roff_node *n, struct roffsu *su)
 static void
 man_root_pre(MAN_ARGS)
 {
-	struct htmlpair	 tag;
 	struct tag	*t, *tt;
 	char		*title;
 
@@ -296,26 +286,20 @@ man_root_pre(MAN_ARGS)
 	assert(man->msec);
 	mandoc_asprintf(&title, "%s(%s)", man->title, man->msec);
 
-	PAIR_CLASS_INIT(&tag, "head");
-	t = print_otag(h, TAG_TABLE, 1, &tag);
+	t = print_otag(h, TAG_TABLE, "c", "head");
+	print_otag(h, TAG_TBODY, "");
+	tt = print_otag(h, TAG_TR, "");
 
-	print_otag(h, TAG_TBODY, 0, NULL);
-
-	tt = print_otag(h, TAG_TR, 0, NULL);
-
-	PAIR_CLASS_INIT(&tag, "head-ltitle");
-	print_otag(h, TAG_TD, 1, &tag);
+	print_otag(h, TAG_TD, "c", "head-ltitle");
 	print_text(h, title);
 	print_stagq(h, tt);
 
-	PAIR_CLASS_INIT(&tag, "head-vol");
-	print_otag(h, TAG_TD, 1, &tag);
+	print_otag(h, TAG_TD, "c", "head-vol");
 	if (NULL != man->vol)
 		print_text(h, man->vol);
 	print_stagq(h, tt);
 
-	PAIR_CLASS_INIT(&tag, "head-rtitle");
-	print_otag(h, TAG_TD, 1, &tag);
+	print_otag(h, TAG_TD, "c", "head-rtitle");
 	print_text(h, title);
 	print_tagq(h, t);
 	free(title);
@@ -324,24 +308,16 @@ man_root_pre(MAN_ARGS)
 static void
 man_root_post(MAN_ARGS)
 {
-	struct htmlpair	 tag;
 	struct tag	*t, *tt;
 
-	PAIR_CLASS_INIT(&tag, "foot");
-	t = print_otag(h, TAG_TABLE, 1, &tag);
+	t = print_otag(h, TAG_TABLE, "c", "foot");
+	tt = print_otag(h, TAG_TR, "");
 
-	tt = print_otag(h, TAG_TR, 0, NULL);
-
-	PAIR_CLASS_INIT(&tag, "foot-date");
-	print_otag(h, TAG_TD, 1, &tag);
-
-	assert(man->date);
+	print_otag(h, TAG_TD, "c", "foot-date");
 	print_text(h, man->date);
 	print_stagq(h, tt);
 
-	PAIR_CLASS_INIT(&tag, "foot-os");
-	print_otag(h, TAG_TD, 1, &tag);
-
+	print_otag(h, TAG_TD, "c", "foot-os");
 	if (man->os)
 		print_text(h, man->os);
 	print_tagq(h, t);
@@ -352,7 +328,6 @@ static int
 man_br_pre(MAN_ARGS)
 {
 	struct roffsu	 su;
-	struct htmlpair	 tag;
 
 	SCALE_VS_INIT(&su, 1);
 
@@ -363,10 +338,7 @@ man_br_pre(MAN_ARGS)
 	} else
 		su.scale = 0.0;
 
-	bufinit(h);
-	bufcat_su(h, "height", &su);
-	PAIR_STYLE_INIT(&tag, h);
-	print_otag(h, TAG_DIV, 1, &tag);
+	print_otag(h, TAG_DIV, "suh", &su);
 
 	/* So the div isn't empty: */
 	print_text(h, "\\~");
@@ -377,17 +349,13 @@ man_br_pre(MAN_ARGS)
 static int
 man_SH_pre(MAN_ARGS)
 {
-	struct htmlpair	 tag;
-
 	if (n->type == ROFFT_BLOCK) {
 		mh->fl &= ~MANH_LITERAL;
-		PAIR_CLASS_INIT(&tag, "section");
-		print_otag(h, TAG_DIV, 1, &tag);
 		return 1;
 	} else if (n->type == ROFFT_BODY)
 		return 1;
 
-	print_otag(h, TAG_H1, 0, NULL);
+	print_otag(h, TAG_H1, "c", "Sh");
 	return 1;
 }
 
@@ -400,7 +368,7 @@ man_alt_pre(MAN_ARGS)
 	struct tag	*t;
 
 	if ((savelit = mh->fl & MANH_LITERAL))
-		print_otag(h, TAG_BR, 0, NULL);
+		print_otag(h, TAG_BR, "");
 
 	mh->fl &= ~MANH_LITERAL;
 
@@ -433,7 +401,7 @@ man_alt_pre(MAN_ARGS)
 			h->flags |= HTML_NOSPACE;
 
 		if (TAG_MAX != fp)
-			t = print_otag(h, fp, 0, NULL);
+			t = print_otag(h, fp, "");
 
 		print_man_node(man, nn, mh, h);
 
@@ -450,27 +418,22 @@ man_alt_pre(MAN_ARGS)
 static int
 man_SM_pre(MAN_ARGS)
 {
-
-	print_otag(h, TAG_SMALL, 0, NULL);
+	print_otag(h, TAG_SMALL, "");
 	if (MAN_SB == n->tok)
-		print_otag(h, TAG_B, 0, NULL);
+		print_otag(h, TAG_B, "");
 	return 1;
 }
 
 static int
 man_SS_pre(MAN_ARGS)
 {
-	struct htmlpair	 tag;
-
 	if (n->type == ROFFT_BLOCK) {
 		mh->fl &= ~MANH_LITERAL;
-		PAIR_CLASS_INIT(&tag, "subsection");
-		print_otag(h, TAG_DIV, 1, &tag);
 		return 1;
 	} else if (n->type == ROFFT_BODY)
 		return 1;
 
-	print_otag(h, TAG_H2, 0, NULL);
+	print_otag(h, TAG_H2, "c", "Ss");
 	return 1;
 }
 
@@ -492,16 +455,16 @@ man_IP_pre(MAN_ARGS)
 	const struct roff_node	*nn;
 
 	if (n->type == ROFFT_BODY) {
-		print_otag(h, TAG_DD, 0, NULL);
+		print_otag(h, TAG_DD, "c", "It-tag");
 		return 1;
 	} else if (n->type != ROFFT_HEAD) {
-		print_otag(h, TAG_DL, 0, NULL);
+		print_otag(h, TAG_DL, "c", "Bl-tag");
 		return 1;
 	}
 
 	/* FIXME: width specification. */
 
-	print_otag(h, TAG_DT, 0, NULL);
+	print_otag(h, TAG_DT, "c", "It-tag");
 
 	/* For IP, only print the first header element. */
 
@@ -512,7 +475,7 @@ man_IP_pre(MAN_ARGS)
 
 	if (MAN_TP == n->tok) {
 		nn = n->child;
-		while (NULL != nn && 0 == (MAN_LINE & nn->flags))
+		while (NULL != nn && 0 == (NODE_LINE & nn->flags))
 			nn = nn->next;
 		while (NULL != nn) {
 			print_man_node(man, nn, mh, h);
@@ -526,8 +489,7 @@ man_IP_pre(MAN_ARGS)
 static int
 man_HP_pre(MAN_ARGS)
 {
-	struct htmlpair	 tag[2];
-	struct roffsu	 su;
+	struct roffsu	 sum, sui;
 	const struct roff_node *np;
 
 	if (n->type == ROFFT_HEAD)
@@ -537,18 +499,14 @@ man_HP_pre(MAN_ARGS)
 
 	np = n->head->child;
 
-	if (NULL == np || ! a2width(np, &su))
-		SCALE_HS_INIT(&su, INDENT);
+	if (np == NULL || !a2width(np, &sum))
+		SCALE_HS_INIT(&sum, INDENT);
 
-	bufinit(h);
+	sui.unit = sum.unit;
+	sui.scale = -sum.scale;
 
 	print_bvspace(h, n);
-	bufcat_su(h, "margin-left", &su);
-	su.scale = -su.scale;
-	bufcat_su(h, "text-indent", &su);
-	PAIR_STYLE_INIT(&tag[0], h);
-	PAIR_CLASS_INIT(&tag[1], "spacer");
-	print_otag(h, TAG_DIV, 2, tag);
+	print_otag(h, TAG_DIV, "csului", "Pp", &sum, &sui);
 	return 1;
 }
 
@@ -556,22 +514,20 @@ static int
 man_OP_pre(MAN_ARGS)
 {
 	struct tag	*tt;
-	struct htmlpair	 tag;
 
 	print_text(h, "[");
 	h->flags |= HTML_NOSPACE;
-	PAIR_CLASS_INIT(&tag, "opt");
-	tt = print_otag(h, TAG_SPAN, 1, &tag);
+	tt = print_otag(h, TAG_SPAN, "c", "Op");
 
 	if (NULL != (n = n->child)) {
-		print_otag(h, TAG_B, 0, NULL);
+		print_otag(h, TAG_B, "");
 		print_text(h, n->string);
 	}
 
 	print_stagq(h, tt);
 
 	if (NULL != n && NULL != n->next) {
-		print_otag(h, TAG_I, 0, NULL);
+		print_otag(h, TAG_I, "");
 		print_text(h, n->next->string);
 	}
 
@@ -584,16 +540,14 @@ man_OP_pre(MAN_ARGS)
 static int
 man_B_pre(MAN_ARGS)
 {
-
-	print_otag(h, TAG_B, 0, NULL);
+	print_otag(h, TAG_B, "");
 	return 1;
 }
 
 static int
 man_I_pre(MAN_ARGS)
 {
-
-	print_otag(h, TAG_I, 0, NULL);
+	print_otag(h, TAG_I, "");
 	return 1;
 }
 
@@ -602,7 +556,7 @@ man_literal_pre(MAN_ARGS)
 {
 
 	if (MAN_fi == n->tok || MAN_EE == n->tok) {
-		print_otag(h, TAG_BR, 0, NULL);
+		print_otag(h, TAG_BR, "");
 		mh->fl &= ~MANH_LITERAL;
 	} else
 		mh->fl |= MANH_LITERAL;
@@ -613,8 +567,7 @@ man_literal_pre(MAN_ARGS)
 static int
 man_in_pre(MAN_ARGS)
 {
-
-	print_otag(h, TAG_BR, 0, NULL);
+	print_otag(h, TAG_BR, "");
 	return 0;
 }
 
@@ -628,7 +581,6 @@ man_ign_pre(MAN_ARGS)
 static int
 man_RS_pre(MAN_ARGS)
 {
-	struct htmlpair	 tag;
 	struct roffsu	 su;
 
 	if (n->type == ROFFT_HEAD)
@@ -640,25 +592,18 @@ man_RS_pre(MAN_ARGS)
 	if (n->head->child)
 		a2width(n->head->child, &su);
 
-	bufinit(h);
-	bufcat_su(h, "margin-left", &su);
-	PAIR_STYLE_INIT(&tag, h);
-	print_otag(h, TAG_DIV, 1, &tag);
+	print_otag(h, TAG_DIV, "sul", &su);
 	return 1;
 }
 
 static int
 man_UR_pre(MAN_ARGS)
 {
-	struct htmlpair		 tag[2];
-
 	n = n->child;
 	assert(n->type == ROFFT_HEAD);
 	if (n->child != NULL) {
 		assert(n->child->type == ROFFT_TEXT);
-		PAIR_CLASS_INIT(&tag[0], "link-ext");
-		PAIR_HREF_INIT(&tag[1], n->child->string);
-		print_otag(h, TAG_A, 2, tag);
+		print_otag(h, TAG_A, "ch", "Lk", n->child->string);
 	}
 
 	assert(n->next->type == ROFFT_BODY);
diff --git a/contrib/mdocml/man_macro.c b/contrib/mdocml/man_macro.c
index d15335709ec..7fd17c53481 100644
--- a/contrib/mdocml/man_macro.c
+++ b/contrib/mdocml/man_macro.c
@@ -1,4 +1,4 @@
-/*	$Id: man_macro.c,v 1.114 2016/01/08 17:48:09 schwarze Exp $ */
+/*	$Id: man_macro.c,v 1.115 2017/01/10 13:47:00 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons 
  * Copyright (c) 2012, 2013, 2014, 2015 Ingo Schwarze 
@@ -95,7 +95,7 @@ man_unscope(struct roff_man *man, const struct roff_node *to)
 
 		/* Reached the end of the document? */
 
-		if (to == NULL && ! (n->flags & MAN_VALID)) {
+		if (to == NULL && ! (n->flags & NODE_VALID)) {
 			if (man->flags & (MAN_BLINE | MAN_ELINE) &&
 			    man_macros[n->tok].flags & MAN_SCOPED) {
 				mandoc_vmsg(MANDOCERR_BLK_LINE,
@@ -130,7 +130,7 @@ man_unscope(struct roff_man *man, const struct roff_node *to)
 
 		man->last = n;
 		n = n->parent;
-		man->last->flags |= MAN_VALID;
+		man->last->flags |= NODE_VALID;
 	}
 
 	/*
@@ -164,7 +164,7 @@ rew_scope(struct roff_man *man, int tok)
 	for (;;) {
 		if (n->type == ROFFT_ROOT)
 			return;
-		if (n->flags & MAN_VALID) {
+		if (n->flags & NODE_VALID) {
 			n = n->parent;
 			continue;
 		}
@@ -356,13 +356,13 @@ in_line_eoln(MACRO_PROT_ARGS)
 	}
 
 	/*
-	 * Append MAN_EOS in case the last snipped argument
+	 * Append NODE_EOS in case the last snipped argument
 	 * ends with a dot, e.g. `.IR syslog (3).'
 	 */
 
 	if (n != man->last &&
 	    mandoc_eos(man->last->string, strlen(man->last->string)))
-		man->last->flags |= MAN_EOS;
+		man->last->flags |= NODE_EOS;
 
 	/*
 	 * If no arguments are specified and this is MAN_SCOPED (i.e.,
diff --git a/contrib/mdocml/man_term.c b/contrib/mdocml/man_term.c
index f45e24afea4..672ab416322 100644
--- a/contrib/mdocml/man_term.c
+++ b/contrib/mdocml/man_term.c
@@ -1,4 +1,4 @@
-/*	$Id: man_term.c,v 1.187 2016/01/08 17:48:09 schwarze Exp $ */
+/*	$Id: man_term.c,v 1.188 2017/01/10 13:47:00 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons 
  * Copyright (c) 2010-2015 Ingo Schwarze 
@@ -319,7 +319,7 @@ pre_alternate(DECL_ARGS)
 			mt->fl |= MANT_LITERAL;
 		assert(nn->type == ROFFT_TEXT);
 		term_word(p, nn->string);
-		if (nn->flags & MAN_EOS)
+		if (nn->flags & NODE_EOS)
                 	p->flags |= TERMP_SENTENCE;
 		if (nn->next)
 			p->flags |= TERMP_NOSPACE;
@@ -677,7 +677,7 @@ pre_TP(DECL_ARGS)
 	/* Calculate offset. */
 
 	if ((nn = n->parent->head->child) != NULL &&
-	    nn->string != NULL && ! (MAN_LINE & nn->flags) &&
+	    nn->string != NULL && ! (NODE_LINE & nn->flags) &&
 	    a2roffsu(nn->string, &su, SCALE_EN)) {
 		len = term_hspan(p, &su) / 24;
 		if (len < 0 && (size_t)(-len) > mt->offset)
@@ -698,7 +698,7 @@ pre_TP(DECL_ARGS)
 
 		/* Don't print same-line elements. */
 		nn = n->child;
-		while (NULL != nn && 0 == (MAN_LINE & nn->flags))
+		while (NULL != nn && 0 == (NODE_LINE & nn->flags))
 			nn = nn->next;
 
 		while (NULL != nn) {
@@ -960,17 +960,17 @@ print_man_node(DECL_ARGS)
 		if ('\0' == *n->string) {
 			term_vspace(p);
 			return;
-		} else if (' ' == *n->string && MAN_LINE & n->flags)
+		} else if (' ' == *n->string && NODE_LINE & n->flags)
 			term_newln(p);
 
 		term_word(p, n->string);
 		goto out;
 
 	case ROFFT_EQN:
-		if ( ! (n->flags & MAN_LINE))
+		if ( ! (n->flags & NODE_LINE))
 			p->flags |= TERMP_NOSPACE;
 		term_eqn(p, n->eqn);
-		if (n->next != NULL && ! (n->next->flags & MAN_LINE))
+		if (n->next != NULL && ! (n->next->flags & NODE_LINE))
 			p->flags |= TERMP_NOSPACE;
 		return;
 	case ROFFT_TBL:
@@ -1007,7 +1007,7 @@ out:
 	 */
 	if (mt->fl & MANT_LITERAL &&
 	    ! (p->flags & (TERMP_NOBREAK | TERMP_NONEWLINE)) &&
-	    (n->next == NULL || n->next->flags & MAN_LINE)) {
+	    (n->next == NULL || n->next->flags & NODE_LINE)) {
 		rm = p->rmargin;
 		rmax = p->maxrmargin;
 		p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
@@ -1023,7 +1023,7 @@ out:
 			p->rmargin = rm;
 		p->maxrmargin = rmax;
 	}
-	if (MAN_EOS & n->flags)
+	if (NODE_EOS & n->flags)
 		p->flags |= TERMP_SENTENCE;
 }
 
diff --git a/contrib/mdocml/mandoc.1 b/contrib/mdocml/mandoc.1
index f4707aa28b0..946955a64c5 100644
--- a/contrib/mdocml/mandoc.1
+++ b/contrib/mdocml/mandoc.1
@@ -1,7 +1,7 @@
-.\"	$Id: mandoc.1,v 1.164 2015/11/05 17:47:51 schwarze Exp $
+.\"	$Id: mandoc.1,v 1.171 2017/01/21 02:32:39 schwarze Exp $
 .\"
 .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons 
-.\" Copyright (c) 2012, 2014, 2015 Ingo Schwarze 
+.\" Copyright (c) 2012, 2014-2017 Ingo Schwarze 
 .\"
 .\" Permission to use, copy, modify, and distribute this software for any
 .\" purpose with or without fee is hereby granted, provided that the above
@@ -15,7 +15,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: November 5 2015 $
+.Dd $Mdocdate: January 21 2017 $
 .Dt MANDOC 1
 .Os
 .Sh NAME
@@ -75,6 +75,10 @@ This overrides any earlier
 and
 .Fl l
 options.
+.It Fl h
+Display only the SYNOPSIS lines.
+Implies
+.Fl c .
 .It Fl I Cm os Ns = Ns Ar name
 Override the default operating system
 .Ar name
@@ -85,10 +89,6 @@ and for the
 .Xr man 7
 .Sq \&TH
 macro.
-.It Fl h
-Display only the SYNOPSIS lines.
-Implies
-.Fl c .
 .It Fl K Ar encoding
 Specify the input encoding.
 The supported
@@ -498,7 +498,15 @@ Use
 to show a human readable representation of the syntax tree.
 It is useful for debugging the source code of manual pages.
 The exact format is subject to change, so don't write parsers for it.
-Each output line shows one syntax tree node.
+.Pp
+The first paragraph shows meta data found in the
+.Xr mdoc 7
+prologue, on the
+.Xr man 7
+.Ic \&TH
+line, or the fallbacks used.
+.Pp
+In the tree dump, each output line shows one syntax tree node.
 Child nodes are indented with respect to their parent node.
 The columns are:
 .Pp
@@ -529,6 +537,12 @@ The input column number (starting at one).
 A closing parenthesis if the node is a closing delimiter.
 .It
 A full stop if the node ends a sentence.
+.It
+NOSRC if the node is not in the input file,
+but automatically generated from macros.
+.It
+NOPRT if the node is not supposed to generate output
+for any output format.
 .El
 .El
 .Sh ENVIRONMENT
@@ -809,11 +823,13 @@ This may confuse
 .Xr makewhatis 8
 and
 .Xr apropos 1 .
-.It Sy "NAME section without name"
+.It Sy "NAME section without Nm before Nd"
 .Pq mdoc
 The NAME section does not contain any
 .Ic \&Nm
-child macro.
+child macro before the first
+.Ic \&Nd
+macro.
 .It Sy "NAME section without description"
 .Pq mdoc
 The NAME section lacks the mandatory
@@ -830,6 +846,11 @@ The NAME section contains plain text or macros other than
 .Ic \&Nm
 and
 .Ic \&Nd .
+.It Sy "missing comma before name"
+.Pq mdoc
+The NAME section contains an
+.Ic \&Nm
+macro that is neither the first one nor preceded by a comma.
 .It Sy "missing description line, using \(dq\(dq"
 .Pq mdoc
 The
@@ -1147,6 +1168,13 @@ macro is immediately followed by an
 .Ic \&Re
 macro on the next input line.
 Such an empty block does not produce any output.
+.It Sy "missing section argument"
+.Pq mdoc
+An
+.Ic \&Xr
+macro lacks its second, section number argument.
+The first argument, i.e. the name, is printed, but without subsequent
+parentheses.
 .It Sy "missing -std argument, adding it"
 .Pq mdoc
 An
@@ -1615,8 +1643,8 @@ macro fails to specify the list type.
 .It Sy "missing manual name, using \(dq\(dq"
 .Pq mdoc
 The first call to
-.Ic \&Nm
-lacks the required argument.
+.Ic \&Nm ,
+or any call in the NAME section, lacks the required argument.
 .It Sy "uname(3) system call failed, using UNKNOWN"
 .Pq mdoc
 The
@@ -1812,12 +1840,3 @@ utility was written by
 .An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
 and is maintained by
 .An Ingo Schwarze Aq Mt schwarze@openbsd.org .
-.Sh BUGS
-In
-.Fl T Cm html ,
-the maximum size of an element attribute is determined by
-.Dv BUFSIZ ,
-which is usually 1024 bytes.
-Be aware of this when setting long link
-formats such as
-.Fl O Cm style Ns = Ns Ar really/long/link .
diff --git a/contrib/mdocml/mandoc.3 b/contrib/mdocml/mandoc.3
index 18b5707c492..6f7c3eb09a1 100644
--- a/contrib/mdocml/mandoc.3
+++ b/contrib/mdocml/mandoc.3
@@ -1,7 +1,7 @@
-.\"	$Id: mandoc.3,v 1.37 2016/07/07 19:19:01 schwarze Exp $
+.\"	$Id: mandoc.3,v 1.38 2017/01/09 01:37:03 schwarze Exp $
 .\"
 .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons 
-.\" Copyright (c) 2010-2016 Ingo Schwarze 
+.\" Copyright (c) 2010-2017 Ingo Schwarze 
 .\"
 .\" Permission to use, copy, modify, and distribute this software for any
 .\" purpose with or without fee is hereby granted, provided that the above
@@ -15,7 +15,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: July 7 2016 $
+.Dd $Mdocdate: January 9 2017 $
 .Dt MANDOC 3
 .Os
 .Sh NAME
@@ -34,7 +34,8 @@
 .Nm mparse_reset ,
 .Nm mparse_result ,
 .Nm mparse_strerror ,
-.Nm mparse_strlevel
+.Nm mparse_strlevel ,
+.Nm mparse_updaterc 
 .Nd mandoc macro compiler library
 .Sh SYNOPSIS
 .In sys/types.h
@@ -100,6 +101,11 @@
 .Fo mparse_strlevel
 .Fa "enum mandoclevel"
 .Fc
+.Ft void
+.Fo mparse_updaterc
+.Fa "struct mparse *parse"
+.Fa "enum mandoclevel *rc"
+.Fc
 .In roff.h
 .Ft void
 .Fo deroff
@@ -181,6 +187,9 @@ or
 .Fn man_validate ,
 respectively;
 .It
+if information about the validity of the input is needed, fetch it with
+.Fn mparse_updaterc ;
+.It
 iterate over parse nodes with starting from the
 .Fa first
 member of the returned
@@ -416,6 +425,22 @@ Declared in
 .In mandoc.h ,
 implemented in
 .Pa read.c .
+.It Fn mparse_updaterc
+If the highest warning or error level that occurred during the current
+.Fa parse
+is higher than
+.Pf * Fa rc ,
+update
+.Pf * Fa rc
+accordingly.
+This is useful after calling
+.Fn mdoc_validate
+or
+.Fn man_validate .
+Declared in
+.In mandoc.h ,
+implemented in
+.Pa read.c .
 .El
 .Ss Variables
 .Bl -ohang
diff --git a/contrib/mdocml/mandoc.css b/contrib/mdocml/mandoc.css
index 90085061fc0..162b730749e 100644
--- a/contrib/mdocml/mandoc.css
+++ b/contrib/mdocml/mandoc.css
@@ -1,159 +1,173 @@
-/* $Id: mandoc.css,v 1.2 2016/04/13 10:19:23 schwarze Exp $ */
-
+/* $Id: mandoc.css,v 1.13 2017/01/21 02:29:57 schwarze Exp $ */
 /*
- * This is an example style-sheet provided for mandoc(1) and the -Thtml
- * or -Txhtml output mode.
- *
- * It mimics the appearance of the traditional cvsweb output.
- *
- * See mdoc(7) and man(7) for macro explanations.
+ * Standard style sheet for mandoc(1) -Thtml and man.cgi(8).
  */
 
-html		{ max-width: 880px; margin-left: 1em; }
-body		{ font-size: smaller; font-family: Helvetica,Arial,sans-serif; }
-body > div			{ padding-left: 2em;
-				  padding-top: 1em; }
-body > div.mandoc,
-body > div#mancgi		{ padding-left: 0em;
-				  padding-top: 0em; }
-body > div.results		{ font-size: smaller; }
-#mancgi fieldset		{ text-align: center;
-				  border: thin solid silver;
-				  border-radius: 1em;
-			  	  font-size: small; }
-#mancgi input[name=expr] 	{ width: 25%; }
-.results td.title		{ vertical-align: top;
-				  padding-right: 1em; }
-h1		{ margin-bottom: 1ex; font-size: 110% } 
-div.section > h1 { margin-left: -4ex; } /* Section header (Sh, SH). */
-h2		{ margin-bottom: 1ex; font-size: 105%; margin-left: -2ex; } /* Sub-section header (Ss, SS). */
-table		{ width: 100%; margin-top: 0ex; margin-bottom: 0ex; } /* All tables. */
-td		{ vertical-align: top; } /* All table cells. */
-p		{ } /* Paragraph: Pp, Lp. */
-blockquote	{ margin-left: 5ex; margin-top: 0ex; margin-bottom: 0ex; } /* D1. */
-div.section	{ margin-bottom: 2ex; margin-left: 5ex; } /* Sections (Sh, SH). */
-div.subsection	{ } /* Sub-sections (Ss, SS). */
-table.synopsis	{ } /* SYNOPSIS section table. */
-div.spacer	{ margin: 1em 0; }
+/* Global defaults. */
 
-/* Preamble structure. */
+html {		max-width: 100ex; }
+body {		font-family: Helvetica,Arial,sans-serif; }
+table {		margin-top: 0em;
+		margin-bottom: 0em; }
+td {		vertical-align: top; }
+ul, ol, dl {	margin-top: 0em;
+		margin-bottom: 0em; }
+li, dt {	margin-top: 1em; }
 
-table.foot	{ font-size: smaller; margin-top: 1em; border-top: 1px dotted #dddddd; } /* Document footer. */
-td.foot-date	{ width: 50%; } /* Document footer: date. */
-td.foot-os	{ width: 50%; } /* Document footer: OS/source. */
-table.head	{ font-size: smaller; margin-bottom: 1em; border-bottom: 1px dotted #dddddd; } /* Document header. */
-td.head-ltitle	{ width: 10%; } /* Document header: left-title. */
-td.head-vol	{ width: 80%; } /* Document header: volume. */
-td.head-rtitle	{ width: 10%; } /* Document header: right-title. */
+/* Search form and search results. */
 
-/* General font modes. */
+fieldset {	border: thin solid silver;
+		border-radius: 1em;
+		text-align: center; }
+input[name=expr] {
+		width: 25%; }
 
-i		{ } /* Italic: BI, IB, I, (implicit). */
-.emph		{ font-style: italic; font-weight: normal; } /* Emphasis: Em, Bl -emphasis. */
-b		{ } /* Bold: SB, BI, IB, BR, RB, B, (implicit). */
-.symb		{ font-style: normal; font-weight: bold; } /* Symbolic: Sy, Ms, Bf -symbolic. */
-small		{ } /* Small: SB, SM. */
-.lit		{ font-style: normal; font-weight: normal; font-family: monospace; } /* Literal: Dl, Li, Ql, Bf -literal, Bl -literal, Bl -unfilled. */
+table.results {	margin-top: 1em;
+		margin-left: 2em;
+		font-size: smaller; }
 
-/* Block modes. */
+/* Header and footer lines. */
 
-.display	{ } /* Top of all Bd, D1, Dl. */
-.list		{ } /* Top of all Bl. */
+table.head {	width: 100%;
+		border-bottom: 1px dotted #808080;
+		margin-bottom: 1em;
+		font-size: smaller; }
+td.head-vol {	text-align: center; }
+td.head-rtitle {
+		text-align: right; }
+span.Nd { }
 
-/* Context-specific modes. */
+table.foot {	width: 100%;
+		border-top: 1px dotted #808080;
+		margin-top: 1em;
+		font-size: smaller; }
+td.foot-os {	text-align: right; }
 
-i.addr		{ font-weight: normal; } /* Address (Ad). */
-i.arg		{ font-weight: normal; } /* Command argument (Ar). */
-span.author	{ } /* Author name (An). */
-b.cmd		{ font-style: normal; } /* Command (Cm). */
-b.config	{ font-style: normal; } /* Config statement (Cd). */
-span.define	{ } /* Defines (Dv). */
-span.desc	{ } /* Nd.  After em-dash. */
-b.diag		{ font-style: normal; } /* Diagnostic (Bl -diag). */
-span.env	{ } /* Environment variables (Ev). */
-span.errno	{ } /* Error string (Er). */
-i.farg		{ font-weight: normal; } /* Function argument (Fa, Fn). */
-i.file		{ font-weight: normal; } /* File (Pa). */
-b.flag		{ font-style: normal; } /* Flag (Fl, Cm). */
-b.fname		{ font-style: normal; } /* Function name (Fa, Fn, Rv). */
-i.ftype		{ font-weight: normal; } /* Function types (Ft, Fn). */
-b.includes	{ font-style: normal; } /* Header includes (In). */
-span.lib	{ } /* Library (Lb). */
-i.link-sec	{ font-weight: normal; } /* Section links (Sx). */
-b.macro		{ font-style: normal; } /* Macro-ish thing (Fd). */
-b.name		{ font-style: normal; } /* Name of utility (Nm). */
-span.opt	{ } /* Options (Op, Oo/Oc). */
-span.ref	{ } /* Citations (Rs). */
-span.ref-auth	{ } /* Reference author (%A). */
-i.ref-book	{ font-weight: normal; } /* Reference book (%B). */
-span.ref-city	{ } /* Reference city (%C). */
-span.ref-date	{ } /* Reference date (%D). */
-i.ref-issue	{ font-weight: normal; } /* Reference issuer/publisher (%I). */
-i.ref-jrnl	{ font-weight: normal; } /* Reference journal (%J). */
-span.ref-num	{ } /* Reference number (%N). */
-span.ref-opt	{ } /* Reference optionals (%O). */
-span.ref-page	{ } /* Reference page (%P). */
-span.ref-corp	{ } /* Reference corporate/foreign author (%Q). */
-span.ref-rep	{ } /* Reference report (%R). */
-span.ref-title	{ text-decoration: underline; } /* Reference title (%T). */
-span.ref-vol	{ } /* Reference volume (%V). */
-span.type	{ font-style: italic; font-weight: normal; } /* Variable types (Vt). */
-span.unix	{ } /* Unices (Ux, Ox, Nx, Fx, Bx, Bsx, Dx). */
-b.utility	{ font-style: normal; } /* Name of utility (Ex). */
-b.var		{ font-style: normal; } /* Variables (Rv). */
+/* Sections and paragraphs. */
 
-a.link-ext	{ } /* Off-site link (Lk). */
-a.link-includes	{ } /* Include-file link (In). */
-a.link-mail	{ } /* Mailto links (Mt). */
-a.link-man	{ } /* Manual links (Xr). */
-a.link-ref	{ } /* Reference section links (%Q). */
-a.link-sec	{ } /* Section links (Sx). */
+div.manual-text {
+		margin-left: 5ex; }
+h1.Sh {		margin-top: 2ex;
+		margin-bottom: 1ex;
+		margin-left: -4ex;
+		font-size: 110%; }
+h2.Ss {		margin-top: 2ex;
+		margin-bottom: 1ex;
+		margin-left: -2ex;
+		font-size: 105%; }
+div.Pp {	margin: 1ex 0ex; }
+a.Sx { }
+a.Xr { }
 
-/* Formatting for lists.  See mdoc(7). */
+/* Displays and lists. */
 
-dl.list-diag	{ }
-dt.list-diag	{ }
-dd.list-diag	{ }
+div.Bd { }
+div.D1 {	margin-left: 5ex; }
 
-dl.list-hang	{ }
-dt.list-hang	{ }
-dd.list-hang	{ }
+ul.Bl-bullet {	list-style-type: disc;
+		padding-left: 1em; }
+li.It-bullet { }
+ul.Bl-dash {	list-style-type: none;
+		padding-left: 0em; }
+li.It-dash:before {
+		content: "\2014  "; }
+ul.Bl-item {	list-style-type: none;
+		padding-left: 0em; }
+li.It-item { }
 
-dl.list-inset	{ }
-dt.list-inset	{ }
-dd.list-inset	{ }
+ol.Bl-enum {	padding-left: 2em; }
+li.It-enum { }
 
-dl.list-ohang	{ }
-dt.list-ohang	{ }
-dd.list-ohang	{ margin-left: 0ex; }
+dl.Bl-diag { }
+dt.It-diag { }
+dd.It-diag { }
+b.It-diag {	font-style: normal; }
+dl.Bl-hang { }
+dt.It-hang { }
+dd.It-hang { }
+dl.Bl-inset { }
+dt.It-inset { }
+dd.It-inset { }
+dl.Bl-ohang { }
+dt.It-ohang { }
+dd.It-ohang {	margin-left: 0ex; }
+dl.Bl-tag { }
+dt.It-tag { }
+dd.It-tag { }
 
-dl.list-tag	{ }
-dt.list-tag	{ }
-dd.list-tag	{ }
+table.Bl-column { }
+tr.It-column { }
+td.It-column {	margin-top: 1em; }
 
-table.list-col	{ }
-tr.list-col	{ }
-td.list-col	{ }
+span.Rs	{ }
+span.RsA { }
+i.RsB {		font-weight: normal; }
+span.RsC { }
+span.RsD { }
+i.RsI {		font-weight: normal; }
+i.RsJ {		font-weight: normal; }
+span.RsN { }
+span.RsO { }
+span.RsP { }
+span.RsQ { }
+span.RsR { }
+span.RsT {	text-decoration: underline; }
+a.RsU { }
+span.RsV { }
 
-ul.list-bul	{ list-style-type: disc; padding-left: 1em; }
-li.list-bul	{ }
+span.eqn { }
+table.tbl { }
 
-ul.list-dash	{ list-style-type: none; padding-left: 0em; }
-li.list-dash:before { content: "\2014  "; }
+/* Semantic markup for command line utilities. */
 
-ul.list-hyph	{ list-style-type: none; padding-left: 0em; }
-li.list-hyph:before { content: "\2013  "; }
+table.Nm { }
+b.Nm {		font-style: normal; }
+b.Fl {		font-style: normal; }
+b.Cm {		font-style: normal; }
+i.Ar {		font-weight: normal; }
+span.Op { }
+b.Ic {		font-style: normal; }
+code.Ev {	font-style: normal;
+		font-weight: normal;
+		font-family: monospace; }
+i.Pa {		font-weight: normal; }
 
-ul.list-item	{ list-style-type: none; padding-left: 0em; }
-li.list-item	{ }
+/* Semantic markup for function libraries. */
 
-ol.list-enum	{ padding-left: 2em; }
-li.list-enum	{ }
+span.Lb { }
+b.In {		font-style: normal; }
+a.In { }
+b.Fd {		font-style: normal; }
+i.Ft {		font-weight: normal; }
+b.Fn {		font-style: normal; }
+i.Fa {		font-weight: normal; }
+i.Vt {		font-weight: normal; }
+i.Va {		font-weight: normal; }
+code.Dv {	font-style: normal;
+		font-weight: normal;
+		font-family: monospace; }
+code.Er {	font-style: normal;
+		font-weight: normal;
+		font-family: monospace; }
 
-/* Equation modes.  See eqn(7). */
+/* Various semantic markup. */
 
-span.eqn	{ }
+span.An { }
+a.Lk { }
+a.Mt { }
+b.Cd {		font-style: normal; }
+i.Ad {		font-weight: normal; }
+b.Ms {		font-style: normal; }
+a.Ux { }
 
-/* Table modes.  See tbl(7). */
+/* Physical markup. */
 
-table.tbl	{ }
+.No {		font-style: normal;
+		font-weight: normal; }
+.Em {		font-style: italic;
+		font-weight: normal; }
+.Sy {		font-style: normal;
+		font-weight: bold; }
+.Li {		font-style: normal;
+		font-weight: normal;
+		font-family: monospace; }
diff --git a/contrib/mdocml/mandoc.db.5 b/contrib/mdocml/mandoc.db.5
index de6ea11bd0d..26907d139f4 100644
--- a/contrib/mdocml/mandoc.db.5
+++ b/contrib/mdocml/mandoc.db.5
@@ -1,6 +1,6 @@
-.\"	$Id: mandoc.db.5,v 1.4 2016/07/07 14:35:48 schwarze Exp $
+.\"	$Id: mandoc.db.5,v 1.5 2016/08/01 12:27:15 schwarze Exp $
 .\"
-.\" Copyright (c) 2014 Ingo Schwarze 
+.\" Copyright (c) 2014, 2016 Ingo Schwarze 
 .\"
 .\" Permission to use, copy, modify, and distribute this software for any
 .\" purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: July 7 2016 $
+.Dd $Mdocdate: August 1 2016 $
 .Dt MANDOC.DB 5
 .Os
 .Sh NAME
@@ -23,7 +23,7 @@
 .Sh DESCRIPTION
 The
 .Nm
-SQLite3 file format is used to store information about installed manual
+file format is used to store information about installed manual
 pages to facilitate semantic searching for manuals.
 Each manual page tree contains its own
 .Nm
@@ -34,87 +34,156 @@ for examples.
 Such database files are generated by
 .Xr makewhatis 8
 and used by
+.Xr man 1 ,
 .Xr apropos 1
 and
 .Xr whatis 1 .
 .Pp
-One line in the following tables describes:
-.Bl -tag -width Ds
-.It Sy mpages
-One physical manual page file, no matter how many times and under which
-names it may appear in the file system.
-.It Sy mlinks
-One entry in the file system, no matter which content it points to.
-.It Sy names
-One manual page name, no matter whether it appears in a page header,
-in a NAME or SYNOPSIS section, or as a file name.
-.It Sy keys
-One chunk of text from some macro invocation.
+The file format uses three datatypes:
+.Pp
+.Bl -dash -compact -offset 2n -width 1n
+.It
+32-bit signed integer numbers in big endian (network) byte ordering
+.It
+NUL-terminated strings
+.It
+lists of NUL-terminated strings, terminated by a second NUL character
 .El
 .Pp
-Each record in the latter three tables uses its
-.Va pageid
-column to point to a record in the
-.Sy mpages
-table.
+Numbers are aligned to four-byte boundaries; where they follow
+strings or lists of strings, padding with additional NUL characters
+occurs.
+Some, but not all, numbers point to positions in the file.
+These pointers are measured in bytes, and the first byte of the
+file is considered to be byte 0.
 .Pp
-The other columns are as follows; unless stated otherwise, they are
-of type
-.Vt TEXT .
-.Bl -tag -width mpages.desc
-.It Sy mpages.desc
-The description line
-.Pq Sq \&Nd
-of the page.
-.It Sy mpages.form
-An
-.Vt INTEGER
-bit field.
-If bit
-.Dv FORM_GZ
-is set, the page is compressed and requires
-.Xr gunzip 1
-for display.
-If bit
-.Dv FORM_SRC
-is set, the page is unformatted, that is in
+Each file consists of:
+.Pp
+.Bl -dash -compact -offset 2n -width 1n
+.It
+One magic number, 0x3a7d0cdb.
+.It
+One version number, currently 1.
+.It
+One pointer to the macros table.
+.It
+One pointer to the final magic number.
+.It
+The pages table (variable length).
+.It
+The macros table (variable length).
+.It
+The magic number once again, 0x3a7d0cdb.
+.El
+.Pp
+The pages table contains one entry for each physical manual page
+file, no matter how many hard and soft links it may have in the
+file system.
+The pages table consists of:
+.Pp
+.Bl -dash -compact -offset 2n -width 1n
+.It
+The number of pages in the database.
+.It
+For each page:
+.Bl -dash -compact -offset 2n -width 1n
+.It
+One pointer to the list of names.
+.It
+One pointer to the list of sections.
+.It
+One pointer to the list of architectures
+or 0 if the page is machine-independent.
+.It
+One pointer to the one-line description string.
+.It
+One pointer to the list of filenames.
+.El
+.It
+For each page, the list of names.
+Each name is preceded by a single byte indicating the sources of the name.
+The meaning of the bits is:
+.Bl -dash -compact -offset 2n -width 1n
+.It
+0x10: The name appears in a filename.
+.It
+0x08: The name appears in a header line, i.e. in a .Dt or .TH macro.
+.It
+0x04: The name is the first one in the title line, i.e. it appears
+in the first .Nm macro in the NAME section.
+.It
+0x02: The name appears in any .Nm macro in the NAME section.
+.It
+0x01: The name appears in an .Nm block in the SYNOPSIS section.
+.El
+.It
+For each page, the list of sections.
+Each section is given as a string, not as a number.
+.It
+For each architecture-dependent page, the list of architectures.
+.It
+For each page, the one-line description string taken from the .Nd macro.
+.It
+For each page, the list of filenames relative to the root of the
+respective manpath.
+This list includes hard links, soft links, and links simulated
+with .so
+.Xr roff 7
+requests.
+The first filename is preceded by a single byte
+having the following significance:
+.Bl -dash -compact -offset 2n -width 1n
+.It
+.Dv FORM_SRC No = 0x01 :
+The file format is
 .Xr mdoc 7
 or
-.Xr man 7
-format, and requires
-.Xr mandoc 1
-for display.
-If bit
-.Dv FORM_SRC
-is not set, the page is formatted, i.e. a
-.Sq cat
-page.
-.It Sy mlinks.sec
-The manual section as found in the subdirectory name.
-.It Sy mlinks.arch
-The manual architecture as found in the subdirectory name, or
-.Qq any .
-.It Sy mlinks.name
-The manual name as found in the file name.
-.It Sy names.bits
-An
-.Vt INTEGER
-bit mask telling whether the name came from a header line, from the
-NAME or SYNOPSIS section, or from a file name.
-Bits are defined in
-.In mansearch.h .
-.It Sy names.name
-The name itself.
-.It Sy keys.bits
-An
-.Vt INTEGER
-bit mask telling which semantic contexts the key was found in;
-defined in
-.In mansearch.h ,
-documented in
+.Xr man 7 .
+.It
+.Dv FORM_CAT No = 0x02 :
+The manual page is preformatted.
+.El
+.It
+Zero to three NUL bytes for padding.
+.El
+.Pp
+The macros table consists of:
+.Pp
+.Bl -dash -compact -offset 2n -width 1n
+.It
+The number of different macro keys, currently 36.
+The ordering of macros is defined in
+.In mansearch.h
+and the significance of the macro keys is documented in
 .Xr apropos 1 .
-.It Sy keys.key
-The string found in those contexts.
+.It
+For each macro key, one pointer to the respective macro table.
+.It
+For each macro key, the macro table (variable length).
+.El
+.Pp
+Each macro table consists of:
+.Pp
+.Bl -dash -compact -offset 2n -width 1n
+.It
+The number of entries in the table.
+.It
+For each entry:
+.Bl -dash -compact -offset 2n -width 1n
+.It
+One pointer to the value of the macro key.
+Each value is a string of text taken from some macro invocation.
+.It
+One pointer to the list of pages.
+.El
+.It
+For each entry, the value of the macro key.
+.It
+Zero to three NUL bytes for padding.
+.It
+For each entry, one or more pointers to pages in the pages table,
+pointing to the pointer to the list of names,
+followed by the number 0.
 .El
 .Sh FILES
 .Bl -tag -width /usr/share/man/mandoc.db -compact
@@ -128,10 +197,16 @@ Window System.
 The same for
 .Xr packages 7 .
 .El
+.Pp
+A program to dump
+.Nm
+files in a human-readable format suitable for
+.Xr diff 1
+is provided in the directory
+.Pa /usr/src/regress/usr.bin/mandoc/db/dbm_dump/ .
 .Sh SEE ALSO
 .Xr apropos 1 ,
 .Xr man 1 ,
-.Xr sqlite3 1 ,
 .Xr whatis 1 ,
 .Xr makewhatis 8
 .Sh HISTORY
@@ -140,7 +215,7 @@ A manual page database
 first appeared in
 .Bx 2 .
 The present format first appeared in
-.Ox 5.6 .
+.Ox 6.1 .
 .Sh AUTHORS
 .An -nosplit
 The original version of
@@ -148,9 +223,6 @@ The original version of
 was written by
 .An Bill Joy
 in 1979.
-An SQLite3 version was first implemented by
-.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
-in 2012.
 The present database format was designed by
 .An Ingo Schwarze Aq Mt schwarze@openbsd.org
-in 2014.
+in 2016.
diff --git a/contrib/mdocml/mandoc.h b/contrib/mdocml/mandoc.h
index d63814c6dea..2ea64ea0aea 100644
--- a/contrib/mdocml/mandoc.h
+++ b/contrib/mdocml/mandoc.h
@@ -1,7 +1,7 @@
-/*	$Id: mandoc.h,v 1.209 2016/01/08 02:53:13 schwarze Exp $ */
+/*	$Id: mandoc.h,v 1.213 2017/01/09 01:37:03 schwarze Exp $ */
 /*
  * Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons 
- * Copyright (c) 2010-2016 Ingo Schwarze 
+ * Copyright (c) 2010-2017 Ingo Schwarze 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -65,10 +65,11 @@ enum	mandocerr {
 	MANDOCERR_DOC_EMPTY, /* no document body */
 	MANDOCERR_SEC_BEFORE, /* content before first section header: macro */
 	MANDOCERR_NAMESEC_FIRST, /* first section is not NAME: Sh title */
-	MANDOCERR_NAMESEC_NONM, /* NAME section without name */
+	MANDOCERR_NAMESEC_NONM, /* NAME section without Nm before Nd */
 	MANDOCERR_NAMESEC_NOND, /* NAME section without description */
 	MANDOCERR_NAMESEC_ND, /* description not at the end of NAME */
 	MANDOCERR_NAMESEC_BAD, /* bad NAME section content: macro */
+	MANDOCERR_NAMESEC_PUNCT, /* missing comma before name: Nm name */
 	MANDOCERR_ND_EMPTY, /* missing description line, using "" */
 	MANDOCERR_SEC_ORDER, /* sections out of conventional order: Sh title */
 	MANDOCERR_SEC_REP, /* duplicate section title: Sh title */
@@ -98,7 +99,7 @@ enum	mandocerr {
 	MANDOCERR_ARG_EMPTY, /* empty argument, using 0n: macro arg */
 	MANDOCERR_BD_NOTYPE, /* missing display type, using -ragged: Bd */
 	MANDOCERR_BL_LATETYPE, /* list type is not the first argument: Bl arg */
-	MANDOCERR_BL_NOWIDTH, /* missing -width in -tag list, using 8n */
+	MANDOCERR_BL_NOWIDTH, /* missing -width in -tag list, using 6n */
 	MANDOCERR_EX_NONAME, /* missing utility name, using "": Ex */
 	MANDOCERR_FO_NOHEAD, /* missing function name, using "": Fo */
 	MANDOCERR_IT_NOHEAD, /* empty head in list item: Bl -type It */
@@ -107,6 +108,7 @@ enum	mandocerr {
 	MANDOCERR_BF_BADFONT, /* unknown font type, using \fR: Bf font */
 	MANDOCERR_PF_SKIP, /* nothing follows prefix: Pf arg */
 	MANDOCERR_RS_EMPTY, /* empty reference block: Rs */
+	MANDOCERR_XR_NOSEC, /* missing section argument: Xr arg */
 	MANDOCERR_ARG_STD, /* missing -std argument, adding it: macro */
 	MANDOCERR_OP_EMPTY, /* missing option string, using "": OP */
 	MANDOCERR_UR_NOHEAD, /* missing resource identifier, using "": UR */
@@ -433,3 +435,4 @@ void		  mparse_result(struct mparse *,
 const char	 *mparse_getkeep(const struct mparse *);
 const char	 *mparse_strerror(enum mandocerr);
 const char	 *mparse_strlevel(enum mandoclevel);
+void		  mparse_updaterc(struct mparse *, enum mandoclevel *);
diff --git a/contrib/mdocml/mandoc_aux.h b/contrib/mdocml/mandoc_aux.h
index 2ae3a0cd2de..603cc5a7257 100644
--- a/contrib/mdocml/mandoc_aux.h
+++ b/contrib/mdocml/mandoc_aux.h
@@ -1,4 +1,4 @@
-/*	$Id: mandoc_aux.h,v 1.4 2015/11/07 14:01:16 schwarze Exp $ */
+/*	$Id: mandoc_aux.h,v 1.5 2016/07/19 13:36:13 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2011 Kristaps Dzonsons 
  * Copyright (c) 2014 Ingo Schwarze 
@@ -16,7 +16,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-int		  mandoc_asprintf(char **, const char *, ...);
+int		  mandoc_asprintf(char **, const char *, ...)
+			__attribute__((__format__ (printf, 2, 3)));
 void		 *mandoc_calloc(size_t, size_t);
 void		 *mandoc_malloc(size_t);
 void		 *mandoc_realloc(void *, size_t);
diff --git a/contrib/mdocml/mandoc_html.3 b/contrib/mdocml/mandoc_html.3
index 994eb3a288e..80b1fe69f7c 100644
--- a/contrib/mdocml/mandoc_html.3
+++ b/contrib/mdocml/mandoc_html.3
@@ -1,6 +1,6 @@
-.\"	$Id: mandoc_html.3,v 1.1 2014/07/23 18:13:09 schwarze Exp $
+.\"	$Id: mandoc_html.3,v 1.3 2017/01/17 15:32:44 schwarze Exp $
 .\"
-.\" Copyright (c) 2014 Ingo Schwarze 
+.\" Copyright (c) 2014, 2017 Ingo Schwarze 
 .\"
 .\" Permission to use, copy, modify, and distribute this software for any
 .\" purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: July 23 2014 $
+.Dd $Mdocdate: January 17 2017 $
 .Dt MANDOC_HTML 3
 .Os
 .Sh NAME
@@ -30,8 +30,8 @@
 .Fo print_otag
 .Fa "struct html *h"
 .Fa "enum htmltag tag"
-.Fa "int sz"
-.Fa "const struct htmlpair *p"
+.Fa "const char *fmt"
+.Fa ...
 .Fc
 .Ft void
 .Fo print_tagq
@@ -84,15 +84,6 @@ These structures are declared in
 .Bl -tag -width Ds
 .It Vt struct html
 Internal state of the HTML formatter.
-.It Vt struct htmlpair
-Holds one HTML attribute.
-Members are
-.Fa "enum htmlattr key"
-and
-.Fa "const char *val" .
-Helper macros
-.Fn PAIR_*
-are provided to support initialization of such structures.
 .It Vt struct tag
 One entry for the LIFO stack of HTML elements.
 Members are
@@ -134,14 +125,136 @@ The function
 .Fn print_otag
 prints the start tag of an HTML element with the name
 .Fa tag ,
-including the
-.Fa sz
-attributes that can optionally be provided in the
-.Fa p
-array.
-It uses the private function
-.Fn print_attr
-which in turn uses the private function
+optionally including the attributes specified by
+.Fa fmt .
+If
+.Fa fmt
+is the empty string, no attributes are written.
+Each letter of
+.Fa fmt
+specifies one attribute to write.
+Most attributes require one
+.Va char *
+argument which becomes the value of the attribute.
+The arguments have to be given in the same order as the attribute letters.
+.Bl -tag -width 1n -offset indent
+.It Cm c
+Print a
+.Cm class
+attribute.
+.It Cm h
+Print a
+.Cm href
+attribute.
+This attribute letter can optionally be followed by a modifier letter.
+If followed by
+.Cm R ,
+it formats the link as a local one by prefixing a
+.Sq #
+character.
+If followed by
+.Cm I ,
+it interpretes the argument as a header file name
+and generates a link using the
+.Xr mandoc 1
+.Fl O Cm includes
+option.
+If followed by
+.Cm M ,
+it takes two arguments instead of one, a manual page name and
+section, and formats them as a link to a manual page using the
+.Xr mandoc 1
+.Fl O Cm man
+option.
+.It Cm i
+Print an
+.Cm id
+attribute.
+.It Cm \&?
+Print an arbitrary attribute.
+This format letter requires two
+.Vt char *
+arguments, the attribute name and the value.
+.It Cm s
+Print a
+.Cm style
+attribute.
+If present, it must be the last format letter.
+In contrast to the other format letters, this one does not yet
+print the value and does not require an argument.
+Instead, the rest of the format string consists of pairs of
+argument type letters and style name letters.
+.El
+.Pp
+Argument type letters each require on argument as follows:
+.Bl -tag -width 1n -offset indent
+.It Cm h
+Requires one
+.Vt int
+argument, interpreted as a horizontal length in units of
+.Dv SCALE_EN .
+.It Cm s
+Requires one
+.Vt char *
+argument, used as a style value.
+.It Cm u
+Requires one
+.Vt struct roffsu *
+argument, used as a length.
+.It Cm v
+Requires one
+.Vt int
+argument, interpreted as a vertical length in units of
+.Dv SCALE_VS .
+.It Cm w
+Requires one
+.Vt char *
+argument, interpreted as an
+.Xr mdoc 7 Ns -style
+width specifier.
+.El
+.Pp
+Style name letters decide what to do with the preceding argument:
+.Bl -tag -width 1n -offset indent
+.It Cm b
+Set
+.Cm margin-bottom
+to the given length.
+.It Cm h
+Set
+.Cm height
+to the given length.
+.It Cm i
+Set
+.Cm text-indent
+to the given length.
+.It Cm l
+Set
+.Cm margin-left
+to the given length.
+.It Cm t
+Set
+.Cm margin-top
+to the given length.
+.It Cm w
+Set
+.Cm width
+to the given length.
+.It Cm W
+Set
+.Cm min-width
+to the given length.
+.It Cm \&?
+The special pair
+.Cm s?
+requires two
+.Vt char *
+arguments.
+The first is the style name, the second its value.
+.El
+.Pp
+.Fn print_otag
+uses the private function
 .Fn print_encode
 to take care of HTML encoding.
 If required by the element type, it remembers in
@@ -175,28 +288,6 @@ and
 functions.
 .Pp
 The functions
-.Fn bufinit ,
-.Fn bufcat* ,
-and
-.Fn buffmt*
-do not directly produce output but buffer text in the
-.Fa buf
-member of
-.Fa h .
-They are not used internally by
-.Pa html.c
-but intended for use by the language-specific formatters
-to ease preparation of strings for the
-.Fa p
-argument of
-.Fn print_otag
-and for the
-.Fa word
-argument of
-.Fn print_text .
-Consequently, these functions do not do any HTML encoding.
-.Pp
-The functions
 .Fn html_strlen ,
 .Fn print_eqn ,
 .Fn print_tbl ,
diff --git a/contrib/mdocml/mandocdb.c b/contrib/mdocml/mandocdb.c
index 3b9bda0d612..133e73670c1 100644
--- a/contrib/mdocml/mandocdb.c
+++ b/contrib/mdocml/mandocdb.c
@@ -1,7 +1,8 @@
-/*	$Id: mandocdb.c,v 1.218 2016/07/12 05:18:38 kristaps Exp $ */
+/*	$Id: mandocdb.c,v 1.237 2017/01/11 17:39:53 schwarze Exp $ */
 /*
  * Copyright (c) 2011, 2012 Kristaps Dzonsons 
- * Copyright (c) 2011-2016 Ingo Schwarze 
+ * Copyright (c) 2011-2017 Ingo Schwarze 
+ * Copyright (c) 2016 Ed Maste 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -37,6 +38,7 @@
 #if HAVE_SANDBOX_INIT
 #include 
 #endif
+#include 
 #include 
 #include 
 #include 
@@ -44,8 +46,6 @@
 #include 
 #include 
 
-#include 
-
 #include "mandoc_aux.h"
 #include "mandoc_ohash.h"
 #include "mandoc.h"
@@ -54,29 +54,11 @@
 #include "man.h"
 #include "manconf.h"
 #include "mansearch.h"
+#include "dba_array.h"
+#include "dba.h"
 
-extern int mansearch_keymax;
 extern const char *const mansearch_keynames[];
 
-#define	SQL_EXEC(_v) \
-	if (SQLITE_OK != sqlite3_exec(db, (_v), NULL, NULL, NULL)) \
-		say("", "%s: %s", (_v), sqlite3_errmsg(db))
-#define	SQL_BIND_TEXT(_s, _i, _v) \
-	if (SQLITE_OK != sqlite3_bind_text \
-		((_s), (_i)++, (_v), -1, SQLITE_STATIC)) \
-		say(mlink->file, "%s", sqlite3_errmsg(db))
-#define	SQL_BIND_INT(_s, _i, _v) \
-	if (SQLITE_OK != sqlite3_bind_int \
-		((_s), (_i)++, (_v))) \
-		say(mlink->file, "%s", sqlite3_errmsg(db))
-#define	SQL_BIND_INT64(_s, _i, _v) \
-	if (SQLITE_OK != sqlite3_bind_int64 \
-		((_s), (_i)++, (_v))) \
-		say(mlink->file, "%s", sqlite3_errmsg(db))
-#define SQL_STEP(_s) \
-	if (SQLITE_DONE != sqlite3_step((_s))) \
-		say(mlink->file, "%s", sqlite3_errmsg(db))
-
 enum	op {
 	OP_DEFAULT = 0, /* new dbs from dir list or default config */
 	OP_CONFFILE, /* new databases from custom config file */
@@ -98,15 +80,15 @@ struct	inodev {
 
 struct	mpage {
 	struct inodev	 inodev;  /* used for hashing routine */
-	int64_t		 pageid;  /* pageid in mpages SQL table */
+	struct dba_array *dba;
 	char		*sec;     /* section from file content */
 	char		*arch;    /* architecture from file content */
 	char		*title;   /* title from file content */
 	char		*desc;    /* description from file content */
 	struct mpage	*next;    /* singly linked list */
 	struct mlink	*mlinks;  /* singly linked list */
-	int		 form;    /* format from file content */
 	int		 name_head_done;
+	enum form	 form;    /* format from file content */
 };
 
 struct	mlink {
@@ -117,19 +99,9 @@ struct	mlink {
 	char		*fsec;    /* section from file name suffix */
 	struct mlink	*next;    /* singly linked list */
 	struct mpage	*mpage;   /* parent */
-	int		 dform;   /* format from directory */
-	int		 fform;   /* format from file name suffix */
 	int		 gzip;	  /* filename has a .gz suffix */
-};
-
-enum	stmt {
-	STMT_DELETE_PAGE = 0,	/* delete mpage */
-	STMT_INSERT_PAGE,	/* insert mpage */
-	STMT_INSERT_LINK,	/* insert mlink */
-	STMT_INSERT_NAME,	/* insert name */
-	STMT_SELECT_NAME,	/* retrieve existing name flags */
-	STMT_INSERT_KEY,	/* insert parsed key */
-	STMT__MAX
+	enum form	 dform;   /* format from directory */
+	enum form	 fform;   /* format from file name suffix */
 };
 
 typedef	int (*mdoc_fp)(struct mpage *, const struct roff_meta *,
@@ -138,23 +110,28 @@ typedef	int (*mdoc_fp)(struct mpage *, const struct roff_meta *,
 struct	mdoc_handler {
 	mdoc_fp		 fp; /* optional handler */
 	uint64_t	 mask;  /* set unless handler returns 0 */
+	int		 taboo;  /* node flags that must not be set */
 };
 
-static	void	 dbclose(int);
-static	void	 dbadd(struct mpage *);
+
+int		 mandocdb(int, char *[]);
+
+static	void	 dbadd(struct dba *, struct mpage *);
 static	void	 dbadd_mlink(const struct mlink *mlink);
-static	void	 dbadd_mlink_name(const struct mlink *mlink);
-static	int	 dbopen(int);
-static	void	 dbprune(void);
+static	void	 dbprune(struct dba *);
+static	void	 dbwrite(struct dba *);
 static	void	 filescan(const char *);
+#if HAVE_FTS_COMPARE_CONST
 static	int	 fts_compare(const FTSENT *const *, const FTSENT *const *);
+#else
+static	int	 fts_compare(const FTSENT **, const FTSENT **);
+#endif
 static	void	 mlink_add(struct mlink *, const struct stat *);
 static	void	 mlink_check(struct mpage *, struct mlink *);
 static	void	 mlink_free(struct mlink *);
 static	void	 mlinks_undupe(struct mpage *);
 static	void	 mpages_free(void);
-static	void	 mpages_merge(struct mparse *);
-static	void	 names_check(void);
+static	void	 mpages_merge(struct dba *, struct mparse *);
 static	void	 parse_cat(struct mpage *, int);
 static	void	 parse_man(struct mpage *, const struct roff_meta *,
 			const struct roff_node *);
@@ -182,14 +159,14 @@ static	int	 parse_mdoc_Xr(struct mpage *, const struct roff_meta *,
 static	void	 putkey(const struct mpage *, char *, uint64_t);
 static	void	 putkeys(const struct mpage *, char *, size_t, uint64_t);
 static	void	 putmdockey(const struct mpage *,
-			const struct roff_node *, uint64_t);
+			const struct roff_node *, uint64_t, int);
 static	int	 render_string(char **, size_t *);
-static	void	 say(const char *, const char *, ...);
+static	void	 say(const char *, const char *, ...)
+			__attribute__((__format__ (printf, 2, 3)));
 static	int	 set_basedir(const char *, int);
 static	int	 treescan(void);
 static	size_t	 utf8(unsigned int, char [7]);
 
-static	char		 tempfilename[32];
 static	int		 nodb; /* no database changes */
 static	int		 mparse_options; /* abort the parse early */
 static	int		 use_all; /* use all found files */
@@ -199,139 +176,137 @@ static	int		 write_utf8; /* write UTF-8 output; else ASCII */
 static	int		 exitcode; /* to be returned by main */
 static	enum op		 op; /* operational mode */
 static	char		 basedir[PATH_MAX]; /* current base directory */
+static	struct mpage	*mpage_head; /* list of distinct manual pages */
 static	struct ohash	 mpages; /* table of distinct manual pages */
 static	struct ohash	 mlinks; /* table of directory entries */
 static	struct ohash	 names; /* table of all names */
 static	struct ohash	 strings; /* table of all strings */
-static	sqlite3		*db = NULL; /* current database */
-static	sqlite3_stmt	*stmts[STMT__MAX]; /* current statements */
 static	uint64_t	 name_mask;
-static	struct mpage	*mpage_head;
 
 static	const struct mdoc_handler mdocs[MDOC_MAX] = {
-	{ NULL, 0 },  /* Ap */
-	{ NULL, 0 },  /* Dd */
-	{ NULL, 0 },  /* Dt */
-	{ NULL, 0 },  /* Os */
-	{ parse_mdoc_Sh, TYPE_Sh }, /* Sh */
-	{ parse_mdoc_head, TYPE_Ss }, /* Ss */
-	{ NULL, 0 },  /* Pp */
-	{ NULL, 0 },  /* D1 */
-	{ NULL, 0 },  /* Dl */
-	{ NULL, 0 },  /* Bd */
-	{ NULL, 0 },  /* Ed */
-	{ NULL, 0 },  /* Bl */
-	{ NULL, 0 },  /* El */
-	{ NULL, 0 },  /* It */
-	{ NULL, 0 },  /* Ad */
-	{ NULL, TYPE_An },  /* An */
-	{ NULL, TYPE_Ar },  /* Ar */
-	{ NULL, TYPE_Cd },  /* Cd */
-	{ NULL, TYPE_Cm },  /* Cm */
-	{ NULL, TYPE_Dv },  /* Dv */
-	{ NULL, TYPE_Er },  /* Er */
-	{ NULL, TYPE_Ev },  /* Ev */
-	{ NULL, 0 },  /* Ex */
-	{ NULL, TYPE_Fa },  /* Fa */
-	{ parse_mdoc_Fd, 0 },  /* Fd */
-	{ NULL, TYPE_Fl },  /* Fl */
-	{ parse_mdoc_Fn, 0 },  /* Fn */
-	{ NULL, TYPE_Ft },  /* Ft */
-	{ NULL, TYPE_Ic },  /* Ic */
-	{ NULL, TYPE_In },  /* In */
-	{ NULL, TYPE_Li },  /* Li */
-	{ parse_mdoc_Nd, 0 },  /* Nd */
-	{ parse_mdoc_Nm, 0 },  /* Nm */
-	{ NULL, 0 },  /* Op */
-	{ NULL, 0 },  /* Ot */
-	{ NULL, TYPE_Pa },  /* Pa */
-	{ NULL, 0 },  /* Rv */
-	{ NULL, TYPE_St },  /* St */
-	{ parse_mdoc_Va, TYPE_Va },  /* Va */
-	{ parse_mdoc_Va, TYPE_Vt },  /* Vt */
-	{ parse_mdoc_Xr, 0 },  /* Xr */
-	{ NULL, 0 },  /* %A */
-	{ NULL, 0 },  /* %B */
-	{ NULL, 0 },  /* %D */
-	{ NULL, 0 },  /* %I */
-	{ NULL, 0 },  /* %J */
-	{ NULL, 0 },  /* %N */
-	{ NULL, 0 },  /* %O */
-	{ NULL, 0 },  /* %P */
-	{ NULL, 0 },  /* %R */
-	{ NULL, 0 },  /* %T */
-	{ NULL, 0 },  /* %V */
-	{ NULL, 0 },  /* Ac */
-	{ NULL, 0 },  /* Ao */
-	{ NULL, 0 },  /* Aq */
-	{ NULL, TYPE_At },  /* At */
-	{ NULL, 0 },  /* Bc */
-	{ NULL, 0 },  /* Bf */
-	{ NULL, 0 },  /* Bo */
-	{ NULL, 0 },  /* Bq */
-	{ NULL, TYPE_Bsx },  /* Bsx */
-	{ NULL, TYPE_Bx },  /* Bx */
-	{ NULL, 0 },  /* Db */
-	{ NULL, 0 },  /* Dc */
-	{ NULL, 0 },  /* Do */
-	{ NULL, 0 },  /* Dq */
-	{ NULL, 0 },  /* Ec */
-	{ NULL, 0 },  /* Ef */
-	{ NULL, TYPE_Em },  /* Em */
-	{ NULL, 0 },  /* Eo */
-	{ NULL, TYPE_Fx },  /* Fx */
-	{ NULL, TYPE_Ms },  /* Ms */
-	{ NULL, 0 },  /* No */
-	{ NULL, 0 },  /* Ns */
-	{ NULL, TYPE_Nx },  /* Nx */
-	{ NULL, TYPE_Ox },  /* Ox */
-	{ NULL, 0 },  /* Pc */
-	{ NULL, 0 },  /* Pf */
-	{ NULL, 0 },  /* Po */
-	{ NULL, 0 },  /* Pq */
-	{ NULL, 0 },  /* Qc */
-	{ NULL, 0 },  /* Ql */
-	{ NULL, 0 },  /* Qo */
-	{ NULL, 0 },  /* Qq */
-	{ NULL, 0 },  /* Re */
-	{ NULL, 0 },  /* Rs */
-	{ NULL, 0 },  /* Sc */
-	{ NULL, 0 },  /* So */
-	{ NULL, 0 },  /* Sq */
-	{ NULL, 0 },  /* Sm */
-	{ NULL, 0 },  /* Sx */
-	{ NULL, TYPE_Sy },  /* Sy */
-	{ NULL, TYPE_Tn },  /* Tn */
-	{ NULL, 0 },  /* Ux */
-	{ NULL, 0 },  /* Xc */
-	{ NULL, 0 },  /* Xo */
-	{ parse_mdoc_Fo, 0 },  /* Fo */
-	{ NULL, 0 },  /* Fc */
-	{ NULL, 0 },  /* Oo */
-	{ NULL, 0 },  /* Oc */
-	{ NULL, 0 },  /* Bk */
-	{ NULL, 0 },  /* Ek */
-	{ NULL, 0 },  /* Bt */
-	{ NULL, 0 },  /* Hf */
-	{ NULL, 0 },  /* Fr */
-	{ NULL, 0 },  /* Ud */
-	{ NULL, TYPE_Lb },  /* Lb */
-	{ NULL, 0 },  /* Lp */
-	{ NULL, TYPE_Lk },  /* Lk */
-	{ NULL, TYPE_Mt },  /* Mt */
-	{ NULL, 0 },  /* Brq */
-	{ NULL, 0 },  /* Bro */
-	{ NULL, 0 },  /* Brc */
-	{ NULL, 0 },  /* %C */
-	{ NULL, 0 },  /* Es */
-	{ NULL, 0 },  /* En */
-	{ NULL, TYPE_Dx },  /* Dx */
-	{ NULL, 0 },  /* %Q */
-	{ NULL, 0 },  /* br */
-	{ NULL, 0 },  /* sp */
-	{ NULL, 0 },  /* %U */
-	{ NULL, 0 },  /* Ta */
-	{ NULL, 0 },  /* ll */
+	{ NULL, 0, 0 },  /* Ap */
+	{ NULL, 0, NODE_NOPRT },  /* Dd */
+	{ NULL, 0, NODE_NOPRT },  /* Dt */
+	{ NULL, 0, NODE_NOPRT },  /* Os */
+	{ parse_mdoc_Sh, TYPE_Sh, 0 }, /* Sh */
+	{ parse_mdoc_head, TYPE_Ss, 0 }, /* Ss */
+	{ NULL, 0, 0 },  /* Pp */
+	{ NULL, 0, 0 },  /* D1 */
+	{ NULL, 0, 0 },  /* Dl */
+	{ NULL, 0, 0 },  /* Bd */
+	{ NULL, 0, 0 },  /* Ed */
+	{ NULL, 0, 0 },  /* Bl */
+	{ NULL, 0, 0 },  /* El */
+	{ NULL, 0, 0 },  /* It */
+	{ NULL, 0, 0 },  /* Ad */
+	{ NULL, TYPE_An, 0 },  /* An */
+	{ NULL, TYPE_Ar, 0 },  /* Ar */
+	{ NULL, TYPE_Cd, 0 },  /* Cd */
+	{ NULL, TYPE_Cm, 0 },  /* Cm */
+	{ NULL, TYPE_Dv, 0 },  /* Dv */
+	{ NULL, TYPE_Er, 0 },  /* Er */
+	{ NULL, TYPE_Ev, 0 },  /* Ev */
+	{ NULL, 0, 0 },  /* Ex */
+	{ NULL, TYPE_Fa, 0 },  /* Fa */
+	{ parse_mdoc_Fd, 0, 0 },  /* Fd */
+	{ NULL, TYPE_Fl, 0 },  /* Fl */
+	{ parse_mdoc_Fn, 0, 0 },  /* Fn */
+	{ NULL, TYPE_Ft, 0 },  /* Ft */
+	{ NULL, TYPE_Ic, 0 },  /* Ic */
+	{ NULL, TYPE_In, 0 },  /* In */
+	{ NULL, TYPE_Li, 0 },  /* Li */
+	{ parse_mdoc_Nd, 0, 0 },  /* Nd */
+	{ parse_mdoc_Nm, 0, 0 },  /* Nm */
+	{ NULL, 0, 0 },  /* Op */
+	{ NULL, 0, 0 },  /* Ot */
+	{ NULL, TYPE_Pa, NODE_NOSRC },  /* Pa */
+	{ NULL, 0, 0 },  /* Rv */
+	{ NULL, TYPE_St, 0 },  /* St */
+	{ parse_mdoc_Va, TYPE_Va, 0 },  /* Va */
+	{ parse_mdoc_Va, TYPE_Vt, 0 },  /* Vt */
+	{ parse_mdoc_Xr, 0, 0 },  /* Xr */
+	{ NULL, 0, 0 },  /* %A */
+	{ NULL, 0, 0 },  /* %B */
+	{ NULL, 0, 0 },  /* %D */
+	{ NULL, 0, 0 },  /* %I */
+	{ NULL, 0, 0 },  /* %J */
+	{ NULL, 0, 0 },  /* %N */
+	{ NULL, 0, 0 },  /* %O */
+	{ NULL, 0, 0 },  /* %P */
+	{ NULL, 0, 0 },  /* %R */
+	{ NULL, 0, 0 },  /* %T */
+	{ NULL, 0, 0 },  /* %V */
+	{ NULL, 0, 0 },  /* Ac */
+	{ NULL, 0, 0 },  /* Ao */
+	{ NULL, 0, 0 },  /* Aq */
+	{ NULL, TYPE_At, 0 },  /* At */
+	{ NULL, 0, 0 },  /* Bc */
+	{ NULL, 0, 0 },  /* Bf */
+	{ NULL, 0, 0 },  /* Bo */
+	{ NULL, 0, 0 },  /* Bq */
+	{ NULL, TYPE_Bsx, NODE_NOSRC },  /* Bsx */
+	{ NULL, TYPE_Bx, NODE_NOSRC },  /* Bx */
+	{ NULL, 0, 0 },  /* Db */
+	{ NULL, 0, 0 },  /* Dc */
+	{ NULL, 0, 0 },  /* Do */
+	{ NULL, 0, 0 },  /* Dq */
+	{ NULL, 0, 0 },  /* Ec */
+	{ NULL, 0, 0 },  /* Ef */
+	{ NULL, TYPE_Em, 0 },  /* Em */
+	{ NULL, 0, 0 },  /* Eo */
+	{ NULL, TYPE_Fx, NODE_NOSRC },  /* Fx */
+	{ NULL, TYPE_Ms, 0 },  /* Ms */
+	{ NULL, 0, 0 },  /* No */
+	{ NULL, 0, 0 },  /* Ns */
+	{ NULL, TYPE_Nx, NODE_NOSRC },  /* Nx */
+	{ NULL, TYPE_Ox, NODE_NOSRC },  /* Ox */
+	{ NULL, 0, 0 },  /* Pc */
+	{ NULL, 0, 0 },  /* Pf */
+	{ NULL, 0, 0 },  /* Po */
+	{ NULL, 0, 0 },  /* Pq */
+	{ NULL, 0, 0 },  /* Qc */
+	{ NULL, 0, 0 },  /* Ql */
+	{ NULL, 0, 0 },  /* Qo */
+	{ NULL, 0, 0 },  /* Qq */
+	{ NULL, 0, 0 },  /* Re */
+	{ NULL, 0, 0 },  /* Rs */
+	{ NULL, 0, 0 },  /* Sc */
+	{ NULL, 0, 0 },  /* So */
+	{ NULL, 0, 0 },  /* Sq */
+	{ NULL, 0, 0 },  /* Sm */
+	{ NULL, 0, 0 },  /* Sx */
+	{ NULL, TYPE_Sy, 0 },  /* Sy */
+	{ NULL, TYPE_Tn, 0 },  /* Tn */
+	{ NULL, 0, NODE_NOSRC },  /* Ux */
+	{ NULL, 0, 0 },  /* Xc */
+	{ NULL, 0, 0 },  /* Xo */
+	{ parse_mdoc_Fo, 0, 0 },  /* Fo */
+	{ NULL, 0, 0 },  /* Fc */
+	{ NULL, 0, 0 },  /* Oo */
+	{ NULL, 0, 0 },  /* Oc */
+	{ NULL, 0, 0 },  /* Bk */
+	{ NULL, 0, 0 },  /* Ek */
+	{ NULL, 0, 0 },  /* Bt */
+	{ NULL, 0, 0 },  /* Hf */
+	{ NULL, 0, 0 },  /* Fr */
+	{ NULL, 0, 0 },  /* Ud */
+	{ NULL, TYPE_Lb, NODE_NOSRC },  /* Lb */
+	{ NULL, 0, 0 },  /* Lp */
+	{ NULL, TYPE_Lk, 0 },  /* Lk */
+	{ NULL, TYPE_Mt, NODE_NOSRC },  /* Mt */
+	{ NULL, 0, 0 },  /* Brq */
+	{ NULL, 0, 0 },  /* Bro */
+	{ NULL, 0, 0 },  /* Brc */
+	{ NULL, 0, 0 },  /* %C */
+	{ NULL, 0, 0 },  /* Es */
+	{ NULL, 0, 0 },  /* En */
+	{ NULL, TYPE_Dx, NODE_NOSRC },  /* Dx */
+	{ NULL, 0, 0 },  /* %Q */
+	{ NULL, 0, 0 },  /* br */
+	{ NULL, 0, 0 },  /* sp */
+	{ NULL, 0, 0 },  /* %U */
+	{ NULL, 0, 0 },  /* Ta */
+	{ NULL, 0, 0 },  /* ll */
 };
 
 
@@ -340,6 +315,7 @@ mandocdb(int argc, char *argv[])
 {
 	struct manconf	  conf;
 	struct mparse	 *mp;
+	struct dba	 *dba;
 	const char	 *path_arg, *progname;
 	size_t		  j, sz;
 	int		  ch, i;
@@ -359,7 +335,6 @@ mandocdb(int argc, char *argv[])
 #endif
 
 	memset(&conf, 0, sizeof(conf));
-	memset(stmts, 0, STMT__MAX * sizeof(sqlite3_stmt *));
 
 	/*
 	 * We accept a few different invocations.
@@ -460,7 +435,8 @@ mandocdb(int argc, char *argv[])
 		if (OP_TEST != op && 0 == set_basedir(path_arg, 1))
 			goto out;
 
-		if (dbopen(1)) {
+		dba = nodb ? dba_new(128) : dba_read(MANDOC_DB);
+		if (dba != NULL) {
 			/*
 			 * The existing database is usable.  Process
 			 * all files specified on the command-line.
@@ -477,28 +453,28 @@ mandocdb(int argc, char *argv[])
 			use_all = 1;
 			for (i = 0; i < argc; i++)
 				filescan(argv[i]);
-			if (OP_TEST != op)
-				dbprune();
+			if (nodb == 0)
+				dbprune(dba);
 		} else {
-			/*
-			 * Database missing or corrupt.
-			 * Recreate from scratch.
-			 */
+			/* Database missing or corrupt. */
+			if (op != OP_UPDATE || errno != ENOENT)
+				say(MANDOC_DB, "%s: Automatically recreating"
+				    " from scratch", strerror(errno));
 			exitcode = (int)MANDOCLEVEL_OK;
 			op = OP_DEFAULT;
 			if (0 == treescan())
 				goto out;
-			if (0 == dbopen(0))
-				goto out;
+			dba = dba_new(128);
 		}
 		if (OP_DELETE != op)
-			mpages_merge(mp);
-		dbclose(OP_DEFAULT == op ? 0 : 1);
+			mpages_merge(dba, mp);
+		if (nodb == 0)
+			dbwrite(dba);
+		dba_free(dba);
 	} else {
 		/*
 		 * If we have arguments, use them as our manpaths.
-		 * If we don't, grok from manpath(1) or however else
-		 * manconf_parse() wants to do it.
+		 * If we don't, use man.conf(5).
 		 */
 		if (argc > 0) {
 			conf.manpath.paths = mandoc_reallocarray(NULL,
@@ -538,14 +514,11 @@ mandocdb(int argc, char *argv[])
 				continue;
 			if (0 == treescan())
 				continue;
-			if (0 == dbopen(0))
-				continue;
-
-			mpages_merge(mp);
-			if (warnings && !nodb &&
-			    ! (MPARSE_QUICK & mparse_options))
-				names_check();
-			dbclose(0);
+			dba = dba_new(128);
+			mpages_merge(dba, mp);
+			if (nodb == 0)
+				dbwrite(dba);
+			dba_free(dba);
 
 			if (j + 1 < conf.manpath.sz) {
 				mpages_free();
@@ -574,17 +547,17 @@ usage:
 	return (int)MANDOCLEVEL_BADARG;
 }
 
+/*
+ * To get a singly linked list in alpha order while inserting entries
+ * at the beginning, process directory entries in reverse alpha order.
+ */
 static int
+#if HAVE_FTS_COMPARE_CONST
 fts_compare(const FTSENT *const *a, const FTSENT *const *b)
+#else
+fts_compare(const FTSENT **a, const FTSENT **b)
+#endif
 {
-
-	/*
-	 * The mpage list is processed in the opposite order to which pages are
-	 * added, so traverse the hierarchy in reverse alpha order, resulting
-	 * in database inserts in alpha order. This is not required for correct
-	 * operation, but is helpful when inspecting the database during
-	 * development.
-	 */
 	return -strcmp((*a)->fts_name, (*b)->fts_name);
 }
 
@@ -609,7 +582,8 @@ treescan(void)
 	FTS		*f;
 	FTSENT		*ff;
 	struct mlink	*mlink;
-	int		 dform, gzip;
+	int		 gzip;
+	enum form	 dform;
 	char		*dsec, *arch, *fsec, *cp;
 	const char	*path;
 	const char	*argv[2];
@@ -983,6 +957,7 @@ mlink_add(struct mlink *mlink, const struct stat *st)
 		mpage = mandoc_calloc(1, sizeof(struct mpage));
 		mpage->inodev.st_ino = inodev.st_ino;
 		mpage->inodev.st_dev = inodev.st_dev;
+		mpage->form = FORM_NONE;
 		mpage->next = mpage_head;
 		mpage_head = mpage;
 		ohash_insert(&mpages, slot, mpage);
@@ -1009,8 +984,8 @@ mpages_free(void)
 	struct mpage	*mpage;
 	struct mlink	*mlink;
 
-	while (NULL != (mpage = mpage_head)) {
-		while (NULL != (mlink = mpage->mlinks)) {
+	while ((mpage = mpage_head) != NULL) {
+		while ((mlink = mpage->mlinks) != NULL) {
 			mpage->mlinks = mlink->next;
 			mlink_free(mlink);
 		}
@@ -1096,7 +1071,7 @@ mlink_check(struct mpage *mpage, struct mlink *mlink)
 	 * architectures.
 	 * A few manuals are even shared across completely
 	 * different architectures, for example fdformat(1)
-	 * on amd64, i386, sparc, and sparc64.
+	 * on amd64, i386, and sparc64.
 	 */
 
 	if (strcasecmp(mpage->arch, mlink->arch))
@@ -1131,9 +1106,8 @@ mlink_check(struct mpage *mpage, struct mlink *mlink)
  * and filename to determine whether the file is parsable or not.
  */
 static void
-mpages_merge(struct mparse *mp)
+mpages_merge(struct dba *dba, struct mparse *mp)
 {
-	char			 any[] = "any";
 	struct mpage		*mpage, *mpage_dest;
 	struct mlink		*mlink, *mlink_dest;
 	struct roff_man		*man;
@@ -1141,9 +1115,6 @@ mpages_merge(struct mparse *mp)
 	char			*cp;
 	int			 fd;
 
-	if ( ! nodb)
-		SQL_EXEC("BEGIN TRANSACTION");
-
 	for (mpage = mpage_head; mpage != NULL; mpage = mpage->next) {
 		mlinks_undupe(mpage);
 		if ((mlink = mpage->mlinks) == NULL)
@@ -1197,8 +1168,8 @@ mpages_merge(struct mparse *mp)
 					 * to the target.
 					 */
 
-					if (mpage_dest->pageid)
-						dbadd_mlink_name(mlink);
+					if (mpage_dest->dba != NULL)
+						dbadd_mlink(mlink);
 
 					if (mlink->next == NULL)
 						break;
@@ -1234,19 +1205,6 @@ mpages_merge(struct mparse *mp)
 			mpage->arch = mandoc_strdup(mlink->arch);
 			mpage->title = mandoc_strdup(mlink->name);
 		}
-		putkey(mpage, mpage->sec, TYPE_sec);
-		if (*mpage->arch != '\0')
-			putkey(mpage, mpage->arch, TYPE_arch);
-
-		for ( ; mlink != NULL; mlink = mlink->next) {
-			if ('\0' != *mlink->dsec)
-				putkey(mpage, mlink->dsec, TYPE_sec);
-			if ('\0' != *mlink->fsec)
-				putkey(mpage, mlink->fsec, TYPE_sec);
-			putkey(mpage, '\0' == *mlink->arch ?
-			    any : mlink->arch, TYPE_arch);
-			putkey(mpage, mlink->name, NAME_FILE);
-		}
 
 		assert(mpage->desc == NULL);
 		if (man != NULL && man->macroset == MACROSET_MDOC)
@@ -1263,51 +1221,13 @@ mpages_merge(struct mparse *mp)
 			     mlink = mlink->next)
 				mlink_check(mpage, mlink);
 
-		dbadd(mpage);
+		dbadd(dba, mpage);
 		mlink = mpage->mlinks;
 
 nextpage:
 		ohash_delete(&strings);
 		ohash_delete(&names);
 	}
-
-	if (0 == nodb)
-		SQL_EXEC("END TRANSACTION");
-}
-
-static void
-names_check(void)
-{
-	sqlite3_stmt	*stmt;
-	const char	*name, *sec, *arch, *key;
-
-	sqlite3_prepare_v2(db,
-	  "SELECT name, sec, arch, key FROM ("
-	    "SELECT name AS key, pageid FROM names "
-	    "WHERE bits & ? AND NOT EXISTS ("
-	      "SELECT pageid FROM mlinks "
-	      "WHERE mlinks.pageid == names.pageid "
-	      "AND mlinks.name == names.name"
-	    ")"
-	  ") JOIN ("
-	    "SELECT sec, arch, name, pageid FROM mlinks "
-	    "GROUP BY pageid"
-	  ") USING (pageid);",
-	  -1, &stmt, NULL);
-
-	if (sqlite3_bind_int64(stmt, 1, NAME_TITLE) != SQLITE_OK)
-		say("", "%s", sqlite3_errmsg(db));
-
-	while (sqlite3_step(stmt) == SQLITE_ROW) {
-		name = (const char *)sqlite3_column_text(stmt, 0);
-		sec  = (const char *)sqlite3_column_text(stmt, 1);
-		arch = (const char *)sqlite3_column_text(stmt, 2);
-		key  = (const char *)sqlite3_column_text(stmt, 3);
-		say("", "%s(%s%s%s) lacks mlink \"%s\"", name, sec,
-		    '\0' == *arch ? "" : "/",
-		    '\0' == *arch ? "" : arch, key);
-	}
-	sqlite3_finalize(stmt);
 }
 
 static void
@@ -1432,13 +1352,6 @@ parse_cat(struct mpage *mpage, int fd)
 static void
 putkey(const struct mpage *mpage, char *value, uint64_t type)
 {
-	char	 *cp;
-
-	assert(NULL != value);
-	if (TYPE_arch == type)
-		for (cp = value; *cp; cp++)
-			if (isupper((unsigned char)*cp))
-				*cp = _tolower((unsigned char)*cp);
 	putkeys(mpage, value, strlen(value), type);
 }
 
@@ -1447,12 +1360,14 @@ putkey(const struct mpage *mpage, char *value, uint64_t type)
  */
 static void
 putmdockey(const struct mpage *mpage,
-	const struct roff_node *n, uint64_t m)
+	const struct roff_node *n, uint64_t m, int taboo)
 {
 
 	for ( ; NULL != n; n = n->next) {
+		if (n->flags & taboo)
+			continue;
 		if (NULL != n->child)
-			putmdockey(mpage, n->child, m);
+			putmdockey(mpage, n->child, m, taboo);
 		if (n->type == ROFFT_TEXT)
 			putkey(mpage, n->string, m);
 	}
@@ -1590,6 +1505,8 @@ parse_mdoc(struct mpage *mpage, const struct roff_meta *meta,
 
 	assert(NULL != n);
 	for (n = n->child; NULL != n; n = n->next) {
+		if (n->flags & mdocs[n->tok].taboo)
+			continue;
 		switch (n->type) {
 		case ROFFT_ELEM:
 		case ROFFT_BLOCK:
@@ -1601,7 +1518,7 @@ parse_mdoc(struct mpage *mpage, const struct roff_meta *meta,
 				       break;
 			if (mdocs[n->tok].mask)
 				putmdockey(mpage, n->child,
-				    mdocs[n->tok].mask);
+				    mdocs[n->tok].mask, mdocs[n->tok].taboo);
 			break;
 		default:
 			assert(n->type != ROFFT_ROOT);
@@ -1769,17 +1686,17 @@ parse_mdoc_Nm(struct mpage *mpage, const struct roff_meta *meta,
 {
 
 	if (SEC_NAME == n->sec)
-		putmdockey(mpage, n->child, NAME_TITLE);
+		putmdockey(mpage, n->child, NAME_TITLE, 0);
 	else if (n->sec == SEC_SYNOPSIS && n->type == ROFFT_HEAD) {
 		if (n->child == NULL)
 			putkey(mpage, meta->name, NAME_SYN);
 		else
-			putmdockey(mpage, n->child, NAME_SYN);
+			putmdockey(mpage, n->child, NAME_SYN, 0);
 	}
 	if ( ! (mpage->name_head_done ||
 	    n->child == NULL || n->child->string == NULL ||
 	    strcasecmp(n->child->string, meta->title))) {
-		putkey(mpage, n->child->string, ROFFT_HEAD);
+		putkey(mpage, n->child->string, NAME_HEAD);
 		mpage->name_head_done = 1;
 	}
 	return 0;
@@ -1827,15 +1744,16 @@ putkeys(const struct mpage *mpage, char *cp, size_t sz, uint64_t v)
 			name_mask &= ~NAME_FIRST;
 		if (debug > 1)
 			say(mpage->mlinks->file,
-			    "Adding name %*s, bits=%d", sz, cp, v);
+			    "Adding name %*s, bits=0x%llx", (int)sz, cp,
+			    (unsigned long long)v);
 	} else {
 		htab = &strings;
 		if (debug > 1)
-		    for (i = 0; i < mansearch_keymax; i++)
+		    for (i = 0; i < KEY_MAX; i++)
 			if ((uint64_t)1 << i & v)
 			    say(mpage->mlinks->file,
 				"Adding key %s=%*s",
-				mansearch_keynames[i], sz, cp);
+				mansearch_keynames[i], (int)sz, cp);
 	}
 
 	end = cp + sz;
@@ -2037,53 +1955,24 @@ render_string(char **public, size_t *psz)
 static void
 dbadd_mlink(const struct mlink *mlink)
 {
-	size_t		 i;
-
-	i = 1;
-	SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->dsec);
-	SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->arch);
-	SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->name);
-	SQL_BIND_INT64(stmts[STMT_INSERT_LINK], i, mlink->mpage->pageid);
-	SQL_STEP(stmts[STMT_INSERT_LINK]);
-	sqlite3_reset(stmts[STMT_INSERT_LINK]);
-}
-
-static void
-dbadd_mlink_name(const struct mlink *mlink)
-{
-	uint64_t	 bits;
-	size_t		 i;
-
-	dbadd_mlink(mlink);
-
-	i = 1;
-	SQL_BIND_INT64(stmts[STMT_SELECT_NAME], i, mlink->mpage->pageid);
-	bits = NAME_FILE & NAME_MASK;
-	if (sqlite3_step(stmts[STMT_SELECT_NAME]) == SQLITE_ROW) {
-		bits |= sqlite3_column_int64(stmts[STMT_SELECT_NAME], 0);
-		sqlite3_reset(stmts[STMT_SELECT_NAME]);
-	}
-
-	i = 1;
-	SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, bits);
-	SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, mlink->name);
-	SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, mlink->mpage->pageid);
-	SQL_STEP(stmts[STMT_INSERT_NAME]);
-	sqlite3_reset(stmts[STMT_INSERT_NAME]);
+	dba_page_alias(mlink->mpage->dba, mlink->name, NAME_FILE);
+	dba_page_add(mlink->mpage->dba, DBP_SECT, mlink->dsec);
+	dba_page_add(mlink->mpage->dba, DBP_SECT, mlink->fsec);
+	dba_page_add(mlink->mpage->dba, DBP_ARCH, mlink->arch);
+	dba_page_add(mlink->mpage->dba, DBP_FILE, mlink->file);
 }
 
 /*
  * Flush the current page's terms (and their bits) into the database.
- * Wrap the entire set of additions in a transaction to make sqlite be a
- * little faster.
  * Also, handle escape sequences at the last possible moment.
  */
 static void
-dbadd(struct mpage *mpage)
+dbadd(struct dba *dba, struct mpage *mpage)
 {
 	struct mlink	*mlink;
 	struct str	*key;
 	char		*cp;
+	uint64_t	 mask;
 	size_t		 i;
 	unsigned int	 slot;
 	int		 mustfree;
@@ -2128,127 +2017,106 @@ dbadd(struct mpage *mpage)
 	cp = mpage->desc;
 	i = strlen(cp);
 	mustfree = render_string(&cp, &i);
-	i = 1;
-	SQL_BIND_TEXT(stmts[STMT_INSERT_PAGE], i, cp);
-	SQL_BIND_INT(stmts[STMT_INSERT_PAGE], i, mpage->form);
-	SQL_STEP(stmts[STMT_INSERT_PAGE]);
-	mpage->pageid = sqlite3_last_insert_rowid(db);
-	sqlite3_reset(stmts[STMT_INSERT_PAGE]);
+	mpage->dba = dba_page_new(dba->pages,
+	    *mpage->arch == '\0' ? mlink->arch : mpage->arch,
+	    cp, mlink->file, mpage->form);
 	if (mustfree)
 		free(cp);
+	dba_page_add(mpage->dba, DBP_SECT, mpage->sec);
 
-	while (NULL != mlink) {
+	while (mlink != NULL) {
 		dbadd_mlink(mlink);
 		mlink = mlink->next;
 	}
-	mlink = mpage->mlinks;
 
 	for (key = ohash_first(&names, &slot); NULL != key;
 	     key = ohash_next(&names, &slot)) {
 		assert(key->mpage == mpage);
-		i = 1;
-		SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, key->mask);
-		SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, key->key);
-		SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, mpage->pageid);
-		SQL_STEP(stmts[STMT_INSERT_NAME]);
-		sqlite3_reset(stmts[STMT_INSERT_NAME]);
+		dba_page_alias(mpage->dba, key->key, key->mask);
 		free(key);
 	}
 	for (key = ohash_first(&strings, &slot); NULL != key;
 	     key = ohash_next(&strings, &slot)) {
 		assert(key->mpage == mpage);
-		i = 1;
-		SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, key->mask);
-		SQL_BIND_TEXT(stmts[STMT_INSERT_KEY], i, key->key);
-		SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, mpage->pageid);
-		SQL_STEP(stmts[STMT_INSERT_KEY]);
-		sqlite3_reset(stmts[STMT_INSERT_KEY]);
+		i = 0;
+		for (mask = TYPE_Xr; mask <= TYPE_Lb; mask *= 2) {
+			if (key->mask & mask)
+				dba_macro_add(dba->macros, i,
+				    key->key, mpage->dba);
+			i++;
+		}
 		free(key);
 	}
 }
 
 static void
-dbprune(void)
+dbprune(struct dba *dba)
 {
-	struct mpage	*mpage;
-	struct mlink	*mlink;
-	size_t		 i;
-	unsigned int	 slot;
+	struct dba_array	*page, *files;
+	char			*file;
 
-	if (0 == nodb)
-		SQL_EXEC("BEGIN TRANSACTION");
-
-	for (mpage = ohash_first(&mpages, &slot); NULL != mpage;
-	     mpage = ohash_next(&mpages, &slot)) {
-		mlink = mpage->mlinks;
-		if (debug)
-			say(mlink->file, "Deleting from database");
-		if (nodb)
-			continue;
-		for ( ; NULL != mlink; mlink = mlink->next) {
-			i = 1;
-			SQL_BIND_TEXT(stmts[STMT_DELETE_PAGE],
-			    i, mlink->dsec);
-			SQL_BIND_TEXT(stmts[STMT_DELETE_PAGE],
-			    i, mlink->arch);
-			SQL_BIND_TEXT(stmts[STMT_DELETE_PAGE],
-			    i, mlink->name);
-			SQL_STEP(stmts[STMT_DELETE_PAGE]);
-			sqlite3_reset(stmts[STMT_DELETE_PAGE]);
+	dba_array_FOREACH(dba->pages, page) {
+		files = dba_array_get(page, DBP_FILE);
+		dba_array_FOREACH(files, file) {
+			if (*file < ' ')
+				file++;
+			if (ohash_find(&mlinks, ohash_qlookup(&mlinks,
+			    file)) != NULL) {
+				if (debug)
+					say(file, "Deleting from database");
+				dba_array_del(dba->pages);
+				break;
+			}
 		}
 	}
-
-	if (0 == nodb)
-		SQL_EXEC("END TRANSACTION");
 }
 
 /*
- * Close an existing database and its prepared statements.
- * If "real" is not set, rename the temporary file into the real one.
+ * Write the database from memory to disk.
  */
 static void
-dbclose(int real)
+dbwrite(struct dba *dba)
 {
-	size_t		 i;
+	char		 tfn[32];
 	int		 status;
 	pid_t		 child;
 
-	if (nodb)
-		return;
-
-	for (i = 0; i < STMT__MAX; i++) {
-		sqlite3_finalize(stmts[i]);
-		stmts[i] = NULL;
-	}
-
-	sqlite3_close(db);
-	db = NULL;
-
-	if (real)
-		return;
-
-	if ('\0' == *tempfilename) {
-		if (-1 == rename(MANDOC_DB "~", MANDOC_DB)) {
+	if (dba_write(MANDOC_DB "~", dba) != -1) {
+		if (rename(MANDOC_DB "~", MANDOC_DB) == -1) {
 			exitcode = (int)MANDOCLEVEL_SYSERR;
 			say(MANDOC_DB, "&rename");
+			unlink(MANDOC_DB "~");
 		}
 		return;
 	}
 
+	(void)strlcpy(tfn, "/tmp/mandocdb.XXXXXXXX", sizeof(tfn));
+	if (mkdtemp(tfn) == NULL) {
+		exitcode = (int)MANDOCLEVEL_SYSERR;
+		say("", "&%s", tfn);
+		return;
+	}
+
+	(void)strlcat(tfn, "/" MANDOC_DB, sizeof(tfn));
+	if (dba_write(tfn, dba) == -1) {
+		exitcode = (int)MANDOCLEVEL_SYSERR;
+		say(tfn, "&dba_write");
+		goto out;
+	}
+
 	switch (child = fork()) {
 	case -1:
 		exitcode = (int)MANDOCLEVEL_SYSERR;
 		say("", "&fork cmp");
 		return;
 	case 0:
-		execlp("cmp", "cmp", "-s",
-		    tempfilename, MANDOC_DB, (char *)NULL);
+		execlp("cmp", "cmp", "-s", tfn, MANDOC_DB, (char *)NULL);
 		say("", "&exec cmp");
 		exit(0);
 	default:
 		break;
 	}
-	if (-1 == waitpid(child, &status, 0)) {
+	if (waitpid(child, &status, 0) == -1) {
 		exitcode = (int)MANDOCLEVEL_SYSERR;
 		say("", "&wait cmp");
 	} else if (WIFSIGNALED(status)) {
@@ -2260,175 +2128,29 @@ dbclose(int real)
 		    "Data changed, but cannot replace database");
 	}
 
-	*strrchr(tempfilename, '/') = '\0';
+out:
+	*strrchr(tfn, '/') = '\0';
 	switch (child = fork()) {
 	case -1:
 		exitcode = (int)MANDOCLEVEL_SYSERR;
 		say("", "&fork rm");
 		return;
 	case 0:
-		execlp("rm", "rm", "-rf", tempfilename, (char *)NULL);
+		execlp("rm", "rm", "-rf", tfn, (char *)NULL);
 		say("", "&exec rm");
 		exit((int)MANDOCLEVEL_SYSERR);
 	default:
 		break;
 	}
-	if (-1 == waitpid(child, &status, 0)) {
+	if (waitpid(child, &status, 0) == -1) {
 		exitcode = (int)MANDOCLEVEL_SYSERR;
 		say("", "&wait rm");
 	} else if (WIFSIGNALED(status) || WEXITSTATUS(status)) {
 		exitcode = (int)MANDOCLEVEL_SYSERR;
-		say("", "%s: Cannot remove temporary directory",
-		    tempfilename);
+		say("", "%s: Cannot remove temporary directory", tfn);
 	}
 }
 
-/*
- * This is straightforward stuff.
- * Open a database connection to a "temporary" database, then open a set
- * of prepared statements we'll use over and over again.
- * If "real" is set, we use the existing database; if not, we truncate a
- * temporary one.
- * Must be matched by dbclose().
- */
-static int
-dbopen(int real)
-{
-	const char	*sql;
-	int		 rc, ofl;
-
-	if (nodb)
-		return 1;
-
-	*tempfilename = '\0';
-	ofl = SQLITE_OPEN_READWRITE;
-
-	if (real) {
-		rc = sqlite3_open_v2(MANDOC_DB, &db, ofl, NULL);
-		if (SQLITE_OK != rc) {
-			exitcode = (int)MANDOCLEVEL_SYSERR;
-			if (SQLITE_CANTOPEN != rc)
-				say(MANDOC_DB, "%s", sqlite3_errstr(rc));
-			return 0;
-		}
-		goto prepare_statements;
-	}
-
-	ofl |= SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE;
-
-	remove(MANDOC_DB "~");
-	rc = sqlite3_open_v2(MANDOC_DB "~", &db, ofl, NULL);
-	if (SQLITE_OK == rc)
-		goto create_tables;
-	if (MPARSE_QUICK & mparse_options) {
-		exitcode = (int)MANDOCLEVEL_SYSERR;
-		say(MANDOC_DB "~", "%s", sqlite3_errstr(rc));
-		return 0;
-	}
-
-	(void)strlcpy(tempfilename, "/tmp/mandocdb.XXXXXX",
-	    sizeof(tempfilename));
-	if (NULL == mkdtemp(tempfilename)) {
-		exitcode = (int)MANDOCLEVEL_SYSERR;
-		say("", "&%s", tempfilename);
-		return 0;
-	}
-	(void)strlcat(tempfilename, "/" MANDOC_DB,
-	    sizeof(tempfilename));
-	rc = sqlite3_open_v2(tempfilename, &db, ofl, NULL);
-	if (SQLITE_OK != rc) {
-		exitcode = (int)MANDOCLEVEL_SYSERR;
-		say("", "%s: %s", tempfilename, sqlite3_errstr(rc));
-		return 0;
-	}
-
-create_tables:
-	sql = "CREATE TABLE \"mpages\" (\n"
-	      " \"desc\" TEXT NOT NULL,\n"
-	      " \"form\" INTEGER NOT NULL,\n"
-	      " \"pageid\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL\n"
-	      ");\n"
-	      "\n"
-	      "CREATE TABLE \"mlinks\" (\n"
-	      " \"sec\" TEXT NOT NULL,\n"
-	      " \"arch\" TEXT NOT NULL,\n"
-	      " \"name\" TEXT NOT NULL,\n"
-	      " \"pageid\" INTEGER NOT NULL REFERENCES mpages(pageid) "
-		"ON DELETE CASCADE\n"
-	      ");\n"
-	      "CREATE INDEX mlinks_pageid_idx ON mlinks (pageid);\n"
-	      "\n"
-	      "CREATE TABLE \"names\" (\n"
-	      " \"bits\" INTEGER NOT NULL,\n"
-	      " \"name\" TEXT NOT NULL,\n"
-	      " \"pageid\" INTEGER NOT NULL REFERENCES mpages(pageid) "
-		"ON DELETE CASCADE,\n"
-	      " UNIQUE (\"name\", \"pageid\") ON CONFLICT REPLACE\n"
-	      ");\n"
-	      "\n"
-	      "CREATE TABLE \"keys\" (\n"
-	      " \"bits\" INTEGER NOT NULL,\n"
-	      " \"key\" TEXT NOT NULL,\n"
-	      " \"pageid\" INTEGER NOT NULL REFERENCES mpages(pageid) "
-		"ON DELETE CASCADE\n"
-	      ");\n"
-	      "CREATE INDEX keys_pageid_idx ON keys (pageid);\n";
-
-	if (SQLITE_OK != sqlite3_exec(db, sql, NULL, NULL, NULL)) {
-		exitcode = (int)MANDOCLEVEL_SYSERR;
-		say(MANDOC_DB, "%s", sqlite3_errmsg(db));
-		sqlite3_close(db);
-		return 0;
-	}
-
-prepare_statements:
-	if (SQLITE_OK != sqlite3_exec(db,
-	    "PRAGMA foreign_keys = ON", NULL, NULL, NULL)) {
-		exitcode = (int)MANDOCLEVEL_SYSERR;
-		say(MANDOC_DB, "PRAGMA foreign_keys: %s",
-		    sqlite3_errmsg(db));
-		sqlite3_close(db);
-		return 0;
-	}
-
-	sql = "DELETE FROM mpages WHERE pageid IN "
-		"(SELECT pageid FROM mlinks WHERE "
-		"sec=? AND arch=? AND name=?)";
-	sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_DELETE_PAGE], NULL);
-	sql = "INSERT INTO mpages "
-		"(desc,form) VALUES (?,?)";
-	sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_PAGE], NULL);
-	sql = "INSERT INTO mlinks "
-		"(sec,arch,name,pageid) VALUES (?,?,?,?)";
-	sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_LINK], NULL);
-	sql = "SELECT bits FROM names where pageid = ?";
-	sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_SELECT_NAME], NULL);
-	sql = "INSERT INTO names "
-		"(bits,name,pageid) VALUES (?,?,?)";
-	sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_NAME], NULL);
-	sql = "INSERT INTO keys "
-		"(bits,key,pageid) VALUES (?,?,?)";
-	sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_KEY], NULL);
-
-#ifndef __APPLE__
-	/*
-	 * When opening a new database, we can turn off
-	 * synchronous mode for much better performance.
-	 */
-
-	if (real && SQLITE_OK != sqlite3_exec(db,
-	    "PRAGMA synchronous = OFF", NULL, NULL, NULL)) {
-		exitcode = (int)MANDOCLEVEL_SYSERR;
-		say(MANDOC_DB, "PRAGMA synchronous: %s",
-		    sqlite3_errmsg(db));
-		sqlite3_close(db);
-		return 0;
-	}
-#endif
-
-	return 1;
-}
-
 static int
 set_basedir(const char *targetdir, int report_baddir)
 {
diff --git a/contrib/mdocml/manpath.c b/contrib/mdocml/manpath.c
index 83c329ec9bb..008c5939237 100644
--- a/contrib/mdocml/manpath.c
+++ b/contrib/mdocml/manpath.c
@@ -1,4 +1,4 @@
-/*	$Id: manpath.c,v 1.30 2016/05/28 13:44:13 schwarze Exp $	*/
+/*	$Id: manpath.c,v 1.31 2016/07/19 22:40:33 schwarze Exp $	*/
 /*
  * Copyright (c) 2011, 2014, 2015 Ingo Schwarze 
  * Copyright (c) 2011 Kristaps Dzonsons 
@@ -32,9 +32,7 @@
 #include "mandoc_aux.h"
 #include "manconf.h"
 
-#if !HAVE_MANPATH
 static	void	 manconf_file(struct manconf *, const char *);
-#endif
 static	void	 manpath_add(struct manpaths *, const char *, int);
 static	void	 manpath_parseline(struct manpaths *, char *, int);
 
@@ -43,52 +41,6 @@ void
 manconf_parse(struct manconf *conf, const char *file,
 		char *defp, char *auxp)
 {
-#if HAVE_MANPATH
-	char		 cmd[(PATH_MAX * 3) + 20];
-	FILE		*stream;
-	char		*buf;
-	size_t		 sz, bsz;
-
-	strlcpy(cmd, "manpath", sizeof(cmd));
-	if (file) {
-		strlcat(cmd, " -C ", sizeof(cmd));
-		strlcat(cmd, file, sizeof(cmd));
-	}
-	if (auxp) {
-		strlcat(cmd, " -m ", sizeof(cmd));
-		strlcat(cmd, auxp, sizeof(cmd));
-	}
-	if (defp) {
-		strlcat(cmd, " -M ", sizeof(cmd));
-		strlcat(cmd, defp, sizeof(cmd));
-	}
-
-	/* Open manpath(1).  Ignore errors. */
-
-	stream = popen(cmd, "r");
-	if (NULL == stream)
-		return;
-
-	buf = NULL;
-	bsz = 0;
-
-	/* Read in as much output as we can. */
-
-	do {
-		buf = mandoc_realloc(buf, bsz + 1024);
-		sz = fread(buf + bsz, 1, 1024, stream);
-		bsz += sz;
-	} while (sz > 0);
-
-	if ( ! ferror(stream) && feof(stream) &&
-			bsz && '\n' == buf[bsz - 1]) {
-		buf[bsz - 1] = '\0';
-		manpath_parseline(&conf->manpath, buf, 1);
-	}
-
-	free(buf);
-	pclose(stream);
-#else
 	char		*insert;
 
 	/* Always prepend -m. */
@@ -137,7 +89,6 @@ manconf_parse(struct manconf *conf, const char *file,
 
 	/* MANPATH overrides man.conf(5) completely. */
 	manpath_parseline(&conf->manpath, defp, 0);
-#endif
 }
 
 /*
@@ -204,7 +155,6 @@ manconf_free(struct manconf *conf)
 	free(conf->output.style);
 }
 
-#if !HAVE_MANPATH
 static void
 manconf_file(struct manconf *conf, const char *file)
 {
@@ -270,7 +220,6 @@ out:
 	if (*manpath_default != '\0')
 		manpath_parseline(&conf->manpath, manpath_default, 0);
 }
-#endif
 
 void
 manconf_output(struct manoutput *conf, const char *cp)
diff --git a/contrib/mdocml/mansearch.c b/contrib/mdocml/mansearch.c
index 1ab879d7f21..6e689bd3586 100644
--- a/contrib/mdocml/mansearch.c
+++ b/contrib/mdocml/mansearch.c
@@ -1,7 +1,7 @@
-/*	$Id: mansearch.c,v 1.65 2016/07/09 15:24:19 schwarze Exp $ */
+/*	$OpenBSD: mansearch.c,v 1.50 2016/07/09 15:23:36 schwarze Exp $ */
 /*
  * Copyright (c) 2012 Kristaps Dzonsons 
- * Copyright (c) 2013, 2014, 2015 Ingo Schwarze 
+ * Copyright (c) 2013, 2014, 2015, 2016 Ingo Schwarze 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -36,143 +36,69 @@
 #include 
 #include 
 
-#include 
-#ifndef SQLITE_DETERMINISTIC
-#define SQLITE_DETERMINISTIC 0
-#endif
-
 #include "mandoc.h"
 #include "mandoc_aux.h"
 #include "mandoc_ohash.h"
 #include "manconf.h"
 #include "mansearch.h"
-
-extern int mansearch_keymax;
-extern const char *const mansearch_keynames[];
-
-#define	SQL_BIND_TEXT(_db, _s, _i, _v) \
-	do { if (SQLITE_OK != sqlite3_bind_text \
-		((_s), (_i)++, (_v), -1, SQLITE_STATIC)) \
-		errx((int)MANDOCLEVEL_SYSERR, "%s", sqlite3_errmsg((_db))); \
-	} while (0)
-#define	SQL_BIND_INT64(_db, _s, _i, _v) \
-	do { if (SQLITE_OK != sqlite3_bind_int64 \
-		((_s), (_i)++, (_v))) \
-		errx((int)MANDOCLEVEL_SYSERR, "%s", sqlite3_errmsg((_db))); \
-	} while (0)
-#define	SQL_BIND_BLOB(_db, _s, _i, _v) \
-	do { if (SQLITE_OK != sqlite3_bind_blob \
-		((_s), (_i)++, (&_v), sizeof(_v), SQLITE_STATIC)) \
-		errx((int)MANDOCLEVEL_SYSERR, "%s", sqlite3_errmsg((_db))); \
-	} while (0)
+#include "dbm.h"
 
 struct	expr {
-	regex_t		 regexp;  /* compiled regexp, if applicable */
-	const char	*substr;  /* to search for, if applicable */
-	struct expr	*next;    /* next in sequence */
-	uint64_t	 bits;    /* type-mask */
-	int		 equal;   /* equality, not subsring match */
-	int		 open;    /* opening parentheses before */
-	int		 and;	  /* logical AND before */
-	int		 close;   /* closing parentheses after */
+	/* Used for terms: */
+	struct dbm_match match;   /* Match type and expression. */
+	uint64_t	 bits;    /* Type mask. */
+	/* Used for OR and AND groups: */
+	struct expr	*next;    /* Next child in the parent group. */
+	struct expr	*child;   /* First child in this group. */
+	enum { EXPR_TERM, EXPR_OR, EXPR_AND } type;
 };
 
-struct	match {
-	uint64_t	 pageid; /* identifier in database */
-	uint64_t	 bits; /* name type mask */
-	char		*desc; /* manual page description */
-	int		 form; /* bit field: formatted, zipped? */
+const char *const mansearch_keynames[KEY_MAX] = {
+	"arch",	"sec",	"Xr",	"Ar",	"Fa",	"Fl",	"Dv",	"Fn",
+	"Ic",	"Pa",	"Cm",	"Li",	"Em",	"Cd",	"Va",	"Ft",
+	"Tn",	"Er",	"Ev",	"Sy",	"Sh",	"In",	"Ss",	"Ox",
+	"An",	"Mt",	"St",	"Bx",	"At",	"Nx",	"Fx",	"Lk",
+	"Ms",	"Bsx",	"Dx",	"Rs",	"Vt",	"Lb",	"Nm",	"Nd"
 };
 
-static	void		 buildnames(const struct mansearch *,
-				struct manpage *, sqlite3 *,
-				sqlite3_stmt *, uint64_t,
-				const char *, int form);
-static	char		*buildoutput(sqlite3 *, sqlite3_stmt *,
-				 uint64_t, uint64_t);
+
+static	struct ohash	*manmerge(struct expr *, struct ohash *);
+static	struct ohash	*manmerge_term(struct expr *, struct ohash *);
+static	struct ohash	*manmerge_or(struct expr *, struct ohash *);
+static	struct ohash	*manmerge_and(struct expr *, struct ohash *);
+static	char		*buildnames(const struct dbm_page *);
+static	char		*buildoutput(size_t, int32_t);
+static	size_t		 lstlen(const char *);
+static	void		 lstcat(char *, size_t *, const char *);
+static	int		 lstmatch(const char *, const char *);
 static	struct expr	*exprcomp(const struct mansearch *,
-				int, char *[]);
+				int, char *[], int *);
+static	struct expr	*expr_and(const struct mansearch *,
+				int, char *[], int *);
+static	struct expr	*exprterm(const struct mansearch *,
+				int, char *[], int *);
 static	void		 exprfree(struct expr *);
-static	struct expr	*exprterm(const struct mansearch *, char *, int);
 static	int		 manpage_compare(const void *, const void *);
-static	void		 sql_append(char **sql, size_t *sz,
-				const char *newstr, int count);
-static	void		 sql_match(sqlite3_context *context,
-				int argc, sqlite3_value **argv);
-static	void		 sql_regexp(sqlite3_context *context,
-				int argc, sqlite3_value **argv);
-static	char		*sql_statement(const struct expr *);
 
 
-int
-mansearch_setup(int start)
-{
-	static void	*pagecache;
-	int		 c;
-
-#define	PC_PAGESIZE	1280
-#define	PC_NUMPAGES	256
-
-	if (start) {
-		if (NULL != pagecache) {
-			warnx("pagecache already enabled");
-			return (int)MANDOCLEVEL_BADARG;
-		}
-
-		pagecache = mmap(NULL, PC_PAGESIZE * PC_NUMPAGES,
-		    PROT_READ | PROT_WRITE,
-		    MAP_SHARED | MAP_ANON, -1, 0);
-
-		if (MAP_FAILED == pagecache) {
-			warn("mmap");
-			pagecache = NULL;
-			return (int)MANDOCLEVEL_SYSERR;
-		}
-
-		c = sqlite3_config(SQLITE_CONFIG_PAGECACHE,
-		    pagecache, PC_PAGESIZE, PC_NUMPAGES);
-
-		if (SQLITE_OK == c)
-			return (int)MANDOCLEVEL_OK;
-
-		warnx("pagecache: %s", sqlite3_errstr(c));
-
-	} else if (NULL == pagecache) {
-		warnx("pagecache missing");
-		return (int)MANDOCLEVEL_BADARG;
-	}
-
-	if (-1 == munmap(pagecache, PC_PAGESIZE * PC_NUMPAGES)) {
-		warn("munmap");
-		pagecache = NULL;
-		return (int)MANDOCLEVEL_SYSERR;
-	}
-
-	pagecache = NULL;
-	return (int)MANDOCLEVEL_OK;
-}
-
 int
 mansearch(const struct mansearch *search,
 		const struct manpaths *paths,
 		int argc, char *argv[],
 		struct manpage **res, size_t *sz)
 {
-	int64_t		 pageid;
-	uint64_t	 outbit, iterbit;
 	char		 buf[PATH_MAX];
-	char		*sql;
+	struct dbm_res	*rp;
+	struct expr	*e;
+	struct dbm_page	*page;
 	struct manpage	*mpage;
-	struct expr	*e, *ep;
-	sqlite3		*db;
-	sqlite3_stmt	*s, *s2;
-	struct match	*mp;
-	struct ohash	 htab;
-	unsigned int	 idx;
-	size_t		 i, j, cur, maxres;
-	int		 c, chdir_status, getcwd_status, indexbit;
+	struct ohash	*htab;
+	size_t		 cur, i, maxres, outkey;
+	unsigned int	 slot;
+	int		 argi, chdir_status, getcwd_status, im;
 
-	if (argc == 0 || (e = exprcomp(search, argc, argv)) == NULL) {
+	argi = 0;
+	if ((e = exprcomp(search, argc, argv, &argi)) == NULL) {
 		*sz = 0;
 		return 0;
 	}
@@ -180,19 +106,14 @@ mansearch(const struct mansearch *search,
 	cur = maxres = 0;
 	*res = NULL;
 
-	if (NULL != search->outkey) {
-		outbit = TYPE_Nd;
-		for (indexbit = 0, iterbit = 1;
-		     indexbit < mansearch_keymax;
-		     indexbit++, iterbit <<= 1) {
+	outkey = KEY_Nd;
+	if (search->outkey != NULL)
+		for (im = 0; im < KEY_MAX; im++)
 			if (0 == strcasecmp(search->outkey,
-			    mansearch_keynames[indexbit])) {
-				outbit = iterbit;
+			    mansearch_keynames[im])) {
+				outkey = im;
 				break;
 			}
-		}
-	} else
-		outbit = 0;
 
 	/*
 	 * Remember the original working directory, if possible.
@@ -208,8 +129,6 @@ mansearch(const struct mansearch *search,
 	} else
 		getcwd_status = 1;
 
-	sql = sql_statement(e);
-
 	/*
 	 * Loop over the directories (containing databases) for us to
 	 * search.
@@ -235,123 +154,48 @@ mansearch(const struct mansearch *search,
 		}
 		chdir_status = 1;
 
-		c = sqlite3_open_v2(MANDOC_DB, &db,
-		    SQLITE_OPEN_READONLY, NULL);
-
-		if (SQLITE_OK != c) {
+		if (dbm_open(MANDOC_DB) == -1) {
 			warn("%s/%s", paths->paths[i], MANDOC_DB);
-			sqlite3_close(db);
 			continue;
 		}
 
-		/*
-		 * Define the SQL functions for substring
-		 * and regular expression matching.
-		 */
-
-		c = sqlite3_create_function(db, "match", 2,
-		    SQLITE_UTF8 | SQLITE_DETERMINISTIC,
-		    NULL, sql_match, NULL, NULL);
-		assert(SQLITE_OK == c);
-		c = sqlite3_create_function(db, "regexp", 2,
-		    SQLITE_UTF8 | SQLITE_DETERMINISTIC,
-		    NULL, sql_regexp, NULL, NULL);
-		assert(SQLITE_OK == c);
-
-		j = 1;
-		c = sqlite3_prepare_v2(db, sql, -1, &s, NULL);
-		if (SQLITE_OK != c)
-			errx((int)MANDOCLEVEL_SYSERR,
-			    "%s", sqlite3_errmsg(db));
-
-		for (ep = e; NULL != ep; ep = ep->next) {
-			if (NULL == ep->substr) {
-				SQL_BIND_BLOB(db, s, j, ep->regexp);
-			} else
-				SQL_BIND_TEXT(db, s, j, ep->substr);
-			if (0 == ((TYPE_Nd | TYPE_Nm) & ep->bits))
-				SQL_BIND_INT64(db, s, j, ep->bits);
+		if ((htab = manmerge(e, NULL)) == NULL) {
+			dbm_close();
+			continue;
 		}
 
-		mandoc_ohash_init(&htab, 4, offsetof(struct match, pageid));
+		for (rp = ohash_first(htab, &slot); rp != NULL;
+		    rp = ohash_next(htab, &slot)) {
+			page = dbm_page_get(rp->page);
 
-		/*
-		 * Hash each entry on its [unique] document identifier.
-		 * This is a uint64_t.
-		 * Instead of using a hash function, simply convert the
-		 * uint64_t to a uint32_t, the hash value's type.
-		 * This gives good performance and preserves the
-		 * distribution of buckets in the table.
-		 */
-		while (SQLITE_ROW == (c = sqlite3_step(s))) {
-			pageid = sqlite3_column_int64(s, 2);
-			idx = ohash_lookup_memory(&htab,
-			    (char *)&pageid, sizeof(uint64_t),
-			    (uint32_t)pageid);
-
-			if (NULL != ohash_find(&htab, idx))
+			if (lstmatch(search->sec, page->sect) == 0 ||
+			    lstmatch(search->arch, page->arch) == 0)
 				continue;
 
-			mp = mandoc_calloc(1, sizeof(struct match));
-			mp->pageid = pageid;
-			mp->form = sqlite3_column_int(s, 1);
-			mp->bits = sqlite3_column_int64(s, 3);
-			if (TYPE_Nd == outbit)
-				mp->desc = mandoc_strdup((const char *)
-				    sqlite3_column_text(s, 0));
-			ohash_insert(&htab, idx, mp);
-		}
-
-		if (SQLITE_DONE != c)
-			warnx("%s", sqlite3_errmsg(db));
-
-		sqlite3_finalize(s);
-
-		c = sqlite3_prepare_v2(db,
-		    "SELECT sec, arch, name, pageid FROM mlinks "
-		    "WHERE pageid=? ORDER BY sec, arch, name",
-		    -1, &s, NULL);
-		if (SQLITE_OK != c)
-			errx((int)MANDOCLEVEL_SYSERR,
-			    "%s", sqlite3_errmsg(db));
-
-		c = sqlite3_prepare_v2(db,
-		    "SELECT bits, key, pageid FROM keys "
-		    "WHERE pageid=? AND bits & ?",
-		    -1, &s2, NULL);
-		if (SQLITE_OK != c)
-			errx((int)MANDOCLEVEL_SYSERR,
-			    "%s", sqlite3_errmsg(db));
-
-		for (mp = ohash_first(&htab, &idx);
-				NULL != mp;
-				mp = ohash_next(&htab, &idx)) {
 			if (cur + 1 > maxres) {
 				maxres += 1024;
 				*res = mandoc_reallocarray(*res,
-				    maxres, sizeof(struct manpage));
+				    maxres, sizeof(**res));
 			}
 			mpage = *res + cur;
+			mandoc_asprintf(&mpage->file, "%s/%s",
+			    paths->paths[i], page->file + 1);
+			mpage->names = buildnames(page);
+			mpage->output = (int)outkey == KEY_Nd ?
+			    mandoc_strdup(page->desc) :
+			    buildoutput(outkey, page->addr);
 			mpage->ipath = i;
-			mpage->bits = mp->bits;
-			mpage->sec = 10;
-			mpage->form = mp->form;
-			buildnames(search, mpage, db, s, mp->pageid,
-			    paths->paths[i], mp->form);
-			if (mpage->names != NULL) {
-				mpage->output = TYPE_Nd & outbit ?
-				    mp->desc : outbit ?
-				    buildoutput(db, s2, mp->pageid, outbit) :
-				    NULL;
-				cur++;
-			}
-			free(mp);
+			mpage->bits = rp->bits;
+			mpage->sec = *page->sect - '0';
+			if (mpage->sec < 0 || mpage->sec > 9)
+				mpage->sec = 10;
+			mpage->form = *page->file;
+			free(rp);
+			cur++;
 		}
-
-		sqlite3_finalize(s);
-		sqlite3_finalize(s2);
-		sqlite3_close(db);
-		ohash_delete(&htab);
+		ohash_delete(htab);
+		free(htab);
+		dbm_close();
 
 		/*
 		 * In man(1) mode, prefer matches in earlier trees
@@ -365,11 +209,169 @@ mansearch(const struct mansearch *search,
 	if (chdir_status && getcwd_status && chdir(buf) == -1)
 		warn("%s", buf);
 	exprfree(e);
-	free(sql);
 	*sz = cur;
 	return 1;
 }
 
+/*
+ * Merge the results for the expression tree rooted at e
+ * into the the result list htab.
+ */
+static struct ohash *
+manmerge(struct expr *e, struct ohash *htab)
+{
+	switch (e->type) {
+	case EXPR_TERM:
+		return manmerge_term(e, htab);
+	case EXPR_OR:
+		return manmerge_or(e->child, htab);
+	case EXPR_AND:
+		return manmerge_and(e->child, htab);
+	default:
+		abort();
+	}
+}
+
+static struct ohash *
+manmerge_term(struct expr *e, struct ohash *htab)
+{
+	struct dbm_res	 res, *rp;
+	uint64_t	 ib;
+	unsigned int	 slot;
+	int		 im;
+
+	if (htab == NULL) {
+		htab = mandoc_malloc(sizeof(*htab));
+		mandoc_ohash_init(htab, 4, offsetof(struct dbm_res, page));
+	}
+
+	for (im = 0, ib = 1; im < KEY_MAX; im++, ib <<= 1) {
+		if ((e->bits & ib) == 0)
+			continue;
+
+		switch (ib) {
+		case TYPE_arch:
+			dbm_page_byarch(&e->match);
+			break;
+		case TYPE_sec:
+			dbm_page_bysect(&e->match);
+			break;
+		case TYPE_Nm:
+			dbm_page_byname(&e->match);
+			break;
+		case TYPE_Nd:
+			dbm_page_bydesc(&e->match);
+			break;
+		default:
+			dbm_page_bymacro(im - 2, &e->match);
+			break;
+		}
+
+		/*
+		 * When hashing for deduplication, use the unique
+		 * page ID itself instead of a hash function;
+		 * that is quite efficient.
+		 */
+
+		for (;;) {
+			res = dbm_page_next();
+			if (res.page == -1)
+				break;
+			slot = ohash_lookup_memory(htab,
+			    (char *)&res, sizeof(res.page), res.page);
+			if ((rp = ohash_find(htab, slot)) != NULL) {
+				rp->bits |= res.bits;
+				continue;
+			}
+			rp = mandoc_malloc(sizeof(*rp));
+			*rp = res;
+			ohash_insert(htab, slot, rp);
+		}
+	}
+	return htab;
+}
+
+static struct ohash *
+manmerge_or(struct expr *e, struct ohash *htab)
+{
+	while (e != NULL) {
+		htab = manmerge(e, htab);
+		e = e->next;
+	}
+	return htab;
+}
+
+static struct ohash *
+manmerge_and(struct expr *e, struct ohash *htab)
+{
+	struct ohash	*hand, *h1, *h2;
+	struct dbm_res	*res;
+	unsigned int	 slot1, slot2;
+
+	/* Evaluate the first term of the AND clause. */
+
+	hand = manmerge(e, NULL);
+
+	while ((e = e->next) != NULL) {
+
+		/* Evaluate the next term and prepare for ANDing. */
+
+		h2 = manmerge(e, NULL);
+		if (ohash_entries(h2) < ohash_entries(hand)) {
+			h1 = h2;
+			h2 = hand;
+		} else
+			h1 = hand;
+		hand = mandoc_malloc(sizeof(*hand));
+		mandoc_ohash_init(hand, 4, offsetof(struct dbm_res, page));
+
+		/* Keep all pages that are in both result sets. */
+
+		for (res = ohash_first(h1, &slot1); res != NULL;
+		    res = ohash_next(h1, &slot1)) {
+			if (ohash_find(h2, ohash_lookup_memory(h2,
+			    (char *)res, sizeof(res->page),
+			    res->page)) == NULL)
+				free(res);
+			else
+				ohash_insert(hand, ohash_lookup_memory(hand,
+				    (char *)res, sizeof(res->page),
+				    res->page), res);
+		}
+
+		/* Discard the merged results. */
+
+		for (res = ohash_first(h2, &slot2); res != NULL;
+		    res = ohash_next(h2, &slot2))
+			free(res);
+		ohash_delete(h2);
+		free(h2);
+		ohash_delete(h1);
+		free(h1);
+	}
+
+	/* Merge the result of the AND into htab. */
+
+	if (htab == NULL)
+		return hand;
+
+	for (res = ohash_first(hand, &slot1); res != NULL;
+	    res = ohash_next(hand, &slot1)) {
+		slot2 = ohash_lookup_memory(htab,
+		    (char *)res, sizeof(res->page), res->page);
+		if (ohash_find(htab, slot2) == NULL)
+			ohash_insert(htab, slot2, res);
+		else
+			free(res);
+	}
+
+	/* Discard the merged result. */
+
+	ohash_delete(hand);
+	free(hand);
+	return htab;
+}
+
 void
 mansearch_free(struct manpage *res, size_t sz)
 {
@@ -396,457 +398,354 @@ manpage_compare(const void *vp1, const void *vp2)
 	    strcasecmp(mp1->names, mp2->names);
 }
 
-static void
-buildnames(const struct mansearch *search, struct manpage *mpage,
-		sqlite3 *db, sqlite3_stmt *s,
-		uint64_t pageid, const char *path, int form)
+static char *
+buildnames(const struct dbm_page *page)
 {
-	glob_t		 globinfo;
-	char		*firstname, *newnames, *prevsec, *prevarch;
-	const char	*oldnames, *sep1, *name, *sec, *sep2, *arch, *fsec;
-	size_t		 i;
-	int		 c, globres;
+	char	*buf;
+	size_t	 i, sz;
 
-	mpage->file = NULL;
-	mpage->names = NULL;
-	firstname = prevsec = prevarch = NULL;
-	i = 1;
-	SQL_BIND_INT64(db, s, i, pageid);
-	while (SQLITE_ROW == (c = sqlite3_step(s))) {
-
-		/* Decide whether we already have some names. */
-
-		if (NULL == mpage->names) {
-			oldnames = "";
-			sep1 = "";
-		} else {
-			oldnames = mpage->names;
-			sep1 = ", ";
-		}
-
-		/* Fetch the next name, rejecting sec/arch mismatches. */
-
-		sec = (const char *)sqlite3_column_text(s, 0);
-		if (search->sec != NULL && strcasecmp(sec, search->sec))
-			continue;
-		arch = (const char *)sqlite3_column_text(s, 1);
-		if (search->arch != NULL && *arch != '\0' &&
-		    strcasecmp(arch, search->arch))
-			continue;
-		name = (const char *)sqlite3_column_text(s, 2);
-
-		/* Remember the first section found. */
-
-		if (9 < mpage->sec && '1' <= *sec && '9' >= *sec)
-			mpage->sec = (*sec - '1') + 1;
-
-		/* If the section changed, append the old one. */
-
-		if (NULL != prevsec &&
-		    (strcmp(sec, prevsec) ||
-		     strcmp(arch, prevarch))) {
-			sep2 = '\0' == *prevarch ? "" : "/";
-			mandoc_asprintf(&newnames, "%s(%s%s%s)",
-			    oldnames, prevsec, sep2, prevarch);
-			free(mpage->names);
-			oldnames = mpage->names = newnames;
-			free(prevsec);
-			free(prevarch);
-			prevsec = prevarch = NULL;
-		}
-
-		/* Save the new section, to append it later. */
-
-		if (NULL == prevsec) {
-			prevsec = mandoc_strdup(sec);
-			prevarch = mandoc_strdup(arch);
-		}
-
-		/* Append the new name. */
-
-		mandoc_asprintf(&newnames, "%s%s%s",
-		    oldnames, sep1, name);
-		free(mpage->names);
-		mpage->names = newnames;
-
-		/* Also save the first file name encountered. */
-
-		if (mpage->file != NULL)
-			continue;
-
-		if (form & FORM_SRC) {
-			sep1 = "man";
-			fsec = sec;
-		} else {
-			sep1 = "cat";
-			fsec = "0";
-		}
-		sep2 = *arch == '\0' ? "" : "/";
-		mandoc_asprintf(&mpage->file, "%s/%s%s%s%s/%s.%s",
-		    path, sep1, sec, sep2, arch, name, fsec);
-		if (access(mpage->file, R_OK) != -1)
-			continue;
-
-		/* Handle unusual file name extensions. */
-
-		if (firstname == NULL)
-			firstname = mpage->file;
-		else
-			free(mpage->file);
-		mandoc_asprintf(&mpage->file, "%s/%s%s%s%s/%s.*",
-		    path, sep1, sec, sep2, arch, name);
-		globres = glob(mpage->file, 0, NULL, &globinfo);
-		free(mpage->file);
-		mpage->file = globres ? NULL :
-		    mandoc_strdup(*globinfo.gl_pathv);
-		globfree(&globinfo);
+	sz = lstlen(page->name) + 1 + lstlen(page->sect) +
+	    (page->arch == NULL ? 0 : 1 + lstlen(page->arch)) + 2;
+	buf = mandoc_malloc(sz);
+	i = 0;
+	lstcat(buf, &i, page->name);
+	buf[i++] = '(';
+	lstcat(buf, &i, page->sect);
+	if (page->arch != NULL) {
+		buf[i++] = '/';
+		lstcat(buf, &i, page->arch);
 	}
-	if (c != SQLITE_DONE)
-		warnx("%s", sqlite3_errmsg(db));
-	sqlite3_reset(s);
+	buf[i++] = ')';
+	buf[i++] = '\0';
+	assert(i == sz);
+	return buf;
+}
 
-	/* If none of the files is usable, use the first name. */
+/*
+ * Count the buffer space needed to print the NUL-terminated
+ * list of NUL-terminated strings, when printing two separator
+ * characters between strings.
+ */
+static size_t
+lstlen(const char *cp)
+{
+	size_t	 sz;
 
-	if (mpage->file == NULL)
-		mpage->file = firstname;
-	else if (mpage->file != firstname)
-		free(firstname);
+	for (sz = 0;; sz++) {
+		if (cp[0] == '\0') {
+			if (cp[1] == '\0')
+				break;
+			sz++;
+		} else if (cp[0] < ' ')
+			sz--;
+		cp++;
+	}
+	return sz;
+}
 
-	/* Append one final section to the names. */
-
-	if (prevsec != NULL) {
-		sep2 = *prevarch == '\0' ? "" : "/";
-		mandoc_asprintf(&newnames, "%s(%s%s%s)",
-		    mpage->names, prevsec, sep2, prevarch);
-		free(mpage->names);
-		mpage->names = newnames;
-		free(prevsec);
-		free(prevarch);
+/*
+ * Print the NUL-terminated list of NUL-terminated strings
+ * into the buffer, seperating strings with a comma and a blank.
+ */
+static void
+lstcat(char *buf, size_t *i, const char *cp)
+{
+	for (;;) {
+		if (cp[0] == '\0') {
+			if (cp[1] == '\0')
+				break;
+			buf[(*i)++] = ',';
+			buf[(*i)++] = ' ';
+		} else if (cp[0] >= ' ')
+			buf[(*i)++] = cp[0];
+		cp++;
 	}
 }
 
-static char *
-buildoutput(sqlite3 *db, sqlite3_stmt *s, uint64_t pageid, uint64_t outbit)
+/*
+ * Return 1 if the string *want occurs in any of the strings
+ * in the NUL-terminated string list *have, or 0 otherwise.
+ * If either argument is NULL or empty, assume no filtering
+ * is desired and return 1.
+ */
+static int
+lstmatch(const char *want, const char *have)
 {
-	char		*output, *newoutput;
-	const char	*oldoutput, *sep1, *data;
-	size_t		 i;
-	int		 c;
+        if (want == NULL || have == NULL || *have == '\0')
+                return 1;
+        while (*have != '\0') {
+                if (strcasestr(have, want) != NULL)
+                        return 1;
+                have = strchr(have, '\0') + 1;
+        }
+        return 0;
+}
+
+/*
+ * Build a list of values taken by the macro im
+ * in the manual page with big-endian address addr.
+ */
+static char *
+buildoutput(size_t im, int32_t addr)
+{
+	const char	*oldoutput, *sep;
+	char		*output, *newoutput, *value;
 
 	output = NULL;
-	i = 1;
-	SQL_BIND_INT64(db, s, i, pageid);
-	SQL_BIND_INT64(db, s, i, outbit);
-	while (SQLITE_ROW == (c = sqlite3_step(s))) {
-		if (NULL == output) {
+	dbm_macro_bypage(im - 2, addr);
+	while ((value = dbm_macro_next()) != NULL) {
+		if (output == NULL) {
 			oldoutput = "";
-			sep1 = "";
+			sep = "";
 		} else {
 			oldoutput = output;
-			sep1 = " # ";
+			sep = " # ";
 		}
-		data = (const char *)sqlite3_column_text(s, 1);
-		mandoc_asprintf(&newoutput, "%s%s%s",
-		    oldoutput, sep1, data);
+		mandoc_asprintf(&newoutput, "%s%s%s", oldoutput, sep, value);
 		free(output);
 		output = newoutput;
 	}
-	if (SQLITE_DONE != c)
-		warnx("%s", sqlite3_errmsg(db));
-	sqlite3_reset(s);
 	return output;
 }
 
-/*
- * Implement substring match as an application-defined SQL function.
- * Using the SQL LIKE or GLOB operators instead would be a bad idea
- * because that would require escaping metacharacters in the string
- * being searched for.
- */
-static void
-sql_match(sqlite3_context *context, int argc, sqlite3_value **argv)
-{
-
-	assert(2 == argc);
-	sqlite3_result_int(context, NULL != strcasestr(
-	    (const char *)sqlite3_value_text(argv[1]),
-	    (const char *)sqlite3_value_text(argv[0])));
-}
-
-/*
- * Implement regular expression match
- * as an application-defined SQL function.
- */
-static void
-sql_regexp(sqlite3_context *context, int argc, sqlite3_value **argv)
-{
-
-	assert(2 == argc);
-	sqlite3_result_int(context, !regexec(
-	    (regex_t *)sqlite3_value_blob(argv[0]),
-	    (const char *)sqlite3_value_text(argv[1]),
-	    0, NULL, 0));
-}
-
-static void
-sql_append(char **sql, size_t *sz, const char *newstr, int count)
-{
-	size_t		 newsz;
-
-	newsz = 1 < count ? (size_t)count : strlen(newstr);
-	*sql = mandoc_realloc(*sql, *sz + newsz + 1);
-	if (1 < count)
-		memset(*sql + *sz, *newstr, (size_t)count);
-	else
-		memcpy(*sql + *sz, newstr, newsz);
-	*sz += newsz;
-	(*sql)[*sz] = '\0';
-}
-
-/*
- * Prepare the search SQL statement.
- */
-static char *
-sql_statement(const struct expr *e)
-{
-	char		*sql;
-	size_t		 sz;
-	int		 needop;
-
-	sql = mandoc_strdup(e->equal ?
-	    "SELECT desc, form, pageid, bits "
-		"FROM mpages NATURAL JOIN names WHERE " :
-	    "SELECT desc, form, pageid, 0 FROM mpages WHERE ");
-	sz = strlen(sql);
-
-	for (needop = 0; NULL != e; e = e->next) {
-		if (e->and)
-			sql_append(&sql, &sz, " AND ", 1);
-		else if (needop)
-			sql_append(&sql, &sz, " OR ", 1);
-		if (e->open)
-			sql_append(&sql, &sz, "(", e->open);
-		sql_append(&sql, &sz,
-		    TYPE_Nd & e->bits
-		    ? (NULL == e->substr
-			? "desc REGEXP ?"
-			: "desc MATCH ?")
-		    : TYPE_Nm == e->bits
-		    ? (NULL == e->substr
-			? "pageid IN (SELECT pageid FROM names "
-			  "WHERE name REGEXP ?)"
-			: e->equal
-			? "name = ? "
-			: "pageid IN (SELECT pageid FROM names "
-			  "WHERE name MATCH ?)")
-		    : (NULL == e->substr
-			? "pageid IN (SELECT pageid FROM keys "
-			  "WHERE key REGEXP ? AND bits & ?)"
-			: "pageid IN (SELECT pageid FROM keys "
-			  "WHERE key MATCH ? AND bits & ?)"), 1);
-		if (e->close)
-			sql_append(&sql, &sz, ")", e->close);
-		needop = 1;
-	}
-
-	return sql;
-}
-
 /*
  * Compile a set of string tokens into an expression.
  * Tokens in "argv" are assumed to be individual expression atoms (e.g.,
  * "(", "foo=bar", etc.).
  */
 static struct expr *
-exprcomp(const struct mansearch *search, int argc, char *argv[])
+exprcomp(const struct mansearch *search, int argc, char *argv[], int *argi)
 {
-	uint64_t	 mask;
-	int		 i, toopen, logic, igncase, toclose;
-	struct expr	*first, *prev, *cur, *next;
+	struct expr	*parent, *child;
+	int		 needterm, nested;
 
-	first = cur = NULL;
-	logic = igncase = toopen = toclose = 0;
-
-	for (i = 0; i < argc; i++) {
-		if (0 == strcmp("(", argv[i])) {
-			if (igncase)
-				goto fail;
-			toopen++;
-			toclose++;
-			continue;
-		} else if (0 == strcmp(")", argv[i])) {
-			if (toopen || logic || igncase || NULL == cur)
-				goto fail;
-			cur->close++;
-			if (0 > --toclose)
-				goto fail;
-			continue;
-		} else if (0 == strcmp("-a", argv[i])) {
-			if (toopen || logic || igncase || NULL == cur)
-				goto fail;
-			logic = 1;
-			continue;
-		} else if (0 == strcmp("-o", argv[i])) {
-			if (toopen || logic || igncase || NULL == cur)
-				goto fail;
-			logic = 2;
-			continue;
-		} else if (0 == strcmp("-i", argv[i])) {
-			if (igncase)
-				goto fail;
-			igncase = 1;
+	if ((nested = *argi) == argc)
+		return NULL;
+	needterm = 1;
+	parent = child = NULL;
+	while (*argi < argc) {
+		if (strcmp(")", argv[*argi]) == 0) {
+			if (needterm)
+				warnx("missing term "
+				    "before closing parenthesis");
+			needterm = 0;
+			if (nested)
+				break;
+			warnx("ignoring unmatched right parenthesis");
+			++*argi;
 			continue;
 		}
-		next = exprterm(search, argv[i], !igncase);
-		if (NULL == next)
-			goto fail;
-		if (NULL == first)
-			first = next;
-		else
-			cur->next = next;
-		prev = cur = next;
-
-		/*
-		 * Searching for descriptions must be split out
-		 * because they are stored in the mpages table,
-		 * not in the keys table.
-		 */
-
-		for (mask = TYPE_Nm; mask <= TYPE_Nd; mask <<= 1) {
-			if (mask & cur->bits && ~mask & cur->bits) {
-				next = mandoc_calloc(1,
-				    sizeof(struct expr));
-				memcpy(next, cur, sizeof(struct expr));
-				prev->open = 1;
-				cur->bits = mask;
-				cur->next = next;
-				cur = next;
-				cur->bits &= ~mask;
+		if (strcmp("-o", argv[*argi]) == 0) {
+			if (needterm) {
+				if (*argi > 0)
+					warnx("ignoring -o after %s",
+					    argv[*argi - 1]);
+				else
+					warnx("ignoring initial -o");
 			}
+			needterm = 1;
+			++*argi;
+			continue;
 		}
-		prev->and = (1 == logic);
-		prev->open += toopen;
-		if (cur != prev)
-			cur->close = 1;
-
-		toopen = logic = igncase = 0;
+		needterm = 0;
+		if (child == NULL) {
+			child = expr_and(search, argc, argv, argi);
+			continue;
+		}
+		if (parent == NULL) {
+			parent = mandoc_calloc(1, sizeof(*parent));
+			parent->type = EXPR_OR;
+			parent->next = NULL;
+			parent->child = child;
+		}
+		child->next = expr_and(search, argc, argv, argi);
+		child = child->next;
 	}
-	if ( ! (toopen || logic || igncase || toclose))
-		return first;
-
-fail:
-	if (NULL != first)
-		exprfree(first);
-	return NULL;
+	if (needterm && *argi)
+		warnx("ignoring trailing %s", argv[*argi - 1]);
+	return parent == NULL ? child : parent;
 }
 
 static struct expr *
-exprterm(const struct mansearch *search, char *buf, int cs)
+expr_and(const struct mansearch *search, int argc, char *argv[], int *argi)
+{
+	struct expr	*parent, *child;
+	int		 needterm;
+
+	needterm = 1;
+	parent = child = NULL;
+	while (*argi < argc) {
+		if (strcmp(")", argv[*argi]) == 0) {
+			if (needterm)
+				warnx("missing term "
+				    "before closing parenthesis");
+			needterm = 0;
+			break;
+		}
+		if (strcmp("-o", argv[*argi]) == 0)
+			break;
+		if (strcmp("-a", argv[*argi]) == 0) {
+			if (needterm) {
+				if (*argi > 0)
+					warnx("ignoring -a after %s",
+					    argv[*argi - 1]);
+				else
+					warnx("ignoring initial -a");
+			}
+			needterm = 1;
+			++*argi;
+			continue;
+		}
+		if (needterm == 0)
+			break;
+		if (child == NULL) {
+			child = exprterm(search, argc, argv, argi);
+			if (child != NULL)
+				needterm = 0;
+			continue;
+		}
+		needterm = 0;
+		if (parent == NULL) {
+			parent = mandoc_calloc(1, sizeof(*parent));
+			parent->type = EXPR_AND;
+			parent->next = NULL;
+			parent->child = child;
+		}
+		child->next = exprterm(search, argc, argv, argi);
+		if (child->next != NULL) {
+			child = child->next;
+			needterm = 0;
+		}
+	}
+	if (needterm && *argi)
+		warnx("ignoring trailing %s", argv[*argi - 1]);
+	return parent == NULL ? child : parent;
+}
+
+static struct expr *
+exprterm(const struct mansearch *search, int argc, char *argv[], int *argi)
 {
 	char		 errbuf[BUFSIZ];
 	struct expr	*e;
 	char		*key, *val;
 	uint64_t	 iterbit;
-	int		 i, irc;
+	int		 cs, i, irc;
 
-	if ('\0' == *buf)
-		return NULL;
+	if (strcmp("(", argv[*argi]) == 0) {
+		++*argi;
+		e = exprcomp(search, argc, argv, argi);
+		if (*argi < argc) {
+			assert(strcmp(")", argv[*argi]) == 0);
+			++*argi;
+		} else
+			warnx("unclosed parenthesis");
+		return e;
+	}
 
-	e = mandoc_calloc(1, sizeof(struct expr));
+	e = mandoc_calloc(1, sizeof(*e));
+	e->type = EXPR_TERM;
+	e->bits = 0;
+	e->next = NULL;
+	e->child = NULL;
 
 	if (search->argmode == ARG_NAME) {
 		e->bits = TYPE_Nm;
-		e->substr = buf;
-		e->equal = 1;
+		e->match.type = DBM_EXACT;
+		e->match.str = argv[(*argi)++];
 		return e;
 	}
 
 	/*
 	 * Separate macro keys from search string.
-	 * If needed, request regular expression handling
-	 * by setting e->substr to NULL.
+	 * If needed, request regular expression handling.
 	 */
 
 	if (search->argmode == ARG_WORD) {
 		e->bits = TYPE_Nm;
-		e->substr = NULL;
+		e->match.type = DBM_REGEX;
 #if HAVE_REWB_BSD
-		mandoc_asprintf(&val, "[[:<:]]%s[[:>:]]", buf);
+		mandoc_asprintf(&val, "[[:<:]]%s[[:>:]]", argv[*argi]);
 #elif HAVE_REWB_SYSV
-		mandoc_asprintf(&val, "\\<%s\\>", buf);
+		mandoc_asprintf(&val, "\\<%s\\>", argv[*argi]);
 #else
 		mandoc_asprintf(&val,
-		    "(^|[^a-zA-Z01-9_])%s([^a-zA-Z01-9_]|$)", buf);
+		    "(^|[^a-zA-Z01-9_])%s([^a-zA-Z01-9_]|$)", argv[*argi]);
 #endif
 		cs = 0;
-	} else if ((val = strpbrk(buf, "=~")) == NULL) {
+	} else if ((val = strpbrk(argv[*argi], "=~")) == NULL) {
 		e->bits = TYPE_Nm | TYPE_Nd;
-		e->substr = buf;
+		e->match.type = DBM_SUB;
+		e->match.str = argv[*argi];
 	} else {
-		if (val == buf)
+		if (val == argv[*argi])
 			e->bits = TYPE_Nm | TYPE_Nd;
-		if ('=' == *val)
-			e->substr = val + 1;
+		if (*val == '=') {
+			e->match.type = DBM_SUB;
+			e->match.str = val + 1;
+		} else
+			e->match.type = DBM_REGEX;
 		*val++ = '\0';
-		if (NULL != strstr(buf, "arch"))
+		if (strstr(argv[*argi], "arch") != NULL)
 			cs = 0;
 	}
 
 	/* Compile regular expressions. */
 
-	if (NULL == e->substr) {
-		irc = regcomp(&e->regexp, val,
+	if (e->match.type == DBM_REGEX) {
+		e->match.re = mandoc_malloc(sizeof(*e->match.re));
+		irc = regcomp(e->match.re, val,
 		    REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE));
+		if (irc) {
+			regerror(irc, e->match.re, errbuf, sizeof(errbuf));
+			warnx("regcomp /%s/: %s", val, errbuf);
+		}
 		if (search->argmode == ARG_WORD)
 			free(val);
 		if (irc) {
-			regerror(irc, &e->regexp, errbuf, sizeof(errbuf));
-			warnx("regcomp: %s", errbuf);
+			free(e->match.re);
 			free(e);
+			++*argi;
 			return NULL;
 		}
 	}
 
-	if (e->bits)
+	if (e->bits) {
+		++*argi;
 		return e;
+	}
 
 	/*
 	 * Parse out all possible fields.
 	 * If the field doesn't resolve, bail.
 	 */
 
-	while (NULL != (key = strsep(&buf, ","))) {
+	while (NULL != (key = strsep(&argv[*argi], ","))) {
 		if ('\0' == *key)
 			continue;
-		for (i = 0, iterbit = 1;
-		     i < mansearch_keymax;
-		     i++, iterbit <<= 1) {
-			if (0 == strcasecmp(key,
-			    mansearch_keynames[i])) {
+		for (i = 0, iterbit = 1; i < KEY_MAX; i++, iterbit <<= 1) {
+			if (0 == strcasecmp(key, mansearch_keynames[i])) {
 				e->bits |= iterbit;
 				break;
 			}
 		}
-		if (i == mansearch_keymax) {
-			if (strcasecmp(key, "any")) {
-				free(e);
-				return NULL;
-			}
+		if (i == KEY_MAX) {
+			if (strcasecmp(key, "any"))
+				warnx("treating unknown key "
+				    "\"%s\" as \"any\"", key);
 			e->bits |= ~0ULL;
 		}
 	}
 
+	++*argi;
 	return e;
 }
 
 static void
-exprfree(struct expr *p)
+exprfree(struct expr *e)
 {
-	struct expr	*pp;
-
-	while (NULL != p) {
-		pp = p->next;
-		free(p);
-		p = pp;
-	}
+	if (e->next != NULL)
+		exprfree(e->next);
+	if (e->child != NULL)
+		exprfree(e->child);
+	free(e);
 }
diff --git a/contrib/mdocml/mansearch.h b/contrib/mdocml/mansearch.h
index 7f68ff67675..892c6e1e8a5 100644
--- a/contrib/mdocml/mansearch.h
+++ b/contrib/mdocml/mansearch.h
@@ -1,7 +1,7 @@
-/*	$Id: mansearch.h,v 1.24 2015/11/07 14:01:16 schwarze Exp $ */
+/*	$Id: mansearch.h,v 1.27 2016/08/01 12:31:00 schwarze Exp $ */
 /*
  * Copyright (c) 2012 Kristaps Dzonsons 
- * Copyright (c) 2013, 2014 Ingo Schwarze 
+ * Copyright (c) 2013, 2014, 2016 Ingo Schwarze 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -17,6 +17,12 @@
  */
 
 #define	MANDOC_DB	 "mandoc.db"
+#define	MANDOCDB_MAGIC	 0x3a7d0cdb
+#define	MANDOCDB_VERSION 1
+
+#define	MACRO_MAX	 36
+#define	KEY_Nd		 39
+#define	KEY_MAX		 40
 
 #define	TYPE_arch	 0x0000000000000001ULL
 #define	TYPE_sec	 0x0000000000000002ULL
@@ -66,9 +72,11 @@
 #define	NAME_FILE	 0x0000004000000010ULL
 #define	NAME_MASK	 0x000000000000001fULL
 
-#define	FORM_CAT	 0  /* manual page is preformatted */
-#define	FORM_SRC	 1  /* format is mdoc(7) or man(7) */
-#define	FORM_NONE	 4  /* format is unknown */
+enum	form {
+	FORM_SRC = 1,	/* Format is mdoc(7) or man(7). */
+	FORM_CAT,	/* Manual page is preformatted. */
+	FORM_NONE	/* Format is unknown. */
+};
 
 enum	argmode {
 	ARG_FILE = 0,
@@ -84,7 +92,7 @@ struct	manpage {
 	size_t		 ipath; /* number of the manpath */
 	uint64_t	 bits; /* name type mask */
 	int		 sec; /* section number, 10 means invalid */
-	int		 form; /* 0 == catpage */
+	enum form	 form;
 };
 
 struct	mansearch {
@@ -98,7 +106,6 @@ struct	mansearch {
 
 struct	manpaths;
 
-int	mansearch_setup(int);
 int	mansearch(const struct mansearch *cfg, /* options */
 		const struct manpaths *paths, /* manpaths */
 		int argc, /* size of argv */
diff --git a/contrib/mdocml/mdoc.7 b/contrib/mdocml/mdoc.7
index 198a46a9636..e28db482db0 100644
--- a/contrib/mdocml/mdoc.7
+++ b/contrib/mdocml/mdoc.7
@@ -1,7 +1,7 @@
-.\"	$Id: mdoc.7,v 1.257 2015/11/05 12:06:45 schwarze Exp $
+.\"	$Id: mdoc.7,v 1.260 2017/01/09 14:10:53 schwarze Exp $
 .\"
 .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons 
-.\" Copyright (c) 2010, 2011, 2013 Ingo Schwarze 
+.\" Copyright (c) 2010, 2011, 2013-2017 Ingo Schwarze 
 .\"
 .\" Permission to use, copy, modify, and distribute this software for any
 .\" purpose with or without fee is hereby granted, provided that the above
@@ -15,7 +15,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: November 5 2015 $
+.Dd $Mdocdate: January 9 2017 $
 .Dt MDOC 7
 .Os
 .Sh NAME
@@ -1831,14 +1831,25 @@ The
 list is the most complicated.
 Its syntax is as follows:
 .Pp
-.D1 Pf \. Sx \&It Ar cell Op  Ar cell ...
 .D1 Pf \. Sx \&It Ar cell Op Sx \&Ta Ar cell ...
+.D1 Pf \. Sx \&It Ar cell Op  Ar cell ...
 .Pp
 The arguments consist of one or more lines of text and macros
 representing a complete table line.
-Cells within the line are delimited by tabs or by the special
+Cells within the line are delimited by the special
 .Sx \&Ta
-block macro.
+block macro or by literal tab characters.
+.Pp
+Using literal tabs is strongly discouraged because they are very
+hard to use correctly and
+.Nm
+code using them is very hard to read.
+In particular, a blank character is syntactically significant
+before and after the literal tab character.
+If a word precedes or follows the tab without an intervening blank,
+that word is never interpreted as a macro call, but always output
+literally.
+.Pp
 The tab cell delimiter may only be used within the
 .Sx \&It
 line itself; on following lines, only the
@@ -1853,9 +1864,10 @@ Note that quoted strings may span tab-delimited cells on an
 line.
 For example,
 .Pp
-.Dl .It \(dqcol1 ;  col2 ;\(dq \&;
+.Dl .It \(dqcol1 ,\&  col2 ,\(dq \&;
 .Pp
-will preserve the semicolon whitespace except for the last.
+will preserve the whitespace before both commas,
+but not the whitespace before the semicolon.
 .Pp
 See also
 .Sx \&Bl .
@@ -2714,14 +2726,13 @@ Link to another manual
 .Pq Qq cross-reference .
 Its syntax is as follows:
 .Pp
-.D1 Pf \. Sx \&Xr Ar name Op section
+.D1 Pf \. Sx \&Xr Ar name section
 .Pp
 Cross reference the
 .Ar name
 and
 .Ar section
-number of another man page;
-omitting the section number is rarely useful.
+number of another man page.
 .Pp
 Examples:
 .Dl \&.Xr mandoc 1
@@ -3033,7 +3044,7 @@ then the macro accepts an arbitrary number of arguments.
 .It Sx \&Ux  Ta    Yes      Ta    Yes      Ta    n
 .It Sx \&Va  Ta    Yes      Ta    Yes      Ta    n
 .It Sx \&Vt  Ta    Yes      Ta    Yes      Ta    >0
-.It Sx \&Xr  Ta    Yes      Ta    Yes      Ta    >0
+.It Sx \&Xr  Ta    Yes      Ta    Yes      Ta    2
 .It Sx \&br  Ta    \&No     Ta    \&No     Ta    0
 .It Sx \&sp  Ta    \&No     Ta    \&No     Ta    1
 .El
@@ -3217,6 +3228,12 @@ but produces large indentations.
 .Xr mandoc_char 7 ,
 .Xr roff 7 ,
 .Xr tbl 7
+.Pp
+The web page
+.Lk http://mdocml.bsd.lv/mdoc/ "extended documentation for the mdoc language"
+provides a few tutorial-style pages for beginners, an extensive style
+guide for advanced authors, and an alphabetic index helping to choose
+the best macros for various kinds of content.
 .Sh HISTORY
 The
 .Nm
diff --git a/contrib/mdocml/mdoc.c b/contrib/mdocml/mdoc.c
index 724d45c652c..009496184ab 100644
--- a/contrib/mdocml/mdoc.c
+++ b/contrib/mdocml/mdoc.c
@@ -1,7 +1,7 @@
-/*	$Id: mdoc.c,v 1.256 2015/10/30 19:04:16 schwarze Exp $ */
+/*	$Id: mdoc.c,v 1.258 2017/01/10 13:47:00 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons 
- * Copyright (c) 2010, 2012-2015 Ingo Schwarze 
+ * Copyright (c) 2010, 2012-2016 Ingo Schwarze 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -140,8 +140,8 @@ mdoc_endbody_alloc(struct roff_man *mdoc, int line, int pos, int tok,
 {
 	struct roff_node *p;
 
-	body->flags |= MDOC_ENDED;
-	body->parent->flags |= MDOC_ENDED;
+	body->flags |= NODE_ENDED;
+	body->parent->flags |= NODE_ENDED;
 	p = roff_node_alloc(mdoc, line, pos, ROFFT_BODY, tok);
 	p->body = body;
 	p->norm = body->norm;
@@ -219,29 +219,19 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
 	struct roff_node *n;
 	char		 *c, *ws, *end;
 
-	assert(mdoc->last);
 	n = mdoc->last;
 
 	/*
-	 * Divert directly to list processing if we're encountering a
-	 * columnar ROFFT_BLOCK with or without a prior ROFFT_BLOCK entry
-	 * (a ROFFT_BODY means it's already open, in which case we should
-	 * process within its context in the normal way).
+	 * If a column list contains plain text, assume an implicit item
+	 * macro.  This can happen one or more times at the beginning
+	 * of such a list, intermixed with non-It mdoc macros and with
+	 * nodes generated on the roff level, for example by tbl.
 	 */
 
-	if (n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
-	    n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) {
-		/* `Bl' is open without any children. */
-		mdoc->flags |= MDOC_FREECOL;
-		mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf);
-		return 1;
-	}
-
-	if (n->tok == MDOC_It && n->type == ROFFT_BLOCK &&
-	    NULL != n->parent &&
-	    MDOC_Bl == n->parent->tok &&
-	    LIST_column == n->parent->norm->Bl.type) {
-		/* `Bl' has block-level `It' children. */
+	if ((n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
+	     n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) ||
+	    (n->parent != NULL && n->parent->tok == MDOC_Bl &&
+	     n->parent->norm->Bl.type == LIST_column)) {
 		mdoc->flags |= MDOC_FREECOL;
 		mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf);
 		return 1;
@@ -302,7 +292,7 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
 		 * behaviour that we want to work around it.
 		 */
 		roff_elem_alloc(mdoc, line, offs, MDOC_sp);
-		mdoc->last->flags |= MDOC_VALID | MDOC_ENDED;
+		mdoc->last->flags |= NODE_VALID | NODE_ENDED;
 		mdoc->next = ROFF_NEXT_SIBLING;
 		return 1;
 	}
@@ -321,7 +311,7 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
 	assert(buf < end);
 
 	if (mandoc_eos(buf+offs, (size_t)(end-buf-offs)))
-		mdoc->last->flags |= MDOC_EOS;
+		mdoc->last->flags |= NODE_EOS;
 	return 1;
 }
 
@@ -393,36 +383,23 @@ mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs)
 	 * into macro processing.
 	 */
 
-	if (NULL == mdoc->last || MDOC_It == tok || MDOC_El == tok) {
+	n = mdoc->last;
+	if (n == NULL || tok == MDOC_It || tok == MDOC_El) {
 		mdoc_macro(mdoc, tok, ln, sv, &offs, buf);
 		return 1;
 	}
 
-	n = mdoc->last;
-	assert(mdoc->last);
-
 	/*
-	 * If the first macro of a `Bl -column', open an `It' block
-	 * context around the parsed macro.
+	 * If a column list contains a non-It macro, assume an implicit
+	 * item macro.  This can happen one or more times at the
+	 * beginning of such a list, intermixed with text lines and
+	 * with nodes generated on the roff level, for example by tbl.
 	 */
 
-	if (n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
-	    n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) {
-		mdoc->flags |= MDOC_FREECOL;
-		mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf);
-		return 1;
-	}
-
-	/*
-	 * If we're following a block-level `It' within a `Bl -column'
-	 * context (perhaps opened in the above block or in ptext()),
-	 * then open an `It' block context around the parsed macro.
-	 */
-
-	if (n->tok == MDOC_It && n->type == ROFFT_BLOCK &&
-	    NULL != n->parent &&
-	    MDOC_Bl == n->parent->tok &&
-	    LIST_column == n->parent->norm->Bl.type) {
+	if ((n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
+	     n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) ||
+	    (n->parent != NULL && n->parent->tok == MDOC_Bl &&
+	     n->parent->norm->Bl.type == LIST_column)) {
 		mdoc->flags |= MDOC_FREECOL;
 		mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf);
 		return 1;
diff --git a/contrib/mdocml/mdoc_argv.c b/contrib/mdocml/mdoc_argv.c
index 8675bdb2db5..b47c7dbdea3 100644
--- a/contrib/mdocml/mdoc_argv.c
+++ b/contrib/mdocml/mdoc_argv.c
@@ -1,4 +1,4 @@
-/*	$Id: mdoc_argv.c,v 1.107 2015/10/17 00:21:07 schwarze Exp $ */
+/*	$Id: mdoc_argv.c,v 1.109 2016/08/28 16:15:12 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons 
  * Copyright (c) 2012, 2014, 2015 Ingo Schwarze 
@@ -29,6 +29,7 @@
 #include "roff.h"
 #include "mdoc.h"
 #include "libmandoc.h"
+#include "roff_int.h"
 #include "libmdoc.h"
 
 #define	MULTI_STEP	 5 /* pre-allocate argument values */
@@ -479,7 +480,7 @@ args(struct roff_man *mdoc, int line, int *pos,
 			 * unless there is a blank in between.
 			 */
 
-			if (p[-1] != ' ')
+			if (p > buf && p[-1] != ' ')
 				mdoc->flags |= MDOC_PHRASEQL;
 			if (p[1] != ' ')
 				mdoc->flags |= MDOC_PHRASEQN;
diff --git a/contrib/mdocml/mdoc_hash.c b/contrib/mdocml/mdoc_hash.c
index 476116d792a..cad3c2db1af 100644
--- a/contrib/mdocml/mdoc_hash.c
+++ b/contrib/mdocml/mdoc_hash.c
@@ -1,4 +1,4 @@
-/*	$Id: mdoc_hash.c,v 1.26 2015/10/06 18:32:19 schwarze Exp $ */
+/*	$Id: mdoc_hash.c,v 1.27 2016/07/15 18:03:45 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons 
  * Copyright (c) 2015 Ingo Schwarze 
@@ -26,8 +26,10 @@
 #include 
 #include 
 
+#include "mandoc.h"
 #include "roff.h"
 #include "mdoc.h"
+#include "libmandoc.h"
 #include "libmdoc.h"
 
 static	unsigned char	 table[27 * 12];
diff --git a/contrib/mdocml/mdoc_html.c b/contrib/mdocml/mdoc_html.c
index 8e21bc79630..3f757d20eb3 100644
--- a/contrib/mdocml/mdoc_html.c
+++ b/contrib/mdocml/mdoc_html.c
@@ -1,7 +1,7 @@
-/*	$Id: mdoc_html.c,v 1.240 2016/01/08 17:48:09 schwarze Exp $ */
+/*	$Id: mdoc_html.c,v 1.260 2017/01/21 02:09:51 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons 
- * Copyright (c) 2014, 2015, 2016 Ingo Schwarze 
+ * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -48,14 +48,13 @@ struct	htmlmdoc {
 	void		(*post)(MDOC_ARGS);
 };
 
+static	char		 *make_id(const struct roff_node *);
 static	void		  print_mdoc_head(MDOC_ARGS);
 static	void		  print_mdoc_node(MDOC_ARGS);
 static	void		  print_mdoc_nodelist(MDOC_ARGS);
 static	void		  synopsis_pre(struct html *,
 				const struct roff_node *);
 
-static	void		  a2width(const char *, struct roffsu *);
-
 static	void		  mdoc_root_post(MDOC_ARGS);
 static	int		  mdoc_root_pre(MDOC_ARGS);
 
@@ -70,9 +69,8 @@ static	int		  mdoc_bf_pre(MDOC_ARGS);
 static	void		  mdoc_bk_post(MDOC_ARGS);
 static	int		  mdoc_bk_pre(MDOC_ARGS);
 static	int		  mdoc_bl_pre(MDOC_ARGS);
-static	int		  mdoc_bt_pre(MDOC_ARGS);
-static	int		  mdoc_bx_pre(MDOC_ARGS);
 static	int		  mdoc_cd_pre(MDOC_ARGS);
+static	int		  mdoc_cm_pre(MDOC_ARGS);
 static	int		  mdoc_d1_pre(MDOC_ARGS);
 static	int		  mdoc_dv_pre(MDOC_ARGS);
 static	int		  mdoc_fa_pre(MDOC_ARGS);
@@ -107,7 +105,6 @@ static	int		  mdoc_pp_pre(MDOC_ARGS);
 static	void		  mdoc_quote_post(MDOC_ARGS);
 static	int		  mdoc_quote_pre(MDOC_ARGS);
 static	int		  mdoc_rs_pre(MDOC_ARGS);
-static	int		  mdoc_rv_pre(MDOC_ARGS);
 static	int		  mdoc_sh_pre(MDOC_ARGS);
 static	int		  mdoc_skip_pre(MDOC_ARGS);
 static	int		  mdoc_sm_pre(MDOC_ARGS);
@@ -115,7 +112,6 @@ static	int		  mdoc_sp_pre(MDOC_ARGS);
 static	int		  mdoc_ss_pre(MDOC_ARGS);
 static	int		  mdoc_sx_pre(MDOC_ARGS);
 static	int		  mdoc_sy_pre(MDOC_ARGS);
-static	int		  mdoc_ud_pre(MDOC_ARGS);
 static	int		  mdoc_va_pre(MDOC_ARGS);
 static	int		  mdoc_vt_pre(MDOC_ARGS);
 static	int		  mdoc_xr_pre(MDOC_ARGS);
@@ -140,7 +136,7 @@ static	const struct htmlmdoc mdocs[MDOC_MAX] = {
 	{mdoc_an_pre, NULL}, /* An */
 	{mdoc_ar_pre, NULL}, /* Ar */
 	{mdoc_cd_pre, NULL}, /* Cd */
-	{mdoc_fl_pre, NULL}, /* Cm */
+	{mdoc_cm_pre, NULL}, /* Cm */
 	{mdoc_dv_pre, NULL}, /* Dv */
 	{mdoc_er_pre, NULL}, /* Er */
 	{mdoc_ev_pre, NULL}, /* Ev */
@@ -158,7 +154,7 @@ static	const struct htmlmdoc mdocs[MDOC_MAX] = {
 	{mdoc_quote_pre, mdoc_quote_post}, /* Op */
 	{mdoc_ft_pre, NULL}, /* Ot */
 	{mdoc_pa_pre, NULL}, /* Pa */
-	{mdoc_rv_pre, NULL}, /* Rv */
+	{mdoc_ex_pre, NULL}, /* Rv */
 	{NULL, NULL}, /* St */
 	{mdoc_va_pre, NULL}, /* Va */
 	{mdoc_vt_pre, NULL}, /* Vt */
@@ -183,7 +179,7 @@ static	const struct htmlmdoc mdocs[MDOC_MAX] = {
 	{mdoc_quote_pre, mdoc_quote_post}, /* Bo */
 	{mdoc_quote_pre, mdoc_quote_post}, /* Bq */
 	{mdoc_xx_pre, NULL}, /* Bsx */
-	{mdoc_bx_pre, NULL}, /* Bx */
+	{mdoc_xx_pre, NULL}, /* Bx */
 	{mdoc_skip_pre, NULL}, /* Db */
 	{NULL, NULL}, /* Dc */
 	{mdoc_quote_pre, mdoc_quote_post}, /* Do */
@@ -224,10 +220,10 @@ static	const struct htmlmdoc mdocs[MDOC_MAX] = {
 	{NULL, NULL}, /* Oc */
 	{mdoc_bk_pre, mdoc_bk_post}, /* Bk */
 	{NULL, NULL}, /* Ek */
-	{mdoc_bt_pre, NULL}, /* Bt */
+	{NULL, NULL}, /* Bt */
 	{NULL, NULL}, /* Hf */
 	{mdoc_em_pre, NULL}, /* Fr */
-	{mdoc_ud_pre, NULL}, /* Ud */
+	{NULL, NULL}, /* Ud */
 	{mdoc_lb_pre, NULL}, /* Lb */
 	{mdoc_pp_pre, NULL}, /* Lp */
 	{mdoc_lk_pre, NULL}, /* Lk */
@@ -247,37 +243,6 @@ static	const struct htmlmdoc mdocs[MDOC_MAX] = {
 	{mdoc_skip_pre, NULL}, /* ll */
 };
 
-static	const char * const lists[LIST_MAX] = {
-	NULL,
-	"list-bul",
-	"list-col",
-	"list-dash",
-	"list-diag",
-	"list-enum",
-	"list-hang",
-	"list-hyph",
-	"list-inset",
-	"list-item",
-	"list-ohang",
-	"list-tag"
-};
-
-
-/*
- * Calculate the scaling unit passed in a `-width' argument.  This uses
- * either a native scaling unit (e.g., 1i, 2m) or the string length of
- * the value.
- */
-static void
-a2width(const char *p, struct roffsu *su)
-{
-
-	if (a2roffsu(p, su, SCALE_MAX) < 2) {
-		su->unit = SCALE_EN;
-		su->scale = html_strlen(p);
-	} else if (su->scale < 0.0)
-		su->scale = 0.0;
-}
 
 /*
  * See the same function in mdoc_term.c for documentation.
@@ -286,14 +251,14 @@ static void
 synopsis_pre(struct html *h, const struct roff_node *n)
 {
 
-	if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags))
+	if (NULL == n->prev || ! (NODE_SYNPRETTY & n->flags))
 		return;
 
 	if (n->prev->tok == n->tok &&
 	    MDOC_Fo != n->tok &&
 	    MDOC_Ft != n->tok &&
 	    MDOC_Fn != n->tok) {
-		print_otag(h, TAG_BR, 0, NULL);
+		print_otag(h, TAG_BR, "");
 		return;
 	}
 
@@ -312,7 +277,7 @@ synopsis_pre(struct html *h, const struct roff_node *n)
 		}
 		/* FALLTHROUGH */
 	default:
-		print_otag(h, TAG_BR, 0, NULL);
+		print_otag(h, TAG_BR, "");
 		break;
 	}
 }
@@ -320,45 +285,48 @@ synopsis_pre(struct html *h, const struct roff_node *n)
 void
 html_mdoc(void *arg, const struct roff_man *mdoc)
 {
-	struct htmlpair	 tag;
 	struct html	*h;
-	struct tag	*t, *tt;
+	struct tag	*t;
 
-	PAIR_CLASS_INIT(&tag, "mandoc");
 	h = (struct html *)arg;
 
-	if ( ! (HTML_FRAGMENT & h->oflags)) {
+	if ((h->oflags & HTML_FRAGMENT) == 0) {
 		print_gen_decls(h);
-		t = print_otag(h, TAG_HTML, 0, NULL);
-		tt = print_otag(h, TAG_HEAD, 0, NULL);
+		print_otag(h, TAG_HTML, "");
+		t = print_otag(h, TAG_HEAD, "");
 		print_mdoc_head(&mdoc->meta, mdoc->first->child, h);
-		print_tagq(h, tt);
-		print_otag(h, TAG_BODY, 0, NULL);
-		print_otag(h, TAG_DIV, 1, &tag);
-	} else
-		t = print_otag(h, TAG_DIV, 1, &tag);
+		print_tagq(h, t);
+		print_otag(h, TAG_BODY, "");
+	}
 
 	mdoc_root_pre(&mdoc->meta, mdoc->first->child, h);
+	t = print_otag(h, TAG_DIV, "c", "manual-text");
 	print_mdoc_nodelist(&mdoc->meta, mdoc->first->child, h);
-	mdoc_root_post(&mdoc->meta, mdoc->first->child, h);
 	print_tagq(h, t);
-	putchar('\n');
+	mdoc_root_post(&mdoc->meta, mdoc->first->child, h);
+	print_tagq(h, NULL);
 }
 
 static void
 print_mdoc_head(MDOC_ARGS)
 {
+	char	*cp;
 
 	print_gen_head(h);
-	bufinit(h);
-	bufcat(h, meta->title);
-	if (meta->msec)
-		bufcat_fmt(h, "(%s)", meta->msec);
-	if (meta->arch)
-		bufcat_fmt(h, " (%s)", meta->arch);
 
-	print_otag(h, TAG_TITLE, 0, NULL);
-	print_text(h, h->buf);
+	if (meta->arch != NULL && meta->msec != NULL)
+		mandoc_asprintf(&cp, "%s(%s) (%s)", meta->title,
+		    meta->msec, meta->arch);
+	else if (meta->msec != NULL)
+		mandoc_asprintf(&cp, "%s(%s)", meta->title, meta->msec);
+	else if (meta->arch != NULL)
+		mandoc_asprintf(&cp, "%s (%s)", meta->title, meta->arch);
+	else
+		cp = mandoc_strdup(meta->title);
+
+	print_otag(h, TAG_TITLE, "");
+	print_text(h, cp);
+	free(cp);
 }
 
 static void
@@ -377,9 +345,12 @@ print_mdoc_node(MDOC_ARGS)
 	int		 child;
 	struct tag	*t;
 
+	if (n->flags & NODE_NOPRT)
+		return;
+
 	child = 1;
 	t = h->tags.head;
-	n->flags &= ~MDOC_ENDED;
+	n->flags &= ~NODE_ENDED;
 
 	switch (n->type) {
 	case ROFFT_TEXT:
@@ -390,18 +361,16 @@ print_mdoc_node(MDOC_ARGS)
 		 * Make sure that if we're in a literal mode already
 		 * (i.e., within a 
) don't print the newline.
 		 */
-		if (' ' == *n->string && MDOC_LINE & n->flags)
+		if (' ' == *n->string && NODE_LINE & n->flags)
 			if ( ! (HTML_LITERAL & h->flags))
-				print_otag(h, TAG_BR, 0, NULL);
-		if (MDOC_DELIMC & n->flags)
+				print_otag(h, TAG_BR, "");
+		if (NODE_DELIMC & n->flags)
 			h->flags |= HTML_NOSPACE;
 		print_text(h, n->string);
-		if (MDOC_DELIMO & n->flags)
+		if (NODE_DELIMO & n->flags)
 			h->flags |= HTML_NOSPACE;
 		return;
 	case ROFFT_EQN:
-		if (n->flags & MDOC_LINE)
-			putchar('\n');
 		print_eqn(h, n->eqn);
 		break;
 	case ROFFT_TBL:
@@ -428,7 +397,7 @@ print_mdoc_node(MDOC_ARGS)
 		break;
 	}
 
-	if (h->flags & HTML_KEEP && n->flags & MDOC_LINE) {
+	if (h->flags & HTML_KEEP && n->flags & NODE_LINE) {
 		h->flags &= ~HTML_KEEP;
 		h->flags |= HTML_PREKEEP;
 	}
@@ -442,11 +411,11 @@ print_mdoc_node(MDOC_ARGS)
 	case ROFFT_EQN:
 		break;
 	default:
-		if ( ! mdocs[n->tok].post || n->flags & MDOC_ENDED)
+		if ( ! mdocs[n->tok].post || n->flags & NODE_ENDED)
 			break;
 		(*mdocs[n->tok].post)(meta, n, h);
 		if (n->end != ENDBODY_NOT)
-			n->body->flags |= MDOC_ENDED;
+			n->body->flags |= NODE_ENDED;
 		if (n->end == ENDBODY_NOSPACE)
 			h->flags |= HTML_NOSPACE;
 		break;
@@ -456,23 +425,17 @@ print_mdoc_node(MDOC_ARGS)
 static void
 mdoc_root_post(MDOC_ARGS)
 {
-	struct htmlpair	 tag;
 	struct tag	*t, *tt;
 
-	PAIR_CLASS_INIT(&tag, "foot");
-	t = print_otag(h, TAG_TABLE, 1, &tag);
+	t = print_otag(h, TAG_TABLE, "c", "foot");
+	print_otag(h, TAG_TBODY, "");
+	tt = print_otag(h, TAG_TR, "");
 
-	print_otag(h, TAG_TBODY, 0, NULL);
-
-	tt = print_otag(h, TAG_TR, 0, NULL);
-
-	PAIR_CLASS_INIT(&tag, "foot-date");
-	print_otag(h, TAG_TD, 1, &tag);
+	print_otag(h, TAG_TD, "c", "foot-date");
 	print_text(h, meta->date);
 	print_stagq(h, tt);
 
-	PAIR_CLASS_INIT(&tag, "foot-os");
-	print_otag(h, TAG_TD, 1, &tag);
+	print_otag(h, TAG_TD, "c", "foot-os");
 	print_text(h, meta->os);
 	print_tagq(h, t);
 }
@@ -480,7 +443,6 @@ mdoc_root_post(MDOC_ARGS)
 static int
 mdoc_root_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag;
 	struct tag	*t, *tt;
 	char		*volume, *title;
 
@@ -496,25 +458,19 @@ mdoc_root_pre(MDOC_ARGS)
 		mandoc_asprintf(&title, "%s(%s)",
 		    meta->title, meta->msec);
 
-	PAIR_CLASS_INIT(&tag, "head");
-	t = print_otag(h, TAG_TABLE, 1, &tag);
+	t = print_otag(h, TAG_TABLE, "c", "head");
+	print_otag(h, TAG_TBODY, "");
+	tt = print_otag(h, TAG_TR, "");
 
-	print_otag(h, TAG_TBODY, 0, NULL);
-
-	tt = print_otag(h, TAG_TR, 0, NULL);
-
-	PAIR_CLASS_INIT(&tag, "head-ltitle");
-	print_otag(h, TAG_TD, 1, &tag);
+	print_otag(h, TAG_TD, "c", "head-ltitle");
 	print_text(h, title);
 	print_stagq(h, tt);
 
-	PAIR_CLASS_INIT(&tag, "head-vol");
-	print_otag(h, TAG_TD, 1, &tag);
+	print_otag(h, TAG_TD, "c", "head-vol");
 	print_text(h, volume);
 	print_stagq(h, tt);
 
-	PAIR_CLASS_INIT(&tag, "head-rtitle");
-	print_otag(h, TAG_TD, 1, &tag);
+	print_otag(h, TAG_TD, "c", "head-rtitle");
 	print_text(h, title);
 	print_tagq(h, t);
 
@@ -523,15 +479,35 @@ mdoc_root_pre(MDOC_ARGS)
 	return 1;
 }
 
+static char *
+make_id(const struct roff_node *n)
+{
+	const struct roff_node	*nch;
+	char			*buf, *cp;
+
+	for (nch = n->child; nch != NULL; nch = nch->next)
+		if (nch->type != ROFFT_TEXT)
+			return NULL;
+
+	buf = NULL;
+	deroff(&buf, n);
+
+	/* http://www.w3.org/TR/html5/dom.html#the-id-attribute */
+
+	for (cp = buf; *cp != '\0'; cp++)
+		if (*cp == ' ')
+			*cp = '_';
+
+	return buf;
+}
+
 static int
 mdoc_sh_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag;
+	char	*id;
 
 	switch (n->type) {
 	case ROFFT_BLOCK:
-		PAIR_CLASS_INIT(&tag, "section");
-		print_otag(h, TAG_DIV, 1, &tag);
 		return 1;
 	case ROFFT_BODY:
 		if (n->sec == SEC_AUTHORS)
@@ -541,19 +517,11 @@ mdoc_sh_pre(MDOC_ARGS)
 		break;
 	}
 
-	bufinit(h);
-
-	for (n = n->child; n != NULL && n->type == ROFFT_TEXT; ) {
-		bufcat_id(h, n->string);
-		if (NULL != (n = n->next))
-			bufcat_id(h, " ");
-	}
-
-	if (NULL == n) {
-		PAIR_ID_INIT(&tag, h->buf);
-		print_otag(h, TAG_H1, 1, &tag);
+	if ((id = make_id(n)) != NULL) {
+		print_otag(h, TAG_H1, "ci", "Sh", id);
+		free(id);
 	} else
-		print_otag(h, TAG_H1, 0, NULL);
+		print_otag(h, TAG_H1, "c", "Sh");
 
 	return 1;
 }
@@ -561,28 +529,16 @@ mdoc_sh_pre(MDOC_ARGS)
 static int
 mdoc_ss_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag;
+	char	*id;
 
-	if (n->type == ROFFT_BLOCK) {
-		PAIR_CLASS_INIT(&tag, "subsection");
-		print_otag(h, TAG_DIV, 1, &tag);
-		return 1;
-	} else if (n->type == ROFFT_BODY)
+	if (n->type != ROFFT_HEAD)
 		return 1;
 
-	bufinit(h);
-
-	for (n = n->child; n != NULL && n->type == ROFFT_TEXT; ) {
-		bufcat_id(h, n->string);
-		if (NULL != (n = n->next))
-			bufcat_id(h, " ");
-	}
-
-	if (NULL == n) {
-		PAIR_ID_INIT(&tag, h->buf);
-		print_otag(h, TAG_H2, 1, &tag);
+	if ((id = make_id(n)) != NULL) {
+		print_otag(h, TAG_H2, "ci", "Ss", id);
+		free(id);
 	} else
-		print_otag(h, TAG_H2, 0, NULL);
+		print_otag(h, TAG_H2, "c", "Ss");
 
 	return 1;
 }
@@ -590,70 +546,61 @@ mdoc_ss_pre(MDOC_ARGS)
 static int
 mdoc_fl_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag;
-
-	PAIR_CLASS_INIT(&tag, "flag");
-	print_otag(h, TAG_B, 1, &tag);
-
-	/* `Cm' has no leading hyphen. */
-
-	if (MDOC_Cm == n->tok)
-		return 1;
-
+	print_otag(h, TAG_B, "c", "Fl");
 	print_text(h, "\\-");
 
 	if (!(n->child == NULL &&
 	    (n->next == NULL ||
 	     n->next->type == ROFFT_TEXT ||
-	     n->next->flags & MDOC_LINE)))
+	     n->next->flags & NODE_LINE)))
 		h->flags |= HTML_NOSPACE;
 
 	return 1;
 }
 
+static int
+mdoc_cm_pre(MDOC_ARGS)
+{
+	print_otag(h, TAG_B, "c", "Cm");
+	return 1;
+}
+
 static int
 mdoc_nd_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag;
-
 	if (n->type != ROFFT_BODY)
 		return 1;
 
 	/* XXX: this tag in theory can contain block elements. */
 
 	print_text(h, "\\(em");
-	PAIR_CLASS_INIT(&tag, "desc");
-	print_otag(h, TAG_SPAN, 1, &tag);
+	print_otag(h, TAG_SPAN, "c", "Nd");
 	return 1;
 }
 
 static int
 mdoc_nm_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag;
-	struct roffsu	 su;
 	int		 len;
 
 	switch (n->type) {
 	case ROFFT_HEAD:
-		print_otag(h, TAG_TD, 0, NULL);
+		print_otag(h, TAG_TD, "");
 		/* FALLTHROUGH */
 	case ROFFT_ELEM:
-		PAIR_CLASS_INIT(&tag, "name");
-		print_otag(h, TAG_B, 1, &tag);
+		print_otag(h, TAG_B, "c", "Nm");
 		if (n->child == NULL && meta->name != NULL)
 			print_text(h, meta->name);
 		return 1;
 	case ROFFT_BODY:
-		print_otag(h, TAG_TD, 0, NULL);
+		print_otag(h, TAG_TD, "");
 		return 1;
 	default:
 		break;
 	}
 
 	synopsis_pre(h, n);
-	PAIR_CLASS_INIT(&tag, "synopsis");
-	print_otag(h, TAG_TABLE, 1, &tag);
+	print_otag(h, TAG_TABLE, "c", "Nm");
 
 	for (len = 0, n = n->head->child; n; n = n->next)
 		if (n->type == ROFFT_TEXT)
@@ -662,35 +609,25 @@ mdoc_nm_pre(MDOC_ARGS)
 	if (len == 0 && meta->name != NULL)
 		len = html_strlen(meta->name);
 
-	SCALE_HS_INIT(&su, len);
-	bufinit(h);
-	bufcat_su(h, "width", &su);
-	PAIR_STYLE_INIT(&tag, h);
-	print_otag(h, TAG_COL, 1, &tag);
-	print_otag(h, TAG_COL, 0, NULL);
-	print_otag(h, TAG_TBODY, 0, NULL);
-	print_otag(h, TAG_TR, 0, NULL);
+	print_otag(h, TAG_COL, "shw", len);
+	print_otag(h, TAG_COL, "");
+	print_otag(h, TAG_TBODY, "");
+	print_otag(h, TAG_TR, "");
 	return 1;
 }
 
 static int
 mdoc_xr_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag[2];
-
 	if (NULL == n->child)
 		return 0;
 
-	PAIR_CLASS_INIT(&tag[0], "link-man");
-
-	if (h->base_man) {
-		buffmt_man(h, n->child->string,
-		    n->child->next ?
-		    n->child->next->string : NULL);
-		PAIR_HREF_INIT(&tag[1], h->buf);
-		print_otag(h, TAG_A, 2, tag);
-	} else
-		print_otag(h, TAG_A, 1, tag);
+	if (h->base_man)
+		print_otag(h, TAG_A, "chM", "Xr",
+		    n->child->string, n->child->next == NULL ?
+		    NULL : n->child->next->string);
+	else
+		print_otag(h, TAG_A, "c", "Xr");
 
 	n = n->child;
 	print_text(h, n->string);
@@ -711,7 +648,7 @@ static int
 mdoc_ns_pre(MDOC_ARGS)
 {
 
-	if ( ! (MDOC_LINE & n->flags))
+	if ( ! (NODE_LINE & n->flags))
 		h->flags |= HTML_NOSPACE;
 	return 1;
 }
@@ -719,174 +656,124 @@ mdoc_ns_pre(MDOC_ARGS)
 static int
 mdoc_ar_pre(MDOC_ARGS)
 {
-	struct htmlpair tag;
-
-	PAIR_CLASS_INIT(&tag, "arg");
-	print_otag(h, TAG_I, 1, &tag);
+	print_otag(h, TAG_I, "c", "Ar");
 	return 1;
 }
 
 static int
 mdoc_xx_pre(MDOC_ARGS)
 {
-	const char	*pp;
-	struct htmlpair	 tag;
-	int		 flags;
-
-	switch (n->tok) {
-	case MDOC_Bsx:
-		pp = "BSD/OS";
-		break;
-	case MDOC_Dx:
-		pp = "DragonFly";
-		break;
-	case MDOC_Fx:
-		pp = "FreeBSD";
-		break;
-	case MDOC_Nx:
-		pp = "NetBSD";
-		break;
-	case MDOC_Ox:
-		pp = "OpenBSD";
-		break;
-	case MDOC_Ux:
-		pp = "UNIX";
-		break;
-	default:
-		return 1;
-	}
-
-	PAIR_CLASS_INIT(&tag, "unix");
-	print_otag(h, TAG_SPAN, 1, &tag);
-
-	print_text(h, pp);
-	if (n->child) {
-		flags = h->flags;
-		h->flags |= HTML_KEEP;
-		print_text(h, n->child->string);
-		h->flags = flags;
-	}
-	return 0;
-}
-
-static int
-mdoc_bx_pre(MDOC_ARGS)
-{
-	struct htmlpair	 tag;
-
-	PAIR_CLASS_INIT(&tag, "unix");
-	print_otag(h, TAG_SPAN, 1, &tag);
-
-	if (NULL != (n = n->child)) {
-		print_text(h, n->string);
-		h->flags |= HTML_NOSPACE;
-		print_text(h, "BSD");
-	} else {
-		print_text(h, "BSD");
-		return 0;
-	}
-
-	if (NULL != (n = n->next)) {
-		h->flags |= HTML_NOSPACE;
-		print_text(h, "-");
-		h->flags |= HTML_NOSPACE;
-		print_text(h, n->string);
-	}
-
-	return 0;
+	print_otag(h, TAG_SPAN, "c", "Ux");
+	return 1;
 }
 
 static int
 mdoc_it_pre(MDOC_ARGS)
 {
-	struct roffsu	 su;
-	enum mdoc_list	 type;
-	struct htmlpair	 tag[2];
-	const struct roff_node *bl;
+	const struct roff_node	*bl;
+	const char		*cattr;
+	enum mdoc_list		 type;
 
 	bl = n->parent;
-	while (bl && MDOC_Bl != bl->tok)
+	while (bl != NULL && bl->tok != MDOC_Bl)
 		bl = bl->parent;
-
-	assert(bl);
-
 	type = bl->norm->Bl.type;
 
-	assert(lists[type]);
-	PAIR_CLASS_INIT(&tag[0], lists[type]);
+	switch (type) {
+	case LIST_bullet:
+		cattr = "It-bullet";
+		break;
+	case LIST_dash:
+	case LIST_hyphen:
+		cattr = "It-dash";
+		break;
+	case LIST_item:
+		cattr = "It-item";
+		break;
+	case LIST_enum:
+		cattr = "It-enum";
+		break;
+	case LIST_diag:
+		cattr = "It-diag";
+		break;
+	case LIST_hang:
+		cattr = "It-hang";
+		break;
+	case LIST_inset:
+		cattr = "It-inset";
+		break;
+	case LIST_ohang:
+		cattr = "It-ohang";
+		break;
+	case LIST_tag:
+		cattr = "It-tag";
+		break;
+	case LIST_column:
+		cattr = "It-column";
+		break;
+	default:
+		break;
+	}
 
-	bufinit(h);
-
-	if (n->type == ROFFT_HEAD) {
-		switch (type) {
-		case LIST_bullet:
-		case LIST_dash:
-		case LIST_item:
-		case LIST_hyphen:
-		case LIST_enum:
+	switch (type) {
+	case LIST_bullet:
+	case LIST_dash:
+	case LIST_hyphen:
+	case LIST_item:
+	case LIST_enum:
+		switch (n->type) {
+		case ROFFT_HEAD:
 			return 0;
-		case LIST_diag:
-		case LIST_hang:
-		case LIST_inset:
-		case LIST_ohang:
-		case LIST_tag:
-			SCALE_VS_INIT(&su, ! bl->norm->Bl.comp);
-			bufcat_su(h, "margin-top", &su);
-			PAIR_STYLE_INIT(&tag[1], h);
-			print_otag(h, TAG_DT, 2, tag);
-			if (LIST_diag != type)
-				break;
-			PAIR_CLASS_INIT(&tag[0], "diag");
-			print_otag(h, TAG_B, 1, tag);
-			break;
-		case LIST_column:
+		case ROFFT_BODY:
+			if (bl->norm->Bl.comp)
+				print_otag(h, TAG_LI, "csvt", cattr, 0);
+			else
+				print_otag(h, TAG_LI, "c", cattr);
 			break;
 		default:
 			break;
 		}
-	} else if (n->type == ROFFT_BODY) {
-		switch (type) {
-		case LIST_bullet:
-		case LIST_hyphen:
-		case LIST_dash:
-		case LIST_enum:
-		case LIST_item:
-			SCALE_VS_INIT(&su, ! bl->norm->Bl.comp);
-			bufcat_su(h, "margin-top", &su);
-			PAIR_STYLE_INIT(&tag[1], h);
-			print_otag(h, TAG_LI, 2, tag);
+		break;
+	case LIST_diag:
+	case LIST_hang:
+	case LIST_inset:
+	case LIST_ohang:
+	case LIST_tag:
+		switch (n->type) {
+		case ROFFT_HEAD:
+			if (bl->norm->Bl.comp)
+				print_otag(h, TAG_DT, "csvt", cattr, 0);
+			else
+				print_otag(h, TAG_DT, "c", cattr);
+			if (type == LIST_diag)
+				print_otag(h, TAG_B, "c", cattr);
 			break;
-		case LIST_diag:
-		case LIST_hang:
-		case LIST_inset:
-		case LIST_ohang:
-		case LIST_tag:
-			if (NULL == bl->norm->Bl.width) {
-				print_otag(h, TAG_DD, 1, tag);
-				break;
-			}
-			a2width(bl->norm->Bl.width, &su);
-			bufcat_su(h, "margin-left", &su);
-			PAIR_STYLE_INIT(&tag[1], h);
-			print_otag(h, TAG_DD, 2, tag);
-			break;
-		case LIST_column:
-			SCALE_VS_INIT(&su, ! bl->norm->Bl.comp);
-			bufcat_su(h, "margin-top", &su);
-			PAIR_STYLE_INIT(&tag[1], h);
-			print_otag(h, TAG_TD, 2, tag);
+		case ROFFT_BODY:
+			if (bl->norm->Bl.width == NULL)
+				print_otag(h, TAG_DD, "c", cattr);
+			else
+				print_otag(h, TAG_DD, "cswl", cattr,
+				    bl->norm->Bl.width);
 			break;
 		default:
 			break;
 		}
-	} else {
-		switch (type) {
-		case LIST_column:
-			print_otag(h, TAG_TR, 1, tag);
+		break;
+	case LIST_column:
+		switch (n->type) {
+		case ROFFT_HEAD:
+			break;
+		case ROFFT_BODY:
+			if (bl->norm->Bl.comp)
+				print_otag(h, TAG_TD, "csvt", cattr, 0);
+			else
+				print_otag(h, TAG_TD, "c", cattr);
 			break;
 		default:
-			break;
+			print_otag(h, TAG_TR, "c", cattr);
 		}
+	default:
+		break;
 	}
 
 	return 1;
@@ -895,14 +782,13 @@ mdoc_it_pre(MDOC_ARGS)
 static int
 mdoc_bl_pre(MDOC_ARGS)
 {
+	const char	*cattr;
 	int		 i;
-	struct htmlpair	 tag[3];
-	struct roffsu	 su;
-	char		 buf[BUFSIZ];
+	enum htmltag	 elemtype;
 
 	if (n->type == ROFFT_BODY) {
 		if (LIST_column == n->norm->Bl.type)
-			print_otag(h, TAG_TBODY, 0, NULL);
+			print_otag(h, TAG_TBODY, "");
 		return 1;
 	}
 
@@ -917,142 +803,92 @@ mdoc_bl_pre(MDOC_ARGS)
 		 * screen and we want to preserve that behaviour.
 		 */
 
-		for (i = 0; i < (int)n->norm->Bl.ncols; i++) {
-			bufinit(h);
-			a2width(n->norm->Bl.cols[i], &su);
-			if (i < (int)n->norm->Bl.ncols - 1)
-				bufcat_su(h, "width", &su);
-			else
-				bufcat_su(h, "min-width", &su);
-			PAIR_STYLE_INIT(&tag[0], h);
-			print_otag(h, TAG_COL, 1, tag);
-		}
+		for (i = 0; i < (int)n->norm->Bl.ncols - 1; i++)
+			print_otag(h, TAG_COL, "sww", n->norm->Bl.cols[i]);
+		print_otag(h, TAG_COL, "swW", n->norm->Bl.cols[i]);
 
 		return 0;
 	}
 
-	SCALE_VS_INIT(&su, 0);
-	bufinit(h);
-	bufcat_su(h, "margin-top", &su);
-	bufcat_su(h, "margin-bottom", &su);
-	PAIR_STYLE_INIT(&tag[0], h);
-
-	assert(lists[n->norm->Bl.type]);
-	(void)strlcpy(buf, "list ", BUFSIZ);
-	(void)strlcat(buf, lists[n->norm->Bl.type], BUFSIZ);
-	PAIR_INIT(&tag[1], ATTR_CLASS, buf);
-
-	/* Set the block's left-hand margin. */
-
-	if (n->norm->Bl.offs) {
-		a2width(n->norm->Bl.offs, &su);
-		bufcat_su(h, "margin-left", &su);
-	}
-
 	switch (n->norm->Bl.type) {
 	case LIST_bullet:
+		elemtype = TAG_UL;
+		cattr = "Bl-bullet";
+		break;
 	case LIST_dash:
 	case LIST_hyphen:
+		elemtype = TAG_UL;
+		cattr = "Bl-dash";
+		break;
 	case LIST_item:
-		print_otag(h, TAG_UL, 2, tag);
+		elemtype = TAG_UL;
+		cattr = "Bl-item";
 		break;
 	case LIST_enum:
-		print_otag(h, TAG_OL, 2, tag);
+		elemtype = TAG_OL;
+		cattr = "Bl-enum";
 		break;
 	case LIST_diag:
+		elemtype = TAG_DL;
+		cattr = "Bl-diag";
+		break;
 	case LIST_hang:
+		elemtype = TAG_DL;
+		cattr = "Bl-hang";
+		break;
 	case LIST_inset:
+		elemtype = TAG_DL;
+		cattr = "Bl-inset";
+		break;
 	case LIST_ohang:
+		elemtype = TAG_DL;
+		cattr = "Bl-ohang";
+		break;
 	case LIST_tag:
-		print_otag(h, TAG_DL, 2, tag);
+		elemtype = TAG_DL;
+		cattr = "Bl-tag";
 		break;
 	case LIST_column:
-		print_otag(h, TAG_TABLE, 2, tag);
+		elemtype = TAG_TABLE;
+		cattr = "Bl-column";
 		break;
 	default:
 		abort();
 	}
 
+	if (n->norm->Bl.offs)
+		print_otag(h, elemtype, "cswl", cattr, n->norm->Bl.offs);
+	else
+		print_otag(h, elemtype, "c", cattr);
+
 	return 1;
 }
 
 static int
 mdoc_ex_pre(MDOC_ARGS)
 {
-	struct htmlpair	  tag;
-	struct tag	 *t;
-	struct roff_node *nch;
-
 	if (n->prev)
-		print_otag(h, TAG_BR, 0, NULL);
-
-	PAIR_CLASS_INIT(&tag, "utility");
-
-	print_text(h, "The");
-
-	for (nch = n->child; nch != NULL; nch = nch->next) {
-		assert(nch->type == ROFFT_TEXT);
-
-		t = print_otag(h, TAG_B, 1, &tag);
-		print_text(h, nch->string);
-		print_tagq(h, t);
-
-		if (nch->next == NULL)
-			continue;
-
-		if (nch->prev != NULL || nch->next->next != NULL) {
-			h->flags |= HTML_NOSPACE;
-			print_text(h, ",");
-		}
-
-		if (nch->next->next == NULL)
-			print_text(h, "and");
-	}
-
-	if (n->child != NULL && n->child->next != NULL)
-		print_text(h, "utilities exit\\~0");
-	else
-		print_text(h, "utility exits\\~0");
-
-	print_text(h, "on success, and\\~>0 if an error occurs.");
-	return 0;
+		print_otag(h, TAG_BR, "");
+	return 1;
 }
 
 static int
 mdoc_em_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
-
-	PAIR_CLASS_INIT(&tag, "emph");
-	print_otag(h, TAG_SPAN, 1, &tag);
+	print_otag(h, TAG_I, "c", "Em");
 	return 1;
 }
 
 static int
 mdoc_d1_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag[2];
-	struct roffsu	 su;
-
 	if (n->type != ROFFT_BLOCK)
 		return 1;
 
-	SCALE_VS_INIT(&su, 0);
-	bufinit(h);
-	bufcat_su(h, "margin-top", &su);
-	bufcat_su(h, "margin-bottom", &su);
-	PAIR_STYLE_INIT(&tag[0], h);
-	print_otag(h, TAG_BLOCKQUOTE, 1, tag);
+	print_otag(h, TAG_DIV, "c", "D1");
 
-	/* BLOCKQUOTE needs a block body. */
-
-	PAIR_CLASS_INIT(&tag[0], "display");
-	print_otag(h, TAG_DIV, 1, tag);
-
-	if (MDOC_Dl == n->tok) {
-		PAIR_CLASS_INIT(&tag[0], "lit");
-		print_otag(h, TAG_CODE, 1, tag);
-	}
+	if (n->tok == MDOC_Dl)
+		print_otag(h, TAG_CODE, "c", "Li");
 
 	return 1;
 }
@@ -1060,32 +896,22 @@ mdoc_d1_pre(MDOC_ARGS)
 static int
 mdoc_sx_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag[2];
+	char	*id;
 
-	bufinit(h);
-	bufcat(h, "#");
+	if ((id = make_id(n)) != NULL) {
+		print_otag(h, TAG_A, "chR", "Sx", id);
+		free(id);
+	} else
+		print_otag(h, TAG_A, "c", "Sx");
 
-	for (n = n->child; n; ) {
-		bufcat_id(h, n->string);
-		if (NULL != (n = n->next))
-			bufcat_id(h, " ");
-	}
-
-	PAIR_CLASS_INIT(&tag[0], "link-sec");
-	PAIR_HREF_INIT(&tag[1], h->buf);
-
-	print_otag(h, TAG_I, 1, tag);
-	print_otag(h, TAG_A, 2, tag);
 	return 1;
 }
 
 static int
 mdoc_bd_pre(MDOC_ARGS)
 {
-	struct htmlpair		 tag[2];
-	int			 comp, sv;
+	int			 comp, offs, sv;
 	struct roff_node	*nn;
-	struct roffsu		 su;
 
 	if (n->type == ROFFT_HEAD)
 		return 0;
@@ -1109,27 +935,24 @@ mdoc_bd_pre(MDOC_ARGS)
 
 	if (n->norm->Bd.offs == NULL ||
 	    ! strcmp(n->norm->Bd.offs, "left"))
-		SCALE_HS_INIT(&su, 0);
+		offs = 0;
 	else if ( ! strcmp(n->norm->Bd.offs, "indent"))
-		SCALE_HS_INIT(&su, INDENT);
+		offs = INDENT;
 	else if ( ! strcmp(n->norm->Bd.offs, "indent-two"))
-		SCALE_HS_INIT(&su, INDENT * 2);
+		offs = INDENT * 2;
 	else
-		a2width(n->norm->Bd.offs, &su);
+		offs = -1;
 
-	bufinit(h);
-	bufcat_su(h, "margin-left", &su);
-	PAIR_STYLE_INIT(&tag[0], h);
+	if (offs == -1)
+		print_otag(h, TAG_DIV, "cswl", "Bd", n->norm->Bd.offs);
+	else
+		print_otag(h, TAG_DIV, "cshl", "Bd", offs);
 
-	if (DISP_unfilled != n->norm->Bd.type &&
-	    DISP_literal != n->norm->Bd.type) {
-		PAIR_CLASS_INIT(&tag[1], "display");
-		print_otag(h, TAG_DIV, 2, tag);
+	if (n->norm->Bd.type != DISP_unfilled &&
+	    n->norm->Bd.type != DISP_literal)
 		return 1;
-	}
 
-	PAIR_CLASS_INIT(&tag[1], "lit display");
-	print_otag(h, TAG_PRE, 2, tag);
+	print_otag(h, TAG_PRE, "c", "Li");
 
 	/* This can be recursive: save & set our literal state. */
 
@@ -1158,7 +981,7 @@ mdoc_bd_pre(MDOC_ARGS)
 			break;
 		}
 		if (h->flags & HTML_NONEWLINE ||
-		    (nn->next && ! (nn->next->flags & MDOC_LINE)))
+		    (nn->next && ! (nn->next->flags & NODE_LINE)))
 			continue;
 		else if (nn->next)
 			print_text(h, "\n");
@@ -1175,28 +998,20 @@ mdoc_bd_pre(MDOC_ARGS)
 static int
 mdoc_pa_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
-
-	PAIR_CLASS_INIT(&tag, "file");
-	print_otag(h, TAG_I, 1, &tag);
+	print_otag(h, TAG_I, "c", "Pa");
 	return 1;
 }
 
 static int
 mdoc_ad_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
-
-	PAIR_CLASS_INIT(&tag, "addr");
-	print_otag(h, TAG_I, 1, &tag);
+	print_otag(h, TAG_I, "c", "Ad");
 	return 1;
 }
 
 static int
 mdoc_an_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
-
 	if (n->norm->An.auth == AUTH_split) {
 		h->flags &= ~HTML_NOSPLIT;
 		h->flags |= HTML_SPLIT;
@@ -1209,54 +1024,41 @@ mdoc_an_pre(MDOC_ARGS)
 	}
 
 	if (h->flags & HTML_SPLIT)
-		print_otag(h, TAG_BR, 0, NULL);
+		print_otag(h, TAG_BR, "");
 
 	if (n->sec == SEC_AUTHORS && ! (h->flags & HTML_NOSPLIT))
 		h->flags |= HTML_SPLIT;
 
-	PAIR_CLASS_INIT(&tag, "author");
-	print_otag(h, TAG_SPAN, 1, &tag);
+	print_otag(h, TAG_SPAN, "c", "An");
 	return 1;
 }
 
 static int
 mdoc_cd_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
-
 	synopsis_pre(h, n);
-	PAIR_CLASS_INIT(&tag, "config");
-	print_otag(h, TAG_B, 1, &tag);
+	print_otag(h, TAG_B, "c", "Cd");
 	return 1;
 }
 
 static int
 mdoc_dv_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
-
-	PAIR_CLASS_INIT(&tag, "define");
-	print_otag(h, TAG_SPAN, 1, &tag);
+	print_otag(h, TAG_CODE, "c", "Dv");
 	return 1;
 }
 
 static int
 mdoc_ev_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
-
-	PAIR_CLASS_INIT(&tag, "env");
-	print_otag(h, TAG_SPAN, 1, &tag);
+	print_otag(h, TAG_CODE, "c", "Ev");
 	return 1;
 }
 
 static int
 mdoc_er_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
-
-	PAIR_CLASS_INIT(&tag, "errno");
-	print_otag(h, TAG_SPAN, 1, &tag);
+	print_otag(h, TAG_CODE, "c", "Er");
 	return 1;
 }
 
@@ -1264,17 +1066,15 @@ static int
 mdoc_fa_pre(MDOC_ARGS)
 {
 	const struct roff_node	*nn;
-	struct htmlpair		 tag;
 	struct tag		*t;
 
-	PAIR_CLASS_INIT(&tag, "farg");
 	if (n->parent->tok != MDOC_Fo) {
-		print_otag(h, TAG_I, 1, &tag);
+		print_otag(h, TAG_I, "c", "Fa");
 		return 1;
 	}
 
 	for (nn = n->child; nn; nn = nn->next) {
-		t = print_otag(h, TAG_I, 1, &tag);
+		t = print_otag(h, TAG_I, "c", "Fa");
 		print_text(h, nn->string);
 		print_tagq(h, t);
 		if (nn->next) {
@@ -1294,11 +1094,8 @@ mdoc_fa_pre(MDOC_ARGS)
 static int
 mdoc_fd_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag[2];
-	char		 buf[BUFSIZ];
-	size_t		 sz;
-	int		 i;
 	struct tag	*t;
+	char		*buf, *cp;
 
 	synopsis_pre(h, n);
 
@@ -1308,43 +1105,29 @@ mdoc_fd_pre(MDOC_ARGS)
 	assert(n->type == ROFFT_TEXT);
 
 	if (strcmp(n->string, "#include")) {
-		PAIR_CLASS_INIT(&tag[0], "macro");
-		print_otag(h, TAG_B, 1, tag);
+		print_otag(h, TAG_B, "c", "Fd");
 		return 1;
 	}
 
-	PAIR_CLASS_INIT(&tag[0], "includes");
-	print_otag(h, TAG_B, 1, tag);
+	print_otag(h, TAG_B, "c", "In");
 	print_text(h, n->string);
 
 	if (NULL != (n = n->next)) {
 		assert(n->type == ROFFT_TEXT);
 
-		/*
-		 * XXX This is broken and not easy to fix.
-		 * When using -Oincludes, truncation may occur.
-		 * Dynamic allocation wouldn't help because
-		 * passing long strings to buffmt_includes()
-		 * does not work either.
-		 */
-
-		strlcpy(buf, '<' == *n->string || '"' == *n->string ?
-		    n->string + 1 : n->string, BUFSIZ);
-
-		sz = strlen(buf);
-		if (sz && ('>' == buf[sz - 1] || '"' == buf[sz - 1]))
-			buf[sz - 1] = '\0';
-
-		PAIR_CLASS_INIT(&tag[0], "link-includes");
-
-		i = 1;
 		if (h->base_includes) {
-			buffmt_includes(h, buf);
-			PAIR_HREF_INIT(&tag[i], h->buf);
-			i++;
-		}
+			cp = n->string;
+			if (*cp == '<' || *cp == '"')
+				cp++;
+			buf = mandoc_strdup(cp);
+			cp = strchr(buf, '\0') - 1;
+			if (cp >= buf && (*cp == '>' || *cp == '"'))
+				*cp = '\0';
+			t = print_otag(h, TAG_A, "chI", "In", buf);
+			free(buf);
+		} else
+			t = print_otag(h, TAG_A, "c", "In");
 
-		t = print_otag(h, TAG_A, i, tag);
 		print_text(h, n->string);
 		print_tagq(h, t);
 
@@ -1362,8 +1145,6 @@ mdoc_fd_pre(MDOC_ARGS)
 static int
 mdoc_vt_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag;
-
 	if (n->type == ROFFT_BLOCK) {
 		synopsis_pre(h, n);
 		return 1;
@@ -1372,19 +1153,15 @@ mdoc_vt_pre(MDOC_ARGS)
 	} else if (n->type == ROFFT_HEAD)
 		return 0;
 
-	PAIR_CLASS_INIT(&tag, "type");
-	print_otag(h, TAG_SPAN, 1, &tag);
+	print_otag(h, TAG_I, "c", "Vt");
 	return 1;
 }
 
 static int
 mdoc_ft_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag;
-
 	synopsis_pre(h, n);
-	PAIR_CLASS_INIT(&tag, "ftype");
-	print_otag(h, TAG_I, 1, &tag);
+	print_otag(h, TAG_I, "c", "Ft");
 	return 1;
 }
 
@@ -1392,12 +1169,11 @@ static int
 mdoc_fn_pre(MDOC_ARGS)
 {
 	struct tag	*t;
-	struct htmlpair	 tag[2];
 	char		 nbuf[BUFSIZ];
 	const char	*sp, *ep;
-	int		 sz, i, pretty;
+	int		 sz, pretty;
 
-	pretty = MDOC_SYNPRETTY & n->flags;
+	pretty = NODE_SYNPRETTY & n->flags;
 	synopsis_pre(h, n);
 
 	/* Split apart into type and name. */
@@ -1406,8 +1182,7 @@ mdoc_fn_pre(MDOC_ARGS)
 
 	ep = strchr(sp, ' ');
 	if (NULL != ep) {
-		PAIR_CLASS_INIT(&tag[0], "ftype");
-		t = print_otag(h, TAG_I, 1, tag);
+		t = print_otag(h, TAG_I, "c", "Ft");
 
 		while (ep) {
 			sz = MIN((int)(ep - sp), BUFSIZ - 1);
@@ -1420,25 +1195,7 @@ mdoc_fn_pre(MDOC_ARGS)
 		print_tagq(h, t);
 	}
 
-	PAIR_CLASS_INIT(&tag[0], "fname");
-
-	/*
-	 * FIXME: only refer to IDs that we know exist.
-	 */
-
-#if 0
-	if (MDOC_SYNPRETTY & n->flags) {
-		nbuf[0] = '\0';
-		html_idcat(nbuf, sp, BUFSIZ);
-		PAIR_ID_INIT(&tag[1], nbuf);
-	} else {
-		strlcpy(nbuf, "#", BUFSIZ);
-		html_idcat(nbuf, sp, BUFSIZ);
-		PAIR_HREF_INIT(&tag[1], nbuf);
-	}
-#endif
-
-	t = print_otag(h, TAG_B, 1, tag);
+	t = print_otag(h, TAG_B, "c", "Fn");
 
 	if (sp)
 		print_text(h, sp);
@@ -1449,16 +1206,12 @@ mdoc_fn_pre(MDOC_ARGS)
 	print_text(h, "(");
 	h->flags |= HTML_NOSPACE;
 
-	PAIR_CLASS_INIT(&tag[0], "farg");
-	bufinit(h);
-	bufcat_style(h, "white-space", "nowrap");
-	PAIR_STYLE_INIT(&tag[1], h);
-
 	for (n = n->child->next; n; n = n->next) {
-		i = 1;
-		if (MDOC_SYNPRETTY & n->flags)
-			i = 2;
-		t = print_otag(h, TAG_I, i, tag);
+		if (NODE_SYNPRETTY & n->flags)
+			t = print_otag(h, TAG_I, "css?", "Fa",
+			    "white-space", "nowrap");
+		else
+			t = print_otag(h, TAG_I, "c", "Fa");
 		print_text(h, n->string);
 		print_tagq(h, t);
 		if (n->next) {
@@ -1514,7 +1267,6 @@ static int
 mdoc_sp_pre(MDOC_ARGS)
 {
 	struct roffsu	 su;
-	struct htmlpair	 tag;
 
 	SCALE_VS_INIT(&su, 1);
 
@@ -1528,10 +1280,7 @@ mdoc_sp_pre(MDOC_ARGS)
 	} else
 		su.scale = 0.0;
 
-	bufinit(h);
-	bufcat_su(h, "height", &su);
-	PAIR_STYLE_INIT(&tag, h);
-	print_otag(h, TAG_DIV, 1, &tag);
+	print_otag(h, TAG_DIV, "suh", &su);
 
 	/* So the div isn't empty: */
 	print_text(h, "\\~");
@@ -1543,17 +1292,12 @@ mdoc_sp_pre(MDOC_ARGS)
 static int
 mdoc_lk_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag[2];
-
 	if (NULL == (n = n->child))
 		return 0;
 
 	assert(n->type == ROFFT_TEXT);
 
-	PAIR_CLASS_INIT(&tag[0], "link-ext");
-	PAIR_HREF_INIT(&tag[1], n->string);
-
-	print_otag(h, TAG_A, 2, tag);
+	print_otag(h, TAG_A, "ch", "Lk", n->string);
 
 	if (NULL == n->next)
 		print_text(h, n->string);
@@ -1567,22 +1311,17 @@ mdoc_lk_pre(MDOC_ARGS)
 static int
 mdoc_mt_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag[2];
 	struct tag	*t;
-
-	PAIR_CLASS_INIT(&tag[0], "link-mail");
+	char		*cp;
 
 	for (n = n->child; n; n = n->next) {
 		assert(n->type == ROFFT_TEXT);
 
-		bufinit(h);
-		bufcat(h, "mailto:");
-		bufcat(h, n->string);
-
-		PAIR_HREF_INIT(&tag[1], h->buf);
-		t = print_otag(h, TAG_A, 2, tag);
+		mandoc_asprintf(&cp, "mailto:%s", n->string);
+		t = print_otag(h, TAG_A, "ch", "Mt", cp);
 		print_text(h, n->string);
 		print_tagq(h, t);
+		free(cp);
 	}
 
 	return 0;
@@ -1591,7 +1330,6 @@ mdoc_mt_pre(MDOC_ARGS)
 static int
 mdoc_fo_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag;
 	struct tag	*t;
 
 	if (n->type == ROFFT_BODY) {
@@ -1608,8 +1346,7 @@ mdoc_fo_pre(MDOC_ARGS)
 		return 0;
 
 	assert(n->child->string);
-	PAIR_CLASS_INIT(&tag, "fname");
-	t = print_otag(h, TAG_B, 1, &tag);
+	t = print_otag(h, TAG_B, "c", "Fn");
 	print_text(h, n->child->string);
 	print_tagq(h, t);
 	return 0;
@@ -1631,13 +1368,9 @@ static int
 mdoc_in_pre(MDOC_ARGS)
 {
 	struct tag	*t;
-	struct htmlpair	 tag[2];
-	int		 i;
 
 	synopsis_pre(h, n);
-
-	PAIR_CLASS_INIT(&tag[0], "includes");
-	print_otag(h, TAG_B, 1, tag);
+	print_otag(h, TAG_B, "c", "In");
 
 	/*
 	 * The first argument of the `In' gets special treatment as
@@ -1646,7 +1379,7 @@ mdoc_in_pre(MDOC_ARGS)
 	 * of no children.
 	 */
 
-	if (MDOC_SYNPRETTY & n->flags && MDOC_LINE & n->flags)
+	if (NODE_SYNPRETTY & n->flags && NODE_LINE & n->flags)
 		print_text(h, "#include");
 
 	print_text(h, "<");
@@ -1655,16 +1388,10 @@ mdoc_in_pre(MDOC_ARGS)
 	if (NULL != (n = n->child)) {
 		assert(n->type == ROFFT_TEXT);
 
-		PAIR_CLASS_INIT(&tag[0], "link-includes");
-
-		i = 1;
-		if (h->base_includes) {
-			buffmt_includes(h, n->string);
-			PAIR_HREF_INIT(&tag[i], h->buf);
-			i++;
-		}
-
-		t = print_otag(h, TAG_A, i, tag);
+		if (h->base_includes)
+			t = print_otag(h, TAG_A, "chI", "In", n->string);
+		else
+			t = print_otag(h, TAG_A, "c", "In");
 		print_text(h, n->string);
 		print_tagq(h, t);
 
@@ -1685,75 +1412,14 @@ mdoc_in_pre(MDOC_ARGS)
 static int
 mdoc_ic_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
-
-	PAIR_CLASS_INIT(&tag, "cmd");
-	print_otag(h, TAG_B, 1, &tag);
+	print_otag(h, TAG_B, "c", "Ic");
 	return 1;
 }
 
-static int
-mdoc_rv_pre(MDOC_ARGS)
-{
-	struct htmlpair	 tag;
-	struct tag	*t;
-	struct roff_node *nch;
-
-	if (n->prev)
-		print_otag(h, TAG_BR, 0, NULL);
-
-	PAIR_CLASS_INIT(&tag, "fname");
-
-	if (n->child != NULL) {
-		print_text(h, "The");
-
-		for (nch = n->child; nch != NULL; nch = nch->next) {
-			t = print_otag(h, TAG_B, 1, &tag);
-			print_text(h, nch->string);
-			print_tagq(h, t);
-
-			h->flags |= HTML_NOSPACE;
-			print_text(h, "()");
-
-			if (nch->next == NULL)
-				continue;
-
-			if (nch->prev != NULL || nch->next->next != NULL) {
-				h->flags |= HTML_NOSPACE;
-				print_text(h, ",");
-			}
-			if (nch->next->next == NULL)
-				print_text(h, "and");
-		}
-
-		if (n->child != NULL && n->child->next != NULL)
-			print_text(h, "functions return");
-		else
-			print_text(h, "function returns");
-
-		print_text(h, "the value\\~0 if successful;");
-	} else
-		print_text(h, "Upon successful completion,"
-                    " the value\\~0 is returned;");
-
-	print_text(h, "otherwise the value\\~\\-1 is returned"
-	   " and the global variable");
-
-	PAIR_CLASS_INIT(&tag, "var");
-	t = print_otag(h, TAG_B, 1, &tag);
-	print_text(h, "errno");
-	print_tagq(h, t);
-	print_text(h, "is set to indicate the error.");
-	return 0;
-}
-
 static int
 mdoc_va_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
-
-	PAIR_CLASS_INIT(&tag, "var");
-	print_otag(h, TAG_B, 1, &tag);
+	print_otag(h, TAG_I, "c", "Va");
 	return 1;
 }
 
@@ -1770,8 +1436,7 @@ mdoc_ap_pre(MDOC_ARGS)
 static int
 mdoc_bf_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag[2];
-	struct roffsu	 su;
+	const char	*cattr;
 
 	if (n->type == ROFFT_HEAD)
 		return 0;
@@ -1779,35 +1444,27 @@ mdoc_bf_pre(MDOC_ARGS)
 		return 1;
 
 	if (FONT_Em == n->norm->Bf.font)
-		PAIR_CLASS_INIT(&tag[0], "emph");
+		cattr = "Em";
 	else if (FONT_Sy == n->norm->Bf.font)
-		PAIR_CLASS_INIT(&tag[0], "symb");
+		cattr = "Sy";
 	else if (FONT_Li == n->norm->Bf.font)
-		PAIR_CLASS_INIT(&tag[0], "lit");
+		cattr = "Li";
 	else
-		PAIR_CLASS_INIT(&tag[0], "none");
+		cattr = "none";
 
 	/*
 	 * We want this to be inline-formatted, but needs to be div to
 	 * accept block children.
 	 */
-	bufinit(h);
-	bufcat_style(h, "display", "inline");
-	SCALE_HS_INIT(&su, 1);
-	/* Needs a left-margin for spacing. */
-	bufcat_su(h, "margin-left", &su);
-	PAIR_STYLE_INIT(&tag[1], h);
-	print_otag(h, TAG_DIV, 2, tag);
+
+	print_otag(h, TAG_DIV, "css?hl", cattr, "display", "inline", 1);
 	return 1;
 }
 
 static int
 mdoc_ms_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
-
-	PAIR_CLASS_INIT(&tag, "symb");
-	print_otag(h, TAG_SPAN, 1, &tag);
+	print_otag(h, TAG_B, "c", "Ms");
 	return 1;
 }
 
@@ -1823,154 +1480,116 @@ static void
 mdoc_pf_post(MDOC_ARGS)
 {
 
-	if ( ! (n->next == NULL || n->next->flags & MDOC_LINE))
+	if ( ! (n->next == NULL || n->next->flags & NODE_LINE))
 		h->flags |= HTML_NOSPACE;
 }
 
 static int
 mdoc_rs_pre(MDOC_ARGS)
 {
-	struct htmlpair	 tag;
-
 	if (n->type != ROFFT_BLOCK)
 		return 1;
 
 	if (n->prev && SEC_SEE_ALSO == n->sec)
 		print_paragraph(h);
 
-	PAIR_CLASS_INIT(&tag, "ref");
-	print_otag(h, TAG_SPAN, 1, &tag);
+	print_otag(h, TAG_SPAN, "c", "Rs");
 	return 1;
 }
 
 static int
 mdoc_no_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
-
-	PAIR_CLASS_INIT(&tag, "none");
-	print_otag(h, TAG_CODE, 1, &tag);
+	print_otag(h, TAG_SPAN, "c", "No");
 	return 1;
 }
 
 static int
 mdoc_li_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
-
-	PAIR_CLASS_INIT(&tag, "lit");
-	print_otag(h, TAG_CODE, 1, &tag);
+	print_otag(h, TAG_CODE, "c", "Li");
 	return 1;
 }
 
 static int
 mdoc_sy_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
-
-	PAIR_CLASS_INIT(&tag, "symb");
-	print_otag(h, TAG_SPAN, 1, &tag);
+	print_otag(h, TAG_B, "c", "Sy");
 	return 1;
 }
 
-static int
-mdoc_bt_pre(MDOC_ARGS)
-{
-
-	print_text(h, "is currently in beta test.");
-	return 0;
-}
-
-static int
-mdoc_ud_pre(MDOC_ARGS)
-{
-
-	print_text(h, "currently under development.");
-	return 0;
-}
-
 static int
 mdoc_lb_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
+	if (SEC_LIBRARY == n->sec && NODE_LINE & n->flags && n->prev)
+		print_otag(h, TAG_BR, "");
 
-	if (SEC_LIBRARY == n->sec && MDOC_LINE & n->flags && n->prev)
-		print_otag(h, TAG_BR, 0, NULL);
-
-	PAIR_CLASS_INIT(&tag, "lib");
-	print_otag(h, TAG_SPAN, 1, &tag);
+	print_otag(h, TAG_SPAN, "c", "Lb");
 	return 1;
 }
 
 static int
 mdoc__x_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag[2];
-	enum htmltag	t;
+	const char	*cattr;
+	enum htmltag	 t;
 
 	t = TAG_SPAN;
 
 	switch (n->tok) {
 	case MDOC__A:
-		PAIR_CLASS_INIT(&tag[0], "ref-auth");
+		cattr = "RsA";
 		if (n->prev && MDOC__A == n->prev->tok)
 			if (NULL == n->next || MDOC__A != n->next->tok)
 				print_text(h, "and");
 		break;
 	case MDOC__B:
-		PAIR_CLASS_INIT(&tag[0], "ref-book");
 		t = TAG_I;
+		cattr = "RsB";
 		break;
 	case MDOC__C:
-		PAIR_CLASS_INIT(&tag[0], "ref-city");
+		cattr = "RsC";
 		break;
 	case MDOC__D:
-		PAIR_CLASS_INIT(&tag[0], "ref-date");
+		cattr = "RsD";
 		break;
 	case MDOC__I:
-		PAIR_CLASS_INIT(&tag[0], "ref-issue");
 		t = TAG_I;
+		cattr = "RsI";
 		break;
 	case MDOC__J:
-		PAIR_CLASS_INIT(&tag[0], "ref-jrnl");
 		t = TAG_I;
+		cattr = "RsJ";
 		break;
 	case MDOC__N:
-		PAIR_CLASS_INIT(&tag[0], "ref-num");
+		cattr = "RsN";
 		break;
 	case MDOC__O:
-		PAIR_CLASS_INIT(&tag[0], "ref-opt");
+		cattr = "RsO";
 		break;
 	case MDOC__P:
-		PAIR_CLASS_INIT(&tag[0], "ref-page");
+		cattr = "RsP";
 		break;
 	case MDOC__Q:
-		PAIR_CLASS_INIT(&tag[0], "ref-corp");
+		cattr = "RsQ";
 		break;
 	case MDOC__R:
-		PAIR_CLASS_INIT(&tag[0], "ref-rep");
+		cattr = "RsR";
 		break;
 	case MDOC__T:
-		PAIR_CLASS_INIT(&tag[0], "ref-title");
+		cattr = "RsT";
 		break;
 	case MDOC__U:
-		PAIR_CLASS_INIT(&tag[0], "link-ref");
-		break;
+		print_otag(h, TAG_A, "ch", "RsU", n->child->string);
+		return 1;
 	case MDOC__V:
-		PAIR_CLASS_INIT(&tag[0], "ref-vol");
+		cattr = "RsV";
 		break;
 	default:
 		abort();
 	}
 
-	if (MDOC__U != n->tok) {
-		print_otag(h, t, 1, tag);
-		return 1;
-	}
-
-	PAIR_HREF_INIT(&tag[1], n->child->string);
-	print_otag(h, TAG_A, 2, tag);
-
+	print_otag(h, t, "c", cattr);
 	return 1;
 }
 
@@ -2023,8 +1642,6 @@ mdoc_bk_post(MDOC_ARGS)
 static int
 mdoc_quote_pre(MDOC_ARGS)
 {
-	struct htmlpair	tag;
-
 	if (n->type != ROFFT_BODY)
 		return 1;
 
@@ -2046,8 +1663,7 @@ mdoc_quote_pre(MDOC_ARGS)
 	case MDOC_Op:
 		print_text(h, "\\(lB");
 		h->flags |= HTML_NOSPACE;
-		PAIR_CLASS_INIT(&tag, "opt");
-		print_otag(h, TAG_SPAN, 1, &tag);
+		print_otag(h, TAG_SPAN, "c", "Op");
 		break;
 	case MDOC_En:
 		if (NULL == n->norm->Es ||
@@ -2068,8 +1684,7 @@ mdoc_quote_pre(MDOC_ARGS)
 	case MDOC_Ql:
 		print_text(h, "\\(oq");
 		h->flags |= HTML_NOSPACE;
-		PAIR_CLASS_INIT(&tag, "lit");
-		print_otag(h, TAG_CODE, 1, &tag);
+		print_otag(h, TAG_CODE, "c", "Li");
 		break;
 	case MDOC_So:
 	case MDOC_Sq:
diff --git a/contrib/mdocml/mdoc_macro.c b/contrib/mdocml/mdoc_macro.c
index ca959589acd..d4edcea1416 100644
--- a/contrib/mdocml/mdoc_macro.c
+++ b/contrib/mdocml/mdoc_macro.c
@@ -1,7 +1,7 @@
-/*	$Id: mdoc_macro.c,v 1.206 2015/10/20 02:01:32 schwarze Exp $ */
+/*	$Id: mdoc_macro.c,v 1.210 2017/01/10 13:47:00 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons 
- * Copyright (c) 2010, 2012-2015 Ingo Schwarze 
+ * Copyright (c) 2010, 2012-2016 Ingo Schwarze 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -216,7 +216,7 @@ mdoc_endparse(struct roff_man *mdoc)
 
 	/* Scan for open explicit scopes. */
 
-	n = mdoc->last->flags & MDOC_VALID ?
+	n = mdoc->last->flags & NODE_VALID ?
 	    mdoc->last->parent : mdoc->last;
 
 	for ( ; n; n = n->parent)
@@ -264,16 +264,16 @@ static void
 rew_last(struct roff_man *mdoc, const struct roff_node *to)
 {
 
-	if (to->flags & MDOC_VALID)
+	if (to->flags & NODE_VALID)
 		return;
 
 	while (mdoc->last != to) {
 		mdoc_state(mdoc, mdoc->last);
-		mdoc->last->flags |= MDOC_VALID | MDOC_ENDED;
+		mdoc->last->flags |= NODE_VALID | NODE_ENDED;
 		mdoc->last = mdoc->last->parent;
 	}
 	mdoc_state(mdoc, mdoc->last);
-	mdoc->last->flags |= MDOC_VALID | MDOC_ENDED;
+	mdoc->last->flags |= NODE_VALID | NODE_ENDED;
 	mdoc->next = ROFF_NEXT_SIBLING;
 }
 
@@ -292,13 +292,13 @@ rew_pending(struct roff_man *mdoc, const struct roff_node *n)
 			case ROFFT_HEAD:
 				roff_body_alloc(mdoc, n->line, n->pos,
 				    n->tok);
-				return;
+				break;
 			case ROFFT_BLOCK:
 				break;
 			default:
 				return;
 			}
-			if ( ! (n->flags & MDOC_BROKEN))
+			if ( ! (n->flags & NODE_BROKEN))
 				return;
 		} else
 			n = mdoc->last;
@@ -309,7 +309,7 @@ rew_pending(struct roff_man *mdoc, const struct roff_node *n)
 
 			if (n->type == ROFFT_BLOCK ||
 			    n->type == ROFFT_HEAD) {
-				if (n->flags & MDOC_ENDED)
+				if (n->flags & NODE_ENDED)
 					break;
 				else
 					return;
@@ -390,18 +390,18 @@ find_pending(struct roff_man *mdoc, int tok, int line, int ppos,
 
 	irc = 0;
 	for (n = mdoc->last; n != NULL && n != target; n = n->parent) {
-		if (n->flags & MDOC_ENDED) {
-			if ( ! (n->flags & MDOC_VALID))
-				n->flags |= MDOC_BROKEN;
+		if (n->flags & NODE_ENDED) {
+			if ( ! (n->flags & NODE_VALID))
+				n->flags |= NODE_BROKEN;
 			continue;
 		}
 		if (n->type == ROFFT_BLOCK &&
 		    mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
 			irc = 1;
-			n->flags = MDOC_BROKEN;
+			n->flags = NODE_BROKEN;
 			if (target->type == ROFFT_HEAD)
-				target->flags = MDOC_ENDED;
-			else if ( ! (target->flags & MDOC_ENDED)) {
+				target->flags = NODE_ENDED;
+			else if ( ! (target->flags & NODE_ENDED)) {
 				mandoc_vmsg(MANDOCERR_BLK_NEST,
 				    mdoc->parse, line, ppos,
 				    "%s breaks %s", mdoc_macronames[tok],
@@ -444,11 +444,11 @@ dword(struct roff_man *mdoc, int line, int col, const char *p,
 	 */
 
 	if (d == DELIM_OPEN)
-		mdoc->last->flags |= MDOC_DELIMO;
+		mdoc->last->flags |= NODE_DELIMO;
 	else if (d == DELIM_CLOSE &&
 	    ! (mdoc->flags & MDOC_NODELIMC) &&
 	    mdoc->last->parent->tok != MDOC_Fd)
-		mdoc->last->flags |= MDOC_DELIMC;
+		mdoc->last->flags |= NODE_DELIMC;
 	mdoc->flags &= ~MDOC_NODELIMC;
 }
 
@@ -481,7 +481,7 @@ append_delims(struct roff_man *mdoc, int line, int *pos, char *buf)
 		 */
 
 		if (mandoc_eos(p, strlen(p)))
-			mdoc->last->flags |= MDOC_EOS;
+			mdoc->last->flags |= NODE_EOS;
 	}
 }
 
@@ -549,29 +549,40 @@ blk_exp_close(MACRO_PROT_ARGS)
 		break;
 	}
 
+	/* Search backwards for the beginning of our own body. */
+
+	atok = rew_alt(tok);
+	body = NULL;
+	for (n = mdoc->last; n; n = n->parent) {
+		if (n->flags & NODE_ENDED || n->tok != atok ||
+		    n->type != ROFFT_BODY || n->end != ENDBODY_NOT)
+			continue;
+		body = n;
+		break;
+	}
+
 	/*
 	 * Search backwards for beginnings of blocks,
 	 * both of our own and of pending sub-blocks.
 	 */
 
-	atok = rew_alt(tok);
-	body = endbody = itblk = later = NULL;
+	endbody = itblk = later = NULL;
 	for (n = mdoc->last; n; n = n->parent) {
-		if (n->flags & MDOC_ENDED) {
-			if ( ! (n->flags & MDOC_VALID))
-				n->flags |= MDOC_BROKEN;
+		if (n->flags & NODE_ENDED) {
+			if ( ! (n->flags & NODE_VALID))
+				n->flags |= NODE_BROKEN;
 			continue;
 		}
 
-		/* Remember the start of our own body. */
+		/*
+		 * Mismatching end macros can never break anything,
+		 * SYNOPSIS name blocks can never be broken,
+		 * and we only care about the breaking of BLOCKs.
+		 */
 
-		if (n->type == ROFFT_BODY && atok == n->tok) {
-			if (n->end == ENDBODY_NOT)
-				body = n;
-			continue;
-		}
-
-		if (n->type != ROFFT_BLOCK || n->tok == MDOC_Nm)
+		if (body == NULL ||
+		    n->tok == MDOC_Nm ||
+		    n->type != ROFFT_BLOCK)
 			continue;
 
 		if (n->tok == MDOC_It) {
@@ -609,7 +620,7 @@ blk_exp_close(MACRO_PROT_ARGS)
 			    atok, body, ENDBODY_SPACE);
 
 			if (tok == MDOC_El)
-				itblk->flags |= MDOC_ENDED | MDOC_BROKEN;
+				itblk->flags |= NODE_ENDED | NODE_BROKEN;
 
 			/*
 			 * If a block closing macro taking arguments
@@ -631,7 +642,7 @@ blk_exp_close(MACRO_PROT_ARGS)
 
 		/* Breaking an open sub block. */
 
-		n->flags |= MDOC_BROKEN;
+		n->flags |= NODE_BROKEN;
 		if (later == NULL)
 			later = n;
 	}
@@ -639,8 +650,6 @@ blk_exp_close(MACRO_PROT_ARGS)
 	if (body == NULL) {
 		mandoc_msg(MANDOCERR_BLK_NOTOPEN, mdoc->parse,
 		    line, ppos, mdoc_macronames[tok]);
-		if (later != NULL)
-			later->flags &= ~MDOC_BROKEN;
 		if (maxargs && endbody == NULL) {
 			/*
 			 * Stray .Ec without previous .Eo:
@@ -697,11 +706,11 @@ blk_exp_close(MACRO_PROT_ARGS)
 	}
 
 	if (n != NULL) {
-		if (ntok != TOKEN_NONE && n->flags & MDOC_BROKEN) {
+		if (ntok != TOKEN_NONE && n->flags & NODE_BROKEN) {
 			target = n;
 			do
 				target = target->parent;
-			while ( ! (target->flags & MDOC_ENDED));
+			while ( ! (target->flags & NODE_ENDED));
 			pending = find_pending(mdoc, ntok, line, ppos,
 			    target);
 		} else
@@ -760,7 +769,7 @@ in_line(MACRO_PROT_ARGS)
 
 		if (ac == ARGS_EOLN) {
 			if (d == DELIM_OPEN)
-				mdoc->last->flags &= ~MDOC_DELIMO;
+				mdoc->last->flags &= ~NODE_DELIMO;
 			break;
 		}
 
@@ -854,7 +863,7 @@ in_line(MACRO_PROT_ARGS)
 		 */
 
 		if (firstarg && d == DELIM_CLOSE && !nc)
-			mdoc->last->flags &= ~MDOC_DELIMC;
+			mdoc->last->flags &= ~NODE_DELIMC;
 		firstarg = 0;
 
 		/*
@@ -917,9 +926,9 @@ blk_full(MACRO_PROT_ARGS)
 
 		blk = NULL;
 		for (n = mdoc->last; n != NULL; n = n->parent) {
-			if (n->flags & MDOC_ENDED) {
-				if ( ! (n->flags & MDOC_VALID))
-					n->flags |= MDOC_BROKEN;
+			if (n->flags & NODE_ENDED) {
+				if ( ! (n->flags & NODE_VALID))
+					n->flags |= NODE_BROKEN;
 				continue;
 			}
 			if (n->type != ROFFT_BLOCK)
@@ -1120,7 +1129,7 @@ blk_full(MACRO_PROT_ARGS)
 			break;
 	}
 
-	if (blk->flags & MDOC_VALID)
+	if (blk->flags & NODE_VALID)
 		return;
 	if (head == NULL)
 		head = roff_head_alloc(mdoc, line, ppos, tok);
@@ -1455,11 +1464,11 @@ phrase_ta(MACRO_PROT_ARGS)
 
 	body = NULL;
 	for (n = mdoc->last; n != NULL; n = n->parent) {
-		if (n->flags & MDOC_ENDED)
+		if (n->flags & NODE_ENDED)
 			continue;
 		if (n->tok == MDOC_It && n->type == ROFFT_BODY)
 			body = n;
-		if (n->tok == MDOC_Bl)
+		if (n->tok == MDOC_Bl && n->end == ENDBODY_NOT)
 			break;
 	}
 
diff --git a/contrib/mdocml/mdoc_man.c b/contrib/mdocml/mdoc_man.c
index ab245313492..2c19e15fb8b 100644
--- a/contrib/mdocml/mdoc_man.c
+++ b/contrib/mdocml/mdoc_man.c
@@ -1,6 +1,6 @@
-/*	$Id: mdoc_man.c,v 1.96 2016/01/08 17:48:09 schwarze Exp $ */
+/*	$Id: mdoc_man.c,v 1.101 2017/01/11 17:39:53 schwarze Exp $ */
 /*
- * Copyright (c) 2011-2016 Ingo Schwarze 
+ * Copyright (c) 2011-2017 Ingo Schwarze 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -79,7 +79,6 @@ static	int	  pre_bf(DECL_ARGS);
 static	int	  pre_bk(DECL_ARGS);
 static	int	  pre_bl(DECL_ARGS);
 static	int	  pre_br(DECL_ARGS);
-static	int	  pre_bx(DECL_ARGS);
 static	int	  pre_dl(DECL_ARGS);
 static	int	  pre_en(DECL_ARGS);
 static	int	  pre_enc(DECL_ARGS);
@@ -103,14 +102,12 @@ static	int	  pre_no(DECL_ARGS);
 static	int	  pre_ns(DECL_ARGS);
 static	int	  pre_pp(DECL_ARGS);
 static	int	  pre_rs(DECL_ARGS);
-static	int	  pre_rv(DECL_ARGS);
 static	int	  pre_sm(DECL_ARGS);
 static	int	  pre_sp(DECL_ARGS);
 static	int	  pre_sect(DECL_ARGS);
 static	int	  pre_sy(DECL_ARGS);
 static	void	  pre_syn(const struct roff_node *);
 static	int	  pre_vt(DECL_ARGS);
-static	int	  pre_ux(DECL_ARGS);
 static	int	  pre_xr(DECL_ARGS);
 static	void	  print_word(const char *);
 static	void	  print_line(const char *, int);
@@ -158,7 +155,7 @@ static	const struct manact manacts[MDOC_MAX + 1] = {
 	{ cond_body, pre_enc, post_enc, "[", "]" }, /* Op */
 	{ NULL, pre_ft, post_font, NULL, NULL }, /* Ot */
 	{ NULL, pre_em, post_font, NULL, NULL }, /* Pa */
-	{ NULL, pre_rv, NULL, NULL, NULL }, /* Rv */
+	{ NULL, pre_ex, NULL, NULL, NULL }, /* Rv */
 	{ NULL, NULL, NULL, NULL, NULL }, /* St */
 	{ NULL, pre_em, post_font, NULL, NULL }, /* Va */
 	{ NULL, pre_vt, post_vt, NULL, NULL }, /* Vt */
@@ -182,8 +179,8 @@ static	const struct manact manacts[MDOC_MAX + 1] = {
 	{ NULL, pre_bf, post_bf, NULL, NULL }, /* Bf */
 	{ cond_body, pre_enc, post_enc, "[", "]" }, /* Bo */
 	{ cond_body, pre_enc, post_enc, "[", "]" }, /* Bq */
-	{ NULL, pre_ux, NULL, "BSD/OS", NULL }, /* Bsx */
-	{ NULL, pre_bx, NULL, NULL, NULL }, /* Bx */
+	{ NULL, NULL, NULL, NULL, NULL }, /* Bsx */
+	{ NULL, NULL, NULL, NULL, NULL }, /* Bx */
 	{ NULL, pre_skip, NULL, NULL, NULL }, /* Db */
 	{ NULL, NULL, NULL, NULL, NULL }, /* Dc */
 	{ cond_body, pre_enc, post_enc, "\\(Lq", "\\(Rq" }, /* Do */
@@ -192,12 +189,12 @@ static	const struct manact manacts[MDOC_MAX + 1] = {
 	{ NULL, NULL, NULL, NULL, NULL }, /* Ef */
 	{ NULL, pre_em, post_font, NULL, NULL }, /* Em */
 	{ cond_body, pre_eo, post_eo, NULL, NULL }, /* Eo */
-	{ NULL, pre_ux, NULL, "FreeBSD", NULL }, /* Fx */
+	{ NULL, NULL, NULL, NULL, NULL }, /* Fx */
 	{ NULL, pre_sy, post_font, NULL, NULL }, /* Ms */
 	{ NULL, pre_no, NULL, NULL, NULL }, /* No */
 	{ NULL, pre_ns, NULL, NULL, NULL }, /* Ns */
-	{ NULL, pre_ux, NULL, "NetBSD", NULL }, /* Nx */
-	{ NULL, pre_ux, NULL, "OpenBSD", NULL }, /* Ox */
+	{ NULL, NULL, NULL, NULL, NULL }, /* Nx */
+	{ NULL, NULL, NULL, NULL, NULL }, /* Ox */
 	{ NULL, NULL, NULL, NULL, NULL }, /* Pc */
 	{ NULL, NULL, post_pf, NULL, NULL }, /* Pf */
 	{ cond_body, pre_enc, post_enc, "(", ")" }, /* Po */
@@ -215,7 +212,7 @@ static	const struct manact manacts[MDOC_MAX + 1] = {
 	{ NULL, pre_em, post_font, NULL, NULL }, /* Sx */
 	{ NULL, pre_sy, post_font, NULL, NULL }, /* Sy */
 	{ NULL, pre_li, post_font, NULL, NULL }, /* Tn */
-	{ NULL, pre_ux, NULL, "UNIX", NULL }, /* Ux */
+	{ NULL, NULL, NULL, NULL, NULL }, /* Ux */
 	{ NULL, NULL, NULL, NULL, NULL }, /* Xc */
 	{ NULL, NULL, NULL, NULL, NULL }, /* Xo */
 	{ NULL, pre_fo, post_fo, NULL, NULL }, /* Fo */
@@ -224,10 +221,10 @@ static	const struct manact manacts[MDOC_MAX + 1] = {
 	{ NULL, NULL, NULL, NULL, NULL }, /* Oc */
 	{ NULL, pre_bk, post_bk, NULL, NULL }, /* Bk */
 	{ NULL, NULL, NULL, NULL, NULL }, /* Ek */
-	{ NULL, pre_ux, NULL, "is currently in beta test.", NULL }, /* Bt */
+	{ NULL, NULL, NULL, NULL, NULL }, /* Bt */
 	{ NULL, NULL, NULL, NULL, NULL }, /* Hf */
 	{ NULL, pre_em, post_font, NULL, NULL }, /* Fr */
-	{ NULL, pre_ux, NULL, "currently under development.", NULL }, /* Ud */
+	{ NULL, NULL, NULL, NULL, NULL }, /* Ud */
 	{ NULL, NULL, post_lb, NULL, NULL }, /* Lb */
 	{ NULL, pre_pp, NULL, NULL, NULL }, /* Lp */
 	{ NULL, pre_lk, NULL, NULL, NULL }, /* Lk */
@@ -238,7 +235,7 @@ static	const struct manact manacts[MDOC_MAX + 1] = {
 	{ NULL, NULL, post_percent, NULL, NULL }, /* %C */
 	{ NULL, pre_skip, NULL, NULL, NULL }, /* Es */
 	{ cond_body, pre_en, post_en, NULL, NULL }, /* En */
-	{ NULL, pre_ux, NULL, "DragonFly", NULL }, /* Dx */
+	{ NULL, NULL, NULL, NULL, NULL }, /* Dx */
 	{ NULL, NULL, post_percent, NULL, NULL }, /* %Q */
 	{ NULL, pre_br, NULL, NULL, NULL }, /* br */
 	{ NULL, pre_sp, post_sp, NULL, NULL }, /* sp */
@@ -575,17 +572,20 @@ print_node(DECL_ARGS)
 	struct roff_node	*sub;
 	int			 cond, do_sub;
 
+	if (n->flags & NODE_NOPRT)
+		return;
+
 	/*
 	 * Break the line if we were parsed subsequent the current node.
 	 * This makes the page structure be more consistent.
 	 */
-	if (MMAN_spc & outflags && MDOC_LINE & n->flags)
+	if (MMAN_spc & outflags && NODE_LINE & n->flags)
 		outflags |= MMAN_nl;
 
 	act = NULL;
 	cond = 0;
 	do_sub = 1;
-	n->flags &= ~MDOC_ENDED;
+	n->flags &= ~NODE_ENDED;
 
 	if (n->type == ROFFT_TEXT) {
 		/*
@@ -598,10 +598,14 @@ print_node(DECL_ARGS)
 			printf("\\&");
 			outflags &= ~MMAN_spc;
 		}
-		if (outflags & MMAN_Sm && ! (n->flags & MDOC_DELIMC))
+		if (n->flags & NODE_DELIMC)
+			outflags &= ~(MMAN_spc | MMAN_spc_force);
+		else if (outflags & MMAN_Sm)
 			outflags |= MMAN_spc_force;
 		print_word(n->string);
-		if (outflags & MMAN_Sm && ! (n->flags & MDOC_DELIMO))
+		if (n->flags & NODE_DELIMO)
+			outflags &= ~(MMAN_spc | MMAN_spc_force);
+		else if (outflags & MMAN_Sm)
 			outflags |= MMAN_spc;
 	} else {
 		/*
@@ -627,14 +631,14 @@ print_node(DECL_ARGS)
 	/*
 	 * Lastly, conditionally run the post-node handler.
 	 */
-	if (MDOC_ENDED & n->flags)
+	if (NODE_ENDED & n->flags)
 		return;
 
 	if (cond && act->post)
 		(*act->post)(meta, n);
 
 	if (ENDBODY_NOT != n->end)
-		n->body->flags |= MDOC_ENDED;
+		n->body->flags |= NODE_ENDED;
 
 	if (ENDBODY_NOSPACE == n->end)
 		outflags &= ~(MMAN_spc | MMAN_nl);
@@ -682,36 +686,8 @@ post_enc(DECL_ARGS)
 static int
 pre_ex(DECL_ARGS)
 {
-	struct roff_node *nch;
-
 	outflags |= MMAN_br | MMAN_nl;
-
-	print_word("The");
-
-	for (nch = n->child; nch != NULL; nch = nch->next) {
-		font_push('B');
-		print_word(nch->string);
-		font_pop();
-
-		if (nch->next == NULL)
-			continue;
-
-		if (nch->prev != NULL || nch->next->next != NULL) {
-			outflags &= ~MMAN_spc;
-			print_word(",");
-		}
-		if (nch->next->next == NULL)
-			print_word("and");
-	}
-
-	if (n->child != NULL && n->child->next != NULL)
-		print_word("utilities exit\\~0");
-	else
-		print_word("utility exits\\~0");
-
-	print_word("on success, and\\~>0 if an error occurs.");
-	outflags |= MMAN_nl;
-	return 0;
+	return 1;
 }
 
 static void
@@ -805,7 +781,7 @@ static void
 pre_syn(const struct roff_node *n)
 {
 
-	if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags))
+	if (NULL == n->prev || ! (NODE_SYNPRETTY & n->flags))
 		return;
 
 	if (n->prev->tok == n->tok &&
@@ -1050,26 +1026,6 @@ pre_br(DECL_ARGS)
 	return 0;
 }
 
-static int
-pre_bx(DECL_ARGS)
-{
-
-	n = n->child;
-	if (n) {
-		print_word(n->string);
-		outflags &= ~MMAN_spc;
-		n = n->next;
-	}
-	print_word("BSD");
-	if (NULL == n)
-		return 0;
-	outflags &= ~MMAN_spc;
-	print_word("-");
-	outflags &= ~MMAN_spc;
-	print_word(n->string);
-	return 0;
-}
-
 static int
 pre_dl(DECL_ARGS)
 {
@@ -1173,7 +1129,7 @@ pre_fa(DECL_ARGS)
 
 	while (NULL != n) {
 		font_push('I');
-		if (am_Fa || MDOC_SYNPRETTY & n->flags)
+		if (am_Fa || NODE_SYNPRETTY & n->flags)
 			outflags |= MMAN_nbrword;
 		print_node(meta, n);
 		font_pop();
@@ -1227,7 +1183,7 @@ post_fl(DECL_ARGS)
 	if (!(n->child != NULL ||
 	    n->next == NULL ||
 	    n->next->type == ROFFT_TEXT ||
-	    n->next->flags & MDOC_LINE))
+	    n->next->flags & NODE_LINE))
 		outflags &= ~MMAN_spc;
 }
 
@@ -1241,7 +1197,7 @@ pre_fn(DECL_ARGS)
 	if (NULL == n)
 		return 0;
 
-	if (MDOC_SYNPRETTY & n->flags)
+	if (NODE_SYNPRETTY & n->flags)
 		print_block(".HP 4n", MMAN_nl);
 
 	font_push('B');
@@ -1262,7 +1218,7 @@ post_fn(DECL_ARGS)
 {
 
 	print_word(")");
-	if (MDOC_SYNPRETTY & n->flags) {
+	if (NODE_SYNPRETTY & n->flags) {
 		print_word(";");
 		outflags |= MMAN_PP;
 	}
@@ -1279,7 +1235,7 @@ pre_fo(DECL_ARGS)
 	case ROFFT_HEAD:
 		if (n->child == NULL)
 			return 0;
-		if (MDOC_SYNPRETTY & n->flags)
+		if (NODE_SYNPRETTY & n->flags)
 			print_block(".HP 4n", MMAN_nl);
 		font_push('B');
 		break;
@@ -1324,7 +1280,7 @@ static int
 pre_in(DECL_ARGS)
 {
 
-	if (MDOC_SYNPRETTY & n->flags) {
+	if (NODE_SYNPRETTY & n->flags) {
 		pre_syn(n);
 		font_push('B');
 		print_word("#include <");
@@ -1341,7 +1297,7 @@ static void
 post_in(DECL_ARGS)
 {
 
-	if (MDOC_SYNPRETTY & n->flags) {
+	if (NODE_SYNPRETTY & n->flags) {
 		outflags &= ~MMAN_spc;
 		print_word(">");
 		font_pop();
@@ -1616,7 +1572,7 @@ static void
 post_pf(DECL_ARGS)
 {
 
-	if ( ! (n->next == NULL || n->next->flags & MDOC_LINE))
+	if ( ! (n->next == NULL || n->next->flags & NODE_LINE))
 		outflags &= ~MMAN_spc;
 }
 
@@ -1642,57 +1598,6 @@ pre_rs(DECL_ARGS)
 	return 1;
 }
 
-static int
-pre_rv(DECL_ARGS)
-{
-	struct roff_node *nch;
-
-	outflags |= MMAN_br | MMAN_nl;
-
-	if (n->child != NULL) {
-		print_word("The");
-
-		for (nch = n->child; nch != NULL; nch = nch->next) {
-			font_push('B');
-			print_word(nch->string);
-			font_pop();
-
-			outflags &= ~MMAN_spc;
-			print_word("()");
-
-			if (nch->next == NULL)
-				continue;
-
-			if (nch->prev != NULL || nch->next->next != NULL) {
-				outflags &= ~MMAN_spc;
-				print_word(",");
-			}
-			if (nch->next->next == NULL)
-				print_word("and");
-		}
-
-		if (n->child != NULL && n->child->next != NULL)
-			print_word("functions return");
-		else
-			print_word("function returns");
-
-		print_word("the value\\~0 if successful;");
-	} else
-		print_word("Upon successful completion, "
-		    "the value\\~0 is returned;");
-
-	print_word("otherwise the value\\~\\-1 is returned"
-	    " and the global variable");
-
-	font_push('I');
-	print_word("errno");
-	font_pop();
-
-	print_word("is set to indicate the error.");
-	outflags |= MMAN_nl;
-	return 0;
-}
-
 static int
 pre_skip(DECL_ARGS)
 {
@@ -1748,7 +1653,7 @@ static int
 pre_vt(DECL_ARGS)
 {
 
-	if (MDOC_SYNPRETTY & n->flags) {
+	if (NODE_SYNPRETTY & n->flags) {
 		switch (n->type) {
 		case ROFFT_BLOCK:
 			pre_syn(n);
@@ -1767,7 +1672,7 @@ static void
 post_vt(DECL_ARGS)
 {
 
-	if (n->flags & MDOC_SYNPRETTY && n->type != ROFFT_BODY)
+	if (n->flags & NODE_SYNPRETTY && n->type != ROFFT_BODY)
 		return;
 	font_pop();
 }
@@ -1789,16 +1694,3 @@ pre_xr(DECL_ARGS)
 	print_word(")");
 	return 0;
 }
-
-static int
-pre_ux(DECL_ARGS)
-{
-
-	print_word(manacts[n->tok].prefix);
-	if (NULL == n->child)
-		return 0;
-	outflags &= ~MMAN_spc;
-	print_word("\\ ");
-	outflags &= ~MMAN_spc;
-	return 1;
-}
diff --git a/contrib/mdocml/mdoc_state.c b/contrib/mdocml/mdoc_state.c
index cbd7376309e..4e376ef0734 100644
--- a/contrib/mdocml/mdoc_state.c
+++ b/contrib/mdocml/mdoc_state.c
@@ -1,4 +1,4 @@
-/*	$Id: mdoc_state.c,v 1.3 2015/10/30 18:53:54 schwarze Exp $ */
+/*	$Id: mdoc_state.c,v 1.4 2017/01/10 13:47:00 schwarze Exp $ */
 /*
  * Copyright (c) 2014, 2015 Ingo Schwarze 
  *
@@ -249,7 +249,7 @@ state_sh(STATE_ARGS)
 	if (n->type != ROFFT_HEAD)
 		return;
 
-	if ( ! (n->flags & MDOC_VALID)) {
+	if ( ! (n->flags & NODE_VALID)) {
 		secname = NULL;
 		deroff(&secname, n);
 
diff --git a/contrib/mdocml/mdoc_term.c b/contrib/mdocml/mdoc_term.c
index e846436273d..dad54c8c44f 100644
--- a/contrib/mdocml/mdoc_term.c
+++ b/contrib/mdocml/mdoc_term.c
@@ -1,7 +1,7 @@
-/*	$Id: mdoc_term.c,v 1.331 2016/01/08 17:48:09 schwarze Exp $ */
+/*	$Id: mdoc_term.c,v 1.341 2017/01/11 17:39:53 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons 
- * Copyright (c) 2010, 2012-2016 Ingo Schwarze 
+ * Copyright (c) 2010, 2012-2017 Ingo Schwarze 
  * Copyright (c) 2013 Franco Fichtner 
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -80,6 +80,7 @@ static	void	  termp_pf_post(DECL_ARGS);
 static	void	  termp_quote_post(DECL_ARGS);
 static	void	  termp_sh_post(DECL_ARGS);
 static	void	  termp_ss_post(DECL_ARGS);
+static	void	  termp_xx_post(DECL_ARGS);
 
 static	int	  termp__a_pre(DECL_ARGS);
 static	int	  termp__t_pre(DECL_ARGS);
@@ -90,11 +91,10 @@ static	int	  termp_bf_pre(DECL_ARGS);
 static	int	  termp_bk_pre(DECL_ARGS);
 static	int	  termp_bl_pre(DECL_ARGS);
 static	int	  termp_bold_pre(DECL_ARGS);
-static	int	  termp_bt_pre(DECL_ARGS);
-static	int	  termp_bx_pre(DECL_ARGS);
 static	int	  termp_cd_pre(DECL_ARGS);
 static	int	  termp_d1_pre(DECL_ARGS);
 static	int	  termp_eo_pre(DECL_ARGS);
+static	int	  termp_em_pre(DECL_ARGS);
 static	int	  termp_er_pre(DECL_ARGS);
 static	int	  termp_ex_pre(DECL_ARGS);
 static	int	  termp_fa_pre(DECL_ARGS);
@@ -113,15 +113,14 @@ static	int	  termp_nm_pre(DECL_ARGS);
 static	int	  termp_ns_pre(DECL_ARGS);
 static	int	  termp_quote_pre(DECL_ARGS);
 static	int	  termp_rs_pre(DECL_ARGS);
-static	int	  termp_rv_pre(DECL_ARGS);
 static	int	  termp_sh_pre(DECL_ARGS);
 static	int	  termp_skip_pre(DECL_ARGS);
 static	int	  termp_sm_pre(DECL_ARGS);
 static	int	  termp_sp_pre(DECL_ARGS);
 static	int	  termp_ss_pre(DECL_ARGS);
+static	int	  termp_sy_pre(DECL_ARGS);
 static	int	  termp_tag_pre(DECL_ARGS);
 static	int	  termp_under_pre(DECL_ARGS);
-static	int	  termp_ud_pre(DECL_ARGS);
 static	int	  termp_vt_pre(DECL_ARGS);
 static	int	  termp_xr_pre(DECL_ARGS);
 static	int	  termp_xx_pre(DECL_ARGS);
@@ -163,7 +162,7 @@ static	const struct termact termacts[MDOC_MAX] = {
 	{ termp_quote_pre, termp_quote_post }, /* Op */
 	{ termp_ft_pre, NULL }, /* Ot */
 	{ termp_under_pre, NULL }, /* Pa */
-	{ termp_rv_pre, NULL }, /* Rv */
+	{ termp_ex_pre, NULL }, /* Rv */
 	{ NULL, NULL }, /* St */
 	{ termp_under_pre, NULL }, /* Va */
 	{ termp_vt_pre, NULL }, /* Vt */
@@ -187,22 +186,22 @@ static	const struct termact termacts[MDOC_MAX] = {
 	{ termp_bf_pre, NULL }, /* Bf */
 	{ termp_quote_pre, termp_quote_post }, /* Bo */
 	{ termp_quote_pre, termp_quote_post }, /* Bq */
-	{ termp_xx_pre, NULL }, /* Bsx */
-	{ termp_bx_pre, NULL }, /* Bx */
+	{ termp_xx_pre, termp_xx_post }, /* Bsx */
+	{ NULL, NULL }, /* Bx */
 	{ termp_skip_pre, NULL }, /* Db */
 	{ NULL, NULL }, /* Dc */
 	{ termp_quote_pre, termp_quote_post }, /* Do */
 	{ termp_quote_pre, termp_quote_post }, /* Dq */
 	{ NULL, NULL }, /* Ec */ /* FIXME: no space */
 	{ NULL, NULL }, /* Ef */
-	{ termp_under_pre, NULL }, /* Em */
+	{ termp_em_pre, NULL }, /* Em */
 	{ termp_eo_pre, termp_eo_post }, /* Eo */
-	{ termp_xx_pre, NULL }, /* Fx */
+	{ termp_xx_pre, termp_xx_post }, /* Fx */
 	{ termp_bold_pre, NULL }, /* Ms */
 	{ termp_li_pre, NULL }, /* No */
 	{ termp_ns_pre, NULL }, /* Ns */
-	{ termp_xx_pre, NULL }, /* Nx */
-	{ termp_xx_pre, NULL }, /* Ox */
+	{ termp_xx_pre, termp_xx_post }, /* Nx */
+	{ termp_xx_pre, termp_xx_post }, /* Ox */
 	{ NULL, NULL }, /* Pc */
 	{ NULL, termp_pf_post }, /* Pf */
 	{ termp_quote_pre, termp_quote_post }, /* Po */
@@ -218,9 +217,9 @@ static	const struct termact termacts[MDOC_MAX] = {
 	{ termp_quote_pre, termp_quote_post }, /* Sq */
 	{ termp_sm_pre, NULL }, /* Sm */
 	{ termp_under_pre, NULL }, /* Sx */
-	{ termp_bold_pre, NULL }, /* Sy */
+	{ termp_sy_pre, NULL }, /* Sy */
 	{ NULL, NULL }, /* Tn */
-	{ termp_xx_pre, NULL }, /* Ux */
+	{ termp_xx_pre, termp_xx_post }, /* Ux */
 	{ NULL, NULL }, /* Xc */
 	{ NULL, NULL }, /* Xo */
 	{ termp_fo_pre, termp_fo_post }, /* Fo */
@@ -229,10 +228,10 @@ static	const struct termact termacts[MDOC_MAX] = {
 	{ NULL, NULL }, /* Oc */
 	{ termp_bk_pre, termp_bk_post }, /* Bk */
 	{ NULL, NULL }, /* Ek */
-	{ termp_bt_pre, NULL }, /* Bt */
+	{ NULL, NULL }, /* Bt */
 	{ NULL, NULL }, /* Hf */
 	{ termp_under_pre, NULL }, /* Fr */
-	{ termp_ud_pre, NULL }, /* Ud */
+	{ NULL, NULL }, /* Ud */
 	{ NULL, termp_lb_post }, /* Lb */
 	{ termp_sp_pre, NULL }, /* Lp */
 	{ termp_lk_pre, NULL }, /* Lk */
@@ -243,7 +242,7 @@ static	const struct termact termacts[MDOC_MAX] = {
 	{ NULL, termp____post }, /* %C */
 	{ termp_skip_pre, NULL }, /* Es */
 	{ termp_quote_pre, termp_quote_post }, /* En */
-	{ termp_xx_pre, NULL }, /* Dx */
+	{ termp_xx_pre, termp_xx_post }, /* Dx */
 	{ NULL, termp____post }, /* %Q */
 	{ termp_sp_pre, NULL }, /* br */
 	{ termp_sp_pre, NULL }, /* sp */
@@ -283,6 +282,8 @@ terminal_mdoc(void *arg, const struct roff_man *mdoc)
 			p->defindent = 5;
 		term_begin(p, print_mdoc_head, print_mdoc_foot,
 		    &mdoc->meta);
+		while (n != NULL && n->flags & NODE_NOPRT)
+			n = n->next;
 		if (n != NULL) {
 			if (n->tok != MDOC_Sh)
 				term_vspace(p);
@@ -309,10 +310,13 @@ print_mdoc_node(DECL_ARGS)
 	struct termpair	 npair;
 	size_t		 offset, rmargin;
 
+	if (n->flags & NODE_NOPRT)
+		return;
+
 	chld = 1;
 	offset = p->offset;
 	rmargin = p->rmargin;
-	n->flags &= ~MDOC_ENDED;
+	n->flags &= ~NODE_ENDED;
 	n->prev_font = p->fonti;
 
 	memset(&npair, 0, sizeof(struct termpair));
@@ -323,7 +327,7 @@ print_mdoc_node(DECL_ARGS)
 	 * invoked in a prior line, revert it to PREKEEP.
 	 */
 
-	if (p->flags & TERMP_KEEP && n->flags & MDOC_LINE) {
+	if (p->flags & TERMP_KEEP && n->flags & NODE_LINE) {
 		p->flags &= ~TERMP_KEEP;
 		p->flags |= TERMP_PREKEEP;
 	}
@@ -335,19 +339,19 @@ print_mdoc_node(DECL_ARGS)
 
 	switch (n->type) {
 	case ROFFT_TEXT:
-		if (' ' == *n->string && MDOC_LINE & n->flags)
+		if (' ' == *n->string && NODE_LINE & n->flags)
 			term_newln(p);
-		if (MDOC_DELIMC & n->flags)
+		if (NODE_DELIMC & n->flags)
 			p->flags |= TERMP_NOSPACE;
 		term_word(p, n->string);
-		if (MDOC_DELIMO & n->flags)
+		if (NODE_DELIMO & n->flags)
 			p->flags |= TERMP_NOSPACE;
 		break;
 	case ROFFT_EQN:
-		if ( ! (n->flags & MDOC_LINE))
+		if ( ! (n->flags & NODE_LINE))
 			p->flags |= TERMP_NOSPACE;
 		term_eqn(p, n->eqn);
-		if (n->next != NULL && ! (n->next->flags & MDOC_LINE))
+		if (n->next != NULL && ! (n->next->flags & NODE_LINE))
 			p->flags |= TERMP_NOSPACE;
 		break;
 	case ROFFT_TBL:
@@ -377,7 +381,7 @@ print_mdoc_node(DECL_ARGS)
 	case ROFFT_EQN:
 		break;
 	default:
-		if ( ! termacts[n->tok].post || MDOC_ENDED & n->flags)
+		if ( ! termacts[n->tok].post || NODE_ENDED & n->flags)
 			break;
 		(void)(*termacts[n->tok].post)(p, &npair, meta, n);
 
@@ -387,7 +391,7 @@ print_mdoc_node(DECL_ARGS)
 		 * that it must not call the post handler again.
 		 */
 		if (ENDBODY_NOT != n->end)
-			n->body->flags |= MDOC_ENDED;
+			n->body->flags |= NODE_ENDED;
 
 		/*
 		 * End of line terminating an implicit block
@@ -399,7 +403,7 @@ print_mdoc_node(DECL_ARGS)
 		break;
 	}
 
-	if (MDOC_EOS & n->flags)
+	if (NODE_EOS & n->flags)
 		p->flags |= TERMP_SENTENCE;
 
 	if (MDOC_ll != n->tok) {
@@ -562,6 +566,8 @@ print_bvspace(struct termp *p,
 	/* Do not vspace directly after Ss/Sh. */
 
 	nn = n;
+	while (nn->prev != NULL && nn->prev->flags & NODE_NOPRT)
+		nn = nn->prev;
 	while (nn->prev == NULL) {
 		do {
 			nn = nn->parent;
@@ -631,10 +637,10 @@ termp_it_pre(DECL_ARGS)
 		width = term_len(p, 2);
 		break;
 	case LIST_hang:
+	case LIST_tag:
 		width = term_len(p, 8);
 		break;
 	case LIST_column:
-	case LIST_tag:
 		width = term_len(p, 10);
 		break;
 	default:
@@ -1042,7 +1048,7 @@ termp_fl_pre(DECL_ARGS)
 	if (!(n->child == NULL &&
 	    (n->next == NULL ||
 	     n->next->type == ROFFT_TEXT ||
-	     n->next->flags & MDOC_LINE)))
+	     n->next->flags & NODE_LINE)))
 		p->flags |= TERMP_NOSPACE;
 
 	return 1;
@@ -1087,7 +1093,7 @@ static int
 termp_ns_pre(DECL_ARGS)
 {
 
-	if ( ! (MDOC_LINE & n->flags))
+	if ( ! (NODE_LINE & n->flags))
 		p->flags |= TERMP_NOSPACE;
 	return 1;
 }
@@ -1103,92 +1109,11 @@ termp_rs_pre(DECL_ARGS)
 	return 1;
 }
 
-static int
-termp_rv_pre(DECL_ARGS)
-{
-	struct roff_node *nch;
-
-	term_newln(p);
-
-	if (n->child != NULL) {
-		term_word(p, "The");
-
-		for (nch = n->child; nch != NULL; nch = nch->next) {
-			term_fontpush(p, TERMFONT_BOLD);
-			term_word(p, nch->string);
-			term_fontpop(p);
-
-			p->flags |= TERMP_NOSPACE;
-			term_word(p, "()");
-
-			if (nch->next == NULL)
-				continue;
-
-			if (nch->prev != NULL || nch->next->next != NULL) {
-				p->flags |= TERMP_NOSPACE;
-				term_word(p, ",");
-			}
-			if (nch->next->next == NULL)
-				term_word(p, "and");
-		}
-
-		if (n->child != NULL && n->child->next != NULL)
-			term_word(p, "functions return");
-		else
-			term_word(p, "function returns");
-
-		term_word(p, "the value\\~0 if successful;");
-	} else
-		term_word(p, "Upon successful completion,"
-		    " the value\\~0 is returned;");
-
-	term_word(p, "otherwise the value\\~\\-1 is returned"
-	    " and the global variable");
-
-	term_fontpush(p, TERMFONT_UNDER);
-	term_word(p, "errno");
-	term_fontpop(p);
-
-	term_word(p, "is set to indicate the error.");
-	p->flags |= TERMP_SENTENCE;
-
-	return 0;
-}
-
 static int
 termp_ex_pre(DECL_ARGS)
 {
-	struct roff_node *nch;
-
 	term_newln(p);
-	term_word(p, "The");
-
-	for (nch = n->child; nch != NULL; nch = nch->next) {
-		term_fontpush(p, TERMFONT_BOLD);
-		term_word(p, nch->string);
-		term_fontpop(p);
-
-		if (nch->next == NULL)
-			continue;
-
-		if (nch->prev != NULL || nch->next->next != NULL) {
-			p->flags |= TERMP_NOSPACE;
-			term_word(p, ",");
-		}
-
-		if (nch->next->next == NULL)
-			term_word(p, "and");
-	}
-
-	if (n->child != NULL && n->child->next != NULL)
-		term_word(p, "utilities exit\\~0");
-	else
-		term_word(p, "utility exits\\~0");
-
-	term_word(p, "on success, and\\~>0 if an error occurs.");
-
-	p->flags |= TERMP_SENTENCE;
-	return 0;
+	return 1;
 }
 
 static int
@@ -1253,7 +1178,7 @@ synopsis_pre(struct termp *p, const struct roff_node *n)
 	 * Obviously, if we're not in a SYNOPSIS or no prior macros
 	 * exist, do nothing.
 	 */
-	if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags))
+	if (NULL == n->prev || ! (NODE_SYNPRETTY & n->flags))
 		return;
 
 	/*
@@ -1389,32 +1314,14 @@ termp_sh_post(DECL_ARGS)
 	}
 }
 
-static int
-termp_bt_pre(DECL_ARGS)
-{
-
-	term_word(p, "is currently in beta test.");
-	p->flags |= TERMP_SENTENCE;
-	return 0;
-}
-
 static void
 termp_lb_post(DECL_ARGS)
 {
 
-	if (SEC_LIBRARY == n->sec && MDOC_LINE & n->flags)
+	if (SEC_LIBRARY == n->sec && NODE_LINE & n->flags)
 		term_newln(p);
 }
 
-static int
-termp_ud_pre(DECL_ARGS)
-{
-
-	term_word(p, "currently under development.");
-	p->flags |= TERMP_SENTENCE;
-	return 0;
-}
-
 static int
 termp_d1_pre(DECL_ARGS)
 {
@@ -1430,7 +1337,7 @@ static int
 termp_ft_pre(DECL_ARGS)
 {
 
-	/* NB: MDOC_LINE does not effect this! */
+	/* NB: NODE_LINE does not effect this! */
 	synopsis_pre(p, n);
 	term_fontpush(p, TERMFONT_UNDER);
 	return 1;
@@ -1442,7 +1349,7 @@ termp_fn_pre(DECL_ARGS)
 	size_t		 rmargin = 0;
 	int		 pretty;
 
-	pretty = MDOC_SYNPRETTY & n->flags;
+	pretty = NODE_SYNPRETTY & n->flags;
 
 	synopsis_pre(p, n);
 
@@ -1460,7 +1367,7 @@ termp_fn_pre(DECL_ARGS)
 	term_word(p, n->string);
 	term_fontpop(p);
 
-	if (n->sec == SEC_DESCRIPTION)
+	if (n->sec == SEC_DESCRIPTION || n->sec == SEC_CUSTOM)
 		tag_put(n->string, ++fn_prio, p->line);
 
 	if (pretty) {
@@ -1608,7 +1515,7 @@ termp_bd_pre(DECL_ARGS)
 			break;
 		}
 		if (p->flags & TERMP_NONEWLINE ||
-		    (nn->next && ! (nn->next->flags & MDOC_LINE)))
+		    (nn->next && ! (nn->next->flags & NODE_LINE)))
 			continue;
 		term_flushln(p);
 		p->flags |= TERMP_NOSPACE;
@@ -1642,85 +1549,41 @@ termp_bd_post(DECL_ARGS)
 	p->maxrmargin = rmax;
 }
 
-static int
-termp_bx_pre(DECL_ARGS)
-{
-
-	if (NULL != (n = n->child)) {
-		term_word(p, n->string);
-		p->flags |= TERMP_NOSPACE;
-		term_word(p, "BSD");
-	} else {
-		term_word(p, "BSD");
-		return 0;
-	}
-
-	if (NULL != (n = n->next)) {
-		p->flags |= TERMP_NOSPACE;
-		term_word(p, "-");
-		p->flags |= TERMP_NOSPACE;
-		term_word(p, n->string);
-	}
-
-	return 0;
-}
-
 static int
 termp_xx_pre(DECL_ARGS)
 {
-	const char	*pp;
-	int		 flags;
+	if ((n->aux = p->flags & TERMP_PREKEEP) == 0)
+		p->flags |= TERMP_PREKEEP;
+	return 1;
+}
 
-	pp = NULL;
-	switch (n->tok) {
-	case MDOC_Bsx:
-		pp = "BSD/OS";
-		break;
-	case MDOC_Dx:
-		pp = "DragonFly";
-		break;
-	case MDOC_Fx:
-		pp = "FreeBSD";
-		break;
-	case MDOC_Nx:
-		pp = "NetBSD";
-		break;
-	case MDOC_Ox:
-		pp = "OpenBSD";
-		break;
-	case MDOC_Ux:
-		pp = "UNIX";
-		break;
-	default:
-		abort();
-	}
-
-	term_word(p, pp);
-	if (n->child) {
-		flags = p->flags;
-		p->flags |= TERMP_KEEP;
-		term_word(p, n->child->string);
-		p->flags = flags;
-	}
-	return 0;
+static void
+termp_xx_post(DECL_ARGS)
+{
+	if (n->aux == 0)
+		p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
 }
 
 static void
 termp_pf_post(DECL_ARGS)
 {
 
-	if ( ! (n->next == NULL || n->next->flags & MDOC_LINE))
+	if ( ! (n->next == NULL || n->next->flags & NODE_LINE))
 		p->flags |= TERMP_NOSPACE;
 }
 
 static int
 termp_ss_pre(DECL_ARGS)
 {
+	struct roff_node *nn;
 
 	switch (n->type) {
 	case ROFFT_BLOCK:
 		term_newln(p);
-		if (n->prev)
+		for (nn = n->prev; nn != NULL; nn = nn->prev)
+			if ((nn->flags & NODE_NOPRT) == 0)
+				break;
+		if (nn != NULL)
 			term_vspace(p);
 		break;
 	case ROFFT_HEAD:
@@ -1760,7 +1623,7 @@ termp_in_pre(DECL_ARGS)
 
 	synopsis_pre(p, n);
 
-	if (MDOC_SYNPRETTY & n->flags && MDOC_LINE & n->flags) {
+	if (NODE_SYNPRETTY & n->flags && NODE_LINE & n->flags) {
 		term_fontpush(p, TERMFONT_BOLD);
 		term_word(p, "#include");
 		term_word(p, "<");
@@ -1777,13 +1640,13 @@ static void
 termp_in_post(DECL_ARGS)
 {
 
-	if (MDOC_SYNPRETTY & n->flags)
+	if (NODE_SYNPRETTY & n->flags)
 		term_fontpush(p, TERMFONT_BOLD);
 
 	p->flags |= TERMP_NOSPACE;
 	term_word(p, ">");
 
-	if (MDOC_SYNPRETTY & n->flags)
+	if (NODE_SYNPRETTY & n->flags)
 		term_fontpop(p);
 }
 
@@ -1990,7 +1853,7 @@ termp_fo_pre(DECL_ARGS)
 	size_t		 rmargin = 0;
 	int		 pretty;
 
-	pretty = MDOC_SYNPRETTY & n->flags;
+	pretty = NODE_SYNPRETTY & n->flags;
 
 	if (n->type == ROFFT_BLOCK) {
 		synopsis_pre(p, n);
@@ -2036,7 +1899,7 @@ termp_fo_post(DECL_ARGS)
 	p->flags |= TERMP_NOSPACE;
 	term_word(p, ")");
 
-	if (MDOC_SYNPRETTY & n->flags) {
+	if (NODE_SYNPRETTY & n->flags) {
 		p->flags |= TERMP_NOSPACE;
 		term_word(p, ";");
 		term_flushln(p);
@@ -2120,6 +1983,7 @@ static int
 termp_li_pre(DECL_ARGS)
 {
 
+	termp_tag_pre(p, pair, meta, n);
 	term_fontpush(p, TERMFONT_NONE);
 	return 1;
 }
@@ -2217,6 +2081,26 @@ termp_under_pre(DECL_ARGS)
 	return 1;
 }
 
+static int
+termp_em_pre(DECL_ARGS)
+{
+	if (n->child != NULL &&
+	    n->child->type == ROFFT_TEXT)
+		tag_put(n->child->string, 0, p->line);
+	term_fontpush(p, TERMFONT_UNDER);
+	return 1;
+}
+
+static int
+termp_sy_pre(DECL_ARGS)
+{
+	if (n->child != NULL &&
+	    n->child->type == ROFFT_TEXT)
+		tag_put(n->child->string, 0, p->line);
+	term_fontpush(p, TERMFONT_BOLD);
+	return 1;
+}
+
 static int
 termp_er_pre(DECL_ARGS)
 {
@@ -2235,7 +2119,9 @@ termp_tag_pre(DECL_ARGS)
 
 	if (n->child != NULL &&
 	    n->child->type == ROFFT_TEXT &&
-	    n->prev == NULL &&
+	    (n->prev == NULL ||
+	     (n->prev->type == ROFFT_TEXT &&
+	      strcmp(n->prev->string, "|") == 0)) &&
 	    (n->parent->tok == MDOC_It ||
 	     (n->parent->tok == MDOC_Xo &&
 	      n->parent->parent->prev == NULL &&
diff --git a/contrib/mdocml/mdoc_validate.c b/contrib/mdocml/mdoc_validate.c
index e369349c8a3..043145ae1cc 100644
--- a/contrib/mdocml/mdoc_validate.c
+++ b/contrib/mdocml/mdoc_validate.c
@@ -1,7 +1,7 @@
-/*	$Id: mdoc_validate.c,v 1.301 2016/01/08 17:48:09 schwarze Exp $ */
+/*	$Id: mdoc_validate.c,v 1.317 2017/01/11 17:39:53 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons 
- * Copyright (c) 2010-2016 Ingo Schwarze 
+ * Copyright (c) 2010-2017 Ingo Schwarze 
  * Copyright (c) 2010 Joerg Sonnenberger 
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -51,6 +51,7 @@ enum	check_ineq {
 
 typedef	void	(*v_post)(POST_ARGS);
 
+static	int	 build_list(struct roff_man *, int);
 static	void	 check_text(struct roff_man *, int, int, char *);
 static	void	 check_argv(struct roff_man *,
 			struct roff_node *, struct mdoc_argv *);
@@ -67,7 +68,6 @@ static	void	 post_bf(POST_ARGS);
 static	void	 post_bk(POST_ARGS);
 static	void	 post_bl(POST_ARGS);
 static	void	 post_bl_block(POST_ARGS);
-static	void	 post_bl_block_tag(POST_ARGS);
 static	void	 post_bl_head(POST_ARGS);
 static	void	 post_bl_norm(POST_ARGS);
 static	void	 post_bx(POST_ARGS);
@@ -96,6 +96,7 @@ static	void	 post_par(POST_ARGS);
 static	void	 post_prevpar(POST_ARGS);
 static	void	 post_root(POST_ARGS);
 static	void	 post_rs(POST_ARGS);
+static	void	 post_rv(POST_ARGS);
 static	void	 post_sh(POST_ARGS);
 static	void	 post_sh_head(POST_ARGS);
 static	void	 post_sh_name(POST_ARGS);
@@ -104,6 +105,8 @@ static	void	 post_sh_authors(POST_ARGS);
 static	void	 post_sm(POST_ARGS);
 static	void	 post_st(POST_ARGS);
 static	void	 post_std(POST_ARGS);
+static	void	 post_xr(POST_ARGS);
+static	void	 post_xx(POST_ARGS);
 
 static	v_post mdoc_valids[MDOC_MAX] = {
 	NULL,		/* Ap */
@@ -142,11 +145,11 @@ static	v_post mdoc_valids[MDOC_MAX] = {
 	NULL,		/* Op */
 	post_obsolete,	/* Ot */
 	post_defaults,	/* Pa */
-	post_std,	/* Rv */
+	post_rv,	/* Rv */
 	post_st,	/* St */
 	NULL,		/* Va */
 	NULL,		/* Vt */
-	NULL,		/* Xr */
+	post_xr,	/* Xr */
 	NULL,		/* %A */
 	post_hyph,	/* %B */ /* FIXME: can be used outside Rs/Re. */
 	NULL,		/* %D */
@@ -166,7 +169,7 @@ static	v_post mdoc_valids[MDOC_MAX] = {
 	post_bf,	/* Bf */
 	NULL,		/* Bo */
 	NULL,		/* Bq */
-	NULL,		/* Bsx */
+	post_xx,	/* Bsx */
 	post_bx,	/* Bx */
 	post_obsolete,	/* Db */
 	NULL,		/* Dc */
@@ -176,12 +179,12 @@ static	v_post mdoc_valids[MDOC_MAX] = {
 	NULL,		/* Ef */
 	NULL,		/* Em */
 	NULL,		/* Eo */
-	NULL,		/* Fx */
+	post_xx,	/* Fx */
 	NULL,		/* Ms */
 	NULL,		/* No */
 	post_ns,	/* Ns */
-	NULL,		/* Nx */
-	NULL,		/* Ox */
+	post_xx,	/* Nx */
+	post_xx,	/* Ox */
 	NULL,		/* Pc */
 	NULL,		/* Pf */
 	NULL,		/* Po */
@@ -199,7 +202,7 @@ static	v_post mdoc_valids[MDOC_MAX] = {
 	post_hyph,	/* Sx */
 	NULL,		/* Sy */
 	NULL,		/* Tn */
-	NULL,		/* Ux */
+	post_xx,	/* Ux */
 	NULL,		/* Xc */
 	NULL,		/* Xo */
 	post_fo,	/* Fo */
@@ -222,7 +225,7 @@ static	v_post mdoc_valids[MDOC_MAX] = {
 	NULL,		/* %C */
 	post_es,	/* Es */
 	post_en,	/* En */
-	NULL,		/* Dx */
+	post_xx,	/* Dx */
 	NULL,		/* %Q */
 	post_par,	/* br */
 	post_par,	/* sp */
@@ -297,7 +300,8 @@ mdoc_node_validate(struct roff_man *mdoc)
 	mdoc->next = ROFF_NEXT_SIBLING;
 	switch (n->type) {
 	case ROFFT_TEXT:
-		if (n->sec != SEC_SYNOPSIS || n->parent->tok != MDOC_Fd)
+		if (n->sec != SEC_SYNOPSIS ||
+		    (n->parent->tok != MDOC_Cd && n->parent->tok != MDOC_Fd))
 			check_text(mdoc, n->line, n->pos, n->string);
 		break;
 	case ROFFT_EQN:
@@ -316,9 +320,9 @@ mdoc_node_validate(struct roff_man *mdoc)
 		 */
 
 		if (n->child != NULL)
-			n->child->flags &= ~MDOC_DELIMC;
+			n->child->flags &= ~NODE_DELIMC;
 		if (n->last != NULL)
-			n->last->flags &= ~MDOC_DELIMO;
+			n->last->flags &= ~NODE_DELIMO;
 
 		/* Call the macro's postprocessor. */
 
@@ -502,6 +506,7 @@ post_bl_norm(POST_ARGS)
 		mandoc_msg(MANDOCERR_BL_NOTYPE, mdoc->parse,
 		    n->line, n->pos, "Bl");
 		n->norm->Bl.type = LIST_item;
+		mdoclt = MDOC_Item;
 	}
 
 	/*
@@ -618,6 +623,10 @@ post_bd(POST_ARGS)
 	}
 }
 
+/*
+ * Stand-alone line macros.
+ */
+
 static void
 post_an_norm(POST_ARGS)
 {
@@ -645,6 +654,158 @@ post_an_norm(POST_ARGS)
 		abort();
 }
 
+static void
+post_eoln(POST_ARGS)
+{
+	struct roff_node	*n;
+
+	n = mdoc->last;
+	if (n->child != NULL)
+		mandoc_vmsg(MANDOCERR_ARG_SKIP, mdoc->parse,
+		    n->line, n->pos, "%s %s",
+		    mdoc_macronames[n->tok], n->child->string);
+
+	while (n->child != NULL)
+		roff_node_delete(mdoc, n->child);
+
+	roff_word_alloc(mdoc, n->line, n->pos, n->tok == MDOC_Bt ?
+	    "is currently in beta test." : "currently under development.");
+	mdoc->last->flags |= NODE_EOS | NODE_NOSRC;
+	mdoc->last = n;
+}
+
+static int
+build_list(struct roff_man *mdoc, int tok)
+{
+	struct roff_node	*n;
+	int			 ic;
+
+	n = mdoc->last->next;
+	for (ic = 1;; ic++) {
+		roff_elem_alloc(mdoc, n->line, n->pos, tok);
+		mdoc->last->flags |= NODE_NOSRC;
+		mdoc_node_relink(mdoc, n);
+		n = mdoc->last = mdoc->last->parent;
+		mdoc->next = ROFF_NEXT_SIBLING;
+		if (n->next == NULL)
+			return ic;
+		if (ic > 1 || n->next->next != NULL) {
+			roff_word_alloc(mdoc, n->line, n->pos, ",");
+			mdoc->last->flags |= NODE_DELIMC | NODE_NOSRC;
+		}
+		n = mdoc->last->next;
+		if (n->next == NULL) {
+			roff_word_alloc(mdoc, n->line, n->pos, "and");
+			mdoc->last->flags |= NODE_NOSRC;
+		}
+	}
+}
+
+static void
+post_ex(POST_ARGS)
+{
+	struct roff_node	*n;
+	int			 ic;
+
+	post_std(mdoc);
+
+	n = mdoc->last;
+	mdoc->next = ROFF_NEXT_CHILD;
+	roff_word_alloc(mdoc, n->line, n->pos, "The");
+	mdoc->last->flags |= NODE_NOSRC;
+
+	if (mdoc->last->next != NULL)
+		ic = build_list(mdoc, MDOC_Nm);
+	else if (mdoc->meta.name != NULL) {
+		roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Nm);
+		mdoc->last->flags |= NODE_NOSRC;
+		roff_word_alloc(mdoc, n->line, n->pos, mdoc->meta.name);
+		mdoc->last->flags |= NODE_NOSRC;
+		mdoc->last = mdoc->last->parent;
+		mdoc->next = ROFF_NEXT_SIBLING;
+		ic = 1;
+	} else {
+		mandoc_msg(MANDOCERR_EX_NONAME, mdoc->parse,
+		    n->line, n->pos, "Ex");
+		ic = 0;
+	}
+
+	roff_word_alloc(mdoc, n->line, n->pos,
+	    ic > 1 ? "utilities exit\\~0" : "utility exits\\~0");
+	mdoc->last->flags |= NODE_NOSRC;
+	roff_word_alloc(mdoc, n->line, n->pos,
+	    "on success, and\\~>0 if an error occurs.");
+	mdoc->last->flags |= NODE_EOS | NODE_NOSRC;
+	mdoc->last = n;
+}
+
+static void
+post_lb(POST_ARGS)
+{
+	struct roff_node	*n;
+	const char		*p;
+
+	n = mdoc->last;
+	assert(n->child->type == ROFFT_TEXT);
+	mdoc->next = ROFF_NEXT_CHILD;
+
+	if ((p = mdoc_a2lib(n->child->string)) != NULL) {
+		n->child->flags |= NODE_NOPRT;
+		roff_word_alloc(mdoc, n->line, n->pos, p);
+		mdoc->last->flags = NODE_NOSRC;
+		mdoc->last = n;
+		return;
+	}
+
+	roff_word_alloc(mdoc, n->line, n->pos, "library");
+	mdoc->last->flags = NODE_NOSRC;
+	roff_word_alloc(mdoc, n->line, n->pos, "\\(Lq");
+	mdoc->last->flags = NODE_DELIMO | NODE_NOSRC;
+	mdoc->last = mdoc->last->next;
+	roff_word_alloc(mdoc, n->line, n->pos, "\\(Rq");
+	mdoc->last->flags = NODE_DELIMC | NODE_NOSRC;
+	mdoc->last = n;
+}
+
+static void
+post_rv(POST_ARGS)
+{
+	struct roff_node	*n;
+	int			 ic;
+
+	post_std(mdoc);
+
+	n = mdoc->last;
+	mdoc->next = ROFF_NEXT_CHILD;
+	if (n->child != NULL) {
+		roff_word_alloc(mdoc, n->line, n->pos, "The");
+		mdoc->last->flags |= NODE_NOSRC;
+		ic = build_list(mdoc, MDOC_Fn);
+		roff_word_alloc(mdoc, n->line, n->pos,
+		    ic > 1 ? "functions return" : "function returns");
+		mdoc->last->flags |= NODE_NOSRC;
+		roff_word_alloc(mdoc, n->line, n->pos,
+		    "the value\\~0 if successful;");
+	} else
+		roff_word_alloc(mdoc, n->line, n->pos, "Upon successful "
+		    "completion, the value\\~0 is returned;");
+	mdoc->last->flags |= NODE_NOSRC;
+
+	roff_word_alloc(mdoc, n->line, n->pos, "otherwise "
+	    "the value\\~\\-1 is returned and the global variable");
+	mdoc->last->flags |= NODE_NOSRC;
+	roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Va);
+	mdoc->last->flags |= NODE_NOSRC;
+	roff_word_alloc(mdoc, n->line, n->pos, "errno");
+	mdoc->last->flags |= NODE_NOSRC;
+	mdoc->last = mdoc->last->parent;
+	mdoc->next = ROFF_NEXT_SIBLING;
+	roff_word_alloc(mdoc, n->line, n->pos,
+	    "is set to indicate the error.");
+	mdoc->last->flags |= NODE_EOS | NODE_NOSRC;
+	mdoc->last = n;
+}
+
 static void
 post_std(POST_ARGS)
 {
@@ -659,6 +820,30 @@ post_std(POST_ARGS)
 	    n->line, n->pos, mdoc_macronames[n->tok]);
 }
 
+static void
+post_st(POST_ARGS)
+{
+	struct roff_node	 *n, *nch;
+	const char		 *p;
+
+	n = mdoc->last;
+	nch = n->child;
+	assert(nch->type == ROFFT_TEXT);
+
+	if ((p = mdoc_a2st(nch->string)) == NULL) {
+		mandoc_vmsg(MANDOCERR_ST_BAD, mdoc->parse,
+		    nch->line, nch->pos, "St %s", nch->string);
+		roff_node_delete(mdoc, n);
+		return;
+	}
+
+	nch->flags |= NODE_NOPRT;
+	mdoc->next = ROFF_NEXT_CHILD;
+	roff_word_alloc(mdoc, nch->line, nch->pos, p);
+	mdoc->last->flags |= NODE_NOSRC;
+	mdoc->last= n;
+}
+
 static void
 post_obsolete(POST_ARGS)
 {
@@ -670,6 +855,10 @@ post_obsolete(POST_ARGS)
 		    n->line, n->pos, mdoc_macronames[n->tok]);
 }
 
+/*
+ * Block macros.
+ */
+
 static void
 post_bf(POST_ARGS)
 {
@@ -735,39 +924,6 @@ post_bf(POST_ARGS)
 		    "Bf %s", np->child->string);
 }
 
-static void
-post_lb(POST_ARGS)
-{
-	struct roff_node	*n;
-	const char		*stdlibname;
-	char			*libname;
-
-	n = mdoc->last->child;
-	assert(n->type == ROFFT_TEXT);
-
-	if (NULL == (stdlibname = mdoc_a2lib(n->string)))
-		mandoc_asprintf(&libname,
-		    "library \\(Lq%s\\(Rq", n->string);
-	else
-		libname = mandoc_strdup(stdlibname);
-
-	free(n->string);
-	n->string = libname;
-}
-
-static void
-post_eoln(POST_ARGS)
-{
-	const struct roff_node *n;
-
-	n = mdoc->last;
-	if (n->child != NULL)
-		mandoc_vmsg(MANDOCERR_ARG_SKIP,
-		    mdoc->parse, n->line, n->pos,
-		    "%s %s", mdoc_macronames[n->tok],
-		    n->child->string);
-}
-
 static void
 post_fname(POST_ARGS)
 {
@@ -850,12 +1006,11 @@ post_nm(POST_ARGS)
 	     n->last->tok == MDOC_Lp))
 		mdoc_node_relink(mdoc, n->last);
 
-	if (mdoc->meta.name != NULL)
-		return;
-
-	deroff(&mdoc->meta.name, n);
-
 	if (mdoc->meta.name == NULL)
+		deroff(&mdoc->meta.name, n);
+
+	if (mdoc->meta.name == NULL ||
+	    (mdoc->lastsec == SEC_NAME && n->child == NULL))
 		mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse,
 		    n->line, n->pos, "Nm");
 }
@@ -885,9 +1040,11 @@ post_display(POST_ARGS)
 	n = mdoc->last;
 	switch (n->type) {
 	case ROFFT_BODY:
-		if (n->end != ENDBODY_NOT)
-			break;
-		if (n->child == NULL)
+		if (n->end != ENDBODY_NOT) {
+			if (n->tok == MDOC_Bd &&
+			    n->body->parent->args == NULL)
+				roff_node_delete(mdoc, n);
+		} else if (n->child == NULL)
 			mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse,
 			    n->line, n->pos, mdoc_macronames[n->tok]);
 		else if (n->tok == MDOC_D1)
@@ -942,12 +1099,15 @@ post_defaults(POST_ARGS)
 	case MDOC_Ar:
 		mdoc->next = ROFF_NEXT_CHILD;
 		roff_word_alloc(mdoc, nn->line, nn->pos, "file");
+		mdoc->last->flags |= NODE_NOSRC;
 		roff_word_alloc(mdoc, nn->line, nn->pos, "...");
+		mdoc->last->flags |= NODE_NOSRC;
 		break;
 	case MDOC_Pa:
 	case MDOC_Mt:
 		mdoc->next = ROFF_NEXT_CHILD;
 		roff_word_alloc(mdoc, nn->line, nn->pos, "~");
+		mdoc->last->flags |= NODE_NOSRC;
 		break;
 	default:
 		abort();
@@ -958,17 +1118,11 @@ post_defaults(POST_ARGS)
 static void
 post_at(POST_ARGS)
 {
-	struct roff_node	*n;
-	const char		*std_att;
-	char			*att;
+	struct roff_node	*n, *nch;
+	const char		*att;
 
 	n = mdoc->last;
-	if (n->child == NULL) {
-		mdoc->next = ROFF_NEXT_CHILD;
-		roff_word_alloc(mdoc, n->line, n->pos, "AT&T UNIX");
-		mdoc->last = n;
-		return;
-	}
+	nch = n->child;
 
 	/*
 	 * If we have a child, look it up in the standard keys.  If a
@@ -976,17 +1130,19 @@ post_at(POST_ARGS)
 	 * prefix "AT&T UNIX " to the existing data.
 	 */
 
-	n = n->child;
-	assert(n->type == ROFFT_TEXT);
-	if ((std_att = mdoc_a2att(n->string)) == NULL) {
+	att = NULL;
+	if (nch != NULL && ((att = mdoc_a2att(nch->string)) == NULL))
 		mandoc_vmsg(MANDOCERR_AT_BAD, mdoc->parse,
-		    n->line, n->pos, "At %s", n->string);
-		mandoc_asprintf(&att, "AT&T UNIX %s", n->string);
-	} else
-		att = mandoc_strdup(std_att);
+		    nch->line, nch->pos, "At %s", nch->string);
 
-	free(n->string);
-	n->string = att;
+	mdoc->next = ROFF_NEXT_CHILD;
+	if (att != NULL) {
+		roff_word_alloc(mdoc, nch->line, nch->pos, att);
+		nch->flags |= NODE_NOPRT;
+	} else
+		roff_word_alloc(mdoc, n->line, n->pos, "AT&T UNIX");
+	mdoc->last->flags |= NODE_NOSRC;
+	mdoc->last = n;
 }
 
 static void
@@ -1024,6 +1180,41 @@ post_es(POST_ARGS)
 	mdoc->last_es = mdoc->last;
 }
 
+static void
+post_xx(POST_ARGS)
+{
+	struct roff_node	*n;
+	const char		*os;
+
+	n = mdoc->last;
+	switch (n->tok) {
+	case MDOC_Bsx:
+		os = "BSD/OS";
+		break;
+	case MDOC_Dx:
+		os = "DragonFly";
+		break;
+	case MDOC_Fx:
+		os = "FreeBSD";
+		break;
+	case MDOC_Nx:
+		os = "NetBSD";
+		break;
+	case MDOC_Ox:
+		os = "OpenBSD";
+		break;
+	case MDOC_Ux:
+		os = "UNIX";
+		break;
+	default:
+		abort();
+	}
+	mdoc->next = ROFF_NEXT_CHILD;
+	roff_word_alloc(mdoc, n->line, n->pos, os);
+	mdoc->last->flags |= NODE_NOSRC;
+	mdoc->last = n;
+}
+
 static void
 post_it(POST_ARGS)
 {
@@ -1063,10 +1254,11 @@ post_it(POST_ARGS)
 			    mdoc_argnames[nbl->args->argv[0].arg]);
 		/* FALLTHROUGH */
 	case LIST_item:
-		if (nit->head->child != NULL)
+		if ((nch = nit->head->child) != NULL)
 			mandoc_vmsg(MANDOCERR_ARG_SKIP,
 			    mdoc->parse, nit->line, nit->pos,
-			    "It %s", nit->head->child->string);
+			    "It %s", nch->string == NULL ?
+			    mdoc_macronames[nch->tok] : nch->string);
 		break;
 	case LIST_column:
 		cols = (int)nbl->norm->Bl.ncols;
@@ -1095,22 +1287,7 @@ post_bl_block(POST_ARGS)
 
 	post_prevpar(mdoc);
 
-	/*
-	 * These are fairly complicated, so we've broken them into two
-	 * functions.  post_bl_block_tag() is called when a -tag is
-	 * specified, but no -width (it must be guessed).  The second
-	 * when a -width is specified (macro indicators must be
-	 * rewritten into real lengths).
-	 */
-
 	n = mdoc->last;
-
-	if (n->norm->Bl.type == LIST_tag &&
-	    n->norm->Bl.width == NULL) {
-		post_bl_block_tag(mdoc);
-		assert(n->norm->Bl.width != NULL);
-	}
-
 	for (ni = n->body->child; ni != NULL; ni = ni->next) {
 		if (ni->body == NULL)
 			continue;
@@ -1167,71 +1344,6 @@ rewrite_macro2len(char **arg)
 	mandoc_asprintf(arg, "%zun", width);
 }
 
-static void
-post_bl_block_tag(POST_ARGS)
-{
-	struct roff_node *n, *nn;
-	size_t		  sz, ssz;
-	int		  i;
-	char		  buf[24];
-
-	/*
-	 * Calculate the -width for a `Bl -tag' list if it hasn't been
-	 * provided.  Uses the first head macro.  NOTE AGAIN: this is
-	 * ONLY if the -width argument has NOT been provided.  See
-	 * rewrite_macro2len() for converting the -width string.
-	 */
-
-	sz = 10;
-	n = mdoc->last;
-
-	for (nn = n->body->child; nn != NULL; nn = nn->next) {
-		if (nn->tok != MDOC_It)
-			continue;
-
-		assert(nn->type == ROFFT_BLOCK);
-		nn = nn->head->child;
-
-		if (nn == NULL)
-			break;
-
-		if (nn->type == ROFFT_TEXT) {
-			sz = strlen(nn->string) + 1;
-			break;
-		}
-
-		if (0 != (ssz = macro2len(nn->tok)))
-			sz = ssz;
-
-		break;
-	}
-
-	/* Defaults to ten ens. */
-
-	(void)snprintf(buf, sizeof(buf), "%un", (unsigned int)sz);
-
-	/*
-	 * We have to dynamically add this to the macro's argument list.
-	 * We're guaranteed that a MDOC_Width doesn't already exist.
-	 */
-
-	assert(n->args != NULL);
-	i = (int)(n->args->argc)++;
-
-	n->args->argv = mandoc_reallocarray(n->args->argv,
-	    n->args->argc, sizeof(struct mdoc_argv));
-
-	n->args->argv[i].arg = MDOC_Width;
-	n->args->argv[i].line = n->line;
-	n->args->argv[i].pos = n->pos;
-	n->args->argv[i].sz = 1;
-	n->args->argv[i].value = mandoc_malloc(sizeof(char *));
-	n->args->argv[i].value[0] = mandoc_strdup(buf);
-
-	/* Set our width! */
-	n->norm->Bl.width = n->args->argv[i].value[0];
-}
-
 static void
 post_bl_head(POST_ARGS)
 {
@@ -1325,11 +1437,41 @@ post_bl(POST_ARGS)
 		return;
 	}
 	while (nchild != NULL) {
+		nnext = nchild->next;
 		if (nchild->tok == MDOC_It ||
 		    (nchild->tok == MDOC_Sm &&
-		     nchild->next != NULL &&
-		     nchild->next->tok == MDOC_It)) {
-			nchild = nchild->next;
+		     nnext != NULL && nnext->tok == MDOC_It)) {
+			nchild = nnext;
+			continue;
+		}
+
+		/*
+		 * In .Bl -column, the first rows may be implicit,
+		 * that is, they may not start with .It macros.
+		 * Such rows may be followed by nodes generated on the
+		 * roff level, for example .TS, which cannot be moved
+		 * out of the list.  In that case, wrap such roff nodes
+		 * into an implicit row.
+		 */
+
+		if (nchild->prev != NULL) {
+			mdoc->last = nchild;
+			mdoc->next = ROFF_NEXT_SIBLING;
+			roff_block_alloc(mdoc, nchild->line,
+			    nchild->pos, MDOC_It);
+			roff_head_alloc(mdoc, nchild->line,
+			    nchild->pos, MDOC_It);
+			mdoc->next = ROFF_NEXT_SIBLING;
+			roff_body_alloc(mdoc, nchild->line,
+			    nchild->pos, MDOC_It);
+			while (nchild->tok != MDOC_It) {
+				mdoc_node_relink(mdoc, nchild);
+				if ((nchild = nnext) == NULL)
+					break;
+				nnext = nchild->next;
+				mdoc->next = ROFF_NEXT_SIBLING;
+			}
+			mdoc->last = nbody;
 			continue;
 		}
 
@@ -1345,13 +1487,11 @@ post_bl(POST_ARGS)
 		nblock  = nbody->parent;
 		nprev   = nblock->prev;
 		nparent = nblock->parent;
-		nnext   = nchild->next;
 
 		/*
 		 * Unlink this child.
 		 */
 
-		assert(nchild->prev == NULL);
 		nbody->child = nnext;
 		if (nnext == NULL)
 			nbody->last  = NULL;
@@ -1461,27 +1601,6 @@ post_root(POST_ARGS)
 		    n->line, n->pos, mdoc_macronames[n->tok]);
 }
 
-static void
-post_st(POST_ARGS)
-{
-	struct roff_node	 *n, *nch;
-	const char		 *p;
-
-	n = mdoc->last;
-	nch = n->child;
-
-	assert(nch->type == ROFFT_TEXT);
-
-	if ((p = mdoc_a2st(nch->string)) == NULL) {
-		mandoc_vmsg(MANDOCERR_ST_BAD, mdoc->parse,
-		    nch->line, nch->pos, "St %s", nch->string);
-		roff_node_delete(mdoc, n);
-	} else {
-		free(nch->string);
-		nch->string = mandoc_strdup(p);
-	}
-}
-
 static void
 post_rs(POST_ARGS)
 {
@@ -1600,7 +1719,7 @@ static void
 post_ns(POST_ARGS)
 {
 
-	if (mdoc->last->flags & MDOC_LINE)
+	if (mdoc->last->flags & NODE_LINE)
 		mandoc_msg(MANDOCERR_NS_SKIP, mdoc->parse,
 		    mdoc->last->line, mdoc->last->pos, NULL);
 }
@@ -1646,8 +1765,12 @@ post_sh_name(POST_ARGS)
 	for (n = mdoc->last->child; n != NULL; n = n->next) {
 		switch (n->tok) {
 		case MDOC_Nm:
+			if (hasnm && n->child != NULL)
+				mandoc_vmsg(MANDOCERR_NAMESEC_PUNCT,
+				    mdoc->parse, n->line, n->pos,
+				    "Nm %s", n->child->string);
 			hasnm = 1;
-			break;
+			continue;
 		case MDOC_Nd:
 			hasnd = 1;
 			if (n->next != NULL)
@@ -1655,14 +1778,19 @@ post_sh_name(POST_ARGS)
 				    mdoc->parse, n->line, n->pos, NULL);
 			break;
 		case TOKEN_NONE:
-			if (hasnm)
-				break;
+			if (n->type == ROFFT_TEXT &&
+			    n->string[0] == ',' && n->string[1] == '\0' &&
+			    n->next != NULL && n->next->tok == MDOC_Nm) {
+				n = n->next;
+				continue;
+			}
 			/* FALLTHROUGH */
 		default:
 			mandoc_msg(MANDOCERR_NAMESEC_BAD, mdoc->parse,
 			    n->line, n->pos, mdoc_macronames[n->tok]);
-			break;
+			continue;
 		}
+		break;
 	}
 
 	if ( ! hasnm)
@@ -1759,8 +1887,9 @@ post_sh_authors(POST_ARGS)
 static void
 post_sh_head(POST_ARGS)
 {
-	const char	*goodsec;
-	enum roff_sec	 sec;
+	struct roff_node	*nch;
+	const char		*goodsec;
+	enum roff_sec		 sec;
 
 	/*
 	 * Process a new section.  Sections are either "named" or
@@ -1773,10 +1902,13 @@ post_sh_head(POST_ARGS)
 
 	/* The NAME should be first. */
 
-	if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed)
+	if (sec != SEC_NAME && mdoc->lastnamed == SEC_NONE)
 		mandoc_vmsg(MANDOCERR_NAMESEC_FIRST, mdoc->parse,
-		    mdoc->last->line, mdoc->last->pos,
-		    "Sh %s", secnames[sec]);
+		    mdoc->last->line, mdoc->last->pos, "Sh %s",
+		    sec != SEC_CUSTOM ? secnames[sec] :
+		    (nch = mdoc->last->child) == NULL ? "" :
+		    nch->type == ROFFT_TEXT ? nch->string :
+		    mdoc_macronames[nch->tok]);
 
 	/* The SYNOPSIS gets special attention in other areas. */
 
@@ -1851,6 +1983,21 @@ post_sh_head(POST_ARGS)
 	}
 }
 
+static void
+post_xr(POST_ARGS)
+{
+	struct roff_node *n, *nch;
+
+	n = mdoc->last;
+	nch = n->child;
+	if (nch->next == NULL) {
+		mandoc_vmsg(MANDOCERR_XR_NOSEC, mdoc->parse,
+		    n->line, n->pos, "Xr %s", nch->string);
+		return;
+	}
+	assert(nch->next == n->last);
+}
+
 static void
 post_ignpar(POST_ARGS)
 {
@@ -1961,6 +2108,8 @@ post_dd(POST_ARGS)
 	char		 *datestr;
 
 	n = mdoc->last;
+	n->flags |= NODE_NOPRT;
+
 	if (mdoc->meta.date != NULL) {
 		mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
 		    n->line, n->pos, "Dd");
@@ -1978,7 +2127,7 @@ post_dd(POST_ARGS)
 	if (n->child == NULL || n->child->string[0] == '\0') {
 		mdoc->meta.date = mdoc->quick ? mandoc_strdup("") :
 		    mandoc_normdate(mdoc->parse, NULL, n->line, n->pos);
-		goto out;
+		return;
 	}
 
 	datestr = NULL;
@@ -1990,8 +2139,6 @@ post_dd(POST_ARGS)
 		    datestr, n->line, n->pos);
 		free(datestr);
 	}
-out:
-	roff_node_delete(mdoc, n);
 }
 
 static void
@@ -2002,10 +2149,12 @@ post_dt(POST_ARGS)
 	char		 *p;
 
 	n = mdoc->last;
+	n->flags |= NODE_NOPRT;
+
 	if (mdoc->flags & MDOC_PBODY) {
 		mandoc_msg(MANDOCERR_DT_LATE, mdoc->parse,
 		    n->line, n->pos, "Dt");
-		goto out;
+		return;
 	}
 
 	if (mdoc->meta.title != NULL)
@@ -2047,7 +2196,7 @@ post_dt(POST_ARGS)
 			}
 	}
 
-	/* Mandatory second argument: section. */
+	/* Mandatory second argument: section. */
 
 	if (nn != NULL)
 		nn = nn->next;
@@ -2057,7 +2206,7 @@ post_dt(POST_ARGS)
 		    mdoc->parse, n->line, n->pos,
 		    "Dt %s", mdoc->meta.title);
 		mdoc->meta.vol = mandoc_strdup("LOCAL");
-		goto out;  /* msec and arch remain NULL. */
+		return;  /* msec and arch remain NULL. */
 	}
 
 	mdoc->meta.msec = mandoc_strdup(nn->string);
@@ -2075,7 +2224,7 @@ post_dt(POST_ARGS)
 	/* Optional third argument: architecture. */
 
 	if ((nn = nn->next) == NULL)
-		goto out;
+		return;
 
 	for (p = nn->string; *p != '\0'; p++)
 		*p = tolower((unsigned char)*p);
@@ -2086,15 +2235,41 @@ post_dt(POST_ARGS)
 	if ((nn = nn->next) != NULL)
 		mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse,
 		    nn->line, nn->pos, "Dt ... %s", nn->string);
-
-out:
-	roff_node_delete(mdoc, n);
 }
 
 static void
 post_bx(POST_ARGS)
 {
-	struct roff_node	*n;
+	struct roff_node	*n, *nch;
+
+	n = mdoc->last;
+	nch = n->child;
+
+	if (nch != NULL) {
+		mdoc->last = nch;
+		nch = nch->next;
+		mdoc->next = ROFF_NEXT_SIBLING;
+		roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Ns);
+		mdoc->last->flags |= NODE_NOSRC;
+		mdoc->next = ROFF_NEXT_SIBLING;
+	} else
+		mdoc->next = ROFF_NEXT_CHILD;
+	roff_word_alloc(mdoc, n->line, n->pos, "BSD");
+	mdoc->last->flags |= NODE_NOSRC;
+
+	if (nch == NULL) {
+		mdoc->last = n;
+		return;
+	}
+
+	roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Ns);
+	mdoc->last->flags |= NODE_NOSRC;
+	mdoc->next = ROFF_NEXT_SIBLING;
+	roff_word_alloc(mdoc, n->line, n->pos, "-");
+	mdoc->last->flags |= NODE_NOSRC;
+	roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Ns);
+	mdoc->last->flags |= NODE_NOSRC;
+	mdoc->last = n;
 
 	/*
 	 * Make `Bx's second argument always start with an uppercase
@@ -2102,8 +2277,7 @@ post_bx(POST_ARGS)
 	 * uppercase blindly.
 	 */
 
-	if ((n = mdoc->last->child) != NULL && (n = n->next) != NULL)
-		*n->string = (char)toupper((unsigned char)*n->string);
+	*nch->string = (char)toupper((unsigned char)*nch->string);
 }
 
 static void
@@ -2116,6 +2290,8 @@ post_os(POST_ARGS)
 	struct roff_node *n;
 
 	n = mdoc->last;
+	n->flags |= NODE_NOPRT;
+
 	if (mdoc->meta.os != NULL)
 		mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
 		    n->line, n->pos, "Os");
@@ -2136,11 +2312,11 @@ post_os(POST_ARGS)
 	mdoc->meta.os = NULL;
 	deroff(&mdoc->meta.os, n);
 	if (mdoc->meta.os)
-		goto out;
+		return;
 
 	if (mdoc->defos) {
 		mdoc->meta.os = mandoc_strdup(mdoc->defos);
-		goto out;
+		return;
 	}
 
 #ifdef OSNAME
@@ -2157,35 +2333,6 @@ post_os(POST_ARGS)
 	}
 	mdoc->meta.os = mandoc_strdup(defbuf);
 #endif /*!OSNAME*/
-
-out:
-	roff_node_delete(mdoc, n);
-}
-
-/*
- * If no argument is provided,
- * fill in the name of the current manual page.
- */
-static void
-post_ex(POST_ARGS)
-{
-	struct roff_node *n;
-
-	post_std(mdoc);
-
-	n = mdoc->last;
-	if (n->child != NULL)
-		return;
-
-	if (mdoc->meta.name == NULL) {
-		mandoc_msg(MANDOCERR_EX_NONAME, mdoc->parse,
-		    n->line, n->pos, "Ex");
-		return;
-	}
-
-	mdoc->next = ROFF_NEXT_CHILD;
-	roff_word_alloc(mdoc, n->line, n->pos, mdoc->meta.name);
-	mdoc->last = n;
 }
 
 enum roff_sec
diff --git a/contrib/mdocml/read.c b/contrib/mdocml/read.c
index 6cbcd2df007..d20a6098e9e 100644
--- a/contrib/mdocml/read.c
+++ b/contrib/mdocml/read.c
@@ -1,7 +1,7 @@
-/*	$Id: read.c,v 1.149 2016/07/10 13:34:30 schwarze Exp $ */
+/*	$Id: read.c,v 1.157 2017/01/09 01:37:03 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons 
- * Copyright (c) 2010-2016 Ingo Schwarze 
+ * Copyright (c) 2010-2017 Ingo Schwarze 
  * Copyright (c) 2010, 2012 Joerg Sonnenberger 
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -19,10 +19,8 @@
 #include "config.h"
 
 #include 
-#if HAVE_MMAP
 #include 
 #include 
-#endif
 
 #include 
 #include 
@@ -110,10 +108,11 @@ static	const char * const	mandocerrs[MANDOCERR_MAX] = {
 	"no document body",
 	"content before first section header",
 	"first section is not \"NAME\"",
-	"NAME section without name",
+	"NAME section without Nm before Nd",
 	"NAME section without description",
 	"description not at the end of NAME",
 	"bad NAME section content",
+	"missing comma before name",
 	"missing description line, using \"\"",
 	"sections out of conventional order",
 	"duplicate section title",
@@ -143,7 +142,7 @@ static	const char * const	mandocerrs[MANDOCERR_MAX] = {
 	"empty argument, using 0n",
 	"missing display type, using -ragged",
 	"list type is not the first argument",
-	"missing -width in -tag list, using 8n",
+	"missing -width in -tag list, using 6n",
 	"missing utility name, using \"\"",
 	"missing function name, using \"\"",
 	"empty head in list item",
@@ -152,6 +151,7 @@ static	const char * const	mandocerrs[MANDOCERR_MAX] = {
 	"unknown font type, using \\fR",
 	"nothing follows prefix",
 	"empty reference block",
+	"missing section argument",
 	"missing -std argument, adding it",
 	"missing option string, using \"\"",
 	"missing resource identifier, using \"\"",
@@ -291,13 +291,6 @@ choose_parser(struct mparse *curp)
 		}
 	}
 
-	if (curp->man == NULL) {
-		curp->man = roff_man_alloc(curp->roff, curp, curp->defos,
-		    curp->options & MPARSE_QUICK ? 1 : 0);
-		curp->man->macroset = MACROSET_MAN;
-		curp->man->first->tok = TOKEN_NONE;
-	}
-
 	if (format == MPARSE_MDOC) {
 		mdoc_hash_init();
 		curp->man->macroset = MACROSET_MDOC;
@@ -324,6 +317,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
 	const char	*save_file;
 	char		*cp;
 	size_t		 pos; /* byte number in the ln buffer */
+	size_t		 j;  /* auxiliary byte number in the blk buffer */
 	enum rofferr	 rr;
 	int		 of;
 	int		 lnn; /* line number in the real file */
@@ -429,14 +423,21 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
 			}
 
 			if ('"' == blk.buf[i + 1] || '#' == blk.buf[i + 1]) {
+				j = i;
 				i += 2;
 				/* Comment, skip to end of line */
 				for (; i < blk.sz; ++i) {
-					if ('\n' == blk.buf[i]) {
-						++i;
-						++lnn;
-						break;
-					}
+					if (blk.buf[i] != '\n')
+						continue;
+					if (blk.buf[i - 1] == ' ' ||
+					    blk.buf[i - 1] == '\t')
+						mandoc_msg(
+						    MANDOCERR_SPACE_EOL,
+						    curp, curp->line,
+						    pos + i-1 - j, NULL);
+					++i;
+					++lnn;
+					break;
 				}
 
 				/* Backout trailing whitespaces */
@@ -562,15 +563,7 @@ rerun:
 			break;
 		}
 
-		/*
-		 * If input parsers have not been allocated, do so now.
-		 * We keep these instanced between parsers, but set them
-		 * locally per parse routine since we can use different
-		 * parsers with each one.
-		 */
-
-		if (curp->man == NULL ||
-		    curp->man->macroset == MACROSET_NONE)
+		if (curp->man->macroset == MACROSET_NONE)
 			choose_parser(curp);
 
 		/*
@@ -613,7 +606,6 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
 	size_t		 off;
 	ssize_t		 ssz;
 
-#if HAVE_MMAP
 	struct stat	 st;
 
 	if (fstat(fd, &st) == -1)
@@ -637,7 +629,6 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
 		if (fb->buf != MAP_FAILED)
 			return 1;
 	}
-#endif
 
 	if (curp->gzip) {
 		if ((gz = gzdopen(fd, "rb")) == NULL)
@@ -683,10 +674,6 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
 static void
 mparse_end(struct mparse *curp)
 {
-
-	if (curp->man == NULL && curp->sodest == NULL)
-		curp->man = roff_man_alloc(curp->roff, curp, curp->defos,
-		    curp->options & MPARSE_QUICK ? 1 : 0);
 	if (curp->man->macroset == MACROSET_NONE)
 		curp->man->macroset = MACROSET_MAN;
 	if (curp->man->macroset == MACROSET_MDOC)
@@ -766,11 +753,9 @@ mparse_readfd(struct mparse *curp, int fd, const char *file)
 		    (MPARSE_UTF8 | MPARSE_LATIN1);
 		mparse_parse_buffer(curp, blk, file);
 		curp->filenc = save_filenc;
-#if HAVE_MMAP
 		if (with_mmap)
 			munmap(blk.buf, blk.sz);
 		else
-#endif
 			free(blk.buf);
 	}
 	return curp->file_status;
@@ -842,11 +827,8 @@ mparse_alloc(int options, enum mandoclevel wlevel, mandocmsg mmsg,
 void
 mparse_reset(struct mparse *curp)
 {
-
 	roff_reset(curp->roff);
-
-	if (curp->man != NULL)
-		roff_man_reset(curp->man);
+	roff_man_reset(curp->man);
 	if (curp->secondary)
 		curp->secondary->sz = 0;
 
@@ -884,6 +866,13 @@ mparse_result(struct mparse *curp, struct roff_man **man,
 		*man = curp->man;
 }
 
+void
+mparse_updaterc(struct mparse *curp, enum mandoclevel *rc)
+{
+	if (curp->file_status > *rc)
+		*rc = curp->file_status;
+}
+
 void
 mandoc_vmsg(enum mandocerr t, struct mparse *m,
 		int ln, int pos, const char *fmt, ...)
diff --git a/contrib/mdocml/roff.c b/contrib/mdocml/roff.c
index 13b9439e4df..966ed9d53dd 100644
--- a/contrib/mdocml/roff.c
+++ b/contrib/mdocml/roff.c
@@ -1,7 +1,7 @@
-/*	$Id: roff.c,v 1.284 2016/01/08 17:48:10 schwarze Exp $ */
+/*	$Id: roff.c,v 1.288 2017/01/12 18:02:20 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons 
- * Copyright (c) 2010-2015 Ingo Schwarze 
+ * Copyright (c) 2010-2015, 2017 Ingo Schwarze 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -991,11 +991,11 @@ roff_node_alloc(struct roff_man *man, int line, int pos,
 	n->sec = man->lastsec;
 
 	if (man->flags & MDOC_SYNOPSIS)
-		n->flags |= MDOC_SYNPRETTY;
+		n->flags |= NODE_SYNPRETTY;
 	else
-		n->flags &= ~MDOC_SYNPRETTY;
+		n->flags &= ~NODE_SYNPRETTY;
 	if (man->flags & MDOC_NEWLINE)
-		n->flags |= MDOC_LINE;
+		n->flags |= NODE_LINE;
 	man->flags &= ~MDOC_NEWLINE;
 
 	return n;
@@ -1017,9 +1017,13 @@ roff_node_append(struct roff_man *man, struct roff_node *n)
 		n->parent = man->last->parent;
 		break;
 	case ROFF_NEXT_CHILD:
+		if (man->last->child != NULL) {
+			n->next = man->last->child;
+			man->last->child->prev = n;
+		} else
+			man->last->last = n;
 		man->last->child = n;
 		n->parent = man->last;
-		n->parent->last = n;
 		break;
 	default:
 		abort();
@@ -1059,10 +1063,7 @@ roff_word_alloc(struct roff_man *man, int line, int pos, const char *word)
 	n = roff_node_alloc(man, line, pos, ROFFT_TEXT, TOKEN_NONE);
 	n->string = roff_strdup(man->roff, word);
 	roff_node_append(man, n);
-	if (man->macroset == MACROSET_MDOC)
-		n->flags |= MDOC_VALID | MDOC_ENDED;
-	else
-		n->flags |= MAN_VALID;
+	n->flags |= NODE_VALID | NODE_ENDED;
 	man->next = ROFF_NEXT_SIBLING;
 }
 
@@ -1132,7 +1133,7 @@ roff_addeqn(struct roff_man *man, const struct eqn *eqn)
 	n = roff_node_alloc(man, eqn->ln, eqn->pos, ROFFT_EQN, TOKEN_NONE);
 	n->eqn = eqn;
 	if (eqn->ln > man->last->line)
-		n->flags |= MDOC_LINE;
+		n->flags |= NODE_LINE;
 	roff_node_append(man, n);
 	man->next = ROFF_NEXT_SIBLING;
 }
@@ -1147,10 +1148,7 @@ roff_addtbl(struct roff_man *man, const struct tbl_span *tbl)
 	n = roff_node_alloc(man, tbl->line, 0, ROFFT_TBL, TOKEN_NONE);
 	n->span = tbl;
 	roff_node_append(man, n);
-	if (man->macroset == MACROSET_MDOC)
-		n->flags |= MDOC_VALID | MDOC_ENDED;
-	else
-		n->flags |= MAN_VALID;
+	n->flags |= NODE_VALID | NODE_ENDED;
 	man->next = ROFF_NEXT_SIBLING;
 }
 
@@ -1225,16 +1223,12 @@ deroff(char **dest, const struct roff_node *n)
 		return;
 	}
 
-	/* Skip leading whitespace and escape sequences. */
+	/* Skip leading whitespace. */
 
-	cp = n->string;
-	while (*cp != '\0') {
-		if ('\\' == *cp) {
+	for (cp = n->string; *cp != '\0'; cp++) {
+		if (cp[0] == '\\' && strchr(" %&0^|~", cp[1]) != NULL)
 			cp++;
-			mandoc_escape((const char **)&cp, NULL, NULL);
-		} else if (isspace((unsigned char)*cp))
-			cp++;
-		else
+		else if ( ! isspace((unsigned char)*cp))
 			break;
 	}
 
diff --git a/contrib/mdocml/roff.h b/contrib/mdocml/roff.h
index 19ec50f42e5..3039d4e9f53 100644
--- a/contrib/mdocml/roff.h
+++ b/contrib/mdocml/roff.h
@@ -1,7 +1,7 @@
-/*	$OpenBSD$	*/
+/*	$Id: roff.h,v 1.39 2017/01/10 13:47:00 schwarze Exp $	*/
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons 
- * Copyright (c) 2013, 2014, 2015 Ingo Schwarze 
+ * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -98,17 +98,16 @@ struct	roff_node {
 	int		  tok;     /* Request or macro ID. */
 #define	TOKEN_NONE	 (-1)	   /* No request or macro. */
 	int		  flags;
-#define	MDOC_VALID	 (1 << 0)  /* Has been validated. */
-#define	MDOC_ENDED	 (1 << 1)  /* Gone past body end mark. */
-#define MDOC_EOS	 (1 << 2)  /* At sentence boundary. */
-#define	MDOC_LINE	 (1 << 3)  /* First macro/text on line. */
-#define MDOC_SYNPRETTY	 (1 << 4)  /* SYNOPSIS-style formatting. */
-#define MDOC_BROKEN	 (1 << 5)  /* Must validate parent when ending. */
-#define	MDOC_DELIMO	 (1 << 6)
-#define	MDOC_DELIMC	 (1 << 7)
-#define	MAN_VALID	  MDOC_VALID
-#define	MAN_EOS		  MDOC_EOS
-#define	MAN_LINE	  MDOC_LINE
+#define	NODE_VALID	 (1 << 0)  /* Has been validated. */
+#define	NODE_ENDED	 (1 << 1)  /* Gone past body end mark. */
+#define	NODE_EOS	 (1 << 2)  /* At sentence boundary. */
+#define	NODE_LINE	 (1 << 3)  /* First macro/text on line. */
+#define	NODE_SYNPRETTY	 (1 << 4)  /* SYNOPSIS-style formatting. */
+#define	NODE_BROKEN	 (1 << 5)  /* Must validate parent when ending. */
+#define	NODE_DELIMO	 (1 << 6)
+#define	NODE_DELIMC	 (1 << 7)
+#define	NODE_NOSRC	 (1 << 8)  /* Generated node, not in input file. */
+#define	NODE_NOPRT	 (1 << 9)  /* Shall not print anything. */
 	int		  prev_font; /* Before entering this node. */
 	int		  aux;     /* Decoded node data, type-dependent. */
 	enum roff_type	  type;    /* AST node type. */
diff --git a/contrib/mdocml/tag.c b/contrib/mdocml/tag.c
index baedf15ad9e..0fbd2e10597 100644
--- a/contrib/mdocml/tag.c
+++ b/contrib/mdocml/tag.c
@@ -1,6 +1,6 @@
-/*      $Id: tag.c,v 1.12 2016/07/08 20:42:15 schwarze Exp $    */
+/*	$Id: tag.c,v 1.17 2017/01/09 17:49:58 schwarze Exp $ */
 /*
- * Copyright (c) 2015 Ingo Schwarze 
+ * Copyright (c) 2015, 2016 Ingo Schwarze 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -31,12 +31,14 @@
 #include "tag.h"
 
 struct tag_entry {
-	size_t	 line;
+	size_t	*lines;
+	size_t	 maxlines;
+	size_t	 nlines;
 	int	 prio;
 	char	 s[];
 };
 
-static	void	 tag_signal(int);
+static	void	 tag_signal(int) __attribute__((noreturn));
 
 static struct ohash	 tag_data;
 static struct tag_files	 tag_files;
@@ -128,18 +130,58 @@ tag_put(const char *s, int prio, size_t line)
 	size_t			 len;
 	unsigned int		 slot;
 
-	if (tag_files.tfd <= 0 || strchr(s, ' ') != NULL)
+	/* Sanity checks. */
+
+	if (tag_files.tfd <= 0)
 		return;
+	if (s[0] == '\\' && (s[1] == '&' || s[1] == 'e'))
+		s += 2;
+	if (*s == '\0' || strchr(s, ' ') != NULL)
+		return;
+
 	slot = ohash_qlookup(&tag_data, s);
 	entry = ohash_find(&tag_data, slot);
+
 	if (entry == NULL) {
+
+		/* Build a new entry. */
+
 		len = strlen(s) + 1;
 		entry = mandoc_malloc(sizeof(*entry) + len);
 		memcpy(entry->s, s, len);
+		entry->lines = NULL;
+		entry->maxlines = entry->nlines = 0;
 		ohash_insert(&tag_data, slot, entry);
-	} else if (entry->prio <= prio)
-		return;
-	entry->line = line;
+
+	} else {
+
+		/* Handle priority 0 entries. */
+
+		if (prio == 0) {
+			if (entry->prio == 0)
+				entry->prio = -1;
+			return;
+		}
+
+		/* A better entry is already present, ignore the new one. */
+
+		if (entry->prio > 0 && entry->prio < prio)
+			return;
+
+		/* The existing entry is worse, clear it. */
+
+		if (entry->prio < 1 || entry->prio > prio)
+			entry->nlines = 0;
+	}
+
+	/* Remember the new line. */
+
+	if (entry->maxlines == entry->nlines) {
+		entry->maxlines += 4;
+		entry->lines = mandoc_reallocarray(entry->lines,
+		    entry->maxlines, sizeof(*entry->lines));
+	}
+	entry->lines[entry->nlines++] = line;
 	entry->prio = prio;
 }
 
@@ -152,6 +194,7 @@ tag_write(void)
 {
 	FILE			*stream;
 	struct tag_entry	*entry;
+	size_t			 i;
 	unsigned int		 slot;
 
 	if (tag_files.tfd <= 0)
@@ -159,9 +202,11 @@ tag_write(void)
 	stream = fdopen(tag_files.tfd, "w");
 	entry = ohash_first(&tag_data, &slot);
 	while (entry != NULL) {
-		if (stream != NULL)
-			fprintf(stream, "%s %s %zu\n",
-			    entry->s, tag_files.ofn, entry->line);
+		if (stream != NULL && entry->prio >= 0)
+			for (i = 0; i < entry->nlines; i++)
+				fprintf(stream, "%s %s %zu\n",
+				    entry->s, tag_files.ofn, entry->lines[i]);
+		free(entry->lines);
 		free(entry);
 		entry = ohash_next(&tag_data, &slot);
 	}
@@ -176,11 +221,11 @@ tag_unlink(void)
 	pid_t	 tc_pgid;
 
 	if (tag_files.tcpgid != -1) {
-		tc_pgid = tcgetpgrp(STDIN_FILENO);
+		tc_pgid = tcgetpgrp(tag_files.ofd);
 		if (tc_pgid == tag_files.pager_pid ||
 		    tc_pgid == getpgid(0) ||
 		    getpgid(tc_pgid) == -1)
-			(void)tcsetpgrp(STDIN_FILENO, tag_files.tcpgid);
+			(void)tcsetpgrp(tag_files.ofd, tag_files.tcpgid);
 	}
 	if (*tag_files.ofn != '\0')
 		unlink(tag_files.ofn);
diff --git a/contrib/mdocml/tbl_html.c b/contrib/mdocml/tbl_html.c
index 51c43286cbe..962d900e368 100644
--- a/contrib/mdocml/tbl_html.c
+++ b/contrib/mdocml/tbl_html.c
@@ -1,7 +1,7 @@
-/*	$Id: tbl_html.c,v 1.18 2015/10/12 00:08:16 schwarze Exp $ */
+/*	$Id: tbl_html.c,v 1.19 2017/01/17 01:47:51 schwarze Exp $ */
 /*
  * Copyright (c) 2011 Kristaps Dzonsons 
- * Copyright (c) 2014, 2015 Ingo Schwarze 
+ * Copyright (c) 2014, 2015, 2017 Ingo Schwarze 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -50,9 +50,6 @@ html_tbl_strlen(const char *p, void *arg)
 static void
 html_tblopen(struct html *h, const struct tbl_span *sp)
 {
-	struct htmlpair	 tag;
-	struct roffsu	 su;
-	struct roffcol	*col;
 	int		 ic;
 
 	if (h->tbl.cols == NULL) {
@@ -62,19 +59,12 @@ html_tblopen(struct html *h, const struct tbl_span *sp)
 	}
 
 	assert(NULL == h->tblt);
-	PAIR_CLASS_INIT(&tag, "tbl");
-	h->tblt = print_otag(h, TAG_TABLE, 1, &tag);
+	h->tblt = print_otag(h, TAG_TABLE, "c", "tbl");
 
-	for (ic = 0; ic < sp->opts->cols; ic++) {
-		bufinit(h);
-		col = h->tbl.cols + ic;
-		SCALE_HS_INIT(&su, col->width);
-		bufcat_su(h, "width", &su);
-		PAIR_STYLE_INIT(&tag, h);
-		print_otag(h, TAG_COL, 1, &tag);
-	}
+	for (ic = 0; ic < sp->opts->cols; ic++)
+		print_otag(h, TAG_COL, "shw", h->tbl.cols[ic].width);
 
-	print_otag(h, TAG_TBODY, 0, NULL);
+	print_otag(h, TAG_TBODY, "");
 }
 
 void
@@ -90,7 +80,6 @@ void
 print_tbl(struct html *h, const struct tbl_span *sp)
 {
 	const struct tbl_dat *dp;
-	struct htmlpair	 tag;
 	struct tag	*tt;
 	int		 ic;
 
@@ -104,19 +93,18 @@ print_tbl(struct html *h, const struct tbl_span *sp)
 	h->flags |= HTML_NONOSPACE;
 	h->flags |= HTML_NOSPACE;
 
-	tt = print_otag(h, TAG_TR, 0, NULL);
+	tt = print_otag(h, TAG_TR, "");
 
 	switch (sp->pos) {
 	case TBL_SPAN_HORIZ:
 	case TBL_SPAN_DHORIZ:
-		PAIR_INIT(&tag, ATTR_COLSPAN, "0");
-		print_otag(h, TAG_TD, 1, &tag);
+		print_otag(h, TAG_TD, "?", "colspan", "0");
 		break;
 	default:
 		dp = sp->first;
 		for (ic = 0; ic < sp->opts->cols; ic++) {
 			print_stagq(h, tt);
-			print_otag(h, TAG_TD, 0, NULL);
+			print_otag(h, TAG_TD, "");
 
 			if (dp == NULL || dp->layout->col > ic)
 				continue;
diff --git a/contrib/mdocml/term.c b/contrib/mdocml/term.c
index 0fd8f7c0197..1217d473cad 100644
--- a/contrib/mdocml/term.c
+++ b/contrib/mdocml/term.c
@@ -1,7 +1,7 @@
-/*	$Id: term.c,v 1.257 2016/04/12 15:30:00 schwarze Exp $ */
+/*	$Id: term.c,v 1.259 2017/01/08 18:16:58 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons 
- * Copyright (c) 2010-2015 Ingo Schwarze 
+ * Copyright (c) 2010-2017 Ingo Schwarze 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -504,7 +504,9 @@ term_word(struct termp *p, const char *word)
 				}
 			}
 			/* Trim trailing backspace/blank pair. */
-			if (p->col > 2 && p->buf[p->col - 1] == ' ')
+			if (p->col > 2 &&
+			    (p->buf[p->col - 1] == ' ' ||
+			     p->buf[p->col - 1] == '\t'))
 				p->col -= 2;
 			continue;
 		default:
@@ -568,7 +570,7 @@ encode1(struct termp *p, int c)
 	    p->fontq[p->fonti] : TERMFONT_NONE;
 
 	if (p->flags & TERMP_BACKBEFORE) {
-		if (p->buf[p->col - 1] == ' ')
+		if (p->buf[p->col - 1] == ' ' || p->buf[p->col - 1] == '\t')
 			p->col--;
 		else
 			p->buf[p->col++] = 8;
@@ -604,8 +606,20 @@ encode(struct termp *p, const char *word, size_t sz)
 		if (ASCII_HYPH == word[i] ||
 		    isgraph((unsigned char)word[i]))
 			encode1(p, word[i]);
-		else
+		else {
 			p->buf[p->col++] = word[i];
+
+			/*
+			 * Postpone the effect of \z while handling
+			 * an overstrike sequence from ascii_uc2str().
+			 */
+
+			if (word[i] == '\b' &&
+			    (p->flags & TERMP_BACKBEFORE)) {
+				p->flags &= ~TERMP_BACKBEFORE;
+				p->flags |= TERMP_BACKAFTER;
+			}
+		}
 	}
 }
 
diff --git a/contrib/mdocml/term_ascii.c b/contrib/mdocml/term_ascii.c
index fecdb0a964d..df5ff13901c 100644
--- a/contrib/mdocml/term_ascii.c
+++ b/contrib/mdocml/term_ascii.c
@@ -1,4 +1,4 @@
-/*	$Id: term_ascii.c,v 1.53 2016/07/08 22:29:05 schwarze Exp $ */
+/*	$Id: term_ascii.c,v 1.54 2016/07/31 09:29:13 schwarze Exp $ */
 /*
  * Copyright (c) 2010, 2011 Kristaps Dzonsons 
  * Copyright (c) 2014, 2015 Ingo Schwarze 
@@ -98,7 +98,7 @@ ascii_init(enum termenc enc, const struct manoutput *outopts)
 
 		v = TERMENC_LOCALE == enc ?
 		    setlocale(LC_CTYPE, "") :
-		    setlocale(LC_CTYPE, "en_US.UTF-8");
+		    setlocale(LC_CTYPE, UTF8_LOCALE);
 		if (NULL != v && MB_CUR_MAX > 1) {
 			p->enc = enc;
 			p->advance = locale_advance;
diff --git a/contrib/mdocml/term_ps.c b/contrib/mdocml/term_ps.c
index 6105d5589fc..286a89f91a6 100644
--- a/contrib/mdocml/term_ps.c
+++ b/contrib/mdocml/term_ps.c
@@ -1,7 +1,7 @@
-/*	$Id: term_ps.c,v 1.80 2015/12/23 20:50:13 schwarze Exp $ */
+/*	$Id: term_ps.c,v 1.82 2016/08/10 11:03:43 schwarze Exp $ */
 /*
  * Copyright (c) 2010, 2011 Kristaps Dzonsons 
- * Copyright (c) 2014, 2015 Ingo Schwarze 
+ * Copyright (c) 2014, 2015, 2016 Ingo Schwarze 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -98,15 +98,13 @@ static	void		  ps_begin(struct termp *);
 static	void		  ps_closepage(struct termp *);
 static	void		  ps_end(struct termp *);
 static	void		  ps_endline(struct termp *);
-static	void		  ps_fclose(struct termp *);
 static	void		  ps_growbuf(struct termp *, size_t);
 static	void		  ps_letter(struct termp *, int);
 static	void		  ps_pclose(struct termp *);
+static	void		  ps_plast(struct termp *);
 static	void		  ps_pletter(struct termp *, int);
-#if __GNUC__ - 0 >= 4
-__attribute__((__format__ (__printf__, 2, 3)))
-#endif
-static	void		  ps_printf(struct termp *, const char *, ...);
+static	void		  ps_printf(struct termp *, const char *, ...)
+				__attribute__((__format__ (printf, 2, 3)));
 static	void		  ps_putchar(struct termp *, char);
 static	void		  ps_setfont(struct termp *, enum termfont);
 static	void		  ps_setwidth(struct termp *, int, int);
@@ -782,6 +780,9 @@ ps_end(struct termp *p)
 {
 	size_t		 i, xref, base;
 
+	ps_plast(p);
+	ps_pclose(p);
+
 	/*
 	 * At the end of the file, do one last showpage.  This is the
 	 * same behaviour as groff(1) and works for multiple pages as
@@ -1025,39 +1026,53 @@ ps_pclose(struct termp *p)
 	p->ps->flags &= ~PS_INLINE;
 }
 
+/* If we have a `last' char that wasn't printed yet, print it now. */
 static void
-ps_fclose(struct termp *p)
+ps_plast(struct termp *p)
 {
+	size_t	 wx;
 
-	/*
-	 * Strong closure: if we have a last-char, spit it out after
-	 * checking that we're in the right font mode.  This will of
-	 * course open a new scope, if applicable.
-	 *
-	 * Following this, close out any scope that's open.
-	 */
-
-	if (p->ps->last != '\0') {
-		assert( ! (p->ps->flags & PS_BACKSP));
-		if (p->ps->nextf != p->ps->lastf) {
-			ps_pclose(p);
-			ps_setfont(p, p->ps->nextf);
-		}
-		p->ps->nextf = TERMFONT_NONE;
-		ps_pletter(p, p->ps->last);
-		p->ps->last = '\0';
-	}
-
-	if ( ! (PS_INLINE & p->ps->flags))
+	if (p->ps->last == '\0')
 		return;
 
-	ps_pclose(p);
+	/* Check the font mode; open a new scope if it doesn't match. */
+
+	if (p->ps->nextf != p->ps->lastf) {
+		ps_pclose(p);
+		ps_setfont(p, p->ps->nextf);
+	}
+	p->ps->nextf = TERMFONT_NONE;
+
+	/*
+	 * For an overstrike, if a previous character
+	 * was wider, advance to center the new one.
+	 */
+
+	if (p->ps->pscolnext) {
+		wx = fonts[p->ps->lastf].gly[(int)p->ps->last-32].wx;
+		if (p->ps->pscol + wx < p->ps->pscolnext)
+			p->ps->pscol = (p->ps->pscol +
+			    p->ps->pscolnext - wx) / 2;
+	}
+
+	ps_pletter(p, p->ps->last);
+	p->ps->last = '\0';
+
+	/*
+	 * For an overstrike, if a previous character
+	 * was wider, advance to the end of the old one.
+	 */
+
+	if (p->ps->pscol < p->ps->pscolnext) {
+		ps_pclose(p);
+		p->ps->pscol = p->ps->pscolnext;
+	}
 }
 
 static void
 ps_letter(struct termp *p, int arg)
 {
-	size_t		savecol, wx;
+	size_t		savecol;
 	char		c;
 
 	c = arg >= 128 || arg <= 0 ? '?' : arg;
@@ -1123,43 +1138,12 @@ ps_letter(struct termp *p, int arg)
 	 * Use them and print it.
 	 */
 
-	if (p->ps->last != '\0') {
-		if (p->ps->nextf != p->ps->lastf) {
-			ps_pclose(p);
-			ps_setfont(p, p->ps->nextf);
-		}
-		p->ps->nextf = TERMFONT_NONE;
-
-		/*
-		 * For an overstrike, if a previous character
-		 * was wider, advance to center the new one.
-		 */
-
-		if (p->ps->pscolnext) {
-			wx = fonts[p->ps->lastf].gly[(int)p->ps->last-32].wx;
-			if (p->ps->pscol + wx < p->ps->pscolnext)
-				p->ps->pscol = (p->ps->pscol +
-				    p->ps->pscolnext - wx) / 2;
-		}
-
-		ps_pletter(p, p->ps->last);
-
-		/*
-		 * For an overstrike, if a previous character
-		 * was wider, advance to the end of the old one.
-		 */
-
-		if (p->ps->pscol < p->ps->pscolnext) {
-			ps_pclose(p);
-			p->ps->pscol = p->ps->pscolnext;
-		}
-	}
+	ps_plast(p);
 
 	/*
 	 * Do not print the current character yet because font
-	 * instructions might follow; only remember it.
-	 * For the first character, nothing else is done.
-	 * The final character will get printed from ps_fclose().
+	 * instructions might follow; only remember the character.
+	 * It will get printed later from ps_plast().
 	 */
 
 	p->ps->last = c;
@@ -1192,7 +1176,8 @@ ps_advance(struct termp *p, size_t len)
 	 * and readjust our column settings.
 	 */
 
-	ps_fclose(p);
+	ps_plast(p);
+	ps_pclose(p);
 	p->ps->pscol += len;
 }
 
@@ -1202,7 +1187,8 @@ ps_endline(struct termp *p)
 
 	/* Close out any scopes we have open: we're at eoln. */
 
-	ps_fclose(p);
+	ps_plast(p);
+	ps_pclose(p);
 
 	/*
 	 * If we're in the margin, don't try to recalculate our current
diff --git a/contrib/mdocml/test-EFTYPE.c b/contrib/mdocml/test-EFTYPE.c
new file mode 100644
index 00000000000..148f54f769e
--- /dev/null
+++ b/contrib/mdocml/test-EFTYPE.c
@@ -0,0 +1,7 @@
+#include 
+
+int
+main(void)
+{
+	return !EFTYPE;
+}
diff --git a/contrib/mdocml/test-PATH_MAX.c b/contrib/mdocml/test-PATH_MAX.c
new file mode 100644
index 00000000000..99bcc0b4869
--- /dev/null
+++ b/contrib/mdocml/test-PATH_MAX.c
@@ -0,0 +1,30 @@
+/*
+ * POSIX allows PATH_MAX to not be defined, see
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html;
+ * the GNU Hurd is an example of a system not having it.
+ *
+ * Arguably, it would be better to test sysconf(_SC_PATH_MAX),
+ * but since the individual *.c files include "config.h" before
+ * , overriding an excessive value of PATH_MAX from
+ * "config.h" is impossible anyway, so for now, the simplest
+ * fix is to provide a value only on systems not having any.
+ * So far, we encountered no system defining PATH_MAX to an
+ * impractically large value, even though POSIX explicitly
+ * allows that.
+ *
+ * The real fix would be to replace all static buffers of size
+ * PATH_MAX by dynamically allocated buffers.  But that is
+ * somewhat intrusive because it touches several files and
+ * because it requires changing struct mlink in mandocdb.c.
+ * So i'm postponing that for now.
+ */
+
+#include 
+#include 
+
+int
+main(void)
+{
+	printf("PATH_MAX is defined to be %ld\n", (long)PATH_MAX);
+	return 0;
+}
diff --git a/contrib/mdocml/test-be32toh.c b/contrib/mdocml/test-be32toh.c
new file mode 100644
index 00000000000..471e85ea5e4
--- /dev/null
+++ b/contrib/mdocml/test-be32toh.c
@@ -0,0 +1,11 @@
+#ifdef SYS_ENDIAN
+#include 
+#else
+#include 
+#endif
+
+int
+main(void)
+{
+	return htobe32(be32toh(0x3a7d0cdb)) != 0x3a7d0cdb;
+}
diff --git a/contrib/mdocml/test-fts.c b/contrib/mdocml/test-fts.c
index dbee52926d4..23e44152576 100644
--- a/contrib/mdocml/test-fts.c
+++ b/contrib/mdocml/test-fts.c
@@ -2,6 +2,13 @@
 #include 
 #include 
 #include 
+#include 
+
+#ifdef FTS_COMPARE_CONST
+int fts_compare(const FTSENT *const *, const FTSENT *const *);
+#else
+int fts_compare(const FTSENT **, const FTSENT **);
+#endif
 
 int
 main(void)
@@ -14,7 +21,7 @@ main(void)
 	argv[1] = (char *)NULL;
 
 	ftsp = fts_open((char * const *)argv,
-	    FTS_PHYSICAL | FTS_NOCHDIR, NULL);
+	    FTS_PHYSICAL | FTS_NOCHDIR, fts_compare);
 
 	if (ftsp == NULL) {
 		perror("fts_open");
@@ -40,3 +47,13 @@ main(void)
 
 	return 0;
 }
+
+int
+#ifdef FTS_COMPARE_CONST
+fts_compare(const FTSENT *const *a, const FTSENT *const *b)
+#else
+fts_compare(const FTSENT **a, const FTSENT **b)
+#endif
+{
+	return strcmp((*a)->fts_name, (*b)->fts_name);
+}
diff --git a/contrib/mdocml/test-mmap.c b/contrib/mdocml/test-mmap.c
deleted file mode 100644
index 3a6232d9ce9..00000000000
--- a/contrib/mdocml/test-mmap.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#include 
-#include 
-#include 
-
-int
-main(void)
-{
-	return mmap(NULL, 1, PROT_READ, MAP_SHARED, -1, 0) != MAP_FAILED;
-}
diff --git a/contrib/mdocml/test-nanosleep.c b/contrib/mdocml/test-nanosleep.c
new file mode 100644
index 00000000000..4b25ca4cfbf
--- /dev/null
+++ b/contrib/mdocml/test-nanosleep.c
@@ -0,0 +1,17 @@
+#include 
+#include 
+
+int
+main(void)
+{
+	struct timespec	 timeout;
+
+	timeout.tv_sec = 0;
+	timeout.tv_nsec = 100000000;	/* 0.1 seconds */
+	
+	if (nanosleep(&timeout, NULL)) {
+		perror("nanosleep");
+		return 1;
+	}
+	return 0;
+}
diff --git a/contrib/mdocml/test-ntohl.c b/contrib/mdocml/test-ntohl.c
new file mode 100644
index 00000000000..52dcc256ff5
--- /dev/null
+++ b/contrib/mdocml/test-ntohl.c
@@ -0,0 +1,7 @@
+#include 
+
+int
+main(void)
+{
+	return htonl(ntohl(0x3a7d0cdb)) != 0x3a7d0cdb;
+}
diff --git a/contrib/mdocml/test-ohash.c b/contrib/mdocml/test-ohash.c
index 138d520d1c4..1844fe56ad8 100644
--- a/contrib/mdocml/test-ohash.c
+++ b/contrib/mdocml/test-ohash.c
@@ -3,9 +3,27 @@
 #include 
 #include 
 
-void *xmalloc(size_t sz, void *arg) { return calloc(1,sz); }
-void *xcalloc(size_t nmemb, size_t sz, void *arg) { return calloc(nmemb,sz); }
-void xfree(void *p, void *arg) { free(p); }
+static void	*xmalloc(size_t, void *);
+static void	*xcalloc(size_t, size_t, void *);
+static void	 xfree(void *, void *);
+
+
+static void *
+xmalloc(size_t sz, void *arg) {
+	return calloc(1,sz);
+}
+
+static void *
+xcalloc(size_t nmemb, size_t sz, void *arg)
+{
+	return calloc(nmemb,sz);
+}
+
+static void
+xfree(void *p, void *arg)
+{
+	free(p);
+}
 
 int
 main(void)
diff --git a/contrib/mdocml/test-sandbox_init.c b/contrib/mdocml/test-sandbox_init.c
new file mode 100644
index 00000000000..a4902ee6166
--- /dev/null
+++ b/contrib/mdocml/test-sandbox_init.c
@@ -0,0 +1,13 @@
+#include 
+
+int
+main(void)
+{
+	char	*ep;
+	int	 rc;
+
+	rc = sandbox_init(kSBXProfileNoInternet, SANDBOX_NAMED, &ep);
+	if (-1 == rc)
+		sandbox_free_error(ep);
+	return(-1 == rc);
+}
diff --git a/contrib/mdocml/test-sqlite3.c b/contrib/mdocml/test-sqlite3.c
deleted file mode 100644
index 11f17adcbbb..00000000000
--- a/contrib/mdocml/test-sqlite3.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*	$Id: test-sqlite3.c,v 1.2 2015/10/06 18:32:20 schwarze Exp $	*/
-/*
- * Copyright (c) 2014 Ingo Schwarze 
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include 
-#include 
-#include 
-
-int
-main(void)
-{
-	sqlite3	*db;
-
-	if (sqlite3_open_v2("test.db", &db,
-	    SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
-	    NULL) != SQLITE_OK) {
-		perror("test.db");
-		fprintf(stderr, "sqlite3_open_v2: %s", sqlite3_errmsg(db));
-		return 1;
-	}
-	unlink("test.db");
-
-	if (sqlite3_exec(db, "PRAGMA foreign_keys = ON",
-	    NULL, NULL, NULL) != SQLITE_OK) {
-		fprintf(stderr, "sqlite3_exec: %s", sqlite3_errmsg(db));
-		return 1;
-	}
-
-	if (sqlite3_close(db) != SQLITE_OK) {
-		fprintf(stderr, "sqlite3_close: %s", sqlite3_errmsg(db));
-		return 1;
-	}
-	return 0;
-}
diff --git a/contrib/mdocml/test-sqlite3_errstr.c b/contrib/mdocml/test-sqlite3_errstr.c
deleted file mode 100644
index 4d3c7c54a5e..00000000000
--- a/contrib/mdocml/test-sqlite3_errstr.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include 
-#include 
-
-int
-main(void)
-{
-	return strcmp(sqlite3_errstr(SQLITE_OK), "not an error");
-}
diff --git a/contrib/mdocml/test-vasprintf.c b/contrib/mdocml/test-vasprintf.c
index bdb4408e300..ee6980a2895 100644
--- a/contrib/mdocml/test-vasprintf.c
+++ b/contrib/mdocml/test-vasprintf.c
@@ -1,4 +1,4 @@
-/*	$Id: test-vasprintf.c,v 1.3 2015/10/06 18:32:20 schwarze Exp $	*/
+/*	$Id: test-vasprintf.c,v 1.4 2016/07/18 18:35:05 schwarze Exp $	*/
 /*
  * Copyright (c) 2015 Ingo Schwarze 
  *
@@ -23,7 +23,10 @@
 #include 
 #include 
 
-int
+static int	 testfunc(char **, const char *, ...);
+
+
+static int
 testfunc(char **ret, const char *format, ...)
 {
 	va_list	 ap;
diff --git a/contrib/mdocml/test-wchar.c b/contrib/mdocml/test-wchar.c
index a096705ebcf..32962d9fe66 100644
--- a/contrib/mdocml/test-wchar.c
+++ b/contrib/mdocml/test-wchar.c
@@ -1,4 +1,4 @@
-/*	$Id: test-wchar.c,v 1.3 2015/10/06 18:32:20 schwarze Exp $	*/
+/*	$Id: test-wchar.c,v 1.4 2016/07/31 09:29:13 schwarze Exp $	*/
 /*
  * Copyright (c) 2014 Ingo Schwarze 
  *
@@ -35,9 +35,9 @@ main(void)
 		return 1;
 	}
 
-	if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL) {
-		fputs("setlocale(LC_CTYPE, \"en_US.UTF-8\") failed\n",
-		    stderr);
+	if (setlocale(LC_CTYPE, UTF8_LOCALE) == NULL) {
+		fprintf(stderr, "setlocale(LC_CTYPE, \"%s\") failed\n",
+		    UTF8_LOCALE);
 		return 1;
 	}
 
diff --git a/contrib/mdocml/tree.c b/contrib/mdocml/tree.c
index 52ca7547f44..9e68b69e5fb 100644
--- a/contrib/mdocml/tree.c
+++ b/contrib/mdocml/tree.c
@@ -1,7 +1,7 @@
-/*	$Id: tree.c,v 1.69 2015/10/12 00:08:16 schwarze Exp $ */
+/*	$Id: tree.c,v 1.72 2017/01/12 17:29:33 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons 
- * Copyright (c) 2013, 2014, 2015 Ingo Schwarze 
+ * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze 
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -33,6 +33,7 @@
 
 static	void	print_box(const struct eqn_box *, int);
 static	void	print_man(const struct roff_node *, int);
+static	void	print_meta(const struct roff_meta *);
 static	void	print_mdoc(const struct roff_node *, int);
 static	void	print_span(const struct tbl_span *, int);
 
@@ -40,17 +41,40 @@ static	void	print_span(const struct tbl_span *, int);
 void
 tree_mdoc(void *arg, const struct roff_man *mdoc)
 {
-
+	print_meta(&mdoc->meta);
+	putchar('\n');
 	print_mdoc(mdoc->first->child, 0);
 }
 
 void
 tree_man(void *arg, const struct roff_man *man)
 {
-
+	print_meta(&man->meta);
+	if (man->meta.hasbody == 0)
+		puts("body  = empty");
+	putchar('\n');
 	print_man(man->first->child, 0);
 }
 
+static void
+print_meta(const struct roff_meta *meta)
+{
+	if (meta->title != NULL)
+		printf("title = \"%s\"\n", meta->title);
+	if (meta->name != NULL)
+		printf("name  = \"%s\"\n", meta->name);
+	if (meta->msec != NULL)
+		printf("sec   = \"%s\"\n", meta->msec);
+	if (meta->vol != NULL)
+		printf("vol   = \"%s\"\n", meta->vol);
+	if (meta->arch != NULL)
+		printf("arch  = \"%s\"\n", meta->arch);
+	if (meta->os != NULL)
+		printf("os    = \"%s\"\n", meta->os);
+	if (meta->date != NULL)
+		printf("date  = \"%s\"\n", meta->date);
+}
+
 static void
 print_mdoc(const struct roff_node *n, int indent)
 {
@@ -159,15 +183,19 @@ print_mdoc(const struct roff_node *n, int indent)
 		}
 
 		putchar(' ');
-		if (MDOC_DELIMO & n->flags)
+		if (NODE_DELIMO & n->flags)
 			putchar('(');
-		if (MDOC_LINE & n->flags)
+		if (NODE_LINE & n->flags)
 			putchar('*');
 		printf("%d:%d", n->line, n->pos + 1);
-		if (MDOC_DELIMC & n->flags)
+		if (NODE_DELIMC & n->flags)
 			putchar(')');
-		if (MDOC_EOS & n->flags)
+		if (NODE_EOS & n->flags)
 			putchar('.');
+		if (NODE_NOSRC & n->flags)
+			printf(" NOSRC");
+		if (NODE_NOPRT & n->flags)
+			printf(" NOPRT");
 		putchar('\n');
 	}
 
@@ -248,10 +276,10 @@ print_man(const struct roff_node *n, int indent)
 		for (i = 0; i < indent; i++)
 			putchar(' ');
 		printf("%s (%s) ", p, t);
-		if (MAN_LINE & n->flags)
+		if (NODE_LINE & n->flags)
 			putchar('*');
 		printf("%d:%d", n->line, n->pos + 1);
-		if (MAN_EOS & n->flags)
+		if (NODE_EOS & n->flags)
 			putchar('.');
 		putchar('\n');
 	}
diff --git a/contrib/zlib/ChangeLog b/contrib/zlib/ChangeLog
index fed9adb5277..30199a65a03 100644
--- a/contrib/zlib/ChangeLog
+++ b/contrib/zlib/ChangeLog
@@ -1,6 +1,10 @@
 
                 ChangeLog file for zlib
 
+Changes in 1.2.11 (15 Jan 2017)
+- Fix deflate stored bug when pulling last block from window
+- Permit immediate deflateParams changes before any deflate input
+
 Changes in 1.2.10 (2 Jan 2017)
 - Avoid warnings on snprintf() return value
 - Fix bug in deflate_stored() for zero-length input
diff --git a/contrib/zlib/README b/contrib/zlib/README
index e2250bdbc2c..51106de4753 100644
--- a/contrib/zlib/README
+++ b/contrib/zlib/README
@@ -1,6 +1,6 @@
 ZLIB DATA COMPRESSION LIBRARY
 
-zlib 1.2.10 is a general purpose data compression library.  All the code is
+zlib 1.2.11 is a general purpose data compression library.  All the code is
 thread safe.  The data format used by the zlib library is described by RFCs
 (Request for Comments) 1950 to 1952 in the files
 http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
@@ -31,7 +31,7 @@ Mark Nelson  wrote an article about zlib for the Jan.  1997
 issue of Dr.  Dobb's Journal; a copy of the article is available at
 http://marknelson.us/1997/01/01/zlib-engine/ .
 
-The changes made in version 1.2.10 are documented in the file ChangeLog.
+The changes made in version 1.2.11 are documented in the file ChangeLog.
 
 Unsupported third party contributions are provided in directory contrib/ .
 
diff --git a/contrib/zlib/deflate.c b/contrib/zlib/deflate.c
index 2ad890e3547..1ec761448de 100644
--- a/contrib/zlib/deflate.c
+++ b/contrib/zlib/deflate.c
@@ -52,7 +52,7 @@
 #include "deflate.h"
 
 const char deflate_copyright[] =
-   " deflate 1.2.10 Copyright 1995-2017 Jean-loup Gailly and Mark Adler ";
+   " deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler ";
 /*
   If you use the zlib library in a product, an acknowledgment is welcome
   in the documentation of your product. If for some reason you cannot
@@ -586,7 +586,8 @@ int ZEXPORT deflateParams(strm, level, strategy)
     }
     func = configuration_table[s->level].func;
 
-    if ((strategy != s->strategy || func != configuration_table[level].func)) {
+    if ((strategy != s->strategy || func != configuration_table[level].func) &&
+        s->high_water) {
         /* Flush the last buffer: */
         int err = deflate(strm, Z_BLOCK);
         if (err == Z_STREAM_ERROR)
@@ -1671,8 +1672,6 @@ local block_state deflate_stored(s, flush)
             len = left + s->strm->avail_in;     /* limit len to the input */
         if (len > have)
             len = have;                         /* limit len to the output */
-        if (left > len)
-            left = len;                         /* limit window pull to len */
 
         /* If the stored block would be less than min_block in length, or if
          * unable to copy all of the available input when flushing, then try
@@ -1681,13 +1680,13 @@ local block_state deflate_stored(s, flush)
          */
         if (len < min_block && ((len == 0 && flush != Z_FINISH) ||
                                 flush == Z_NO_FLUSH ||
-                                len - left != s->strm->avail_in))
+                                len != left + s->strm->avail_in))
             break;
 
         /* Make a dummy stored block in pending to get the header bytes,
          * including any pending bits. This also updates the debugging counts.
          */
-        last = flush == Z_FINISH && len - left == s->strm->avail_in ? 1 : 0;
+        last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0;
         _tr_stored_block(s, (char *)0, 0L, last);
 
         /* Replace the lengths in the dummy stored block with len. */
@@ -1699,14 +1698,16 @@ local block_state deflate_stored(s, flush)
         /* Write the stored block header bytes. */
         flush_pending(s->strm);
 
-        /* Update debugging counts for the data about to be copied. */
 #ifdef ZLIB_DEBUG
+        /* Update debugging counts for the data about to be copied. */
         s->compressed_len += len << 3;
         s->bits_sent += len << 3;
 #endif
 
         /* Copy uncompressed bytes from the window to next_out. */
         if (left) {
+            if (left > len)
+                left = len;
             zmemcpy(s->strm->next_out, s->window + s->block_start, left);
             s->strm->next_out += left;
             s->strm->avail_out -= left;
@@ -1756,6 +1757,8 @@ local block_state deflate_stored(s, flush)
         s->block_start = s->strstart;
         s->insert += MIN(used, s->w_size - s->insert);
     }
+    if (s->high_water < s->strstart)
+        s->high_water = s->strstart;
 
     /* If the last block was written to next_out, then done. */
     if (last)
@@ -1783,6 +1786,8 @@ local block_state deflate_stored(s, flush)
         read_buf(s->strm, s->window + s->strstart, have);
         s->strstart += have;
     }
+    if (s->high_water < s->strstart)
+        s->high_water = s->strstart;
 
     /* There was not enough avail_out to write a complete worthy or flushed
      * stored block to next_out. Write a stored block to pending instead, if we
diff --git a/contrib/zlib/gzlib.c b/contrib/zlib/gzlib.c
index 18187bf0771..b4cb5e4a48c 100644
--- a/contrib/zlib/gzlib.c
+++ b/contrib/zlib/gzlib.c
@@ -1,5 +1,5 @@
 /* gzlib.c -- zlib functions common to reading and writing gzip files
- * Copyright (C) 2004, 2010, 2011, 2012, 2013, 2016 Mark Adler
+ * Copyright (C) 2004-2017 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
diff --git a/contrib/zlib/gzwrite.c b/contrib/zlib/gzwrite.c
index a8152b6a15d..8b38834d517 100644
--- a/contrib/zlib/gzwrite.c
+++ b/contrib/zlib/gzwrite.c
@@ -1,5 +1,5 @@
 /* gzwrite.c -- zlib functions for writing gzip files
- * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
+ * Copyright (C) 2004-2017 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
diff --git a/contrib/zlib/inffast.c b/contrib/zlib/inffast.c
index 29eb7d8244a..0dbd1dbc09f 100644
--- a/contrib/zlib/inffast.c
+++ b/contrib/zlib/inffast.c
@@ -1,5 +1,5 @@
 /* inffast.c -- fast decoding
- * Copyright (C) 1995-2008, 2010, 2013, 2016 Mark Adler
+ * Copyright (C) 1995-2017 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
diff --git a/contrib/zlib/inftrees.c b/contrib/zlib/inftrees.c
index 8a904ddbcef..2ea08fc13ea 100644
--- a/contrib/zlib/inftrees.c
+++ b/contrib/zlib/inftrees.c
@@ -9,7 +9,7 @@
 #define MAXBITS 15
 
 const char inflate_copyright[] =
-   " inflate 1.2.10 Copyright 1995-2017 Mark Adler ";
+   " inflate 1.2.11 Copyright 1995-2017 Mark Adler ";
 /*
   If you use the zlib library in a product, an acknowledgment is welcome
   in the documentation of your product. If for some reason you cannot
@@ -62,7 +62,7 @@ unsigned short FAR *work;
         35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
     static const unsigned short lext[31] = { /* Length codes 257..285 extra */
         16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
-        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 192, 202};
+        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202};
     static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
         1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
         257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
diff --git a/contrib/zlib/trees.c b/contrib/zlib/trees.c
index 357f3139254..50cf4b4571c 100644
--- a/contrib/zlib/trees.c
+++ b/contrib/zlib/trees.c
@@ -1,5 +1,5 @@
 /* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2016 Jean-loup Gailly
+ * Copyright (C) 1995-2017 Jean-loup Gailly
  * detect_data_type() function provided freely by Cosmin Truta, 2006
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
@@ -906,7 +906,7 @@ void ZLIB_INTERNAL _tr_align(s)
 
 /* ===========================================================================
  * Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file.
+ * trees or store, and write out the encoded block.
  */
 void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
     deflate_state *s;
diff --git a/contrib/zlib/zlib.3 b/contrib/zlib/zlib.3
index 00dc06119b1..bda4eb07370 100644
--- a/contrib/zlib/zlib.3
+++ b/contrib/zlib/zlib.3
@@ -1,4 +1,4 @@
-.TH ZLIB 3 "2 Jan 2017"
+.TH ZLIB 3 "15 Jan 2017"
 .SH NAME
 zlib \- compression/decompression library
 .SH SYNOPSIS
@@ -105,7 +105,7 @@ before asking for help.
 Send questions and/or comments to zlib@gzip.org,
 or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
 .SH AUTHORS AND LICENSE
-Version 1.2.10
+Version 1.2.11
 .LP
 Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
 .LP
diff --git a/contrib/zlib/zlib.h b/contrib/zlib/zlib.h
index dc90dc8d22b..f09cdaf1e05 100644
--- a/contrib/zlib/zlib.h
+++ b/contrib/zlib/zlib.h
@@ -1,5 +1,5 @@
 /* zlib.h -- interface of the 'zlib' general purpose compression library
-  version 1.2.10, January 2nd, 2017
+  version 1.2.11, January 15th, 2017
 
   Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
 
@@ -37,11 +37,11 @@
 extern "C" {
 #endif
 
-#define ZLIB_VERSION "1.2.10"
-#define ZLIB_VERNUM 0x12a0
+#define ZLIB_VERSION "1.2.11"
+#define ZLIB_VERNUM 0x12b0
 #define ZLIB_VER_MAJOR 1
 #define ZLIB_VER_MINOR 2
-#define ZLIB_VER_REVISION 10
+#define ZLIB_VER_REVISION 11
 #define ZLIB_VER_SUBREVISION 0
 
 /*
@@ -712,10 +712,11 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
    used to switch between compression and straight copy of the input data, or
    to switch to a different kind of input data requiring a different strategy.
    If the compression approach (which is a function of the level) or the
-   strategy is changed, then the input available so far is compressed with the
-   old level and strategy using deflate(strm, Z_BLOCK).  There are three
-   approaches for the compression levels 0, 1..3, and 4..9 respectively.  The
-   new level and strategy will take effect at the next call of deflate().
+   strategy is changed, and if any input has been consumed in a previous
+   deflate() call, then the input available so far is compressed with the old
+   level and strategy using deflate(strm, Z_BLOCK).  There are three approaches
+   for the compression levels 0, 1..3, and 4..9 respectively.  The new level
+   and strategy will take effect at the next call of deflate().
 
      If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does
    not have enough output space to complete, then the parameter change will not
diff --git a/contrib/zlib/zutil.c b/contrib/zlib/zutil.c
index 56534fba0ff..a76c6b0c7e5 100644
--- a/contrib/zlib/zutil.c
+++ b/contrib/zlib/zutil.c
@@ -1,5 +1,5 @@
 /* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2005, 2010, 2011, 2012, 2016 Jean-loup Gailly
+ * Copyright (C) 1995-2017 Jean-loup Gailly
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
diff --git a/etc/mtree/BSD.debug.dist b/etc/mtree/BSD.debug.dist
index 3d8fcb7bc2d..c47f4d997dc 100644
--- a/etc/mtree/BSD.debug.dist
+++ b/etc/mtree/BSD.debug.dist
@@ -40,8 +40,6 @@
                 ..
                 i18n
                 ..
-                private
-                ..
             ..
             libexec
                 bsdinstall
diff --git a/gnu/usr.bin/gdb/gdbserver/Makefile b/gnu/usr.bin/gdb/gdbserver/Makefile
index f5cfd4c49f6..fa46e6de14f 100644
--- a/gnu/usr.bin/gdb/gdbserver/Makefile
+++ b/gnu/usr.bin/gdb/gdbserver/Makefile
@@ -3,7 +3,7 @@
 # Not elf specific so don't install in /usr/libexec/elf
 BINDIR=/usr/bin
 
-GDBDIR=	${.CURDIR}/../../../../contrib/gdb
+GDBDIR=	${SRCTOP}/contrib/gdb
 .PATH:	${GDBDIR}/gdb/signals
 .PATH:	${GDBDIR}/gdb/gdbserver
 .PATH:	${GDBDIR}/gdb
diff --git a/lib/csu/aarch64/Makefile b/lib/csu/aarch64/Makefile
index 9747619c233..cd04b54b62f 100644
--- a/lib/csu/aarch64/Makefile
+++ b/lib/csu/aarch64/Makefile
@@ -1,12 +1,12 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../common
+.PATH: ${.CURDIR:H}/common
 
 SRCS=		crt1.c crti.S crtn.S
 OBJS=		${SRCS:N*.h:R:S/$/.o/g}
 OBJS+=		Scrt1.o gcrt1.o
-CFLAGS+=	-I${.CURDIR}/../common \
-		-I${.CURDIR}/../../libc/include
+CFLAGS+=	-I${.CURDIR:H}/common \
+		-I${SRCTOP}/lib/libc/include
 
 FILES=		${OBJS}
 FILESMODE=	${LIBMODE}
diff --git a/lib/csu/amd64/Makefile b/lib/csu/amd64/Makefile
index e9ca6b91ad6..1c4b0ede88e 100644
--- a/lib/csu/amd64/Makefile
+++ b/lib/csu/amd64/Makefile
@@ -1,12 +1,12 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../common
+.PATH: ${.CURDIR:H}/common
 
 SRCS=		crt1.c crti.S crtn.S
 OBJS=		${SRCS:N*.h:R:S/$/.o/g}
 OBJS+=		Scrt1.o gcrt1.o
-CFLAGS+=	-I${.CURDIR}/../common \
-		-I${.CURDIR}/../../libc/include
+CFLAGS+=	-I${.CURDIR:H}/common \
+		-I${SRCTOP}/lib/libc/include
 CFLAGS+=	-fno-omit-frame-pointer
 
 FILES=		${OBJS}
diff --git a/lib/csu/arm/Makefile b/lib/csu/arm/Makefile
index 1b3a6f84213..c4cbce72424 100644
--- a/lib/csu/arm/Makefile
+++ b/lib/csu/arm/Makefile
@@ -1,12 +1,12 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../common
+.PATH: ${.CURDIR:H}/common
 
 SRCS=		crt1.c crti.S crtn.S
 OBJS=		${SRCS:N*.h:R:S/$/.o/g}
 OBJS+=		Scrt1.o gcrt1.o
-CFLAGS+=	-I${.CURDIR}/../common \
-		-I${.CURDIR}/../../libc/include
+CFLAGS+=	-I${.CURDIR:H}/common \
+		-I${SRCTOP}/lib/libc/include
 STATIC_CFLAGS+=	-mlong-calls
 
 FILES=		${OBJS}
diff --git a/lib/csu/i386/Makefile b/lib/csu/i386/Makefile
index d64f803e03e..ca54614f067 100644
--- a/lib/csu/i386/Makefile
+++ b/lib/csu/i386/Makefile
@@ -1,12 +1,12 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../common
+.PATH: ${.CURDIR:H}/common
 
 SRCS=		crti.S crtn.S
 OBJS=		${SRCS:N*.h:R:S/$/.o/g}
 OBJS+=		gcrt1.o crt1.o Scrt1.o
-CFLAGS+=	-I${.CURDIR}/../common \
-		-I${.CURDIR}/../../libc/include
+CFLAGS+=	-I${.CURDIR:H}/common \
+		-I${SRCTOP}/lib/libc/include
 
 FILES=		${OBJS}
 FILESMODE=	${LIBMODE}
diff --git a/lib/csu/mips/Makefile b/lib/csu/mips/Makefile
index 9747619c233..cd04b54b62f 100644
--- a/lib/csu/mips/Makefile
+++ b/lib/csu/mips/Makefile
@@ -1,12 +1,12 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../common
+.PATH: ${.CURDIR:H}/common
 
 SRCS=		crt1.c crti.S crtn.S
 OBJS=		${SRCS:N*.h:R:S/$/.o/g}
 OBJS+=		Scrt1.o gcrt1.o
-CFLAGS+=	-I${.CURDIR}/../common \
-		-I${.CURDIR}/../../libc/include
+CFLAGS+=	-I${.CURDIR:H}/common \
+		-I${SRCTOP}/lib/libc/include
 
 FILES=		${OBJS}
 FILESMODE=	${LIBMODE}
diff --git a/lib/csu/powerpc/Makefile b/lib/csu/powerpc/Makefile
index 9747619c233..cd04b54b62f 100644
--- a/lib/csu/powerpc/Makefile
+++ b/lib/csu/powerpc/Makefile
@@ -1,12 +1,12 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../common
+.PATH: ${.CURDIR:H}/common
 
 SRCS=		crt1.c crti.S crtn.S
 OBJS=		${SRCS:N*.h:R:S/$/.o/g}
 OBJS+=		Scrt1.o gcrt1.o
-CFLAGS+=	-I${.CURDIR}/../common \
-		-I${.CURDIR}/../../libc/include
+CFLAGS+=	-I${.CURDIR:H}/common \
+		-I${SRCTOP}/lib/libc/include
 
 FILES=		${OBJS}
 FILESMODE=	${LIBMODE}
diff --git a/lib/csu/powerpc64/Makefile b/lib/csu/powerpc64/Makefile
index a97ef1ef3e4..104ab206488 100644
--- a/lib/csu/powerpc64/Makefile
+++ b/lib/csu/powerpc64/Makefile
@@ -1,12 +1,12 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../common
+.PATH: ${.CURDIR:H}/common
 
 SRCS=		crt1.c crti.S crtn.S
 OBJS=		${SRCS:N*.h:R:S/$/.o/g}
 OBJS+=		Scrt1.o gcrt1.o
-CFLAGS+=	-I${.CURDIR}/../common \
-		-I${.CURDIR}/../../libc/include \
+CFLAGS+=	-I${.CURDIR:H}/common \
+		-I${SRCTOP}/lib/libc/include \
 		-mlongcall
 
 # XXX: See the log for r232932 as to why the above -mlongcall is needed.  Since
diff --git a/lib/csu/riscv/Makefile b/lib/csu/riscv/Makefile
index 9747619c233..cd04b54b62f 100644
--- a/lib/csu/riscv/Makefile
+++ b/lib/csu/riscv/Makefile
@@ -1,12 +1,12 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../common
+.PATH: ${.CURDIR:H}/common
 
 SRCS=		crt1.c crti.S crtn.S
 OBJS=		${SRCS:N*.h:R:S/$/.o/g}
 OBJS+=		Scrt1.o gcrt1.o
-CFLAGS+=	-I${.CURDIR}/../common \
-		-I${.CURDIR}/../../libc/include
+CFLAGS+=	-I${.CURDIR:H}/common \
+		-I${SRCTOP}/lib/libc/include
 
 FILES=		${OBJS}
 FILESMODE=	${LIBMODE}
diff --git a/lib/csu/sparc64/Makefile b/lib/csu/sparc64/Makefile
index 0074cb998c2..874c377a940 100644
--- a/lib/csu/sparc64/Makefile
+++ b/lib/csu/sparc64/Makefile
@@ -1,11 +1,12 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../common
+.PATH: ${.CURDIR:H}/common
 
 SRCS=		crt1.c crti.S crtn.S
 OBJS=		${SRCS:N*.h:R:S/$/.o/g}
 OBJS+=		Scrt1.o gcrt1.o
-CFLAGS+=	-I${.CURDIR}/../common -I${.CURDIR}/../../libc/include
+CFLAGS+=	-I${.CURDIR:H}/common \
+		-I${SRCTOP}/lib/libc/include
 
 FILES=		${OBJS}
 FILESMODE=	${LIBMODE}
diff --git a/lib/libalias/libalias/Makefile b/lib/libalias/libalias/Makefile
index feed9a852c2..60c59a3ed31 100644
--- a/lib/libalias/libalias/Makefile
+++ b/lib/libalias/libalias/Makefile
@@ -1,6 +1,6 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../../../sys/netinet/libalias
+.PATH: ${SRCTOP}/sys/netinet/libalias
 
 PACKAGE=lib${LIB}
 LIB=	alias
diff --git a/lib/libalias/modules/Makefile b/lib/libalias/modules/Makefile
index dc66ad23c2e..24333ea6380 100644
--- a/lib/libalias/modules/Makefile
+++ b/lib/libalias/modules/Makefile
@@ -1,6 +1,6 @@
 # $FreeBSD$
 
-.include "${.CURDIR}/../../../sys/modules/libalias/modules/modules.inc"
+.include "${SRCTOP}/sys/modules/libalias/modules/modules.inc"
 
 SUBDIR=	${MODULES}
 
diff --git a/lib/libalias/modules/Makefile.inc b/lib/libalias/modules/Makefile.inc
index 23df02da7db..730f37435e0 100644
--- a/lib/libalias/modules/Makefile.inc
+++ b/lib/libalias/modules/Makefile.inc
@@ -1,6 +1,6 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../../../../sys/netinet/libalias
+.PATH: ${SRCTOP}/sys/netinet/libalias
 
 SHLIBDIR?= /lib
 LIB?=   alias_${NAME}
diff --git a/lib/libarchive/Makefile b/lib/libarchive/Makefile
index 67aff5cecb2..af75cbd501a 100644
--- a/lib/libarchive/Makefile
+++ b/lib/libarchive/Makefile
@@ -2,7 +2,7 @@
 .include 
 
 PACKAGE=lib${LIB}
-_LIBARCHIVEDIR=	${.CURDIR}/../../contrib/libarchive
+_LIBARCHIVEDIR=	${SRCTOP}/contrib/libarchive
 
 LIB=	archive
 
diff --git a/lib/libauditd/Makefile b/lib/libauditd/Makefile
index f8ed80a30fe..2df9fa8fb0e 100644
--- a/lib/libauditd/Makefile
+++ b/lib/libauditd/Makefile
@@ -3,7 +3,7 @@
 #
 
 PACKAGE=lib${LIB}
-OPENBSMDIR=		${.CURDIR}/../../contrib/openbsm
+OPENBSMDIR=		${SRCTOP}/contrib/openbsm
 _LIBAUDITDDIR=		${OPENBSMDIR}/libauditd
 _LIBBSMDIR=		${OPENBSMDIR}/libbsm
 
diff --git a/lib/libbegemot/Makefile b/lib/libbegemot/Makefile
index d2783859254..c5d3bb8badc 100644
--- a/lib/libbegemot/Makefile
+++ b/lib/libbegemot/Makefile
@@ -1,6 +1,6 @@
 # $FreeBSD$
 
-LIBBEGEMOT_DIR=${.CURDIR}/../../contrib/libbegemot
+LIBBEGEMOT_DIR=${SRCTOP}/contrib/libbegemot
 
 PACKAGE=lib${LIB}
 .PATH: ${LIBBEGEMOT_DIR}
diff --git a/lib/libblocksruntime/Makefile b/lib/libblocksruntime/Makefile
index 5933fb5253d..a7b04d8ac07 100644
--- a/lib/libblocksruntime/Makefile
+++ b/lib/libblocksruntime/Makefile
@@ -6,7 +6,7 @@ SHLIB_MAJOR=0
 CFLAGS+=-I${.CURDIR}
 WARNS?=	2
 
-.PATH: ${.CURDIR}/../../contrib/compiler-rt/lib/BlocksRuntime
+.PATH: ${SRCTOP}/contrib/compiler-rt/lib/BlocksRuntime
 
 INCS=	Block.h Block_private.h
 SRCS=	data.c runtime.c
diff --git a/lib/libbluetooth/Makefile b/lib/libbluetooth/Makefile
index a8573ec2fff..f6273ab5ce8 100644
--- a/lib/libbluetooth/Makefile
+++ b/lib/libbluetooth/Makefile
@@ -6,7 +6,7 @@ LIB=		bluetooth
 MAN=		bluetooth.3
 
 WARNS?=		2
-CFLAGS+=	-I${.CURDIR} -I${.CURDIR}/../../sys
+CFLAGS+=	-I${.CURDIR} -I${SRCTOP}/sys
 
 SHLIB_MAJOR=	4
 
diff --git a/lib/libbsm/Makefile b/lib/libbsm/Makefile
index 4416227da06..e9bd28ee044 100644
--- a/lib/libbsm/Makefile
+++ b/lib/libbsm/Makefile
@@ -3,7 +3,7 @@
 #
 
 PACKAGE=	lib${LIB}
-OPENBSMDIR=		${.CURDIR}/../../contrib/openbsm
+OPENBSMDIR=		${SRCTOP}/contrib/openbsm
 _LIBBSMDIR=		${OPENBSMDIR}/libbsm
 
 LIB=		bsm
diff --git a/lib/libbsnmp/libbsnmp/Makefile b/lib/libbsnmp/libbsnmp/Makefile
index 67a17e1e74b..fcca2ed12d8 100644
--- a/lib/libbsnmp/libbsnmp/Makefile
+++ b/lib/libbsnmp/libbsnmp/Makefile
@@ -4,7 +4,7 @@
 
 .include 
 
-CONTRIB= ${.CURDIR}/../../../contrib/bsnmp/lib
+CONTRIB= ${SRCTOP}/contrib/bsnmp/lib
 .PATH: ${CONTRIB}
 
 LIB=	bsnmp
diff --git a/lib/libbz2/Makefile b/lib/libbz2/Makefile
index 93c724ee095..cbdb87cb276 100644
--- a/lib/libbz2/Makefile
+++ b/lib/libbz2/Makefile
@@ -1,7 +1,7 @@
 # $FreeBSD$
 
 PACKAGE=	lib${LIB}
-BZ2DIR=	${.CURDIR}/../../contrib/bzip2
+BZ2DIR=	${SRCTOP}/contrib/bzip2
 .PATH: ${BZ2DIR}
 
 LIB=		bz2
diff --git a/lib/libc/Makefile b/lib/libc/Makefile
index 377a6ee6cd1..97739713cb0 100644
--- a/lib/libc/Makefile
+++ b/lib/libc/Makefile
@@ -36,7 +36,7 @@ SHLIB_LDSCRIPT=libc_nossp.ldscript
 .endif
 SHLIB_LDSCRIPT_LINKS=libxnet.so
 WARNS?=	2
-CFLAGS+=-I${LIBC_SRCTOP}/include -I${LIBC_SRCTOP}/../../include
+CFLAGS+=-I${LIBC_SRCTOP}/include -I${SRCTOP}/include
 CFLAGS+=-I${LIBC_SRCTOP}/${LIBC_ARCH}
 .if ${MK_NLS} != "no"
 CFLAGS+=-DNLS
diff --git a/lib/libc/aarch64/string/Makefile.inc b/lib/libc/aarch64/string/Makefile.inc
index 218a635da1e..b247c1c28d9 100644
--- a/lib/libc/aarch64/string/Makefile.inc
+++ b/lib/libc/aarch64/string/Makefile.inc
@@ -4,7 +4,7 @@
 # https://git.linaro.org/toolchain/cortex-strings.git
 #
 
-.PATH: ${LIBC_SRCTOP}/../../contrib/cortex-strings/src/aarch64
+.PATH: ${SRCTOP}/contrib/cortex-strings/src/aarch64
 
 MDSRCS+=memchr.S \
 	memcmp.S \
diff --git a/lib/libc/arm/aeabi/Makefile.inc b/lib/libc/arm/aeabi/Makefile.inc
index b036db88dfa..44ed2c696f4 100644
--- a/lib/libc/arm/aeabi/Makefile.inc
+++ b/lib/libc/arm/aeabi/Makefile.inc
@@ -21,7 +21,7 @@ SRCS+=	aeabi_vfp_double.S	\
 # libc. This causes issues when other parts of libc call these functions.
 # We work around this by including these functions in libc but mark them as
 # hidden so users of libc will not pick up these versions.
-.PATH: ${LIBC_SRCTOP}/../../contrib/compiler-rt/lib/builtins/arm
+.PATH: ${SRCTOP}/contrib/compiler-rt/lib/builtins/arm
 
 SRCS+=	aeabi_memcmp.S		\
 	aeabi_memcpy.S		\
diff --git a/lib/libc/capability/Makefile.inc b/lib/libc/capability/Makefile.inc
index d4b65629cc6..a53ba1f2304 100644
--- a/lib/libc/capability/Makefile.inc
+++ b/lib/libc/capability/Makefile.inc
@@ -1,7 +1,7 @@
 # $FreeBSD$
 
 # capability sources
-.PATH: ${LIBC_SRCTOP}/../../sys/kern ${LIBC_SRCTOP}/capability
+.PATH: ${SRCTOP}/sys/kern ${LIBC_SRCTOP}/capability
 
 SRCS+=	subr_capability.c
 
diff --git a/lib/libc/gdtoa/Makefile.inc b/lib/libc/gdtoa/Makefile.inc
index e25f51686bb..61dbf34adba 100644
--- a/lib/libc/gdtoa/Makefile.inc
+++ b/lib/libc/gdtoa/Makefile.inc
@@ -10,11 +10,11 @@ GDTOASRCS+=dmisc.c dtoa.c gdtoa.c gethex.c gmisc.c \
 
 SYM_MAPS+=${LIBC_SRCTOP}/gdtoa/Symbol.map
 
-CFLAGS+=-I${LIBC_SRCTOP}/../../contrib/gdtoa
+CFLAGS+=-I${SRCTOP}/contrib/gdtoa
 
 .for src in ${GDTOASRCS}
 MISRCS+=gdtoa_${src}
 CLEANFILES+=gdtoa_${src}
-gdtoa_${src}: ${LIBC_SRCTOP}/../../contrib/gdtoa/${src} .NOMETA
+gdtoa_${src}: ${SRCTOP}/contrib/gdtoa/${src} .NOMETA
 	ln -sf ${.ALLSRC} ${.TARGET}
 .endfor
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index ab8a8c9b727..460d09a9c4e 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -152,11 +152,11 @@ SRCS+=	fts-compat.c \
 	unvis-compat.c
 .endif
 
-.PATH: ${LIBC_SRCTOP}/../../contrib/libc-pwcache
+.PATH: ${SRCTOP}/contrib/libc-pwcache
 SRCS+=	pwcache.c pwcache.h
 
-.PATH: ${LIBC_SRCTOP}/../../contrib/libc-vis
-CFLAGS+=	-I${LIBC_SRCTOP}/../../contrib/libc-vis
+.PATH: ${SRCTOP}/contrib/libc-vis
+CFLAGS+=	-I${SRCTOP}/contrib/libc-vis
 SRCS+=	unvis.c vis.c
 
 MISRCS+=modf.c
diff --git a/lib/libc/iconv/Makefile.inc b/lib/libc/iconv/Makefile.inc
index 3b247376c39..25094ce8d9e 100644
--- a/lib/libc/iconv/Makefile.inc
+++ b/lib/libc/iconv/Makefile.inc
@@ -22,5 +22,5 @@ SRCS+=	iconv_compat.c
 SYM_MAPS+= ${LIBC_SRCTOP}/iconv/Symbol.map
 
 .if ${MK_ICONV} == yes
-.include "${LIBC_SRCTOP}/../libc_nonshared/Makefile.iconv"
+.include "${SRCTOP}/lib/libc_nonshared/Makefile.iconv"
 .endif
diff --git a/lib/libc/md/Makefile.inc b/lib/libc/md/Makefile.inc
index 338f64d46c3..3f173c866d1 100644
--- a/lib/libc/md/Makefile.inc
+++ b/lib/libc/md/Makefile.inc
@@ -1,5 +1,5 @@
 # $FreeBSD$
 
-.PATH: ${LIBC_SRCTOP}/../libmd
+.PATH: ${SRCTOP}/lib/libmd
 
 SRCS+=	md5c.c
diff --git a/lib/libc/posix1e/Makefile.inc b/lib/libc/posix1e/Makefile.inc
index 85fed32c140..151f8506820 100644
--- a/lib/libc/posix1e/Makefile.inc
+++ b/lib/libc/posix1e/Makefile.inc
@@ -5,7 +5,7 @@
 CFLAGS+=-D_ACL_PRIVATE
 
 # Copy kern/subr_acl_nfs4.c to the libc object directory.
-subr_acl_nfs4.c: ${LIBC_SRCTOP}/../../sys/kern/subr_acl_nfs4.c
+subr_acl_nfs4.c: ${SRCTOP}/sys/kern/subr_acl_nfs4.c
 	cat ${.ALLSRC} > ${.TARGET}
 
 SRCS+=	acl_branding.c			\
diff --git a/lib/libc/regex/grot/Makefile b/lib/libc/regex/grot/Makefile
index 056b55eac32..d0123883cd2 100644
--- a/lib/libc/regex/grot/Makefile
+++ b/lib/libc/regex/grot/Makefile
@@ -5,7 +5,7 @@
 # Do not take -DPOSIX_MISTAKE out.  REGCFLAGS isn't important to you (it's
 # for my use in some special contexts).
 
-PATHS= ${.CURDIR}/.. ${.CURDIR}/../../locale ${.CURDIR}/../../../../include
+PATHS= ${LIBC_SRCTOP}/regex ${LIBC_SRCTOP}/locale ${SRCTOP}/include
 .PATH: ${PATHS}
 
 CFLAGS+= -static -DPOSIX_MISTAKE -DREDEBUG $(REGCFLAGS)
diff --git a/lib/libc/resolv/Makefile.inc b/lib/libc/resolv/Makefile.inc
index 1a48687c61c..9bb7bbe46d2 100644
--- a/lib/libc/resolv/Makefile.inc
+++ b/lib/libc/resolv/Makefile.inc
@@ -9,4 +9,4 @@ SRCS+=	herror.c h_errno.c mtctxres.c res_comp.c res_data.c res_debug.c \
 
 SYM_MAPS+= ${LIBC_SRCTOP}/resolv/Symbol.map
 
-CFLAGS+=-I${LIBC_SRCTOP}/../libmd
+CFLAGS+=-I${SRCTOP}/lib/libmd
diff --git a/lib/libc/stdlib/jemalloc/Makefile.inc b/lib/libc/stdlib/jemalloc/Makefile.inc
index f507e00d2ae..f491e95759d 100644
--- a/lib/libc/stdlib/jemalloc/Makefile.inc
+++ b/lib/libc/stdlib/jemalloc/Makefile.inc
@@ -9,18 +9,18 @@ JEMALLOCSRCS:= jemalloc.c arena.c atomic.c base.c bitmap.c chunk.c \
 
 SYM_MAPS+=${LIBC_SRCTOP}/stdlib/jemalloc/Symbol.map
 
-CFLAGS+=-I${LIBC_SRCTOP}/../../contrib/jemalloc/include
+CFLAGS+=-I${SRCTOP}/contrib/jemalloc/include
 
 .for src in ${JEMALLOCSRCS}
 MISRCS+=jemalloc_${src}
 CLEANFILES+=jemalloc_${src}
-jemalloc_${src}: ${LIBC_SRCTOP}/../../contrib/jemalloc/src/${src} .NOMETA
+jemalloc_${src}: ${SRCTOP}/contrib/jemalloc/src/${src} .NOMETA
 	ln -sf ${.ALLSRC} ${.TARGET}
 .endfor
 
 MAN+=jemalloc.3
 CLEANFILES+=jemalloc.3
-jemalloc.3: ${LIBC_SRCTOP}/../../contrib/jemalloc/doc/jemalloc.3 .NOMETA
+jemalloc.3: ${SRCTOP}/contrib/jemalloc/doc/jemalloc.3 .NOMETA
 	ln -sf ${.ALLSRC} ${.TARGET}
 
 MLINKS+= \
diff --git a/lib/libc/stdtime/Makefile.inc b/lib/libc/stdtime/Makefile.inc
index 9b53ba57258..fb0d2b93414 100644
--- a/lib/libc/stdtime/Makefile.inc
+++ b/lib/libc/stdtime/Makefile.inc
@@ -1,15 +1,14 @@
 #	Makefile.inc,v 1.2 1994/09/13 21:26:01 wollman Exp
 # $FreeBSD$
 
-.PATH:	${LIBC_SRCTOP}/stdtime ${LIBC_SRCTOP}/../locale \
-	${LIBC_SRCTOP}/../../contrib/tzcode/stdtime
+.PATH:	${LIBC_SRCTOP}/stdtime ${SRCTOP}/contrib/tzcode/stdtime
 
 SRCS+=	asctime.c difftime.c localtime.c strftime.c strptime.c timelocal.c \
 	time32.c
 
 SYM_MAPS+= ${LIBC_SRCTOP}/stdtime/Symbol.map
 
-CFLAGS+= -I${LIBC_SRCTOP}/../../contrib/tzcode/stdtime -I${LIBC_SRCTOP}/stdtime
+CFLAGS+= -I${SRCTOP}/contrib/tzcode/stdtime -I${LIBC_SRCTOP}/stdtime
 
 CFLAGS.localtime.c= -fwrapv
 
diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc
index 7b2b9b73480..d8ade45e491 100644
--- a/lib/libc/string/Makefile.inc
+++ b/lib/libc/string/Makefile.inc
@@ -2,7 +2,7 @@
 # $FreeBSD$
 
 .PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/string ${LIBC_SRCTOP}/string
-.PATH: ${LIBC_SRCTOP}/../../sys/libkern
+.PATH: ${SRCTOP}/sys/libkern
 
 CFLAGS+= -I${LIBC_SRCTOP}/locale
 
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
index 02a0a5377cf..03c326c9371 100644
--- a/lib/libc/sys/Makefile.inc
+++ b/lib/libc/sys/Makefile.inc
@@ -6,7 +6,7 @@
 
 # Include the generated makefile containing the *complete* list
 # of syscall names in MIASM.
-.include "${LIBC_SRCTOP}/../../sys/sys/syscall.mk"
+.include "${SRCTOP}/sys/sys/syscall.mk"
 
 # Include machine dependent definitions.
 #
diff --git a/lib/libc/sys/getsockopt.2 b/lib/libc/sys/getsockopt.2
index bafd23d6efb..1f742ee7c33 100644
--- a/lib/libc/sys/getsockopt.2
+++ b/lib/libc/sys/getsockopt.2
@@ -28,7 +28,7 @@
 .\"     @(#)getsockopt.2	8.4 (Berkeley) 5/2/95
 .\" $FreeBSD$
 .\"
-.Dd April 5, 2013
+.Dd January 18, 2017
 .Dt GETSOCKOPT 2
 .Os
 .Sh NAME
@@ -188,6 +188,7 @@ The following options are recognized in
 .It Dv SO_LISTENINCQLEN Ta "get incomplete queue length of the socket (get only)"
 .It Dv SO_USER_COOKIE Ta "set the 'so_user_cookie' value for the socket (uint32_t, set only)"
 .It Dv SO_TS_CLOCK Ta "set specific format of timestamp returned by SO_TIMESTAMP"
+.It Dv SO_MAX_PACING_RATE "set the maximum transmit rate in bytes per second for the socket"
 .El
 .Pp
 .Dv SO_DEBUG
@@ -455,10 +456,10 @@ Additional timestamp types are available by following
 .Dv SO_TIMESTAMP
 with
 .Dv SO_TS_CLOCK ,
-which requests specific timestamp format to be returned instead of
+which requests a specific timestamp format to be returned instead of
 .Dv SCM_TIMESTAMP when
 .Dv SO_TIMESTAMP is enabled.
-The following
+These
 .Dv SO_TS_CLOCK
 values are recognized in
 .Fx :
@@ -515,6 +516,10 @@ returns the maximal number of queued connections, as set by
 returns the number of unaccepted complete connections.
 .Dv SO_LISTENINCQLEN
 returns the number of unaccepted incomplete connections.
+.Pp
+.Dv SO_MAX_PACING_RATE
+instruct the socket and underlying network adapter layers to limit the
+transfer rate to the given unsigned 32-bit value in bytes per second.
 .Sh RETURN VALUES
 .Rv -std
 .Sh ERRORS
diff --git a/lib/libc/sys/shm_open.2 b/lib/libc/sys/shm_open.2
index f77eb49736a..0855c076faf 100644
--- a/lib/libc/sys/shm_open.2
+++ b/lib/libc/sys/shm_open.2
@@ -28,7 +28,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 13, 2017
+.Dd January 20, 2017
 .Dt SHM_OPEN 2
 .Os
 .Sh NAME
@@ -187,6 +187,11 @@ kernel implementation explicitly includes support for
 and
 .Xr write 2 .
 .Pp
+.Fx
+also supports zero-copy transmission of data from shared memory
+objects with
+.Xr sendfile 2 .
+.Pp
 Neither shared memory objects nor their contents persist across reboots.
 .Pp
 Writes do not extend shared memory objects, so
@@ -281,7 +286,8 @@ requires write permission to the shared memory object.
 .Xr fstat 2 ,
 .Xr ftruncate 2 ,
 .Xr mmap 2 ,
-.Xr munmap 2
+.Xr munmap 2 ,
+.Xr sendfile 2
 .Sh STANDARDS
 The
 .Fn shm_open
diff --git a/lib/libc/x86/sys/Makefile.inc b/lib/libc/x86/sys/Makefile.inc
index c00a2173e08..0e8026ae47c 100644
--- a/lib/libc/x86/sys/Makefile.inc
+++ b/lib/libc/x86/sys/Makefile.inc
@@ -4,3 +4,7 @@
 
 SRCS+= \
 	__vdso_gettc.c
+
+.if ${MACHINE_CPUARCH} == "amd64" && ${MK_HYPERV} != "no"
+CFLAGS+=	-DWANT_HYPERV
+.endif
diff --git a/lib/libc/x86/sys/__vdso_gettc.c b/lib/libc/x86/sys/__vdso_gettc.c
index 723db6e0874..bf46a10e48b 100644
--- a/lib/libc/x86/sys/__vdso_gettc.c
+++ b/lib/libc/x86/sys/__vdso_gettc.c
@@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
-#ifdef __amd64__
+#ifdef WANT_HYPERV
 #include 
 #endif
 #include "libc_private.h"
@@ -158,7 +158,7 @@ __vdso_init_hpet(uint32_t u)
 		munmap((void *)new_map, PAGE_SIZE);
 }
 
-#ifdef __amd64__
+#ifdef WANT_HYPERV
 
 #define HYPERV_REFTSC_DEVPATH	"/dev/" HYPERV_REFTSC_DEVNAME
 
@@ -217,7 +217,7 @@ __vdso_hyperv_tsc(struct hyperv_reftsc *tsc_ref, u_int *tc)
 	return (ENOSYS);
 }
 
-#endif	/* __amd64__ */
+#endif	/* WANT_HYPERV */
 
 #pragma weak __vdso_gettc
 int
@@ -246,7 +246,7 @@ __vdso_gettc(const struct vdso_timehands *th, u_int *tc)
 			return (ENOSYS);
 		*tc = *(volatile uint32_t *)(map + HPET_MAIN_COUNTER);
 		return (0);
-#ifdef __amd64__
+#ifdef WANT_HYPERV
 	case VDSO_TH_ALGO_X86_HVTSC:
 		if (hyperv_ref_tsc == NULL)
 			__vdso_init_hyperv_tsc();
diff --git a/lib/libc_nonshared/Makefile b/lib/libc_nonshared/Makefile
index db4fb32c792..261828072e7 100644
--- a/lib/libc_nonshared/Makefile
+++ b/lib/libc_nonshared/Makefile
@@ -6,7 +6,7 @@
 # bsd.lib.mk doesn't have an easy way to express that.
 MK_PROFILE?=no
 .include 
-NO_PIC=	
+NO_PIC=
 # -fpic on some platforms, -fPIC on others.
 CFLAGS+=${PICFLAG} -DPIC -fvisibility=hidden
 
@@ -18,9 +18,9 @@ LIBC_NONSHARED_SRCS=
 SRCS=	__stub.c
 
 .if ${MK_ICONV} == "yes"
-.PATH: ${.CURDIR}/../libc/iconv
+.PATH: ${SRCTOP}/lib/libc/iconv
 .include "Makefile.iconv"
-CFLAGS+=-I${.CURDIR}/../libc/iconv
+CFLAGS+=-I${SRCTOP}/lib/libc/iconv
 .endif
 
 SRCS+=	${LIBC_NONSHARED_SRCS}
diff --git a/lib/libcam/Makefile b/lib/libcam/Makefile
index a4cae7aa8a6..37b3c4fcc70 100644
--- a/lib/libcam/Makefile
+++ b/lib/libcam/Makefile
@@ -36,11 +36,10 @@ MLINKS+=	cam.3 cam_open_device.3 \
 		cam_cdbparse.3 csio_encode_visit.3 \
 		cam_cdbparse.3 buff_encode_visit.3
 
-.PATH:		${.CURDIR}/../../sys/cam/scsi ${.CURDIR}/../../sys/cam/ata \
-		${.CURDIR}/../../sys/cam
+.PATH:		${SRCTOP}/sys/cam/scsi ${SRCTOP}/sys/cam/ata \
+		${SRCTOP}/sys/cam
 
-SDIR=		${.CURDIR}/../../sys
-CFLAGS+=	-I${.CURDIR} -I${SDIR}
+CFLAGS+=	-I${.CURDIR} -I${SRCTOP}/sys
 
 SHLIB_MAJOR=	7
 
diff --git a/lib/libcom_err/Makefile b/lib/libcom_err/Makefile
index b6f389f7bb8..ca65c091387 100644
--- a/lib/libcom_err/Makefile
+++ b/lib/libcom_err/Makefile
@@ -5,7 +5,7 @@ LIB=	com_err
 SRCS=	com_err.c error.c
 INCS=	${COM_ERRDIR}/com_err.h ${COM_ERRDIR}/com_right.h
 MAN=	com_err.3
-COM_ERRDIR=	${.CURDIR}/../../contrib/com_err
+COM_ERRDIR=	${SRCTOP}/contrib/com_err
 CFLAGS+=	-I${COM_ERRDIR}
 
 LDFLAGS=	-Wl,--no-undefined
diff --git a/lib/libcompat/Makefile b/lib/libcompat/Makefile
index 0bd47dfce0b..4961b10af9a 100644
--- a/lib/libcompat/Makefile
+++ b/lib/libcompat/Makefile
@@ -3,7 +3,7 @@
 
 PACKAGE=lib${LIB}
 LIB=	compat
-CFLAGS+=-DLIBC_SCCS -DSYSLIBC_SCCS -I${.CURDIR}/../libc/locale
+CFLAGS+=-DLIBC_SCCS -DSYSLIBC_SCCS -I${SRCTOP}/lib/libc/locale
 NO_PIC=
 
 WARNS?=	0
diff --git a/lib/libcrypt/Makefile b/lib/libcrypt/Makefile
index fc966f597d7..a31cdbea34c 100644
--- a/lib/libcrypt/Makefile
+++ b/lib/libcrypt/Makefile
@@ -10,7 +10,7 @@ SHLIBDIR?=	/lib
 SHLIB_MAJOR=	5
 LIB=		crypt
 
-.PATH:		${.CURDIR}/../libmd ${.CURDIR}/../../sys/crypto/sha2
+.PATH:		${SRCTOP}/lib/libmd ${SRCTOP}/sys/crypto/sha2
 SRCS=		crypt.c misc.c \
 		crypt-md5.c md5c.c \
 		crypt-nthash.c md4c.c \
@@ -19,12 +19,12 @@ SRCS=		crypt.c misc.c \
 MAN=		crypt.3
 MLINKS=		crypt.3 crypt_get_format.3 crypt.3 crypt_r.3 \
 		crypt.3 crypt_set_format.3
-CFLAGS+=	-I${.CURDIR}/../libmd -I${.CURDIR}/../libutil \
-		-I${.CURDIR}/../../sys/crypto/sha2
+CFLAGS+=	-I${SRCTOP}/lib/libmd -I${SRCTOP}/lib/libutil \
+		-I${SRCTOP}/sys/crypto/sha2
 
 # Pull in the strong crypto, if it is present.
-.if exists(${.CURDIR}/../../secure/lib/libcrypt) && ${MK_CRYPT} != "no"
-.PATH:		${.CURDIR}/../../secure/lib/libcrypt
+.if exists(${SRCTOP}/secure/lib/libcrypt) && ${MK_CRYPT} != "no"
+.PATH:		${SRCTOP}/secure/lib/libcrypt
 SRCS+=		crypt-des.c crypt-blowfish.c blowfish.c
 CFLAGS+=	-I${.CURDIR} -DHAS_DES -DHAS_BLOWFISH
 .endif
diff --git a/lib/libcxxrt/Makefile b/lib/libcxxrt/Makefile
index f2efe8db541..5332024b44a 100644
--- a/lib/libcxxrt/Makefile
+++ b/lib/libcxxrt/Makefile
@@ -1,7 +1,7 @@
 # $FreeBSD$
 
 PACKAGE=	clibs
-SRCDIR=		${.CURDIR}/../../contrib/libcxxrt
+SRCDIR=		${SRCTOP}/contrib/libcxxrt
 
 SHLIB_MAJOR=	1
 SHLIBDIR?=	/lib
diff --git a/lib/libdevdctl/tests/Makefile b/lib/libdevdctl/tests/Makefile
index 3bbbd0d955c..ce256bb88a8 100644
--- a/lib/libdevdctl/tests/Makefile
+++ b/lib/libdevdctl/tests/Makefile
@@ -2,7 +2,7 @@
 
 TESTSDIR= ${TESTSBASE}/lib/libdevdctl
 
-.PATH:	${.CURDIR}/..
+.PATH:	${.CURDIR:H}
 
 PLAIN_TESTS_CXX= libdevdctl_unittest
 
diff --git a/lib/libdwarf/Makefile b/lib/libdwarf/Makefile
index e2bb5a5289e..03f40cdd85e 100644
--- a/lib/libdwarf/Makefile
+++ b/lib/libdwarf/Makefile
@@ -94,7 +94,7 @@ CLEANFILES=	${GENSRCS}
 CLEANDIRS=	sys
 CFLAGS+=	-I. -I${SRCDIR} -I${ELFTCDIR}/common -I${ELFTCDIR}/libelf
 
-sys/elf32.h sys/elf64.h sys/elf_common.h: ${.CURDIR}/../../sys/${.TARGET} .NOMETA
+sys/elf32.h sys/elf64.h sys/elf_common.h: ${SRCTOP}/sys/${.TARGET} .NOMETA
 	mkdir -p ${.OBJDIR}/sys
 	ln -sf ${.ALLSRC} ${.TARGET}
 
diff --git a/lib/libelf/Makefile b/lib/libelf/Makefile
index 55ce30b8eb4..5c1cb8c19a4 100644
--- a/lib/libelf/Makefile
+++ b/lib/libelf/Makefile
@@ -82,7 +82,7 @@ CLEANFILES=	${GENSRCS}
 CLEANDIRS=	sys
 CFLAGS+=	-I. -I${SRCDIR} -I${ELFTCDIR}/common
 
-sys/elf32.h sys/elf64.h sys/elf_common.h: ${.CURDIR}/../../sys/${.TARGET} .NOMETA
+sys/elf32.h sys/elf64.h sys/elf_common.h: ${SRCTOP}/sys/${.TARGET} .NOMETA
 	mkdir -p ${.OBJDIR}/sys
 	ln -sf ${.ALLSRC} ${.TARGET}
 
diff --git a/lib/libevent/Makefile b/lib/libevent/Makefile
index d8cc57216cd..4d692f3cda9 100644
--- a/lib/libevent/Makefile
+++ b/lib/libevent/Makefile
@@ -1,7 +1,7 @@
 # $FreeBSD$
 
 PACKAGE=lib${LIB}
-.PATH:	${.CURDIR}/../../contrib/pf/libevent
+.PATH:	${SRCTOP}/contrib/pf/libevent
 
 .include 
 
diff --git a/lib/libexecinfo/Makefile b/lib/libexecinfo/Makefile
index c444f7fc685..9086d18d434 100644
--- a/lib/libexecinfo/Makefile
+++ b/lib/libexecinfo/Makefile
@@ -1,7 +1,7 @@
 # $FreeBSD$
 
 PACKAGE=lib${LIB}
-LIBEXECINFO=	${.CURDIR}/../../contrib/libexecinfo
+LIBEXECINFO=	${SRCTOP}/contrib/libexecinfo
 
 LIB=		execinfo
 SHLIB_MAJOR=	1
diff --git a/lib/libexpat/Makefile b/lib/libexpat/Makefile
index d0de3e0089c..20665c67fe9 100644
--- a/lib/libexpat/Makefile
+++ b/lib/libexpat/Makefile
@@ -1,7 +1,7 @@
 # $FreeBSD$
 
 PACKAGE=lib${LIB}
-EXPAT=		${.CURDIR}/../../contrib/expat
+EXPAT=		${SRCTOP}/contrib/expat
 
 LIB=		bsdxml
 SHLIBDIR?=	/lib
diff --git a/lib/libgssapi/Makefile b/lib/libgssapi/Makefile
index a48610114b4..052bf73a12f 100644
--- a/lib/libgssapi/Makefile
+++ b/lib/libgssapi/Makefile
@@ -3,7 +3,7 @@
 PACKAGE=lib${LIB}
 LIB=		gssapi
 SHLIB_MAJOR=	10
-VERSION_DEF=	${.CURDIR}/../libc/Versions.def
+VERSION_DEF=	${SRCTOP}/lib/libc/Versions.def
 SYMBOL_MAPS=	${.CURDIR}/Symbol.map
 
 SRCS=
diff --git a/lib/libiconv_modules/Makefile.inc b/lib/libiconv_modules/Makefile.inc
index 51ae7184fbb..d4247363753 100644
--- a/lib/libiconv_modules/Makefile.inc
+++ b/lib/libiconv_modules/Makefile.inc
@@ -1,10 +1,10 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../../libc/iconv
+.PATH: ${SRCTOP}/lib/libc/iconv
 
 SHLIB_MAJOR= 4
 WARNS?=	6
-CFLAGS+= -I${.CURDIR}/../../libc/iconv
+CFLAGS+= -I${SRCTOP}/lib/libc/iconv
 
 CFLAGS+=	-Dbool=_Bool
 
diff --git a/lib/libiconv_modules/mapper_parallel/Makefile b/lib/libiconv_modules/mapper_parallel/Makefile
index b79c3ad0886..00086657854 100644
--- a/lib/libiconv_modules/mapper_parallel/Makefile
+++ b/lib/libiconv_modules/mapper_parallel/Makefile
@@ -1,6 +1,6 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../mapper_serial
+.PATH: ${.CURDIR:H}/mapper_serial
 
 SHLIB=	mapper_parallel
 SRCS+=	citrus_mapper_serial.c
diff --git a/lib/libkiconv/Makefile b/lib/libkiconv/Makefile
index 5ada7db0b06..44ec6c0c9d6 100644
--- a/lib/libkiconv/Makefile
+++ b/lib/libkiconv/Makefile
@@ -17,7 +17,7 @@ MLINKS+=	kiconv.3 kiconv_add_xlat16_cspair.3 \
 		kiconv.3 kiconv_add_xlat16_cspairs.3 \
 		kiconv.3 kiconv_add_xlat16_table.3
 
-CFLAGS+=	-I${.CURDIR}/../../sys
+CFLAGS+=	-I${SRCTOP}/sys
 
 WARNS?=		1
 
diff --git a/lib/libldns/Makefile b/lib/libldns/Makefile
index 14dc9f9da1a..042b4e046a0 100644
--- a/lib/libldns/Makefile
+++ b/lib/libldns/Makefile
@@ -1,7 +1,7 @@
 # $FreeBSD$
 
 # Vendor sources and generated files
-LDNSDIR = ${.CURDIR}/../../contrib/ldns
+LDNSDIR = ${SRCTOP}/contrib/ldns
 
 PACKAGE=lib${LIB}
 .PATH: ${LDNSDIR} ${LDNSDIR}/compat
diff --git a/lib/liblzma/Makefile b/lib/liblzma/Makefile
index 62c2994feba..9dd77351484 100644
--- a/lib/liblzma/Makefile
+++ b/lib/liblzma/Makefile
@@ -2,9 +2,9 @@
 
 PACKAGE=lib${LIB}
 LIB=		lzma
-LZMADIR=	${.CURDIR}/../../contrib/xz/src/liblzma
+LZMADIR=	${SRCTOP}/contrib/xz/src/liblzma
 
-.PATH: ${LZMADIR}/../common
+.PATH: ${LZMADIR:H}/common
 SRCS+=	tuklib_physmem.c tuklib_cpucores.c
 
 .PATH: ${LZMADIR}/api/lzma
@@ -145,7 +145,7 @@ CFLAGS+=	-DHAVE_CONFIG_H \
 		-I${LZMADIR}/lzma \
 		-I${LZMADIR}/delta \
 		-I${LZMADIR}/simple \
-		-I${LZMADIR}/../common
+		-I${LZMADIR:H}/common
 
 LIBADD+=	pthread
 
diff --git a/lib/libmagic/Makefile b/lib/libmagic/Makefile
index 302338c3cd5..65fdc755360 100644
--- a/lib/libmagic/Makefile
+++ b/lib/libmagic/Makefile
@@ -2,7 +2,7 @@
 # Copyright (c) David E. O'Brien, 2000-2004, 2006, 2009
 
 PACKAGE=lib${LIB}
-CONTRDIR=	${.CURDIR}/../../contrib/file
+CONTRDIR=	${SRCTOP}/contrib/file
 .PATH: ${CONTRDIR}/src
 .PATH: ${CONTRDIR}/doc
 
diff --git a/lib/libmd/Makefile b/lib/libmd/Makefile
index 9afdc4583f4..f7de303333e 100644
--- a/lib/libmd/Makefile
+++ b/lib/libmd/Makefile
@@ -78,11 +78,11 @@ CLEANFILES+=	md[245]hl.c md[245].ref md[245].3 mddriver \
 # in which case:
 #   * macros are used to rename symbols to libcrypt internal names
 #   * no weak aliases are generated
-CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../../sys/crypto/sha2
-CFLAGS+= -I${.CURDIR}/../../sys/crypto/skein
+CFLAGS+= -I${.CURDIR} -I${SRCTOP}/sys/crypto/sha2
+CFLAGS+= -I${SRCTOP}/sys/crypto/skein
 CFLAGS+= -DWEAK_REFS
-.PATH: ${.CURDIR}/${MACHINE_ARCH} ${.CURDIR}/../../sys/crypto/sha2
-.PATH: ${.CURDIR}/../../sys/crypto/skein ${.CURDIR}/../../sys/crypto/skein/${MACHINE_ARCH}
+.PATH: ${.CURDIR}/${MACHINE_ARCH} ${SRCTOP}/sys/crypto/sha2
+.PATH: ${SRCTOP}/sys/crypto/skein ${SRCTOP}/sys/crypto/skein/${MACHINE_ARCH}
 
 .if exists(${MACHINE_ARCH}/sha.S)
 SRCS+=	sha.S
diff --git a/lib/libmilter/Makefile b/lib/libmilter/Makefile
index 88a80b7e068..a8efe9cec7b 100644
--- a/lib/libmilter/Makefile
+++ b/lib/libmilter/Makefile
@@ -3,7 +3,7 @@
 .include 
 
 PACKAGE=sendmail
-SENDMAIL_DIR=${.CURDIR}/../../contrib/sendmail
+SENDMAIL_DIR=${SRCTOP}/contrib/sendmail
 .PATH:	${SENDMAIL_DIR}/libmilter ${SENDMAIL_DIR}/libsm
 
 CFLAGS+=-I${SENDMAIL_DIR}/src -I${SENDMAIL_DIR}/include -I.
diff --git a/lib/libmp/Makefile b/lib/libmp/Makefile
index 8d8c5278e57..16f96abaa03 100644
--- a/lib/libmp/Makefile
+++ b/lib/libmp/Makefile
@@ -10,9 +10,9 @@ MAN=		libmp.3
 INCS=		mp.h
 SRCS=		mpasbn.c
 
-CFLAGS+=	-I${.CURDIR}/../../crypto
+CFLAGS+=	-I${SRCTOP}/crypto
 
-VERSION_DEF=	${.CURDIR}/../libc/Versions.def
+VERSION_DEF=	${SRCTOP}/lib/libc/Versions.def
 SYMBOL_MAPS=	${.CURDIR}/Symbol.map
 
 .if ${MK_TESTS} != "no"
diff --git a/lib/libngatm/Makefile b/lib/libngatm/Makefile
index 71f21d5d011..afda4fb3e59 100644
--- a/lib/libngatm/Makefile
+++ b/lib/libngatm/Makefile
@@ -8,8 +8,8 @@ SHLIB_MAJOR= 4
 MAN=	libngatm.3 uniaddr.3 unifunc.3 unimsg.3 unisap.3 unistruct.3
 
 # source of the library lives in contrib
-SDIR=	${.CURDIR}/../../sys
-CTRB=	${.CURDIR}/../../contrib/ngatm
+SDIR=	${SRCTOP}/sys
+CTRB=	${SRCTOP}/contrib/ngatm
 LIBBASE= ${SDIR}/contrib/ngatm
 
 CFLAGS+= -I${LIBBASE} -I${.OBJDIR} -I${CTRB}/libngatm
diff --git a/lib/libnv/Makefile b/lib/libnv/Makefile
index f520c8b05ad..8ef5d287112 100644
--- a/lib/libnv/Makefile
+++ b/lib/libnv/Makefile
@@ -8,8 +8,8 @@ SHLIBDIR?= /lib
 LIB=	nv
 SHLIB_MAJOR= 0
 
-.PATH: ${.CURDIR}/../../sys/contrib/libnv ${.CURDIR}/../../sys/sys
-CFLAGS+=-I${.CURDIR}/../../sys -I${.CURDIR}
+.PATH: ${SRCTOP}/sys/contrib/libnv ${SRCTOP}/sys/sys
+CFLAGS+=-I${SRCTOP}/sys -I${.CURDIR}
 
 SRCS=	cnvlist.c
 SRCS+=	dnvlist.c
diff --git a/lib/libopie/Makefile b/lib/libopie/Makefile
index 367bbc6ac7b..4507d252ea9 100644
--- a/lib/libopie/Makefile
+++ b/lib/libopie/Makefile
@@ -3,7 +3,7 @@
 # $FreeBSD$
 #
 PACKAGE=lib${LIB}
-OPIE_DIST?=	${.CURDIR}/../../contrib/opie
+OPIE_DIST?=	${SRCTOP}/contrib/opie
 DIST_DIR=	${OPIE_DIST}/${.CURDIR:T}
 SHLIB_MAJOR=    8
 
diff --git a/lib/libpam/libpam/Makefile b/lib/libpam/libpam/Makefile
index 1e634b70549..41863ad07c4 100644
--- a/lib/libpam/libpam/Makefile
+++ b/lib/libpam/libpam/Makefile
@@ -36,7 +36,7 @@
 # $FreeBSD$
 
 PACKAGE=lib${LIB}
-OPENPAM=	${.CURDIR}/../../../contrib/openpam
+OPENPAM=	${SRCTOP}/contrib/openpam
 .PATH: ${OPENPAM}/include ${OPENPAM}/lib/libpam ${OPENPAM}/doc/man
 
 # static_libpam will build libpam.a
diff --git a/lib/libpam/modules/Makefile.inc b/lib/libpam/modules/Makefile.inc
index 899c3cbbc8f..87885c36b35 100644
--- a/lib/libpam/modules/Makefile.inc
+++ b/lib/libpam/modules/Makefile.inc
@@ -1,11 +1,11 @@
 # $FreeBSD$
 
-PAMDIR=		${.CURDIR}/../../../../contrib/openpam
+PAMDIR=		${SRCTOP}/contrib/openpam
 
 MK_INSTALLLIB=	no
 MK_PROFILE=	no
 
-CFLAGS+= -I${PAMDIR}/include -I${.CURDIR}/../../libpam
+CFLAGS+= -I${PAMDIR}/include -I${SRCTOP}/lib/libpam
 
 SHLIB_NAME?=	${LIB}.so.${SHLIB_MAJOR}
 LIBADD+=	pam
diff --git a/lib/libpam/modules/pam_passwdqc/Makefile b/lib/libpam/modules/pam_passwdqc/Makefile
index cd236428988..2b10fdcae4a 100644
--- a/lib/libpam/modules/pam_passwdqc/Makefile
+++ b/lib/libpam/modules/pam_passwdqc/Makefile
@@ -1,6 +1,6 @@
 # $FreeBSD$
 
-SRCDIR=	${.CURDIR}/../../../../contrib/pam_modules/pam_passwdqc
+SRCDIR=	${SRCTOP}/contrib/pam_modules/pam_passwdqc
 .PATH: ${SRCDIR}
 
 LIB=	pam_passwdqc
diff --git a/lib/libpam/modules/pam_ssh/Makefile b/lib/libpam/modules/pam_ssh/Makefile
index 8de1bdfadc8..d2168b395d8 100644
--- a/lib/libpam/modules/pam_ssh/Makefile
+++ b/lib/libpam/modules/pam_ssh/Makefile
@@ -1,7 +1,7 @@
 # PAM module for SSH
 # $FreeBSD$
 
-SSHDIR=	${.CURDIR}/../../../../crypto/openssh
+SSHDIR=	${SRCTOP}/crypto/openssh
 
 LIB=	pam_ssh
 MAN=	pam_ssh.8
diff --git a/lib/libpam/static_libpam/Makefile b/lib/libpam/static_libpam/Makefile
index ee49517649f..9c393386efc 100644
--- a/lib/libpam/static_libpam/Makefile
+++ b/lib/libpam/static_libpam/Makefile
@@ -35,7 +35,7 @@
 #
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../libpam
+.PATH: ${SRCTOP}/lib/libpam
 
 # Only build the static library.
 LIB=	pam
@@ -66,4 +66,4 @@ CLEANFILES+=	openpam_static.o \
 openpam_static_modules.o: openpam_static.o ${STATIC_MODULES}
 	${CC} -nostdlib ${CFLAGS} -o ${.TARGET} -r -Wl,--whole-archive ${.ALLSRC}
 
-.include "${.CURDIR}/../libpam/Makefile"
+.include "${.CURDIR:H}/libpam/Makefile"
diff --git a/lib/libpcap/Makefile b/lib/libpcap/Makefile
index e7512e65912..9b7ffe96e13 100644
--- a/lib/libpcap/Makefile
+++ b/lib/libpcap/Makefile
@@ -114,7 +114,7 @@ SHLIB_MAJOR=	8
 #
 # Magic to grab sources out of src/contrib
 #
-PCAP_DISTDIR?=${.CURDIR}/../../contrib/libpcap
+PCAP_DISTDIR?=${SRCTOP}/contrib/libpcap
 CFLAGS+=-I${PCAP_DISTDIR}
 .PATH:	${PCAP_DISTDIR}
 .PATH:	${PCAP_DISTDIR}/bpf/net
diff --git a/lib/libpe/Makefile b/lib/libpe/Makefile
index 877b331d101..29634e1565c 100644
--- a/lib/libpe/Makefile
+++ b/lib/libpe/Makefile
@@ -3,7 +3,7 @@
 
 INTERNALLIB=
 
-ELFTCDIR=	${.CURDIR}/../../contrib/elftoolchain
+ELFTCDIR=	${SRCTOP}/contrib/elftoolchain
 
 .PATH:	${ELFTCDIR}/libpe
 
diff --git a/lib/libproc/Makefile b/lib/libproc/Makefile
index 79b903a0830..6749251f000 100644
--- a/lib/libproc/Makefile
+++ b/lib/libproc/Makefile
@@ -30,9 +30,9 @@ LIBADD+=	elf procstat rtld_db util
 .if ${MK_CDDL} != "no"
 LIBADD+=	ctf
 IGNORE_PRAGMA=	YES
-CFLAGS+=	-I${.CURDIR}/../../cddl/contrib/opensolaris/lib/libctf/common \
-		-I${.CURDIR}/../../sys/cddl/contrib/opensolaris/uts/common \
-		-I${.CURDIR}/../../sys/cddl/compat/opensolaris
+CFLAGS+=	-I${SRCTOP}/cddl/contrib/opensolaris/lib/libctf/common \
+		-I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common \
+		-I${SRCTOP}/sys/cddl/compat/opensolaris
 .else
 CFLAGS+=	-DNO_CTF
 .endif
diff --git a/lib/libprocstat/zfs/Makefile b/lib/libprocstat/zfs/Makefile
index 9200f024480..a58f298c62c 100644
--- a/lib/libprocstat/zfs/Makefile
+++ b/lib/libprocstat/zfs/Makefile
@@ -1,21 +1,21 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/..
+.PATH: ${.CURDIR:H}
 
 SRCS=	zfs.c
 OBJS=	zfs.o
 WARNS?=	1
 
-CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
-CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
-CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
-CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common
-CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs
-CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
-CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
-CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
-CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
-CFLAGS+= -I${.CURDIR}/..
+CFLAGS+= -I${SRCTOP}/sys/cddl/compat/opensolaris
+CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/include
+CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/lib/libumem
+CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common
+CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
+CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
+CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
+CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys
+CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head
+CFLAGS+= -I${.CURDIR:H}
 CFLAGS+= -DNEED_SOLARIS_BOOLEAN
 
 all: ${OBJS}
diff --git a/lib/librpcsec_gss/Makefile b/lib/librpcsec_gss/Makefile
index e59f1e5cfa5..7dccfc55611 100644
--- a/lib/librpcsec_gss/Makefile
+++ b/lib/librpcsec_gss/Makefile
@@ -8,11 +8,11 @@ SRCS+=	rpcsec_gss.c rpcsec_gss_prot.c rpcsec_gss_conf.c rpcsec_gss_misc.c \
 
 LIBADD=	gssapi
 
-VERSION_DEF=	${.CURDIR}/../libc/Versions.def
+VERSION_DEF=	${SRCTOP}/lib/libc/Versions.def
 SYMBOL_MAPS=	${.CURDIR}/Symbol.map
 
-CFLAGS+= -I${.CURDIR}/../../include
-CFLAGS+= -I${.CURDIR}/../../libc_rpc
+CFLAGS+= -I${SRCTOP}/include
+CFLAGS+= -I${SRCTOP}/lib/libc_rpc
 MK_PROFILE=	no
 
 MAN=	rpcsec_gss.3
diff --git a/lib/librpcsvc/Makefile b/lib/librpcsvc/Makefile
index 1deda175c6a..b49170081c5 100644
--- a/lib/librpcsvc/Makefile
+++ b/lib/librpcsvc/Makefile
@@ -3,7 +3,7 @@
 
 .include 
 
-.PATH: ${.CURDIR}/../../include/rpcsvc
+.PATH: ${SRCTOP}/include/rpcsvc
 
 PACKAGE=lib${LIB}
 LIB=    rpcsvc
diff --git a/lib/librt/Makefile b/lib/librt/Makefile
index 560f2af3685..5417b9ef3bf 100644
--- a/lib/librt/Makefile
+++ b/lib/librt/Makefile
@@ -5,7 +5,7 @@
 PACKAGE=lib${LIB}
 LIB=rt
 SHLIB_MAJOR= 1
-CFLAGS+=-I${.CURDIR}/../libc/include -I${.CURDIR}
+CFLAGS+=-I${SRCTOP}/lib/libc/include -I${.CURDIR}
 .ifndef NO_THREAD_STACK_UNWIND
 CFLAGS+=-fexceptions
 .endif
@@ -18,7 +18,7 @@ SRCS+= aio.c mq.c sigev_thread.c timer.c
 
 PRECIOUSLIB=
 
-VERSION_DEF=${.CURDIR}/../libc/Versions.def
+VERSION_DEF=${SRCTOP}/lib/libc/Versions.def
 SYMBOL_MAPS=${.CURDIR}/Symbol.map
 
 .if ${MK_TESTS} != "no"
diff --git a/lib/libsbuf/Makefile b/lib/libsbuf/Makefile
index ebf4a8d4a99..3d8ea6f5dda 100644
--- a/lib/libsbuf/Makefile
+++ b/lib/libsbuf/Makefile
@@ -10,6 +10,6 @@ SHLIB_MAJOR	= 6
 SYMBOL_MAPS=    ${.CURDIR}/Symbol.map
 VERSION_DEF=	${.CURDIR}/Version.def
 
-.PATH:	${.CURDIR}/../../sys/kern
+.PATH:	${SRCTOP}/sys/kern
 
 .include 
diff --git a/lib/libsm/Makefile b/lib/libsm/Makefile
index 984009259fc..94af1b32213 100644
--- a/lib/libsm/Makefile
+++ b/lib/libsm/Makefile
@@ -3,7 +3,7 @@
 .include 
 
 PACKAGE=sendmail
-SENDMAIL_DIR=${.CURDIR}/../../contrib/sendmail
+SENDMAIL_DIR=${SRCTOP}/contrib/sendmail
 .PATH:	${SENDMAIL_DIR}/libsm
 
 CFLAGS+=-I${SENDMAIL_DIR}/src -I${SENDMAIL_DIR}/include -I.
diff --git a/lib/libsmb/Makefile b/lib/libsmb/Makefile
index 6236a2e00fb..519db5ff946 100644
--- a/lib/libsmb/Makefile
+++ b/lib/libsmb/Makefile
@@ -3,7 +3,7 @@
 .include 
 
 PACKAGE=lib${LIB}
-CONTRIBDIR=	${.CURDIR}/../../contrib/smbfs
+CONTRIBDIR=	${SRCTOP}/contrib/smbfs
 .PATH: ${CONTRIBDIR}/lib/smb
 
 LIB=	smb
diff --git a/lib/libsmdb/Makefile b/lib/libsmdb/Makefile
index 3fbd1164886..b1957b9c214 100644
--- a/lib/libsmdb/Makefile
+++ b/lib/libsmdb/Makefile
@@ -1,7 +1,7 @@
 # $FreeBSD$
 
 PACKAGE=lib${LIB}
-SENDMAIL_DIR=${.CURDIR}/../../contrib/sendmail
+SENDMAIL_DIR=${SRCTOP}/contrib/sendmail
 .PATH:	${SENDMAIL_DIR}/libsmdb
 
 CFLAGS+=-I${SENDMAIL_DIR}/src -I${SENDMAIL_DIR}/include -I.
diff --git a/lib/libsmutil/Makefile b/lib/libsmutil/Makefile
index e1d908e9fea..ff3f8491225 100644
--- a/lib/libsmutil/Makefile
+++ b/lib/libsmutil/Makefile
@@ -1,7 +1,7 @@
 # $FreeBSD$
 
 PACKAGE=lib${LIB}
-SENDMAIL_DIR=${.CURDIR}/../../contrib/sendmail
+SENDMAIL_DIR=${SRCTOP}/contrib/sendmail
 .PATH:	${SENDMAIL_DIR}/libsmutil
 
 CFLAGS+=-I${SENDMAIL_DIR}/src -I${SENDMAIL_DIR}/include -I.
diff --git a/lib/libsqlite3/Makefile b/lib/libsqlite3/Makefile
index 37a3a6ef122..5e0d17b7713 100644
--- a/lib/libsqlite3/Makefile
+++ b/lib/libsqlite3/Makefile
@@ -8,7 +8,7 @@ LIBADD+=	pthread
 
 SRCS=	sqlite3.c
 
-SQLITE=	${.CURDIR}/../../contrib/sqlite3
+SQLITE=	${SRCTOP}/contrib/sqlite3
 .PATH:	${SQLITE}
 
 WARNS=	3
diff --git a/lib/libstdthreads/Makefile b/lib/libstdthreads/Makefile
index 3200d4e36ba..de696c7dca4 100644
--- a/lib/libstdthreads/Makefile
+++ b/lib/libstdthreads/Makefile
@@ -35,7 +35,7 @@ MLINKS=	thrd_create.3 call_once.3 \
 
 LIBADD=	pthread
 
-VERSION_DEF= ${.CURDIR}/../libc/Versions.def
+VERSION_DEF= ${SRCTOP}/lib/libc/Versions.def
 SYMBOL_MAPS= ${.CURDIR}/Symbol.map
 
 .include 
diff --git a/lib/libsysdecode/Makefile b/lib/libsysdecode/Makefile
index 47ba9af97cb..bde9460fee7 100644
--- a/lib/libsysdecode/Makefile
+++ b/lib/libsysdecode/Makefile
@@ -9,8 +9,8 @@ SRCS=	errno.c flags.c ioctl.c signal.c syscallnames.c utrace.c
 INCS=	sysdecode.h
 
 CFLAGS+= -I${.OBJDIR}
-CFLAGS+= -I${.CURDIR}/../../sys
-CFLAGS+= -I${.CURDIR}/../../libexec/rtld-elf
+CFLAGS+= -I${SRCTOP}/sys
+CFLAGS+= -I${SRCTOP}/libexec/rtld-elf
 
 MAN=	sysdecode.3 \
 	sysdecode_abi_to_freebsd_errno.3 \
diff --git a/lib/libtelnet/Makefile b/lib/libtelnet/Makefile
index b5bba12bebe..36c2dda75fb 100644
--- a/lib/libtelnet/Makefile
+++ b/lib/libtelnet/Makefile
@@ -4,7 +4,7 @@
 .include 
 
 PACKAGE=lib${LIB}
-TELNETDIR=	${.CURDIR}/../../contrib/telnet
+TELNETDIR=	${SRCTOP}/contrib/telnet
 .PATH:		${TELNETDIR}/libtelnet
 
 LIB=		telnet
diff --git a/lib/libthr/Makefile b/lib/libthr/Makefile
index 517a30f21ee..5b3e3bff71b 100644
--- a/lib/libthr/Makefile
+++ b/lib/libthr/Makefile
@@ -18,13 +18,13 @@ LIB=thr
 SHLIB_MAJOR= 3
 WARNS?=	3
 CFLAGS+=-DPTHREAD_KERNEL
-CFLAGS+=-I${.CURDIR}/../libc/include -I${.CURDIR}/thread \
-	-I${.CURDIR}/../../include
+CFLAGS+=-I${SRCTOP}/lib/libc/include -I${.CURDIR}/thread \
+	-I${SRCTOP}/include
 CFLAGS+=-I${.CURDIR}/arch/${MACHINE_CPUARCH}/include
 CFLAGS+=-I${.CURDIR}/sys
-CFLAGS+=-I${.CURDIR}/../../libexec/rtld-elf
-CFLAGS+=-I${.CURDIR}/../../libexec/rtld-elf/${MACHINE_CPUARCH}
-CFLAGS+=-I${.CURDIR}/../libthread_db
+CFLAGS+=-I${SRCTOP}/libexec/rtld-elf
+CFLAGS+=-I${SRCTOP}/libexec/rtld-elf/${MACHINE_CPUARCH}
+CFLAGS+=-I${SRCTOP}/lib/libthread_db
 CFLAGS+=-Winline
 
 .ifndef NO_THREAD_UNWIND_STACK
@@ -34,7 +34,7 @@ CFLAGS+=-D_PTHREAD_FORCED_UNWIND
 
 LDFLAGS+=-Wl,-znodelete
 
-VERSION_DEF=${.CURDIR}/../libc/Versions.def
+VERSION_DEF=${SRCTOP}/lib/libc/Versions.def
 SYMBOL_MAPS=${.CURDIR}/pthread.map
 
 MAN=	libthr.3
diff --git a/lib/libthr/support/Makefile.inc b/lib/libthr/support/Makefile.inc
index 1814f8a5f3d..cd4d206e5ad 100644
--- a/lib/libthr/support/Makefile.inc
+++ b/lib/libthr/support/Makefile.inc
@@ -1,15 +1,15 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/support ${.CURDIR}/../libc/gen ${.CURDIR}/../libc/string
+.PATH: ${.CURDIR}/support ${SRCTOP}/lib/libc/gen ${SRCTOP}/lib/libc/string
 
 # libc must search machine_arch, then machine_cpuarch, but libthr has all its
 # code implemented in machine_cpuarch.  Cope.
-.if exists(${.CURDIR}/../libc/${MACHINE_ARCH}/sys)
-.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/sys
-CFLAGS+= -I${.CURDIR}/../libc/${MACHINE_ARCH}
+.if exists(${SRCTOP}/lib/libc/${MACHINE_ARCH}/sys)
+.PATH: ${SRCTOP}/lib/libc/${MACHINE_ARCH}/sys
+CFLAGS+= -I${SRCTOP}/lib/libc/${MACHINE_ARCH}
 .else
-.PATH: ${.CURDIR}/../libc/${MACHINE_CPUARCH}/sys
-CFLAGS+= -I${.CURDIR}/../libc/${MACHINE_CPUARCH}
+.PATH: ${SRCTOP}/lib/libc/${MACHINE_CPUARCH}/sys
+CFLAGS+= -I${SRCTOP}/lib/libc/${MACHINE_CPUARCH}
 .endif
 
 SYSCALLS= thr_new
diff --git a/lib/libthread_db/Makefile b/lib/libthread_db/Makefile
index dfd45163950..1484b880394 100644
--- a/lib/libthread_db/Makefile
+++ b/lib/libthread_db/Makefile
@@ -15,7 +15,7 @@ CFLAGS+=-I. -I${.CURDIR}
 SYM_MAPS+=${.CURDIR}/Symbol.map
 
 SYMBOL_MAPS=${SYM_MAPS}
-VERSION_DEF=${.CURDIR}/../libc/Versions.def
+VERSION_DEF=${SRCTOP}/lib/libc/Versions.def
 
 # Unfortunately, clang gives an incorrect warning about alignment in
 # arch/i386/libpthread_md.c, so turn that off for now.
diff --git a/lib/libufs/Makefile b/lib/libufs/Makefile
index 86fa4c9c47b..c1948b3a0f0 100644
--- a/lib/libufs/Makefile
+++ b/lib/libufs/Makefile
@@ -18,7 +18,7 @@ MLINKS+= ufs_disk_close.3 ufs_disk_fillout.3
 MLINKS+= ufs_disk_close.3 ufs_disk_fillout_blank.3
 MLINKS+= ufs_disk_close.3 ufs_disk_write.3
 
-.PATH:  ${.CURDIR}/../../sys/ufs/ffs
+.PATH:  ${SRCTOP}/sys/ufs/ffs
 
 WARNS?=	2
 
diff --git a/lib/libulog/Makefile b/lib/libulog/Makefile
index 434f3f6ce19..7c793e9a0e7 100644
--- a/lib/libulog/Makefile
+++ b/lib/libulog/Makefile
@@ -22,7 +22,7 @@ MLINKS+=ulog_login.3 ulog_login_pseudo.3 \
 
 LIBADD=	md
 
-VERSION_DEF= ${.CURDIR}/../libc/Versions.def
+VERSION_DEF= ${SRCTOP}/lib/libc/Versions.def
 SYMBOL_MAPS= ${.CURDIR}/Symbol.map
 
 .if ${MK_INSTALLLIB} != "no"
diff --git a/lib/libunbound/Makefile b/lib/libunbound/Makefile
index a30bfc754bb..2e0e249afc8 100644
--- a/lib/libunbound/Makefile
+++ b/lib/libunbound/Makefile
@@ -2,8 +2,8 @@
 
 PACKAGE=lib${LIB}
 # Vendor sources and generated files
-LDNSDIR= ${.CURDIR}/../../contrib/ldns
-UNBOUNDDIR= ${.CURDIR}/../../contrib/unbound
+LDNSDIR= ${SRCTOP}/contrib/ldns
+UNBOUNDDIR= ${SRCTOP}/contrib/unbound
 
 # Hold my beer and watch this
 .PATH: ${UNBOUNDDIR} ${UNBOUNDDIR}/cachedb ${UNBOUNDDIR}/dns64 ${UNBOUNDDIR}/iterator ${UNBOUNDDIR}/sldns ${UNBOUNDDIR}/libunbound ${UNBOUNDDIR}/services ${UNBOUNDDIR}/services/cache ${UNBOUNDDIR}/util ${UNBOUNDDIR}/util/data ${UNBOUNDDIR}/util/storage ${UNBOUNDDIR}/validator 
diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile
index 07412e0ece4..aa0f25e51ea 100644
--- a/lib/libutil/Makefile
+++ b/lib/libutil/Makefile
@@ -25,7 +25,7 @@ CFLAGS+= -DLIBC_SCCS
 CFLAGS+= -DINET6
 .endif
 
-CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../libc/gen/
+CFLAGS+= -I${.CURDIR} -I${SRCTOP}/lib/libc/gen/
 
 MAN+=	expand_number.3 flopen.3 fparseln.3 hexdump.3 \
 	humanize_number.3 kinfo_getallproc.3 kinfo_getfile.3 \
diff --git a/lib/libwrap/Makefile b/lib/libwrap/Makefile
index b2253d88863..180ef35b9b9 100644
--- a/lib/libwrap/Makefile
+++ b/lib/libwrap/Makefile
@@ -15,7 +15,7 @@ MLINKS=	hosts_access.3 hosts_ctl.3 \
 	hosts_access.3 request_set.3 \
 	hosts_options.5 hosts.allow.5
 
-.PATH:	${.CURDIR}/../../contrib/tcp_wrappers
+.PATH:	${SRCTOP}/contrib/tcp_wrappers
 
 CFLAGS+=-DFACILITY=LOG_AUTH -DHOSTS_ACCESS -DNETGROUP -DDAEMON_UMASK=022 \
 	-DREAL_DAEMON_DIR=\"${LIBEXECDIR}\" -DPROCESS_OPTIONS \
diff --git a/lib/libypclnt/Makefile b/lib/libypclnt/Makefile
index 113a3cc8321..c043d6381fd 100644
--- a/lib/libypclnt/Makefile
+++ b/lib/libypclnt/Makefile
@@ -24,9 +24,9 @@ GENSRCS=yp.h \
 	yppasswd_private_xdr.c
 
 RPCGEN=	RPCGEN_CPP=${CPP:Q} rpcgen -C
-RPCSRC=	${.CURDIR}/../../include/rpcsvc/yp.x
-RPCSRC_PW=	${.CURDIR}/../../include/rpcsvc/yppasswd.x
-RPCSRC_PRIV=	${.CURDIR}/../../usr.sbin/rpc.yppasswdd/yppasswd_private.x
+RPCSRC=	${SRCTOP}/include/rpcsvc/yp.x
+RPCSRC_PW=	${SRCTOP}/include/rpcsvc/yppasswd.x
+RPCSRC_PRIV=	${SRCTOP}/usr.sbin/rpc.yppasswdd/yppasswd_private.x
 
 yp.h: ${RPCSRC}
 	${RPCGEN} -h -o ${.TARGET} ${RPCSRC}
diff --git a/lib/ncurses/config.mk b/lib/ncurses/config.mk
index d01e17a413b..d15be860113 100644
--- a/lib/ncurses/config.mk
+++ b/lib/ncurses/config.mk
@@ -2,25 +2,25 @@
 
 # This Makefile is shared by libncurses, libform, libmenu, libpanel.
 
-NCURSES_DIR=	${.CURDIR}/../../../contrib/ncurses
+NCURSES_DIR=	${SRCTOP}/contrib/ncurses
 
 .if defined(ENABLE_WIDEC)
 LIB_SUFFIX=	w
 CFLAGS+=	-D_XOPEN_SOURCE_EXTENDED -DENABLE_WIDEC
-NCURSES_CFG_H=	${.CURDIR}/../ncurses/ncurses_cfg.h
+NCURSES_CFG_H=	${.CURDIR:H}/ncurses/ncurses_cfg.h
 .else
 LIB_SUFFIX=
 NCURSES_CFG_H=	${.CURDIR}/ncurses_cfg.h
 .endif
 
 CFLAGS+=	-I.
-.if exists(${.OBJDIR}/../ncurses${LIB_SUFFIX})
-CFLAGS+=	-I${.OBJDIR}/../ncurses${LIB_SUFFIX}
+.if exists(${.OBJDIR:H}/ncurses${LIB_SUFFIX})
+CFLAGS+=	-I${.OBJDIR:H}/ncurses${LIB_SUFFIX}
 .endif
-CFLAGS+=	-I${.CURDIR}/../ncurses${LIB_SUFFIX}
+CFLAGS+=	-I${.CURDIR:H}/ncurses${LIB_SUFFIX}
 
 # for ${NCURSES_CFG_H}
-CFLAGS+=	-I${.CURDIR}/../ncurses
+CFLAGS+=	-I${.CURDIR:H}/ncurses
 
 CFLAGS+=	-I${NCURSES_DIR}/include
 CFLAGS+=	-I${NCURSES_DIR}/ncurses
diff --git a/lib/ncurses/form/Makefile b/lib/ncurses/form/Makefile
index beefb2c4a7d..eab5bbb63c0 100644
--- a/lib/ncurses/form/Makefile
+++ b/lib/ncurses/form/Makefile
@@ -1,6 +1,6 @@
 # $FreeBSD$
 
-.include "${.CURDIR}/../config.mk"
+.include "${.CURDIR:H}/config.mk"
 
 SRCDIR=	${NCURSES_DIR}/form
 
diff --git a/lib/ncurses/formw/Makefile b/lib/ncurses/formw/Makefile
index 54885034ff3..3ec7637373b 100644
--- a/lib/ncurses/formw/Makefile
+++ b/lib/ncurses/formw/Makefile
@@ -2,4 +2,4 @@
 
 ENABLE_WIDEC=
 
-.include "${.CURDIR}/../form/Makefile"
+.include "${.CURDIR:H}/form/Makefile"
diff --git a/lib/ncurses/menu/Makefile b/lib/ncurses/menu/Makefile
index d3890de73e3..653619638fb 100644
--- a/lib/ncurses/menu/Makefile
+++ b/lib/ncurses/menu/Makefile
@@ -1,6 +1,6 @@
 # $FreeBSD$
 
-.include "${.CURDIR}/../config.mk"
+.include "${.CURDIR:H}/config.mk"
 
 SRCDIR=	${NCURSES_DIR}/menu
 
diff --git a/lib/ncurses/menuw/Makefile b/lib/ncurses/menuw/Makefile
index d5a100f0cff..d6df5633282 100644
--- a/lib/ncurses/menuw/Makefile
+++ b/lib/ncurses/menuw/Makefile
@@ -2,4 +2,4 @@
 
 ENABLE_WIDEC=
 
-.include "${.CURDIR}/../menu/Makefile"
+.include "${.CURDIR:H}/menu/Makefile"
diff --git a/lib/ncurses/ncurses/Makefile b/lib/ncurses/ncurses/Makefile
index f8649ccf03d..d880ebb8d00 100644
--- a/lib/ncurses/ncurses/Makefile
+++ b/lib/ncurses/ncurses/Makefile
@@ -10,7 +10,7 @@ MK_MAN=no
 
 .include 
 
-.include "${.CURDIR}/../config.mk"
+.include "${.CURDIR:H}/config.mk"
 
 LIB=		ncurses${LIB_SUFFIX}
 SHLIB_MAJOR=	8
diff --git a/lib/ncurses/ncursesw/Makefile b/lib/ncurses/ncursesw/Makefile
index 277c90b2f07..5f6040e7119 100644
--- a/lib/ncurses/ncursesw/Makefile
+++ b/lib/ncurses/ncursesw/Makefile
@@ -2,6 +2,6 @@
 
 ENABLE_WIDEC=
 
-.PATH: ${.CURDIR}/../ncurses
+.PATH: ${.CURDIR:H}/ncurses
 
-.include "${.CURDIR}/../ncurses/Makefile"
+.include "${.CURDIR:H}/ncurses/Makefile"
diff --git a/lib/ncurses/panel/Makefile b/lib/ncurses/panel/Makefile
index b075bcf056a..1993f5e76ac 100644
--- a/lib/ncurses/panel/Makefile
+++ b/lib/ncurses/panel/Makefile
@@ -1,6 +1,6 @@
 # $FreeBSD$
 
-.include "${.CURDIR}/../config.mk"
+.include "${.CURDIR:H}/config.mk"
 
 SRCDIR=	${NCURSES_DIR}/panel
 
diff --git a/lib/ncurses/panelw/Makefile b/lib/ncurses/panelw/Makefile
index 7642e34906f..2585738a5e6 100644
--- a/lib/ncurses/panelw/Makefile
+++ b/lib/ncurses/panelw/Makefile
@@ -2,4 +2,4 @@
 
 ENABLE_WIDEC=
 
-.include "${.CURDIR}/../panel/Makefile"
+.include "${.CURDIR:H}/panel/Makefile"
diff --git a/sbin/camcontrol/camcontrol.8 b/sbin/camcontrol/camcontrol.8
index ce4d2cfea26..d6caa9a9edf 100644
--- a/sbin/camcontrol/camcontrol.8
+++ b/sbin/camcontrol/camcontrol.8
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 15, 2017
+.Dd January 20, 2017
 .Dt CAMCONTROL 8
 .Os
 .Sh NAME
@@ -2374,6 +2374,20 @@ this power condition will be affected.
 .It state
 Enable or disable a particular power condition.
 .Bl -tag -width 7n
+.It Fl e
+Enable the power condition.
+One of 
+.Fl e
+or
+.Fl d
+is required.
+.It Fl d
+Disable the power condition.
+One of
+.Fl d
+or
+.Fl e
+is required.
 .It Fl p Ar cond
 Specify the power condition: Idle_a, Idle_b, Idle_c, Standby_y, Standby_z.
 This argument is required.
diff --git a/sbin/camcontrol/epc.c b/sbin/camcontrol/epc.c
index 783db59f62b..3b74d08a4eb 100644
--- a/sbin/camcontrol/epc.c
+++ b/sbin/camcontrol/epc.c
@@ -783,6 +783,7 @@ epc(struct cam_device *device, int argc, char **argv, char *combinedopt,
 			warnx("Must specify a timer value (-T time)");
 			error = 1;
 		}
+		/* FALLTHROUGH */
 	case ATA_SF_EPC_SET_STATE:
 		if (enable == -1) {
 			warnx("Must specify enable (-e) or disable (-d)");
diff --git a/sbin/camcontrol/persist.c b/sbin/camcontrol/persist.c
index e53c4fa163e..a56027b5c90 100644
--- a/sbin/camcontrol/persist.c
+++ b/sbin/camcontrol/persist.c
@@ -241,9 +241,11 @@ persist_print_cap(struct scsi_per_res_cap *cap, uint32_t valid_len)
 {
 	uint32_t length;
 	int check_type_mask = 0;
+	uint32_t type_mask;
 
 	length = scsi_2btoul(cap->length);
 	length = MIN(length, valid_len);
+	type_mask = scsi_2btoul(cap->type_mask);
 
 	if (length < __offsetof(struct scsi_per_res_cap, type_mask)) {
 		fprintf(stdout, "Insufficient data (%u bytes) to report "
@@ -345,20 +347,20 @@ persist_print_cap(struct scsi_per_res_cap *cap, uint32_t valid_len)
 		fprintf(stdout, "Supported Persistent Reservation Types:\n");
 		fprintf(stdout, "    Write Exclusive - All Registrants "
 			"(WR_EX_AR): %d\n",
-			(cap->type_mask[0] & SPRI_TM_WR_EX_AR)? 1 : 0);
+			(type_mask & SPRI_TM_WR_EX_AR)? 1 : 0);
 		fprintf(stdout, "    Exclusive Access - Registrants Only "
 			"(EX_AC_RO): %d\n",
-			(cap->type_mask[0] & SPRI_TM_EX_AC_RO) ? 1 : 0);
+			(type_mask & SPRI_TM_EX_AC_RO) ? 1 : 0);
 		fprintf(stdout, "    Write Exclusive - Registrants Only "
 			"(WR_EX_RO): %d\n",
-			(cap->type_mask[0] & SPRI_TM_WR_EX_RO)? 1 : 0);
+			(type_mask & SPRI_TM_WR_EX_RO)? 1 : 0);
 		fprintf(stdout, "    Exclusive Access (EX_AC): %d\n",
-			(cap->type_mask[0] & SPRI_TM_EX_AC) ? 1 : 0);
+			(type_mask & SPRI_TM_EX_AC) ? 1 : 0);
 		fprintf(stdout, "    Write Exclusive (WR_EX): %d\n",
-			(cap->type_mask[0] & SPRI_TM_WR_EX) ? 1 : 0);
+			(type_mask & SPRI_TM_WR_EX) ? 1 : 0);
 		fprintf(stdout, "    Exclusive Access - All Registrants "
 			"(EX_AC_AR): %d\n",
-			(cap->type_mask[1] & SPRI_TM_EX_AC_AR) ? 1 : 0);
+			(type_mask & SPRI_TM_EX_AC_AR) ? 1 : 0);
 	} else {
 		fprintf(stdout, "Persistent Reservation Type Mask is NOT "
 			"valid\n");
diff --git a/sbin/camcontrol/timestamp.c b/sbin/camcontrol/timestamp.c
index 032357be832..300fbe4254b 100644
--- a/sbin/camcontrol/timestamp.c
+++ b/sbin/camcontrol/timestamp.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -138,6 +139,8 @@ set_restore_flags(struct cam_device *device, uint8_t *flags, int set_flag,
 	 * Create the control page at the correct point in the mode_buf, it
 	 * starts after the header and the blk description.
 	 */
+	assert(hdr_and_blk_length <=
+	    sizeof(mode_buf) - sizeof(struct scsi_control_ext_page));
 	control_page = (struct scsi_control_ext_page *)&mode_buf
 	    [hdr_and_blk_length];
 	if (set_flag != 0) {
@@ -240,6 +243,7 @@ report_timestamp(struct cam_device *device, uint64_t *ts,
 bailout:
 	if (ccb != NULL)
 		cam_freeccb(ccb);
+	free(report_buf);
 
 	return error;
 }
diff --git a/sbin/devd/devd.cc b/sbin/devd/devd.cc
index d88c1507b71..7e28e55b44e 100644
--- a/sbin/devd/devd.cc
+++ b/sbin/devd/devd.cc
@@ -95,6 +95,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "devd.h"		/* C compatible definitions */
@@ -372,7 +373,7 @@ media::do_match(config &c)
 	s = socket(PF_INET, SOCK_DGRAM, 0);
 	if (s >= 0) {
 		memset(&ifmr, 0, sizeof(ifmr));
-		strncpy(ifmr.ifm_name, value.c_str(), sizeof(ifmr.ifm_name));
+		strlcpy(ifmr.ifm_name, value.c_str(), sizeof(ifmr.ifm_name));
 
 		if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) >= 0 &&
 		    ifmr.ifm_status & IFM_AVALID) {
@@ -871,8 +872,10 @@ create_socket(const char *name, int socktype)
 	if (::bind(fd, (struct sockaddr *) & sun, slen) < 0)
 		err(1, "bind");
 	listen(fd, 4);
-	chown(name, 0, 0);	/* XXX - root.wheel */
-	chmod(name, 0666);
+	if (chown(name, 0, 0))	/* XXX - root.wheel */
+		err(1, "chown");
+	if (chmod(name, 0666))
+		err(1, "chmod");
 	return (fd);
 }
 
@@ -1058,7 +1061,13 @@ event_loop(void)
 				buffer[rv] = '\0';
 				while (buffer[--rv] == '\n')
 					buffer[rv] = '\0';
-				process_event(buffer);
+				try {
+					process_event(buffer);
+				}
+				catch (std::length_error e) {
+					devdlog(LOG_ERR, "Dropping event %s "
+					    "due to low memory", buffer);
+				}
 			} else if (rv < 0) {
 				if (errno != EINTR)
 					break;
@@ -1076,6 +1085,8 @@ event_loop(void)
 		if (FD_ISSET(seqpacket_fd, &fds))
 			new_client(seqpacket_fd, SOCK_SEQPACKET);
 	}
+	close(seqpacket_fd);
+	close(stream_fd);
 	close(fd);
 }
 
@@ -1218,7 +1229,8 @@ check_devd_enabled()
 	if (val == 0) {
 		warnx("Setting " SYSCTL " to 1000");
 		val = 1000;
-		sysctlbyname(SYSCTL, NULL, NULL, &val, sizeof(val));
+		if (sysctlbyname(SYSCTL, NULL, NULL, &val, sizeof(val)))
+			err(1, "sysctlbyname");
 	}
 }
 
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index fe5016346d6..290798fd8ca 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -28,7 +28,7 @@
 .\"     From: @(#)ifconfig.8	8.3 (Berkeley) 1/5/94
 .\" $FreeBSD$
 .\"
-.Dd September 17, 2016
+.Dd January 18, 2017
 .Dt IFCONFIG 8
 .Os
 .Sh NAME
@@ -460,6 +460,8 @@ this directive is used to select between 802.11a
 and 802.11g
 .Pq Cm 11g
 operating modes.
+.It Cm txrtlmt
+Set if the driver supports TX rate limiting.
 .It Cm inst Ar minst , Cm instance Ar minst
 Set the media instance to
 .Ar minst .
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index cd6116602ee..23dbdb88bae 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -1145,7 +1145,7 @@ unsetifdescr(const char *val, int value, int s, const struct afswtch *afp)
 "\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" \
 "\10VLAN_HWCSUM\11TSO4\12TSO6\13LRO\14WOL_UCAST\15WOL_MCAST\16WOL_MAGIC" \
 "\17TOE4\20TOE6\21VLAN_HWFILTER\23VLAN_HWTSO\24LINKSTATE\25NETMAP" \
-"\26RXCSUM_IPV6\27TXCSUM_IPV6"
+"\26RXCSUM_IPV6\27TXCSUM_IPV6\31TXRTLMT"
 
 /*
  * Print the status of the interface.  If an address family was
@@ -1453,6 +1453,8 @@ static struct cmd basic_cmds[] = {
 	DEF_CMD("-wol_mcast",	-IFCAP_WOL_MCAST,	setifcap),
 	DEF_CMD("wol_magic",	IFCAP_WOL_MAGIC,	setifcap),
 	DEF_CMD("-wol_magic",	-IFCAP_WOL_MAGIC,	setifcap),
+	DEF_CMD("txrtlmt",	IFCAP_TXRTLMT,	setifcap),
+	DEF_CMD("-txrtlmt",	-IFCAP_TXRTLMT,	setifcap),
 	DEF_CMD("normal",	-IFF_LINK0,	setifflags),
 	DEF_CMD("compress",	IFF_LINK0,	setifflags),
 	DEF_CMD("noicmp",	IFF_LINK1,	setifflags),
diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c
index 8ff16323274..f2d2fc44d31 100644
--- a/sbin/ifconfig/ifieee80211.c
+++ b/sbin/ifconfig/ifieee80211.c
@@ -1787,6 +1787,21 @@ set80211stbc(const char *val, int d, int s, const struct afswtch *rafp)
 	set80211(s, IEEE80211_IOC_STBC, stbc, 0, NULL);
 }
 
+static void
+set80211ldpc(const char *val, int d, int s, const struct afswtch *rafp)
+{
+        int ldpc;
+ 
+        if (get80211val(s, IEEE80211_IOC_LDPC, &ldpc) < 0)
+                errx(-1, "cannot set LDPC setting");
+        if (d < 0) {
+                d = -d;
+                ldpc &= ~d;
+        } else
+                ldpc |= d;
+        set80211(s, IEEE80211_IOC_LDPC, ldpc, 0, NULL);
+}
+
 static
 DECL_CMD_FUNC(set80211ampdulimit, val, d)
 {
@@ -5030,6 +5045,23 @@ end:
 				break;
 			}
 		}
+		if (get80211val(s, IEEE80211_IOC_LDPC, &val) != -1) {
+			switch (val) {
+			case 0:
+				LINE_CHECK("-ldpc");
+				break;
+			case 1:
+				LINE_CHECK("ldpctx -ldpcrx");
+				break;
+			case 2:
+				LINE_CHECK("-ldpctx ldpcrx");
+				break;
+			case 3:
+				if (verbose)
+					LINE_CHECK("ldpc");
+				break;
+			}
+		}
 	}
 
 	if (IEEE80211_IS_CHAN_VHT(c) || verbose) {
@@ -5602,7 +5634,13 @@ static struct cmd ieee80211_cmds[] = {
 	DEF_CMD("stbctx",	1,	set80211stbc),
 	DEF_CMD("-stbctx",	-1,	set80211stbc),
 	DEF_CMD("stbc",		3,	set80211stbc),		/* NB: tx+rx */
-	DEF_CMD("-ampdu",	-3,	set80211stbc),
+	DEF_CMD("-stbc",	-3,	set80211stbc),
+	DEF_CMD("ldpcrx",	2,	set80211ldpc),
+	DEF_CMD("-ldpcrx",	-2,	set80211ldpc),
+	DEF_CMD("ldpctx",	1,	set80211ldpc),
+	DEF_CMD("-ldpctx",	-1,	set80211ldpc),
+	DEF_CMD("ldpc",		3,	set80211ldpc),		/* NB: tx+rx */
+	DEF_CMD("-ldpc",	-3,	set80211ldpc),
 	DEF_CMD("puren",	1,	set80211puren),
 	DEF_CMD("-puren",	0,	set80211puren),
 	DEF_CMD("doth",		1,	set80211doth),
diff --git a/sbin/restore/dirs.c b/sbin/restore/dirs.c
index 57b0523a69d..0c6f38c972b 100644
--- a/sbin/restore/dirs.c
+++ b/sbin/restore/dirs.c
@@ -645,7 +645,7 @@ setdirmodes(int flags)
 		if (!Nflag) {
 			if (node.extsize > 0) {
 				if (bufsize >= node.extsize) {
-					set_extattr_file(cp, buf, node.extsize);
+					set_extattr(-1, cp, buf, node.extsize, SXA_FILE);
 				} else {
 					fprintf(stderr, "Cannot restore %s%s\n",
 					    "extended attributes for ", cp);
diff --git a/sbin/restore/extern.h b/sbin/restore/extern.h
index 9b319ca7090..1689649a0d7 100644
--- a/sbin/restore/extern.h
+++ b/sbin/restore/extern.h
@@ -87,7 +87,12 @@ struct direct	*rst_readdir(RST_DIR *);
 void		 rst_closedir(void *);
 void	 	 runcmdshell(void);
 char		*savename(char *);
-void		 set_extattr_file(char *, void *, int);
+enum set_extattr_mode {
+	SXA_FILE,
+	SXA_LINK,
+	SXA_FD,
+};
+void		 set_extattr(int, char *, void *, int, enum set_extattr_mode);
 void	 	 setdirmodes(int);
 void		 setinput(char *, int);
 void		 setup(void);
diff --git a/sbin/restore/tape.c b/sbin/restore/tape.c
index f66f8b4caf4..67f770ab63b 100644
--- a/sbin/restore/tape.c
+++ b/sbin/restore/tape.c
@@ -105,8 +105,6 @@ static void	 findinode(struct s_spcl *);
 static void	 findtapeblksize(void);
 static char	*setupextattr(int);
 static void	 xtrattr(char *, size_t);
-static void	 set_extattr_link(char *, void *, int);
-static void	 set_extattr_fd(int, char *, void *, int);
 static void	 skiphole(void (*)(char *, size_t), size_t *);
 static int	 gethead(struct s_spcl *);
 static void	 readtape(char *);
@@ -627,7 +625,7 @@ extractfile(char *name)
 		}
 		if (linkit(lnkbuf, name, SYMLINK) == GOOD) {
 			if (extsize > 0)
-				set_extattr_link(name, buf, extsize);
+				set_extattr(-1, name, buf, extsize, SXA_LINK);
 			(void) lchown(name, uid, gid);
 			(void) lchmod(name, mode);
 			(void) utimensat(AT_FDCWD, name, ctimep,
@@ -658,7 +656,7 @@ extractfile(char *name)
 		} else {
 			buf = setupextattr(extsize);
 			getfile(xtrnull, xtrattr, xtrnull);
-			set_extattr_file(name, buf, extsize);
+			set_extattr(-1, name, buf, extsize, SXA_FILE);
 		}
 		(void) chown(name, uid, gid);
 		(void) chmod(name, mode);
@@ -688,7 +686,7 @@ extractfile(char *name)
 		} else {
 			buf = setupextattr(extsize);
 			getfile(xtrnull, xtrattr, xtrnull);
-			set_extattr_file(name, buf, extsize);
+			set_extattr(-1, name, buf, extsize, SXA_FILE);
 		}
 		(void) chown(name, uid, gid);
 		(void) chmod(name, mode);
@@ -715,7 +713,7 @@ extractfile(char *name)
 		buf = setupextattr(extsize);
 		getfile(xtrfile, xtrattr, xtrskip);
 		if (extsize > 0)
-			set_extattr_fd(ofile, name, buf, extsize);
+			set_extattr(ofile, name, buf, extsize, SXA_FD);
 		(void) fchown(ofile, uid, gid);
 		(void) fchmod(ofile, mode);
 		(void) futimens(ofile, ctimep);
@@ -728,12 +726,16 @@ extractfile(char *name)
 }
 
 /*
- * Set attributes for a file.
+ * Set attributes on a file descriptor, link, or file.
  */
 void
-set_extattr_file(char *name, void *buf, int size)
+set_extattr(int fd, char *name, void *buf, int size, enum set_extattr_mode mode)
 {
 	struct extattr *eap, *eaend;
+	const char *method;
+	ssize_t res;
+	int error;
+	char eaname[EXTATTR_MAXNAMELEN + 1];
 
 	vprintf(stdout, "Set attributes for %s:", name);
 	eaend = buf + size;
@@ -748,17 +750,34 @@ set_extattr_file(char *name, void *buf, int size)
 		}
 		if (eap->ea_namespace == EXTATTR_NAMESPACE_EMPTY)
 			continue;
-		vprintf(stdout, "\n\t%s, (%d bytes), %*s",
+		snprintf(eaname, sizeof(eaname), "%.*s",
+		    (int)eap->ea_namelength, eap->ea_name);
+		vprintf(stdout, "\n\t%s, (%d bytes), %s",
 			namespace_names[eap->ea_namespace], eap->ea_length,
-			eap->ea_namelength, eap->ea_name);
+			eaname);
 		/*
 		 * First we try the general attribute setting interface.
 		 * However, some attributes can only be set by root or
 		 * by using special interfaces (for example, ACLs).
 		 */
-		if (extattr_set_file(name, eap->ea_namespace, eap->ea_name,
-		    EXTATTR_CONTENT(eap), EXTATTR_CONTENT_SIZE(eap)) != -1) {
-			dprintf(stdout, " (set using extattr_set_file)");
+		if (mode == SXA_FD) {
+			res = extattr_set_fd(fd, eap->ea_namespace,
+			    eaname, EXTATTR_CONTENT(eap),
+			    EXTATTR_CONTENT_SIZE(eap));
+			method = "extattr_set_fd";
+		} else if (mode == SXA_LINK) {
+			res = extattr_set_link(name, eap->ea_namespace,
+			    eaname, EXTATTR_CONTENT(eap),
+			    EXTATTR_CONTENT_SIZE(eap));
+			method = "extattr_set_link";
+		} else if (mode == SXA_FILE) {
+			res = extattr_set_file(name, eap->ea_namespace,
+			    eaname, EXTATTR_CONTENT(eap),
+			    EXTATTR_CONTENT_SIZE(eap));
+			method = "extattr_set_file";
+		}
+		if (res != -1) {
+			dprintf(stdout, " (set using %s)", method);
 			continue;
 		}
 		/*
@@ -767,137 +786,37 @@ set_extattr_file(char *name, void *buf, int size)
 		 * know about.
 		 */
 		if (eap->ea_namespace == EXTATTR_NAMESPACE_SYSTEM &&
-		    !strcmp(eap->ea_name, POSIX1E_ACL_ACCESS_EXTATTR_NAME)) {
-			if (acl_set_file(name, ACL_TYPE_ACCESS,
-			    EXTATTR_CONTENT(eap)) != -1) {
-				dprintf(stdout, " (set using acl_set_file)");
+		    strcmp(eaname, POSIX1E_ACL_ACCESS_EXTATTR_NAME) == 0) {
+			if (mode == SXA_FD) {
+				error = acl_set_fd(fd, EXTATTR_CONTENT(eap));
+				method = "acl_set_fd";
+			} else if (mode == SXA_LINK) {
+				error = acl_set_link_np(name, ACL_TYPE_ACCESS,
+				    EXTATTR_CONTENT(eap));
+				method = "acl_set_link_np";
+			} else if (mode == SXA_FILE) {
+				error = acl_set_file(name, ACL_TYPE_ACCESS,
+				    EXTATTR_CONTENT(eap));
+				method = "acl_set_file";
+			}
+			if (error != -1) {
+				dprintf(stdout, " (set using %s)", method);
 				continue;
 			}
 		}
 		if (eap->ea_namespace == EXTATTR_NAMESPACE_SYSTEM &&
-		    !strcmp(eap->ea_name, POSIX1E_ACL_DEFAULT_EXTATTR_NAME)) {
-			if (acl_set_file(name, ACL_TYPE_DEFAULT,
-			    EXTATTR_CONTENT(eap)) != -1) {
-				dprintf(stdout, " (set using acl_set_file)");
-				continue;
+		    strcmp(eaname, POSIX1E_ACL_DEFAULT_EXTATTR_NAME) == 0) {
+			if (mode == SXA_LINK) {
+				error = acl_set_link_np(name, ACL_TYPE_DEFAULT,
+				    EXTATTR_CONTENT(eap));
+				method = "acl_set_link_np";
+			} else {
+				error = acl_set_file(name, ACL_TYPE_DEFAULT,
+				    EXTATTR_CONTENT(eap));
+				method = "acl_set_file";
 			}
-		}
-		vprintf(stdout, " (unable to set)");
-	}
-	vprintf(stdout, "\n");
-}
-
-/*
- * Set attributes for a symbolic link.
- */
-static void
-set_extattr_link(char *name, void *buf, int size)
-{
-	struct extattr *eap, *eaend;
-
-	vprintf(stdout, "Set attributes for %s:", name);
-	eaend = buf + size;
-	for (eap = buf; eap < eaend; eap = EXTATTR_NEXT(eap)) {
-		/*
-		 * Make sure this entry is complete.
-		 */
-		if (EXTATTR_NEXT(eap) > eaend || eap->ea_length <= 0) {
-			dprintf(stdout, "\n\t%scorrupted",
-				eap == buf ? "" : "remainder ");
-			break;
-		}
-		if (eap->ea_namespace == EXTATTR_NAMESPACE_EMPTY)
-			continue;
-		vprintf(stdout, "\n\t%s, (%d bytes), %*s",
-			namespace_names[eap->ea_namespace], eap->ea_length,
-			eap->ea_namelength, eap->ea_name);
-		/*
-		 * First we try the general attribute setting interface.
-		 * However, some attributes can only be set by root or
-		 * by using special interfaces (for example, ACLs).
-		 */
-		if (extattr_set_link(name, eap->ea_namespace, eap->ea_name,
-		    EXTATTR_CONTENT(eap), EXTATTR_CONTENT_SIZE(eap)) != -1) {
-			dprintf(stdout, " (set using extattr_set_link)");
-			continue;
-		}
-		/*
-		 * If the general interface refuses to set the attribute,
-		 * then we try all the specialized interfaces that we
-		 * know about.
-		 */
-		if (eap->ea_namespace == EXTATTR_NAMESPACE_SYSTEM &&
-		    !strcmp(eap->ea_name, POSIX1E_ACL_ACCESS_EXTATTR_NAME)) {
-			if (acl_set_link_np(name, ACL_TYPE_ACCESS,
-			    EXTATTR_CONTENT(eap)) != -1) {
-				dprintf(stdout, " (set using acl_set_link_np)");
-				continue;
-			}
-		}
-		if (eap->ea_namespace == EXTATTR_NAMESPACE_SYSTEM &&
-		    !strcmp(eap->ea_name, POSIX1E_ACL_DEFAULT_EXTATTR_NAME)) {
-			if (acl_set_link_np(name, ACL_TYPE_DEFAULT,
-			    EXTATTR_CONTENT(eap)) != -1) {
-				dprintf(stdout, " (set using acl_set_link_np)");
-				continue;
-			}
-		}
-		vprintf(stdout, " (unable to set)");
-	}
-	vprintf(stdout, "\n");
-}
-
-/*
- * Set attributes on a file descriptor.
- */
-static void
-set_extattr_fd(int fd, char *name, void *buf, int size)
-{
-	struct extattr *eap, *eaend;
-
-	vprintf(stdout, "Set attributes for %s:", name);
-	eaend = buf + size;
-	for (eap = buf; eap < eaend; eap = EXTATTR_NEXT(eap)) {
-		/*
-		 * Make sure this entry is complete.
-		 */
-		if (EXTATTR_NEXT(eap) > eaend || eap->ea_length <= 0) {
-			dprintf(stdout, "\n\t%scorrupted",
-				eap == buf ? "" : "remainder ");
-			break;
-		}
-		if (eap->ea_namespace == EXTATTR_NAMESPACE_EMPTY)
-			continue;
-		vprintf(stdout, "\n\t%s, (%d bytes), %*s",
-			namespace_names[eap->ea_namespace], eap->ea_length,
-			eap->ea_namelength, eap->ea_name);
-		/*
-		 * First we try the general attribute setting interface.
-		 * However, some attributes can only be set by root or
-		 * by using special interfaces (for example, ACLs).
-		 */
-		if (extattr_set_fd(fd, eap->ea_namespace, eap->ea_name,
-		    EXTATTR_CONTENT(eap), EXTATTR_CONTENT_SIZE(eap)) != -1) {
-			dprintf(stdout, " (set using extattr_set_fd)");
-			continue;
-		}
-		/*
-		 * If the general interface refuses to set the attribute,
-		 * then we try all the specialized interfaces that we
-		 * know about.
-		 */
-		if (eap->ea_namespace == EXTATTR_NAMESPACE_SYSTEM &&
-		    !strcmp(eap->ea_name, POSIX1E_ACL_ACCESS_EXTATTR_NAME)) {
-			if (acl_set_fd(fd, EXTATTR_CONTENT(eap)) != -1) {
-				dprintf(stdout, " (set using acl_set_fd)");
-				continue;
-			}
-		}
-		if (eap->ea_namespace == EXTATTR_NAMESPACE_SYSTEM &&
-		    !strcmp(eap->ea_name, POSIX1E_ACL_DEFAULT_EXTATTR_NAME)) {
-			if (acl_set_file(name, ACL_TYPE_DEFAULT,
-			    EXTATTR_CONTENT(eap)) != -1) {
-				dprintf(stdout, " (set using acl_set_file)");
+			if (error != -1) {
+				dprintf(stdout, " (set using %s)", method);
 				continue;
 			}
 		}
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 1b4e442c587..816f929dc2c 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -889,6 +889,10 @@ MAN+=		iscsi_initiator.4
 MAN+=		iser.4
 .endif
 
+.if ${MK_OFED} != "no"
+MAN+=		mlx4ib.4
+.endif
+
 .if ${MK_TESTS} != "no"
 ATF=            ${.CURDIR}/../../../contrib/atf
 .PATH:          ${ATF}/doc
diff --git a/share/man/man4/mlx4en.4 b/share/man/man4/mlx4en.4
index 898183689c6..8ec4db9cf8e 100644
--- a/share/man/man4/mlx4en.4
+++ b/share/man/man4/mlx4en.4
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd September 30, 2016
+.Dd January 18, 2017
 .Dt MLX4EN 4
 .Os
 .Sh NAME
@@ -81,6 +81,7 @@ If an issue is identified with this driver with a supported adapter,
 email all the specific information related to the issue to
 .Aq Mt freebsd-drivers@mellanox.com .
 .Sh SEE ALSO
+.Xr mlx4ib 4 ,
 .Xr ifconfig 8
 .Sh HISTORY
 The
diff --git a/share/man/man4/mlx4ib.4 b/share/man/man4/mlx4ib.4
new file mode 100644
index 00000000000..79535abca9f
--- /dev/null
+++ b/share/man/man4/mlx4ib.4
@@ -0,0 +1,96 @@
+.\" Copyright (c) 2016 Mellanox Technologies
+.\" 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 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 AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd January 18, 2017
+.Dt MLX4IB 4
+.Os
+.Sh NAME
+.Nm mlx4ib
+.Nd "Mellanox ConnectX-3 10GbE/40GbE network adapter driver"
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following lines in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "options COMPAT_LINUXKPI"
+.Cd "device mlx4"
+.Cd "device mlx4ib"
+.Ed
+.Pp
+To load the driver as a module at run-time,
+run the following command as root:
+.Bd -literal -offset indent
+kldload mlx4ib
+.Ed
+.Pp
+To load the driver as a
+module at boot time, place the following lines in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+mlx4ib_load="YES"
+.Ed
+.Sh DESCRIPTION
+Mellanox ConnectX adapter cards with Virtual Protocol Interconnect
+(VPI) provide the highest performing and most flexible interconnect
+solution for Enterprise Data Centers, High-Performance Computing, and
+Embedded environments.
+Clustered data bases, parallelized applications, transactional
+services and high-performance embedded I/O applications will achieve
+significant performance improvements resulting in reduced completion
+time and lower cost per operation.
+.Sh HARDWARE
+The
+.Nm
+driver supports the following network adapters:
+.Pp
+.Bl -bullet -compact
+.It
+Mellanox ConnectX-2 (IB)
+.It
+Mellanox ConnectX-3 (IB)
+.El
+.Sh SUPPORT
+For general information and support,
+go to the Mellanox support website at:
+.Pa http://www.mellanox.com/ .
+.Pp
+If an issue is identified with this driver with a supported adapter,
+email all the specific information related to the issue to
+.Aq Mt freebsd-drivers@mellanox.com .
+.Sh SEE ALSO
+.Xr mlx4en 4 ,
+.Xr ifconfig 8
+.Sh HISTORY
+The
+.Nm
+device driver first appeared in
+.Fx 9.x .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Mellanox Technologies  .
diff --git a/share/man/man4/usb_quirk.4 b/share/man/man4/usb_quirk.4
index 5ca603ab09d..55ab8ebc757 100644
--- a/share/man/man4/usb_quirk.4
+++ b/share/man/man4/usb_quirk.4
@@ -16,7 +16,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 4, 2016
+.Dd January 17, 2017
 .Dt USB_QUIRK 4
 .Os
 .Sh NAME
@@ -52,6 +52,10 @@ input is async despite claim of adaptive
 do not adjust for fractional samples
 .It UQ_AU_NO_XU
 audio device has broken extension unit
+.It UQ_AU_VENDOR_CLASS
+audio device uses vendor class to identify itself
+.It UQ_AU_SET_SPDIF_CM6206
+audio device needs special programming to enable S/PDIF audio output
 .It UQ_BAD_ADC
 bad audio spec version number
 .It UQ_BAD_AUDIO
diff --git a/share/man/man5/fs.5 b/share/man/man5/fs.5
index 94a873bea30..c52fa1f1b68 100644
--- a/share/man/man5/fs.5
+++ b/share/man/man5/fs.5
@@ -28,7 +28,7 @@
 .\"     @(#)fs.5	8.2 (Berkeley) 4/19/94
 .\" $FreeBSD$
 .\"
-.Dd April 23, 2016
+.Dd January 16, 2017
 .Dt FS 5
 .Os
 .Sh NAME
@@ -388,18 +388,19 @@ For further information, see the include file
 The format of an external attribute is defined by the extattr structure:
 .Bd -literal
 struct extattr {
-	int32_t	ea_length;	    /* length of this attribute */
-	int8_t	ea_namespace;	    /* name space of this attribute */
-	int8_t	ea_contentpadlen;   /* padding at end of attribute */
-	int8_t	ea_namelength;	    /* length of attribute name */
-	char	ea_name[1];	    /* null-terminated attribute name */
+	uint32_t ea_length;	    /* length of this attribute */
+	uint8_t	ea_namespace;	    /* name space of this attribute */
+	uint8_t	ea_contentpadlen;   /* bytes of padding at end of attribute */
+	uint8_t	ea_namelength;	    /* length of attribute name */
+	char	ea_name[1];	    /* attribute name (NOT nul-terminated) */
+	/* padding, if any, to align attribute content to 8 byte boundary */
 	/* extended attribute content follows */
 };
 .Ed
 .Pp
 Several macros are defined to manipulate these structures.
 Each macro takes a pointer to an extattr structure.
-.Bl -tag -width ".Dv EXTATTR_SET_LENGTHS(eap, size)"
+.Bl -tag -width ".Dv EXTATTR_CONTENT_SIZE(eap)"
 .It Dv EXTATTR_NEXT(eap)
 Returns a pointer to the next extended attribute following
 .Fa eap .
@@ -409,35 +410,19 @@ Returns a pointer to the extended attribute content referenced by
 .It Dv EXTATTR_CONTENT_SIZE(eap)
 Returns the size of the extended attribute content referenced by
 .Fa eap .
-.It Dv EXTATTR_SET_LENGTHS(eap, size)
-Called with the size of the attribute content after initializing
-the attribute name to calculate and set the
-.Fa ea_length ,
-.Fa ea_namelength ,
-and
-.Fa ea_contentpadlen
-fields of the extended attribute structure.
 .El
 .Pp
 The following code identifies an ACL:
 .Bd -literal
 	if (eap->ea_namespace == EXTATTR_NAMESPACE_SYSTEM &&
-	    !strcmp(eap->ea_name, POSIX1E_ACL_ACCESS_EXTATTR_NAME) {
+            eap->ea_namelength == sizeof(POSIX1E_ACL_ACCESS_EXTATTR_NAME) - 1 &&
+	    strncmp(eap->ea_name, POSIX1E_ACL_ACCESS_EXTATTR_NAME,
+             sizeof(POSIX1E_ACL_ACCESS_EXTATTR_NAME) - 1) == 0) {
 		aclp = EXTATTR_CONTENT(eap);
 		acllen = EXTATTR_CONTENT_SIZE(eap);
 		...
 	}
 .Ed
-.Pp
-The following code creates an extended attribute
-containing a copy of a structure
-.Fa mygif :
-.Bd -literal
-	eap->ea_namespace = EXTATTR_NAMESPACE_USER;
-	strcpy(eap->ea_name, "filepic.gif");
-	EXTATTR_SET_LENGTHS(eap, sizeof(struct mygif));
-	memcpy(EXTATTR_CONTENT(eap), &mygif, sizeof(struct mygif));
-.Ed
 .Sh HISTORY
 A super-block structure named filsys appeared in
 .At v6 .
diff --git a/share/man/man5/tmpfs.5 b/share/man/man5/tmpfs.5
index 9cce1fba868..6374b092564 100644
--- a/share/man/man5/tmpfs.5
+++ b/share/man/man5/tmpfs.5
@@ -1,7 +1,12 @@
 .\"-
 .\" Copyright (c) 2007 Xin LI
+.\" Copyright (c) 2017 The FreeBSD Foundation, Inc.
 .\" All rights reserved.
 .\"
+.\" Part of this documentation was written 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:
@@ -49,12 +54,12 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 23, 2012
+.Dd January 17, 2017
 .Dt TMPFS 5
 .Os
 .Sh NAME
 .Nm tmpfs
-.Nd "efficient memory file system"
+.Nd "in-memory file system"
 .Sh SYNOPSIS
 To compile this driver into the kernel,
 place the following line in your
@@ -72,17 +77,40 @@ tmpfs_load="YES"
 .Sh DESCRIPTION
 The
 .Nm
-driver will permit the
-.Fx
-kernel to access
+driver implements in-memory, or
 .Tn tmpfs
-file systems.
+file system.
+The filesystem stores both file metadata and data in main memory.
+This allows very fast and low latency accesses to the data.
+The data is volatile.
+An umount or system reboot invalidates it.
+These properties make the filesystem's mounts suitable for fast
+scratch storage, e.g.
+.Pa /tmp .
+.Pp
+If the system becomes low on memory and swap is configured (see
+.Xr swapon 8 ),
+file data may be written to the swap space, freeing memory
+for other needs.
+The current implementation never swaps out metadata, including
+the directory content.
+Keep this in mind when planning the mount limits, especially when expecting
+to place many small files on a tmpfs mount.
+.Pp
+When a file from a tmpfs mount is mmaped (see
+.Xr mmap 2 )
+into the process address space, the swap VM object which manages the file
+pages is used to implement mapping and to avoid double-copying of
+the file data.
+This quirk causes process inspection tools, like
+.Xr procstat 1 ,
+to report anonymous memory mappings instead of file mappings.
 .Sh OPTIONS
 The following options are available when
 mounting
 .Nm
 file systems:
-.Bl -tag -width indent
+.Bl -tag -width "It Cm maxfilesize"
 .It Cm gid
 Specifies the group ID of the root inode of the file system.
 Defaults to the mount point's GID.
@@ -114,11 +142,15 @@ memory file system:
 .Pp
 .Dl "mount -t tmpfs tmpfs /tmp"
 .Sh SEE ALSO
+.Xr procstat 1 ,
 .Xr nmount 2 ,
+.Xr mmap 2 ,
 .Xr unmount 2 ,
 .Xr fstab 5 ,
 .Xr mdmfs 8 ,
-.Xr mount 8
+.Xr mount 8 ,
+.Xr swapinfo 8 ,
+.Xr swapon 8
 .Sh HISTORY
 The
 .Nm
@@ -130,7 +162,7 @@ The
 .Nm
 kernel implementation was written by
 .An Julio M. Merino Vidal Aq Mt jmmv@NetBSD.org
-as a Google SoC project.
+as a Google Summer of Code project.
 .Pp
 .An Rohit Jalan
 and others ported it from
@@ -140,5 +172,3 @@ to
 .Pp
 This manual page was written by
 .An Xin LI Aq Mt delphij@FreeBSD.org .
-.Sh BUGS
-Some file system mount time options may not be well-supported.
diff --git a/share/man/man7/arch.7 b/share/man/man7/arch.7
index 6f09463ef49..cc20866470e 100644
--- a/share/man/man7/arch.7
+++ b/share/man/man7/arch.7
@@ -26,7 +26,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd October 20, 2016
+.Dd January 21, 2017
 .Dt ARCH 7
 .Os
 .Sh NAME
@@ -135,7 +135,8 @@ On all supported architectures,
 .It mips64hf    Ta hard Ta identical to double
 .It powerpc     Ta hard Ta hard, double precision
 .It powerpc64   Ta hard Ta hard, double precision
-.It riscv       Ta
+.It riscv64     Ta hard Ta hard, double precision
+.It riscv64sf   Ta soft Ta soft, double precision
 .It sparc64     Ta hard Ta hard, quad precision
 .El
 .Ss Predefined Macros
diff --git a/share/mk/bsd.README b/share/mk/bsd.README
index de2981de36a..849f4139b6a 100644
--- a/share/mk/bsd.README
+++ b/share/mk/bsd.README
@@ -418,7 +418,15 @@ tree.
 bsd.snmpmod.mk leverages bsd.lib.mk for building MIB modules and
 bsd.files.mk for installing MIB description and definition files.
 
-It has no additional targets.
+It implements the following additional targets:
+
+	smilint:
+		execute smilint on the MIBs defined by BMIBS.
+
+		The net-mgmt/libsmi package must be installed before
+		executing this target. The net-mgmt/net-snmp package
+		should be installed as well to reduce false positives
+		from smilint.
 
 It sets/uses the following variables:
 
@@ -444,8 +452,19 @@ EXTRAMIBSYMS	Extra MIB definition files used only for extracting
 
 		See ${MOD}_oid.h for more details.
 
+LOCALBASE	The package root where smilint and the net-snmp
+		definitions can be found
+
 MOD		The bsnmpd module name.
 
+SMILINT		smilint binary to use with the smilint make target.
+
+SMILINT_FLAGS	flags to pass to smilint.
+
+SMIPATH		A colon-separated directory path where MIBs definitions
+		can be found. See "SMIPATH" in smi_config for more
+		details.
+
 XSYM		MIB names to extract symbols for. See ${MOD}_oid.h for
 		more details.
 
diff --git a/share/mk/bsd.snmpmod.mk b/share/mk/bsd.snmpmod.mk
index b3aab0626a8..224b82d1ee0 100644
--- a/share/mk/bsd.snmpmod.mk
+++ b/share/mk/bsd.snmpmod.mk
@@ -25,4 +25,18 @@ FILESGROUPS+=	BMIBS
 BMIBSDIR?=	${SHAREDIR}/snmp/mibs
 .endif
 
+.if !target(smilint) && !empty(BMIBS)
+LOCALBASE?=	/usr/local
+
+SMILINT?=	${LOCALBASE}/bin/smilint
+
+SMIPATH?=	${BMIBSDIR}:${LOCALBASE}/share/snmp/mibs
+
+SMILINT_FLAGS?=	-c /dev/null -l6 -i group-membership
+
+smilint: ${BMIBS}
+	SMIPATH=${SMIPATH} ${SMILINT} ${SMILINT_FLAGS} ${.ALLSRC}
+.endif
+smilint: .PHONY
+
 .include 
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 817cdbe97c9..5d09929bd84 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -1862,16 +1862,16 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force)
 			return;
 
 		/*
-		 * Otherwise, do per-cache line flush.  Use the mfence
+		 * Otherwise, do per-cache line flush.  Use the sfence
 		 * instruction to insure that previous stores are
 		 * included in the write-back.  The processor
 		 * propagates flush to other processors in the cache
 		 * coherence domain.
 		 */
-		mfence();
+		sfence();
 		for (; sva < eva; sva += cpu_clflush_line_size)
 			clflushopt(sva);
-		mfence();
+		sfence();
 	} else if ((cpu_feature & CPUID_CLFSH) != 0 &&
 	    eva - sva < PMAP_CLFLUSH_THRESHOLD) {
 		if (pmap_kextract(sva) == lapic_paddr)
@@ -1915,7 +1915,9 @@ pmap_invalidate_cache_pages(vm_page_t *pages, int count)
 	    ((cpu_feature & CPUID_CLFSH) == 0 && !useclflushopt))
 		pmap_invalidate_cache();
 	else {
-		if (useclflushopt || cpu_vendor_id != CPU_VENDOR_INTEL)
+		if (useclflushopt)
+			sfence();
+		else if (cpu_vendor_id != CPU_VENDOR_INTEL)
 			mfence();
 		for (i = 0; i < count; i++) {
 			daddr = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pages[i]));
@@ -1927,7 +1929,9 @@ pmap_invalidate_cache_pages(vm_page_t *pages, int count)
 					clflush(daddr);
 			}
 		}
-		if (useclflushopt || cpu_vendor_id != CPU_VENDOR_INTEL)
+		if (useclflushopt)
+			sfence();
+		else if (cpu_vendor_id != CPU_VENDOR_INTEL)
 			mfence();
 	}
 }
diff --git a/sys/amd64/cloudabi32/cloudabi32_sysvec.c b/sys/amd64/cloudabi32/cloudabi32_sysvec.c
index 5cf73ab5bfe..36371919796 100644
--- a/sys/amd64/cloudabi32/cloudabi32_sysvec.c
+++ b/sys/amd64/cloudabi32/cloudabi32_sysvec.c
@@ -181,7 +181,7 @@ cloudabi32_thread_setregs(struct thread *td,
 
 	/* Perform standard register initialization. */
 	stack.ss_sp = TO_PTR(attr->stack);
-	stack.ss_size = attr->stack_size - sizeof(args);
+	stack.ss_size = attr->stack_len - sizeof(args);
 	cpu_set_upcall(td, TO_PTR(attr->entry_point), NULL, &stack);
 
 	/*
diff --git a/sys/amd64/cloudabi64/cloudabi64_sysvec.c b/sys/amd64/cloudabi64/cloudabi64_sysvec.c
index f1b38630c0d..060825e7998 100644
--- a/sys/amd64/cloudabi64/cloudabi64_sysvec.c
+++ b/sys/amd64/cloudabi64/cloudabi64_sysvec.c
@@ -164,7 +164,7 @@ cloudabi64_thread_setregs(struct thread *td,
 	 * from the top of the stack to store a single element array,
 	 * containing a pointer to the TCB. %fs base will point to this.
 	 */
-	tcbptr = rounddown(attr->stack + attr->stack_size - sizeof(tcbptr),
+	tcbptr = rounddown(attr->stack + attr->stack_len - sizeof(tcbptr),
 	    _Alignof(tcbptr));
 	error = copyout(&tcb, (void *)tcbptr, sizeof(tcb));
 	if (error != 0)
diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h
index 4b7df46ce9c..5fa0d77f3d1 100644
--- a/sys/amd64/include/cpufunc.h
+++ b/sys/amd64/include/cpufunc.h
@@ -326,6 +326,13 @@ mfence(void)
 	__asm __volatile("mfence" : : : "memory");
 }
 
+static __inline void
+sfence(void)
+{
+
+	__asm __volatile("sfence" : : : "memory");
+}
+
 static __inline void
 ia32_pause(void)
 {
diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c
index 5cb41500932..53a8bdc660a 100644
--- a/sys/amd64/vmm/vmm_dev.c
+++ b/sys/amd64/vmm/vmm_dev.c
@@ -258,7 +258,7 @@ alloc_memseg(struct vmmdev_softc *sc, struct vm_memseg *mseg)
 	if (VM_MEMSEG_NAME(mseg)) {
 		sysmem = false;
 		name = malloc(SPECNAMELEN + 1, M_VMMDEV, M_WAITOK);
-		error = copystr(VM_MEMSEG_NAME(mseg), name, SPECNAMELEN + 1, 0);
+		error = copystr(mseg->name, name, SPECNAMELEN + 1, 0);
 		if (error)
 			goto done;
 	}
diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c
index 805a09d5f13..a8de0e51d6e 100644
--- a/sys/arm/arm/pmap-v6.c
+++ b/sys/arm/arm/pmap-v6.c
@@ -110,11 +110,6 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
-#ifdef SMP
-#include 
-#else
-#include 
-#endif
 
 #ifdef DDB
 #include 
@@ -296,16 +291,6 @@ vm_paddr_t first_managed_pa;
 /*
  *  All those kernel PT submaps that BSD is so fond of
  */
-struct sysmaps {
-	struct	mtx lock;
-	pt2_entry_t *CMAP1;
-	pt2_entry_t *CMAP2;
-	pt2_entry_t *CMAP3;
-	caddr_t	CADDR1;
-	caddr_t	CADDR2;
-	caddr_t	CADDR3;
-};
-static struct sysmaps sysmaps_pcpu[MAXCPU];
 caddr_t _tmppt = 0;
 
 struct msgbuf *msgbufp = NULL; /* XXX move it to machdep.c */
@@ -1134,8 +1119,7 @@ void
 pmap_bootstrap(vm_offset_t firstaddr)
 {
 	pt2_entry_t *unused __unused;
-	struct sysmaps *sysmaps;
-	u_int i;
+	struct pcpu *pc;
 
 	/*
 	 * Initialize the kernel pmap (which is statically allocated).
@@ -1174,15 +1158,13 @@ pmap_bootstrap(vm_offset_t firstaddr)
 
 	/*
 	 * Local CMAP1/CMAP2 are used for zeroing and copying pages.
-	 * Local CMAP3 is used for data cache cleaning.
+	 * Local CMAP2 is also used for data cache cleaning.
 	 */
-	for (i = 0; i < MAXCPU; i++) {
-		sysmaps = &sysmaps_pcpu[i];
-		mtx_init(&sysmaps->lock, "SYSMAPS", NULL, MTX_DEF);
-		SYSMAP(caddr_t, sysmaps->CMAP1, sysmaps->CADDR1, 1);
-		SYSMAP(caddr_t, sysmaps->CMAP2, sysmaps->CADDR2, 1);
-		SYSMAP(caddr_t, sysmaps->CMAP3, sysmaps->CADDR3, 1);
-	}
+	pc = pcpu_find(curcpu);
+	mtx_init(&pc->pc_cmap_lock, "SYSMAPS", NULL, MTX_DEF);
+	SYSMAP(caddr_t, pc->pc_cmap1_pte2p, pc->pc_cmap1_addr, 1);
+	SYSMAP(caddr_t, pc->pc_cmap2_pte2p, pc->pc_cmap2_addr, 1);
+	SYSMAP(vm_offset_t, unused, pc->pc_qmap_addr, 1);
 
 	/*
 	 * Crashdump maps.
@@ -1215,19 +1197,32 @@ pmap_bootstrap(vm_offset_t firstaddr)
 }
 
 static void
-pmap_init_qpages(void)
+pmap_init_reserved_pages(void)
 {
 	struct pcpu *pc;
+	vm_offset_t pages;
 	int i;
 
 	CPU_FOREACH(i) {
 		pc = pcpu_find(i);
-		pc->pc_qmap_addr = kva_alloc(PAGE_SIZE);
-		if (pc->pc_qmap_addr == 0)
+		/*
+		 * Skip if the mapping has already been initialized,
+		 * i.e. this is the BSP.
+		 */
+		if (pc->pc_cmap1_addr != 0)
+			continue;
+		mtx_init(&pc->pc_cmap_lock, "SYSMAPS", NULL, MTX_DEF);
+		pages = kva_alloc(PAGE_SIZE * 3);
+		if (pages == 0)
 			panic("%s: unable to allocate KVA", __func__);
+		pc->pc_cmap1_pte2p = pt2map_entry(pages);
+		pc->pc_cmap2_pte2p = pt2map_entry(pages + PAGE_SIZE);
+		pc->pc_cmap1_addr = (caddr_t)pages;
+		pc->pc_cmap2_addr = (caddr_t)(pages + PAGE_SIZE);
+		pc->pc_qmap_addr = pages + (PAGE_SIZE * 2);
 	}
 }
-SYSINIT(qpages_init, SI_SUB_CPU, SI_ORDER_ANY, pmap_init_qpages, NULL);
+SYSINIT(rpages_init, SI_SUB_CPU, SI_ORDER_ANY, pmap_init_reserved_pages, NULL);
 
 /*
  *  The function can already be use in second initialization stage.
@@ -1578,8 +1573,9 @@ pagezero(void *page)
 static __inline vm_paddr_t
 pmap_pt2pg_zero(vm_page_t m)
 {
+	pt2_entry_t *cmap2_pte2p;
 	vm_paddr_t pa;
-	struct sysmaps *sysmaps;
+	struct pcpu *pc;
 
 	pa = VM_PAGE_TO_PHYS(m);
 
@@ -1588,20 +1584,27 @@ pmap_pt2pg_zero(vm_page_t m)
 	 *      to sync it even if the sync is only DSB.
 	 */
 	sched_pin();
-	sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
-	mtx_lock(&sysmaps->lock);
-	if (pte2_load(sysmaps->CMAP2) != 0)
+	pc = pcpu_find(curcpu);
+	cmap2_pte2p = pc->pc_cmap2_pte2p;
+	mtx_lock(&pc->pc_cmap_lock);
+	if (pte2_load(cmap2_pte2p) != 0)
 		panic("%s: CMAP2 busy", __func__);
-	pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(pa, PTE2_AP_KRW,
+	pte2_store(cmap2_pte2p, PTE2_KERN_NG(pa, PTE2_AP_KRW,
 	    vm_page_pte2_attr(m)));
 	/*  Even VM_ALLOC_ZERO request is only advisory. */
 	if ((m->flags & PG_ZERO) == 0)
-		pagezero(sysmaps->CADDR2);
-	pte2_sync_range((pt2_entry_t *)sysmaps->CADDR2, PAGE_SIZE);
-	pte2_clear(sysmaps->CMAP2);
-	tlb_flush((vm_offset_t)sysmaps->CADDR2);
+		pagezero(pc->pc_cmap2_addr);
+	pte2_sync_range((pt2_entry_t *)pc->pc_cmap2_addr, PAGE_SIZE);
+	pte2_clear(cmap2_pte2p);
+	tlb_flush((vm_offset_t)pc->pc_cmap2_addr);
+
+	/*
+	 * Unpin the thread before releasing the lock.  Otherwise the thread
+	 * could be rescheduled while still bound to the current CPU, only
+	 * to unpin itself immediately upon resuming execution.
+	 */
 	sched_unpin();
-	mtx_unlock(&sysmaps->lock);
+	mtx_unlock(&pc->pc_cmap_lock);
 
 	return (pa);
 }
@@ -5628,9 +5631,10 @@ small_mappings:
 void
 pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
 {
-	struct sysmaps *sysmaps;
+	pt2_entry_t *cmap2_pte2p;
 	vm_memattr_t oma;
 	vm_paddr_t pa;
+	struct pcpu *pc;
 
 	oma = m->md.pat_mode;
 	m->md.pat_mode = ma;
@@ -5657,17 +5661,18 @@ pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
 	if (ma != oma) {
 		pa = VM_PAGE_TO_PHYS(m);
 		sched_pin();
-		sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
-		mtx_lock(&sysmaps->lock);
-		if (*sysmaps->CMAP2)
+		pc = pcpu_find(curcpu);
+		cmap2_pte2p = pc->pc_cmap2_pte2p;
+		mtx_lock(&pc->pc_cmap_lock);
+		if (pte2_load(cmap2_pte2p) != 0)
 			panic("%s: CMAP2 busy", __func__);
-		pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(pa, PTE2_AP_KRW,
+		pte2_store(cmap2_pte2p, PTE2_KERN_NG(pa, PTE2_AP_KRW,
 		    vm_memattr_to_pte2(ma)));
-		dcache_wbinv_poc((vm_offset_t)sysmaps->CADDR2, pa, PAGE_SIZE);
-		pte2_clear(sysmaps->CMAP2);
-		tlb_flush((vm_offset_t)sysmaps->CADDR2);
+		dcache_wbinv_poc((vm_offset_t)pc->pc_cmap2_addr, pa, PAGE_SIZE);
+		pte2_clear(cmap2_pte2p);
+		tlb_flush((vm_offset_t)pc->pc_cmap2_addr);
 		sched_unpin();
-		mtx_unlock(&sysmaps->lock);
+		mtx_unlock(&pc->pc_cmap_lock);
 	}
 }
 
@@ -5745,20 +5750,22 @@ pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
 void
 pmap_zero_page(vm_page_t m)
 {
-	struct sysmaps *sysmaps;
+	pt2_entry_t *cmap2_pte2p;
+	struct pcpu *pc;
 
 	sched_pin();
-	sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
-	mtx_lock(&sysmaps->lock);
-	if (pte2_load(sysmaps->CMAP2) != 0)
+	pc = pcpu_find(curcpu);
+	cmap2_pte2p = pc->pc_cmap2_pte2p;
+	mtx_lock(&pc->pc_cmap_lock);
+	if (pte2_load(cmap2_pte2p) != 0)
 		panic("%s: CMAP2 busy", __func__);
-	pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(VM_PAGE_TO_PHYS(m), PTE2_AP_KRW,
+	pte2_store(cmap2_pte2p, PTE2_KERN_NG(VM_PAGE_TO_PHYS(m), PTE2_AP_KRW,
 	    vm_page_pte2_attr(m)));
-	pagezero(sysmaps->CADDR2);
-	pte2_clear(sysmaps->CMAP2);
-	tlb_flush((vm_offset_t)sysmaps->CADDR2);
+	pagezero(pc->pc_cmap2_addr);
+	pte2_clear(cmap2_pte2p);
+	tlb_flush((vm_offset_t)pc->pc_cmap2_addr);
 	sched_unpin();
-	mtx_unlock(&sysmaps->lock);
+	mtx_unlock(&pc->pc_cmap_lock);
 }
 
 /*
@@ -5770,23 +5777,25 @@ pmap_zero_page(vm_page_t m)
 void
 pmap_zero_page_area(vm_page_t m, int off, int size)
 {
-	struct sysmaps *sysmaps;
+	pt2_entry_t *cmap2_pte2p;
+	struct pcpu *pc;
 
 	sched_pin();
-	sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
-	mtx_lock(&sysmaps->lock);
-	if (pte2_load(sysmaps->CMAP2) != 0)
+	pc = pcpu_find(curcpu);
+	cmap2_pte2p = pc->pc_cmap2_pte2p;
+	mtx_lock(&pc->pc_cmap_lock);
+	if (pte2_load(cmap2_pte2p) != 0)
 		panic("%s: CMAP2 busy", __func__);
-	pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(VM_PAGE_TO_PHYS(m), PTE2_AP_KRW,
+	pte2_store(cmap2_pte2p, PTE2_KERN_NG(VM_PAGE_TO_PHYS(m), PTE2_AP_KRW,
 	    vm_page_pte2_attr(m)));
 	if (off == 0 && size == PAGE_SIZE)
-		pagezero(sysmaps->CADDR2);
+		pagezero(pc->pc_cmap2_addr);
 	else
-		bzero(sysmaps->CADDR2 + off, size);
-	pte2_clear(sysmaps->CMAP2);
-	tlb_flush((vm_offset_t)sysmaps->CADDR2);
+		bzero(pc->pc_cmap2_addr + off, size);
+	pte2_clear(cmap2_pte2p);
+	tlb_flush((vm_offset_t)pc->pc_cmap2_addr);
 	sched_unpin();
-	mtx_unlock(&sysmaps->lock);
+	mtx_unlock(&pc->pc_cmap_lock);
 }
 
 /*
@@ -5798,26 +5807,29 @@ pmap_zero_page_area(vm_page_t m, int off, int size)
 void
 pmap_copy_page(vm_page_t src, vm_page_t dst)
 {
-	struct sysmaps *sysmaps;
+	pt2_entry_t *cmap1_pte2p, *cmap2_pte2p;
+	struct pcpu *pc;
 
 	sched_pin();
-	sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
-	mtx_lock(&sysmaps->lock);
-	if (pte2_load(sysmaps->CMAP1) != 0)
+	pc = pcpu_find(curcpu);
+	cmap1_pte2p = pc->pc_cmap1_pte2p;
+	cmap2_pte2p = pc->pc_cmap2_pte2p;
+	mtx_lock(&pc->pc_cmap_lock);
+	if (pte2_load(cmap1_pte2p) != 0)
 		panic("%s: CMAP1 busy", __func__);
-	if (pte2_load(sysmaps->CMAP2) != 0)
+	if (pte2_load(cmap2_pte2p) != 0)
 		panic("%s: CMAP2 busy", __func__);
-	pte2_store(sysmaps->CMAP1, PTE2_KERN_NG(VM_PAGE_TO_PHYS(src),
+	pte2_store(cmap1_pte2p, PTE2_KERN_NG(VM_PAGE_TO_PHYS(src),
 	    PTE2_AP_KR | PTE2_NM, vm_page_pte2_attr(src)));
-	pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(VM_PAGE_TO_PHYS(dst),
+	pte2_store(cmap2_pte2p, PTE2_KERN_NG(VM_PAGE_TO_PHYS(dst),
 	    PTE2_AP_KRW, vm_page_pte2_attr(dst)));
-	bcopy(sysmaps->CADDR1, sysmaps->CADDR2, PAGE_SIZE);
-	pte2_clear(sysmaps->CMAP1);
-	tlb_flush((vm_offset_t)sysmaps->CADDR1);
-	pte2_clear(sysmaps->CMAP2);
-	tlb_flush((vm_offset_t)sysmaps->CADDR2);
+	bcopy(pc->pc_cmap1_addr, pc->pc_cmap2_addr, PAGE_SIZE);
+	pte2_clear(cmap1_pte2p);
+	tlb_flush((vm_offset_t)pc->pc_cmap1_addr);
+	pte2_clear(cmap2_pte2p);
+	tlb_flush((vm_offset_t)pc->pc_cmap2_addr);
 	sched_unpin();
-	mtx_unlock(&sysmaps->lock);
+	mtx_unlock(&pc->pc_cmap_lock);
 }
 
 int unmapped_buf_allowed = 1;
@@ -5826,18 +5838,21 @@ void
 pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[],
     vm_offset_t b_offset, int xfersize)
 {
-	struct sysmaps *sysmaps;
+	pt2_entry_t *cmap1_pte2p, *cmap2_pte2p;
 	vm_page_t a_pg, b_pg;
 	char *a_cp, *b_cp;
 	vm_offset_t a_pg_offset, b_pg_offset;
+	struct pcpu *pc;
 	int cnt;
 
 	sched_pin();
-	sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
-	mtx_lock(&sysmaps->lock);
-	if (*sysmaps->CMAP1 != 0)
+	pc = pcpu_find(curcpu);
+	cmap1_pte2p = pc->pc_cmap1_pte2p;
+	cmap2_pte2p = pc->pc_cmap2_pte2p;
+	mtx_lock(&pc->pc_cmap_lock);
+	if (pte2_load(cmap1_pte2p) != 0)
 		panic("pmap_copy_pages: CMAP1 busy");
-	if (*sysmaps->CMAP2 != 0)
+	if (pte2_load(cmap2_pte2p) != 0)
 		panic("pmap_copy_pages: CMAP2 busy");
 	while (xfersize > 0) {
 		a_pg = ma[a_offset >> PAGE_SHIFT];
@@ -5846,25 +5861,25 @@ pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[],
 		b_pg = mb[b_offset >> PAGE_SHIFT];
 		b_pg_offset = b_offset & PAGE_MASK;
 		cnt = min(cnt, PAGE_SIZE - b_pg_offset);
-		pte2_store(sysmaps->CMAP1, PTE2_KERN_NG(VM_PAGE_TO_PHYS(a_pg),
+		pte2_store(cmap1_pte2p, PTE2_KERN_NG(VM_PAGE_TO_PHYS(a_pg),
 		    PTE2_AP_KR | PTE2_NM, vm_page_pte2_attr(a_pg)));
-		tlb_flush_local((vm_offset_t)sysmaps->CADDR1);
-		pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(VM_PAGE_TO_PHYS(b_pg),
+		tlb_flush_local((vm_offset_t)pc->pc_cmap1_addr);
+		pte2_store(cmap2_pte2p, PTE2_KERN_NG(VM_PAGE_TO_PHYS(b_pg),
 		    PTE2_AP_KRW, vm_page_pte2_attr(b_pg)));
-		tlb_flush_local((vm_offset_t)sysmaps->CADDR2);
-		a_cp = sysmaps->CADDR1 + a_pg_offset;
-		b_cp = sysmaps->CADDR2 + b_pg_offset;
+		tlb_flush_local((vm_offset_t)pc->pc_cmap2_addr);
+		a_cp = pc->pc_cmap1_addr + a_pg_offset;
+		b_cp = pc->pc_cmap2_addr + b_pg_offset;
 		bcopy(a_cp, b_cp, cnt);
 		a_offset += cnt;
 		b_offset += cnt;
 		xfersize -= cnt;
 	}
-	pte2_clear(sysmaps->CMAP1);
-	tlb_flush((vm_offset_t)sysmaps->CADDR1);
-	pte2_clear(sysmaps->CMAP2);
-	tlb_flush((vm_offset_t)sysmaps->CADDR2);
+	pte2_clear(cmap1_pte2p);
+	tlb_flush((vm_offset_t)pc->pc_cmap1_addr);
+	pte2_clear(cmap2_pte2p);
+	tlb_flush((vm_offset_t)pc->pc_cmap2_addr);
 	sched_unpin();
-	mtx_unlock(&sysmaps->lock);
+	mtx_unlock(&pc->pc_cmap_lock);
 }
 
 vm_offset_t
@@ -6190,22 +6205,24 @@ pmap_set_pcb_pagedir(pmap_t pmap, struct pcb *pcb)
 static void
 pmap_dcache_wb_pou(vm_paddr_t pa, vm_size_t size, uint32_t attr)
 {
-	struct sysmaps *sysmaps;
+	pt2_entry_t *cmap2_pte2p;
+	struct pcpu *pc;
 
 	KASSERT(((pa & PAGE_MASK) + size) <= PAGE_SIZE,
 	    ("%s: not on single page", __func__));
 
 	sched_pin();
-	sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
-	mtx_lock(&sysmaps->lock);
-	if (*sysmaps->CMAP3)
-		panic("%s: CMAP3 busy", __func__);
-	pte2_store(sysmaps->CMAP3, PTE2_KERN_NG(pa, PTE2_AP_KRW, attr));
-	dcache_wb_pou((vm_offset_t)sysmaps->CADDR3 + (pa & PAGE_MASK), size);
-	pte2_clear(sysmaps->CMAP3);
-	tlb_flush((vm_offset_t)sysmaps->CADDR3);
+	pc = pcpu_find(curcpu);
+	cmap2_pte2p = pc->pc_cmap2_pte2p;
+	mtx_lock(&pc->pc_cmap_lock);
+	if (pte2_load(cmap2_pte2p) != 0)
+		panic("%s: CMAP2 busy", __func__);
+	pte2_store(cmap2_pte2p, PTE2_KERN_NG(pa, PTE2_AP_KRW, attr));
+	dcache_wb_pou((vm_offset_t)pc->pc_cmap2_addr + (pa & PAGE_MASK), size);
+	pte2_clear(cmap2_pte2p);
+	tlb_flush((vm_offset_t)pc->pc_cmap2_addr);
 	sched_unpin();
-	mtx_unlock(&sysmaps->lock);
+	mtx_unlock(&pc->pc_cmap_lock);
 }
 
 /*
@@ -6455,25 +6472,27 @@ pmap_fault(pmap_t pmap, vm_offset_t far, uint32_t fsr, int idx, bool usermode)
 static void
 pmap_zero_page_check(vm_page_t m)
 {
+	pt2_entry_t *cmap2_pte2p;
 	uint32_t *p, *end;
-	struct sysmaps *sysmaps;
+	struct pcpu *pc;
 
 	sched_pin();
-	sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
-	mtx_lock(&sysmaps->lock);
-	if (pte2_load(sysmaps->CMAP2) != 0)
+	pc = pcpu_find(curcpu);
+	cmap2_pte2p = pc->pc_cmap2_pte2p;
+	mtx_lock(&pc->pc_cmap_lock);
+	if (pte2_load(cmap2_pte2p) != 0)
 		panic("%s: CMAP2 busy", __func__);
-	pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(VM_PAGE_TO_PHYS(m), PTE2_AP_KRW,
+	pte2_store(cmap2_pte2p, PTE2_KERN_NG(VM_PAGE_TO_PHYS(m), PTE2_AP_KRW,
 	    vm_page_pte2_attr(m)));
-	end = (uint32_t*)(sysmaps->CADDR2 + PAGE_SIZE);
-	for (p = (uint32_t*)sysmaps->CADDR2; p < end; p++)
+	end = (uint32_t*)(pc->pc_cmap2_addr + PAGE_SIZE);
+	for (p = (uint32_t*)pc->pc_cmap2_addr; p < end; p++)
 		if (*p != 0)
 			panic("%s: page %p not zero, va: %p", __func__, m,
-			    sysmaps->CADDR2);
-	pte2_clear(sysmaps->CMAP2);
-	tlb_flush((vm_offset_t)sysmaps->CADDR2);
+			    pc->pc_cmap2_addr);
+	pte2_clear(cmap2_pte2p);
+	tlb_flush((vm_offset_t)pc->pc_cmap2_addr);
 	sched_unpin();
-	mtx_unlock(&sysmaps->lock);
+	mtx_unlock(&pc->pc_cmap_lock);
 }
 
 int
diff --git a/sys/arm/cloudabi32/cloudabi32_sysvec.c b/sys/arm/cloudabi32/cloudabi32_sysvec.c
index 040dcc323c9..731de0b0d88 100644
--- a/sys/arm/cloudabi32/cloudabi32_sysvec.c
+++ b/sys/arm/cloudabi32/cloudabi32_sysvec.c
@@ -148,7 +148,7 @@ cloudabi32_thread_setregs(struct thread *td,
 
 	/* Perform standard register initialization. */
 	stack.ss_sp = TO_PTR(attr->stack);
-	stack.ss_size = attr->stack_size;
+	stack.ss_size = attr->stack_len;
 	cpu_set_upcall(td, TO_PTR(attr->entry_point), NULL, &stack);
 
 	/*
diff --git a/sys/arm/include/pcpu.h b/sys/arm/include/pcpu.h
index 3cc258188ff..d02ccc8f546 100644
--- a/sys/arm/include/pcpu.h
+++ b/sys/arm/include/pcpu.h
@@ -32,6 +32,9 @@
 
 #ifdef _KERNEL
 
+#include 
+#include 
+
 #define	ALT_STACK_SIZE	128
 
 struct vmspace;
@@ -39,16 +42,22 @@ struct vmspace;
 #endif	/* _KERNEL */
 
 #if __ARM_ARCH >= 6
+
 #define PCPU_MD_FIELDS							\
 	unsigned int pc_vfpsid;						\
 	unsigned int pc_vfpmvfr0;					\
 	unsigned int pc_vfpmvfr1;					\
 	struct pmap *pc_curpmap;					\
+	struct mtx pc_cmap_lock;					\
+	void *pc_cmap1_pte2p;						\
+	void *pc_cmap2_pte2p;						\
+	caddr_t pc_cmap1_addr;						\
+	caddr_t pc_cmap2_addr;						\
 	vm_offset_t pc_qmap_addr;					\
 	void *pc_qmap_pte;						\
 	unsigned int pc_dbreg[32];					\
 	int pc_dbreg_cmd;						\
-	char __pad[1]
+	char __pad[27]
 #else
 #define PCPU_MD_FIELDS							\
 	vm_offset_t qmap_addr;						\
diff --git a/sys/arm/ti/cpsw/if_cpsw.c b/sys/arm/ti/cpsw/if_cpsw.c
index 355a423eb6a..30dc008b20c 100644
--- a/sys/arm/ti/cpsw/if_cpsw.c
+++ b/sys/arm/ti/cpsw/if_cpsw.c
@@ -783,8 +783,7 @@ cpsw_get_fdt_data(struct cpsw_softc *sc, int port)
 static int
 cpsw_attach(device_t dev)
 {
-	bus_dma_segment_t segs[1];
-	int error, i, nsegs;
+	int error, i;
 	struct cpsw_softc *sc;
 	uint32_t reg;
 
@@ -859,15 +858,8 @@ cpsw_attach(device_t dev)
 		return (error);
 	}
 
-	/* Allocate the null mbuf and pre-sync it. */
-	sc->null_mbuf = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
-	memset(sc->null_mbuf->m_data, 0, sc->null_mbuf->m_ext.ext_size);
-	bus_dmamap_create(sc->mbuf_dtag, 0, &sc->null_mbuf_dmamap);
-	bus_dmamap_load_mbuf_sg(sc->mbuf_dtag, sc->null_mbuf_dmamap,
-	    sc->null_mbuf, segs, &nsegs, BUS_DMA_NOWAIT);
-	bus_dmamap_sync(sc->mbuf_dtag, sc->null_mbuf_dmamap,
-	    BUS_DMASYNC_PREWRITE);
-	sc->null_mbuf_paddr = segs[0].ds_addr;
+	/* Allocate a NULL buffer for padding. */
+	sc->nullpad = malloc(ETHER_MIN_LEN, M_DEVBUF, M_WAITOK | M_ZERO);
 
 	cpsw_init_slots(sc);
 
@@ -946,13 +938,9 @@ cpsw_detach(device_t dev)
 	for (i = 0; i < nitems(sc->_slots); ++i)
 		cpsw_free_slot(sc, &sc->_slots[i]);
 
-	/* Free null mbuf. */
-	if (sc->null_mbuf_dmamap) {
-		bus_dmamap_unload(sc->mbuf_dtag, sc->null_mbuf_dmamap);
-		error = bus_dmamap_destroy(sc->mbuf_dtag, sc->null_mbuf_dmamap);
-		KASSERT(error == 0, ("Mapping still active"));
-		m_freem(sc->null_mbuf);
-	}
+	/* Free null padding buffer. */
+	if (sc->nullpad)
+		free(sc->nullpad, M_DEVBUF);
 
 	/* Free DMA tag */
 	if (sc->mbuf_dtag) {
@@ -1395,6 +1383,16 @@ cpswp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 	ifr = (struct ifreq *)data;
 
 	switch (command) {
+	case SIOCSIFCAP:
+		changed = ifp->if_capenable ^ ifr->ifr_reqcap;
+		if (changed & IFCAP_HWCSUM) {
+			if ((ifr->ifr_reqcap & changed) & IFCAP_HWCSUM)
+				ifp->if_capenable |= IFCAP_HWCSUM;
+			else
+				ifp->if_capenable &= ~IFCAP_HWCSUM;
+		}
+		error = 0;
+		break;
 	case SIOCSIFFLAGS:
 		CPSW_PORT_LOCK(sc);
 		if (ifp->if_flags & IFF_UP) {
@@ -1632,21 +1630,36 @@ cpsw_rx_dequeue(struct cpsw_softc *sc)
 		/* TODO: track SOP/EOP bits to assemble a full mbuf
 		   out of received fragments. */
 		slot->mbuf->m_data += bd.bufoff;
-		slot->mbuf->m_len = bd.pktlen - 4;
-		slot->mbuf->m_pkthdr.len = bd.pktlen - 4;
-		slot->mbuf->m_flags |= M_PKTHDR;
-		slot->mbuf->m_pkthdr.rcvif = psc->ifp;
+		slot->mbuf->m_len = bd.buflen;
+		if (bd.flags & CPDMA_BD_SOP) {
+			slot->mbuf->m_pkthdr.len = bd.pktlen;
+			slot->mbuf->m_pkthdr.rcvif = psc->ifp;
+			slot->mbuf->m_flags |= M_PKTHDR;
+		}
+		slot->mbuf->m_next = NULL;
 		slot->mbuf->m_nextpkt = NULL;
+		if (bd.flags & CPDMA_BD_PASS_CRC)
+			m_adj(slot->mbuf, -ETHER_CRC_LEN);
 
 		if ((psc->ifp->if_capenable & IFCAP_RXCSUM) != 0) {
 			/* check for valid CRC by looking into pkt_err[5:4] */
-			if ((bd.flags & CPDMA_BD_PKT_ERR_MASK) == 0) {
+			if ((bd.flags &
+			    (CPDMA_BD_SOP | CPDMA_BD_PKT_ERR_MASK)) ==
+			    CPDMA_BD_SOP) {
 				slot->mbuf->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
 				slot->mbuf->m_pkthdr.csum_flags |= CSUM_IP_VALID;
 				slot->mbuf->m_pkthdr.csum_data = 0xffff;
 			}
 		}
 
+		if (STAILQ_FIRST(&sc->rx.active) != NULL &&
+		    (bd.flags & (CPDMA_BD_EOP | CPDMA_BD_EOQ)) ==
+		    (CPDMA_BD_EOP | CPDMA_BD_EOQ)) {
+			cpsw_write_hdp_slot(sc, &sc->rx,
+			    STAILQ_FIRST(&sc->rx.active));
+			sc->rx.queue_restart++;
+		}
+
 		/* Add mbuf to packet list to be returned. */
 		if (mb_tail) {
 			mb_tail->m_nextpkt = slot->mbuf;
@@ -1679,7 +1692,6 @@ cpsw_rx_enqueue(struct cpsw_softc *sc)
 	struct cpsw_cpdma_bd bd;
 	struct cpsw_slot *first_new_slot, *last_old_slot, *next, *slot;
 	int error, nsegs, added = 0;
-	uint32_t flags;
 
 	/* Register new mbufs with hardware. */
 	first_new_slot = NULL;
@@ -1745,22 +1757,13 @@ cpsw_rx_enqueue(struct cpsw_softc *sc)
 	} else {
 		/* Add buffers to end of current queue. */
 		cpsw_cpdma_write_bd_next(sc, last_old_slot, first_new_slot);
-		/* If underrun, restart queue. */
-		if ((flags = cpsw_cpdma_read_bd_flags(sc, last_old_slot)) &
-		    CPDMA_BD_EOQ) {
-			flags &= ~CPDMA_BD_EOQ;
-			cpsw_cpdma_write_bd_flags(sc, last_old_slot, flags);
-			cpsw_write_hdp_slot(sc, &sc->rx, first_new_slot);
-			sc->rx.queue_restart++;
-		}
 	}
 	sc->rx.queue_adds += added;
 	sc->rx.avail_queue_len -= added;
 	sc->rx.active_queue_len += added;
 	cpsw_write_4(sc, CPSW_CPDMA_RX_FREEBUFFER(0), added);
-	if (sc->rx.active_queue_len > sc->rx.max_active_queue_len) {
+	if (sc->rx.active_queue_len > sc->rx.max_active_queue_len)
 		sc->rx.max_active_queue_len = sc->rx.active_queue_len;
-	}
 }
 
 static void
@@ -1800,13 +1803,8 @@ cpswp_tx_enqueue(struct cpswp_softc *sc)
 	struct cpsw_cpdma_bd bd;
 	struct cpsw_slot *first_new_slot, *last, *last_old_slot, *next, *slot;
 	struct mbuf *m0;
-	int error, flags, nsegs, seg, added = 0, padlen;
+	int error, nsegs, seg, added = 0, padlen;
 
-	flags = 0;
-	if (sc->swsc->dualemac) {
-		flags = CPDMA_BD_TO_PORT |
-		    ((sc->unit + 1) & CPDMA_BD_PORT_MASK);
-	}
 	/* Pull pending packets from IF queue and prep them for DMA. */
 	last = NULL;
 	first_new_slot = NULL;
@@ -1817,21 +1815,19 @@ cpswp_tx_enqueue(struct cpswp_softc *sc)
 			break;
 
 		slot->mbuf = m0;
-		padlen = ETHER_MIN_LEN - slot->mbuf->m_pkthdr.len;
+		padlen = ETHER_MIN_LEN - ETHER_CRC_LEN - m0->m_pkthdr.len;
 		if (padlen < 0)
 			padlen = 0;
+		else if (padlen > 0)
+			m_append(slot->mbuf, padlen, sc->swsc->nullpad);
 
 		/* Create mapping in DMA memory */
 		error = bus_dmamap_load_mbuf_sg(sc->swsc->mbuf_dtag,
 		    slot->dmamap, slot->mbuf, segs, &nsegs, BUS_DMA_NOWAIT);
 		/* If the packet is too fragmented, try to simplify. */
 		if (error == EFBIG ||
-		    (error == 0 &&
-		    nsegs + (padlen > 0 ? 1 : 0) > sc->swsc->tx.avail_queue_len)) {
+		    (error == 0 && nsegs > sc->swsc->tx.avail_queue_len)) {
 			bus_dmamap_unload(sc->swsc->mbuf_dtag, slot->dmamap);
-			if (padlen > 0) /* May as well add padding. */
-				m_append(slot->mbuf, padlen,
-				    sc->swsc->null_mbuf->m_data);
 			m0 = m_defrag(slot->mbuf, M_NOWAIT);
 			if (m0 == NULL) {
 				device_printf(sc->dev,
@@ -1883,8 +1879,12 @@ cpswp_tx_enqueue(struct cpswp_softc *sc)
 		bd.bufptr = segs[0].ds_addr;
 		bd.bufoff = 0;
 		bd.buflen = segs[0].ds_len;
-		bd.pktlen = m_length(slot->mbuf, NULL) + padlen;
-		bd.flags =  CPDMA_BD_SOP | CPDMA_BD_OWNER | flags;
+		bd.pktlen = m_length(slot->mbuf, NULL);
+		bd.flags =  CPDMA_BD_SOP | CPDMA_BD_OWNER;
+		if (sc->swsc->dualemac) {
+			bd.flags |= CPDMA_BD_TO_PORT;
+			bd.flags |= ((sc->unit + 1) & CPDMA_BD_PORT_MASK);
+		}
 		for (seg = 1; seg < nsegs; ++seg) {
 			/* Save the previous buffer (which isn't EOP) */
 			cpsw_cpdma_write_bd(sc->swsc, slot, &bd);
@@ -1902,44 +1902,20 @@ cpswp_tx_enqueue(struct cpswp_softc *sc)
 			bd.bufoff = 0;
 			bd.buflen = segs[seg].ds_len;
 			bd.pktlen = 0;
-			bd.flags = CPDMA_BD_OWNER | flags;
+			bd.flags = CPDMA_BD_OWNER;
 		}
+
 		/* Save the final buffer. */
-		if (padlen <= 0)
-			bd.flags |= CPDMA_BD_EOP;
-		else {
-			next = STAILQ_NEXT(slot, next);
-			bd.next = cpsw_cpdma_bd_paddr(sc->swsc, next);
-		}
+		bd.flags |= CPDMA_BD_EOP;
 		cpsw_cpdma_write_bd(sc->swsc, slot, &bd);
 		STAILQ_REMOVE_HEAD(&sc->swsc->tx.avail, next);
 		STAILQ_INSERT_TAIL(&sc->swsc->tx.active, slot, next);
 
-		if (padlen > 0) {
-			slot = STAILQ_FIRST(&sc->swsc->tx.avail);
-
-			/* Setup buffer of null pad bytes (definitely EOP). */
-			bd.next = 0;
-			bd.bufptr = sc->swsc->null_mbuf_paddr;
-			bd.bufoff = 0;
-			bd.buflen = padlen;
-			bd.pktlen = 0;
-			bd.flags = CPDMA_BD_EOP | CPDMA_BD_OWNER | flags;
-			cpsw_cpdma_write_bd(sc->swsc, slot, &bd);
-			++nsegs;
-
-			STAILQ_REMOVE_HEAD(&sc->swsc->tx.avail, next);
-			STAILQ_INSERT_TAIL(&sc->swsc->tx.active, slot, next);
-		}
-
 		last = slot;
-
 		added += nsegs;
 		if (nsegs > sc->swsc->tx.longest_chain)
 			sc->swsc->tx.longest_chain = nsegs;
 
-		// TODO: Should we defer the BPF tap until
-		// after all packets are queued?
 		BPF_MTAP(sc->ifp, m0);
 	}
 
diff --git a/sys/arm/ti/cpsw/if_cpswreg.h b/sys/arm/ti/cpsw/if_cpswreg.h
index 6d6a647565c..c0ee3586fc4 100644
--- a/sys/arm/ti/cpsw/if_cpswreg.h
+++ b/sys/arm/ti/cpsw/if_cpswreg.h
@@ -191,6 +191,7 @@
 #define	 CPDMA_BD_OWNER			(1 << 13)
 #define	 CPDMA_BD_EOQ			(1 << 12)
 #define	 CPDMA_BD_TDOWNCMPLT		(1 << 11)
+#define	 CPDMA_BD_PASS_CRC		(1 << 10)
 #define	 CPDMA_BD_PKT_ERR_MASK		(3 << 4)
 #define	 CPDMA_BD_TO_PORT		(1 << 4)
 #define	 CPDMA_BD_PORT_MASK		3
diff --git a/sys/arm/ti/cpsw/if_cpswvar.h b/sys/arm/ti/cpsw/if_cpswvar.h
index f037dd515f0..904c68db7ed 100644
--- a/sys/arm/ti/cpsw/if_cpswvar.h
+++ b/sys/arm/ti/cpsw/if_cpswvar.h
@@ -104,10 +104,8 @@ struct cpsw_softc {
 	struct resource	*irq_res[CPSW_INTR_COUNT];
 	void		*ih_cookie[CPSW_INTR_COUNT];
 
-	/* An mbuf full of nulls for TX padding. */
-	bus_dmamap_t null_mbuf_dmamap;
-	struct mbuf *null_mbuf;
-	bus_addr_t null_mbuf_paddr;
+	/* A buffer full of nulls for TX padding. */
+	void		*nullpad;
 
 	bus_dma_tag_t	mbuf_dtag;
 
diff --git a/sys/arm/xilinx/zy7_ehci.c b/sys/arm/xilinx/zy7_ehci.c
index f6e34f77449..0b7a3ffd22e 100644
--- a/sys/arm/xilinx/zy7_ehci.c
+++ b/sys/arm/xilinx/zy7_ehci.c
@@ -325,13 +325,10 @@ zy7_ehci_detach(device_t dev)
 	/* during module unload there are lots of children leftover */
 	device_delete_children(dev);
 	
-	sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
-
-	if (sc->sc_irq_res && sc->sc_intr_hdl)
-		/* call ehci_detach() after ehci_init() called after
-		 * successful bus_setup_intr().
-		 */
+	if ((sc->sc_flags & EHCI_SCFLG_DONEINIT) != 0) {
 		ehci_detach(sc);
+		sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
+	}
 
 	if (sc->sc_irq_res) {
 		if (sc->sc_intr_hdl != NULL)
diff --git a/sys/arm64/cloudabi64/cloudabi64_sysvec.c b/sys/arm64/cloudabi64/cloudabi64_sysvec.c
index 79b1046ddc9..9cdabe85ce1 100644
--- a/sys/arm64/cloudabi64/cloudabi64_sysvec.c
+++ b/sys/arm64/cloudabi64/cloudabi64_sysvec.c
@@ -140,7 +140,7 @@ cloudabi64_thread_setregs(struct thread *td,
 
 	/* Perform standard register initialization. */
 	stack.ss_sp = TO_PTR(attr->stack);
-	stack.ss_size = attr->stack_size;
+	stack.ss_size = attr->stack_len;
 	cpu_set_upcall(td, TO_PTR(attr->entry_point), NULL, &stack);
 
 	/*
diff --git a/sys/boot/efi/include/efidevp.h b/sys/boot/efi/include/efidevp.h
index dda79de7af1..4f252472a80 100644
--- a/sys/boot/efi/include/efidevp.h
+++ b/sys/boot/efi/include/efidevp.h
@@ -73,8 +73,6 @@ typedef struct _EFI_DEVICE_PATH {
             (a)->Length[1] = 0;                         \
             }
 
-
-
 /*
  *
  */
@@ -424,5 +422,33 @@ typedef union {
 
 } EFI_DEV_PATH_PTR;
 
+#define	EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID			\
+    { 0xbc62157e, 0x3e33, 0x4fec, { 0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf } }
+
+#define	EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID				\
+    { 0x8b843e20, 0x8132, 0x4852, { 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } }
+
+INTERFACE_DECL(_EFI_DEVICE_PATH_PROTOCOL);
+
+typedef
+CHAR16*
+(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_NODE) (
+    IN struct _EFI_DEVICE_PATH *This,
+    IN BOOLEAN                 DisplayOnly,
+    IN BOOLEAN                 AllowShortCuts
+    );
+
+typedef
+CHAR16*
+(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_PATH) (
+    IN struct _EFI_DEVICE_PATH *This,
+    IN BOOLEAN                 DisplayOnly,
+    IN BOOLEAN                 AllowShortCuts
+    );
+
+typedef struct _EFI_DEVICE_PATH_TO_TEXT_PROTOCOL {
+	EFI_DEVICE_PATH_TO_TEXT_NODE ConvertDeviceNodeToText;
+	EFI_DEVICE_PATH_TO_TEXT_PATH ConvertDevicePathToText;
+} EFI_DEVICE_PATH_TO_TEXT_PROTOCOL;
 
 #endif
diff --git a/sys/boot/efi/libefi/devpath.c b/sys/boot/efi/libefi/devpath.c
index 105c86134a8..cc1045eaf51 100644
--- a/sys/boot/efi/libefi/devpath.c
+++ b/sys/boot/efi/libefi/devpath.c
@@ -30,36 +30,6 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
-/* XXX: This belongs in an efifoo.h header. */
-#define	EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID			\
-    { 0xbc62157e, 0x3e33, 0x4fec, { 0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf } }
-
-#define	EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID				\
-    { 0x8b843e20, 0x8132, 0x4852, { 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } }
-
-INTERFACE_DECL(_EFI_DEVICE_PATH_PROTOCOL);
-
-typedef
-CHAR16*
-(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_NODE) (
-    IN struct _EFI_DEVICE_PATH *This,
-    IN BOOLEAN                 DisplayOnly,
-    IN BOOLEAN                 AllowShortCuts
-    );
-
-typedef
-CHAR16*
-(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_PATH) (
-    IN struct _EFI_DEVICE_PATH *This,
-    IN BOOLEAN                 DisplayOnly,
-    IN BOOLEAN                 AllowShortCuts
-    );
-
-typedef struct _EFI_DEVICE_PATH_TO_TEXT_PROTOCOL {
-	EFI_DEVICE_PATH_TO_TEXT_NODE ConvertDeviceNodeToText;
-	EFI_DEVICE_PATH_TO_TEXT_PATH ConvertDevicePathToText;
-} EFI_DEVICE_PATH_TO_TEXT_PROTOCOL;
-
 static EFI_GUID ImageDevicePathGUID =
     EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID;
 static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
@@ -136,15 +106,18 @@ efi_devpath_trim(EFI_DEVICE_PATH *devpath)
 	EFI_DEVICE_PATH *node, *copy;
 	size_t prefix, len;
 
-	node = efi_devpath_last_node(devpath);
+	if ((node = efi_devpath_last_node(devpath)) == NULL)
+		return (NULL);
 	prefix = (UINT8 *)node - (UINT8 *)devpath;
 	if (prefix == 0)
 		return (NULL);
 	len = prefix + DevicePathNodeLength(NextDevicePathNode(node));
 	copy = malloc(len);
-	memcpy(copy, devpath, prefix);
-	node = (EFI_DEVICE_PATH *)((UINT8 *)copy + prefix);
-	SetDevicePathEndNode(node);
+	if (copy != NULL) {
+		memcpy(copy, devpath, prefix);
+		node = (EFI_DEVICE_PATH *)((UINT8 *)copy + prefix);
+		SetDevicePathEndNode(node);
+	}
 	return (copy);
 }
 
diff --git a/sys/boot/efi/libefi/efinet.c b/sys/boot/efi/libefi/efinet.c
index 1207088d868..26802c2287d 100644
--- a/sys/boot/efi/libefi/efinet.c
+++ b/sys/boot/efi/libefi/efinet.c
@@ -291,12 +291,18 @@ efinet_dev_init()
 	if (EFI_ERROR(status))
 		return (efi_status_to_errno(status));
 	handles2 = (EFI_HANDLE *)malloc(sz);
+	if (handles2 == NULL) {
+		free(handles);
+		return (ENOMEM);
+	}
 	nifs = 0;
 	for (i = 0; i < sz / sizeof(EFI_HANDLE); i++) {
 		devpath = efi_lookup_devpath(handles[i]);
 		if (devpath == NULL)
 			continue;
-		node = efi_devpath_last_node(devpath);
+		if ((node = efi_devpath_last_node(devpath)) == NULL)
+			continue;
+
 		if (DevicePathType(node) != MESSAGING_DEVICE_PATH ||
 		    DevicePathSubType(node) != MSG_MAC_ADDR_DP)
 			continue;
@@ -318,20 +324,24 @@ efinet_dev_init()
 	}
 	free(handles);
 	if (nifs == 0) {
-		free(handles2);
-		return (ENOENT);
+		err = ENOENT;
+		goto done;
 	}
 
 	err = efi_register_handles(&efinet_dev, handles2, NULL, nifs);
-	if (err != 0) {
-		free(handles2);
-		return (err);
-	}
+	if (err != 0)
+		goto done;
 
-	efinetif.netif_nifs = nifs;
 	efinetif.netif_ifs = calloc(nifs, sizeof(struct netif_dif));
-
 	stats = calloc(nifs, sizeof(struct netif_stats));
+	if (efinetif.netif_ifs == NULL || stats == NULL) {
+		free(efinetif.netif_ifs);
+		free(stats);
+		efinetif.netif_ifs = NULL;
+		err = ENOMEM;
+		goto done;
+	}
+	efinetif.netif_nifs = nifs;
 
 	for (i = 0; i < nifs; i++) {
 
@@ -341,9 +351,9 @@ efinet_dev_init()
 		dif->dif_stats = &stats[i];
 		dif->dif_private = handles2[i];
 	}
+done:
 	free(handles2);
-
-	return (0);
+	return (err);
 }
 
 static int
diff --git a/sys/boot/efi/libefi/efipart.c b/sys/boot/efi/libefi/efipart.c
index 938eed996c8..eb052c9dd34 100644
--- a/sys/boot/efi/libefi/efipart.c
+++ b/sys/boot/efi/libefi/efipart.c
@@ -130,10 +130,13 @@ efipart_init(void)
 		 * we try to find the parent device and add that instead as
 		 * that will be the CD filesystem.
 		 */
-		node = efi_devpath_last_node(devpath);
+		if ((node = efi_devpath_last_node(devpath)) == NULL)
+			continue;
 		if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
 		    DevicePathSubType(node) == MEDIA_CDROM_DP) {
 			devpathcpy = efi_devpath_trim(devpath);
+			if (devpathcpy == NULL)
+				continue;
 			tmpdevpath = devpathcpy;
 			status = BS->LocateDevicePath(&blkio_guid, &tmpdevpath,
 			    &handle);
diff --git a/sys/boot/fdt/dts/arm/ufw.dts b/sys/boot/fdt/dts/arm/ufw.dts
index a2de3abbb92..8b731a1a9d2 100644
--- a/sys/boot/fdt/dts/arm/ufw.dts
+++ b/sys/boot/fdt/dts/arm/ufw.dts
@@ -278,6 +278,7 @@
 	pinctrl-0 = <&mmc1_pins>;
 	bus-width = <4>;
 	non-removable;
+	wp-disable;
 	status = "okay";
 };
 
diff --git a/sys/boot/fdt/dts/mips/beri-netfpga.dts b/sys/boot/fdt/dts/mips/beri-netfpga.dts
index f272f9cfa5d..e93e68e5161 100644
--- a/sys/boot/fdt/dts/mips/beri-netfpga.dts
+++ b/sys/boot/fdt/dts/mips/beri-netfpga.dts
@@ -97,7 +97,6 @@
 		 * we use mips4k coprocessor 0 interrupt management directly.
 		 */
 		compatible = "simple-bus", "mips,mips4k";
-		ranges = <>;
 
 		beripic: beripic@7f804000 {
 			compatible = "sri-cambridge,beri-pic";
diff --git a/sys/boot/fdt/dts/mips/beri-sim.dts b/sys/boot/fdt/dts/mips/beri-sim.dts
index 5e0ab1976b2..602c5677379 100644
--- a/sys/boot/fdt/dts/mips/beri-sim.dts
+++ b/sys/boot/fdt/dts/mips/beri-sim.dts
@@ -95,7 +95,6 @@
 		 * we use mips4k coprocessor 0 interrupt management directly.
 		 */
 		compatible = "simple-bus", "mips,mips4k";
-		ranges = <>;
 
 		beripic0: beripic@7f804000 {
 			compatible = "sri-cambridge,beri-pic";
diff --git a/sys/boot/fdt/dts/mips/beripad-de4.dts b/sys/boot/fdt/dts/mips/beripad-de4.dts
index 287c2306d14..88023132b5b 100644
--- a/sys/boot/fdt/dts/mips/beripad-de4.dts
+++ b/sys/boot/fdt/dts/mips/beripad-de4.dts
@@ -95,7 +95,6 @@
 		 * we use mips4k coprocessor 0 interrupt management directly.
 		 */
 		compatible = "simple-bus", "mips,mips4k";
-		ranges = <>;
 
 		beripic0: beripic@7f804000 {
 			compatible = "sri-cambridge,beri-pic";
diff --git a/sys/boot/fdt/dts/mips/beripad-sockit.dts b/sys/boot/fdt/dts/mips/beripad-sockit.dts
index ad9e4acfbea..72b86437d20 100644
--- a/sys/boot/fdt/dts/mips/beripad-sockit.dts
+++ b/sys/boot/fdt/dts/mips/beripad-sockit.dts
@@ -93,7 +93,6 @@
 		 * we use mips4k coprocessor 0 interrupt management directly.
 		 */
 		compatible = "simple-bus", "mips,mips4k";
-		/* ranges = <>; */
 
 		beripic0: beripic@7f804000 {
 			compatible = "sri-cambridge,beri-pic";
diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index 45a27e281cf..867cf96bb43 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -511,6 +511,14 @@ static struct ada_quirk_entry ada_quirk_table[] =
 		{ T_DIRECT, SIP_MEDIA_FIXED, "*", "INTEL SSDSC2BW*", "*" },
 		/*quirks*/ADA_Q_4K
 	},
+	{
+		/*
+		 * Intel S3610 Series SSDs
+		 * 4k optimised & trim only works in 4k requests + 4k aligned
+		 */
+		{ T_DIRECT, SIP_MEDIA_FIXED, "*", "INTEL SSDSC2BX*", "*" },
+		/*quirks*/ADA_Q_4K
+	},
 	{
 		/*
 		 * Intel X25-M Series SSDs
@@ -567,6 +575,14 @@ static struct ada_quirk_entry ada_quirk_table[] =
 		{ T_DIRECT, SIP_MEDIA_FIXED, "*", "Micron M5[15]0*", "MU01" },
 		/*quirks*/ADA_Q_NCQ_TRIM_BROKEN
 	},
+	{
+		/*
+		 * Micron 5100 SSDs
+		 * 4k optimised & trim only works in 4k requests + 4k aligned
+		 */
+		{ T_DIRECT, SIP_MEDIA_FIXED, "*", "Micron 5100 MTFDDAK*", "*" },
+		/*quirks*/ADA_Q_4K
+	},
 	{
 		/*
 		 * OCZ Agility 2 SSDs
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index 8c6e39adc05..74a780eb557 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -424,7 +424,7 @@ static void ctl_isc_event_handler(ctl_ha_channel chanel, ctl_ha_event event,
 static void ctl_copy_sense_data(union ctl_ha_msg *src, union ctl_io *dest);
 static void ctl_copy_sense_data_back(union ctl_io *src, union ctl_ha_msg *dest);
 static int ctl_init(void);
-void ctl_shutdown(void);
+static int ctl_shutdown(void);
 static int ctl_open(struct cdev *dev, int flags, int fmt, struct thread *td);
 static int ctl_close(struct cdev *dev, int flags, int fmt, struct thread *td);
 static void ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio);
@@ -520,6 +520,8 @@ static const struct ctl_cmd_entry *
     ctl_validate_command(struct ctl_scsiio *ctsio);
 static int ctl_cmd_applicable(uint8_t lun_type,
     const struct ctl_cmd_entry *entry);
+static int ctl_ha_init(void);
+static int ctl_ha_shutdown(void);
 
 static uint64_t ctl_get_prkey(struct ctl_lun *lun, uint32_t residx);
 static void ctl_clr_prkey(struct ctl_lun *lun, uint32_t residx);
@@ -561,6 +563,49 @@ MODULE_VERSION(ctl, 1);
 static struct ctl_frontend ha_frontend =
 {
 	.name = "ha",
+	.init = ctl_ha_init,
+	.shutdown = ctl_ha_shutdown,
+};
+
+static int
+ctl_ha_init(void)
+{
+	struct ctl_softc *softc = control_softc;
+
+	if (ctl_pool_create(softc, "othersc", CTL_POOL_ENTRIES_OTHER_SC,
+	                    &softc->othersc_pool) != 0)
+		return (ENOMEM);
+	if (ctl_ha_msg_init(softc) != CTL_HA_STATUS_SUCCESS) {
+		ctl_pool_free(softc->othersc_pool);
+		return (EIO);
+	}
+	if (ctl_ha_msg_register(CTL_HA_CHAN_CTL, ctl_isc_event_handler)
+	    != CTL_HA_STATUS_SUCCESS) {
+		ctl_ha_msg_destroy(softc);
+		ctl_pool_free(softc->othersc_pool);
+		return (EIO);
+	}
+	return (0);
+};
+
+static int
+ctl_ha_shutdown(void)
+{
+	struct ctl_softc *softc = control_softc;
+	struct ctl_port *port;
+
+	ctl_ha_msg_shutdown(softc);
+	if (ctl_ha_msg_deregister(CTL_HA_CHAN_CTL) != CTL_HA_STATUS_SUCCESS)
+		return (EIO);
+	if (ctl_ha_msg_destroy(softc) != CTL_HA_STATUS_SUCCESS)
+		return (EIO);
+	ctl_pool_free(softc->othersc_pool);
+	while ((port = STAILQ_FIRST(&ha_frontend.port_list)) != NULL) {
+		ctl_port_deregister(port);
+		free(port->port_name, M_CTL);
+		free(port, M_CTL);
+	}
+	return (0);
 };
 
 static void
@@ -696,8 +741,6 @@ ctl_ha_done(union ctl_io *io)
 		msg.scsi.tag_num = io->scsiio.tag_num;
 		msg.scsi.tag_type = io->scsiio.tag_type;
 		msg.scsi.sense_len = io->scsiio.sense_len;
-		msg.scsi.sense_residual = io->scsiio.sense_residual;
-		msg.scsi.residual = io->scsiio.residual;
 		memcpy(&msg.scsi.sense_data, &io->scsiio.sense_data,
 		    io->scsiio.sense_len);
 		ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg,
@@ -725,8 +768,6 @@ ctl_isc_handler_finish_xfer(struct ctl_softc *ctl_softc,
 	ctsio->io_hdr.status = msg_info->hdr.status;
 	ctsio->scsi_status = msg_info->scsi.scsi_status;
 	ctsio->sense_len = msg_info->scsi.sense_len;
-	ctsio->sense_residual = msg_info->scsi.sense_residual;
-	ctsio->residual = msg_info->scsi.residual;
 	memcpy(&ctsio->sense_data, &msg_info->scsi.sense_data,
 	       msg_info->scsi.sense_len);
 	ctl_enqueue_isc((union ctl_io *)ctsio);
@@ -1495,13 +1536,12 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
 			io->io_hdr.msg_type = CTL_MSG_DATAMOVE_DONE;
 			io->io_hdr.flags &= ~CTL_FLAG_DMA_INPROG;
 			io->io_hdr.flags |= CTL_FLAG_IO_ACTIVE;
-			io->io_hdr.port_status = msg->scsi.fetd_status;
-			io->scsiio.residual = msg->scsi.residual;
+			io->io_hdr.port_status = msg->scsi.port_status;
+			io->scsiio.kern_data_resid = msg->scsi.kern_data_resid;
 			if (msg->hdr.status != CTL_STATUS_NONE) {
 				io->io_hdr.status = msg->hdr.status;
 				io->scsiio.scsi_status = msg->scsi.scsi_status;
 				io->scsiio.sense_len = msg->scsi.sense_len;
-				io->scsiio.sense_residual =msg->scsi.sense_residual;
 				memcpy(&io->scsiio.sense_data,
 				    &msg->scsi.sense_data,
 				    msg->scsi.sense_len);
@@ -1787,7 +1827,6 @@ ctl_init(void)
 {
 	struct make_dev_args args;
 	struct ctl_softc *softc;
-	void *other_pool;
 	int i, error;
 
 	softc = control_softc = malloc(sizeof(*control_softc), M_DEVBUF,
@@ -1860,15 +1899,6 @@ ctl_init(void)
 	STAILQ_INIT(&softc->be_list);
 	ctl_tpc_init(softc);
 
-	if (ctl_pool_create(softc, "othersc", CTL_POOL_ENTRIES_OTHER_SC,
-	                    &other_pool) != 0)
-	{
-		printf("ctl: can't allocate %d entry other SC pool, "
-		       "exiting\n", CTL_POOL_ENTRIES_OTHER_SC);
-		return (ENOMEM);
-	}
-	softc->othersc_pool = other_pool;
-
 	if (worker_threads <= 0)
 		worker_threads = max(1, mp_ncpus / 4);
 	if (worker_threads > CTL_MAX_THREADS)
@@ -1888,22 +1918,19 @@ ctl_init(void)
 		    &softc->ctl_proc, &thr->thread, 0, 0, "ctl", "work%d", i);
 		if (error != 0) {
 			printf("error creating CTL work thread!\n");
-			ctl_pool_free(other_pool);
 			return (error);
 		}
 	}
 	error = kproc_kthread_add(ctl_lun_thread, softc,
-	    &softc->ctl_proc, NULL, 0, 0, "ctl", "lun");
+	    &softc->ctl_proc, &softc->lun_thread, 0, 0, "ctl", "lun");
 	if (error != 0) {
 		printf("error creating CTL lun thread!\n");
-		ctl_pool_free(other_pool);
 		return (error);
 	}
 	error = kproc_kthread_add(ctl_thresh_thread, softc,
-	    &softc->ctl_proc, NULL, 0, 0, "ctl", "thresh");
+	    &softc->ctl_proc, &softc->thresh_thread, 0, 0, "ctl", "thresh");
 	if (error != 0) {
 		printf("error creating CTL threshold thread!\n");
-		ctl_pool_free(other_pool);
 		return (error);
 	}
 
@@ -1912,58 +1939,54 @@ ctl_init(void)
 	    softc, 0, ctl_ha_role_sysctl, "I", "HA role for this head");
 
 	if (softc->is_single == 0) {
-		ctl_frontend_register(&ha_frontend);
-		if (ctl_ha_msg_init(softc) != CTL_HA_STATUS_SUCCESS) {
-			printf("ctl_init: ctl_ha_msg_init failed.\n");
+		if (ctl_frontend_register(&ha_frontend) != 0)
 			softc->is_single = 1;
-		} else
-		if (ctl_ha_msg_register(CTL_HA_CHAN_CTL, ctl_isc_event_handler)
-		    != CTL_HA_STATUS_SUCCESS) {
-			printf("ctl_init: ctl_ha_msg_register failed.\n");
-			softc->is_single = 1;
-		}
 	}
 	return (0);
 }
 
-void
+static int
 ctl_shutdown(void)
 {
 	struct ctl_softc *softc = control_softc;
-	struct ctl_lun *lun, *next_lun;
+	int i;
 
-	if (softc->is_single == 0) {
-		ctl_ha_msg_shutdown(softc);
-		if (ctl_ha_msg_deregister(CTL_HA_CHAN_CTL)
-		    != CTL_HA_STATUS_SUCCESS)
-			printf("%s: ctl_ha_msg_deregister failed.\n", __func__);
-		if (ctl_ha_msg_destroy(softc) != CTL_HA_STATUS_SUCCESS)
-			printf("%s: ctl_ha_msg_destroy failed.\n", __func__);
+	if (softc->is_single == 0)
 		ctl_frontend_deregister(&ha_frontend);
+
+	destroy_dev(softc->dev);
+
+	/* Shutdown CTL threads. */
+	softc->shutdown = 1;
+	for (i = 0; i < worker_threads; i++) {
+		struct ctl_thread *thr = &softc->threads[i];
+		while (thr->thread != NULL) {
+			wakeup(thr);
+			if (thr->thread != NULL)
+				pause("CTL thr shutdown", 1);
+		}
+		mtx_destroy(&thr->queue_lock);
+	}
+	while (softc->lun_thread != NULL) {
+		wakeup(&softc->pending_lun_queue);
+		if (softc->lun_thread != NULL)
+			pause("CTL thr shutdown", 1);
+	}
+	while (softc->thresh_thread != NULL) {
+		wakeup(softc->thresh_thread);
+		if (softc->thresh_thread != NULL)
+			pause("CTL thr shutdown", 1);
 	}
-
-	mtx_lock(&softc->ctl_lock);
-
-	STAILQ_FOREACH_SAFE(lun, &softc->lun_list, links, next_lun)
-		ctl_free_lun(lun);
-
-	mtx_unlock(&softc->ctl_lock);
-
-#if 0
-	ctl_shutdown_thread(softc->work_thread);
-	mtx_destroy(&softc->queue_lock);
-#endif
 
 	ctl_tpc_shutdown(softc);
 	uma_zdestroy(softc->io_zone);
 	mtx_destroy(&softc->ctl_lock);
 
-	destroy_dev(softc->dev);
-
 	sysctl_ctx_free(&softc->sysctl_ctx);
 
 	free(softc, M_DEVBUF);
 	control_softc = NULL;
+	return (0);
 }
 
 static int
@@ -1974,7 +1997,7 @@ ctl_module_event_handler(module_t mod, int what, void *arg)
 	case MOD_LOAD:
 		return (ctl_init());
 	case MOD_UNLOAD:
-		return (EBUSY);
+		return (ctl_shutdown());
 	default:
 		return (EOPNOTSUPP);
 	}
@@ -6498,15 +6521,8 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
 	ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
 	ctsio->kern_sg_entries = 0;
 	ctsio->kern_rel_offset = 0;
-	if (total_len < alloc_len) {
-		ctsio->residual = alloc_len - total_len;
-		ctsio->kern_data_len = total_len;
-		ctsio->kern_total_len = total_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
+	ctsio->kern_data_len = min(total_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	switch (ctsio->cdb[0]) {
 	case MODE_SENSE_6: {
@@ -6850,15 +6866,8 @@ ctl_log_sense(struct ctl_scsiio *ctsio)
 	ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
 	ctsio->kern_sg_entries = 0;
 	ctsio->kern_rel_offset = 0;
-	if (total_len < alloc_len) {
-		ctsio->residual = alloc_len - total_len;
-		ctsio->kern_data_len = total_len;
-		ctsio->kern_total_len = total_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
+	ctsio->kern_data_len = min(total_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	header = (struct scsi_log_header *)ctsio->kern_data_ptr;
 	header->page = page_index->page_code;
@@ -6913,7 +6922,6 @@ ctl_read_capacity(struct ctl_scsiio *ctsio)
 
 	ctsio->kern_data_ptr = malloc(sizeof(*data), M_CTL, M_WAITOK | M_ZERO);
 	data = (struct scsi_read_capacity_data *)ctsio->kern_data_ptr;
-	ctsio->residual = 0;
 	ctsio->kern_data_len = sizeof(*data);
 	ctsio->kern_total_len = sizeof(*data);
 	ctsio->kern_rel_offset = 0;
@@ -6971,18 +6979,10 @@ ctl_read_capacity_16(struct ctl_scsiio *ctsio)
 
 	ctsio->kern_data_ptr = malloc(sizeof(*data), M_CTL, M_WAITOK | M_ZERO);
 	data = (struct scsi_read_capacity_data_long *)ctsio->kern_data_ptr;
-
-	if (sizeof(*data) < alloc_len) {
-		ctsio->residual = alloc_len - sizeof(*data);
-		ctsio->kern_data_len = sizeof(*data);
-		ctsio->kern_total_len = sizeof(*data);
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
 	ctsio->kern_sg_entries = 0;
+	ctsio->kern_data_len = min(sizeof(*data), alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	scsi_u64to8b(lun->be_lun->maxlba, data->addr);
 	/* XXX KDM this may not be 512 bytes... */
@@ -7025,18 +7025,10 @@ ctl_get_lba_status(struct ctl_scsiio *ctsio)
 	total_len = sizeof(*data) + sizeof(data->descr[0]);
 	ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
 	data = (struct scsi_get_lba_status_data *)ctsio->kern_data_ptr;
-
-	if (total_len < alloc_len) {
-		ctsio->residual = alloc_len - total_len;
-		ctsio->kern_data_len = total_len;
-		ctsio->kern_total_len = total_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
 	ctsio->kern_sg_entries = 0;
+	ctsio->kern_data_len = min(total_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	/* Fill dummy data in case backend can't tell anything. */
 	scsi_ulto4b(4 + sizeof(data->descr[0]), data->length);
@@ -7087,17 +7079,10 @@ ctl_read_defect(struct ctl_scsiio *ctsio)
 	}
 
 	ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
-	if (data_len < alloc_len) {
-		ctsio->residual = alloc_len - data_len;
-		ctsio->kern_data_len = data_len;
-		ctsio->kern_total_len = data_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
 	ctsio->kern_sg_entries = 0;
+	ctsio->kern_data_len = min(data_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	if (ctsio->cdb[0] == READ_DEFECT_DATA_10) {
 		data10 = (struct scsi_read_defect_data_hdr_10 *)
@@ -7182,19 +7167,10 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio)
 	alloc_len = scsi_4btoul(cdb->length);
 
 	ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
 	ctsio->kern_sg_entries = 0;
-
-	if (total_len < alloc_len) {
-		ctsio->residual = alloc_len - total_len;
-		ctsio->kern_data_len = total_len;
-		ctsio->kern_total_len = total_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
+	ctsio->kern_data_len = min(total_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	if (ext) {
 		rtg_ext_ptr = (struct scsi_target_group_data_extended *)
@@ -7382,19 +7358,10 @@ ctl_report_supported_opcodes(struct ctl_scsiio *ctsio)
 	alloc_len = scsi_4btoul(cdb->length);
 
 	ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
 	ctsio->kern_sg_entries = 0;
-
-	if (total_len < alloc_len) {
-		ctsio->residual = alloc_len - total_len;
-		ctsio->kern_data_len = total_len;
-		ctsio->kern_total_len = total_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
+	ctsio->kern_data_len = min(total_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	switch (cdb->options & RSO_OPTIONS_MASK) {
 	case RSO_OPTIONS_ALL:
@@ -7495,19 +7462,10 @@ ctl_report_supported_tmf(struct ctl_scsiio *ctsio)
 	alloc_len = scsi_4btoul(cdb->length);
 
 	ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
 	ctsio->kern_sg_entries = 0;
-
-	if (total_len < alloc_len) {
-		ctsio->residual = alloc_len - total_len;
-		ctsio->kern_data_len = total_len;
-		ctsio->kern_total_len = total_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
+	ctsio->kern_data_len = min(total_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	data = (struct scsi_report_supported_tmf_ext_data *)ctsio->kern_data_ptr;
 	data->byte1 |= RST_ATS | RST_ATSS | RST_CTSS | RST_LURS | RST_QTS |
@@ -7542,19 +7500,10 @@ ctl_report_timestamp(struct ctl_scsiio *ctsio)
 	alloc_len = scsi_4btoul(cdb->length);
 
 	ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
 	ctsio->kern_sg_entries = 0;
-
-	if (total_len < alloc_len) {
-		ctsio->residual = alloc_len - total_len;
-		ctsio->kern_data_len = total_len;
-		ctsio->kern_total_len = total_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
+	ctsio->kern_data_len = min(total_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	data = (struct scsi_report_timestamp_data *)ctsio->kern_data_ptr;
 	scsi_ulto2b(sizeof(*data) - 2, data->length);
@@ -7615,19 +7564,10 @@ retry:
 	mtx_unlock(&lun->lun_lock);
 
 	ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
-	if (total_len < alloc_len) {
-		ctsio->residual = alloc_len - total_len;
-		ctsio->kern_data_len = total_len;
-		ctsio->kern_total_len = total_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
-
 	ctsio->kern_rel_offset = 0;
 	ctsio->kern_sg_entries = 0;
+	ctsio->kern_data_len = min(total_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	mtx_lock(&lun->lun_lock);
 	switch (cdb->action) {
@@ -9174,18 +9114,10 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
 	 */
 	lun_datalen = sizeof(*lun_data) +
 		(num_filled * sizeof(struct scsi_report_luns_lundata));
-
-	if (lun_datalen < alloc_len) {
-		ctsio->residual = alloc_len - lun_datalen;
-		ctsio->kern_data_len = lun_datalen;
-		ctsio->kern_total_len = lun_datalen;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
 	ctsio->kern_sg_entries = 0;
+	ctsio->kern_data_len = min(lun_datalen, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	/*
 	 * We set this to the actual data length, regardless of how much
@@ -9236,19 +9168,16 @@ ctl_request_sense(struct ctl_scsiio *ctsio)
 	ctsio->kern_data_ptr = malloc(sizeof(*sense_ptr), M_CTL, M_WAITOK);
 	sense_ptr = (struct scsi_sense_data *)ctsio->kern_data_ptr;
 	ctsio->kern_sg_entries = 0;
+	ctsio->kern_rel_offset = 0;
 
 	/*
 	 * struct scsi_sense_data, which is currently set to 256 bytes, is
 	 * larger than the largest allowed value for the length field in the
 	 * REQUEST SENSE CDB, which is 252 bytes as of SPC-4.
 	 */
-	ctsio->residual = 0;
 	ctsio->kern_data_len = cdb->length;
 	ctsio->kern_total_len = cdb->length;
 
-	ctsio->kern_rel_offset = 0;
-	ctsio->kern_sg_entries = 0;
-
 	/*
 	 * If we don't have a LUN, we don't have any pending sense.
 	 */
@@ -9373,19 +9302,10 @@ ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len)
 	    SCSI_EVPD_NUM_SUPPORTED_PAGES;
 	ctsio->kern_data_ptr = malloc(sup_page_size, M_CTL, M_WAITOK | M_ZERO);
 	pages = (struct scsi_vpd_supported_pages *)ctsio->kern_data_ptr;
-	ctsio->kern_sg_entries = 0;
-
-	if (sup_page_size < alloc_len) {
-		ctsio->residual = alloc_len - sup_page_size;
-		ctsio->kern_data_len = sup_page_size;
-		ctsio->kern_total_len = sup_page_size;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
 	ctsio->kern_sg_entries = 0;
+	ctsio->kern_data_len = min(sup_page_size, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	/*
 	 * The control device is always connected.  The disk device, on the
@@ -9443,17 +9363,10 @@ ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len)
 	data_len = 4 + CTL_SN_LEN;
 	ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
 	sn_ptr = (struct scsi_vpd_unit_serial_number *)ctsio->kern_data_ptr;
-	if (data_len < alloc_len) {
-		ctsio->residual = alloc_len - data_len;
-		ctsio->kern_data_len = data_len;
-		ctsio->kern_total_len = data_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
 	ctsio->kern_sg_entries = 0;
+	ctsio->kern_data_len = min(data_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	/*
 	 * The control device is always connected.  The disk device, on the
@@ -9500,18 +9413,9 @@ ctl_inquiry_evpd_eid(struct ctl_scsiio *ctsio, int alloc_len)
 	ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
 	eid_ptr = (struct scsi_vpd_extended_inquiry_data *)ctsio->kern_data_ptr;
 	ctsio->kern_sg_entries = 0;
-
-	if (data_len < alloc_len) {
-		ctsio->residual = alloc_len - data_len;
-		ctsio->kern_data_len = data_len;
-		ctsio->kern_total_len = data_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
-	ctsio->kern_sg_entries = 0;
+	ctsio->kern_data_len = min(data_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	/*
 	 * The control device is always connected.  The disk device, on the
@@ -9574,19 +9478,10 @@ ctl_inquiry_evpd_mpp(struct ctl_scsiio *ctsio, int alloc_len)
 
 	ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
 	mpp_ptr = (struct scsi_vpd_mode_page_policy *)ctsio->kern_data_ptr;
-	ctsio->kern_sg_entries = 0;
-
-	if (data_len < alloc_len) {
-		ctsio->residual = alloc_len - data_len;
-		ctsio->kern_data_len = data_len;
-		ctsio->kern_total_len = data_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
 	ctsio->kern_sg_entries = 0;
+	ctsio->kern_data_len = min(data_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	/*
 	 * The control device is always connected.  The disk device, on the
@@ -9639,18 +9534,10 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len)
 	ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
 	devid_ptr = (struct scsi_vpd_device_id *)ctsio->kern_data_ptr;
 	ctsio->kern_sg_entries = 0;
-
-	if (data_len < alloc_len) {
-		ctsio->residual = alloc_len - data_len;
-		ctsio->kern_data_len = data_len;
-		ctsio->kern_total_len = data_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
 	ctsio->kern_sg_entries = 0;
+	ctsio->kern_data_len = min(data_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	/*
 	 * The control device is always connected.  The disk device, on the
@@ -9767,18 +9654,10 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len)
 	ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
 	sp = (struct scsi_vpd_scsi_ports *)ctsio->kern_data_ptr;
 	ctsio->kern_sg_entries = 0;
-
-	if (data_len < alloc_len) {
-		ctsio->residual = alloc_len - data_len;
-		ctsio->kern_data_len = data_len;
-		ctsio->kern_total_len = data_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
 	ctsio->kern_sg_entries = 0;
+	ctsio->kern_data_len = min(data_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	/*
 	 * The control device is always connected.  The disk device, on the
@@ -9842,18 +9721,10 @@ ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, int alloc_len)
 	ctsio->kern_data_ptr = malloc(sizeof(*bl_ptr), M_CTL, M_WAITOK | M_ZERO);
 	bl_ptr = (struct scsi_vpd_block_limits *)ctsio->kern_data_ptr;
 	ctsio->kern_sg_entries = 0;
-
-	if (sizeof(*bl_ptr) < alloc_len) {
-		ctsio->residual = alloc_len - sizeof(*bl_ptr);
-		ctsio->kern_data_len = sizeof(*bl_ptr);
-		ctsio->kern_total_len = sizeof(*bl_ptr);
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
 	ctsio->kern_sg_entries = 0;
+	ctsio->kern_data_len = min(sizeof(*bl_ptr), alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	/*
 	 * The control device is always connected.  The disk device, on the
@@ -9917,18 +9788,9 @@ ctl_inquiry_evpd_bdc(struct ctl_scsiio *ctsio, int alloc_len)
 	ctsio->kern_data_ptr = malloc(sizeof(*bdc_ptr), M_CTL, M_WAITOK | M_ZERO);
 	bdc_ptr = (struct scsi_vpd_block_device_characteristics *)ctsio->kern_data_ptr;
 	ctsio->kern_sg_entries = 0;
-
-	if (sizeof(*bdc_ptr) < alloc_len) {
-		ctsio->residual = alloc_len - sizeof(*bdc_ptr);
-		ctsio->kern_data_len = sizeof(*bdc_ptr);
-		ctsio->kern_total_len = sizeof(*bdc_ptr);
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
-	ctsio->kern_sg_entries = 0;
+	ctsio->kern_data_len = min(sizeof(*bdc_ptr), alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	/*
 	 * The control device is always connected.  The disk device, on the
@@ -9973,18 +9835,9 @@ ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len)
 	ctsio->kern_data_ptr = malloc(sizeof(*lbp_ptr), M_CTL, M_WAITOK | M_ZERO);
 	lbp_ptr = (struct scsi_vpd_logical_block_prov *)ctsio->kern_data_ptr;
 	ctsio->kern_sg_entries = 0;
-
-	if (sizeof(*lbp_ptr) < alloc_len) {
-		ctsio->residual = alloc_len - sizeof(*lbp_ptr);
-		ctsio->kern_data_len = sizeof(*lbp_ptr);
-		ctsio->kern_total_len = sizeof(*lbp_ptr);
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
-	ctsio->kern_sg_entries = 0;
+	ctsio->kern_data_len = min(sizeof(*lbp_ptr), alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	/*
 	 * The control device is always connected.  The disk device, on the
@@ -10118,16 +9971,8 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio)
 	inq_ptr = (struct scsi_inquiry_data *)ctsio->kern_data_ptr;
 	ctsio->kern_sg_entries = 0;
 	ctsio->kern_rel_offset = 0;
-
-	if (data_len < alloc_len) {
-		ctsio->residual = alloc_len - data_len;
-		ctsio->kern_data_len = data_len;
-		ctsio->kern_total_len = data_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
+	ctsio->kern_data_len = min(data_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	if (lun != NULL) {
 		if ((lun->flags & CTL_LUN_PRIMARY_SC) ||
@@ -10258,6 +10103,9 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio)
 	} else if (port_type == CTL_PORT_SAS) {
 		/* SAS (no version claimed) */
 		scsi_ulto2b(0x0BE0, inq_ptr->version3);
+	} else if (port_type == CTL_PORT_UMASS) {
+		/* USB Mass Storage Class Bulk-Only Transport, Revision 1.0 */
+		scsi_ulto2b(0x1730, inq_ptr->version3);
 	}
 
 	if (lun == NULL) {
@@ -10511,15 +10359,8 @@ done:
 		data_len = (uint8_t *)feature - (uint8_t *)hdr;
 	}
 	scsi_ulto4b(data_len - 4, hdr->data_length);
-	if (data_len < alloc_len) {
-		ctsio->residual = alloc_len - data_len;
-		ctsio->kern_data_len = data_len;
-		ctsio->kern_total_len = data_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
+	ctsio->kern_data_len = min(data_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	ctl_set_success(ctsio);
 	ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
@@ -10550,16 +10391,8 @@ ctl_get_event_status(struct ctl_scsiio *ctsio)
 	ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
 	ctsio->kern_sg_entries = 0;
 	ctsio->kern_rel_offset = 0;
-
-	if (data_len < alloc_len) {
-		ctsio->residual = alloc_len - data_len;
-		ctsio->kern_data_len = data_len;
-		ctsio->kern_total_len = data_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
+	ctsio->kern_data_len = min(data_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	hdr = (struct scsi_get_event_status_header *)ctsio->kern_data_ptr;
 	scsi_ulto2b(0, hdr->descr_length);
@@ -10587,16 +10420,8 @@ ctl_mechanism_status(struct ctl_scsiio *ctsio)
 	ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
 	ctsio->kern_sg_entries = 0;
 	ctsio->kern_rel_offset = 0;
-
-	if (data_len < alloc_len) {
-		ctsio->residual = alloc_len - data_len;
-		ctsio->kern_data_len = data_len;
-		ctsio->kern_total_len = data_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
+	ctsio->kern_data_len = min(data_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	hdr = (struct scsi_mechanism_status_header *)ctsio->kern_data_ptr;
 	hdr->state1 = 0x00;
@@ -10646,16 +10471,8 @@ ctl_read_toc(struct ctl_scsiio *ctsio)
 	ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
 	ctsio->kern_sg_entries = 0;
 	ctsio->kern_rel_offset = 0;
-
-	if (data_len < alloc_len) {
-		ctsio->residual = alloc_len - data_len;
-		ctsio->kern_data_len = data_len;
-		ctsio->kern_total_len = data_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
+	ctsio->kern_data_len = min(data_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	hdr = (struct scsi_read_toc_hdr *)ctsio->kern_data_ptr;
 	if (format == 0) {
@@ -12647,15 +12464,14 @@ ctl_send_datamove_done(union ctl_io *io, int have_lock)
 	msg.hdr.serializing_sc = io->io_hdr.serializing_sc;
 	msg.hdr.nexus = io->io_hdr.nexus;
 	msg.hdr.status = io->io_hdr.status;
+	msg.scsi.kern_data_resid = io->scsiio.kern_data_resid;
 	msg.scsi.tag_num = io->scsiio.tag_num;
 	msg.scsi.tag_type = io->scsiio.tag_type;
 	msg.scsi.scsi_status = io->scsiio.scsi_status;
 	memcpy(&msg.scsi.sense_data, &io->scsiio.sense_data,
 	       io->scsiio.sense_len);
 	msg.scsi.sense_len = io->scsiio.sense_len;
-	msg.scsi.sense_residual = io->scsiio.sense_residual;
-	msg.scsi.fetd_status = io->io_hdr.port_status;
-	msg.scsi.residual = io->scsiio.residual;
+	msg.scsi.port_status = io->io_hdr.port_status;
 	io->io_hdr.flags &= ~CTL_FLAG_IO_ACTIVE;
 	if (io->io_hdr.flags & CTL_FLAG_FAILOVER) {
 		ctl_failover_io(io, /*have_lock*/ have_lock);
@@ -13483,7 +13299,7 @@ ctl_work_thread(void *arg)
 
 	CTL_DEBUG_PRINT(("ctl_work_thread starting\n"));
 
-	for (;;) {
+	while (!softc->shutdown) {
 		/*
 		 * We handle the queues in this order:
 		 * - ISC
@@ -13533,6 +13349,8 @@ ctl_work_thread(void *arg)
 		/* Sleep until we have something to do. */
 		mtx_sleep(thr, &thr->queue_lock, PDROP | PRIBIO, "-", 0);
 	}
+	thr->thread = NULL;
+	kthread_exit();
 }
 
 static void
@@ -13543,7 +13361,7 @@ ctl_lun_thread(void *arg)
 
 	CTL_DEBUG_PRINT(("ctl_lun_thread starting\n"));
 
-	for (;;) {
+	while (!softc->shutdown) {
 		mtx_lock(&softc->ctl_lock);
 		be_lun = STAILQ_FIRST(&softc->pending_lun_queue);
 		if (be_lun != NULL) {
@@ -13557,6 +13375,8 @@ ctl_lun_thread(void *arg)
 		mtx_sleep(&softc->pending_lun_queue, &softc->ctl_lock,
 		    PDROP | PRIBIO, "-", 0);
 	}
+	softc->lun_thread = NULL;
+	kthread_exit();
 }
 
 static void
@@ -13572,7 +13392,7 @@ ctl_thresh_thread(void *arg)
 
 	CTL_DEBUG_PRINT(("ctl_thresh_thread starting\n"));
 
-	for (;;) {
+	while (!softc->shutdown) {
 		mtx_lock(&softc->ctl_lock);
 		STAILQ_FOREACH(lun, &softc->lun_list, links) {
 			if ((lun->flags & CTL_LUN_DISABLED) ||
@@ -13657,9 +13477,11 @@ ctl_thresh_thread(void *arg)
 				mtx_lock(&softc->ctl_lock);
 			}
 		}
-		mtx_unlock(&softc->ctl_lock);
-		pause("-", CTL_LBP_PERIOD * hz);
+		mtx_sleep(&softc->thresh_thread, &softc->ctl_lock,
+		    PDROP | PRIBIO, "-", CTL_LBP_PERIOD * hz);
 	}
+	softc->thresh_thread = NULL;
+	kthread_exit();
 }
 
 static void
diff --git a/sys/cam/ctl/ctl.h b/sys/cam/ctl/ctl.h
index d9a4f5a6c18..3370d15ee6a 100644
--- a/sys/cam/ctl/ctl.h
+++ b/sys/cam/ctl/ctl.h
@@ -53,6 +53,7 @@ typedef enum {
 	CTL_PORT_INTERNAL	= 0x08,
 	CTL_PORT_ISCSI		= 0x10,
 	CTL_PORT_SAS		= 0x20,
+	CTL_PORT_UMASS		= 0x40,
 	CTL_PORT_ALL		= 0xff,
 	CTL_PORT_ISC		= 0x100 // FC port for inter-shelf communication
 } ctl_port_type;
diff --git a/sys/cam/ctl/ctl_backend.c b/sys/cam/ctl/ctl_backend.c
index 86f7d3c35a7..bac7e857b6f 100644
--- a/sys/cam/ctl/ctl_backend.c
+++ b/sys/cam/ctl/ctl_backend.c
@@ -67,11 +67,10 @@ ctl_backend_register(struct ctl_backend_driver *be)
 {
 	struct ctl_softc *softc = control_softc;
 	struct ctl_backend_driver *be_tmp;
+	int error;
 
+	/* Sanity check, make sure this isn't a duplicate registration. */
 	mtx_lock(&softc->ctl_lock);
-	/*
-	 * Sanity check, make sure this isn't a duplicate registration.
-	 */
 	STAILQ_FOREACH(be_tmp, &softc->be_list, links) {
 		if (strcmp(be_tmp->name, be->name) == 0) {
 			mtx_unlock(&softc->ctl_lock);
@@ -79,39 +78,24 @@ ctl_backend_register(struct ctl_backend_driver *be)
 		}
 	}
 	mtx_unlock(&softc->ctl_lock);
-
-	/*
-	 * Call the backend's initialization routine.
-	 */
-	be->init();
-
-	mtx_lock(&softc->ctl_lock);
-	
-	STAILQ_INSERT_TAIL(&softc->be_list, be, links);
-
-	softc->num_backends++;
-
-	/*
-	 * Don't want to increment the usage count for internal consumers,
-	 * we won't be able to unload otherwise.
-	 */
-	/* XXX KDM find a substitute for this? */
-#if 0
-	if ((be->flags & CTL_BE_FLAG_INTERNAL) == 0)
-		MOD_INC_USE_COUNT;
-#endif
-
 #ifdef CS_BE_CONFIG_MOVE_DONE_IS_NOT_USED
 	be->config_move_done = ctl_config_move_done;
 #endif
-	/* XXX KDM fix this! */
 	be->num_luns = 0;
-#if 0
-	atomic_set(&be->num_luns, 0);
-#endif
 
+	/* Call the backend's initialization routine. */
+	if (be->init != NULL) {
+		if ((error = be->init()) != 0) {
+			printf("%s backend init error: %d\n",
+			    be->name, error);
+			return (error);
+		}
+	}
+
+	mtx_lock(&softc->ctl_lock);
+	STAILQ_INSERT_TAIL(&softc->be_list, be, links);
+	softc->num_backends++;
 	mtx_unlock(&softc->ctl_lock);
-
 	return (0);
 }
 
@@ -119,30 +103,21 @@ int
 ctl_backend_deregister(struct ctl_backend_driver *be)
 {
 	struct ctl_softc *softc = control_softc;
+	int error;
 
-	mtx_lock(&softc->ctl_lock);
-
-#if 0
-	if (atomic_read(&be->num_luns) != 0) {
-#endif
-	/* XXX KDM fix this! */
-	if (be->num_luns != 0) {
-		mtx_unlock(&softc->ctl_lock);
-		return (-1);
+	/* Call the backend's shutdown routine. */
+	if (be->shutdown != NULL) {
+		if ((error = be->shutdown()) != 0) {
+			printf("%s backend shutdown error: %d\n",
+			    be->name, error);
+			return (error);
+		}
 	}
 
+	mtx_lock(&softc->ctl_lock);
 	STAILQ_REMOVE(&softc->be_list, be, ctl_backend_driver, links);
-
 	softc->num_backends--;
-
-	/* XXX KDM find a substitute for this? */
-#if 0
-	if ((be->flags & CTL_BE_FLAG_INTERNAL) == 0)
-		MOD_DEC_USE_COUNT;
-#endif
-
 	mtx_unlock(&softc->ctl_lock);
-
 	return (0);
 }
 
diff --git a/sys/cam/ctl/ctl_backend.h b/sys/cam/ctl/ctl_backend.h
index d8ada837773..4202efc137d 100644
--- a/sys/cam/ctl/ctl_backend.h
+++ b/sys/cam/ctl/ctl_backend.h
@@ -55,12 +55,13 @@ typedef enum {
 	{ \
 		switch (type) { \
 		case MOD_LOAD: \
-			ctl_backend_register( \
-				(struct ctl_backend_driver *)data); \
+			return (ctl_backend_register( \
+				(struct ctl_backend_driver *)data)); \
 			break; \
 		case MOD_UNLOAD: \
-			printf(#name " module unload - not possible for this module type\n"); \
-			return EINVAL; \
+			return (ctl_backend_deregister( \
+				(struct ctl_backend_driver *)data)); \
+			break; \
 		default: \
 			return EOPNOTSUPP; \
 		} \
@@ -179,10 +180,10 @@ struct ctl_be_lun {
 typedef enum {
 	CTL_BE_FLAG_NONE	= 0x00,	/* no flags */
 	CTL_BE_FLAG_HAS_CONFIG	= 0x01,	/* can do config reads, writes */
-	CTL_BE_FLAG_INTERNAL	= 0x02	/* don't inc mod refcount */
 } ctl_backend_flags;
 
 typedef int (*be_init_t)(void);
+typedef int (*be_shutdown_t)(void);
 typedef int (*be_func_t)(union ctl_io *io);
 typedef void (*be_vfunc_t)(union ctl_io *io);
 typedef int (*be_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
@@ -194,6 +195,7 @@ struct ctl_backend_driver {
 	char		  name[CTL_BE_NAME_LEN]; /* passed to CTL */
 	ctl_backend_flags flags;	         /* passed to CTL */
 	be_init_t	  init;			 /* passed to CTL */
+	be_shutdown_t	  shutdown;		 /* passed to CTL */
 	be_func_t	  data_submit;		 /* passed to CTL */
 	be_func_t	  data_move_done;	 /* passed to CTL */
 	be_func_t	  config_read;		 /* passed to CTL */
diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c
index 2bc8d697cd1..4a6141ff143 100644
--- a/sys/cam/ctl/ctl_backend_block.c
+++ b/sys/cam/ctl/ctl_backend_block.c
@@ -183,6 +183,7 @@ struct ctl_be_block_lun {
  */
 struct ctl_be_block_softc {
 	struct mtx			 lock;
+	uma_zone_t			 beio_zone;
 	int				 num_luns;
 	STAILQ_HEAD(, ctl_be_block_lun)	 lun_list;
 };
@@ -273,13 +274,15 @@ static int ctl_be_block_config_write(union ctl_io *io);
 static int ctl_be_block_config_read(union ctl_io *io);
 static int ctl_be_block_lun_info(void *be_lun, struct sbuf *sb);
 static uint64_t ctl_be_block_lun_attr(void *be_lun, const char *attrname);
-int ctl_be_block_init(void);
+static int ctl_be_block_init(void);
+static int ctl_be_block_shutdown(void);
 
 static struct ctl_backend_driver ctl_be_block_driver = 
 {
 	.name = "block",
 	.flags = CTL_BE_FLAG_HAS_CONFIG,
 	.init = ctl_be_block_init,
+	.shutdown = ctl_be_block_shutdown,
 	.data_submit = ctl_be_block_submit,
 	.data_move_done = ctl_be_block_move_done,
 	.config_read = ctl_be_block_config_read,
@@ -292,14 +295,12 @@ static struct ctl_backend_driver ctl_be_block_driver =
 MALLOC_DEFINE(M_CTLBLK, "ctlblk", "Memory used for CTL block backend");
 CTL_BACKEND_DECLARE(cbb, ctl_be_block_driver);
 
-static uma_zone_t beio_zone;
-
 static struct ctl_be_block_io *
 ctl_alloc_beio(struct ctl_be_block_softc *softc)
 {
 	struct ctl_be_block_io *beio;
 
-	beio = uma_zalloc(beio_zone, M_WAITOK | M_ZERO);
+	beio = uma_zalloc(softc->beio_zone, M_WAITOK | M_ZERO);
 	beio->softc = softc;
 	return (beio);
 }
@@ -332,7 +333,7 @@ ctl_free_beio(struct ctl_be_block_io *beio)
 		       duplicate_free, beio->num_segs);
 	}
 
-	uma_zfree(beio_zone, beio);
+	uma_zfree(beio->softc->beio_zone, beio);
 }
 
 static void
@@ -2859,19 +2860,40 @@ ctl_be_block_lun_attr(void *be_lun, const char *attrname)
 	return (lun->getattr(lun, attrname));
 }
 
-int
+static int
 ctl_be_block_init(void)
 {
-	struct ctl_be_block_softc *softc;
-	int retval;
-
-	softc = &backend_block_softc;
-	retval = 0;
+	struct ctl_be_block_softc *softc = &backend_block_softc;
 
 	mtx_init(&softc->lock, "ctlblock", NULL, MTX_DEF);
-	beio_zone = uma_zcreate("beio", sizeof(struct ctl_be_block_io),
+	softc->beio_zone = uma_zcreate("beio", sizeof(struct ctl_be_block_io),
 	    NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
 	STAILQ_INIT(&softc->lun_list);
-
-	return (retval);
+	return (0);
+}
+
+
+static int
+ctl_be_block_shutdown(void)
+{
+	struct ctl_be_block_softc *softc = &backend_block_softc;
+	struct ctl_be_block_lun *lun, *next_lun;
+
+	mtx_lock(&softc->lock);
+	STAILQ_FOREACH_SAFE(lun, &softc->lun_list, links, next_lun) {
+		/*
+		 * Drop our lock here.  Since ctl_invalidate_lun() can call
+		 * back into us, this could potentially lead to a recursive
+		 * lock of the same mutex, which would cause a hang.
+		 */
+		mtx_unlock(&softc->lock);
+		ctl_disable_lun(&lun->cbe_lun);
+		ctl_invalidate_lun(&lun->cbe_lun);
+		mtx_lock(&softc->lock);
+	}
+	mtx_unlock(&softc->lock);
+
+	uma_zdestroy(softc->beio_zone);
+	mtx_destroy(&softc->lock);
+	return (0);
 }
diff --git a/sys/cam/ctl/ctl_backend_ramdisk.c b/sys/cam/ctl/ctl_backend_ramdisk.c
index 71ed07ad909..5b85d9c700f 100644
--- a/sys/cam/ctl/ctl_backend_ramdisk.c
+++ b/sys/cam/ctl/ctl_backend_ramdisk.c
@@ -108,8 +108,8 @@ struct ctl_be_ramdisk_softc {
 static struct ctl_be_ramdisk_softc rd_softc;
 extern struct ctl_softc *control_softc;
 
-int ctl_backend_ramdisk_init(void);
-void ctl_backend_ramdisk_shutdown(void);
+static int ctl_backend_ramdisk_init(void);
+static int ctl_backend_ramdisk_shutdown(void);
 static int ctl_backend_ramdisk_move_done(union ctl_io *io);
 static int ctl_backend_ramdisk_submit(union ctl_io *io);
 static void ctl_backend_ramdisk_continue(union ctl_io *io);
@@ -133,6 +133,7 @@ static struct ctl_backend_driver ctl_be_ramdisk_driver =
 	.name = "ramdisk",
 	.flags = CTL_BE_FLAG_HAS_CONFIG,
 	.init = ctl_backend_ramdisk_init,
+	.shutdown = ctl_backend_ramdisk_shutdown,
 	.data_submit = ctl_backend_ramdisk_submit,
 	.data_move_done = ctl_backend_ramdisk_move_done,
 	.config_read = ctl_backend_ramdisk_config_read,
@@ -170,7 +171,7 @@ ctl_backend_ramdisk_init(void)
 	return (0);
 }
 
-void
+static int
 ctl_backend_ramdisk_shutdown(void)
 {
 	struct ctl_be_ramdisk_softc *softc = &rd_softc;
@@ -192,20 +193,16 @@ ctl_backend_ramdisk_shutdown(void)
 		mtx_lock(&softc->lock);
 	}
 	mtx_unlock(&softc->lock);
-	
+
 #ifdef CTL_RAMDISK_PAGES
 	for (i = 0; i < softc->num_pages; i++)
 		free(softc->ramdisk_pages[i], M_RAMDISK);
-
 	free(softc->ramdisk_pages, M_RAMDISK);
 #else
 	free(softc->ramdisk_buffer, M_RAMDISK);
 #endif
-
-	if (ctl_backend_deregister(&ctl_be_ramdisk_driver) != 0) {
-		printf("ctl_backend_ramdisk_shutdown: "
-		       "ctl_backend_deregister() failed!\n");
-	}
+	mtx_destroy(&softc->lock);
+	return (0);
 }
 
 static int
diff --git a/sys/cam/ctl/ctl_frontend.c b/sys/cam/ctl/ctl_frontend.c
index 03ee9da7566..765a31d96a2 100644
--- a/sys/cam/ctl/ctl_frontend.c
+++ b/sys/cam/ctl/ctl_frontend.c
@@ -70,12 +70,11 @@ ctl_frontend_register(struct ctl_frontend *fe)
 {
 	struct ctl_softc *softc = control_softc;
 	struct ctl_frontend *fe_tmp;
+	int error;
 
 	KASSERT(softc != NULL, ("CTL is not initialized"));
 
-	/*
-	 * Sanity check, make sure this isn't a duplicate registration.
-	 */
+	/* Sanity check, make sure this isn't a duplicate registration. */
 	mtx_lock(&softc->ctl_lock);
 	STAILQ_FOREACH(fe_tmp, &softc->fe_list, links) {
 		if (strcmp(fe_tmp->name, fe->name) == 0) {
@@ -86,11 +85,14 @@ ctl_frontend_register(struct ctl_frontend *fe)
 	mtx_unlock(&softc->ctl_lock);
 	STAILQ_INIT(&fe->port_list);
 
-	/*
-	 * Call the frontend's initialization routine.
-	 */
-	if (fe->init != NULL)
-		fe->init();
+	/* Call the frontend's initialization routine. */
+	if (fe->init != NULL) {
+		if ((error = fe->init()) != 0) {
+			printf("%s frontend init error: %d\n",
+			    fe->name, error);
+			return (error);
+		}
+	}
 
 	mtx_lock(&softc->ctl_lock);
 	softc->num_frontends++;
@@ -103,20 +105,21 @@ int
 ctl_frontend_deregister(struct ctl_frontend *fe)
 {
 	struct ctl_softc *softc = control_softc;
+	int error;
 
-	if (!STAILQ_EMPTY(&fe->port_list))
-		return (-1);
+	/* Call the frontend's shutdown routine.*/
+	if (fe->shutdown != NULL) {
+		if ((error = fe->shutdown()) != 0) {
+			printf("%s frontend shutdown error: %d\n",
+			    fe->name, error);
+			return (error);
+		}
+	}
 
 	mtx_lock(&softc->ctl_lock);
 	STAILQ_REMOVE(&softc->fe_list, fe, ctl_frontend, links);
 	softc->num_frontends--;
 	mtx_unlock(&softc->ctl_lock);
-
-	/*
-	 * Call the frontend's shutdown routine.
-	 */
-	if (fe->shutdown != NULL)
-		fe->shutdown();
 	return (0);
 }
 
diff --git a/sys/cam/ctl/ctl_frontend.h b/sys/cam/ctl/ctl_frontend.h
index 37e6824eaa8..38eb863a08f 100644
--- a/sys/cam/ctl/ctl_frontend.h
+++ b/sys/cam/ctl/ctl_frontend.h
@@ -49,7 +49,7 @@ typedef enum {
 } ctl_port_status;
 
 typedef int (*fe_init_t)(void);
-typedef void (*fe_shutdown_t)(void);
+typedef int (*fe_shutdown_t)(void);
 typedef void (*port_func_t)(void *onoff_arg);
 typedef int (*port_info_func_t)(void *onoff_arg, struct sbuf *sb);
 typedef	int (*lun_func_t)(void *arg, int lun_id);
@@ -61,12 +61,13 @@ typedef int (*fe_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
 	{ \
 		switch (type) { \
 		case MOD_LOAD: \
-			ctl_frontend_register( \
-				(struct ctl_frontend *)data); \
+			return (ctl_frontend_register( \
+				(struct ctl_frontend *)data)); \
 			break; \
 		case MOD_UNLOAD: \
-			printf(#name " module unload - not possible for this module type\n"); \
-			return EINVAL; \
+			return (ctl_frontend_deregister( \
+				(struct ctl_frontend *)data)); \
+			break; \
 		default: \
 			return EOPNOTSUPP; \
 		} \
diff --git a/sys/cam/ctl/ctl_frontend_cam_sim.c b/sys/cam/ctl/ctl_frontend_cam_sim.c
index 406adde9d3f..00a960e9e28 100644
--- a/sys/cam/ctl/ctl_frontend_cam_sim.c
+++ b/sys/cam/ctl/ctl_frontend_cam_sim.c
@@ -94,15 +94,14 @@ struct cfcs_softc {
 	CAM_SNS_BUF_PHYS | CAM_CDB_PHYS | CAM_SENSE_PTR |		\
 	CAM_SENSE_PHYS)
 
-int cfcs_init(void);
+static int cfcs_init(void);
+static int cfcs_shutdown(void);
 static void cfcs_poll(struct cam_sim *sim);
 static void cfcs_online(void *arg);
 static void cfcs_offline(void *arg);
 static void cfcs_datamove(union ctl_io *io);
 static void cfcs_done(union ctl_io *io);
 void cfcs_action(struct cam_sim *sim, union ccb *ccb);
-static void cfcs_async(void *callback_arg, uint32_t code,
-		       struct cam_path *path, void *arg);
 
 struct cfcs_softc cfcs_softc;
 /*
@@ -121,14 +120,14 @@ static struct ctl_frontend cfcs_frontend =
 {
 	.name = "camsim",
 	.init = cfcs_init,
+	.shutdown = cfcs_shutdown,
 };
 CTL_FRONTEND_DECLARE(ctlcfcs, cfcs_frontend);
 
-int
+static int
 cfcs_init(void)
 {
 	struct cfcs_softc *softc;
-	struct ccb_setasync csa;
 	struct ctl_port *port;
 	int retval;
 
@@ -214,13 +213,6 @@ cfcs_init(void)
 		goto bailout;
 	}
 
-	xpt_setup_ccb(&csa.ccb_h, softc->path, CAM_PRIORITY_NONE);
-	csa.ccb_h.func_code = XPT_SASYNC_CB;
-	csa.event_enable = AC_LOST_DEVICE;
-	csa.callback = cfcs_async;
-        csa.callback_arg = softc->sim;
-        xpt_action((union ccb *)&csa);
-
 	mtx_unlock(&softc->lock);
 
 	return (retval);
@@ -236,6 +228,27 @@ bailout:
 	return (retval);
 }
 
+static int
+cfcs_shutdown(void)
+{
+	struct cfcs_softc *softc = &cfcs_softc;
+	struct ctl_port *port = &softc->port;
+	int error;
+
+	ctl_port_offline(port);
+
+	mtx_lock(&softc->lock);
+	xpt_free_path(softc->path);
+	xpt_bus_deregister(cam_sim_path(softc->sim));
+	cam_sim_free(softc->sim, /*free_devq*/ TRUE);
+	mtx_unlock(&softc->lock);
+	mtx_destroy(&softc->lock);
+
+	if ((error = ctl_port_deregister(port)) != 0)
+		printf("%s: cam_sim port deregistration failed\n", __func__);
+	return (error);
+}
+
 static void
 cfcs_poll(struct cam_sim *sim)
 {
@@ -801,9 +814,3 @@ cfcs_action(struct cam_sim *sim, union ccb *ccb)
 		break;
 	}
 }
-
-static void
-cfcs_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
-{
-
-}
diff --git a/sys/cam/ctl/ctl_frontend_ioctl.c b/sys/cam/ctl/ctl_frontend_ioctl.c
index 3f5c23c0c55..4063c97392d 100644
--- a/sys/cam/ctl/ctl_frontend_ioctl.c
+++ b/sys/cam/ctl/ctl_frontend_ioctl.c
@@ -76,7 +76,7 @@ struct cfi_softc {
 static struct cfi_softc cfi_softc;
 
 static int cfi_init(void);
-static void cfi_shutdown(void);
+static int cfi_shutdown(void);
 static void cfi_datamove(union ctl_io *io);
 static void cfi_done(union ctl_io *io);
 
@@ -93,6 +93,7 @@ cfi_init(void)
 {
 	struct cfi_softc *isoftc = &cfi_softc;
 	struct ctl_port *port;
+	int error = 0;
 
 	memset(isoftc, 0, sizeof(*isoftc));
 
@@ -108,24 +109,25 @@ cfi_init(void)
 	port->targ_port = -1;
 	port->max_initiators = 1;
 
-	if (ctl_port_register(port) != 0) {
+	if ((error = ctl_port_register(port)) != 0) {
 		printf("%s: ioctl port registration failed\n", __func__);
-		return (0);
+		return (error);
 	}
 	ctl_port_online(port);
 	return (0);
 }
 
-void
+static int
 cfi_shutdown(void)
 {
 	struct cfi_softc *isoftc = &cfi_softc;
-	struct ctl_port *port;
+	struct ctl_port *port = &isoftc->port;
+	int error = 0;
 
-	port = &isoftc->port;
 	ctl_port_offline(port);
-	if (ctl_port_deregister(&isoftc->port) != 0)
-		printf("%s: ctl_frontend_deregister() failed\n", __func__);
+	if ((error = ctl_port_deregister(port)) != 0)
+		printf("%s: ioctl port deregistration failed\n", __func__);
+	return (error);
 }
 
 /*
diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c
index 1171eb0876d..55b56ae18cc 100644
--- a/sys/cam/ctl/ctl_frontend_iscsi.c
+++ b/sys/cam/ctl/ctl_frontend_iscsi.c
@@ -144,7 +144,8 @@ SYSCTL_INT(_kern_cam_ctl_iscsi, OID_AUTO, maxcmdsn_delta, CTLFLAG_RWTUN,
 #define	PDU_TOTAL_TRANSFER_LEN(X)	(X)->ip_prv1
 #define	PDU_R2TSN(X)			(X)->ip_prv2
 
-int		cfiscsi_init(void);
+static int	cfiscsi_init(void);
+static int	cfiscsi_shutdown(void);
 static void	cfiscsi_online(void *arg);
 static void	cfiscsi_offline(void *arg);
 static int	cfiscsi_info(void *arg, struct sbuf *sb);
@@ -182,6 +183,7 @@ static struct ctl_frontend cfiscsi_frontend =
 	.name = "iscsi",
 	.init = cfiscsi_init,
 	.ioctl = cfiscsi_ioctl,
+	.shutdown = cfiscsi_shutdown,
 };
 CTL_FRONTEND_DECLARE(ctlcfiscsi, cfiscsi_frontend);
 MODULE_DEPEND(ctlcfiscsi, icl, 1, 1, 1);
@@ -1321,7 +1323,7 @@ cfiscsi_session_delete(struct cfiscsi_session *cs)
 	free(cs, M_CFISCSI);
 }
 
-int
+static int
 cfiscsi_init(void)
 {
 	struct cfiscsi_softc *softc;
@@ -1344,6 +1346,23 @@ cfiscsi_init(void)
 	return (0);
 }
 
+static int
+cfiscsi_shutdown(void)
+{
+	struct cfiscsi_softc *softc = &cfiscsi_softc;
+
+	if (!TAILQ_EMPTY(&softc->sessions) || !TAILQ_EMPTY(&softc->targets))
+		return (EBUSY);
+
+	uma_zdestroy(cfiscsi_data_wait_zone);
+#ifdef ICL_KERNEL_PROXY
+	cv_destroy(&softc->accept_cv);
+#endif
+	cv_destroy(&softc->sessions_cv);
+	mtx_destroy(&softc->lock);
+	return (0);
+}
+
 #ifdef ICL_KERNEL_PROXY
 static void
 cfiscsi_accept(struct socket *so, struct sockaddr *sa, int portal_id)
@@ -2084,7 +2103,8 @@ cfiscsi_ioctl_port_create(struct ctl_req *req)
 	if (ct->ct_state == CFISCSI_TARGET_STATE_ACTIVE) {
 		req->status = CTL_LUN_ERROR;
 		snprintf(req->error_str, sizeof(req->error_str),
-		    "target \"%s\" already exists", target);
+		    "target \"%s\" for portal group tag %u already exists",
+		    target, tag);
 		cfiscsi_target_release(ct);
 		ctl_free_opts(&opts);
 		return;
diff --git a/sys/cam/ctl/ctl_io.h b/sys/cam/ctl/ctl_io.h
index 2684bf8533c..9c472f5cd80 100644
--- a/sys/cam/ctl/ctl_io.h
+++ b/sys/cam/ctl/ctl_io.h
@@ -320,7 +320,7 @@ struct ctl_scsiio {
 	uint8_t	   sense_len;		/* Returned sense length */
 	uint8_t	   scsi_status;		/* SCSI status byte */
 	uint8_t	   sense_residual;	/* Unused. */
-	uint32_t   residual;		/* data residual length */
+	uint32_t   residual;		/* Unused */
 	uint32_t   tag_num;		/* tag number */
 	ctl_tag_type tag_type;		/* simple, ordered, head of queue,etc.*/
 	uint8_t    cdb_len;		/* CDB length */
@@ -373,7 +373,7 @@ struct ctl_taskio {
 /*
  * HA link messages.
  */
-#define	CTL_HA_VERSION		2
+#define	CTL_HA_VERSION		3
 
 /*
  * Used for CTL_MSG_LOGIN.
@@ -469,7 +469,8 @@ struct ctl_ha_msg_dt {
 };
 
 /*
- * Used for CTL_MSG_SERIALIZE, CTL_MSG_FINISH_IO, CTL_MSG_BAD_JUJU.
+ * Used for CTL_MSG_SERIALIZE, CTL_MSG_FINISH_IO, CTL_MSG_BAD_JUJU,
+ * and CTL_MSG_DATAMOVE_DONE.
  */
 struct ctl_ha_msg_scsi {
 	struct ctl_ha_msg_hdr	hdr;
@@ -479,10 +480,9 @@ struct ctl_ha_msg_scsi {
 	uint8_t			cdb_len;	/* CDB length */
 	uint8_t			scsi_status; /* SCSI status byte */
 	uint8_t			sense_len;   /* Returned sense length */
-	uint8_t			sense_residual;	/* sense residual length */
-	uint32_t		residual;    /* data residual length */
-	uint32_t		fetd_status; /* trans status, set by FETD,
+	uint32_t		port_status; /* trans status, set by FETD,
 						0 = good*/
+	uint32_t		kern_data_resid; /* for DATAMOVE_DONE */
 	struct scsi_sense_data	sense_data;  /* sense data */
 };
 
diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h
index 3f46769806b..40f0e612740 100644
--- a/sys/cam/ctl/ctl_private.h
+++ b/sys/cam/ctl/ctl_private.h
@@ -470,7 +470,10 @@ struct ctl_softc {
 	STAILQ_HEAD(, ctl_backend_driver) be_list;
 	struct uma_zone *io_zone;
 	uint32_t cur_pool_id;
+	int shutdown;
 	struct ctl_thread threads[CTL_MAX_THREADS];
+	struct thread *lun_thread;
+	struct thread *thresh_thread;
 	TAILQ_HEAD(tpc_tokens, tpc_token) tpc_tokens;
 	struct callout tpc_timeout;
 	struct mtx tpc_lock;
diff --git a/sys/cam/ctl/ctl_tpc.c b/sys/cam/ctl/ctl_tpc.c
index 9e1cfa852ed..c8d60cad019 100644
--- a/sys/cam/ctl/ctl_tpc.c
+++ b/sys/cam/ctl/ctl_tpc.c
@@ -282,19 +282,10 @@ ctl_inquiry_evpd_tpc(struct ctl_scsiio *ctsio, int alloc_len)
 
 	ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
 	tpc_ptr = (struct scsi_vpd_tpc *)ctsio->kern_data_ptr;
-	ctsio->kern_sg_entries = 0;
-
-	if (data_len < alloc_len) {
-		ctsio->residual = alloc_len - data_len;
-		ctsio->kern_data_len = data_len;
-		ctsio->kern_total_len = data_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
 	ctsio->kern_sg_entries = 0;
+	ctsio->kern_data_len = min(data_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	/*
 	 * The control device is always connected.  The disk device, on the
@@ -457,19 +448,10 @@ ctl_receive_copy_operating_parameters(struct ctl_scsiio *ctsio)
 	alloc_len = scsi_4btoul(cdb->length);
 
 	ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
 	ctsio->kern_sg_entries = 0;
-
-	if (total_len < alloc_len) {
-		ctsio->residual = alloc_len - total_len;
-		ctsio->kern_data_len = total_len;
-		ctsio->kern_total_len = total_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
+	ctsio->kern_data_len = min(total_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	data = (struct scsi_receive_copy_operating_parameters_data *)ctsio->kern_data_ptr;
 	scsi_ulto4b(sizeof(*data) - 4 + 4, data->length);
@@ -554,19 +536,10 @@ ctl_receive_copy_status_lid1(struct ctl_scsiio *ctsio)
 	alloc_len = scsi_4btoul(cdb->length);
 
 	ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
 	ctsio->kern_sg_entries = 0;
-
-	if (total_len < alloc_len) {
-		ctsio->residual = alloc_len - total_len;
-		ctsio->kern_data_len = total_len;
-		ctsio->kern_total_len = total_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
+	ctsio->kern_data_len = min(total_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	data = (struct scsi_receive_copy_status_lid1_data *)ctsio->kern_data_ptr;
 	scsi_ulto4b(sizeof(*data) - 4, data->available_data);
@@ -631,19 +604,10 @@ ctl_receive_copy_failure_details(struct ctl_scsiio *ctsio)
 	alloc_len = scsi_4btoul(cdb->length);
 
 	ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
 	ctsio->kern_sg_entries = 0;
-
-	if (total_len < alloc_len) {
-		ctsio->residual = alloc_len - total_len;
-		ctsio->kern_data_len = total_len;
-		ctsio->kern_total_len = total_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
+	ctsio->kern_data_len = min(total_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	data = (struct scsi_receive_copy_failure_details_data *)ctsio->kern_data_ptr;
 	if (list_copy.completed && (list_copy.error || list_copy.abort)) {
@@ -702,19 +666,10 @@ ctl_receive_copy_status_lid4(struct ctl_scsiio *ctsio)
 	alloc_len = scsi_4btoul(cdb->length);
 
 	ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
 	ctsio->kern_sg_entries = 0;
-
-	if (total_len < alloc_len) {
-		ctsio->residual = alloc_len - total_len;
-		ctsio->kern_data_len = total_len;
-		ctsio->kern_total_len = total_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
+	ctsio->kern_data_len = min(total_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	data = (struct scsi_receive_copy_status_lid4_data *)ctsio->kern_data_ptr;
 	scsi_ulto4b(sizeof(*data) - 4 + list_copy.sense_len,
@@ -2402,19 +2357,10 @@ ctl_receive_rod_token_information(struct ctl_scsiio *ctsio)
 	alloc_len = scsi_4btoul(cdb->length);
 
 	ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
 	ctsio->kern_sg_entries = 0;
-
-	if (total_len < alloc_len) {
-		ctsio->residual = alloc_len - total_len;
-		ctsio->kern_data_len = total_len;
-		ctsio->kern_total_len = total_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
+	ctsio->kern_data_len = min(total_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	data = (struct scsi_receive_copy_status_lid4_data *)ctsio->kern_data_ptr;
 	scsi_ulto4b(sizeof(*data) - 4 + list_copy.sense_len +
@@ -2482,19 +2428,10 @@ ctl_report_all_rod_tokens(struct ctl_scsiio *ctsio)
 	alloc_len = scsi_4btoul(cdb->length);
 
 	ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
 	ctsio->kern_sg_entries = 0;
-
-	if (total_len < alloc_len) {
-		ctsio->residual = alloc_len - total_len;
-		ctsio->kern_data_len = total_len;
-		ctsio->kern_total_len = total_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
 	ctsio->kern_rel_offset = 0;
+	ctsio->kern_data_len = min(total_len, alloc_len);
+	ctsio->kern_total_len = ctsio->kern_data_len;
 
 	data = (struct scsi_report_all_rod_tokens_data *)ctsio->kern_data_ptr;
 	i = 0;
diff --git a/sys/cam/ctl/ctl_tpc_local.c b/sys/cam/ctl/ctl_tpc_local.c
index 47b7ed6c9e3..e5e77b437a2 100644
--- a/sys/cam/ctl/ctl_tpc_local.c
+++ b/sys/cam/ctl/ctl_tpc_local.c
@@ -65,7 +65,7 @@ struct tpcl_softc {
 static struct tpcl_softc tpcl_softc;
 
 static int tpcl_init(void);
-static void tpcl_shutdown(void);
+static int tpcl_shutdown(void);
 static void tpcl_datamove(union ctl_io *io);
 static void tpcl_done(union ctl_io *io);
 
@@ -84,7 +84,7 @@ tpcl_init(void)
 	struct tpcl_softc *tsoftc = &tpcl_softc;
 	struct ctl_port *port;
 	struct scsi_transportid_spi *tid;
-	int len;
+	int error, len;
 
 	memset(tsoftc, 0, sizeof(*tsoftc));
 
@@ -100,9 +100,9 @@ tpcl_init(void)
 	port->targ_port = -1;
 	port->max_initiators = 1;
 
-	if (ctl_port_register(port) != 0) {
-		printf("%s: ctl_port_register() failed with error\n", __func__);
-		return (0);
+	if ((error = ctl_port_register(port)) != 0) {
+		printf("%s: tpc port registration failed\n", __func__);
+		return (error);
 	}
 
 	len = sizeof(struct scsi_transportid_spi);
@@ -118,16 +118,17 @@ tpcl_init(void)
 	return (0);
 }
 
-void
+static int
 tpcl_shutdown(void)
 {
 	struct tpcl_softc *tsoftc = &tpcl_softc;
-	struct ctl_port *port;
+	struct ctl_port *port = &tsoftc->port;
+	int error;
 
-	port = &tsoftc->port;
 	ctl_port_offline(port);
-	if (ctl_port_deregister(&tsoftc->port) != 0)
-		printf("%s: ctl_frontend_deregister() failed\n", __func__);
+	if ((error = ctl_port_deregister(port)) != 0)
+		printf("%s: tpc port deregistration failed\n", __func__);
+	return (error);
 }
 
 static void
diff --git a/sys/cam/ctl/scsi_ctl.c b/sys/cam/ctl/scsi_ctl.c
index a32a67200c9..1d3e0485933 100644
--- a/sys/cam/ctl/scsi_ctl.c
+++ b/sys/cam/ctl/scsi_ctl.c
@@ -188,8 +188,8 @@ MALLOC_DEFINE(M_CTLFE, "CAM CTL FE", "CAM CTL FE interface");
 #define PRIV_CCB(io)	((io)->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptrs[0])
 #define PRIV_INFO(io)	((io)->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptrs[1])
 
-int			ctlfeinitialize(void);
-void			ctlfeshutdown(void);
+static int		ctlfeinitialize(void);
+static int		ctlfeshutdown(void);
 static periph_init_t	ctlfeperiphinit;
 static void		ctlfeasync(void *callback_arg, uint32_t code,
 				   struct cam_path *path, void *arg);
@@ -227,13 +227,15 @@ static struct ctl_frontend ctlfe_frontend =
 };
 CTL_FRONTEND_DECLARE(ctlfe, ctlfe_frontend);
 
-void
+static int
 ctlfeshutdown(void)
 {
-	return;
+
+	/* CAM does not support periph driver unregister now. */
+	return (EBUSY);
 }
 
-int
+static int
 ctlfeinitialize(void)
 {
 
@@ -243,7 +245,7 @@ ctlfeinitialize(void)
 	return (0);
 }
 
-void
+static void
 ctlfeperiphinit(void)
 {
 	cam_status status;
diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h
index 64c45fb26a4..f85d285ec93 100644
--- a/sys/cam/scsi/scsi_all.h
+++ b/sys/cam/scsi/scsi_all.h
@@ -3039,7 +3039,7 @@ struct scsi_set_timestamp_parameters
 {
 	uint8_t reserved1[4];
 	uint8_t timestamp[6];
-	uint8_t reserved2[4];
+	uint8_t reserved2[2];
 };
 
 struct scsi_report_timestamp_parameter_data
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index cad8f01a11c..55f2386262a 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -828,6 +828,11 @@ static struct da_quirk_entry da_quirk_table[] =
 		{ T_DIRECT, SIP_MEDIA_FIXED, "Hitachi", "H??????????E3*", "*" },
 		/*quirks*/DA_Q_4K
 	},
+	{
+		/* Micron Advanced Format (4k) drives */
+		{ T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Micron 5100 MTFDDAK*", "*" },
+		/*quirks*/DA_Q_4K
+	},
 	{
 		/* Samsung Advanced Format (4k) drives */
 		{ T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SAMSUNG HD155UI*", "*" },
@@ -1149,6 +1154,14 @@ static struct da_quirk_entry da_quirk_table[] =
 		{ T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSC2BW*", "*" },
 		/*quirks*/DA_Q_4K
 	},
+	{
+		/*
+		 * Intel S3610 Series SSDs
+		 * 4k optimised & trim only works in 4k requests + 4k aligned
+		 */
+		{ T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSC2BX*", "*" },
+		/*quirks*/DA_Q_4K
+	},
 	{
 		/*
 		 * Intel X25-M Series SSDs
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
index 168a5797499..852f3b54c81 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
@@ -60,6 +60,16 @@ SYSCTL_DECL(_vfs_zfs);
 SYSCTL_INT(_vfs_zfs, OID_AUTO, nopwrite_enabled, CTLFLAG_RDTUN,
     &zfs_nopwrite_enabled, 0, "Enable nopwrite feature");
 
+/*
+ * Tunable to control percentage of dirtied blocks from frees in one TXG.
+ * After this threshold is crossed, additional dirty blocks from frees
+ * wait until the next TXG.
+ * A value of zero will disable this throttle.
+ */
+uint32_t zfs_per_txg_dirty_frees_percent = 30;
+SYSCTL_INT(_vfs_zfs, OID_AUTO, per_txg_dirty_frees_percent, CTLFLAG_RWTUN,
+	&zfs_per_txg_dirty_frees_percent, 0, "Percentage of dirtied blocks from frees in one txg");
+
 const dmu_object_type_info_t dmu_ot[DMU_OT_NUMTYPES] = {
 	{	DMU_BSWAP_UINT8,	TRUE,	"unallocated"		},
 	{	DMU_BSWAP_ZAP,		TRUE,	"object directory"	},
@@ -718,15 +728,25 @@ dmu_free_long_range_impl(objset_t *os, dnode_t *dn, uint64_t offset,
 {
 	uint64_t object_size = (dn->dn_maxblkid + 1) * dn->dn_datablksz;
 	int err;
+	uint64_t dirty_frees_threshold;
+	dsl_pool_t *dp = dmu_objset_pool(os);
 
 	if (offset >= object_size)
 		return (0);
 
+	if (zfs_per_txg_dirty_frees_percent <= 100)
+		dirty_frees_threshold =
+		    zfs_per_txg_dirty_frees_percent * zfs_dirty_data_max / 100;
+	else
+		dirty_frees_threshold = zfs_dirty_data_max / 4;
+
 	if (length == DMU_OBJECT_END || offset + length > object_size)
 		length = object_size - offset;
 
 	while (length != 0) {
-		uint64_t chunk_end, chunk_begin;
+		uint64_t chunk_end, chunk_begin, chunk_len;
+		uint64_t long_free_dirty_all_txgs = 0;
+		dmu_tx_t *tx;
 
 		chunk_end = chunk_begin = offset + length;
 
@@ -737,9 +757,28 @@ dmu_free_long_range_impl(objset_t *os, dnode_t *dn, uint64_t offset,
 		ASSERT3U(chunk_begin, >=, offset);
 		ASSERT3U(chunk_begin, <=, chunk_end);
 
-		dmu_tx_t *tx = dmu_tx_create(os);
-		dmu_tx_hold_free(tx, dn->dn_object,
-		    chunk_begin, chunk_end - chunk_begin);
+		chunk_len = chunk_end - chunk_begin;
+
+		mutex_enter(&dp->dp_lock);
+		for (int t = 0; t < TXG_SIZE; t++) {
+			long_free_dirty_all_txgs +=
+			    dp->dp_long_free_dirty_pertxg[t];
+		}
+		mutex_exit(&dp->dp_lock);
+
+		/*
+		 * To avoid filling up a TXG with just frees wait for
+		 * the next TXG to open before freeing more chunks if
+		 * we have reached the threshold of frees
+		 */
+		if (dirty_frees_threshold != 0 &&
+		    long_free_dirty_all_txgs >= dirty_frees_threshold) {
+			txg_wait_open(dp, 0);
+			continue;
+		}
+
+		tx = dmu_tx_create(os);
+		dmu_tx_hold_free(tx, dn->dn_object, chunk_begin, chunk_len);
 
 		/*
 		 * Mark this transaction as typically resulting in a net
@@ -751,10 +790,18 @@ dmu_free_long_range_impl(objset_t *os, dnode_t *dn, uint64_t offset,
 			dmu_tx_abort(tx);
 			return (err);
 		}
-		dnode_free_range(dn, chunk_begin, chunk_end - chunk_begin, tx);
+
+		mutex_enter(&dp->dp_lock);
+		dp->dp_long_free_dirty_pertxg[dmu_tx_get_txg(tx) & TXG_MASK] +=
+		    chunk_len;
+		mutex_exit(&dp->dp_lock);
+		DTRACE_PROBE3(free__long__range,
+		    uint64_t, long_free_dirty_all_txgs, uint64_t, chunk_len,
+		    uint64_t, dmu_tx_get_txg(tx));
+		dnode_free_range(dn, chunk_begin, chunk_len, tx);
 		dmu_tx_commit(tx);
 
-		length -= chunk_end - chunk_begin;
+		length -= chunk_len;
 	}
 	return (0);
 }
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c
index 9b3b79bfb51..0ac2f70cf3b 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c
@@ -24,6 +24,7 @@
  * Copyright (c) 2013 Steven Hartland. All rights reserved.
  * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
  * Copyright (c) 2014 Integros [integros.com]
+ * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include 
@@ -592,6 +593,16 @@ dsl_pool_sync(dsl_pool_t *dp, uint64_t txg)
 	 */
 	dsl_pool_undirty_space(dp, dp->dp_dirty_pertxg[txg & TXG_MASK], txg);
 
+	/*
+	 * Update the long range free counter after
+	 * we're done syncing user data
+	 */
+	mutex_enter(&dp->dp_lock);
+	ASSERT(spa_sync_pass(dp->dp_spa) == 1 ||
+	    dp->dp_long_free_dirty_pertxg[txg & TXG_MASK] == 0);
+	dp->dp_long_free_dirty_pertxg[txg & TXG_MASK] = 0;
+	mutex_exit(&dp->dp_lock);
+
 	/*
 	 * After the data blocks have been written (ensured by the zio_wait()
 	 * above), update the user/group space accounting.
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h
index 0e27a538208..3e2914640c9 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h
@@ -21,6 +21,7 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #ifndef	_SYS_DSL_POOL_H
@@ -103,6 +104,7 @@ typedef struct dsl_pool {
 	kcondvar_t dp_spaceavail_cv;
 	uint64_t dp_dirty_pertxg[TXG_SIZE];
 	uint64_t dp_dirty_total;
+	uint64_t dp_long_free_dirty_pertxg[TXG_SIZE];
 	uint64_t dp_mos_used_delta;
 	uint64_t dp_mos_compressed_delta;
 	uint64_t dp_mos_uncompressed_delta;
diff --git a/sys/cddl/dev/fbt/arm/fbt_isa.c b/sys/cddl/dev/fbt/arm/fbt_isa.c
index f1fae1ca66f..96dd13029d6 100644
--- a/sys/cddl/dev/fbt/arm/fbt_isa.c
+++ b/sys/cddl/dev/fbt/arm/fbt_isa.c
@@ -61,7 +61,7 @@ fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval)
 
 			/* Get 5th parameter from stack */
 			DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
-			fifthparam = *(register_t *)frame->tf_usr_sp;
+			fifthparam = *(register_t *)frame->tf_svc_sp;
 			DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT | CPU_DTRACE_BADADDR);
 
 			dtrace_probe(fbt->fbtp_id, frame->tf_r0,
diff --git a/sys/compat/cloudabi/cloudabi_file.c b/sys/compat/cloudabi/cloudabi_file.c
index f48b7541da7..f5417e0bb3a 100644
--- a/sys/compat/cloudabi/cloudabi_file.c
+++ b/sys/compat/cloudabi/cloudabi_file.c
@@ -146,7 +146,7 @@ cloudabi_sys_file_create(struct thread *td,
 	char *path;
 	int error;
 
-	error = copyin_path(uap->path, uap->pathlen, &path);
+	error = copyin_path(uap->path, uap->path_len, &path);
 	if (error != 0)
 		return (error);
 
@@ -177,10 +177,10 @@ cloudabi_sys_file_link(struct thread *td,
 	char *path1, *path2;
 	int error;
 
-	error = copyin_path(uap->path1, uap->path1len, &path1);
+	error = copyin_path(uap->path1, uap->path1_len, &path1);
 	if (error != 0)
 		return (error);
-	error = copyin_path(uap->path2, uap->path2len, &path2);
+	error = copyin_path(uap->path2, uap->path2_len, &path2);
 	if (error != 0) {
 		cloudabi_freestr(path1);
 		return (error);
@@ -261,7 +261,7 @@ cloudabi_sys_file_open(struct thread *td,
 	fp->f_flag = fflags & FMASK;
 
 	/* Open path. */
-	error = copyin_path(uap->path, uap->pathlen, &path);
+	error = copyin_path(uap->path, uap->path_len, &path);
 	if (error != 0) {
 		fdrop(fp, td);
 		return (error);
@@ -380,7 +380,7 @@ cloudabi_sys_file_readdir(struct thread *td,
 {
 	struct iovec iov = {
 		.iov_base = uap->buf,
-		.iov_len = uap->nbyte
+		.iov_len = uap->buf_len
 	};
 	struct uio uio = {
 		.uio_iov = &iov,
@@ -494,7 +494,7 @@ done:
 		return (error);
 
 	/* Return number of bytes copied to userspace. */
-	td->td_retval[0] = uap->nbyte - uio.uio_resid;
+	td->td_retval[0] = uap->buf_len - uio.uio_resid;
 	return (0);
 }
 
@@ -505,12 +505,12 @@ cloudabi_sys_file_readlink(struct thread *td,
 	char *path;
 	int error;
 
-	error = copyin_path(uap->path, uap->pathlen, &path);
+	error = copyin_path(uap->path, uap->path_len, &path);
 	if (error != 0)
 		return (error);
 
 	error = kern_readlinkat(td, uap->fd, path, UIO_SYSSPACE,
-	    uap->buf, UIO_USERSPACE, uap->bufsize);
+	    uap->buf, UIO_USERSPACE, uap->buf_len);
 	cloudabi_freestr(path);
 	return (error);
 }
@@ -522,16 +522,16 @@ cloudabi_sys_file_rename(struct thread *td,
 	char *old, *new;
 	int error;
 
-	error = copyin_path(uap->old, uap->oldlen, &old);
+	error = copyin_path(uap->path1, uap->path1_len, &old);
 	if (error != 0)
 		return (error);
-	error = copyin_path(uap->new, uap->newlen, &new);
+	error = copyin_path(uap->path2, uap->path2_len, &new);
 	if (error != 0) {
 		cloudabi_freestr(old);
 		return (error);
 	}
 
-	error = kern_renameat(td, uap->oldfd, old, uap->newfd, new,
+	error = kern_renameat(td, uap->fd1, old, uap->fd2, new,
 	    UIO_SYSSPACE);
 	cloudabi_freestr(old);
 	cloudabi_freestr(new);
@@ -653,7 +653,7 @@ cloudabi_sys_file_stat_get(struct thread *td,
 	char *path;
 	int error;
 
-	error = copyin_path(uap->path, uap->pathlen, &path);
+	error = copyin_path(uap->path, uap->path_len, &path);
 	if (error != 0)
 		return (error);
 
@@ -707,7 +707,7 @@ cloudabi_sys_file_stat_put(struct thread *td,
 	error = copyin(uap->buf, &fs, sizeof(fs));
 	if (error != 0)
 		return (error);
-	error = copyin_path(uap->path, uap->pathlen, &path);
+	error = copyin_path(uap->path, uap->path_len, &path);
 	if (error != 0)
 		return (error);
 
@@ -726,10 +726,10 @@ cloudabi_sys_file_symlink(struct thread *td,
 	char *path1, *path2;
 	int error;
 
-	error = copyin_path(uap->path1, uap->path1len, &path1);
+	error = copyin_path(uap->path1, uap->path1_len, &path1);
 	if (error != 0)
 		return (error);
-	error = copyin_path(uap->path2, uap->path2len, &path2);
+	error = copyin_path(uap->path2, uap->path2_len, &path2);
 	if (error != 0) {
 		cloudabi_freestr(path1);
 		return (error);
@@ -748,7 +748,7 @@ cloudabi_sys_file_unlink(struct thread *td,
 	char *path;
 	int error;
 
-	error = copyin_path(uap->path, uap->pathlen, &path);
+	error = copyin_path(uap->path, uap->path_len, &path);
 	if (error != 0)
 		return (error);
 
diff --git a/sys/compat/cloudabi/cloudabi_mem.c b/sys/compat/cloudabi/cloudabi_mem.c
index 34ee14ab223..55685284fa9 100644
--- a/sys/compat/cloudabi/cloudabi_mem.c
+++ b/sys/compat/cloudabi/cloudabi_mem.c
@@ -63,8 +63,8 @@ cloudabi_sys_mem_advise(struct thread *td,
     struct cloudabi_sys_mem_advise_args *uap)
 {
 	struct madvise_args madvise_args = {
-		.addr	= uap->addr,
-		.len	= uap->len
+		.addr	= uap->mapping,
+		.len	= uap->mapping_len
 	};
 
 	switch (uap->advice) {
@@ -94,8 +94,8 @@ int
 cloudabi_sys_mem_lock(struct thread *td, struct cloudabi_sys_mem_lock_args *uap)
 {
 	struct mlock_args mlock_args = {
-		.addr	= uap->addr,
-		.len	= uap->len
+		.addr	= uap->mapping,
+		.len	= uap->mapping_len
 	};
 
 	return (sys_mlock(td, &mlock_args));
@@ -135,8 +135,8 @@ cloudabi_sys_mem_protect(struct thread *td,
     struct cloudabi_sys_mem_protect_args *uap)
 {
 	struct mprotect_args mprotect_args = {
-		.addr	= uap->addr,
-		.len	= uap->len,
+		.addr	= uap->mapping,
+		.len	= uap->mapping_len,
 	};
 	int error;
 
@@ -152,8 +152,8 @@ int
 cloudabi_sys_mem_sync(struct thread *td, struct cloudabi_sys_mem_sync_args *uap)
 {
 	struct msync_args msync_args = {
-		.addr	= uap->addr,
-		.len	= uap->len,
+		.addr	= uap->mapping,
+		.len	= uap->mapping_len,
 	};
 
 	/* Convert flags. */
@@ -178,8 +178,8 @@ cloudabi_sys_mem_unlock(struct thread *td,
     struct cloudabi_sys_mem_unlock_args *uap)
 {
 	struct munlock_args munlock_args = {
-		.addr	= uap->addr,
-		.len	= uap->len
+		.addr	= uap->mapping,
+		.len	= uap->mapping_len
 	};
 
 	return (sys_munlock(td, &munlock_args));
@@ -190,8 +190,8 @@ cloudabi_sys_mem_unmap(struct thread *td,
     struct cloudabi_sys_mem_unmap_args *uap)
 {
 	struct munmap_args munmap_args = {
-		.addr	= uap->addr,
-		.len	= uap->len
+		.addr	= uap->mapping,
+		.len	= uap->mapping_len
 	};
 
 	return (sys_munmap(td, &munmap_args));
diff --git a/sys/compat/cloudabi/cloudabi_proc.c b/sys/compat/cloudabi/cloudabi_proc.c
index 139af2cfc73..24333311d38 100644
--- a/sys/compat/cloudabi/cloudabi_proc.c
+++ b/sys/compat/cloudabi/cloudabi_proc.c
@@ -53,8 +53,8 @@ cloudabi_sys_proc_exec(struct thread *td,
 	error = pre_execve(td, &oldvmspace);
 	if (error != 0)
 		return (error);
-	error = exec_copyin_data_fds(td, &args, uap->data, uap->datalen,
-	    uap->fds, uap->fdslen);
+	error = exec_copyin_data_fds(td, &args, uap->data, uap->data_len,
+	    uap->fds, uap->fds_len);
 	if (error == 0) {
 		args.fd = uap->fd;
 		error = kern_execve(td, &args, NULL);
diff --git a/sys/compat/cloudabi/cloudabi_random.c b/sys/compat/cloudabi/cloudabi_random.c
index 76a93604d29..02a3252a1b5 100644
--- a/sys/compat/cloudabi/cloudabi_random.c
+++ b/sys/compat/cloudabi/cloudabi_random.c
@@ -38,7 +38,7 @@ cloudabi_sys_random_get(struct thread *td,
 {
 	struct iovec iov = {
 		.iov_base = uap->buf,
-		.iov_len = uap->nbyte
+		.iov_len = uap->buf_len
 	};
 	struct uio uio = {
 		.uio_iov = &iov,
diff --git a/sys/compat/cloudabi/cloudabi_sock.c b/sys/compat/cloudabi/cloudabi_sock.c
index c66e2096f5b..8605b18353f 100644
--- a/sys/compat/cloudabi/cloudabi_sock.c
+++ b/sys/compat/cloudabi/cloudabi_sock.c
@@ -141,7 +141,7 @@ cloudabi_sys_sock_bind(struct thread *td,
 	struct sockaddr_un sun;
 	int error;
 
-	error = copyin_sockaddr_un(uap->path, uap->pathlen, &sun);
+	error = copyin_sockaddr_un(uap->path, uap->path_len, &sun);
 	if (error != 0)
 		return (error);
 	return (kern_bindat(td, uap->fd, uap->sock, (struct sockaddr *)&sun));
@@ -154,7 +154,7 @@ cloudabi_sys_sock_connect(struct thread *td,
 	struct sockaddr_un sun;
 	int error;
 
-	error = copyin_sockaddr_un(uap->path, uap->pathlen, &sun);
+	error = copyin_sockaddr_un(uap->path, uap->path_len, &sun);
 	if (error != 0)
 		return (error);
 	return (kern_connectat(td, uap->fd, uap->sock,
diff --git a/sys/compat/cloudabi32/cloudabi32_fd.c b/sys/compat/cloudabi32/cloudabi32_fd.c
index 1754c482c98..19907a95b07 100644
--- a/sys/compat/cloudabi32/cloudabi32_fd.c
+++ b/sys/compat/cloudabi32/cloudabi32_fd.c
@@ -71,8 +71,8 @@ cloudabi32_copyinuio(const cloudabi32_iovec_t *iovp, size_t iovcnt,
 			free(uio, M_IOV);
 			return (error);
 		}
-		iov[i].iov_base = TO_PTR(iovobj.iov_base);
-		iov[i].iov_len = iovobj.iov_len;
+		iov[i].iov_base = TO_PTR(iovobj.buf);
+		iov[i].iov_len = iovobj.buf_len;
 		if (iov[i].iov_len > INT32_MAX - uio->uio_resid) {
 			free(uio, M_IOV);
 			return (EINVAL);
@@ -91,7 +91,7 @@ cloudabi32_sys_fd_pread(struct thread *td,
 	struct uio *uio;
 	int error;
 
-	error = cloudabi32_copyinuio(uap->iov, uap->iovcnt, &uio);
+	error = cloudabi32_copyinuio(uap->iovs, uap->iovs_len, &uio);
 	if (error != 0)
 		return (error);
 	error = kern_preadv(td, uap->fd, uio, uap->offset);
@@ -106,7 +106,7 @@ cloudabi32_sys_fd_pwrite(struct thread *td,
 	struct uio *uio;
 	int error;
 
-	error = cloudabi32_copyinuio(TO_PTR(uap->iov), uap->iovcnt, &uio);
+	error = cloudabi32_copyinuio(TO_PTR(uap->iovs), uap->iovs_len, &uio);
 	if (error != 0)
 		return (error);
 	error = kern_pwritev(td, uap->fd, uio, uap->offset);
@@ -121,7 +121,7 @@ cloudabi32_sys_fd_read(struct thread *td,
 	struct uio *uio;
 	int error;
 
-	error = cloudabi32_copyinuio(uap->iov, uap->iovcnt, &uio);
+	error = cloudabi32_copyinuio(uap->iovs, uap->iovs_len, &uio);
 	if (error != 0)
 		return (error);
 	error = kern_readv(td, uap->fd, uio);
@@ -136,7 +136,7 @@ cloudabi32_sys_fd_write(struct thread *td,
 	struct uio *uio;
 	int error;
 
-	error = cloudabi32_copyinuio(TO_PTR(uap->iov), uap->iovcnt, &uio);
+	error = cloudabi32_copyinuio(TO_PTR(uap->iovs), uap->iovs_len, &uio);
 	if (error != 0)
 		return (error);
 	error = kern_writev(td, uap->fd, uio);
diff --git a/sys/compat/cloudabi32/cloudabi32_poll.c b/sys/compat/cloudabi32/cloudabi32_poll.c
index 5215580df49..dfffdc6c97e 100644
--- a/sys/compat/cloudabi32/cloudabi32_poll.c
+++ b/sys/compat/cloudabi32/cloudabi32_poll.c
@@ -398,11 +398,11 @@ cloudabi32_sys_poll_fd(struct thread *td,
 			return (EINVAL);
 		timeout.tv_sec = subtimo.clock.timeout / 1000000000;
 		timeout.tv_nsec = subtimo.clock.timeout % 1000000000;
-		return (kern_kevent(td, uap->fd, uap->nin, uap->nout, ©ops,
-		    &timeout));
+		return (kern_kevent(td, uap->fd, uap->in_len, uap->out_len,
+		    ©ops, &timeout));
 	} else {
 		/* Poll without a timeout. */
-		return (kern_kevent(td, uap->fd, uap->nin, uap->nout, ©ops,
-		    NULL));
+		return (kern_kevent(td, uap->fd, uap->in_len, uap->out_len,
+		    ©ops, NULL));
 	}
 }
diff --git a/sys/compat/cloudabi32/cloudabi32_proto.h b/sys/compat/cloudabi32/cloudabi32_proto.h
index 3f028d5f030..ca03f67b41d 100644
--- a/sys/compat/cloudabi32/cloudabi32_proto.h
+++ b/sys/compat/cloudabi32/cloudabi32_proto.h
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/contrib/cloudabi/syscalls32.master 304563 2016-08-21 15:56:19Z ed 
+ * created from FreeBSD: head/sys/contrib/cloudabi/syscalls32.master 312353 2017-01-17 22:03:08Z ed
  */
 
 #ifndef _CLOUDABI32_SYSPROTO_H_
@@ -63,20 +63,20 @@ struct cloudabi_sys_fd_dup_args {
 };
 struct cloudabi32_sys_fd_pread_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
-	char iov_l_[PADL_(const cloudabi32_iovec_t *)]; const cloudabi32_iovec_t * iov; char iov_r_[PADR_(const cloudabi32_iovec_t *)];
-	char iovcnt_l_[PADL_(size_t)]; size_t iovcnt; char iovcnt_r_[PADR_(size_t)];
+	char iovs_l_[PADL_(const cloudabi32_iovec_t *)]; const cloudabi32_iovec_t * iovs; char iovs_r_[PADR_(const cloudabi32_iovec_t *)];
+	char iovs_len_l_[PADL_(size_t)]; size_t iovs_len; char iovs_len_r_[PADR_(size_t)];
 	char offset_l_[PADL_(cloudabi_filesize_t)]; cloudabi_filesize_t offset; char offset_r_[PADR_(cloudabi_filesize_t)];
 };
 struct cloudabi32_sys_fd_pwrite_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
-	char iov_l_[PADL_(const cloudabi32_ciovec_t *)]; const cloudabi32_ciovec_t * iov; char iov_r_[PADR_(const cloudabi32_ciovec_t *)];
-	char iovcnt_l_[PADL_(size_t)]; size_t iovcnt; char iovcnt_r_[PADR_(size_t)];
+	char iovs_l_[PADL_(const cloudabi32_ciovec_t *)]; const cloudabi32_ciovec_t * iovs; char iovs_r_[PADR_(const cloudabi32_ciovec_t *)];
+	char iovs_len_l_[PADL_(size_t)]; size_t iovs_len; char iovs_len_r_[PADR_(size_t)];
 	char offset_l_[PADL_(cloudabi_filesize_t)]; cloudabi_filesize_t offset; char offset_r_[PADR_(cloudabi_filesize_t)];
 };
 struct cloudabi32_sys_fd_read_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
-	char iov_l_[PADL_(const cloudabi32_iovec_t *)]; const cloudabi32_iovec_t * iov; char iov_r_[PADR_(const cloudabi32_iovec_t *)];
-	char iovcnt_l_[PADL_(size_t)]; size_t iovcnt; char iovcnt_r_[PADR_(size_t)];
+	char iovs_l_[PADL_(const cloudabi32_iovec_t *)]; const cloudabi32_iovec_t * iovs; char iovs_r_[PADR_(const cloudabi32_iovec_t *)];
+	char iovs_len_l_[PADL_(size_t)]; size_t iovs_len; char iovs_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_fd_replace_args {
 	char from_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t from; char from_r_[PADR_(cloudabi_fd_t)];
@@ -101,8 +101,8 @@ struct cloudabi_sys_fd_sync_args {
 };
 struct cloudabi32_sys_fd_write_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
-	char iov_l_[PADL_(const cloudabi32_ciovec_t *)]; const cloudabi32_ciovec_t * iov; char iov_r_[PADR_(const cloudabi32_ciovec_t *)];
-	char iovcnt_l_[PADL_(size_t)]; size_t iovcnt; char iovcnt_r_[PADR_(size_t)];
+	char iovs_l_[PADL_(const cloudabi32_ciovec_t *)]; const cloudabi32_ciovec_t * iovs; char iovs_r_[PADR_(const cloudabi32_ciovec_t *)];
+	char iovs_len_l_[PADL_(size_t)]; size_t iovs_len; char iovs_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_file_advise_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
@@ -118,44 +118,44 @@ struct cloudabi_sys_file_allocate_args {
 struct cloudabi_sys_file_create_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 	char type_l_[PADL_(cloudabi_filetype_t)]; cloudabi_filetype_t type; char type_r_[PADR_(cloudabi_filetype_t)];
 };
 struct cloudabi_sys_file_link_args {
 	char fd1_l_[PADL_(cloudabi_lookup_t)]; cloudabi_lookup_t fd1; char fd1_r_[PADR_(cloudabi_lookup_t)];
 	char path1_l_[PADL_(const char *)]; const char * path1; char path1_r_[PADR_(const char *)];
-	char path1len_l_[PADL_(size_t)]; size_t path1len; char path1len_r_[PADR_(size_t)];
+	char path1_len_l_[PADL_(size_t)]; size_t path1_len; char path1_len_r_[PADR_(size_t)];
 	char fd2_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd2; char fd2_r_[PADR_(cloudabi_fd_t)];
 	char path2_l_[PADL_(const char *)]; const char * path2; char path2_r_[PADR_(const char *)];
-	char path2len_l_[PADL_(size_t)]; size_t path2len; char path2len_r_[PADR_(size_t)];
+	char path2_len_l_[PADL_(size_t)]; size_t path2_len; char path2_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_file_open_args {
 	char dirfd_l_[PADL_(cloudabi_lookup_t)]; cloudabi_lookup_t dirfd; char dirfd_r_[PADR_(cloudabi_lookup_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 	char oflags_l_[PADL_(cloudabi_oflags_t)]; cloudabi_oflags_t oflags; char oflags_r_[PADR_(cloudabi_oflags_t)];
 	char fds_l_[PADL_(const cloudabi_fdstat_t *)]; const cloudabi_fdstat_t * fds; char fds_r_[PADR_(const cloudabi_fdstat_t *)];
 };
 struct cloudabi_sys_file_readdir_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char buf_l_[PADL_(void *)]; void * buf; char buf_r_[PADR_(void *)];
-	char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
+	char buf_len_l_[PADL_(size_t)]; size_t buf_len; char buf_len_r_[PADR_(size_t)];
 	char cookie_l_[PADL_(cloudabi_dircookie_t)]; cloudabi_dircookie_t cookie; char cookie_r_[PADR_(cloudabi_dircookie_t)];
 };
 struct cloudabi_sys_file_readlink_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 	char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
-	char bufsize_l_[PADL_(size_t)]; size_t bufsize; char bufsize_r_[PADR_(size_t)];
+	char buf_len_l_[PADL_(size_t)]; size_t buf_len; char buf_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_file_rename_args {
-	char oldfd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t oldfd; char oldfd_r_[PADR_(cloudabi_fd_t)];
-	char old_l_[PADL_(const char *)]; const char * old; char old_r_[PADR_(const char *)];
-	char oldlen_l_[PADL_(size_t)]; size_t oldlen; char oldlen_r_[PADR_(size_t)];
-	char newfd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t newfd; char newfd_r_[PADR_(cloudabi_fd_t)];
-	char new_l_[PADL_(const char *)]; const char * new; char new_r_[PADR_(const char *)];
-	char newlen_l_[PADL_(size_t)]; size_t newlen; char newlen_r_[PADR_(size_t)];
+	char fd1_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd1; char fd1_r_[PADR_(cloudabi_fd_t)];
+	char path1_l_[PADL_(const char *)]; const char * path1; char path1_r_[PADR_(const char *)];
+	char path1_len_l_[PADL_(size_t)]; size_t path1_len; char path1_len_r_[PADR_(size_t)];
+	char fd2_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd2; char fd2_r_[PADR_(cloudabi_fd_t)];
+	char path2_l_[PADL_(const char *)]; const char * path2; char path2_r_[PADR_(const char *)];
+	char path2_len_l_[PADL_(size_t)]; size_t path2_len; char path2_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_file_stat_fget_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
@@ -169,27 +169,27 @@ struct cloudabi_sys_file_stat_fput_args {
 struct cloudabi_sys_file_stat_get_args {
 	char fd_l_[PADL_(cloudabi_lookup_t)]; cloudabi_lookup_t fd; char fd_r_[PADR_(cloudabi_lookup_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 	char buf_l_[PADL_(cloudabi_filestat_t *)]; cloudabi_filestat_t * buf; char buf_r_[PADR_(cloudabi_filestat_t *)];
 };
 struct cloudabi_sys_file_stat_put_args {
 	char fd_l_[PADL_(cloudabi_lookup_t)]; cloudabi_lookup_t fd; char fd_r_[PADR_(cloudabi_lookup_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 	char buf_l_[PADL_(const cloudabi_filestat_t *)]; const cloudabi_filestat_t * buf; char buf_r_[PADR_(const cloudabi_filestat_t *)];
 	char flags_l_[PADL_(cloudabi_fsflags_t)]; cloudabi_fsflags_t flags; char flags_r_[PADR_(cloudabi_fsflags_t)];
 };
 struct cloudabi_sys_file_symlink_args {
 	char path1_l_[PADL_(const char *)]; const char * path1; char path1_r_[PADR_(const char *)];
-	char path1len_l_[PADL_(size_t)]; size_t path1len; char path1len_r_[PADR_(size_t)];
+	char path1_len_l_[PADL_(size_t)]; size_t path1_len; char path1_len_r_[PADR_(size_t)];
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char path2_l_[PADL_(const char *)]; const char * path2; char path2_r_[PADR_(const char *)];
-	char path2len_l_[PADL_(size_t)]; size_t path2len; char path2len_r_[PADR_(size_t)];
+	char path2_len_l_[PADL_(size_t)]; size_t path2_len; char path2_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_file_unlink_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 	char flags_l_[PADL_(cloudabi_ulflags_t)]; cloudabi_ulflags_t flags; char flags_r_[PADR_(cloudabi_ulflags_t)];
 };
 struct cloudabi_sys_lock_unlock_args {
@@ -197,13 +197,13 @@ struct cloudabi_sys_lock_unlock_args {
 	char scope_l_[PADL_(cloudabi_scope_t)]; cloudabi_scope_t scope; char scope_r_[PADR_(cloudabi_scope_t)];
 };
 struct cloudabi_sys_mem_advise_args {
-	char addr_l_[PADL_(void *)]; void * addr; char addr_r_[PADR_(void *)];
-	char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
+	char mapping_l_[PADL_(void *)]; void * mapping; char mapping_r_[PADR_(void *)];
+	char mapping_len_l_[PADL_(size_t)]; size_t mapping_len; char mapping_len_r_[PADR_(size_t)];
 	char advice_l_[PADL_(cloudabi_advice_t)]; cloudabi_advice_t advice; char advice_r_[PADR_(cloudabi_advice_t)];
 };
 struct cloudabi_sys_mem_lock_args {
-	char addr_l_[PADL_(const void *)]; const void * addr; char addr_r_[PADR_(const void *)];
-	char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
+	char mapping_l_[PADL_(const void *)]; const void * mapping; char mapping_r_[PADR_(const void *)];
+	char mapping_len_l_[PADL_(size_t)]; size_t mapping_len; char mapping_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_mem_map_args {
 	char addr_l_[PADL_(void *)]; void * addr; char addr_r_[PADR_(void *)];
@@ -214,22 +214,22 @@ struct cloudabi_sys_mem_map_args {
 	char off_l_[PADL_(cloudabi_filesize_t)]; cloudabi_filesize_t off; char off_r_[PADR_(cloudabi_filesize_t)];
 };
 struct cloudabi_sys_mem_protect_args {
-	char addr_l_[PADL_(void *)]; void * addr; char addr_r_[PADR_(void *)];
-	char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
+	char mapping_l_[PADL_(void *)]; void * mapping; char mapping_r_[PADR_(void *)];
+	char mapping_len_l_[PADL_(size_t)]; size_t mapping_len; char mapping_len_r_[PADR_(size_t)];
 	char prot_l_[PADL_(cloudabi_mprot_t)]; cloudabi_mprot_t prot; char prot_r_[PADR_(cloudabi_mprot_t)];
 };
 struct cloudabi_sys_mem_sync_args {
-	char addr_l_[PADL_(void *)]; void * addr; char addr_r_[PADR_(void *)];
-	char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
+	char mapping_l_[PADL_(void *)]; void * mapping; char mapping_r_[PADR_(void *)];
+	char mapping_len_l_[PADL_(size_t)]; size_t mapping_len; char mapping_len_r_[PADR_(size_t)];
 	char flags_l_[PADL_(cloudabi_msflags_t)]; cloudabi_msflags_t flags; char flags_r_[PADR_(cloudabi_msflags_t)];
 };
 struct cloudabi_sys_mem_unlock_args {
-	char addr_l_[PADL_(const void *)]; const void * addr; char addr_r_[PADR_(const void *)];
-	char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
+	char mapping_l_[PADL_(const void *)]; const void * mapping; char mapping_r_[PADR_(const void *)];
+	char mapping_len_l_[PADL_(size_t)]; size_t mapping_len; char mapping_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_mem_unmap_args {
-	char addr_l_[PADL_(void *)]; void * addr; char addr_r_[PADR_(void *)];
-	char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
+	char mapping_l_[PADL_(void *)]; void * mapping; char mapping_r_[PADR_(void *)];
+	char mapping_len_l_[PADL_(size_t)]; size_t mapping_len; char mapping_len_r_[PADR_(size_t)];
 };
 struct cloudabi32_sys_poll_args {
 	char in_l_[PADL_(const cloudabi32_subscription_t *)]; const cloudabi32_subscription_t * in; char in_r_[PADR_(const cloudabi32_subscription_t *)];
@@ -239,17 +239,17 @@ struct cloudabi32_sys_poll_args {
 struct cloudabi32_sys_poll_fd_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char in_l_[PADL_(const cloudabi32_subscription_t *)]; const cloudabi32_subscription_t * in; char in_r_[PADR_(const cloudabi32_subscription_t *)];
-	char nin_l_[PADL_(size_t)]; size_t nin; char nin_r_[PADR_(size_t)];
+	char in_len_l_[PADL_(size_t)]; size_t in_len; char in_len_r_[PADR_(size_t)];
 	char out_l_[PADL_(cloudabi32_event_t *)]; cloudabi32_event_t * out; char out_r_[PADR_(cloudabi32_event_t *)];
-	char nout_l_[PADL_(size_t)]; size_t nout; char nout_r_[PADR_(size_t)];
+	char out_len_l_[PADL_(size_t)]; size_t out_len; char out_len_r_[PADR_(size_t)];
 	char timeout_l_[PADL_(const cloudabi32_subscription_t *)]; const cloudabi32_subscription_t * timeout; char timeout_r_[PADR_(const cloudabi32_subscription_t *)];
 };
 struct cloudabi_sys_proc_exec_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char data_l_[PADL_(const void *)]; const void * data; char data_r_[PADR_(const void *)];
-	char datalen_l_[PADL_(size_t)]; size_t datalen; char datalen_r_[PADR_(size_t)];
+	char data_len_l_[PADL_(size_t)]; size_t data_len; char data_len_r_[PADR_(size_t)];
 	char fds_l_[PADL_(const cloudabi_fd_t *)]; const cloudabi_fd_t * fds; char fds_r_[PADR_(const cloudabi_fd_t *)];
-	char fdslen_l_[PADL_(size_t)]; size_t fdslen; char fdslen_r_[PADR_(size_t)];
+	char fds_len_l_[PADL_(size_t)]; size_t fds_len; char fds_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_proc_exit_args {
 	char rval_l_[PADL_(cloudabi_exitcode_t)]; cloudabi_exitcode_t rval; char rval_r_[PADR_(cloudabi_exitcode_t)];
@@ -262,7 +262,7 @@ struct cloudabi_sys_proc_raise_args {
 };
 struct cloudabi_sys_random_get_args {
 	char buf_l_[PADL_(void *)]; void * buf; char buf_r_[PADR_(void *)];
-	char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
+	char buf_len_l_[PADL_(size_t)]; size_t buf_len; char buf_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_sock_accept_args {
 	char sock_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t sock; char sock_r_[PADR_(cloudabi_fd_t)];
@@ -272,13 +272,13 @@ struct cloudabi_sys_sock_bind_args {
 	char sock_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t sock; char sock_r_[PADR_(cloudabi_fd_t)];
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_sock_connect_args {
 	char sock_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t sock; char sock_r_[PADR_(cloudabi_fd_t)];
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_sock_listen_args {
 	char sock_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t sock; char sock_r_[PADR_(cloudabi_fd_t)];
diff --git a/sys/compat/cloudabi32/cloudabi32_sock.c b/sys/compat/cloudabi32/cloudabi32_sock.c
index 24ed32c2606..756c247f9e2 100644
--- a/sys/compat/cloudabi32/cloudabi32_sock.c
+++ b/sys/compat/cloudabi32/cloudabi32_sock.c
@@ -62,9 +62,9 @@ cloudabi32_sys_sock_recv(struct thread *td,
 		return (error);
 
 	/* Convert results in cloudabi_recv_in_t to struct msghdr. */
-	if (ri.ri_datalen > UIO_MAXIOV)
+	if (ri.ri_data_len > UIO_MAXIOV)
 		return (EINVAL);
-	msghdr.msg_iovlen = ri.ri_datalen;
+	msghdr.msg_iovlen = ri.ri_data_len;
 	msghdr.msg_iov = malloc(msghdr.msg_iovlen * sizeof(struct iovec),
 	    M_SOCKET, M_WAITOK);
 	user_iov = TO_PTR(ri.ri_data);
@@ -74,8 +74,8 @@ cloudabi32_sys_sock_recv(struct thread *td,
 			free(msghdr.msg_iov, M_SOCKET);
 			return (error);
 		}
-		msghdr.msg_iov[i].iov_base = TO_PTR(iovobj.iov_base);
-		msghdr.msg_iov[i].iov_len = iovobj.iov_len;
+		msghdr.msg_iov[i].iov_base = TO_PTR(iovobj.buf);
+		msghdr.msg_iov[i].iov_len = iovobj.buf_len;
 	}
 	msghdr.msg_name = &ss;
 	msghdr.msg_namelen = sizeof(ss);
@@ -115,9 +115,9 @@ cloudabi32_sys_sock_send(struct thread *td,
 		return (error);
 
 	/* Convert results in cloudabi_send_in_t to struct msghdr. */
-	if (si.si_datalen > UIO_MAXIOV)
+	if (si.si_data_len > UIO_MAXIOV)
 		return (EINVAL);
-	msghdr.msg_iovlen = si.si_datalen;
+	msghdr.msg_iovlen = si.si_data_len;
 	msghdr.msg_iov = malloc(msghdr.msg_iovlen * sizeof(struct iovec),
 	    M_SOCKET, M_WAITOK);
 	user_iov = TO_PTR(si.si_data);
@@ -127,8 +127,8 @@ cloudabi32_sys_sock_send(struct thread *td,
 			free(msghdr.msg_iov, M_SOCKET);
 			return (error);
 		}
-		msghdr.msg_iov[i].iov_base = TO_PTR(iovobj.iov_base);
-		msghdr.msg_iov[i].iov_len = iovobj.iov_len;
+		msghdr.msg_iov[i].iov_base = TO_PTR(iovobj.buf);
+		msghdr.msg_iov[i].iov_len = iovobj.buf_len;
 	}
 
 	flags = MSG_NOSIGNAL;
diff --git a/sys/compat/cloudabi32/cloudabi32_syscall.h b/sys/compat/cloudabi32/cloudabi32_syscall.h
index 4cba6fde4a1..3ec07f13b7d 100644
--- a/sys/compat/cloudabi32/cloudabi32_syscall.h
+++ b/sys/compat/cloudabi32/cloudabi32_syscall.h
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/contrib/cloudabi/syscalls32.master 304563 2016-08-21 15:56:19Z ed 
+ * created from FreeBSD: head/sys/contrib/cloudabi/syscalls32.master 312353 2017-01-17 22:03:08Z ed
  */
 
 #define	CLOUDABI32_SYS_cloudabi_sys_clock_res_get	0
diff --git a/sys/compat/cloudabi32/cloudabi32_syscalls.c b/sys/compat/cloudabi32/cloudabi32_syscalls.c
index 56a46fb5ed1..c24ad817e55 100644
--- a/sys/compat/cloudabi32/cloudabi32_syscalls.c
+++ b/sys/compat/cloudabi32/cloudabi32_syscalls.c
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/contrib/cloudabi/syscalls32.master 304563 2016-08-21 15:56:19Z ed 
+ * created from FreeBSD: head/sys/contrib/cloudabi/syscalls32.master 312353 2017-01-17 22:03:08Z ed
  */
 
 const char *cloudabi32_syscallnames[] = {
diff --git a/sys/compat/cloudabi32/cloudabi32_sysent.c b/sys/compat/cloudabi32/cloudabi32_sysent.c
index 187e38449ca..e2a67ae3bd1 100644
--- a/sys/compat/cloudabi32/cloudabi32_sysent.c
+++ b/sys/compat/cloudabi32/cloudabi32_sysent.c
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/contrib/cloudabi/syscalls32.master 304563 2016-08-21 15:56:19Z ed 
+ * created from FreeBSD: head/sys/contrib/cloudabi/syscalls32.master 312353 2017-01-17 22:03:08Z ed
  */
 
 #include 
diff --git a/sys/compat/cloudabi32/cloudabi32_systrace_args.c b/sys/compat/cloudabi32/cloudabi32_systrace_args.c
index 1b49a5d5eab..6d037bc70b0 100644
--- a/sys/compat/cloudabi32/cloudabi32_systrace_args.c
+++ b/sys/compat/cloudabi32/cloudabi32_systrace_args.c
@@ -74,8 +74,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	case 8: {
 		struct cloudabi32_sys_fd_pread_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
-		uarg[1] = (intptr_t) p->iov; /* const cloudabi32_iovec_t * */
-		uarg[2] = p->iovcnt; /* size_t */
+		uarg[1] = (intptr_t) p->iovs; /* const cloudabi32_iovec_t * */
+		uarg[2] = p->iovs_len; /* size_t */
 		iarg[3] = p->offset; /* cloudabi_filesize_t */
 		*n_args = 4;
 		break;
@@ -84,8 +84,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	case 9: {
 		struct cloudabi32_sys_fd_pwrite_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
-		uarg[1] = (intptr_t) p->iov; /* const cloudabi32_ciovec_t * */
-		uarg[2] = p->iovcnt; /* size_t */
+		uarg[1] = (intptr_t) p->iovs; /* const cloudabi32_ciovec_t * */
+		uarg[2] = p->iovs_len; /* size_t */
 		iarg[3] = p->offset; /* cloudabi_filesize_t */
 		*n_args = 4;
 		break;
@@ -94,8 +94,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	case 10: {
 		struct cloudabi32_sys_fd_read_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
-		uarg[1] = (intptr_t) p->iov; /* const cloudabi32_iovec_t * */
-		uarg[2] = p->iovcnt; /* size_t */
+		uarg[1] = (intptr_t) p->iovs; /* const cloudabi32_iovec_t * */
+		uarg[2] = p->iovs_len; /* size_t */
 		*n_args = 3;
 		break;
 	}
@@ -144,8 +144,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	case 16: {
 		struct cloudabi32_sys_fd_write_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
-		uarg[1] = (intptr_t) p->iov; /* const cloudabi32_ciovec_t * */
-		uarg[2] = p->iovcnt; /* size_t */
+		uarg[1] = (intptr_t) p->iovs; /* const cloudabi32_ciovec_t * */
+		uarg[2] = p->iovs_len; /* size_t */
 		*n_args = 3;
 		break;
 	}
@@ -173,7 +173,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_create_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
 		uarg[1] = (intptr_t) p->path; /* const char * */
-		uarg[2] = p->pathlen; /* size_t */
+		uarg[2] = p->path_len; /* size_t */
 		iarg[3] = p->type; /* cloudabi_filetype_t */
 		*n_args = 4;
 		break;
@@ -183,10 +183,10 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_link_args *p = params;
 		iarg[0] = p->fd1; /* cloudabi_lookup_t */
 		uarg[1] = (intptr_t) p->path1; /* const char * */
-		uarg[2] = p->path1len; /* size_t */
+		uarg[2] = p->path1_len; /* size_t */
 		iarg[3] = p->fd2; /* cloudabi_fd_t */
 		uarg[4] = (intptr_t) p->path2; /* const char * */
-		uarg[5] = p->path2len; /* size_t */
+		uarg[5] = p->path2_len; /* size_t */
 		*n_args = 6;
 		break;
 	}
@@ -195,7 +195,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_open_args *p = params;
 		iarg[0] = p->dirfd; /* cloudabi_lookup_t */
 		uarg[1] = (intptr_t) p->path; /* const char * */
-		uarg[2] = p->pathlen; /* size_t */
+		uarg[2] = p->path_len; /* size_t */
 		iarg[3] = p->oflags; /* cloudabi_oflags_t */
 		uarg[4] = (intptr_t) p->fds; /* const cloudabi_fdstat_t * */
 		*n_args = 5;
@@ -206,7 +206,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_readdir_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
 		uarg[1] = (intptr_t) p->buf; /* void * */
-		uarg[2] = p->nbyte; /* size_t */
+		uarg[2] = p->buf_len; /* size_t */
 		iarg[3] = p->cookie; /* cloudabi_dircookie_t */
 		*n_args = 4;
 		break;
@@ -216,21 +216,21 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_readlink_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
 		uarg[1] = (intptr_t) p->path; /* const char * */
-		uarg[2] = p->pathlen; /* size_t */
+		uarg[2] = p->path_len; /* size_t */
 		uarg[3] = (intptr_t) p->buf; /* char * */
-		uarg[4] = p->bufsize; /* size_t */
+		uarg[4] = p->buf_len; /* size_t */
 		*n_args = 5;
 		break;
 	}
 	/* cloudabi_sys_file_rename */
 	case 24: {
 		struct cloudabi_sys_file_rename_args *p = params;
-		iarg[0] = p->oldfd; /* cloudabi_fd_t */
-		uarg[1] = (intptr_t) p->old; /* const char * */
-		uarg[2] = p->oldlen; /* size_t */
-		iarg[3] = p->newfd; /* cloudabi_fd_t */
-		uarg[4] = (intptr_t) p->new; /* const char * */
-		uarg[5] = p->newlen; /* size_t */
+		iarg[0] = p->fd1; /* cloudabi_fd_t */
+		uarg[1] = (intptr_t) p->path1; /* const char * */
+		uarg[2] = p->path1_len; /* size_t */
+		iarg[3] = p->fd2; /* cloudabi_fd_t */
+		uarg[4] = (intptr_t) p->path2; /* const char * */
+		uarg[5] = p->path2_len; /* size_t */
 		*n_args = 6;
 		break;
 	}
@@ -256,7 +256,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_stat_get_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_lookup_t */
 		uarg[1] = (intptr_t) p->path; /* const char * */
-		uarg[2] = p->pathlen; /* size_t */
+		uarg[2] = p->path_len; /* size_t */
 		uarg[3] = (intptr_t) p->buf; /* cloudabi_filestat_t * */
 		*n_args = 4;
 		break;
@@ -266,7 +266,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_stat_put_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_lookup_t */
 		uarg[1] = (intptr_t) p->path; /* const char * */
-		uarg[2] = p->pathlen; /* size_t */
+		uarg[2] = p->path_len; /* size_t */
 		uarg[3] = (intptr_t) p->buf; /* const cloudabi_filestat_t * */
 		iarg[4] = p->flags; /* cloudabi_fsflags_t */
 		*n_args = 5;
@@ -276,10 +276,10 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	case 29: {
 		struct cloudabi_sys_file_symlink_args *p = params;
 		uarg[0] = (intptr_t) p->path1; /* const char * */
-		uarg[1] = p->path1len; /* size_t */
+		uarg[1] = p->path1_len; /* size_t */
 		iarg[2] = p->fd; /* cloudabi_fd_t */
 		uarg[3] = (intptr_t) p->path2; /* const char * */
-		uarg[4] = p->path2len; /* size_t */
+		uarg[4] = p->path2_len; /* size_t */
 		*n_args = 5;
 		break;
 	}
@@ -288,7 +288,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_unlink_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
 		uarg[1] = (intptr_t) p->path; /* const char * */
-		uarg[2] = p->pathlen; /* size_t */
+		uarg[2] = p->path_len; /* size_t */
 		iarg[3] = p->flags; /* cloudabi_ulflags_t */
 		*n_args = 4;
 		break;
@@ -304,8 +304,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	/* cloudabi_sys_mem_advise */
 	case 32: {
 		struct cloudabi_sys_mem_advise_args *p = params;
-		uarg[0] = (intptr_t) p->addr; /* void * */
-		uarg[1] = p->len; /* size_t */
+		uarg[0] = (intptr_t) p->mapping; /* void * */
+		uarg[1] = p->mapping_len; /* size_t */
 		iarg[2] = p->advice; /* cloudabi_advice_t */
 		*n_args = 3;
 		break;
@@ -313,8 +313,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	/* cloudabi_sys_mem_lock */
 	case 33: {
 		struct cloudabi_sys_mem_lock_args *p = params;
-		uarg[0] = (intptr_t) p->addr; /* const void * */
-		uarg[1] = p->len; /* size_t */
+		uarg[0] = (intptr_t) p->mapping; /* const void * */
+		uarg[1] = p->mapping_len; /* size_t */
 		*n_args = 2;
 		break;
 	}
@@ -333,8 +333,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	/* cloudabi_sys_mem_protect */
 	case 35: {
 		struct cloudabi_sys_mem_protect_args *p = params;
-		uarg[0] = (intptr_t) p->addr; /* void * */
-		uarg[1] = p->len; /* size_t */
+		uarg[0] = (intptr_t) p->mapping; /* void * */
+		uarg[1] = p->mapping_len; /* size_t */
 		iarg[2] = p->prot; /* cloudabi_mprot_t */
 		*n_args = 3;
 		break;
@@ -342,8 +342,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	/* cloudabi_sys_mem_sync */
 	case 36: {
 		struct cloudabi_sys_mem_sync_args *p = params;
-		uarg[0] = (intptr_t) p->addr; /* void * */
-		uarg[1] = p->len; /* size_t */
+		uarg[0] = (intptr_t) p->mapping; /* void * */
+		uarg[1] = p->mapping_len; /* size_t */
 		iarg[2] = p->flags; /* cloudabi_msflags_t */
 		*n_args = 3;
 		break;
@@ -351,16 +351,16 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	/* cloudabi_sys_mem_unlock */
 	case 37: {
 		struct cloudabi_sys_mem_unlock_args *p = params;
-		uarg[0] = (intptr_t) p->addr; /* const void * */
-		uarg[1] = p->len; /* size_t */
+		uarg[0] = (intptr_t) p->mapping; /* const void * */
+		uarg[1] = p->mapping_len; /* size_t */
 		*n_args = 2;
 		break;
 	}
 	/* cloudabi_sys_mem_unmap */
 	case 38: {
 		struct cloudabi_sys_mem_unmap_args *p = params;
-		uarg[0] = (intptr_t) p->addr; /* void * */
-		uarg[1] = p->len; /* size_t */
+		uarg[0] = (intptr_t) p->mapping; /* void * */
+		uarg[1] = p->mapping_len; /* size_t */
 		*n_args = 2;
 		break;
 	}
@@ -378,9 +378,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi32_sys_poll_fd_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
 		uarg[1] = (intptr_t) p->in; /* const cloudabi32_subscription_t * */
-		uarg[2] = p->nin; /* size_t */
+		uarg[2] = p->in_len; /* size_t */
 		uarg[3] = (intptr_t) p->out; /* cloudabi32_event_t * */
-		uarg[4] = p->nout; /* size_t */
+		uarg[4] = p->out_len; /* size_t */
 		uarg[5] = (intptr_t) p->timeout; /* const cloudabi32_subscription_t * */
 		*n_args = 6;
 		break;
@@ -390,9 +390,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_proc_exec_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
 		uarg[1] = (intptr_t) p->data; /* const void * */
-		uarg[2] = p->datalen; /* size_t */
+		uarg[2] = p->data_len; /* size_t */
 		uarg[3] = (intptr_t) p->fds; /* const cloudabi_fd_t * */
-		uarg[4] = p->fdslen; /* size_t */
+		uarg[4] = p->fds_len; /* size_t */
 		*n_args = 5;
 		break;
 	}
@@ -419,7 +419,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	case 45: {
 		struct cloudabi_sys_random_get_args *p = params;
 		uarg[0] = (intptr_t) p->buf; /* void * */
-		uarg[1] = p->nbyte; /* size_t */
+		uarg[1] = p->buf_len; /* size_t */
 		*n_args = 2;
 		break;
 	}
@@ -437,7 +437,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		iarg[0] = p->sock; /* cloudabi_fd_t */
 		iarg[1] = p->fd; /* cloudabi_fd_t */
 		uarg[2] = (intptr_t) p->path; /* const char * */
-		uarg[3] = p->pathlen; /* size_t */
+		uarg[3] = p->path_len; /* size_t */
 		*n_args = 4;
 		break;
 	}
@@ -447,7 +447,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		iarg[0] = p->sock; /* cloudabi_fd_t */
 		iarg[1] = p->fd; /* cloudabi_fd_t */
 		uarg[2] = (intptr_t) p->path; /* const char * */
-		uarg[3] = p->pathlen; /* size_t */
+		uarg[3] = p->path_len; /* size_t */
 		*n_args = 4;
 		break;
 	}
diff --git a/sys/compat/cloudabi32/cloudabi32_thread.c b/sys/compat/cloudabi32/cloudabi32_thread.c
index 50538d971f0..233700b40f1 100644
--- a/sys/compat/cloudabi32/cloudabi32_thread.c
+++ b/sys/compat/cloudabi32/cloudabi32_thread.c
@@ -65,9 +65,9 @@ cloudabi32_sys_thread_create(struct thread *td,
 		return (error);
 
 	/* Remove some space on the top of the stack for the TCB. */
-	args.tcb = rounddown(args.attr.stack + args.attr.stack_size -
+	args.tcb = rounddown(args.attr.stack + args.attr.stack_len -
 	    sizeof(cloudabi32_tcb_t), _Alignof(cloudabi32_tcb_t));
-	args.attr.stack_size = args.tcb - args.attr.stack;
+	args.attr.stack_len = args.tcb - args.attr.stack;
 
 	error = thread_create(td, NULL, initialize_thread, &args);
 	if (error != 0)
diff --git a/sys/compat/cloudabi64/cloudabi64_fd.c b/sys/compat/cloudabi64/cloudabi64_fd.c
index fcfcc42025e..ea403cf3559 100644
--- a/sys/compat/cloudabi64/cloudabi64_fd.c
+++ b/sys/compat/cloudabi64/cloudabi64_fd.c
@@ -71,8 +71,8 @@ cloudabi64_copyinuio(const cloudabi64_iovec_t *iovp, size_t iovcnt,
 			free(uio, M_IOV);
 			return (error);
 		}
-		iov[i].iov_base = TO_PTR(iovobj.iov_base);
-		iov[i].iov_len = iovobj.iov_len;
+		iov[i].iov_base = TO_PTR(iovobj.buf);
+		iov[i].iov_len = iovobj.buf_len;
 		if (iov[i].iov_len > INT64_MAX - uio->uio_resid) {
 			free(uio, M_IOV);
 			return (EINVAL);
@@ -91,7 +91,7 @@ cloudabi64_sys_fd_pread(struct thread *td,
 	struct uio *uio;
 	int error;
 
-	error = cloudabi64_copyinuio(uap->iov, uap->iovcnt, &uio);
+	error = cloudabi64_copyinuio(uap->iovs, uap->iovs_len, &uio);
 	if (error != 0)
 		return (error);
 	error = kern_preadv(td, uap->fd, uio, uap->offset);
@@ -106,7 +106,7 @@ cloudabi64_sys_fd_pwrite(struct thread *td,
 	struct uio *uio;
 	int error;
 
-	error = cloudabi64_copyinuio(TO_PTR(uap->iov), uap->iovcnt, &uio);
+	error = cloudabi64_copyinuio(TO_PTR(uap->iovs), uap->iovs_len, &uio);
 	if (error != 0)
 		return (error);
 	error = kern_pwritev(td, uap->fd, uio, uap->offset);
@@ -121,7 +121,7 @@ cloudabi64_sys_fd_read(struct thread *td,
 	struct uio *uio;
 	int error;
 
-	error = cloudabi64_copyinuio(uap->iov, uap->iovcnt, &uio);
+	error = cloudabi64_copyinuio(uap->iovs, uap->iovs_len, &uio);
 	if (error != 0)
 		return (error);
 	error = kern_readv(td, uap->fd, uio);
@@ -136,7 +136,7 @@ cloudabi64_sys_fd_write(struct thread *td,
 	struct uio *uio;
 	int error;
 
-	error = cloudabi64_copyinuio(TO_PTR(uap->iov), uap->iovcnt, &uio);
+	error = cloudabi64_copyinuio(TO_PTR(uap->iovs), uap->iovs_len, &uio);
 	if (error != 0)
 		return (error);
 	error = kern_writev(td, uap->fd, uio);
diff --git a/sys/compat/cloudabi64/cloudabi64_poll.c b/sys/compat/cloudabi64/cloudabi64_poll.c
index 63d8120b63e..3df52659893 100644
--- a/sys/compat/cloudabi64/cloudabi64_poll.c
+++ b/sys/compat/cloudabi64/cloudabi64_poll.c
@@ -398,11 +398,11 @@ cloudabi64_sys_poll_fd(struct thread *td,
 			return (EINVAL);
 		timeout.tv_sec = subtimo.clock.timeout / 1000000000;
 		timeout.tv_nsec = subtimo.clock.timeout % 1000000000;
-		return (kern_kevent(td, uap->fd, uap->nin, uap->nout, ©ops,
-		    &timeout));
+		return (kern_kevent(td, uap->fd, uap->in_len, uap->out_len,
+		    ©ops, &timeout));
 	} else {
 		/* Poll without a timeout. */
-		return (kern_kevent(td, uap->fd, uap->nin, uap->nout, ©ops,
-		    NULL));
+		return (kern_kevent(td, uap->fd, uap->in_len, uap->out_len,
+		    ©ops, NULL));
 	}
 }
diff --git a/sys/compat/cloudabi64/cloudabi64_proto.h b/sys/compat/cloudabi64/cloudabi64_proto.h
index aed44adae70..40c3a530088 100644
--- a/sys/compat/cloudabi64/cloudabi64_proto.h
+++ b/sys/compat/cloudabi64/cloudabi64_proto.h
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/contrib/cloudabi/syscalls64.master 304483 2016-08-19 17:53:37Z ed 
+ * created from FreeBSD: head/sys/contrib/cloudabi/syscalls64.master 312353 2017-01-17 22:03:08Z ed
  */
 
 #ifndef _CLOUDABI64_SYSPROTO_H_
@@ -63,20 +63,20 @@ struct cloudabi_sys_fd_dup_args {
 };
 struct cloudabi64_sys_fd_pread_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
-	char iov_l_[PADL_(const cloudabi64_iovec_t *)]; const cloudabi64_iovec_t * iov; char iov_r_[PADR_(const cloudabi64_iovec_t *)];
-	char iovcnt_l_[PADL_(size_t)]; size_t iovcnt; char iovcnt_r_[PADR_(size_t)];
+	char iovs_l_[PADL_(const cloudabi64_iovec_t *)]; const cloudabi64_iovec_t * iovs; char iovs_r_[PADR_(const cloudabi64_iovec_t *)];
+	char iovs_len_l_[PADL_(size_t)]; size_t iovs_len; char iovs_len_r_[PADR_(size_t)];
 	char offset_l_[PADL_(cloudabi_filesize_t)]; cloudabi_filesize_t offset; char offset_r_[PADR_(cloudabi_filesize_t)];
 };
 struct cloudabi64_sys_fd_pwrite_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
-	char iov_l_[PADL_(const cloudabi64_ciovec_t *)]; const cloudabi64_ciovec_t * iov; char iov_r_[PADR_(const cloudabi64_ciovec_t *)];
-	char iovcnt_l_[PADL_(size_t)]; size_t iovcnt; char iovcnt_r_[PADR_(size_t)];
+	char iovs_l_[PADL_(const cloudabi64_ciovec_t *)]; const cloudabi64_ciovec_t * iovs; char iovs_r_[PADR_(const cloudabi64_ciovec_t *)];
+	char iovs_len_l_[PADL_(size_t)]; size_t iovs_len; char iovs_len_r_[PADR_(size_t)];
 	char offset_l_[PADL_(cloudabi_filesize_t)]; cloudabi_filesize_t offset; char offset_r_[PADR_(cloudabi_filesize_t)];
 };
 struct cloudabi64_sys_fd_read_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
-	char iov_l_[PADL_(const cloudabi64_iovec_t *)]; const cloudabi64_iovec_t * iov; char iov_r_[PADR_(const cloudabi64_iovec_t *)];
-	char iovcnt_l_[PADL_(size_t)]; size_t iovcnt; char iovcnt_r_[PADR_(size_t)];
+	char iovs_l_[PADL_(const cloudabi64_iovec_t *)]; const cloudabi64_iovec_t * iovs; char iovs_r_[PADR_(const cloudabi64_iovec_t *)];
+	char iovs_len_l_[PADL_(size_t)]; size_t iovs_len; char iovs_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_fd_replace_args {
 	char from_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t from; char from_r_[PADR_(cloudabi_fd_t)];
@@ -101,8 +101,8 @@ struct cloudabi_sys_fd_sync_args {
 };
 struct cloudabi64_sys_fd_write_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
-	char iov_l_[PADL_(const cloudabi64_ciovec_t *)]; const cloudabi64_ciovec_t * iov; char iov_r_[PADR_(const cloudabi64_ciovec_t *)];
-	char iovcnt_l_[PADL_(size_t)]; size_t iovcnt; char iovcnt_r_[PADR_(size_t)];
+	char iovs_l_[PADL_(const cloudabi64_ciovec_t *)]; const cloudabi64_ciovec_t * iovs; char iovs_r_[PADR_(const cloudabi64_ciovec_t *)];
+	char iovs_len_l_[PADL_(size_t)]; size_t iovs_len; char iovs_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_file_advise_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
@@ -118,44 +118,44 @@ struct cloudabi_sys_file_allocate_args {
 struct cloudabi_sys_file_create_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 	char type_l_[PADL_(cloudabi_filetype_t)]; cloudabi_filetype_t type; char type_r_[PADR_(cloudabi_filetype_t)];
 };
 struct cloudabi_sys_file_link_args {
 	char fd1_l_[PADL_(cloudabi_lookup_t)]; cloudabi_lookup_t fd1; char fd1_r_[PADR_(cloudabi_lookup_t)];
 	char path1_l_[PADL_(const char *)]; const char * path1; char path1_r_[PADR_(const char *)];
-	char path1len_l_[PADL_(size_t)]; size_t path1len; char path1len_r_[PADR_(size_t)];
+	char path1_len_l_[PADL_(size_t)]; size_t path1_len; char path1_len_r_[PADR_(size_t)];
 	char fd2_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd2; char fd2_r_[PADR_(cloudabi_fd_t)];
 	char path2_l_[PADL_(const char *)]; const char * path2; char path2_r_[PADR_(const char *)];
-	char path2len_l_[PADL_(size_t)]; size_t path2len; char path2len_r_[PADR_(size_t)];
+	char path2_len_l_[PADL_(size_t)]; size_t path2_len; char path2_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_file_open_args {
 	char dirfd_l_[PADL_(cloudabi_lookup_t)]; cloudabi_lookup_t dirfd; char dirfd_r_[PADR_(cloudabi_lookup_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 	char oflags_l_[PADL_(cloudabi_oflags_t)]; cloudabi_oflags_t oflags; char oflags_r_[PADR_(cloudabi_oflags_t)];
 	char fds_l_[PADL_(const cloudabi_fdstat_t *)]; const cloudabi_fdstat_t * fds; char fds_r_[PADR_(const cloudabi_fdstat_t *)];
 };
 struct cloudabi_sys_file_readdir_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char buf_l_[PADL_(void *)]; void * buf; char buf_r_[PADR_(void *)];
-	char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
+	char buf_len_l_[PADL_(size_t)]; size_t buf_len; char buf_len_r_[PADR_(size_t)];
 	char cookie_l_[PADL_(cloudabi_dircookie_t)]; cloudabi_dircookie_t cookie; char cookie_r_[PADR_(cloudabi_dircookie_t)];
 };
 struct cloudabi_sys_file_readlink_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 	char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
-	char bufsize_l_[PADL_(size_t)]; size_t bufsize; char bufsize_r_[PADR_(size_t)];
+	char buf_len_l_[PADL_(size_t)]; size_t buf_len; char buf_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_file_rename_args {
-	char oldfd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t oldfd; char oldfd_r_[PADR_(cloudabi_fd_t)];
-	char old_l_[PADL_(const char *)]; const char * old; char old_r_[PADR_(const char *)];
-	char oldlen_l_[PADL_(size_t)]; size_t oldlen; char oldlen_r_[PADR_(size_t)];
-	char newfd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t newfd; char newfd_r_[PADR_(cloudabi_fd_t)];
-	char new_l_[PADL_(const char *)]; const char * new; char new_r_[PADR_(const char *)];
-	char newlen_l_[PADL_(size_t)]; size_t newlen; char newlen_r_[PADR_(size_t)];
+	char fd1_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd1; char fd1_r_[PADR_(cloudabi_fd_t)];
+	char path1_l_[PADL_(const char *)]; const char * path1; char path1_r_[PADR_(const char *)];
+	char path1_len_l_[PADL_(size_t)]; size_t path1_len; char path1_len_r_[PADR_(size_t)];
+	char fd2_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd2; char fd2_r_[PADR_(cloudabi_fd_t)];
+	char path2_l_[PADL_(const char *)]; const char * path2; char path2_r_[PADR_(const char *)];
+	char path2_len_l_[PADL_(size_t)]; size_t path2_len; char path2_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_file_stat_fget_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
@@ -169,27 +169,27 @@ struct cloudabi_sys_file_stat_fput_args {
 struct cloudabi_sys_file_stat_get_args {
 	char fd_l_[PADL_(cloudabi_lookup_t)]; cloudabi_lookup_t fd; char fd_r_[PADR_(cloudabi_lookup_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 	char buf_l_[PADL_(cloudabi_filestat_t *)]; cloudabi_filestat_t * buf; char buf_r_[PADR_(cloudabi_filestat_t *)];
 };
 struct cloudabi_sys_file_stat_put_args {
 	char fd_l_[PADL_(cloudabi_lookup_t)]; cloudabi_lookup_t fd; char fd_r_[PADR_(cloudabi_lookup_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 	char buf_l_[PADL_(const cloudabi_filestat_t *)]; const cloudabi_filestat_t * buf; char buf_r_[PADR_(const cloudabi_filestat_t *)];
 	char flags_l_[PADL_(cloudabi_fsflags_t)]; cloudabi_fsflags_t flags; char flags_r_[PADR_(cloudabi_fsflags_t)];
 };
 struct cloudabi_sys_file_symlink_args {
 	char path1_l_[PADL_(const char *)]; const char * path1; char path1_r_[PADR_(const char *)];
-	char path1len_l_[PADL_(size_t)]; size_t path1len; char path1len_r_[PADR_(size_t)];
+	char path1_len_l_[PADL_(size_t)]; size_t path1_len; char path1_len_r_[PADR_(size_t)];
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char path2_l_[PADL_(const char *)]; const char * path2; char path2_r_[PADR_(const char *)];
-	char path2len_l_[PADL_(size_t)]; size_t path2len; char path2len_r_[PADR_(size_t)];
+	char path2_len_l_[PADL_(size_t)]; size_t path2_len; char path2_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_file_unlink_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 	char flags_l_[PADL_(cloudabi_ulflags_t)]; cloudabi_ulflags_t flags; char flags_r_[PADR_(cloudabi_ulflags_t)];
 };
 struct cloudabi_sys_lock_unlock_args {
@@ -197,13 +197,13 @@ struct cloudabi_sys_lock_unlock_args {
 	char scope_l_[PADL_(cloudabi_scope_t)]; cloudabi_scope_t scope; char scope_r_[PADR_(cloudabi_scope_t)];
 };
 struct cloudabi_sys_mem_advise_args {
-	char addr_l_[PADL_(void *)]; void * addr; char addr_r_[PADR_(void *)];
-	char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
+	char mapping_l_[PADL_(void *)]; void * mapping; char mapping_r_[PADR_(void *)];
+	char mapping_len_l_[PADL_(size_t)]; size_t mapping_len; char mapping_len_r_[PADR_(size_t)];
 	char advice_l_[PADL_(cloudabi_advice_t)]; cloudabi_advice_t advice; char advice_r_[PADR_(cloudabi_advice_t)];
 };
 struct cloudabi_sys_mem_lock_args {
-	char addr_l_[PADL_(const void *)]; const void * addr; char addr_r_[PADR_(const void *)];
-	char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
+	char mapping_l_[PADL_(const void *)]; const void * mapping; char mapping_r_[PADR_(const void *)];
+	char mapping_len_l_[PADL_(size_t)]; size_t mapping_len; char mapping_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_mem_map_args {
 	char addr_l_[PADL_(void *)]; void * addr; char addr_r_[PADR_(void *)];
@@ -214,22 +214,22 @@ struct cloudabi_sys_mem_map_args {
 	char off_l_[PADL_(cloudabi_filesize_t)]; cloudabi_filesize_t off; char off_r_[PADR_(cloudabi_filesize_t)];
 };
 struct cloudabi_sys_mem_protect_args {
-	char addr_l_[PADL_(void *)]; void * addr; char addr_r_[PADR_(void *)];
-	char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
+	char mapping_l_[PADL_(void *)]; void * mapping; char mapping_r_[PADR_(void *)];
+	char mapping_len_l_[PADL_(size_t)]; size_t mapping_len; char mapping_len_r_[PADR_(size_t)];
 	char prot_l_[PADL_(cloudabi_mprot_t)]; cloudabi_mprot_t prot; char prot_r_[PADR_(cloudabi_mprot_t)];
 };
 struct cloudabi_sys_mem_sync_args {
-	char addr_l_[PADL_(void *)]; void * addr; char addr_r_[PADR_(void *)];
-	char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
+	char mapping_l_[PADL_(void *)]; void * mapping; char mapping_r_[PADR_(void *)];
+	char mapping_len_l_[PADL_(size_t)]; size_t mapping_len; char mapping_len_r_[PADR_(size_t)];
 	char flags_l_[PADL_(cloudabi_msflags_t)]; cloudabi_msflags_t flags; char flags_r_[PADR_(cloudabi_msflags_t)];
 };
 struct cloudabi_sys_mem_unlock_args {
-	char addr_l_[PADL_(const void *)]; const void * addr; char addr_r_[PADR_(const void *)];
-	char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
+	char mapping_l_[PADL_(const void *)]; const void * mapping; char mapping_r_[PADR_(const void *)];
+	char mapping_len_l_[PADL_(size_t)]; size_t mapping_len; char mapping_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_mem_unmap_args {
-	char addr_l_[PADL_(void *)]; void * addr; char addr_r_[PADR_(void *)];
-	char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
+	char mapping_l_[PADL_(void *)]; void * mapping; char mapping_r_[PADR_(void *)];
+	char mapping_len_l_[PADL_(size_t)]; size_t mapping_len; char mapping_len_r_[PADR_(size_t)];
 };
 struct cloudabi64_sys_poll_args {
 	char in_l_[PADL_(const cloudabi64_subscription_t *)]; const cloudabi64_subscription_t * in; char in_r_[PADR_(const cloudabi64_subscription_t *)];
@@ -239,17 +239,17 @@ struct cloudabi64_sys_poll_args {
 struct cloudabi64_sys_poll_fd_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char in_l_[PADL_(const cloudabi64_subscription_t *)]; const cloudabi64_subscription_t * in; char in_r_[PADR_(const cloudabi64_subscription_t *)];
-	char nin_l_[PADL_(size_t)]; size_t nin; char nin_r_[PADR_(size_t)];
+	char in_len_l_[PADL_(size_t)]; size_t in_len; char in_len_r_[PADR_(size_t)];
 	char out_l_[PADL_(cloudabi64_event_t *)]; cloudabi64_event_t * out; char out_r_[PADR_(cloudabi64_event_t *)];
-	char nout_l_[PADL_(size_t)]; size_t nout; char nout_r_[PADR_(size_t)];
+	char out_len_l_[PADL_(size_t)]; size_t out_len; char out_len_r_[PADR_(size_t)];
 	char timeout_l_[PADL_(const cloudabi64_subscription_t *)]; const cloudabi64_subscription_t * timeout; char timeout_r_[PADR_(const cloudabi64_subscription_t *)];
 };
 struct cloudabi_sys_proc_exec_args {
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char data_l_[PADL_(const void *)]; const void * data; char data_r_[PADR_(const void *)];
-	char datalen_l_[PADL_(size_t)]; size_t datalen; char datalen_r_[PADR_(size_t)];
+	char data_len_l_[PADL_(size_t)]; size_t data_len; char data_len_r_[PADR_(size_t)];
 	char fds_l_[PADL_(const cloudabi_fd_t *)]; const cloudabi_fd_t * fds; char fds_r_[PADR_(const cloudabi_fd_t *)];
-	char fdslen_l_[PADL_(size_t)]; size_t fdslen; char fdslen_r_[PADR_(size_t)];
+	char fds_len_l_[PADL_(size_t)]; size_t fds_len; char fds_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_proc_exit_args {
 	char rval_l_[PADL_(cloudabi_exitcode_t)]; cloudabi_exitcode_t rval; char rval_r_[PADR_(cloudabi_exitcode_t)];
@@ -262,7 +262,7 @@ struct cloudabi_sys_proc_raise_args {
 };
 struct cloudabi_sys_random_get_args {
 	char buf_l_[PADL_(void *)]; void * buf; char buf_r_[PADR_(void *)];
-	char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
+	char buf_len_l_[PADL_(size_t)]; size_t buf_len; char buf_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_sock_accept_args {
 	char sock_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t sock; char sock_r_[PADR_(cloudabi_fd_t)];
@@ -272,13 +272,13 @@ struct cloudabi_sys_sock_bind_args {
 	char sock_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t sock; char sock_r_[PADR_(cloudabi_fd_t)];
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_sock_connect_args {
 	char sock_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t sock; char sock_r_[PADR_(cloudabi_fd_t)];
 	char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)];
 	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
-	char pathlen_l_[PADL_(size_t)]; size_t pathlen; char pathlen_r_[PADR_(size_t)];
+	char path_len_l_[PADL_(size_t)]; size_t path_len; char path_len_r_[PADR_(size_t)];
 };
 struct cloudabi_sys_sock_listen_args {
 	char sock_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t sock; char sock_r_[PADR_(cloudabi_fd_t)];
diff --git a/sys/compat/cloudabi64/cloudabi64_sock.c b/sys/compat/cloudabi64/cloudabi64_sock.c
index 3915ddf0c21..c445c145c23 100644
--- a/sys/compat/cloudabi64/cloudabi64_sock.c
+++ b/sys/compat/cloudabi64/cloudabi64_sock.c
@@ -62,9 +62,9 @@ cloudabi64_sys_sock_recv(struct thread *td,
 		return (error);
 
 	/* Convert results in cloudabi_recv_in_t to struct msghdr. */
-	if (ri.ri_datalen > UIO_MAXIOV)
+	if (ri.ri_data_len > UIO_MAXIOV)
 		return (EINVAL);
-	msghdr.msg_iovlen = ri.ri_datalen;
+	msghdr.msg_iovlen = ri.ri_data_len;
 	msghdr.msg_iov = malloc(msghdr.msg_iovlen * sizeof(struct iovec),
 	    M_SOCKET, M_WAITOK);
 	user_iov = TO_PTR(ri.ri_data);
@@ -74,8 +74,8 @@ cloudabi64_sys_sock_recv(struct thread *td,
 			free(msghdr.msg_iov, M_SOCKET);
 			return (error);
 		}
-		msghdr.msg_iov[i].iov_base = TO_PTR(iovobj.iov_base);
-		msghdr.msg_iov[i].iov_len = iovobj.iov_len;
+		msghdr.msg_iov[i].iov_base = TO_PTR(iovobj.buf);
+		msghdr.msg_iov[i].iov_len = iovobj.buf_len;
 	}
 	msghdr.msg_name = &ss;
 	msghdr.msg_namelen = sizeof(ss);
@@ -115,9 +115,9 @@ cloudabi64_sys_sock_send(struct thread *td,
 		return (error);
 
 	/* Convert results in cloudabi_send_in_t to struct msghdr. */
-	if (si.si_datalen > UIO_MAXIOV)
+	if (si.si_data_len > UIO_MAXIOV)
 		return (EINVAL);
-	msghdr.msg_iovlen = si.si_datalen;
+	msghdr.msg_iovlen = si.si_data_len;
 	msghdr.msg_iov = malloc(msghdr.msg_iovlen * sizeof(struct iovec),
 	    M_SOCKET, M_WAITOK);
 	user_iov = TO_PTR(si.si_data);
@@ -127,8 +127,8 @@ cloudabi64_sys_sock_send(struct thread *td,
 			free(msghdr.msg_iov, M_SOCKET);
 			return (error);
 		}
-		msghdr.msg_iov[i].iov_base = TO_PTR(iovobj.iov_base);
-		msghdr.msg_iov[i].iov_len = iovobj.iov_len;
+		msghdr.msg_iov[i].iov_base = TO_PTR(iovobj.buf);
+		msghdr.msg_iov[i].iov_len = iovobj.buf_len;
 	}
 
 	flags = MSG_NOSIGNAL;
diff --git a/sys/compat/cloudabi64/cloudabi64_syscall.h b/sys/compat/cloudabi64/cloudabi64_syscall.h
index 7d99d5ed1d7..50089dd6961 100644
--- a/sys/compat/cloudabi64/cloudabi64_syscall.h
+++ b/sys/compat/cloudabi64/cloudabi64_syscall.h
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/contrib/cloudabi/syscalls64.master 304483 2016-08-19 17:53:37Z ed 
+ * created from FreeBSD: head/sys/contrib/cloudabi/syscalls64.master 312353 2017-01-17 22:03:08Z ed
  */
 
 #define	CLOUDABI64_SYS_cloudabi_sys_clock_res_get	0
diff --git a/sys/compat/cloudabi64/cloudabi64_syscalls.c b/sys/compat/cloudabi64/cloudabi64_syscalls.c
index d430056d9cb..5388299a092 100644
--- a/sys/compat/cloudabi64/cloudabi64_syscalls.c
+++ b/sys/compat/cloudabi64/cloudabi64_syscalls.c
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/contrib/cloudabi/syscalls64.master 304483 2016-08-19 17:53:37Z ed 
+ * created from FreeBSD: head/sys/contrib/cloudabi/syscalls64.master 312353 2017-01-17 22:03:08Z ed
  */
 
 const char *cloudabi64_syscallnames[] = {
diff --git a/sys/compat/cloudabi64/cloudabi64_sysent.c b/sys/compat/cloudabi64/cloudabi64_sysent.c
index 3b1185023cb..d922a060fef 100644
--- a/sys/compat/cloudabi64/cloudabi64_sysent.c
+++ b/sys/compat/cloudabi64/cloudabi64_sysent.c
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/contrib/cloudabi/syscalls64.master 304483 2016-08-19 17:53:37Z ed 
+ * created from FreeBSD: head/sys/contrib/cloudabi/syscalls64.master 312353 2017-01-17 22:03:08Z ed
  */
 
 #include 
diff --git a/sys/compat/cloudabi64/cloudabi64_systrace_args.c b/sys/compat/cloudabi64/cloudabi64_systrace_args.c
index 032eefd05f4..74005abcf11 100644
--- a/sys/compat/cloudabi64/cloudabi64_systrace_args.c
+++ b/sys/compat/cloudabi64/cloudabi64_systrace_args.c
@@ -74,8 +74,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	case 8: {
 		struct cloudabi64_sys_fd_pread_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
-		uarg[1] = (intptr_t) p->iov; /* const cloudabi64_iovec_t * */
-		uarg[2] = p->iovcnt; /* size_t */
+		uarg[1] = (intptr_t) p->iovs; /* const cloudabi64_iovec_t * */
+		uarg[2] = p->iovs_len; /* size_t */
 		iarg[3] = p->offset; /* cloudabi_filesize_t */
 		*n_args = 4;
 		break;
@@ -84,8 +84,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	case 9: {
 		struct cloudabi64_sys_fd_pwrite_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
-		uarg[1] = (intptr_t) p->iov; /* const cloudabi64_ciovec_t * */
-		uarg[2] = p->iovcnt; /* size_t */
+		uarg[1] = (intptr_t) p->iovs; /* const cloudabi64_ciovec_t * */
+		uarg[2] = p->iovs_len; /* size_t */
 		iarg[3] = p->offset; /* cloudabi_filesize_t */
 		*n_args = 4;
 		break;
@@ -94,8 +94,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	case 10: {
 		struct cloudabi64_sys_fd_read_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
-		uarg[1] = (intptr_t) p->iov; /* const cloudabi64_iovec_t * */
-		uarg[2] = p->iovcnt; /* size_t */
+		uarg[1] = (intptr_t) p->iovs; /* const cloudabi64_iovec_t * */
+		uarg[2] = p->iovs_len; /* size_t */
 		*n_args = 3;
 		break;
 	}
@@ -144,8 +144,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	case 16: {
 		struct cloudabi64_sys_fd_write_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
-		uarg[1] = (intptr_t) p->iov; /* const cloudabi64_ciovec_t * */
-		uarg[2] = p->iovcnt; /* size_t */
+		uarg[1] = (intptr_t) p->iovs; /* const cloudabi64_ciovec_t * */
+		uarg[2] = p->iovs_len; /* size_t */
 		*n_args = 3;
 		break;
 	}
@@ -173,7 +173,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_create_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
 		uarg[1] = (intptr_t) p->path; /* const char * */
-		uarg[2] = p->pathlen; /* size_t */
+		uarg[2] = p->path_len; /* size_t */
 		iarg[3] = p->type; /* cloudabi_filetype_t */
 		*n_args = 4;
 		break;
@@ -183,10 +183,10 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_link_args *p = params;
 		iarg[0] = p->fd1; /* cloudabi_lookup_t */
 		uarg[1] = (intptr_t) p->path1; /* const char * */
-		uarg[2] = p->path1len; /* size_t */
+		uarg[2] = p->path1_len; /* size_t */
 		iarg[3] = p->fd2; /* cloudabi_fd_t */
 		uarg[4] = (intptr_t) p->path2; /* const char * */
-		uarg[5] = p->path2len; /* size_t */
+		uarg[5] = p->path2_len; /* size_t */
 		*n_args = 6;
 		break;
 	}
@@ -195,7 +195,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_open_args *p = params;
 		iarg[0] = p->dirfd; /* cloudabi_lookup_t */
 		uarg[1] = (intptr_t) p->path; /* const char * */
-		uarg[2] = p->pathlen; /* size_t */
+		uarg[2] = p->path_len; /* size_t */
 		iarg[3] = p->oflags; /* cloudabi_oflags_t */
 		uarg[4] = (intptr_t) p->fds; /* const cloudabi_fdstat_t * */
 		*n_args = 5;
@@ -206,7 +206,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_readdir_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
 		uarg[1] = (intptr_t) p->buf; /* void * */
-		uarg[2] = p->nbyte; /* size_t */
+		uarg[2] = p->buf_len; /* size_t */
 		iarg[3] = p->cookie; /* cloudabi_dircookie_t */
 		*n_args = 4;
 		break;
@@ -216,21 +216,21 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_readlink_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
 		uarg[1] = (intptr_t) p->path; /* const char * */
-		uarg[2] = p->pathlen; /* size_t */
+		uarg[2] = p->path_len; /* size_t */
 		uarg[3] = (intptr_t) p->buf; /* char * */
-		uarg[4] = p->bufsize; /* size_t */
+		uarg[4] = p->buf_len; /* size_t */
 		*n_args = 5;
 		break;
 	}
 	/* cloudabi_sys_file_rename */
 	case 24: {
 		struct cloudabi_sys_file_rename_args *p = params;
-		iarg[0] = p->oldfd; /* cloudabi_fd_t */
-		uarg[1] = (intptr_t) p->old; /* const char * */
-		uarg[2] = p->oldlen; /* size_t */
-		iarg[3] = p->newfd; /* cloudabi_fd_t */
-		uarg[4] = (intptr_t) p->new; /* const char * */
-		uarg[5] = p->newlen; /* size_t */
+		iarg[0] = p->fd1; /* cloudabi_fd_t */
+		uarg[1] = (intptr_t) p->path1; /* const char * */
+		uarg[2] = p->path1_len; /* size_t */
+		iarg[3] = p->fd2; /* cloudabi_fd_t */
+		uarg[4] = (intptr_t) p->path2; /* const char * */
+		uarg[5] = p->path2_len; /* size_t */
 		*n_args = 6;
 		break;
 	}
@@ -256,7 +256,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_stat_get_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_lookup_t */
 		uarg[1] = (intptr_t) p->path; /* const char * */
-		uarg[2] = p->pathlen; /* size_t */
+		uarg[2] = p->path_len; /* size_t */
 		uarg[3] = (intptr_t) p->buf; /* cloudabi_filestat_t * */
 		*n_args = 4;
 		break;
@@ -266,7 +266,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_stat_put_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_lookup_t */
 		uarg[1] = (intptr_t) p->path; /* const char * */
-		uarg[2] = p->pathlen; /* size_t */
+		uarg[2] = p->path_len; /* size_t */
 		uarg[3] = (intptr_t) p->buf; /* const cloudabi_filestat_t * */
 		iarg[4] = p->flags; /* cloudabi_fsflags_t */
 		*n_args = 5;
@@ -276,10 +276,10 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	case 29: {
 		struct cloudabi_sys_file_symlink_args *p = params;
 		uarg[0] = (intptr_t) p->path1; /* const char * */
-		uarg[1] = p->path1len; /* size_t */
+		uarg[1] = p->path1_len; /* size_t */
 		iarg[2] = p->fd; /* cloudabi_fd_t */
 		uarg[3] = (intptr_t) p->path2; /* const char * */
-		uarg[4] = p->path2len; /* size_t */
+		uarg[4] = p->path2_len; /* size_t */
 		*n_args = 5;
 		break;
 	}
@@ -288,7 +288,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_file_unlink_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
 		uarg[1] = (intptr_t) p->path; /* const char * */
-		uarg[2] = p->pathlen; /* size_t */
+		uarg[2] = p->path_len; /* size_t */
 		iarg[3] = p->flags; /* cloudabi_ulflags_t */
 		*n_args = 4;
 		break;
@@ -304,8 +304,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	/* cloudabi_sys_mem_advise */
 	case 32: {
 		struct cloudabi_sys_mem_advise_args *p = params;
-		uarg[0] = (intptr_t) p->addr; /* void * */
-		uarg[1] = p->len; /* size_t */
+		uarg[0] = (intptr_t) p->mapping; /* void * */
+		uarg[1] = p->mapping_len; /* size_t */
 		iarg[2] = p->advice; /* cloudabi_advice_t */
 		*n_args = 3;
 		break;
@@ -313,8 +313,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	/* cloudabi_sys_mem_lock */
 	case 33: {
 		struct cloudabi_sys_mem_lock_args *p = params;
-		uarg[0] = (intptr_t) p->addr; /* const void * */
-		uarg[1] = p->len; /* size_t */
+		uarg[0] = (intptr_t) p->mapping; /* const void * */
+		uarg[1] = p->mapping_len; /* size_t */
 		*n_args = 2;
 		break;
 	}
@@ -333,8 +333,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	/* cloudabi_sys_mem_protect */
 	case 35: {
 		struct cloudabi_sys_mem_protect_args *p = params;
-		uarg[0] = (intptr_t) p->addr; /* void * */
-		uarg[1] = p->len; /* size_t */
+		uarg[0] = (intptr_t) p->mapping; /* void * */
+		uarg[1] = p->mapping_len; /* size_t */
 		iarg[2] = p->prot; /* cloudabi_mprot_t */
 		*n_args = 3;
 		break;
@@ -342,8 +342,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	/* cloudabi_sys_mem_sync */
 	case 36: {
 		struct cloudabi_sys_mem_sync_args *p = params;
-		uarg[0] = (intptr_t) p->addr; /* void * */
-		uarg[1] = p->len; /* size_t */
+		uarg[0] = (intptr_t) p->mapping; /* void * */
+		uarg[1] = p->mapping_len; /* size_t */
 		iarg[2] = p->flags; /* cloudabi_msflags_t */
 		*n_args = 3;
 		break;
@@ -351,16 +351,16 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	/* cloudabi_sys_mem_unlock */
 	case 37: {
 		struct cloudabi_sys_mem_unlock_args *p = params;
-		uarg[0] = (intptr_t) p->addr; /* const void * */
-		uarg[1] = p->len; /* size_t */
+		uarg[0] = (intptr_t) p->mapping; /* const void * */
+		uarg[1] = p->mapping_len; /* size_t */
 		*n_args = 2;
 		break;
 	}
 	/* cloudabi_sys_mem_unmap */
 	case 38: {
 		struct cloudabi_sys_mem_unmap_args *p = params;
-		uarg[0] = (intptr_t) p->addr; /* void * */
-		uarg[1] = p->len; /* size_t */
+		uarg[0] = (intptr_t) p->mapping; /* void * */
+		uarg[1] = p->mapping_len; /* size_t */
 		*n_args = 2;
 		break;
 	}
@@ -378,9 +378,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi64_sys_poll_fd_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
 		uarg[1] = (intptr_t) p->in; /* const cloudabi64_subscription_t * */
-		uarg[2] = p->nin; /* size_t */
+		uarg[2] = p->in_len; /* size_t */
 		uarg[3] = (intptr_t) p->out; /* cloudabi64_event_t * */
-		uarg[4] = p->nout; /* size_t */
+		uarg[4] = p->out_len; /* size_t */
 		uarg[5] = (intptr_t) p->timeout; /* const cloudabi64_subscription_t * */
 		*n_args = 6;
 		break;
@@ -390,9 +390,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		struct cloudabi_sys_proc_exec_args *p = params;
 		iarg[0] = p->fd; /* cloudabi_fd_t */
 		uarg[1] = (intptr_t) p->data; /* const void * */
-		uarg[2] = p->datalen; /* size_t */
+		uarg[2] = p->data_len; /* size_t */
 		uarg[3] = (intptr_t) p->fds; /* const cloudabi_fd_t * */
-		uarg[4] = p->fdslen; /* size_t */
+		uarg[4] = p->fds_len; /* size_t */
 		*n_args = 5;
 		break;
 	}
@@ -419,7 +419,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 	case 45: {
 		struct cloudabi_sys_random_get_args *p = params;
 		uarg[0] = (intptr_t) p->buf; /* void * */
-		uarg[1] = p->nbyte; /* size_t */
+		uarg[1] = p->buf_len; /* size_t */
 		*n_args = 2;
 		break;
 	}
@@ -437,7 +437,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		iarg[0] = p->sock; /* cloudabi_fd_t */
 		iarg[1] = p->fd; /* cloudabi_fd_t */
 		uarg[2] = (intptr_t) p->path; /* const char * */
-		uarg[3] = p->pathlen; /* size_t */
+		uarg[3] = p->path_len; /* size_t */
 		*n_args = 4;
 		break;
 	}
@@ -447,7 +447,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		iarg[0] = p->sock; /* cloudabi_fd_t */
 		iarg[1] = p->fd; /* cloudabi_fd_t */
 		uarg[2] = (intptr_t) p->path; /* const char * */
-		uarg[3] = p->pathlen; /* size_t */
+		uarg[3] = p->path_len; /* size_t */
 		*n_args = 4;
 		break;
 	}
diff --git a/sys/compat/cloudabi64/cloudabi64_thread.c b/sys/compat/cloudabi64/cloudabi64_thread.c
index 429ad3398be..4cb980b1530 100644
--- a/sys/compat/cloudabi64/cloudabi64_thread.c
+++ b/sys/compat/cloudabi64/cloudabi64_thread.c
@@ -65,9 +65,9 @@ cloudabi64_sys_thread_create(struct thread *td,
 		return (error);
 
 	/* Remove some space on the top of the stack for the TCB. */
-	args.tcb = rounddown(args.attr.stack + args.attr.stack_size -
+	args.tcb = rounddown(args.attr.stack + args.attr.stack_len -
 	    sizeof(cloudabi64_tcb_t), _Alignof(cloudabi64_tcb_t));
-	args.attr.stack_size = args.tcb - args.attr.stack;
+	args.attr.stack_len = args.tcb - args.attr.stack;
 
 	error = thread_create(td, NULL, initialize_thread, &args);
 	if (error != 0)
diff --git a/sys/conf/Makefile.powerpc b/sys/conf/Makefile.powerpc
index e529ef7cc11..3d01a342d7d 100644
--- a/sys/conf/Makefile.powerpc
+++ b/sys/conf/Makefile.powerpc
@@ -39,7 +39,8 @@ INCLUDES+= -I$S/contrib/libfdt
 # Force __SPE__, since the builtin will be removed later with -mno-spe
 CFLAGS+= -mabi=spe -D__SPE__
 .endif
-CFLAGS+= -msoft-float -Wa,-many
+CFLAGS+= -msoft-float
+CFLAGS.gcc+= -Wa,-many
 
 # Build position-independent kernel
 CFLAGS+= -fPIC
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 2e430bc129d..c8ac5de69ae 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -619,6 +619,8 @@ options 	HWPMC_HOOKS		# Other necessary kernel hooks
 options 	INET			#Internet communications protocols
 options 	INET6			#IPv6 communications protocols
 
+options		RATELIMIT		# TX rate limiting support
+
 options 	ROUTETABLES=2		# allocated fibs up to 65536. default is 1.
 					# but that would be a bad idea as they are large.
 
@@ -772,8 +774,7 @@ options 	NETGRAPH_IPFW
 options 	NETGRAPH_KSOCKET
 options 	NETGRAPH_L2TP
 options 	NETGRAPH_LMI
-# MPPC compression requires proprietary files (not included)
-#options 	NETGRAPH_MPPC_COMPRESSION
+options 	NETGRAPH_MPPC_COMPRESSION
 options 	NETGRAPH_MPPC_ENCRYPTION
 options 	NETGRAPH_NETFLOW
 options 	NETGRAPH_NAT
diff --git a/sys/conf/config.mk b/sys/conf/config.mk
index 0a3e7b9834d..50294961ca1 100644
--- a/sys/conf/config.mk
+++ b/sys/conf/config.mk
@@ -19,6 +19,10 @@ opt_inet.h:
 opt_inet6.h:
 	@echo "#define INET6 1" > ${.TARGET}
 .endif
+.if ${MK_RATELIMIT} != "no"
+opt_ratelimit.h:
+	@echo "#define RATELIMIT 1" > ${.TARGET}
+.endif
 .if ${MK_EISA} != "no"
 opt_eisa.h:
 	@echo "#define DEV_EISA 1" > ${.TARGET}
diff --git a/sys/conf/files b/sys/conf/files
index a17b3421039..fb17efbbc5d 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2716,6 +2716,7 @@ dev/rtwn/rtl8821a/r21a_led.c	optional rtwn
 dev/rtwn/rtl8821a/r21a_rom.c	optional rtwn
 dev/rtwn/rtl8821a/r21a_rx.c	optional rtwn
 dev/rtwn/rtl8821a/usb/r21au_attach.c	optional rtwn_usb
+dev/rtwn/rtl8821a/usb/r21au_dfs.c	optional rtwn_usb
 dev/rtwn/rtl8821a/usb/r21au_init.c	optional rtwn_usb
 rtwn-rtl8188eufw.c		optional rtwn-rtl8188eufw | rtwnfw	\
 	compile-with	"${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8188eufw.fw:rtwn-rtl8188eufw:111 -mrtwn-rtl8188eufw -c${.TARGET}" \
diff --git a/sys/conf/kern.opts.mk b/sys/conf/kern.opts.mk
index 66d43b2ac51..8b793cf5184 100644
--- a/sys/conf/kern.opts.mk
+++ b/sys/conf/kern.opts.mk
@@ -48,6 +48,7 @@ __DEFAULT_NO_OPTIONS = \
     EXTRA_TCP_STACKS \
     NAND \
     OFED \
+    RATELIMIT \
     REPRODUCIBLE_BUILD
 
 # Some options are totally broken on some architectures. We disable
diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk
index ee72dbe0ebe..2afc7080881 100644
--- a/sys/conf/kern.pre.mk
+++ b/sys/conf/kern.pre.mk
@@ -192,7 +192,7 @@ SYSTEM_LD_TAIL= @${OBJCOPY} --strip-symbol gcc2_compiled. ${.TARGET} ; \
 SYSTEM_DEP+= ${LDSCRIPT}
 
 # Calculate path for .m files early, if needed.
-.if !defined(NO_MODULES) && !defined(__MPATH)
+.if !defined(NO_MODULES) && !defined(__MPATH) && !make(install)
 __MPATH!=find ${S:tA}/ -name \*_if.m
 .endif
 
diff --git a/sys/conf/options b/sys/conf/options
index dee1eaddbb0..beea9bd507d 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -412,6 +412,7 @@ BOOTP_NFSV3		opt_bootp.h
 BOOTP_WIRED_TO		opt_bootp.h
 DEVICE_POLLING
 DUMMYNET		opt_ipdn.h
+RATELIMIT		opt_ratelimit.h
 INET			opt_inet.h
 INET6			opt_inet6.h
 IPDIVERT
@@ -516,7 +517,6 @@ NETGRAPH_IPFW		opt_netgraph.h
 NETGRAPH_KSOCKET	opt_netgraph.h
 NETGRAPH_L2TP		opt_netgraph.h
 NETGRAPH_LMI		opt_netgraph.h
-# MPPC compression requires proprietary files (not included)
 NETGRAPH_MPPC_COMPRESSION	opt_netgraph.h
 NETGRAPH_MPPC_ENCRYPTION	opt_netgraph.h
 NETGRAPH_NAT		opt_netgraph.h
diff --git a/sys/contrib/cloudabi/cloudabi32_types.h b/sys/contrib/cloudabi/cloudabi32_types.h
index 71d6429598a..2986e894c2b 100644
--- a/sys/contrib/cloudabi/cloudabi32_types.h
+++ b/sys/contrib/cloudabi/cloudabi32_types.h
@@ -44,11 +44,11 @@ _Static_assert(sizeof(cloudabi32_auxv_t) == 8, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi32_auxv_t) == 4, "Incorrect layout");
 
 typedef struct {
-  _Alignas(4) uint32_t iov_base;
-  _Alignas(4) uint32_t iov_len;
+  _Alignas(4) uint32_t buf;
+  _Alignas(4) uint32_t buf_len;
 } cloudabi32_ciovec_t;
-_Static_assert(offsetof(cloudabi32_ciovec_t, iov_base) == 0, "Incorrect layout");
-_Static_assert(offsetof(cloudabi32_ciovec_t, iov_len) == 4, "Incorrect layout");
+_Static_assert(offsetof(cloudabi32_ciovec_t, buf) == 0, "Incorrect layout");
+_Static_assert(offsetof(cloudabi32_ciovec_t, buf_len) == 4, "Incorrect layout");
 _Static_assert(sizeof(cloudabi32_ciovec_t) == 8, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi32_ciovec_t) == 4, "Incorrect layout");
 
@@ -94,11 +94,11 @@ _Static_assert(sizeof(cloudabi32_event_t) == 32, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi32_event_t) == 8, "Incorrect layout");
 
 typedef struct {
-  _Alignas(4) uint32_t iov_base;
-  _Alignas(4) uint32_t iov_len;
+  _Alignas(4) uint32_t buf;
+  _Alignas(4) uint32_t buf_len;
 } cloudabi32_iovec_t;
-_Static_assert(offsetof(cloudabi32_iovec_t, iov_base) == 0, "Incorrect layout");
-_Static_assert(offsetof(cloudabi32_iovec_t, iov_len) == 4, "Incorrect layout");
+_Static_assert(offsetof(cloudabi32_iovec_t, buf) == 0, "Incorrect layout");
+_Static_assert(offsetof(cloudabi32_iovec_t, buf_len) == 4, "Incorrect layout");
 _Static_assert(sizeof(cloudabi32_iovec_t) == 8, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi32_iovec_t) == 4, "Incorrect layout");
 
@@ -106,30 +106,30 @@ typedef void cloudabi32_processentry_t(uint32_t auxv);
 
 typedef struct {
   _Alignas(4) uint32_t ri_data;
-  _Alignas(4) uint32_t ri_datalen;
+  _Alignas(4) uint32_t ri_data_len;
   _Alignas(4) uint32_t ri_fds;
-  _Alignas(4) uint32_t ri_fdslen;
+  _Alignas(4) uint32_t ri_fds_len;
   _Alignas(2) cloudabi_msgflags_t ri_flags;
 } cloudabi32_recv_in_t;
 _Static_assert(offsetof(cloudabi32_recv_in_t, ri_data) == 0, "Incorrect layout");
-_Static_assert(offsetof(cloudabi32_recv_in_t, ri_datalen) == 4, "Incorrect layout");
+_Static_assert(offsetof(cloudabi32_recv_in_t, ri_data_len) == 4, "Incorrect layout");
 _Static_assert(offsetof(cloudabi32_recv_in_t, ri_fds) == 8, "Incorrect layout");
-_Static_assert(offsetof(cloudabi32_recv_in_t, ri_fdslen) == 12, "Incorrect layout");
+_Static_assert(offsetof(cloudabi32_recv_in_t, ri_fds_len) == 12, "Incorrect layout");
 _Static_assert(offsetof(cloudabi32_recv_in_t, ri_flags) == 16, "Incorrect layout");
 _Static_assert(sizeof(cloudabi32_recv_in_t) == 20, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi32_recv_in_t) == 4, "Incorrect layout");
 
 typedef struct {
   _Alignas(4) uint32_t si_data;
-  _Alignas(4) uint32_t si_datalen;
+  _Alignas(4) uint32_t si_data_len;
   _Alignas(4) uint32_t si_fds;
-  _Alignas(4) uint32_t si_fdslen;
+  _Alignas(4) uint32_t si_fds_len;
   _Alignas(2) cloudabi_msgflags_t si_flags;
 } cloudabi32_send_in_t;
 _Static_assert(offsetof(cloudabi32_send_in_t, si_data) == 0, "Incorrect layout");
-_Static_assert(offsetof(cloudabi32_send_in_t, si_datalen) == 4, "Incorrect layout");
+_Static_assert(offsetof(cloudabi32_send_in_t, si_data_len) == 4, "Incorrect layout");
 _Static_assert(offsetof(cloudabi32_send_in_t, si_fds) == 8, "Incorrect layout");
-_Static_assert(offsetof(cloudabi32_send_in_t, si_fdslen) == 12, "Incorrect layout");
+_Static_assert(offsetof(cloudabi32_send_in_t, si_fds_len) == 12, "Incorrect layout");
 _Static_assert(offsetof(cloudabi32_send_in_t, si_flags) == 16, "Incorrect layout");
 _Static_assert(sizeof(cloudabi32_send_in_t) == 20, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi32_send_in_t) == 4, "Incorrect layout");
@@ -219,12 +219,12 @@ _Static_assert(_Alignof(cloudabi32_recv_out_t) == 4, "Incorrect layout");
 typedef struct {
   _Alignas(4) uint32_t entry_point;
   _Alignas(4) uint32_t stack;
-  _Alignas(4) uint32_t stack_size;
+  _Alignas(4) uint32_t stack_len;
   _Alignas(4) uint32_t argument;
 } cloudabi32_threadattr_t;
 _Static_assert(offsetof(cloudabi32_threadattr_t, entry_point) == 0, "Incorrect layout");
 _Static_assert(offsetof(cloudabi32_threadattr_t, stack) == 4, "Incorrect layout");
-_Static_assert(offsetof(cloudabi32_threadattr_t, stack_size) == 8, "Incorrect layout");
+_Static_assert(offsetof(cloudabi32_threadattr_t, stack_len) == 8, "Incorrect layout");
 _Static_assert(offsetof(cloudabi32_threadattr_t, argument) == 12, "Incorrect layout");
 _Static_assert(sizeof(cloudabi32_threadattr_t) == 16, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi32_threadattr_t) == 4, "Incorrect layout");
diff --git a/sys/contrib/cloudabi/cloudabi64_types.h b/sys/contrib/cloudabi/cloudabi64_types.h
index 5d54e7e47e4..0a185ac47d0 100644
--- a/sys/contrib/cloudabi/cloudabi64_types.h
+++ b/sys/contrib/cloudabi/cloudabi64_types.h
@@ -44,12 +44,11 @@ _Static_assert(sizeof(cloudabi64_auxv_t) == 16, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi64_auxv_t) == 8, "Incorrect layout");
 
 typedef struct {
-  _Alignas(8) uint64_t iov_base;
-  _Alignas(8) uint64_t iov_len;
+  _Alignas(8) uint64_t buf;
+  _Alignas(8) uint64_t buf_len;
 } cloudabi64_ciovec_t;
-_Static_assert(offsetof(cloudabi64_ciovec_t, iov_base) == 0,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_ciovec_t, iov_len) == 8, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_ciovec_t, buf) == 0, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_ciovec_t, buf_len) == 8, "Incorrect layout");
 _Static_assert(sizeof(cloudabi64_ciovec_t) == 16, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi64_ciovec_t) == 8, "Incorrect layout");
 
@@ -82,33 +81,24 @@ typedef struct {
 _Static_assert(offsetof(cloudabi64_event_t, userdata) == 0, "Incorrect layout");
 _Static_assert(offsetof(cloudabi64_event_t, error) == 8, "Incorrect layout");
 _Static_assert(offsetof(cloudabi64_event_t, type) == 10, "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_event_t, clock.identifier) == 16,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_event_t, condvar.condvar) == 16,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_event_t, fd_readwrite.nbytes) == 16,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_event_t, fd_readwrite.fd) == 24,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_event_t, fd_readwrite.flags) == 28,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_event_t, lock.lock) == 16,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_event_t, proc_terminate.fd) == 16,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_event_t, proc_terminate.signal) == 20,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_event_t, proc_terminate.exitcode) == 24,
-               "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_event_t, clock.identifier) == 16, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_event_t, condvar.condvar) == 16, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_event_t, fd_readwrite.nbytes) == 16, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_event_t, fd_readwrite.fd) == 24, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_event_t, fd_readwrite.flags) == 28, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_event_t, lock.lock) == 16, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_event_t, proc_terminate.fd) == 16, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_event_t, proc_terminate.signal) == 20, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_event_t, proc_terminate.exitcode) == 24, "Incorrect layout");
 _Static_assert(sizeof(cloudabi64_event_t) == 32, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi64_event_t) == 8, "Incorrect layout");
 
 typedef struct {
-  _Alignas(8) uint64_t iov_base;
-  _Alignas(8) uint64_t iov_len;
+  _Alignas(8) uint64_t buf;
+  _Alignas(8) uint64_t buf_len;
 } cloudabi64_iovec_t;
-_Static_assert(offsetof(cloudabi64_iovec_t, iov_base) == 0, "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_iovec_t, iov_len) == 8, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_iovec_t, buf) == 0, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_iovec_t, buf_len) == 8, "Incorrect layout");
 _Static_assert(sizeof(cloudabi64_iovec_t) == 16, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi64_iovec_t) == 8, "Incorrect layout");
 
@@ -116,47 +106,38 @@ typedef void cloudabi64_processentry_t(uint64_t auxv);
 
 typedef struct {
   _Alignas(8) uint64_t ri_data;
-  _Alignas(8) uint64_t ri_datalen;
+  _Alignas(8) uint64_t ri_data_len;
   _Alignas(8) uint64_t ri_fds;
-  _Alignas(8) uint64_t ri_fdslen;
+  _Alignas(8) uint64_t ri_fds_len;
   _Alignas(2) cloudabi_msgflags_t ri_flags;
 } cloudabi64_recv_in_t;
-_Static_assert(offsetof(cloudabi64_recv_in_t, ri_data) == 0,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_recv_in_t, ri_datalen) == 8,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_recv_in_t, ri_fds) == 16,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_recv_in_t, ri_fdslen) == 24,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_recv_in_t, ri_flags) == 32,
-               "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_recv_in_t, ri_data) == 0, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_recv_in_t, ri_data_len) == 8, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_recv_in_t, ri_fds) == 16, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_recv_in_t, ri_fds_len) == 24, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_recv_in_t, ri_flags) == 32, "Incorrect layout");
 _Static_assert(sizeof(cloudabi64_recv_in_t) == 40, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi64_recv_in_t) == 8, "Incorrect layout");
 
 typedef struct {
   _Alignas(8) uint64_t si_data;
-  _Alignas(8) uint64_t si_datalen;
+  _Alignas(8) uint64_t si_data_len;
   _Alignas(8) uint64_t si_fds;
-  _Alignas(8) uint64_t si_fdslen;
+  _Alignas(8) uint64_t si_fds_len;
   _Alignas(2) cloudabi_msgflags_t si_flags;
 } cloudabi64_send_in_t;
-_Static_assert(offsetof(cloudabi64_send_in_t, si_data) == 0,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_send_in_t, si_datalen) == 8,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_send_in_t, si_fds) == 16,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_send_in_t, si_fdslen) == 24,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_send_in_t, si_flags) == 32,
-               "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_send_in_t, si_data) == 0, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_send_in_t, si_data_len) == 8, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_send_in_t, si_fds) == 16, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_send_in_t, si_fds_len) == 24, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_send_in_t, si_flags) == 32, "Incorrect layout");
 _Static_assert(sizeof(cloudabi64_send_in_t) == 40, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi64_send_in_t) == 8, "Incorrect layout");
 
-typedef struct { _Alignas(8) uint64_t so_datalen; } cloudabi64_send_out_t;
-_Static_assert(offsetof(cloudabi64_send_out_t, so_datalen) == 0,
-               "Incorrect layout");
+typedef struct {
+  _Alignas(8) uint64_t so_datalen;
+} cloudabi64_send_out_t;
+_Static_assert(offsetof(cloudabi64_send_out_t, so_datalen) == 0, "Incorrect layout");
 _Static_assert(sizeof(cloudabi64_send_out_t) == 8, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi64_send_out_t) == 8, "Incorrect layout");
 
@@ -191,44 +172,29 @@ typedef struct {
     } proc_terminate;
   };
 } cloudabi64_subscription_t;
-_Static_assert(offsetof(cloudabi64_subscription_t, userdata) == 0,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, flags) == 8,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, type) == 10,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, clock.identifier) == 16,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, clock.clock_id) == 24,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, clock.timeout) == 32,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, clock.precision) == 40,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, clock.flags) == 48,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, condvar.condvar) == 16,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, condvar.lock) == 24,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, condvar.condvar_scope) == 32,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, condvar.lock_scope) == 33,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, fd_readwrite.fd) == 16,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, fd_readwrite.flags) == 20,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, lock.lock) == 16,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, lock.lock_scope) == 24,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_subscription_t, proc_terminate.fd) == 16,
-               "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, userdata) == 0, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, flags) == 8, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, type) == 10, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, clock.identifier) == 16, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, clock.clock_id) == 24, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, clock.timeout) == 32, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, clock.precision) == 40, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, clock.flags) == 48, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, condvar.condvar) == 16, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, condvar.lock) == 24, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, condvar.condvar_scope) == 32, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, condvar.lock_scope) == 33, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, fd_readwrite.fd) == 16, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, fd_readwrite.flags) == 20, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, lock.lock) == 16, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, lock.lock_scope) == 24, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_subscription_t, proc_terminate.fd) == 16, "Incorrect layout");
 _Static_assert(sizeof(cloudabi64_subscription_t) == 56, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi64_subscription_t) == 8, "Incorrect layout");
 
-typedef struct { _Alignas(8) uint64_t parent; } cloudabi64_tcb_t;
+typedef struct {
+  _Alignas(8) uint64_t parent;
+} cloudabi64_tcb_t;
 _Static_assert(offsetof(cloudabi64_tcb_t, parent) == 0, "Incorrect layout");
 _Static_assert(sizeof(cloudabi64_tcb_t) == 8, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi64_tcb_t) == 8, "Incorrect layout");
@@ -242,33 +208,24 @@ typedef struct {
   _Alignas(2) cloudabi_sockaddr_t ro_peername;
   _Alignas(2) cloudabi_msgflags_t ro_flags;
 } cloudabi64_recv_out_t;
-_Static_assert(offsetof(cloudabi64_recv_out_t, ro_datalen) == 0,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_recv_out_t, ro_fdslen) == 8,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_recv_out_t, ro_sockname) == 16,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_recv_out_t, ro_peername) == 36,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_recv_out_t, ro_flags) == 56,
-               "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_recv_out_t, ro_datalen) == 0, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_recv_out_t, ro_fdslen) == 8, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_recv_out_t, ro_sockname) == 16, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_recv_out_t, ro_peername) == 36, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_recv_out_t, ro_flags) == 56, "Incorrect layout");
 _Static_assert(sizeof(cloudabi64_recv_out_t) == 64, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi64_recv_out_t) == 8, "Incorrect layout");
 
 typedef struct {
   _Alignas(8) uint64_t entry_point;
   _Alignas(8) uint64_t stack;
-  _Alignas(8) uint64_t stack_size;
+  _Alignas(8) uint64_t stack_len;
   _Alignas(8) uint64_t argument;
 } cloudabi64_threadattr_t;
-_Static_assert(offsetof(cloudabi64_threadattr_t, entry_point) == 0,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_threadattr_t, stack) == 8,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_threadattr_t, stack_size) == 16,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi64_threadattr_t, argument) == 24,
-               "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_threadattr_t, entry_point) == 0, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_threadattr_t, stack) == 8, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_threadattr_t, stack_len) == 16, "Incorrect layout");
+_Static_assert(offsetof(cloudabi64_threadattr_t, argument) == 24, "Incorrect layout");
 _Static_assert(sizeof(cloudabi64_threadattr_t) == 32, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi64_threadattr_t) == 8, "Incorrect layout");
 
diff --git a/sys/contrib/cloudabi/cloudabi_types_common.h b/sys/contrib/cloudabi/cloudabi_types_common.h
index 0297e2a9d99..86e76d3fbbb 100644
--- a/sys/contrib/cloudabi/cloudabi_types_common.h
+++ b/sys/contrib/cloudabi/cloudabi_types_common.h
@@ -38,34 +38,34 @@
 #endif
 
 typedef uint8_t cloudabi_advice_t;
-#define CLOUDABI_ADVICE_DONTNEED 1
-#define CLOUDABI_ADVICE_NOREUSE 2
-#define CLOUDABI_ADVICE_NORMAL 3
-#define CLOUDABI_ADVICE_RANDOM 4
+#define CLOUDABI_ADVICE_DONTNEED   1
+#define CLOUDABI_ADVICE_NOREUSE    2
+#define CLOUDABI_ADVICE_NORMAL     3
+#define CLOUDABI_ADVICE_RANDOM     4
 #define CLOUDABI_ADVICE_SEQUENTIAL 5
-#define CLOUDABI_ADVICE_WILLNEED 6
+#define CLOUDABI_ADVICE_WILLNEED   6
 
 typedef uint32_t cloudabi_auxtype_t;
-#define CLOUDABI_AT_ARGDATA 256
-#define CLOUDABI_AT_ARGDATALEN 257
-#define CLOUDABI_AT_BASE 7
-#define CLOUDABI_AT_CANARY 258
-#define CLOUDABI_AT_CANARYLEN 259
-#define CLOUDABI_AT_NCPUS 260
-#define CLOUDABI_AT_NULL 0
-#define CLOUDABI_AT_PAGESZ 6
-#define CLOUDABI_AT_PHDR 3
-#define CLOUDABI_AT_PHNUM 4
+#define CLOUDABI_AT_ARGDATA      256
+#define CLOUDABI_AT_ARGDATALEN   257
+#define CLOUDABI_AT_BASE           7
+#define CLOUDABI_AT_CANARY       258
+#define CLOUDABI_AT_CANARYLEN    259
+#define CLOUDABI_AT_NCPUS        260
+#define CLOUDABI_AT_NULL           0
+#define CLOUDABI_AT_PAGESZ         6
+#define CLOUDABI_AT_PHDR           3
+#define CLOUDABI_AT_PHNUM          4
 #define CLOUDABI_AT_SYSINFO_EHDR 262
-#define CLOUDABI_AT_TID 261
+#define CLOUDABI_AT_TID          261
 
 typedef uint32_t cloudabi_backlog_t;
 
 typedef uint32_t cloudabi_clockid_t;
-#define CLOUDABI_CLOCK_MONOTONIC 1
+#define CLOUDABI_CLOCK_MONOTONIC          1
 #define CLOUDABI_CLOCK_PROCESS_CPUTIME_ID 2
-#define CLOUDABI_CLOCK_REALTIME 3
-#define CLOUDABI_CLOCK_THREAD_CPUTIME_ID 4
+#define CLOUDABI_CLOCK_REALTIME           3
+#define CLOUDABI_CLOCK_THREAD_CPUTIME_ID  4
 
 typedef uint32_t cloudabi_condvar_t;
 #define CLOUDABI_CONDVAR_HAS_NO_WAITERS 0
@@ -76,110 +76,110 @@ typedef uint64_t cloudabi_dircookie_t;
 #define CLOUDABI_DIRCOOKIE_START 0
 
 typedef uint16_t cloudabi_errno_t;
-#define CLOUDABI_E2BIG 1
-#define CLOUDABI_EACCES 2
-#define CLOUDABI_EADDRINUSE 3
-#define CLOUDABI_EADDRNOTAVAIL 4
-#define CLOUDABI_EAFNOSUPPORT 5
-#define CLOUDABI_EAGAIN 6
-#define CLOUDABI_EALREADY 7
-#define CLOUDABI_EBADF 8
-#define CLOUDABI_EBADMSG 9
-#define CLOUDABI_EBUSY 10
-#define CLOUDABI_ECANCELED 11
-#define CLOUDABI_ECHILD 12
-#define CLOUDABI_ECONNABORTED 13
-#define CLOUDABI_ECONNREFUSED 14
-#define CLOUDABI_ECONNRESET 15
-#define CLOUDABI_EDEADLK 16
-#define CLOUDABI_EDESTADDRREQ 17
-#define CLOUDABI_EDOM 18
-#define CLOUDABI_EDQUOT 19
-#define CLOUDABI_EEXIST 20
-#define CLOUDABI_EFAULT 21
-#define CLOUDABI_EFBIG 22
-#define CLOUDABI_EHOSTUNREACH 23
-#define CLOUDABI_EIDRM 24
-#define CLOUDABI_EILSEQ 25
-#define CLOUDABI_EINPROGRESS 26
-#define CLOUDABI_EINTR 27
-#define CLOUDABI_EINVAL 28
-#define CLOUDABI_EIO 29
-#define CLOUDABI_EISCONN 30
-#define CLOUDABI_EISDIR 31
-#define CLOUDABI_ELOOP 32
-#define CLOUDABI_EMFILE 33
-#define CLOUDABI_EMLINK 34
-#define CLOUDABI_EMSGSIZE 35
-#define CLOUDABI_EMULTIHOP 36
-#define CLOUDABI_ENAMETOOLONG 37
-#define CLOUDABI_ENETDOWN 38
-#define CLOUDABI_ENETRESET 39
-#define CLOUDABI_ENETUNREACH 40
-#define CLOUDABI_ENFILE 41
-#define CLOUDABI_ENOBUFS 42
-#define CLOUDABI_ENODEV 43
-#define CLOUDABI_ENOENT 44
-#define CLOUDABI_ENOEXEC 45
-#define CLOUDABI_ENOLCK 46
-#define CLOUDABI_ENOLINK 47
-#define CLOUDABI_ENOMEM 48
-#define CLOUDABI_ENOMSG 49
-#define CLOUDABI_ENOPROTOOPT 50
-#define CLOUDABI_ENOSPC 51
-#define CLOUDABI_ENOSYS 52
-#define CLOUDABI_ENOTCONN 53
-#define CLOUDABI_ENOTDIR 54
-#define CLOUDABI_ENOTEMPTY 55
+#define CLOUDABI_E2BIG            1
+#define CLOUDABI_EACCES           2
+#define CLOUDABI_EADDRINUSE       3
+#define CLOUDABI_EADDRNOTAVAIL    4
+#define CLOUDABI_EAFNOSUPPORT     5
+#define CLOUDABI_EAGAIN           6
+#define CLOUDABI_EALREADY         7
+#define CLOUDABI_EBADF            8
+#define CLOUDABI_EBADMSG          9
+#define CLOUDABI_EBUSY           10
+#define CLOUDABI_ECANCELED       11
+#define CLOUDABI_ECHILD          12
+#define CLOUDABI_ECONNABORTED    13
+#define CLOUDABI_ECONNREFUSED    14
+#define CLOUDABI_ECONNRESET      15
+#define CLOUDABI_EDEADLK         16
+#define CLOUDABI_EDESTADDRREQ    17
+#define CLOUDABI_EDOM            18
+#define CLOUDABI_EDQUOT          19
+#define CLOUDABI_EEXIST          20
+#define CLOUDABI_EFAULT          21
+#define CLOUDABI_EFBIG           22
+#define CLOUDABI_EHOSTUNREACH    23
+#define CLOUDABI_EIDRM           24
+#define CLOUDABI_EILSEQ          25
+#define CLOUDABI_EINPROGRESS     26
+#define CLOUDABI_EINTR           27
+#define CLOUDABI_EINVAL          28
+#define CLOUDABI_EIO             29
+#define CLOUDABI_EISCONN         30
+#define CLOUDABI_EISDIR          31
+#define CLOUDABI_ELOOP           32
+#define CLOUDABI_EMFILE          33
+#define CLOUDABI_EMLINK          34
+#define CLOUDABI_EMSGSIZE        35
+#define CLOUDABI_EMULTIHOP       36
+#define CLOUDABI_ENAMETOOLONG    37
+#define CLOUDABI_ENETDOWN        38
+#define CLOUDABI_ENETRESET       39
+#define CLOUDABI_ENETUNREACH     40
+#define CLOUDABI_ENFILE          41
+#define CLOUDABI_ENOBUFS         42
+#define CLOUDABI_ENODEV          43
+#define CLOUDABI_ENOENT          44
+#define CLOUDABI_ENOEXEC         45
+#define CLOUDABI_ENOLCK          46
+#define CLOUDABI_ENOLINK         47
+#define CLOUDABI_ENOMEM          48
+#define CLOUDABI_ENOMSG          49
+#define CLOUDABI_ENOPROTOOPT     50
+#define CLOUDABI_ENOSPC          51
+#define CLOUDABI_ENOSYS          52
+#define CLOUDABI_ENOTCONN        53
+#define CLOUDABI_ENOTDIR         54
+#define CLOUDABI_ENOTEMPTY       55
 #define CLOUDABI_ENOTRECOVERABLE 56
-#define CLOUDABI_ENOTSOCK 57
-#define CLOUDABI_ENOTSUP 58
-#define CLOUDABI_ENOTTY 59
-#define CLOUDABI_ENXIO 60
-#define CLOUDABI_EOVERFLOW 61
-#define CLOUDABI_EOWNERDEAD 62
-#define CLOUDABI_EPERM 63
-#define CLOUDABI_EPIPE 64
-#define CLOUDABI_EPROTO 65
+#define CLOUDABI_ENOTSOCK        57
+#define CLOUDABI_ENOTSUP         58
+#define CLOUDABI_ENOTTY          59
+#define CLOUDABI_ENXIO           60
+#define CLOUDABI_EOVERFLOW       61
+#define CLOUDABI_EOWNERDEAD      62
+#define CLOUDABI_EPERM           63
+#define CLOUDABI_EPIPE           64
+#define CLOUDABI_EPROTO          65
 #define CLOUDABI_EPROTONOSUPPORT 66
-#define CLOUDABI_EPROTOTYPE 67
-#define CLOUDABI_ERANGE 68
-#define CLOUDABI_EROFS 69
-#define CLOUDABI_ESPIPE 70
-#define CLOUDABI_ESRCH 71
-#define CLOUDABI_ESTALE 72
-#define CLOUDABI_ETIMEDOUT 73
-#define CLOUDABI_ETXTBSY 74
-#define CLOUDABI_EXDEV 75
-#define CLOUDABI_ENOTCAPABLE 76
+#define CLOUDABI_EPROTOTYPE      67
+#define CLOUDABI_ERANGE          68
+#define CLOUDABI_EROFS           69
+#define CLOUDABI_ESPIPE          70
+#define CLOUDABI_ESRCH           71
+#define CLOUDABI_ESTALE          72
+#define CLOUDABI_ETIMEDOUT       73
+#define CLOUDABI_ETXTBSY         74
+#define CLOUDABI_EXDEV           75
+#define CLOUDABI_ENOTCAPABLE     76
 
 typedef uint16_t cloudabi_eventrwflags_t;
 #define CLOUDABI_EVENT_FD_READWRITE_HANGUP 0x0001
 
 typedef uint8_t cloudabi_eventtype_t;
-#define CLOUDABI_EVENTTYPE_CLOCK 1
-#define CLOUDABI_EVENTTYPE_CONDVAR 2
-#define CLOUDABI_EVENTTYPE_FD_READ 3
-#define CLOUDABI_EVENTTYPE_FD_WRITE 4
-#define CLOUDABI_EVENTTYPE_LOCK_RDLOCK 5
-#define CLOUDABI_EVENTTYPE_LOCK_WRLOCK 6
+#define CLOUDABI_EVENTTYPE_CLOCK          1
+#define CLOUDABI_EVENTTYPE_CONDVAR        2
+#define CLOUDABI_EVENTTYPE_FD_READ        3
+#define CLOUDABI_EVENTTYPE_FD_WRITE       4
+#define CLOUDABI_EVENTTYPE_LOCK_RDLOCK    5
+#define CLOUDABI_EVENTTYPE_LOCK_WRLOCK    6
 #define CLOUDABI_EVENTTYPE_PROC_TERMINATE 7
 
 typedef uint32_t cloudabi_exitcode_t;
 
 typedef uint32_t cloudabi_fd_t;
 #define CLOUDABI_PROCESS_CHILD 0xffffffff
-#define CLOUDABI_MAP_ANON_FD 0xffffffff
+#define CLOUDABI_MAP_ANON_FD   0xffffffff
 
 typedef uint16_t cloudabi_fdflags_t;
-#define CLOUDABI_FDFLAG_APPEND 0x0001
-#define CLOUDABI_FDFLAG_DSYNC 0x0002
+#define CLOUDABI_FDFLAG_APPEND   0x0001
+#define CLOUDABI_FDFLAG_DSYNC    0x0002
 #define CLOUDABI_FDFLAG_NONBLOCK 0x0004
-#define CLOUDABI_FDFLAG_RSYNC 0x0008
-#define CLOUDABI_FDFLAG_SYNC 0x0010
+#define CLOUDABI_FDFLAG_RSYNC    0x0008
+#define CLOUDABI_FDFLAG_SYNC     0x0010
 
 typedef uint16_t cloudabi_fdsflags_t;
-#define CLOUDABI_FDSTAT_FLAGS 0x0001
+#define CLOUDABI_FDSTAT_FLAGS  0x0001
 #define CLOUDABI_FDSTAT_RIGHTS 0x0002
 
 typedef int64_t cloudabi_filedelta_t;
@@ -187,155 +187,155 @@ typedef int64_t cloudabi_filedelta_t;
 typedef uint64_t cloudabi_filesize_t;
 
 typedef uint8_t cloudabi_filetype_t;
-#define CLOUDABI_FILETYPE_UNKNOWN 0
-#define CLOUDABI_FILETYPE_BLOCK_DEVICE 16
-#define CLOUDABI_FILETYPE_CHARACTER_DEVICE 17
-#define CLOUDABI_FILETYPE_DIRECTORY 32
-#define CLOUDABI_FILETYPE_FIFO 48
-#define CLOUDABI_FILETYPE_POLL 64
-#define CLOUDABI_FILETYPE_PROCESS 80
-#define CLOUDABI_FILETYPE_REGULAR_FILE 96
-#define CLOUDABI_FILETYPE_SHARED_MEMORY 112
-#define CLOUDABI_FILETYPE_SOCKET_DGRAM 128
+#define CLOUDABI_FILETYPE_UNKNOWN            0
+#define CLOUDABI_FILETYPE_BLOCK_DEVICE      16
+#define CLOUDABI_FILETYPE_CHARACTER_DEVICE  17
+#define CLOUDABI_FILETYPE_DIRECTORY         32
+#define CLOUDABI_FILETYPE_FIFO              48
+#define CLOUDABI_FILETYPE_POLL              64
+#define CLOUDABI_FILETYPE_PROCESS           80
+#define CLOUDABI_FILETYPE_REGULAR_FILE      96
+#define CLOUDABI_FILETYPE_SHARED_MEMORY    112
+#define CLOUDABI_FILETYPE_SOCKET_DGRAM     128
 #define CLOUDABI_FILETYPE_SOCKET_SEQPACKET 129
-#define CLOUDABI_FILETYPE_SOCKET_STREAM 130
-#define CLOUDABI_FILETYPE_SYMBOLIC_LINK 144
+#define CLOUDABI_FILETYPE_SOCKET_STREAM    130
+#define CLOUDABI_FILETYPE_SYMBOLIC_LINK    144
 
 typedef uint16_t cloudabi_fsflags_t;
-#define CLOUDABI_FILESTAT_ATIM 0x0001
+#define CLOUDABI_FILESTAT_ATIM     0x0001
 #define CLOUDABI_FILESTAT_ATIM_NOW 0x0002
-#define CLOUDABI_FILESTAT_MTIM 0x0004
+#define CLOUDABI_FILESTAT_MTIM     0x0004
 #define CLOUDABI_FILESTAT_MTIM_NOW 0x0008
-#define CLOUDABI_FILESTAT_SIZE 0x0010
+#define CLOUDABI_FILESTAT_SIZE     0x0010
 
 typedef uint64_t cloudabi_inode_t;
 
 typedef uint32_t cloudabi_linkcount_t;
 
 typedef uint32_t cloudabi_lock_t;
-#define CLOUDABI_LOCK_UNLOCKED 0x00000000
-#define CLOUDABI_LOCK_WRLOCKED 0x40000000
+#define CLOUDABI_LOCK_UNLOCKED       0x00000000
+#define CLOUDABI_LOCK_WRLOCKED       0x40000000
 #define CLOUDABI_LOCK_KERNEL_MANAGED 0x80000000
-#define CLOUDABI_LOCK_BOGUS 0x80000000
+#define CLOUDABI_LOCK_BOGUS          0x80000000
 
 typedef uint32_t cloudabi_lookupflags_t;
 #define CLOUDABI_LOOKUP_SYMLINK_FOLLOW 0x00000001
 
 typedef uint8_t cloudabi_mflags_t;
-#define CLOUDABI_MAP_ANON 0x01
-#define CLOUDABI_MAP_FIXED 0x02
+#define CLOUDABI_MAP_ANON    0x01
+#define CLOUDABI_MAP_FIXED   0x02
 #define CLOUDABI_MAP_PRIVATE 0x04
-#define CLOUDABI_MAP_SHARED 0x08
+#define CLOUDABI_MAP_SHARED  0x08
 
 typedef uint8_t cloudabi_mprot_t;
-#define CLOUDABI_PROT_EXEC 0x01
+#define CLOUDABI_PROT_EXEC  0x01
 #define CLOUDABI_PROT_WRITE 0x02
-#define CLOUDABI_PROT_READ 0x04
+#define CLOUDABI_PROT_READ  0x04
 
 typedef uint8_t cloudabi_msflags_t;
-#define CLOUDABI_MS_ASYNC 0x01
+#define CLOUDABI_MS_ASYNC      0x01
 #define CLOUDABI_MS_INVALIDATE 0x02
-#define CLOUDABI_MS_SYNC 0x04
+#define CLOUDABI_MS_SYNC       0x04
 
 typedef uint16_t cloudabi_msgflags_t;
-#define CLOUDABI_MSG_CTRUNC 0x0001
-#define CLOUDABI_MSG_EOR 0x0002
-#define CLOUDABI_MSG_PEEK 0x0004
-#define CLOUDABI_MSG_TRUNC 0x0008
+#define CLOUDABI_MSG_CTRUNC  0x0001
+#define CLOUDABI_MSG_EOR     0x0002
+#define CLOUDABI_MSG_PEEK    0x0004
+#define CLOUDABI_MSG_TRUNC   0x0008
 #define CLOUDABI_MSG_WAITALL 0x0010
 
 typedef uint32_t cloudabi_nthreads_t;
 
 typedef uint16_t cloudabi_oflags_t;
-#define CLOUDABI_O_CREAT 0x0001
+#define CLOUDABI_O_CREAT     0x0001
 #define CLOUDABI_O_DIRECTORY 0x0002
-#define CLOUDABI_O_EXCL 0x0004
-#define CLOUDABI_O_TRUNC 0x0008
+#define CLOUDABI_O_EXCL      0x0004
+#define CLOUDABI_O_TRUNC     0x0008
 
 typedef uint64_t cloudabi_rights_t;
-#define CLOUDABI_RIGHT_FD_DATASYNC 0x0000000000000001
-#define CLOUDABI_RIGHT_FD_READ 0x0000000000000002
-#define CLOUDABI_RIGHT_FD_SEEK 0x0000000000000004
-#define CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS 0x0000000000000008
-#define CLOUDABI_RIGHT_FD_SYNC 0x0000000000000010
-#define CLOUDABI_RIGHT_FD_TELL 0x0000000000000020
-#define CLOUDABI_RIGHT_FD_WRITE 0x0000000000000040
-#define CLOUDABI_RIGHT_FILE_ADVISE 0x0000000000000080
-#define CLOUDABI_RIGHT_FILE_ALLOCATE 0x0000000000000100
-#define CLOUDABI_RIGHT_FILE_CREATE_DIRECTORY 0x0000000000000200
-#define CLOUDABI_RIGHT_FILE_CREATE_FILE 0x0000000000000400
-#define CLOUDABI_RIGHT_FILE_CREATE_FIFO 0x0000000000000800
-#define CLOUDABI_RIGHT_FILE_LINK_SOURCE 0x0000000000001000
-#define CLOUDABI_RIGHT_FILE_LINK_TARGET 0x0000000000002000
-#define CLOUDABI_RIGHT_FILE_OPEN 0x0000000000004000
-#define CLOUDABI_RIGHT_FILE_READDIR 0x0000000000008000
-#define CLOUDABI_RIGHT_FILE_READLINK 0x0000000000010000
-#define CLOUDABI_RIGHT_FILE_RENAME_SOURCE 0x0000000000020000
-#define CLOUDABI_RIGHT_FILE_RENAME_TARGET 0x0000000000040000
-#define CLOUDABI_RIGHT_FILE_STAT_FGET 0x0000000000080000
-#define CLOUDABI_RIGHT_FILE_STAT_FPUT_SIZE 0x0000000000100000
-#define CLOUDABI_RIGHT_FILE_STAT_FPUT_TIMES 0x0000000000200000
-#define CLOUDABI_RIGHT_FILE_STAT_GET 0x0000000000400000
-#define CLOUDABI_RIGHT_FILE_STAT_PUT_TIMES 0x0000000000800000
-#define CLOUDABI_RIGHT_FILE_SYMLINK 0x0000000001000000
-#define CLOUDABI_RIGHT_FILE_UNLINK 0x0000000002000000
-#define CLOUDABI_RIGHT_MEM_MAP 0x0000000004000000
-#define CLOUDABI_RIGHT_MEM_MAP_EXEC 0x0000000008000000
-#define CLOUDABI_RIGHT_POLL_FD_READWRITE 0x0000000010000000
-#define CLOUDABI_RIGHT_POLL_MODIFY 0x0000000020000000
-#define CLOUDABI_RIGHT_POLL_PROC_TERMINATE 0x0000000040000000
-#define CLOUDABI_RIGHT_POLL_WAIT 0x0000000080000000
-#define CLOUDABI_RIGHT_PROC_EXEC 0x0000000100000000
-#define CLOUDABI_RIGHT_SOCK_ACCEPT 0x0000000200000000
-#define CLOUDABI_RIGHT_SOCK_BIND_DIRECTORY 0x0000000400000000
-#define CLOUDABI_RIGHT_SOCK_BIND_SOCKET 0x0000000800000000
+#define CLOUDABI_RIGHT_FD_DATASYNC            0x0000000000000001
+#define CLOUDABI_RIGHT_FD_READ                0x0000000000000002
+#define CLOUDABI_RIGHT_FD_SEEK                0x0000000000000004
+#define CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS      0x0000000000000008
+#define CLOUDABI_RIGHT_FD_SYNC                0x0000000000000010
+#define CLOUDABI_RIGHT_FD_TELL                0x0000000000000020
+#define CLOUDABI_RIGHT_FD_WRITE               0x0000000000000040
+#define CLOUDABI_RIGHT_FILE_ADVISE            0x0000000000000080
+#define CLOUDABI_RIGHT_FILE_ALLOCATE          0x0000000000000100
+#define CLOUDABI_RIGHT_FILE_CREATE_DIRECTORY  0x0000000000000200
+#define CLOUDABI_RIGHT_FILE_CREATE_FILE       0x0000000000000400
+#define CLOUDABI_RIGHT_FILE_CREATE_FIFO       0x0000000000000800
+#define CLOUDABI_RIGHT_FILE_LINK_SOURCE       0x0000000000001000
+#define CLOUDABI_RIGHT_FILE_LINK_TARGET       0x0000000000002000
+#define CLOUDABI_RIGHT_FILE_OPEN              0x0000000000004000
+#define CLOUDABI_RIGHT_FILE_READDIR           0x0000000000008000
+#define CLOUDABI_RIGHT_FILE_READLINK          0x0000000000010000
+#define CLOUDABI_RIGHT_FILE_RENAME_SOURCE     0x0000000000020000
+#define CLOUDABI_RIGHT_FILE_RENAME_TARGET     0x0000000000040000
+#define CLOUDABI_RIGHT_FILE_STAT_FGET         0x0000000000080000
+#define CLOUDABI_RIGHT_FILE_STAT_FPUT_SIZE    0x0000000000100000
+#define CLOUDABI_RIGHT_FILE_STAT_FPUT_TIMES   0x0000000000200000
+#define CLOUDABI_RIGHT_FILE_STAT_GET          0x0000000000400000
+#define CLOUDABI_RIGHT_FILE_STAT_PUT_TIMES    0x0000000000800000
+#define CLOUDABI_RIGHT_FILE_SYMLINK           0x0000000001000000
+#define CLOUDABI_RIGHT_FILE_UNLINK            0x0000000002000000
+#define CLOUDABI_RIGHT_MEM_MAP                0x0000000004000000
+#define CLOUDABI_RIGHT_MEM_MAP_EXEC           0x0000000008000000
+#define CLOUDABI_RIGHT_POLL_FD_READWRITE      0x0000000010000000
+#define CLOUDABI_RIGHT_POLL_MODIFY            0x0000000020000000
+#define CLOUDABI_RIGHT_POLL_PROC_TERMINATE    0x0000000040000000
+#define CLOUDABI_RIGHT_POLL_WAIT              0x0000000080000000
+#define CLOUDABI_RIGHT_PROC_EXEC              0x0000000100000000
+#define CLOUDABI_RIGHT_SOCK_ACCEPT            0x0000000200000000
+#define CLOUDABI_RIGHT_SOCK_BIND_DIRECTORY    0x0000000400000000
+#define CLOUDABI_RIGHT_SOCK_BIND_SOCKET       0x0000000800000000
 #define CLOUDABI_RIGHT_SOCK_CONNECT_DIRECTORY 0x0000001000000000
-#define CLOUDABI_RIGHT_SOCK_CONNECT_SOCKET 0x0000002000000000
-#define CLOUDABI_RIGHT_SOCK_LISTEN 0x0000004000000000
-#define CLOUDABI_RIGHT_SOCK_SHUTDOWN 0x0000008000000000
-#define CLOUDABI_RIGHT_SOCK_STAT_GET 0x0000010000000000
+#define CLOUDABI_RIGHT_SOCK_CONNECT_SOCKET    0x0000002000000000
+#define CLOUDABI_RIGHT_SOCK_LISTEN            0x0000004000000000
+#define CLOUDABI_RIGHT_SOCK_SHUTDOWN          0x0000008000000000
+#define CLOUDABI_RIGHT_SOCK_STAT_GET          0x0000010000000000
 
 typedef uint8_t cloudabi_sa_family_t;
 #define CLOUDABI_AF_UNSPEC 0
-#define CLOUDABI_AF_INET 1
-#define CLOUDABI_AF_INET6 2
-#define CLOUDABI_AF_UNIX 3
+#define CLOUDABI_AF_INET   1
+#define CLOUDABI_AF_INET6  2
+#define CLOUDABI_AF_UNIX   3
 
 typedef uint8_t cloudabi_scope_t;
 #define CLOUDABI_SCOPE_PRIVATE 4
-#define CLOUDABI_SCOPE_SHARED 8
+#define CLOUDABI_SCOPE_SHARED  8
 
 typedef uint8_t cloudabi_sdflags_t;
 #define CLOUDABI_SHUT_RD 0x01
 #define CLOUDABI_SHUT_WR 0x02
 
 typedef uint8_t cloudabi_signal_t;
-#define CLOUDABI_SIGABRT 1
-#define CLOUDABI_SIGALRM 2
-#define CLOUDABI_SIGBUS 3
-#define CLOUDABI_SIGCHLD 4
-#define CLOUDABI_SIGCONT 5
-#define CLOUDABI_SIGFPE 6
-#define CLOUDABI_SIGHUP 7
-#define CLOUDABI_SIGILL 8
-#define CLOUDABI_SIGINT 9
-#define CLOUDABI_SIGKILL 10
-#define CLOUDABI_SIGPIPE 11
-#define CLOUDABI_SIGQUIT 12
-#define CLOUDABI_SIGSEGV 13
-#define CLOUDABI_SIGSTOP 14
-#define CLOUDABI_SIGSYS 15
-#define CLOUDABI_SIGTERM 16
-#define CLOUDABI_SIGTRAP 17
-#define CLOUDABI_SIGTSTP 18
-#define CLOUDABI_SIGTTIN 19
-#define CLOUDABI_SIGTTOU 20
-#define CLOUDABI_SIGURG 21
-#define CLOUDABI_SIGUSR1 22
-#define CLOUDABI_SIGUSR2 23
+#define CLOUDABI_SIGABRT    1
+#define CLOUDABI_SIGALRM    2
+#define CLOUDABI_SIGBUS     3
+#define CLOUDABI_SIGCHLD    4
+#define CLOUDABI_SIGCONT    5
+#define CLOUDABI_SIGFPE     6
+#define CLOUDABI_SIGHUP     7
+#define CLOUDABI_SIGILL     8
+#define CLOUDABI_SIGINT     9
+#define CLOUDABI_SIGKILL   10
+#define CLOUDABI_SIGPIPE   11
+#define CLOUDABI_SIGQUIT   12
+#define CLOUDABI_SIGSEGV   13
+#define CLOUDABI_SIGSTOP   14
+#define CLOUDABI_SIGSYS    15
+#define CLOUDABI_SIGTERM   16
+#define CLOUDABI_SIGTRAP   17
+#define CLOUDABI_SIGTSTP   18
+#define CLOUDABI_SIGTTIN   19
+#define CLOUDABI_SIGTTOU   20
+#define CLOUDABI_SIGURG    21
+#define CLOUDABI_SIGUSR1   22
+#define CLOUDABI_SIGUSR2   23
 #define CLOUDABI_SIGVTALRM 24
-#define CLOUDABI_SIGXCPU 25
-#define CLOUDABI_SIGXFSZ 26
+#define CLOUDABI_SIGXCPU   25
+#define CLOUDABI_SIGXFSZ   26
 
 typedef uint8_t cloudabi_ssflags_t;
 #define CLOUDABI_SOCKSTAT_CLEAR_ERROR 0x01
@@ -347,11 +347,11 @@ typedef uint16_t cloudabi_subclockflags_t;
 #define CLOUDABI_SUBSCRIPTION_CLOCK_ABSTIME 0x0001
 
 typedef uint16_t cloudabi_subflags_t;
-#define CLOUDABI_SUBSCRIPTION_ADD 0x0001
-#define CLOUDABI_SUBSCRIPTION_CLEAR 0x0002
-#define CLOUDABI_SUBSCRIPTION_DELETE 0x0004
+#define CLOUDABI_SUBSCRIPTION_ADD     0x0001
+#define CLOUDABI_SUBSCRIPTION_CLEAR   0x0002
+#define CLOUDABI_SUBSCRIPTION_DELETE  0x0004
 #define CLOUDABI_SUBSCRIPTION_DISABLE 0x0008
-#define CLOUDABI_SUBSCRIPTION_ENABLE 0x0010
+#define CLOUDABI_SUBSCRIPTION_ENABLE  0x0010
 #define CLOUDABI_SUBSCRIPTION_ONESHOT 0x0020
 
 typedef uint16_t cloudabi_subrwflags_t;
@@ -390,13 +390,10 @@ typedef struct {
   _Alignas(8) cloudabi_rights_t fs_rights_base;
   _Alignas(8) cloudabi_rights_t fs_rights_inheriting;
 } cloudabi_fdstat_t;
-_Static_assert(offsetof(cloudabi_fdstat_t, fs_filetype) == 0,
-               "Incorrect layout");
+_Static_assert(offsetof(cloudabi_fdstat_t, fs_filetype) == 0, "Incorrect layout");
 _Static_assert(offsetof(cloudabi_fdstat_t, fs_flags) == 2, "Incorrect layout");
-_Static_assert(offsetof(cloudabi_fdstat_t, fs_rights_base) == 8,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi_fdstat_t, fs_rights_inheriting) == 16,
-               "Incorrect layout");
+_Static_assert(offsetof(cloudabi_fdstat_t, fs_rights_base) == 8, "Incorrect layout");
+_Static_assert(offsetof(cloudabi_fdstat_t, fs_rights_inheriting) == 16, "Incorrect layout");
 _Static_assert(sizeof(cloudabi_fdstat_t) == 24, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi_fdstat_t) == 8, "Incorrect layout");
 
@@ -412,18 +409,12 @@ typedef struct {
 } cloudabi_filestat_t;
 _Static_assert(offsetof(cloudabi_filestat_t, st_dev) == 0, "Incorrect layout");
 _Static_assert(offsetof(cloudabi_filestat_t, st_ino) == 8, "Incorrect layout");
-_Static_assert(offsetof(cloudabi_filestat_t, st_filetype) == 16,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi_filestat_t, st_nlink) == 20,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi_filestat_t, st_size) == 24,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi_filestat_t, st_atim) == 32,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi_filestat_t, st_mtim) == 40,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi_filestat_t, st_ctim) == 48,
-               "Incorrect layout");
+_Static_assert(offsetof(cloudabi_filestat_t, st_filetype) == 16, "Incorrect layout");
+_Static_assert(offsetof(cloudabi_filestat_t, st_nlink) == 20, "Incorrect layout");
+_Static_assert(offsetof(cloudabi_filestat_t, st_size) == 24, "Incorrect layout");
+_Static_assert(offsetof(cloudabi_filestat_t, st_atim) == 32, "Incorrect layout");
+_Static_assert(offsetof(cloudabi_filestat_t, st_mtim) == 40, "Incorrect layout");
+_Static_assert(offsetof(cloudabi_filestat_t, st_ctim) == 48, "Incorrect layout");
 _Static_assert(sizeof(cloudabi_filestat_t) == 56, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi_filestat_t) == 8, "Incorrect layout");
 
@@ -449,16 +440,11 @@ typedef struct {
     } sa_inet6;
   };
 } cloudabi_sockaddr_t;
-_Static_assert(offsetof(cloudabi_sockaddr_t, sa_family) == 0,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi_sockaddr_t, sa_inet.addr) == 2,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi_sockaddr_t, sa_inet.port) == 6,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi_sockaddr_t, sa_inet6.addr) == 2,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi_sockaddr_t, sa_inet6.port) == 18,
-               "Incorrect layout");
+_Static_assert(offsetof(cloudabi_sockaddr_t, sa_family) == 0, "Incorrect layout");
+_Static_assert(offsetof(cloudabi_sockaddr_t, sa_inet.addr) == 2, "Incorrect layout");
+_Static_assert(offsetof(cloudabi_sockaddr_t, sa_inet.port) == 6, "Incorrect layout");
+_Static_assert(offsetof(cloudabi_sockaddr_t, sa_inet6.addr) == 2, "Incorrect layout");
+_Static_assert(offsetof(cloudabi_sockaddr_t, sa_inet6.port) == 18, "Incorrect layout");
 _Static_assert(sizeof(cloudabi_sockaddr_t) == 20, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi_sockaddr_t) == 2, "Incorrect layout");
 
@@ -468,14 +454,10 @@ typedef struct {
   _Alignas(2) cloudabi_errno_t ss_error;
   _Alignas(4) cloudabi_sstate_t ss_state;
 } cloudabi_sockstat_t;
-_Static_assert(offsetof(cloudabi_sockstat_t, ss_sockname) == 0,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi_sockstat_t, ss_peername) == 20,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi_sockstat_t, ss_error) == 40,
-               "Incorrect layout");
-_Static_assert(offsetof(cloudabi_sockstat_t, ss_state) == 44,
-               "Incorrect layout");
+_Static_assert(offsetof(cloudabi_sockstat_t, ss_sockname) == 0, "Incorrect layout");
+_Static_assert(offsetof(cloudabi_sockstat_t, ss_peername) == 20, "Incorrect layout");
+_Static_assert(offsetof(cloudabi_sockstat_t, ss_error) == 40, "Incorrect layout");
+_Static_assert(offsetof(cloudabi_sockstat_t, ss_state) == 44, "Incorrect layout");
 _Static_assert(sizeof(cloudabi_sockstat_t) == 48, "Incorrect layout");
 _Static_assert(_Alignof(cloudabi_sockstat_t) == 4, "Incorrect layout");
 
diff --git a/sys/contrib/cloudabi/syscalls32.master b/sys/contrib/cloudabi/syscalls32.master
index aa3314b8fa7..4e0c2b29324 100644
--- a/sys/contrib/cloudabi/syscalls32.master
+++ b/sys/contrib/cloudabi/syscalls32.master
@@ -65,20 +65,20 @@
 
 8	AUE_NULL	STD	{ size_t cloudabi32_sys_fd_pread( \
 					cloudabi_fd_t fd, \
-					const cloudabi32_iovec_t *iov, \
-					size_t iovcnt, \
+					const cloudabi32_iovec_t *iovs, \
+					size_t iovs_len, \
 					cloudabi_filesize_t offset); }
 
 9	AUE_NULL	STD	{ size_t cloudabi32_sys_fd_pwrite( \
 					cloudabi_fd_t fd, \
-					const cloudabi32_ciovec_t *iov, \
-					size_t iovcnt, \
+					const cloudabi32_ciovec_t *iovs, \
+					size_t iovs_len, \
 					cloudabi_filesize_t offset); }
 
 10	AUE_NULL	STD	{ size_t cloudabi32_sys_fd_read( \
 					cloudabi_fd_t fd, \
-					const cloudabi32_iovec_t *iov, \
-					size_t iovcnt); }
+					const cloudabi32_iovec_t *iovs, \
+					size_t iovs_len); }
 
 11	AUE_NULL	STD	{ void cloudabi_sys_fd_replace( \
 					cloudabi_fd_t from, \
@@ -104,8 +104,8 @@
 
 16	AUE_NULL	STD	{ size_t cloudabi32_sys_fd_write( \
 					cloudabi_fd_t fd, \
-					const cloudabi32_ciovec_t *iov, \
-					size_t iovcnt); }
+					const cloudabi32_ciovec_t *iovs, \
+					size_t iovs_len); }
 
 17	AUE_NULL	STD	{ void cloudabi_sys_file_advise( \
 					cloudabi_fd_t fd, \
@@ -121,44 +121,44 @@
 19	AUE_NULL	STD	{ void cloudabi_sys_file_create( \
 					cloudabi_fd_t fd, \
 					const char *path, \
-					size_t pathlen, \
+					size_t path_len, \
 					cloudabi_filetype_t type); }
 
 20	AUE_NULL	STD	{ void cloudabi_sys_file_link( \
 					cloudabi_lookup_t fd1, \
 					const char *path1, \
-					size_t path1len, \
+					size_t path1_len, \
 					cloudabi_fd_t fd2, \
 					const char *path2, \
-					size_t path2len); }
+					size_t path2_len); }
 
 21	AUE_NULL	STD	{ cloudabi_fd_t cloudabi_sys_file_open( \
 					cloudabi_lookup_t dirfd, \
 					const char *path, \
-					size_t pathlen, \
+					size_t path_len, \
 					cloudabi_oflags_t oflags, \
 					const cloudabi_fdstat_t *fds); }
 
 22	AUE_NULL	STD	{ size_t cloudabi_sys_file_readdir( \
 					cloudabi_fd_t fd, \
 					void *buf, \
-					size_t nbyte, \
+					size_t buf_len, \
 					cloudabi_dircookie_t cookie); }
 
 23	AUE_NULL	STD	{ size_t cloudabi_sys_file_readlink( \
 					cloudabi_fd_t fd, \
 					const char *path, \
-					size_t pathlen, \
+					size_t path_len, \
 					char *buf, \
-					size_t bufsize); }
+					size_t buf_len); }
 
 24	AUE_NULL	STD	{ void cloudabi_sys_file_rename( \
-					cloudabi_fd_t oldfd, \
-					const char *old, \
-					size_t oldlen, \
-					cloudabi_fd_t newfd, \
-					const char *new, \
-					size_t newlen); }
+					cloudabi_fd_t fd1, \
+					const char *path1, \
+					size_t path1_len, \
+					cloudabi_fd_t fd2, \
+					const char *path2, \
+					size_t path2_len); }
 
 25	AUE_NULL	STD	{ void cloudabi_sys_file_stat_fget( \
 					cloudabi_fd_t fd, \
@@ -172,27 +172,27 @@
 27	AUE_NULL	STD	{ void cloudabi_sys_file_stat_get( \
 					cloudabi_lookup_t fd, \
 					const char *path, \
-					size_t pathlen, \
+					size_t path_len, \
 					cloudabi_filestat_t *buf); }
 
 28	AUE_NULL	STD	{ void cloudabi_sys_file_stat_put( \
 					cloudabi_lookup_t fd, \
 					const char *path, \
-					size_t pathlen, \
+					size_t path_len, \
 					const cloudabi_filestat_t *buf, \
 					cloudabi_fsflags_t flags); }
 
 29	AUE_NULL	STD	{ void cloudabi_sys_file_symlink( \
 					const char *path1, \
-					size_t path1len, \
+					size_t path1_len, \
 					cloudabi_fd_t fd, \
 					const char *path2, \
-					size_t path2len); }
+					size_t path2_len); }
 
 30	AUE_NULL	STD	{ void cloudabi_sys_file_unlink( \
 					cloudabi_fd_t fd, \
 					const char *path, \
-					size_t pathlen, \
+					size_t path_len, \
 					cloudabi_ulflags_t flags); }
 
 31	AUE_NULL	STD	{ void cloudabi_sys_lock_unlock( \
@@ -200,13 +200,13 @@
 					cloudabi_scope_t scope); }
 
 32	AUE_NULL	STD	{ void cloudabi_sys_mem_advise( \
-					void *addr, \
-					size_t len, \
+					void *mapping, \
+					size_t mapping_len, \
 					cloudabi_advice_t advice); }
 
 33	AUE_NULL	STD	{ void cloudabi_sys_mem_lock( \
-					const void *addr, \
-					size_t len); }
+					const void *mapping, \
+					size_t mapping_len); }
 
 34	AUE_NULL	STD	{ void cloudabi_sys_mem_map( \
 					void *addr, \
@@ -217,22 +217,22 @@
 					cloudabi_filesize_t off); }
 
 35	AUE_NULL	STD	{ void cloudabi_sys_mem_protect( \
-					void *addr, \
-					size_t len, \
+					void *mapping, \
+					size_t mapping_len, \
 					cloudabi_mprot_t prot); }
 
 36	AUE_NULL	STD	{ void cloudabi_sys_mem_sync( \
-					void *addr, \
-					size_t len, \
+					void *mapping, \
+					size_t mapping_len, \
 					cloudabi_msflags_t flags); }
 
 37	AUE_NULL	STD	{ void cloudabi_sys_mem_unlock( \
-					const void *addr, \
-					size_t len); }
+					const void *mapping, \
+					size_t mapping_len); }
 
 38	AUE_NULL	STD	{ void cloudabi_sys_mem_unmap( \
-					void *addr, \
-					size_t len); }
+					void *mapping, \
+					size_t mapping_len); }
 
 39	AUE_NULL	STD	{ size_t cloudabi32_sys_poll( \
 					const cloudabi32_subscription_t *in, \
@@ -242,17 +242,17 @@
 40	AUE_NULL	STD	{ size_t cloudabi32_sys_poll_fd( \
 					cloudabi_fd_t fd, \
 					const cloudabi32_subscription_t *in, \
-					size_t nin, \
+					size_t in_len, \
 					cloudabi32_event_t *out, \
-					size_t nout, \
+					size_t out_len, \
 					const cloudabi32_subscription_t *timeout); }
 
 41	AUE_NULL	STD	{ void cloudabi_sys_proc_exec( \
 					cloudabi_fd_t fd, \
 					const void *data, \
-					size_t datalen, \
+					size_t data_len, \
 					const cloudabi_fd_t *fds, \
-					size_t fdslen); }
+					size_t fds_len); }
 
 42	AUE_NULL	STD	{ void cloudabi_sys_proc_exit( \
 					cloudabi_exitcode_t rval); }
@@ -264,7 +264,7 @@
 
 45	AUE_NULL	STD	{ void cloudabi_sys_random_get( \
 					void *buf, \
-					size_t nbyte); }
+					size_t buf_len); }
 
 46	AUE_NULL	STD	{ cloudabi_fd_t cloudabi_sys_sock_accept( \
 					cloudabi_fd_t sock, \
@@ -274,13 +274,13 @@
 					cloudabi_fd_t sock, \
 					cloudabi_fd_t fd, \
 					const char *path, \
-					size_t pathlen); }
+					size_t path_len); }
 
 48	AUE_NULL	STD	{ void cloudabi_sys_sock_connect( \
 					cloudabi_fd_t sock, \
 					cloudabi_fd_t fd, \
 					const char *path, \
-					size_t pathlen); }
+					size_t path_len); }
 
 49	AUE_NULL	STD	{ void cloudabi_sys_sock_listen( \
 					cloudabi_fd_t sock, \
diff --git a/sys/contrib/cloudabi/syscalls64.master b/sys/contrib/cloudabi/syscalls64.master
index b2378bdb9fe..7f57d76ce87 100644
--- a/sys/contrib/cloudabi/syscalls64.master
+++ b/sys/contrib/cloudabi/syscalls64.master
@@ -65,20 +65,20 @@
 
 8	AUE_NULL	STD	{ size_t cloudabi64_sys_fd_pread( \
 					cloudabi_fd_t fd, \
-					const cloudabi64_iovec_t *iov, \
-					size_t iovcnt, \
+					const cloudabi64_iovec_t *iovs, \
+					size_t iovs_len, \
 					cloudabi_filesize_t offset); }
 
 9	AUE_NULL	STD	{ size_t cloudabi64_sys_fd_pwrite( \
 					cloudabi_fd_t fd, \
-					const cloudabi64_ciovec_t *iov, \
-					size_t iovcnt, \
+					const cloudabi64_ciovec_t *iovs, \
+					size_t iovs_len, \
 					cloudabi_filesize_t offset); }
 
 10	AUE_NULL	STD	{ size_t cloudabi64_sys_fd_read( \
 					cloudabi_fd_t fd, \
-					const cloudabi64_iovec_t *iov, \
-					size_t iovcnt); }
+					const cloudabi64_iovec_t *iovs, \
+					size_t iovs_len); }
 
 11	AUE_NULL	STD	{ void cloudabi_sys_fd_replace( \
 					cloudabi_fd_t from, \
@@ -104,8 +104,8 @@
 
 16	AUE_NULL	STD	{ size_t cloudabi64_sys_fd_write( \
 					cloudabi_fd_t fd, \
-					const cloudabi64_ciovec_t *iov, \
-					size_t iovcnt); }
+					const cloudabi64_ciovec_t *iovs, \
+					size_t iovs_len); }
 
 17	AUE_NULL	STD	{ void cloudabi_sys_file_advise( \
 					cloudabi_fd_t fd, \
@@ -121,44 +121,44 @@
 19	AUE_NULL	STD	{ void cloudabi_sys_file_create( \
 					cloudabi_fd_t fd, \
 					const char *path, \
-					size_t pathlen, \
+					size_t path_len, \
 					cloudabi_filetype_t type); }
 
 20	AUE_NULL	STD	{ void cloudabi_sys_file_link( \
 					cloudabi_lookup_t fd1, \
 					const char *path1, \
-					size_t path1len, \
+					size_t path1_len, \
 					cloudabi_fd_t fd2, \
 					const char *path2, \
-					size_t path2len); }
+					size_t path2_len); }
 
 21	AUE_NULL	STD	{ cloudabi_fd_t cloudabi_sys_file_open( \
 					cloudabi_lookup_t dirfd, \
 					const char *path, \
-					size_t pathlen, \
+					size_t path_len, \
 					cloudabi_oflags_t oflags, \
 					const cloudabi_fdstat_t *fds); }
 
 22	AUE_NULL	STD	{ size_t cloudabi_sys_file_readdir( \
 					cloudabi_fd_t fd, \
 					void *buf, \
-					size_t nbyte, \
+					size_t buf_len, \
 					cloudabi_dircookie_t cookie); }
 
 23	AUE_NULL	STD	{ size_t cloudabi_sys_file_readlink( \
 					cloudabi_fd_t fd, \
 					const char *path, \
-					size_t pathlen, \
+					size_t path_len, \
 					char *buf, \
-					size_t bufsize); }
+					size_t buf_len); }
 
 24	AUE_NULL	STD	{ void cloudabi_sys_file_rename( \
-					cloudabi_fd_t oldfd, \
-					const char *old, \
-					size_t oldlen, \
-					cloudabi_fd_t newfd, \
-					const char *new, \
-					size_t newlen); }
+					cloudabi_fd_t fd1, \
+					const char *path1, \
+					size_t path1_len, \
+					cloudabi_fd_t fd2, \
+					const char *path2, \
+					size_t path2_len); }
 
 25	AUE_NULL	STD	{ void cloudabi_sys_file_stat_fget( \
 					cloudabi_fd_t fd, \
@@ -172,27 +172,27 @@
 27	AUE_NULL	STD	{ void cloudabi_sys_file_stat_get( \
 					cloudabi_lookup_t fd, \
 					const char *path, \
-					size_t pathlen, \
+					size_t path_len, \
 					cloudabi_filestat_t *buf); }
 
 28	AUE_NULL	STD	{ void cloudabi_sys_file_stat_put( \
 					cloudabi_lookup_t fd, \
 					const char *path, \
-					size_t pathlen, \
+					size_t path_len, \
 					const cloudabi_filestat_t *buf, \
 					cloudabi_fsflags_t flags); }
 
 29	AUE_NULL	STD	{ void cloudabi_sys_file_symlink( \
 					const char *path1, \
-					size_t path1len, \
+					size_t path1_len, \
 					cloudabi_fd_t fd, \
 					const char *path2, \
-					size_t path2len); }
+					size_t path2_len); }
 
 30	AUE_NULL	STD	{ void cloudabi_sys_file_unlink( \
 					cloudabi_fd_t fd, \
 					const char *path, \
-					size_t pathlen, \
+					size_t path_len, \
 					cloudabi_ulflags_t flags); }
 
 31	AUE_NULL	STD	{ void cloudabi_sys_lock_unlock( \
@@ -200,13 +200,13 @@
 					cloudabi_scope_t scope); }
 
 32	AUE_NULL	STD	{ void cloudabi_sys_mem_advise( \
-					void *addr, \
-					size_t len, \
+					void *mapping, \
+					size_t mapping_len, \
 					cloudabi_advice_t advice); }
 
 33	AUE_NULL	STD	{ void cloudabi_sys_mem_lock( \
-					const void *addr, \
-					size_t len); }
+					const void *mapping, \
+					size_t mapping_len); }
 
 34	AUE_NULL	STD	{ void cloudabi_sys_mem_map( \
 					void *addr, \
@@ -217,22 +217,22 @@
 					cloudabi_filesize_t off); }
 
 35	AUE_NULL	STD	{ void cloudabi_sys_mem_protect( \
-					void *addr, \
-					size_t len, \
+					void *mapping, \
+					size_t mapping_len, \
 					cloudabi_mprot_t prot); }
 
 36	AUE_NULL	STD	{ void cloudabi_sys_mem_sync( \
-					void *addr, \
-					size_t len, \
+					void *mapping, \
+					size_t mapping_len, \
 					cloudabi_msflags_t flags); }
 
 37	AUE_NULL	STD	{ void cloudabi_sys_mem_unlock( \
-					const void *addr, \
-					size_t len); }
+					const void *mapping, \
+					size_t mapping_len); }
 
 38	AUE_NULL	STD	{ void cloudabi_sys_mem_unmap( \
-					void *addr, \
-					size_t len); }
+					void *mapping, \
+					size_t mapping_len); }
 
 39	AUE_NULL	STD	{ size_t cloudabi64_sys_poll( \
 					const cloudabi64_subscription_t *in, \
@@ -242,17 +242,17 @@
 40	AUE_NULL	STD	{ size_t cloudabi64_sys_poll_fd( \
 					cloudabi_fd_t fd, \
 					const cloudabi64_subscription_t *in, \
-					size_t nin, \
+					size_t in_len, \
 					cloudabi64_event_t *out, \
-					size_t nout, \
+					size_t out_len, \
 					const cloudabi64_subscription_t *timeout); }
 
 41	AUE_NULL	STD	{ void cloudabi_sys_proc_exec( \
 					cloudabi_fd_t fd, \
 					const void *data, \
-					size_t datalen, \
+					size_t data_len, \
 					const cloudabi_fd_t *fds, \
-					size_t fdslen); }
+					size_t fds_len); }
 
 42	AUE_NULL	STD	{ void cloudabi_sys_proc_exit( \
 					cloudabi_exitcode_t rval); }
@@ -264,7 +264,7 @@
 
 45	AUE_NULL	STD	{ void cloudabi_sys_random_get( \
 					void *buf, \
-					size_t nbyte); }
+					size_t buf_len); }
 
 46	AUE_NULL	STD	{ cloudabi_fd_t cloudabi_sys_sock_accept( \
 					cloudabi_fd_t sock, \
@@ -274,13 +274,13 @@
 					cloudabi_fd_t sock, \
 					cloudabi_fd_t fd, \
 					const char *path, \
-					size_t pathlen); }
+					size_t path_len); }
 
 48	AUE_NULL	STD	{ void cloudabi_sys_sock_connect( \
 					cloudabi_fd_t sock, \
 					cloudabi_fd_t fd, \
 					const char *path, \
-					size_t pathlen); }
+					size_t path_len); }
 
 49	AUE_NULL	STD	{ void cloudabi_sys_sock_listen( \
 					cloudabi_fd_t sock, \
diff --git a/sys/contrib/dev/acpica/changes.txt b/sys/contrib/dev/acpica/changes.txt
index ee16343813b..4e0d69e5746 100644
--- a/sys/contrib/dev/acpica/changes.txt
+++ b/sys/contrib/dev/acpica/changes.txt
@@ -1,3 +1,38 @@
+----------------------------------------
+19 January 2017. Summary of changes for version 20170119:
+
+This release is available at https://acpica.org/downloads
+
+1) General ACPICA software:
+
+Entire source code base: Added the 2017 copyright to all source code 
+legal/licensing module headers and utility/tool signons. This includes 
+the standard Linux dual-license header. This affects virtually every file 
+in the ACPICA core subsystem, iASL compiler, all ACPICA utilities, and 
+the ACPICA test suite.
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Removed/fixed an inadvertent remark when a method argument 
+containing a reference is used as a target operand within the method (and 
+never used as a simple argument), as in the example below. Jeffrey Hugo.
+
+    dsdt.asl   1507:    Store(0x1, Arg0)
+    Remark   2146 -                ^ Method Argument is never used (Arg0)
+
+All tools: Removed the bit width of the compiler that generated the tool 
+from the common signon for all user space tools. This proved to be 
+confusing and unnecessary. This includes similar removal of HARDWARE_NAME 
+from the generic makefiles (Thomas Petazzoni). Example below.
+
+    Old:
+    ASL+ Optimizing Compiler version 20170119-32
+    ASL+ Optimizing Compiler version 20170119-64
+
+    New:
+    ASL+ Optimizing Compiler version 20170119
+
 ----------------------------------------
 22 December 2016. Summary of changes for version 20161222:
 
diff --git a/sys/contrib/dev/acpica/common/acfileio.c b/sys/contrib/dev/acpica/common/acfileio.c
index b58945328e7..431eeef6bdd 100644
--- a/sys/contrib/dev/acpica/common/acfileio.c
+++ b/sys/contrib/dev/acpica/common/acfileio.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/acgetline.c b/sys/contrib/dev/acpica/common/acgetline.c
index 98b3679e2e9..a5ea1494965 100644
--- a/sys/contrib/dev/acpica/common/acgetline.c
+++ b/sys/contrib/dev/acpica/common/acgetline.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/adfile.c b/sys/contrib/dev/acpica/common/adfile.c
index 8cd353f8f72..e48345682d1 100644
--- a/sys/contrib/dev/acpica/common/adfile.c
+++ b/sys/contrib/dev/acpica/common/adfile.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/adisasm.c b/sys/contrib/dev/acpica/common/adisasm.c
index fcc3923fe57..38551e5aa0b 100644
--- a/sys/contrib/dev/acpica/common/adisasm.c
+++ b/sys/contrib/dev/acpica/common/adisasm.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/adwalk.c b/sys/contrib/dev/acpica/common/adwalk.c
index dcf39897fca..90460a8fe65 100644
--- a/sys/contrib/dev/acpica/common/adwalk.c
+++ b/sys/contrib/dev/acpica/common/adwalk.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/ahids.c b/sys/contrib/dev/acpica/common/ahids.c
index aa12bc83513..d5c98b555ec 100644
--- a/sys/contrib/dev/acpica/common/ahids.c
+++ b/sys/contrib/dev/acpica/common/ahids.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/ahpredef.c b/sys/contrib/dev/acpica/common/ahpredef.c
index 96bcbc8436c..7790ace33fe 100644
--- a/sys/contrib/dev/acpica/common/ahpredef.c
+++ b/sys/contrib/dev/acpica/common/ahpredef.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/ahtable.c b/sys/contrib/dev/acpica/common/ahtable.c
index 050ee6b4d3a..bbdc6b50921 100644
--- a/sys/contrib/dev/acpica/common/ahtable.c
+++ b/sys/contrib/dev/acpica/common/ahtable.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/ahuuids.c b/sys/contrib/dev/acpica/common/ahuuids.c
index e18e9b9beb1..18f5e0dd748 100644
--- a/sys/contrib/dev/acpica/common/ahuuids.c
+++ b/sys/contrib/dev/acpica/common/ahuuids.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/cmfsize.c b/sys/contrib/dev/acpica/common/cmfsize.c
index f4e8ac7966e..700000195d2 100644
--- a/sys/contrib/dev/acpica/common/cmfsize.c
+++ b/sys/contrib/dev/acpica/common/cmfsize.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/dmextern.c b/sys/contrib/dev/acpica/common/dmextern.c
index 0b1805871ce..493b9ab57a5 100644
--- a/sys/contrib/dev/acpica/common/dmextern.c
+++ b/sys/contrib/dev/acpica/common/dmextern.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/dmrestag.c b/sys/contrib/dev/acpica/common/dmrestag.c
index 337456e3de4..2c8f980a046 100644
--- a/sys/contrib/dev/acpica/common/dmrestag.c
+++ b/sys/contrib/dev/acpica/common/dmrestag.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/dmtable.c b/sys/contrib/dev/acpica/common/dmtable.c
index 4ec52db71e4..ad08db0dc8e 100644
--- a/sys/contrib/dev/acpica/common/dmtable.c
+++ b/sys/contrib/dev/acpica/common/dmtable.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/dmtables.c b/sys/contrib/dev/acpica/common/dmtables.c
index 258182311b1..c1a0ac14310 100644
--- a/sys/contrib/dev/acpica/common/dmtables.c
+++ b/sys/contrib/dev/acpica/common/dmtables.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/dmtbdump.c b/sys/contrib/dev/acpica/common/dmtbdump.c
index d79658fc156..983d74791cd 100644
--- a/sys/contrib/dev/acpica/common/dmtbdump.c
+++ b/sys/contrib/dev/acpica/common/dmtbdump.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/dmtbinfo.c b/sys/contrib/dev/acpica/common/dmtbinfo.c
index c1145bdca84..9135a3a6e15 100644
--- a/sys/contrib/dev/acpica/common/dmtbinfo.c
+++ b/sys/contrib/dev/acpica/common/dmtbinfo.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/common/getopt.c b/sys/contrib/dev/acpica/common/getopt.c
index f59269a021e..ee9e0b094ee 100644
--- a/sys/contrib/dev/acpica/common/getopt.c
+++ b/sys/contrib/dev/acpica/common/getopt.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslanalyze.c b/sys/contrib/dev/acpica/compiler/aslanalyze.c
index 882378359b4..b5024156345 100644
--- a/sys/contrib/dev/acpica/compiler/aslanalyze.c
+++ b/sys/contrib/dev/acpica/compiler/aslanalyze.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslascii.c b/sys/contrib/dev/acpica/compiler/aslascii.c
index e2166d84a33..1f8bc1bde51 100644
--- a/sys/contrib/dev/acpica/compiler/aslascii.c
+++ b/sys/contrib/dev/acpica/compiler/aslascii.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslbtypes.c b/sys/contrib/dev/acpica/compiler/aslbtypes.c
index cd40f20bfae..5c2a8758985 100644
--- a/sys/contrib/dev/acpica/compiler/aslbtypes.c
+++ b/sys/contrib/dev/acpica/compiler/aslbtypes.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslcodegen.c b/sys/contrib/dev/acpica/compiler/aslcodegen.c
index cf1f170de7f..65b9ac2b3b5 100644
--- a/sys/contrib/dev/acpica/compiler/aslcodegen.c
+++ b/sys/contrib/dev/acpica/compiler/aslcodegen.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslcompile.c b/sys/contrib/dev/acpica/compiler/aslcompile.c
index 3dbd0f62ef7..cffebe2bef7 100644
--- a/sys/contrib/dev/acpica/compiler/aslcompile.c
+++ b/sys/contrib/dev/acpica/compiler/aslcompile.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.h b/sys/contrib/dev/acpica/compiler/aslcompiler.h
index 200cc023603..7d21c8b8bfd 100644
--- a/sys/contrib/dev/acpica/compiler/aslcompiler.h
+++ b/sys/contrib/dev/acpica/compiler/aslcompiler.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.l b/sys/contrib/dev/acpica/compiler/aslcompiler.l
index cd259d76869..8f2c1fbc65e 100644
--- a/sys/contrib/dev/acpica/compiler/aslcompiler.l
+++ b/sys/contrib/dev/acpica/compiler/aslcompiler.l
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslcstyle.y b/sys/contrib/dev/acpica/compiler/aslcstyle.y
index d4034a5f2e4..3cba5f56399 100644
--- a/sys/contrib/dev/acpica/compiler/aslcstyle.y
+++ b/sys/contrib/dev/acpica/compiler/aslcstyle.y
@@ -6,7 +6,7 @@ NoEcho('
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/asldebug.c b/sys/contrib/dev/acpica/compiler/asldebug.c
index 0fa8c0a8d1f..e01e5705e05 100644
--- a/sys/contrib/dev/acpica/compiler/asldebug.c
+++ b/sys/contrib/dev/acpica/compiler/asldebug.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/asldefine.h b/sys/contrib/dev/acpica/compiler/asldefine.h
index f615cb21953..94ee7c88f81 100644
--- a/sys/contrib/dev/acpica/compiler/asldefine.h
+++ b/sys/contrib/dev/acpica/compiler/asldefine.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,7 +48,7 @@
 /*
  * Compiler versions and names
  */
-#define ASL_COMPILER_NAME           "ASL+ Optimizing Compiler"
+#define ASL_COMPILER_NAME           "ASL+ Optimizing Compiler/Disassembler"
 #define AML_DISASSEMBLER_NAME       "AML/ASL+ Disassembler"
 #define ASL_INVOCATION_NAME         "iasl"
 #define ASL_CREATOR_ID              "INTL"
diff --git a/sys/contrib/dev/acpica/compiler/aslerror.c b/sys/contrib/dev/acpica/compiler/aslerror.c
index f71d56acca6..fd6bb25a081 100644
--- a/sys/contrib/dev/acpica/compiler/aslerror.c
+++ b/sys/contrib/dev/acpica/compiler/aslerror.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslexternal.c b/sys/contrib/dev/acpica/compiler/aslexternal.c
index 81e217134c6..bed9079971c 100644
--- a/sys/contrib/dev/acpica/compiler/aslexternal.c
+++ b/sys/contrib/dev/acpica/compiler/aslexternal.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslfileio.c b/sys/contrib/dev/acpica/compiler/aslfileio.c
index f1c664fcba5..e79975ebb8d 100644
--- a/sys/contrib/dev/acpica/compiler/aslfileio.c
+++ b/sys/contrib/dev/acpica/compiler/aslfileio.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslfiles.c b/sys/contrib/dev/acpica/compiler/aslfiles.c
index fc2eaaac746..81cd93d9437 100644
--- a/sys/contrib/dev/acpica/compiler/aslfiles.c
+++ b/sys/contrib/dev/acpica/compiler/aslfiles.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslfold.c b/sys/contrib/dev/acpica/compiler/aslfold.c
index 78a1a60fe6a..1a79698d7ca 100644
--- a/sys/contrib/dev/acpica/compiler/aslfold.c
+++ b/sys/contrib/dev/acpica/compiler/aslfold.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslglobal.h b/sys/contrib/dev/acpica/compiler/aslglobal.h
index 6f35c248ec4..c2f4d61bc79 100644
--- a/sys/contrib/dev/acpica/compiler/aslglobal.h
+++ b/sys/contrib/dev/acpica/compiler/aslglobal.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslhelp.c b/sys/contrib/dev/acpica/compiler/aslhelp.c
index fb2059c1991..88060445c63 100644
--- a/sys/contrib/dev/acpica/compiler/aslhelp.c
+++ b/sys/contrib/dev/acpica/compiler/aslhelp.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslhelpers.y b/sys/contrib/dev/acpica/compiler/aslhelpers.y
index f3a94de9c4c..e0f3e89ef5d 100644
--- a/sys/contrib/dev/acpica/compiler/aslhelpers.y
+++ b/sys/contrib/dev/acpica/compiler/aslhelpers.y
@@ -6,7 +6,7 @@ NoEcho('
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslhex.c b/sys/contrib/dev/acpica/compiler/aslhex.c
index fd809254d00..2483ec8ae21 100644
--- a/sys/contrib/dev/acpica/compiler/aslhex.c
+++ b/sys/contrib/dev/acpica/compiler/aslhex.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslkeywords.y b/sys/contrib/dev/acpica/compiler/aslkeywords.y
index c908ae401c5..57e6d4ec1ab 100644
--- a/sys/contrib/dev/acpica/compiler/aslkeywords.y
+++ b/sys/contrib/dev/acpica/compiler/aslkeywords.y
@@ -6,7 +6,7 @@ NoEcho('
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/asllength.c b/sys/contrib/dev/acpica/compiler/asllength.c
index 2c57794d5ee..6470867646e 100644
--- a/sys/contrib/dev/acpica/compiler/asllength.c
+++ b/sys/contrib/dev/acpica/compiler/asllength.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/asllisting.c b/sys/contrib/dev/acpica/compiler/asllisting.c
index 45ab1e22bdb..37878834782 100644
--- a/sys/contrib/dev/acpica/compiler/asllisting.c
+++ b/sys/contrib/dev/acpica/compiler/asllisting.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/asllistsup.c b/sys/contrib/dev/acpica/compiler/asllistsup.c
index 754f8c997ae..4b6d0725154 100644
--- a/sys/contrib/dev/acpica/compiler/asllistsup.c
+++ b/sys/contrib/dev/acpica/compiler/asllistsup.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslload.c b/sys/contrib/dev/acpica/compiler/aslload.c
index f14e01d77ba..6f812a281f8 100644
--- a/sys/contrib/dev/acpica/compiler/aslload.c
+++ b/sys/contrib/dev/acpica/compiler/aslload.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/asllookup.c b/sys/contrib/dev/acpica/compiler/asllookup.c
index 3e216cc9514..90921741d0b 100644
--- a/sys/contrib/dev/acpica/compiler/asllookup.c
+++ b/sys/contrib/dev/acpica/compiler/asllookup.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslmain.c b/sys/contrib/dev/acpica/compiler/aslmain.c
index 0e8cda9ef47..2823aab0763 100644
--- a/sys/contrib/dev/acpica/compiler/aslmain.c
+++ b/sys/contrib/dev/acpica/compiler/aslmain.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslmap.c b/sys/contrib/dev/acpica/compiler/aslmap.c
index e2133363a41..20c887d1071 100644
--- a/sys/contrib/dev/acpica/compiler/aslmap.c
+++ b/sys/contrib/dev/acpica/compiler/aslmap.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslmapenter.c b/sys/contrib/dev/acpica/compiler/aslmapenter.c
index 8aa66b7881e..8590e558a86 100644
--- a/sys/contrib/dev/acpica/compiler/aslmapenter.c
+++ b/sys/contrib/dev/acpica/compiler/aslmapenter.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslmapoutput.c b/sys/contrib/dev/acpica/compiler/aslmapoutput.c
index c8cd54530e3..a44ec93a9c8 100644
--- a/sys/contrib/dev/acpica/compiler/aslmapoutput.c
+++ b/sys/contrib/dev/acpica/compiler/aslmapoutput.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslmaputils.c b/sys/contrib/dev/acpica/compiler/aslmaputils.c
index 01185e6af1f..c0c029c8a80 100644
--- a/sys/contrib/dev/acpica/compiler/aslmaputils.c
+++ b/sys/contrib/dev/acpica/compiler/aslmaputils.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslmessages.c b/sys/contrib/dev/acpica/compiler/aslmessages.c
index 1545abad62f..c2dbc89984d 100644
--- a/sys/contrib/dev/acpica/compiler/aslmessages.c
+++ b/sys/contrib/dev/acpica/compiler/aslmessages.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslmessages.h b/sys/contrib/dev/acpica/compiler/aslmessages.h
index 0ee063fa596..8d3978345cd 100644
--- a/sys/contrib/dev/acpica/compiler/aslmessages.h
+++ b/sys/contrib/dev/acpica/compiler/aslmessages.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslmethod.c b/sys/contrib/dev/acpica/compiler/aslmethod.c
index b16982a5e5d..983e611741e 100644
--- a/sys/contrib/dev/acpica/compiler/aslmethod.c
+++ b/sys/contrib/dev/acpica/compiler/aslmethod.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslnamesp.c b/sys/contrib/dev/acpica/compiler/aslnamesp.c
index f8149c51ee5..ee8218a71ed 100644
--- a/sys/contrib/dev/acpica/compiler/aslnamesp.c
+++ b/sys/contrib/dev/acpica/compiler/aslnamesp.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/asloffset.c b/sys/contrib/dev/acpica/compiler/asloffset.c
index bb57d35b3b8..1c12e7ba714 100644
--- a/sys/contrib/dev/acpica/compiler/asloffset.c
+++ b/sys/contrib/dev/acpica/compiler/asloffset.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslopcodes.c b/sys/contrib/dev/acpica/compiler/aslopcodes.c
index 0d790a8d498..063fe055da6 100644
--- a/sys/contrib/dev/acpica/compiler/aslopcodes.c
+++ b/sys/contrib/dev/acpica/compiler/aslopcodes.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/asloperands.c b/sys/contrib/dev/acpica/compiler/asloperands.c
index 36a324f1ac2..f1685c3b73b 100644
--- a/sys/contrib/dev/acpica/compiler/asloperands.c
+++ b/sys/contrib/dev/acpica/compiler/asloperands.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslopt.c b/sys/contrib/dev/acpica/compiler/aslopt.c
index 680e3fceee5..b6cbb29b986 100644
--- a/sys/contrib/dev/acpica/compiler/aslopt.c
+++ b/sys/contrib/dev/acpica/compiler/aslopt.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/asloptions.c b/sys/contrib/dev/acpica/compiler/asloptions.c
index 5f86a149b4f..f7499f505f6 100644
--- a/sys/contrib/dev/acpica/compiler/asloptions.c
+++ b/sys/contrib/dev/acpica/compiler/asloptions.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslparser.y b/sys/contrib/dev/acpica/compiler/aslparser.y
index 4c750fcda31..abe26351be7 100644
--- a/sys/contrib/dev/acpica/compiler/aslparser.y
+++ b/sys/contrib/dev/acpica/compiler/aslparser.y
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslpld.c b/sys/contrib/dev/acpica/compiler/aslpld.c
index 39f51e115a5..407d25eaf6b 100644
--- a/sys/contrib/dev/acpica/compiler/aslpld.c
+++ b/sys/contrib/dev/acpica/compiler/aslpld.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslpredef.c b/sys/contrib/dev/acpica/compiler/aslpredef.c
index 673a4ba85e7..64520a05b20 100644
--- a/sys/contrib/dev/acpica/compiler/aslpredef.c
+++ b/sys/contrib/dev/acpica/compiler/aslpredef.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslprepkg.c b/sys/contrib/dev/acpica/compiler/aslprepkg.c
index c70144a7600..ebe71148bf5 100644
--- a/sys/contrib/dev/acpica/compiler/aslprepkg.c
+++ b/sys/contrib/dev/acpica/compiler/aslprepkg.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslprimaries.y b/sys/contrib/dev/acpica/compiler/aslprimaries.y
index b52bbcdc671..eca3dfd71be 100644
--- a/sys/contrib/dev/acpica/compiler/aslprimaries.y
+++ b/sys/contrib/dev/acpica/compiler/aslprimaries.y
@@ -6,7 +6,7 @@ NoEcho('
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslprintf.c b/sys/contrib/dev/acpica/compiler/aslprintf.c
index 7ec3e10dabe..39bd97826cd 100644
--- a/sys/contrib/dev/acpica/compiler/aslprintf.c
+++ b/sys/contrib/dev/acpica/compiler/aslprintf.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslprune.c b/sys/contrib/dev/acpica/compiler/aslprune.c
index b3926216e60..ece9ad48800 100644
--- a/sys/contrib/dev/acpica/compiler/aslprune.c
+++ b/sys/contrib/dev/acpica/compiler/aslprune.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslresource.c b/sys/contrib/dev/acpica/compiler/aslresource.c
index cdeb1db249d..01c6b5f39bc 100644
--- a/sys/contrib/dev/acpica/compiler/aslresource.c
+++ b/sys/contrib/dev/acpica/compiler/aslresource.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslresources.y b/sys/contrib/dev/acpica/compiler/aslresources.y
index 34ce47574bc..3425bc0cb61 100644
--- a/sys/contrib/dev/acpica/compiler/aslresources.y
+++ b/sys/contrib/dev/acpica/compiler/aslresources.y
@@ -6,7 +6,7 @@ NoEcho('
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslrestype1.c b/sys/contrib/dev/acpica/compiler/aslrestype1.c
index dbe88a814ef..0adf189b111 100644
--- a/sys/contrib/dev/acpica/compiler/aslrestype1.c
+++ b/sys/contrib/dev/acpica/compiler/aslrestype1.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslrestype1i.c b/sys/contrib/dev/acpica/compiler/aslrestype1i.c
index 7d9d6917544..74a3c86ebf7 100644
--- a/sys/contrib/dev/acpica/compiler/aslrestype1i.c
+++ b/sys/contrib/dev/acpica/compiler/aslrestype1i.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslrestype2.c b/sys/contrib/dev/acpica/compiler/aslrestype2.c
index fd08cc16597..00e2c7dc4af 100644
--- a/sys/contrib/dev/acpica/compiler/aslrestype2.c
+++ b/sys/contrib/dev/acpica/compiler/aslrestype2.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslrestype2d.c b/sys/contrib/dev/acpica/compiler/aslrestype2d.c
index a23e01e638f..231983ecd77 100644
--- a/sys/contrib/dev/acpica/compiler/aslrestype2d.c
+++ b/sys/contrib/dev/acpica/compiler/aslrestype2d.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslrestype2e.c b/sys/contrib/dev/acpica/compiler/aslrestype2e.c
index fc856355355..7717bad9a8b 100644
--- a/sys/contrib/dev/acpica/compiler/aslrestype2e.c
+++ b/sys/contrib/dev/acpica/compiler/aslrestype2e.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslrestype2q.c b/sys/contrib/dev/acpica/compiler/aslrestype2q.c
index 65d22575009..eec822b72f6 100644
--- a/sys/contrib/dev/acpica/compiler/aslrestype2q.c
+++ b/sys/contrib/dev/acpica/compiler/aslrestype2q.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslrestype2s.c b/sys/contrib/dev/acpica/compiler/aslrestype2s.c
index 3b72f9011a5..54ff66eeaf9 100644
--- a/sys/contrib/dev/acpica/compiler/aslrestype2s.c
+++ b/sys/contrib/dev/acpica/compiler/aslrestype2s.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslrestype2w.c b/sys/contrib/dev/acpica/compiler/aslrestype2w.c
index f3b7757aa10..59f0404d214 100644
--- a/sys/contrib/dev/acpica/compiler/aslrestype2w.c
+++ b/sys/contrib/dev/acpica/compiler/aslrestype2w.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslrules.y b/sys/contrib/dev/acpica/compiler/aslrules.y
index 112f041878b..6ef61e2673e 100644
--- a/sys/contrib/dev/acpica/compiler/aslrules.y
+++ b/sys/contrib/dev/acpica/compiler/aslrules.y
@@ -6,7 +6,7 @@ NoEcho('
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslstartup.c b/sys/contrib/dev/acpica/compiler/aslstartup.c
index cd3bb9489f5..72e9ff396b8 100644
--- a/sys/contrib/dev/acpica/compiler/aslstartup.c
+++ b/sys/contrib/dev/acpica/compiler/aslstartup.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslstubs.c b/sys/contrib/dev/acpica/compiler/aslstubs.c
index cc9f27fc3ba..5b271bccd6a 100644
--- a/sys/contrib/dev/acpica/compiler/aslstubs.c
+++ b/sys/contrib/dev/acpica/compiler/aslstubs.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslsupport.l b/sys/contrib/dev/acpica/compiler/aslsupport.l
index deb9e9a3102..01b3e0c0b87 100644
--- a/sys/contrib/dev/acpica/compiler/aslsupport.l
+++ b/sys/contrib/dev/acpica/compiler/aslsupport.l
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslsupport.y b/sys/contrib/dev/acpica/compiler/aslsupport.y
index cd2605b8367..a6b167467c6 100644
--- a/sys/contrib/dev/acpica/compiler/aslsupport.y
+++ b/sys/contrib/dev/acpica/compiler/aslsupport.y
@@ -6,7 +6,7 @@ NoEcho('
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/asltokens.y b/sys/contrib/dev/acpica/compiler/asltokens.y
index 61213db0b66..6a6771588de 100644
--- a/sys/contrib/dev/acpica/compiler/asltokens.y
+++ b/sys/contrib/dev/acpica/compiler/asltokens.y
@@ -6,7 +6,7 @@ NoEcho('
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/asltransform.c b/sys/contrib/dev/acpica/compiler/asltransform.c
index cc87390ad62..3388faf22e9 100644
--- a/sys/contrib/dev/acpica/compiler/asltransform.c
+++ b/sys/contrib/dev/acpica/compiler/asltransform.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/asltree.c b/sys/contrib/dev/acpica/compiler/asltree.c
index d2f128e2ff2..af13a0f229a 100644
--- a/sys/contrib/dev/acpica/compiler/asltree.c
+++ b/sys/contrib/dev/acpica/compiler/asltree.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/asltypes.h b/sys/contrib/dev/acpica/compiler/asltypes.h
index 411faede483..bd8376760ca 100644
--- a/sys/contrib/dev/acpica/compiler/asltypes.h
+++ b/sys/contrib/dev/acpica/compiler/asltypes.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/asltypes.y b/sys/contrib/dev/acpica/compiler/asltypes.y
index d463997bf6b..36fec68c9e3 100644
--- a/sys/contrib/dev/acpica/compiler/asltypes.y
+++ b/sys/contrib/dev/acpica/compiler/asltypes.y
@@ -6,7 +6,7 @@ NoEcho('
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslutils.c b/sys/contrib/dev/acpica/compiler/aslutils.c
index 8941f8219e7..d93eef56513 100644
--- a/sys/contrib/dev/acpica/compiler/aslutils.c
+++ b/sys/contrib/dev/acpica/compiler/aslutils.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -381,8 +381,8 @@ UtDisplaySummary (
     {
         /* Compiler name and version number */
 
-        FlPrintFile (FileId, "%s version %X%s\n\n",
-            ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, ACPI_WIDTH);
+        FlPrintFile (FileId, "%s version %X\n\n",
+            ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION);
     }
 
     /* Summary of main input and output files */
diff --git a/sys/contrib/dev/acpica/compiler/asluuid.c b/sys/contrib/dev/acpica/compiler/asluuid.c
index a26fdfaa1d3..9ed8872afda 100644
--- a/sys/contrib/dev/acpica/compiler/asluuid.c
+++ b/sys/contrib/dev/acpica/compiler/asluuid.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslwalks.c b/sys/contrib/dev/acpica/compiler/aslwalks.c
index be88bb21b93..1c12304316d 100644
--- a/sys/contrib/dev/acpica/compiler/aslwalks.c
+++ b/sys/contrib/dev/acpica/compiler/aslwalks.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/aslxref.c b/sys/contrib/dev/acpica/compiler/aslxref.c
index 6c0f0aec21b..70482ff159b 100644
--- a/sys/contrib/dev/acpica/compiler/aslxref.c
+++ b/sys/contrib/dev/acpica/compiler/aslxref.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -490,21 +490,18 @@ XfNamespaceLocateBegin (
         RegisterNumber = Op->Asl.AmlOpcode - AML_ARG0; /* 0x68 through 0x6F */
         MethodArgs = Node->MethodArgs;
 
+        /* Mark this Arg as referenced */
+
+        MethodArgs[RegisterNumber].Flags |= ASL_ARG_REFERENCED;
+        MethodArgs[RegisterNumber].Op = Op;
+
         if (Op->Asl.CompileFlags & NODE_IS_TARGET)
         {
             /* Arg is being initialized */
 
             MethodArgs[RegisterNumber].Flags |= ASL_ARG_INITIALIZED;
-            MethodArgs[RegisterNumber].Op = Op;
-
-            return_ACPI_STATUS (AE_OK);
         }
 
-        /* Mark this Arg as referenced */
-
-        MethodArgs[RegisterNumber].Flags |= ASL_ARG_REFERENCED;
-        MethodArgs[RegisterNumber].Op = Op;
-
         return_ACPI_STATUS (AE_OK);
     }
 
diff --git a/sys/contrib/dev/acpica/compiler/aslxrefout.c b/sys/contrib/dev/acpica/compiler/aslxrefout.c
index 7408ffead74..8f0d1e01e57 100644
--- a/sys/contrib/dev/acpica/compiler/aslxrefout.c
+++ b/sys/contrib/dev/acpica/compiler/aslxrefout.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/dtcompile.c b/sys/contrib/dev/acpica/compiler/dtcompile.c
index 56da8d389d1..3d21d45f5e9 100644
--- a/sys/contrib/dev/acpica/compiler/dtcompile.c
+++ b/sys/contrib/dev/acpica/compiler/dtcompile.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/dtcompiler.h b/sys/contrib/dev/acpica/compiler/dtcompiler.h
index 120c03d1e72..01bbad176ce 100644
--- a/sys/contrib/dev/acpica/compiler/dtcompiler.h
+++ b/sys/contrib/dev/acpica/compiler/dtcompiler.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/dtexpress.c b/sys/contrib/dev/acpica/compiler/dtexpress.c
index b9da6700a70..08ccabe144b 100644
--- a/sys/contrib/dev/acpica/compiler/dtexpress.c
+++ b/sys/contrib/dev/acpica/compiler/dtexpress.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/dtfield.c b/sys/contrib/dev/acpica/compiler/dtfield.c
index 399e1d8aacc..e2cecd12acb 100644
--- a/sys/contrib/dev/acpica/compiler/dtfield.c
+++ b/sys/contrib/dev/acpica/compiler/dtfield.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/dtio.c b/sys/contrib/dev/acpica/compiler/dtio.c
index d43b57e435b..493fe67551d 100644
--- a/sys/contrib/dev/acpica/compiler/dtio.c
+++ b/sys/contrib/dev/acpica/compiler/dtio.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/dtparser.l b/sys/contrib/dev/acpica/compiler/dtparser.l
index 9f62bed47cd..d3116858a57 100644
--- a/sys/contrib/dev/acpica/compiler/dtparser.l
+++ b/sys/contrib/dev/acpica/compiler/dtparser.l
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/dtparser.y b/sys/contrib/dev/acpica/compiler/dtparser.y
index d4a6c13b476..ed3afdc2089 100644
--- a/sys/contrib/dev/acpica/compiler/dtparser.y
+++ b/sys/contrib/dev/acpica/compiler/dtparser.y
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/dtsubtable.c b/sys/contrib/dev/acpica/compiler/dtsubtable.c
index 49ae8d5ad54..deb6a9a4b0c 100644
--- a/sys/contrib/dev/acpica/compiler/dtsubtable.c
+++ b/sys/contrib/dev/acpica/compiler/dtsubtable.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/dttable.c b/sys/contrib/dev/acpica/compiler/dttable.c
index dc554495c49..9e2b0402a63 100644
--- a/sys/contrib/dev/acpica/compiler/dttable.c
+++ b/sys/contrib/dev/acpica/compiler/dttable.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/dttable1.c b/sys/contrib/dev/acpica/compiler/dttable1.c
index 673f2561dad..d08dac98f75 100644
--- a/sys/contrib/dev/acpica/compiler/dttable1.c
+++ b/sys/contrib/dev/acpica/compiler/dttable1.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/dttable2.c b/sys/contrib/dev/acpica/compiler/dttable2.c
index 8297ba32031..687b1522103 100644
--- a/sys/contrib/dev/acpica/compiler/dttable2.c
+++ b/sys/contrib/dev/acpica/compiler/dttable2.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/dttemplate.c b/sys/contrib/dev/acpica/compiler/dttemplate.c
index 319ee29f079..4dc6b2e89d4 100644
--- a/sys/contrib/dev/acpica/compiler/dttemplate.c
+++ b/sys/contrib/dev/acpica/compiler/dttemplate.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/dttemplate.h b/sys/contrib/dev/acpica/compiler/dttemplate.h
index b18ac31bc7b..8b05713f506 100644
--- a/sys/contrib/dev/acpica/compiler/dttemplate.h
+++ b/sys/contrib/dev/acpica/compiler/dttemplate.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/dtutils.c b/sys/contrib/dev/acpica/compiler/dtutils.c
index 1099b8498af..e3b4602761a 100644
--- a/sys/contrib/dev/acpica/compiler/dtutils.c
+++ b/sys/contrib/dev/acpica/compiler/dtutils.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/preprocess.h b/sys/contrib/dev/acpica/compiler/preprocess.h
index 50759b54629..2399f92cca8 100644
--- a/sys/contrib/dev/acpica/compiler/preprocess.h
+++ b/sys/contrib/dev/acpica/compiler/preprocess.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/prexpress.c b/sys/contrib/dev/acpica/compiler/prexpress.c
index 32e2b6227fc..799fdf2e204 100644
--- a/sys/contrib/dev/acpica/compiler/prexpress.c
+++ b/sys/contrib/dev/acpica/compiler/prexpress.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/prmacros.c b/sys/contrib/dev/acpica/compiler/prmacros.c
index 0849903f5d8..f2a916d7c49 100644
--- a/sys/contrib/dev/acpica/compiler/prmacros.c
+++ b/sys/contrib/dev/acpica/compiler/prmacros.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/prparser.l b/sys/contrib/dev/acpica/compiler/prparser.l
index 18d78f7fede..77189c57f39 100644
--- a/sys/contrib/dev/acpica/compiler/prparser.l
+++ b/sys/contrib/dev/acpica/compiler/prparser.l
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/prparser.y b/sys/contrib/dev/acpica/compiler/prparser.y
index 32bb407a5fe..225036fec61 100644
--- a/sys/contrib/dev/acpica/compiler/prparser.y
+++ b/sys/contrib/dev/acpica/compiler/prparser.y
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/prscan.c b/sys/contrib/dev/acpica/compiler/prscan.c
index c02280dc6f2..4e07b2ae58c 100644
--- a/sys/contrib/dev/acpica/compiler/prscan.c
+++ b/sys/contrib/dev/acpica/compiler/prscan.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/compiler/prutils.c b/sys/contrib/dev/acpica/compiler/prutils.c
index c4c9dd63f21..4517cdeac38 100644
--- a/sys/contrib/dev/acpica/compiler/prutils.c
+++ b/sys/contrib/dev/acpica/compiler/prutils.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/debugger/dbcmds.c b/sys/contrib/dev/acpica/components/debugger/dbcmds.c
index 191b1b410bd..17e7bd6095a 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbcmds.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbcmds.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/debugger/dbconvert.c b/sys/contrib/dev/acpica/components/debugger/dbconvert.c
index d25d2a9afd4..c44de2a58c0 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbconvert.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbconvert.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/debugger/dbdisply.c b/sys/contrib/dev/acpica/components/debugger/dbdisply.c
index 8db59bc1f77..93ff9229420 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbdisply.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbdisply.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/debugger/dbexec.c b/sys/contrib/dev/acpica/components/debugger/dbexec.c
index 93fa103064a..1791f36da62 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbexec.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbexec.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/debugger/dbfileio.c b/sys/contrib/dev/acpica/components/debugger/dbfileio.c
index 0b3d5a4fa29..6860e842aa4 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbfileio.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbfileio.c
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/debugger/dbhistry.c b/sys/contrib/dev/acpica/components/debugger/dbhistry.c
index b55f108761d..ef88a5ed3d3 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbhistry.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbhistry.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/debugger/dbinput.c b/sys/contrib/dev/acpica/components/debugger/dbinput.c
index 55829bf0e91..92a0f4c8884 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbinput.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbinput.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/debugger/dbmethod.c b/sys/contrib/dev/acpica/components/debugger/dbmethod.c
index 5925a5bf616..dbc66613cb8 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbmethod.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbmethod.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/debugger/dbnames.c b/sys/contrib/dev/acpica/components/debugger/dbnames.c
index f91bf97bb9d..a225ce87477 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbnames.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbnames.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/debugger/dbobject.c b/sys/contrib/dev/acpica/components/debugger/dbobject.c
index 062ad253206..076318dccd0 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbobject.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbobject.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/debugger/dbstats.c b/sys/contrib/dev/acpica/components/debugger/dbstats.c
index 7b48ba0e568..7b3e88e4bb0 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbstats.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbstats.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/debugger/dbtest.c b/sys/contrib/dev/acpica/components/debugger/dbtest.c
index 6be75f231c0..6e274e779a4 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbtest.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbtest.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/debugger/dbutils.c b/sys/contrib/dev/acpica/components/debugger/dbutils.c
index 8e56c209763..73b8d928d89 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbutils.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbutils.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/debugger/dbxface.c b/sys/contrib/dev/acpica/components/debugger/dbxface.c
index d6f4bd536e6..2d39f1ad15b 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbxface.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbxface.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c b/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c
index 365e3015744..7a1ac3bd62e 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c b/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c
index 3b03e3472ab..1f72f73c6d5 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmdeferred.c b/sys/contrib/dev/acpica/components/disassembler/dmdeferred.c
index 5900614507e..846ff7fd0bf 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmdeferred.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmdeferred.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmnames.c b/sys/contrib/dev/acpica/components/disassembler/dmnames.c
index d75db19bd78..169a9da86b1 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmnames.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmnames.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmopcode.c b/sys/contrib/dev/acpica/components/disassembler/dmopcode.c
index 8e14ba79ea9..b73dfdc9256 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmopcode.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmopcode.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmresrc.c b/sys/contrib/dev/acpica/components/disassembler/dmresrc.c
index 5a3628855d3..56947ff3a24 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmresrc.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmresrc.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmresrcl.c b/sys/contrib/dev/acpica/components/disassembler/dmresrcl.c
index f7d53083af9..39c6d56504d 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmresrcl.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmresrcl.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmresrcl2.c b/sys/contrib/dev/acpica/components/disassembler/dmresrcl2.c
index 318c1616c3a..73216010bc4 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmresrcl2.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmresrcl2.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmresrcs.c b/sys/contrib/dev/acpica/components/disassembler/dmresrcs.c
index 2840f806a33..bd301d46407 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmresrcs.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmresrcs.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmutils.c b/sys/contrib/dev/acpica/components/disassembler/dmutils.c
index 32cc4b6afb8..b0903888859 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmutils.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmutils.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmwalk.c b/sys/contrib/dev/acpica/components/disassembler/dmwalk.c
index 1d2568b7be4..39d66ebdfd7 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmwalk.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmwalk.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsargs.c b/sys/contrib/dev/acpica/components/dispatcher/dsargs.c
index b669b56f247..b27305ce70c 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsargs.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsargs.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c b/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c
index e3c68b7a4e8..c830f3b3b40 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsdebug.c b/sys/contrib/dev/acpica/components/dispatcher/dsdebug.c
index 9db1b7be044..51e1081587b 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsdebug.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsdebug.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsfield.c b/sys/contrib/dev/acpica/components/dispatcher/dsfield.c
index 4e3c29a532b..1311692004f 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsfield.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsfield.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsinit.c b/sys/contrib/dev/acpica/components/dispatcher/dsinit.c
index 92a604d1434..749af80bf16 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsinit.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsinit.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsmethod.c b/sys/contrib/dev/acpica/components/dispatcher/dsmethod.c
index 020df913db3..5350b9a65b4 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsmethod.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsmethod.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsmthdat.c b/sys/contrib/dev/acpica/components/dispatcher/dsmthdat.c
index 6e0fc7e5e58..8c14aa2f5fb 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsmthdat.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsmthdat.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsobject.c b/sys/contrib/dev/acpica/components/dispatcher/dsobject.c
index da9512f6845..db6c530cffc 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsobject.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsobject.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c b/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c
index 19bdd551856..91cd18f89d0 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsutils.c b/sys/contrib/dev/acpica/components/dispatcher/dsutils.c
index 1ffd0cbf802..2ed5e99922f 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsutils.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsutils.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dswexec.c b/sys/contrib/dev/acpica/components/dispatcher/dswexec.c
index c43889d754b..b8aaa2893a0 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dswexec.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dswexec.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dswload.c b/sys/contrib/dev/acpica/components/dispatcher/dswload.c
index ff14300003c..3318035ce73 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dswload.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dswload.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dswload2.c b/sys/contrib/dev/acpica/components/dispatcher/dswload2.c
index e060b7c7364..08bb7dfdb85 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dswload2.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dswload2.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dswscope.c b/sys/contrib/dev/acpica/components/dispatcher/dswscope.c
index ba99d1ef654..afedcd770de 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dswscope.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dswscope.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dswstate.c b/sys/contrib/dev/acpica/components/dispatcher/dswstate.c
index b19d6a9792e..914e108ec5e 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dswstate.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dswstate.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/events/evevent.c b/sys/contrib/dev/acpica/components/events/evevent.c
index a4aa037e51c..a4d319a37c7 100644
--- a/sys/contrib/dev/acpica/components/events/evevent.c
+++ b/sys/contrib/dev/acpica/components/events/evevent.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/events/evglock.c b/sys/contrib/dev/acpica/components/events/evglock.c
index b8bd0cf0a85..17cab651f4b 100644
--- a/sys/contrib/dev/acpica/components/events/evglock.c
+++ b/sys/contrib/dev/acpica/components/events/evglock.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/events/evgpe.c b/sys/contrib/dev/acpica/components/events/evgpe.c
index a6439eb4b04..21c80ffd949 100644
--- a/sys/contrib/dev/acpica/components/events/evgpe.c
+++ b/sys/contrib/dev/acpica/components/events/evgpe.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/events/evgpeblk.c b/sys/contrib/dev/acpica/components/events/evgpeblk.c
index e5d3616db4f..2863791271d 100644
--- a/sys/contrib/dev/acpica/components/events/evgpeblk.c
+++ b/sys/contrib/dev/acpica/components/events/evgpeblk.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/events/evgpeinit.c b/sys/contrib/dev/acpica/components/events/evgpeinit.c
index f4254f8e8f9..33690691213 100644
--- a/sys/contrib/dev/acpica/components/events/evgpeinit.c
+++ b/sys/contrib/dev/acpica/components/events/evgpeinit.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/events/evgpeutil.c b/sys/contrib/dev/acpica/components/events/evgpeutil.c
index 99cbc286d1a..94a8f6c9fba 100644
--- a/sys/contrib/dev/acpica/components/events/evgpeutil.c
+++ b/sys/contrib/dev/acpica/components/events/evgpeutil.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/events/evhandler.c b/sys/contrib/dev/acpica/components/events/evhandler.c
index 88496d0113b..850173682a3 100644
--- a/sys/contrib/dev/acpica/components/events/evhandler.c
+++ b/sys/contrib/dev/acpica/components/events/evhandler.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/events/evmisc.c b/sys/contrib/dev/acpica/components/events/evmisc.c
index 4bc478611ba..e6139204f0e 100644
--- a/sys/contrib/dev/acpica/components/events/evmisc.c
+++ b/sys/contrib/dev/acpica/components/events/evmisc.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/events/evregion.c b/sys/contrib/dev/acpica/components/events/evregion.c
index fae3900c198..b4c87b010f3 100644
--- a/sys/contrib/dev/acpica/components/events/evregion.c
+++ b/sys/contrib/dev/acpica/components/events/evregion.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/events/evrgnini.c b/sys/contrib/dev/acpica/components/events/evrgnini.c
index da759c63e71..6c1ac91f6c8 100644
--- a/sys/contrib/dev/acpica/components/events/evrgnini.c
+++ b/sys/contrib/dev/acpica/components/events/evrgnini.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/events/evsci.c b/sys/contrib/dev/acpica/components/events/evsci.c
index a4d71dbe97b..6d71c399ccd 100644
--- a/sys/contrib/dev/acpica/components/events/evsci.c
+++ b/sys/contrib/dev/acpica/components/events/evsci.c
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/events/evxface.c b/sys/contrib/dev/acpica/components/events/evxface.c
index 6306a578387..442b84724f7 100644
--- a/sys/contrib/dev/acpica/components/events/evxface.c
+++ b/sys/contrib/dev/acpica/components/events/evxface.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/events/evxfevnt.c b/sys/contrib/dev/acpica/components/events/evxfevnt.c
index 81d315cb1dd..c3287678ee9 100644
--- a/sys/contrib/dev/acpica/components/events/evxfevnt.c
+++ b/sys/contrib/dev/acpica/components/events/evxfevnt.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/events/evxfgpe.c b/sys/contrib/dev/acpica/components/events/evxfgpe.c
index 47ad6de9635..bdb547e6e99 100644
--- a/sys/contrib/dev/acpica/components/events/evxfgpe.c
+++ b/sys/contrib/dev/acpica/components/events/evxfgpe.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/events/evxfregn.c b/sys/contrib/dev/acpica/components/events/evxfregn.c
index c8a6eddfee2..987ab810d48 100644
--- a/sys/contrib/dev/acpica/components/events/evxfregn.c
+++ b/sys/contrib/dev/acpica/components/events/evxfregn.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exconcat.c b/sys/contrib/dev/acpica/components/executer/exconcat.c
index 8bfbcd48b6b..543715b9a20 100644
--- a/sys/contrib/dev/acpica/components/executer/exconcat.c
+++ b/sys/contrib/dev/acpica/components/executer/exconcat.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exconfig.c b/sys/contrib/dev/acpica/components/executer/exconfig.c
index bd486c493ff..1f16b17bbd6 100644
--- a/sys/contrib/dev/acpica/components/executer/exconfig.c
+++ b/sys/contrib/dev/acpica/components/executer/exconfig.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exconvrt.c b/sys/contrib/dev/acpica/components/executer/exconvrt.c
index 497788a9f63..4e5cf6e1845 100644
--- a/sys/contrib/dev/acpica/components/executer/exconvrt.c
+++ b/sys/contrib/dev/acpica/components/executer/exconvrt.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/excreate.c b/sys/contrib/dev/acpica/components/executer/excreate.c
index 5c38a44188a..4cc3b9d3e37 100644
--- a/sys/contrib/dev/acpica/components/executer/excreate.c
+++ b/sys/contrib/dev/acpica/components/executer/excreate.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exdebug.c b/sys/contrib/dev/acpica/components/executer/exdebug.c
index 24273f81c7b..558f369caaf 100644
--- a/sys/contrib/dev/acpica/components/executer/exdebug.c
+++ b/sys/contrib/dev/acpica/components/executer/exdebug.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exdump.c b/sys/contrib/dev/acpica/components/executer/exdump.c
index 3e6c089a442..41ccb7f599c 100644
--- a/sys/contrib/dev/acpica/components/executer/exdump.c
+++ b/sys/contrib/dev/acpica/components/executer/exdump.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exfield.c b/sys/contrib/dev/acpica/components/executer/exfield.c
index aa71d6ec129..9b2f1290547 100644
--- a/sys/contrib/dev/acpica/components/executer/exfield.c
+++ b/sys/contrib/dev/acpica/components/executer/exfield.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exfldio.c b/sys/contrib/dev/acpica/components/executer/exfldio.c
index affc9c66f5e..9369b36525d 100644
--- a/sys/contrib/dev/acpica/components/executer/exfldio.c
+++ b/sys/contrib/dev/acpica/components/executer/exfldio.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exmisc.c b/sys/contrib/dev/acpica/components/executer/exmisc.c
index 598bf782be1..73f1bfbfa0b 100644
--- a/sys/contrib/dev/acpica/components/executer/exmisc.c
+++ b/sys/contrib/dev/acpica/components/executer/exmisc.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exmutex.c b/sys/contrib/dev/acpica/components/executer/exmutex.c
index 989cb29fc20..4448e370e2b 100644
--- a/sys/contrib/dev/acpica/components/executer/exmutex.c
+++ b/sys/contrib/dev/acpica/components/executer/exmutex.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exnames.c b/sys/contrib/dev/acpica/components/executer/exnames.c
index 13fe83f370b..dbc4b453298 100644
--- a/sys/contrib/dev/acpica/components/executer/exnames.c
+++ b/sys/contrib/dev/acpica/components/executer/exnames.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exoparg1.c b/sys/contrib/dev/acpica/components/executer/exoparg1.c
index eae2168c9c7..619de87dd2a 100644
--- a/sys/contrib/dev/acpica/components/executer/exoparg1.c
+++ b/sys/contrib/dev/acpica/components/executer/exoparg1.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exoparg2.c b/sys/contrib/dev/acpica/components/executer/exoparg2.c
index f223c8dbca5..dcb660bcd1b 100644
--- a/sys/contrib/dev/acpica/components/executer/exoparg2.c
+++ b/sys/contrib/dev/acpica/components/executer/exoparg2.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exoparg3.c b/sys/contrib/dev/acpica/components/executer/exoparg3.c
index 8be4d594b25..b3351f46de6 100644
--- a/sys/contrib/dev/acpica/components/executer/exoparg3.c
+++ b/sys/contrib/dev/acpica/components/executer/exoparg3.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exoparg6.c b/sys/contrib/dev/acpica/components/executer/exoparg6.c
index 09f03360b29..a3dce458cb2 100644
--- a/sys/contrib/dev/acpica/components/executer/exoparg6.c
+++ b/sys/contrib/dev/acpica/components/executer/exoparg6.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exprep.c b/sys/contrib/dev/acpica/components/executer/exprep.c
index 9f59df3f0c6..80e2dd18f10 100644
--- a/sys/contrib/dev/acpica/components/executer/exprep.c
+++ b/sys/contrib/dev/acpica/components/executer/exprep.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exregion.c b/sys/contrib/dev/acpica/components/executer/exregion.c
index 6f4491596d3..2252ff0adaf 100644
--- a/sys/contrib/dev/acpica/components/executer/exregion.c
+++ b/sys/contrib/dev/acpica/components/executer/exregion.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exresnte.c b/sys/contrib/dev/acpica/components/executer/exresnte.c
index 3e878f66f89..36aab0001c6 100644
--- a/sys/contrib/dev/acpica/components/executer/exresnte.c
+++ b/sys/contrib/dev/acpica/components/executer/exresnte.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exresolv.c b/sys/contrib/dev/acpica/components/executer/exresolv.c
index 75c65d6aeb8..cfde4084037 100644
--- a/sys/contrib/dev/acpica/components/executer/exresolv.c
+++ b/sys/contrib/dev/acpica/components/executer/exresolv.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exresop.c b/sys/contrib/dev/acpica/components/executer/exresop.c
index de909989e42..5abcec9308e 100644
--- a/sys/contrib/dev/acpica/components/executer/exresop.c
+++ b/sys/contrib/dev/acpica/components/executer/exresop.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exstore.c b/sys/contrib/dev/acpica/components/executer/exstore.c
index eb474a9d193..345b9917c65 100644
--- a/sys/contrib/dev/acpica/components/executer/exstore.c
+++ b/sys/contrib/dev/acpica/components/executer/exstore.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exstoren.c b/sys/contrib/dev/acpica/components/executer/exstoren.c
index 25a499b86b0..1d67105314e 100644
--- a/sys/contrib/dev/acpica/components/executer/exstoren.c
+++ b/sys/contrib/dev/acpica/components/executer/exstoren.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exstorob.c b/sys/contrib/dev/acpica/components/executer/exstorob.c
index 981e261483f..2cf3777e1c7 100644
--- a/sys/contrib/dev/acpica/components/executer/exstorob.c
+++ b/sys/contrib/dev/acpica/components/executer/exstorob.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exsystem.c b/sys/contrib/dev/acpica/components/executer/exsystem.c
index 6c1dcd3d135..1365118a055 100644
--- a/sys/contrib/dev/acpica/components/executer/exsystem.c
+++ b/sys/contrib/dev/acpica/components/executer/exsystem.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/extrace.c b/sys/contrib/dev/acpica/components/executer/extrace.c
index bc366ed7592..4fb7f5b6d5c 100644
--- a/sys/contrib/dev/acpica/components/executer/extrace.c
+++ b/sys/contrib/dev/acpica/components/executer/extrace.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/executer/exutils.c b/sys/contrib/dev/acpica/components/executer/exutils.c
index 2c7dc8aa0e1..a8d627f4903 100644
--- a/sys/contrib/dev/acpica/components/executer/exutils.c
+++ b/sys/contrib/dev/acpica/components/executer/exutils.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/hardware/hwacpi.c b/sys/contrib/dev/acpica/components/hardware/hwacpi.c
index 54b441620e5..1010b96c090 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwacpi.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwacpi.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/hardware/hwesleep.c b/sys/contrib/dev/acpica/components/hardware/hwesleep.c
index 7b8a5e2be6b..de792252169 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwesleep.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwesleep.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/hardware/hwgpe.c b/sys/contrib/dev/acpica/components/hardware/hwgpe.c
index 27bb46815e0..735e1c1eecf 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwgpe.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwgpe.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/hardware/hwpci.c b/sys/contrib/dev/acpica/components/hardware/hwpci.c
index 3abb424bf7d..2d0e1a6b61b 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwpci.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwpci.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/hardware/hwregs.c b/sys/contrib/dev/acpica/components/hardware/hwregs.c
index 59aa0aaa714..f50cd788a46 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwregs.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwregs.c
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/hardware/hwsleep.c b/sys/contrib/dev/acpica/components/hardware/hwsleep.c
index 25538c5ccf8..24993c7dc70 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwsleep.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwsleep.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/hardware/hwtimer.c b/sys/contrib/dev/acpica/components/hardware/hwtimer.c
index 2c53dc92a65..670ca1c9343 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwtimer.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwtimer.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/hardware/hwvalid.c b/sys/contrib/dev/acpica/components/hardware/hwvalid.c
index c8237f88e7f..0670840bc84 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwvalid.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwvalid.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/hardware/hwxface.c b/sys/contrib/dev/acpica/components/hardware/hwxface.c
index 734dfc254e0..5e7c3f804f6 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwxface.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwxface.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c b/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c
index c75bec47082..2a0a9a60be8 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsaccess.c b/sys/contrib/dev/acpica/components/namespace/nsaccess.c
index bf3226917db..046825fbfd8 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsaccess.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsaccess.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsalloc.c b/sys/contrib/dev/acpica/components/namespace/nsalloc.c
index c85593d023b..f405ad86d32 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsalloc.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsalloc.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsarguments.c b/sys/contrib/dev/acpica/components/namespace/nsarguments.c
index 46d6eb91b99..b241055e48c 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsarguments.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsarguments.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsconvert.c b/sys/contrib/dev/acpica/components/namespace/nsconvert.c
index 71df3a0977e..64bbc16a86c 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsconvert.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsconvert.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsdump.c b/sys/contrib/dev/acpica/components/namespace/nsdump.c
index d34ff110e86..472a312a237 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsdump.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsdump.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsdumpdv.c b/sys/contrib/dev/acpica/components/namespace/nsdumpdv.c
index 8adb76a471d..7e92b210fa7 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsdumpdv.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsdumpdv.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nseval.c b/sys/contrib/dev/acpica/components/namespace/nseval.c
index ea1cceb3917..e11ac6073f1 100644
--- a/sys/contrib/dev/acpica/components/namespace/nseval.c
+++ b/sys/contrib/dev/acpica/components/namespace/nseval.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsinit.c b/sys/contrib/dev/acpica/components/namespace/nsinit.c
index a20846928fb..e9379e133a2 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsinit.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsinit.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsload.c b/sys/contrib/dev/acpica/components/namespace/nsload.c
index 42d9f0db58d..ad5a16a488b 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsload.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsload.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsnames.c b/sys/contrib/dev/acpica/components/namespace/nsnames.c
index 5ddc0d41f44..6bf46a18b6d 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsnames.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsnames.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsobject.c b/sys/contrib/dev/acpica/components/namespace/nsobject.c
index 1e555d99073..ee832d41c8e 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsobject.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsobject.c
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsparse.c b/sys/contrib/dev/acpica/components/namespace/nsparse.c
index 7bb45de946a..fae362d49d2 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsparse.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsparse.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nspredef.c b/sys/contrib/dev/acpica/components/namespace/nspredef.c
index 606b23d5b54..5438f44e5ae 100644
--- a/sys/contrib/dev/acpica/components/namespace/nspredef.c
+++ b/sys/contrib/dev/acpica/components/namespace/nspredef.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsprepkg.c b/sys/contrib/dev/acpica/components/namespace/nsprepkg.c
index e4ea0772c96..5603d2d27a5 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsprepkg.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsprepkg.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsrepair.c b/sys/contrib/dev/acpica/components/namespace/nsrepair.c
index a0d4935e049..0754f7e88c9 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsrepair.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsrepair.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsrepair2.c b/sys/contrib/dev/acpica/components/namespace/nsrepair2.c
index 4873c7fc42a..0d651f8c5f7 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsrepair2.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsrepair2.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nssearch.c b/sys/contrib/dev/acpica/components/namespace/nssearch.c
index 85514aadbf9..99eccb2b855 100644
--- a/sys/contrib/dev/acpica/components/namespace/nssearch.c
+++ b/sys/contrib/dev/acpica/components/namespace/nssearch.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsutils.c b/sys/contrib/dev/acpica/components/namespace/nsutils.c
index f561f851c93..fa9e8327081 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsutils.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsutils.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nswalk.c b/sys/contrib/dev/acpica/components/namespace/nswalk.c
index bdbfa76ee5d..8c0f723ab54 100644
--- a/sys/contrib/dev/acpica/components/namespace/nswalk.c
+++ b/sys/contrib/dev/acpica/components/namespace/nswalk.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsxfeval.c b/sys/contrib/dev/acpica/components/namespace/nsxfeval.c
index 6467d7e2f54..363970476d7 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsxfeval.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsxfeval.c
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsxfname.c b/sys/contrib/dev/acpica/components/namespace/nsxfname.c
index 7a5c1c32385..ef8ff6d5d74 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsxfname.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsxfname.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/namespace/nsxfobj.c b/sys/contrib/dev/acpica/components/namespace/nsxfobj.c
index 81a4756a4d7..9d5e9a22851 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsxfobj.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsxfobj.c
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/parser/psargs.c b/sys/contrib/dev/acpica/components/parser/psargs.c
index 880abab2a0e..9d16b3ab6e0 100644
--- a/sys/contrib/dev/acpica/components/parser/psargs.c
+++ b/sys/contrib/dev/acpica/components/parser/psargs.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/parser/psloop.c b/sys/contrib/dev/acpica/components/parser/psloop.c
index 8565421071f..0d7a477c0ed 100644
--- a/sys/contrib/dev/acpica/components/parser/psloop.c
+++ b/sys/contrib/dev/acpica/components/parser/psloop.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/parser/psobject.c b/sys/contrib/dev/acpica/components/parser/psobject.c
index 31050f15239..50ac0ea59c6 100644
--- a/sys/contrib/dev/acpica/components/parser/psobject.c
+++ b/sys/contrib/dev/acpica/components/parser/psobject.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/parser/psopcode.c b/sys/contrib/dev/acpica/components/parser/psopcode.c
index 9f53d1e42a0..ba9ce9f5c57 100644
--- a/sys/contrib/dev/acpica/components/parser/psopcode.c
+++ b/sys/contrib/dev/acpica/components/parser/psopcode.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/parser/psopinfo.c b/sys/contrib/dev/acpica/components/parser/psopinfo.c
index 6ffd7d2d350..2b0832ecc7c 100644
--- a/sys/contrib/dev/acpica/components/parser/psopinfo.c
+++ b/sys/contrib/dev/acpica/components/parser/psopinfo.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/parser/psparse.c b/sys/contrib/dev/acpica/components/parser/psparse.c
index 700441ee31a..e9bdfbb856b 100644
--- a/sys/contrib/dev/acpica/components/parser/psparse.c
+++ b/sys/contrib/dev/acpica/components/parser/psparse.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/parser/psscope.c b/sys/contrib/dev/acpica/components/parser/psscope.c
index 9ad7a58a2a0..63b925fefaf 100644
--- a/sys/contrib/dev/acpica/components/parser/psscope.c
+++ b/sys/contrib/dev/acpica/components/parser/psscope.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/parser/pstree.c b/sys/contrib/dev/acpica/components/parser/pstree.c
index cf71601f570..6e6ae2fb60d 100644
--- a/sys/contrib/dev/acpica/components/parser/pstree.c
+++ b/sys/contrib/dev/acpica/components/parser/pstree.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/parser/psutils.c b/sys/contrib/dev/acpica/components/parser/psutils.c
index ca3830ed514..c8f49428cdd 100644
--- a/sys/contrib/dev/acpica/components/parser/psutils.c
+++ b/sys/contrib/dev/acpica/components/parser/psutils.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/parser/pswalk.c b/sys/contrib/dev/acpica/components/parser/pswalk.c
index 1a9e55e3640..ddcd5c9061f 100644
--- a/sys/contrib/dev/acpica/components/parser/pswalk.c
+++ b/sys/contrib/dev/acpica/components/parser/pswalk.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/parser/psxface.c b/sys/contrib/dev/acpica/components/parser/psxface.c
index 69b00d2c2f4..24dbe631c9a 100644
--- a/sys/contrib/dev/acpica/components/parser/psxface.c
+++ b/sys/contrib/dev/acpica/components/parser/psxface.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/resources/rsaddr.c b/sys/contrib/dev/acpica/components/resources/rsaddr.c
index ca9e290f2e0..6b95e840750 100644
--- a/sys/contrib/dev/acpica/components/resources/rsaddr.c
+++ b/sys/contrib/dev/acpica/components/resources/rsaddr.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/resources/rscalc.c b/sys/contrib/dev/acpica/components/resources/rscalc.c
index 9cc963859ea..8d54aa44eb9 100644
--- a/sys/contrib/dev/acpica/components/resources/rscalc.c
+++ b/sys/contrib/dev/acpica/components/resources/rscalc.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/resources/rscreate.c b/sys/contrib/dev/acpica/components/resources/rscreate.c
index c9b4b12b7e8..179a5b3d62a 100644
--- a/sys/contrib/dev/acpica/components/resources/rscreate.c
+++ b/sys/contrib/dev/acpica/components/resources/rscreate.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/resources/rsdump.c b/sys/contrib/dev/acpica/components/resources/rsdump.c
index 8699730a10d..fd97ca78621 100644
--- a/sys/contrib/dev/acpica/components/resources/rsdump.c
+++ b/sys/contrib/dev/acpica/components/resources/rsdump.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/resources/rsdumpinfo.c b/sys/contrib/dev/acpica/components/resources/rsdumpinfo.c
index 2173fe3b199..60fbfbb06b9 100644
--- a/sys/contrib/dev/acpica/components/resources/rsdumpinfo.c
+++ b/sys/contrib/dev/acpica/components/resources/rsdumpinfo.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/resources/rsinfo.c b/sys/contrib/dev/acpica/components/resources/rsinfo.c
index 6268b732a43..46789fa6307 100644
--- a/sys/contrib/dev/acpica/components/resources/rsinfo.c
+++ b/sys/contrib/dev/acpica/components/resources/rsinfo.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/resources/rsio.c b/sys/contrib/dev/acpica/components/resources/rsio.c
index 5cf5f34889d..d110a1f1f98 100644
--- a/sys/contrib/dev/acpica/components/resources/rsio.c
+++ b/sys/contrib/dev/acpica/components/resources/rsio.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/resources/rsirq.c b/sys/contrib/dev/acpica/components/resources/rsirq.c
index fa591ea2bb0..1035ec6d2b9 100644
--- a/sys/contrib/dev/acpica/components/resources/rsirq.c
+++ b/sys/contrib/dev/acpica/components/resources/rsirq.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/resources/rslist.c b/sys/contrib/dev/acpica/components/resources/rslist.c
index 216d40ba2d4..5c393c542d1 100644
--- a/sys/contrib/dev/acpica/components/resources/rslist.c
+++ b/sys/contrib/dev/acpica/components/resources/rslist.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/resources/rsmemory.c b/sys/contrib/dev/acpica/components/resources/rsmemory.c
index bb4bae30fb4..1f35742abdc 100644
--- a/sys/contrib/dev/acpica/components/resources/rsmemory.c
+++ b/sys/contrib/dev/acpica/components/resources/rsmemory.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/resources/rsmisc.c b/sys/contrib/dev/acpica/components/resources/rsmisc.c
index 57e85dd8681..de9a463f314 100644
--- a/sys/contrib/dev/acpica/components/resources/rsmisc.c
+++ b/sys/contrib/dev/acpica/components/resources/rsmisc.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/resources/rsserial.c b/sys/contrib/dev/acpica/components/resources/rsserial.c
index 27b3c9e5545..0df5b975507 100644
--- a/sys/contrib/dev/acpica/components/resources/rsserial.c
+++ b/sys/contrib/dev/acpica/components/resources/rsserial.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/resources/rsutils.c b/sys/contrib/dev/acpica/components/resources/rsutils.c
index a3a7ed3fa3b..31fd7a89ee7 100644
--- a/sys/contrib/dev/acpica/components/resources/rsutils.c
+++ b/sys/contrib/dev/acpica/components/resources/rsutils.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/resources/rsxface.c b/sys/contrib/dev/acpica/components/resources/rsxface.c
index c362a1af96d..f277bda285b 100644
--- a/sys/contrib/dev/acpica/components/resources/rsxface.c
+++ b/sys/contrib/dev/acpica/components/resources/rsxface.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/tables/tbdata.c b/sys/contrib/dev/acpica/components/tables/tbdata.c
index e1eccd8a282..2d2ee3cf972 100644
--- a/sys/contrib/dev/acpica/components/tables/tbdata.c
+++ b/sys/contrib/dev/acpica/components/tables/tbdata.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/tables/tbfadt.c b/sys/contrib/dev/acpica/components/tables/tbfadt.c
index ee8a815a822..7ef3ad27030 100644
--- a/sys/contrib/dev/acpica/components/tables/tbfadt.c
+++ b/sys/contrib/dev/acpica/components/tables/tbfadt.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/tables/tbfind.c b/sys/contrib/dev/acpica/components/tables/tbfind.c
index eadfd6fc10c..3ff307d3692 100644
--- a/sys/contrib/dev/acpica/components/tables/tbfind.c
+++ b/sys/contrib/dev/acpica/components/tables/tbfind.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/tables/tbinstal.c b/sys/contrib/dev/acpica/components/tables/tbinstal.c
index 81a13d2a8ff..7374a45e198 100644
--- a/sys/contrib/dev/acpica/components/tables/tbinstal.c
+++ b/sys/contrib/dev/acpica/components/tables/tbinstal.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/tables/tbprint.c b/sys/contrib/dev/acpica/components/tables/tbprint.c
index cbdd562390f..59b58080b43 100644
--- a/sys/contrib/dev/acpica/components/tables/tbprint.c
+++ b/sys/contrib/dev/acpica/components/tables/tbprint.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/tables/tbutils.c b/sys/contrib/dev/acpica/components/tables/tbutils.c
index 08ab87f8e1f..3d6b0bcaf54 100644
--- a/sys/contrib/dev/acpica/components/tables/tbutils.c
+++ b/sys/contrib/dev/acpica/components/tables/tbutils.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/tables/tbxface.c b/sys/contrib/dev/acpica/components/tables/tbxface.c
index 6e231cd8fce..3b3314f6fdd 100644
--- a/sys/contrib/dev/acpica/components/tables/tbxface.c
+++ b/sys/contrib/dev/acpica/components/tables/tbxface.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/tables/tbxfload.c b/sys/contrib/dev/acpica/components/tables/tbxfload.c
index 871797583bf..d66a932ae95 100644
--- a/sys/contrib/dev/acpica/components/tables/tbxfload.c
+++ b/sys/contrib/dev/acpica/components/tables/tbxfload.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/tables/tbxfroot.c b/sys/contrib/dev/acpica/components/tables/tbxfroot.c
index c5a6af29660..06884593018 100644
--- a/sys/contrib/dev/acpica/components/tables/tbxfroot.c
+++ b/sys/contrib/dev/acpica/components/tables/tbxfroot.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utaddress.c b/sys/contrib/dev/acpica/components/utilities/utaddress.c
index 870826d012f..50c589c5dcc 100644
--- a/sys/contrib/dev/acpica/components/utilities/utaddress.c
+++ b/sys/contrib/dev/acpica/components/utilities/utaddress.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utalloc.c b/sys/contrib/dev/acpica/components/utilities/utalloc.c
index b768f5846a2..a4aec9c088d 100644
--- a/sys/contrib/dev/acpica/components/utilities/utalloc.c
+++ b/sys/contrib/dev/acpica/components/utilities/utalloc.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utascii.c b/sys/contrib/dev/acpica/components/utilities/utascii.c
index 9081c55babe..d4b6cfc5924 100644
--- a/sys/contrib/dev/acpica/components/utilities/utascii.c
+++ b/sys/contrib/dev/acpica/components/utilities/utascii.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utbuffer.c b/sys/contrib/dev/acpica/components/utilities/utbuffer.c
index 8b3f75d34c6..4652d5b7db2 100644
--- a/sys/contrib/dev/acpica/components/utilities/utbuffer.c
+++ b/sys/contrib/dev/acpica/components/utilities/utbuffer.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utcache.c b/sys/contrib/dev/acpica/components/utilities/utcache.c
index af6df9214a0..1641879e3b4 100644
--- a/sys/contrib/dev/acpica/components/utilities/utcache.c
+++ b/sys/contrib/dev/acpica/components/utilities/utcache.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utcopy.c b/sys/contrib/dev/acpica/components/utilities/utcopy.c
index c1be4cce2e1..57bb41b87a6 100644
--- a/sys/contrib/dev/acpica/components/utilities/utcopy.c
+++ b/sys/contrib/dev/acpica/components/utilities/utcopy.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utdebug.c b/sys/contrib/dev/acpica/components/utilities/utdebug.c
index 2f60e878008..404680c8e99 100644
--- a/sys/contrib/dev/acpica/components/utilities/utdebug.c
+++ b/sys/contrib/dev/acpica/components/utilities/utdebug.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utdecode.c b/sys/contrib/dev/acpica/components/utilities/utdecode.c
index e2a66e20746..006f12119fa 100644
--- a/sys/contrib/dev/acpica/components/utilities/utdecode.c
+++ b/sys/contrib/dev/acpica/components/utilities/utdecode.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utdelete.c b/sys/contrib/dev/acpica/components/utilities/utdelete.c
index d96f1e91d86..a748fcbd5d5 100644
--- a/sys/contrib/dev/acpica/components/utilities/utdelete.c
+++ b/sys/contrib/dev/acpica/components/utilities/utdelete.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/uterror.c b/sys/contrib/dev/acpica/components/utilities/uterror.c
index bc4193fe5ce..69a9bcfff68 100644
--- a/sys/contrib/dev/acpica/components/utilities/uterror.c
+++ b/sys/contrib/dev/acpica/components/utilities/uterror.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/uteval.c b/sys/contrib/dev/acpica/components/utilities/uteval.c
index 8fb69296e47..5cf19451d12 100644
--- a/sys/contrib/dev/acpica/components/utilities/uteval.c
+++ b/sys/contrib/dev/acpica/components/utilities/uteval.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utexcep.c b/sys/contrib/dev/acpica/components/utilities/utexcep.c
index d2ee5bbf1ba..0b960ffca3c 100644
--- a/sys/contrib/dev/acpica/components/utilities/utexcep.c
+++ b/sys/contrib/dev/acpica/components/utilities/utexcep.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utglobal.c b/sys/contrib/dev/acpica/components/utilities/utglobal.c
index 759780a96dc..dd004f6d6ed 100644
--- a/sys/contrib/dev/acpica/components/utilities/utglobal.c
+++ b/sys/contrib/dev/acpica/components/utilities/utglobal.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/uthex.c b/sys/contrib/dev/acpica/components/utilities/uthex.c
index d4571a25889..f30ea363977 100644
--- a/sys/contrib/dev/acpica/components/utilities/uthex.c
+++ b/sys/contrib/dev/acpica/components/utilities/uthex.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utids.c b/sys/contrib/dev/acpica/components/utilities/utids.c
index 4c8a8bef233..cfbd5024c51 100644
--- a/sys/contrib/dev/acpica/components/utilities/utids.c
+++ b/sys/contrib/dev/acpica/components/utilities/utids.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utinit.c b/sys/contrib/dev/acpica/components/utilities/utinit.c
index 87fb9f65be2..f62667c5406 100644
--- a/sys/contrib/dev/acpica/components/utilities/utinit.c
+++ b/sys/contrib/dev/acpica/components/utilities/utinit.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utlock.c b/sys/contrib/dev/acpica/components/utilities/utlock.c
index 39d1808bee1..94d5e75b7b1 100644
--- a/sys/contrib/dev/acpica/components/utilities/utlock.c
+++ b/sys/contrib/dev/acpica/components/utilities/utlock.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utmath.c b/sys/contrib/dev/acpica/components/utilities/utmath.c
index 788e33067d7..4452267a0b6 100644
--- a/sys/contrib/dev/acpica/components/utilities/utmath.c
+++ b/sys/contrib/dev/acpica/components/utilities/utmath.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utmisc.c b/sys/contrib/dev/acpica/components/utilities/utmisc.c
index 13d920f040e..886a07e2c7e 100644
--- a/sys/contrib/dev/acpica/components/utilities/utmisc.c
+++ b/sys/contrib/dev/acpica/components/utilities/utmisc.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utmutex.c b/sys/contrib/dev/acpica/components/utilities/utmutex.c
index ef99ee07807..50bd431edaa 100644
--- a/sys/contrib/dev/acpica/components/utilities/utmutex.c
+++ b/sys/contrib/dev/acpica/components/utilities/utmutex.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utnonansi.c b/sys/contrib/dev/acpica/components/utilities/utnonansi.c
index 720436e4063..41e7e2eb3d7 100644
--- a/sys/contrib/dev/acpica/components/utilities/utnonansi.c
+++ b/sys/contrib/dev/acpica/components/utilities/utnonansi.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utobject.c b/sys/contrib/dev/acpica/components/utilities/utobject.c
index 656568a5136..5dc19c3f3f5 100644
--- a/sys/contrib/dev/acpica/components/utilities/utobject.c
+++ b/sys/contrib/dev/acpica/components/utilities/utobject.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utosi.c b/sys/contrib/dev/acpica/components/utilities/utosi.c
index ec3dade0ef7..a4276033cdd 100644
--- a/sys/contrib/dev/acpica/components/utilities/utosi.c
+++ b/sys/contrib/dev/acpica/components/utilities/utosi.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utownerid.c b/sys/contrib/dev/acpica/components/utilities/utownerid.c
index 0c57dba03eb..eff0dda9681 100644
--- a/sys/contrib/dev/acpica/components/utilities/utownerid.c
+++ b/sys/contrib/dev/acpica/components/utilities/utownerid.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utpredef.c b/sys/contrib/dev/acpica/components/utilities/utpredef.c
index 015d11b6ff6..8eb6810ae88 100644
--- a/sys/contrib/dev/acpica/components/utilities/utpredef.c
+++ b/sys/contrib/dev/acpica/components/utilities/utpredef.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utresrc.c b/sys/contrib/dev/acpica/components/utilities/utresrc.c
index e498c760b8e..0f03a7472a1 100644
--- a/sys/contrib/dev/acpica/components/utilities/utresrc.c
+++ b/sys/contrib/dev/acpica/components/utilities/utresrc.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utstate.c b/sys/contrib/dev/acpica/components/utilities/utstate.c
index 55778e0fc1f..74a844afb19 100644
--- a/sys/contrib/dev/acpica/components/utilities/utstate.c
+++ b/sys/contrib/dev/acpica/components/utilities/utstate.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utstring.c b/sys/contrib/dev/acpica/components/utilities/utstring.c
index 3d02b6c6efe..dcf55669c7a 100644
--- a/sys/contrib/dev/acpica/components/utilities/utstring.c
+++ b/sys/contrib/dev/acpica/components/utilities/utstring.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utstrtoul64.c b/sys/contrib/dev/acpica/components/utilities/utstrtoul64.c
index 5a7294a24d6..80090f2b041 100644
--- a/sys/contrib/dev/acpica/components/utilities/utstrtoul64.c
+++ b/sys/contrib/dev/acpica/components/utilities/utstrtoul64.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/uttrack.c b/sys/contrib/dev/acpica/components/utilities/uttrack.c
index 6cc0cde7fdf..f92e139676f 100644
--- a/sys/contrib/dev/acpica/components/utilities/uttrack.c
+++ b/sys/contrib/dev/acpica/components/utilities/uttrack.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utuuid.c b/sys/contrib/dev/acpica/components/utilities/utuuid.c
index 281305a1a05..dd8fad4c117 100644
--- a/sys/contrib/dev/acpica/components/utilities/utuuid.c
+++ b/sys/contrib/dev/acpica/components/utilities/utuuid.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utxface.c b/sys/contrib/dev/acpica/components/utilities/utxface.c
index df74a51cdb1..ba0e03043ca 100644
--- a/sys/contrib/dev/acpica/components/utilities/utxface.c
+++ b/sys/contrib/dev/acpica/components/utilities/utxface.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utxferror.c b/sys/contrib/dev/acpica/components/utilities/utxferror.c
index 802da6ddce1..ef911ecdbdd 100644
--- a/sys/contrib/dev/acpica/components/utilities/utxferror.c
+++ b/sys/contrib/dev/acpica/components/utilities/utxferror.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utxfinit.c b/sys/contrib/dev/acpica/components/utilities/utxfinit.c
index 0a6fc10243a..1c295a908b9 100644
--- a/sys/contrib/dev/acpica/components/utilities/utxfinit.c
+++ b/sys/contrib/dev/acpica/components/utilities/utxfinit.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/components/utilities/utxfmutex.c b/sys/contrib/dev/acpica/components/utilities/utxfmutex.c
index ef5a7bc619e..f1e3ceaabc5 100644
--- a/sys/contrib/dev/acpica/components/utilities/utxfmutex.c
+++ b/sys/contrib/dev/acpica/components/utilities/utxfmutex.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acapps.h b/sys/contrib/dev/acpica/include/acapps.h
index d14bce1ff03..ebc1cfbcd7e 100644
--- a/sys/contrib/dev/acpica/include/acapps.h
+++ b/sys/contrib/dev/acpica/include/acapps.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -51,26 +51,26 @@
 /* Common info for tool signons */
 
 #define ACPICA_NAME                 "Intel ACPI Component Architecture"
-#define ACPICA_COPYRIGHT            "Copyright (c) 2000 - 2016 Intel Corporation"
+#define ACPICA_COPYRIGHT            "Copyright (c) 2000 - 2017 Intel Corporation"
 
 #if ACPI_MACHINE_WIDTH == 64
-#define ACPI_WIDTH          "-64"
+#define ACPI_WIDTH          " (64-bit version)"
 
 #elif ACPI_MACHINE_WIDTH == 32
-#define ACPI_WIDTH          "-32"
+#define ACPI_WIDTH          " (32-bit version)"
 
 #else
 #error unknown ACPI_MACHINE_WIDTH
-#define ACPI_WIDTH          "-??"
+#define ACPI_WIDTH          " (unknown bit width, not 32 or 64)"
 
 #endif
 
 /* Macros for signons and file headers */
 
 #define ACPI_COMMON_SIGNON(UtilityName) \
-    "\n%s\n%s version %8.8X%s\n%s\n\n", \
+    "\n%s\n%s version %8.8X\n%s\n\n", \
     ACPICA_NAME, \
-    UtilityName, ((UINT32) ACPI_CA_VERSION), ACPI_WIDTH, \
+    UtilityName, ((UINT32) ACPI_CA_VERSION), \
     ACPICA_COPYRIGHT
 
 #define ACPI_COMMON_HEADER(UtilityName, Prefix) \
diff --git a/sys/contrib/dev/acpica/include/acbuffer.h b/sys/contrib/dev/acpica/include/acbuffer.h
index 78f6db4a9ec..73f41ddbedd 100644
--- a/sys/contrib/dev/acpica/include/acbuffer.h
+++ b/sys/contrib/dev/acpica/include/acbuffer.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acclib.h b/sys/contrib/dev/acpica/include/acclib.h
index ab1c3d7676b..6f2226e08de 100644
--- a/sys/contrib/dev/acpica/include/acclib.h
+++ b/sys/contrib/dev/acpica/include/acclib.h
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/accommon.h b/sys/contrib/dev/acpica/include/accommon.h
index 7851c54e0bc..f4afae43253 100644
--- a/sys/contrib/dev/acpica/include/accommon.h
+++ b/sys/contrib/dev/acpica/include/accommon.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acconfig.h b/sys/contrib/dev/acpica/include/acconfig.h
index d6324911e8a..5e1912ea5fb 100644
--- a/sys/contrib/dev/acpica/include/acconfig.h
+++ b/sys/contrib/dev/acpica/include/acconfig.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acdebug.h b/sys/contrib/dev/acpica/include/acdebug.h
index c5b8eb4bdad..22225c3d5cf 100644
--- a/sys/contrib/dev/acpica/include/acdebug.h
+++ b/sys/contrib/dev/acpica/include/acdebug.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acdisasm.h b/sys/contrib/dev/acpica/include/acdisasm.h
index 3ba84ea6e90..9b43dcd8be4 100644
--- a/sys/contrib/dev/acpica/include/acdisasm.h
+++ b/sys/contrib/dev/acpica/include/acdisasm.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acdispat.h b/sys/contrib/dev/acpica/include/acdispat.h
index 1a6f39e2aa8..f66003c715c 100644
--- a/sys/contrib/dev/acpica/include/acdispat.h
+++ b/sys/contrib/dev/acpica/include/acdispat.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acevents.h b/sys/contrib/dev/acpica/include/acevents.h
index a2ea52042e4..2bb6bf619c9 100644
--- a/sys/contrib/dev/acpica/include/acevents.h
+++ b/sys/contrib/dev/acpica/include/acevents.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acexcep.h b/sys/contrib/dev/acpica/include/acexcep.h
index 2fe81dccce3..6bc741cb08d 100644
--- a/sys/contrib/dev/acpica/include/acexcep.h
+++ b/sys/contrib/dev/acpica/include/acexcep.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acglobal.h b/sys/contrib/dev/acpica/include/acglobal.h
index 60a2ffddfbf..d83825f0fab 100644
--- a/sys/contrib/dev/acpica/include/acglobal.h
+++ b/sys/contrib/dev/acpica/include/acglobal.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/achware.h b/sys/contrib/dev/acpica/include/achware.h
index b7a5f20fec2..a97ec5707e9 100644
--- a/sys/contrib/dev/acpica/include/achware.h
+++ b/sys/contrib/dev/acpica/include/achware.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acinterp.h b/sys/contrib/dev/acpica/include/acinterp.h
index 148e8d0cafe..78eaa1afa20 100644
--- a/sys/contrib/dev/acpica/include/acinterp.h
+++ b/sys/contrib/dev/acpica/include/acinterp.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/aclocal.h b/sys/contrib/dev/acpica/include/aclocal.h
index 734cae17a3b..3b5f779edc2 100644
--- a/sys/contrib/dev/acpica/include/aclocal.h
+++ b/sys/contrib/dev/acpica/include/aclocal.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acmacros.h b/sys/contrib/dev/acpica/include/acmacros.h
index 5a5e79318a7..0e6dee66ff7 100644
--- a/sys/contrib/dev/acpica/include/acmacros.h
+++ b/sys/contrib/dev/acpica/include/acmacros.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acnames.h b/sys/contrib/dev/acpica/include/acnames.h
index 4710323e0c3..9ef39736220 100644
--- a/sys/contrib/dev/acpica/include/acnames.h
+++ b/sys/contrib/dev/acpica/include/acnames.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acnamesp.h b/sys/contrib/dev/acpica/include/acnamesp.h
index 09b319cc87c..651b0d021e3 100644
--- a/sys/contrib/dev/acpica/include/acnamesp.h
+++ b/sys/contrib/dev/acpica/include/acnamesp.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acobject.h b/sys/contrib/dev/acpica/include/acobject.h
index 83f29ec3c98..a40256952fa 100644
--- a/sys/contrib/dev/acpica/include/acobject.h
+++ b/sys/contrib/dev/acpica/include/acobject.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acopcode.h b/sys/contrib/dev/acpica/include/acopcode.h
index e5c35255ca5..ce4e420bfa6 100644
--- a/sys/contrib/dev/acpica/include/acopcode.h
+++ b/sys/contrib/dev/acpica/include/acopcode.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acoutput.h b/sys/contrib/dev/acpica/include/acoutput.h
index 4fb718208c6..0bee1bebcb3 100644
--- a/sys/contrib/dev/acpica/include/acoutput.h
+++ b/sys/contrib/dev/acpica/include/acoutput.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acparser.h b/sys/contrib/dev/acpica/include/acparser.h
index 4137981024f..f92efd8bdca 100644
--- a/sys/contrib/dev/acpica/include/acparser.h
+++ b/sys/contrib/dev/acpica/include/acparser.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acpi.h b/sys/contrib/dev/acpica/include/acpi.h
index 6c422de801e..b17c6909e4f 100644
--- a/sys/contrib/dev/acpica/include/acpi.h
+++ b/sys/contrib/dev/acpica/include/acpi.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acpiosxf.h b/sys/contrib/dev/acpica/include/acpiosxf.h
index f99074fb782..83cdf4372ea 100644
--- a/sys/contrib/dev/acpica/include/acpiosxf.h
+++ b/sys/contrib/dev/acpica/include/acpiosxf.h
@@ -7,7 +7,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acpixf.h b/sys/contrib/dev/acpica/include/acpixf.h
index 7234ae8e331..ae946711c94 100644
--- a/sys/contrib/dev/acpica/include/acpixf.h
+++ b/sys/contrib/dev/acpica/include/acpixf.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20161222
+#define ACPI_CA_VERSION                 0x20170119
 
 #include 
 #include 
diff --git a/sys/contrib/dev/acpica/include/acpredef.h b/sys/contrib/dev/acpica/include/acpredef.h
index ab61c53d7bf..bc89d7289c8 100644
--- a/sys/contrib/dev/acpica/include/acpredef.h
+++ b/sys/contrib/dev/acpica/include/acpredef.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acresrc.h b/sys/contrib/dev/acpica/include/acresrc.h
index 001e6d22af5..08ad0964312 100644
--- a/sys/contrib/dev/acpica/include/acresrc.h
+++ b/sys/contrib/dev/acpica/include/acresrc.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acrestyp.h b/sys/contrib/dev/acpica/include/acrestyp.h
index 72f0d163108..1c8f70ce691 100644
--- a/sys/contrib/dev/acpica/include/acrestyp.h
+++ b/sys/contrib/dev/acpica/include/acrestyp.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acstruct.h b/sys/contrib/dev/acpica/include/acstruct.h
index f7538aded9b..c675b830ebf 100644
--- a/sys/contrib/dev/acpica/include/acstruct.h
+++ b/sys/contrib/dev/acpica/include/acstruct.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/actables.h b/sys/contrib/dev/acpica/include/actables.h
index 3269728a7fd..88e959dc109 100644
--- a/sys/contrib/dev/acpica/include/actables.h
+++ b/sys/contrib/dev/acpica/include/actables.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/actbl.h b/sys/contrib/dev/acpica/include/actbl.h
index a1d5d8f06c7..39b01c2d238 100644
--- a/sys/contrib/dev/acpica/include/actbl.h
+++ b/sys/contrib/dev/acpica/include/actbl.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/actbl1.h b/sys/contrib/dev/acpica/include/actbl1.h
index 0fe925a84bf..c27f4996693 100644
--- a/sys/contrib/dev/acpica/include/actbl1.h
+++ b/sys/contrib/dev/acpica/include/actbl1.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/actbl2.h b/sys/contrib/dev/acpica/include/actbl2.h
index 625d33fab9c..86d3a43f96b 100644
--- a/sys/contrib/dev/acpica/include/actbl2.h
+++ b/sys/contrib/dev/acpica/include/actbl2.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/actbl3.h b/sys/contrib/dev/acpica/include/actbl3.h
index ef40f19fc0a..65711de1c63 100644
--- a/sys/contrib/dev/acpica/include/actbl3.h
+++ b/sys/contrib/dev/acpica/include/actbl3.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/actypes.h b/sys/contrib/dev/acpica/include/actypes.h
index 0d2ab4cc8ad..ca96eb6796a 100644
--- a/sys/contrib/dev/acpica/include/actypes.h
+++ b/sys/contrib/dev/acpica/include/actypes.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acutils.h b/sys/contrib/dev/acpica/include/acutils.h
index 1cc760fb672..21bc9e4fecf 100644
--- a/sys/contrib/dev/acpica/include/acutils.h
+++ b/sys/contrib/dev/acpica/include/acutils.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/acuuid.h b/sys/contrib/dev/acpica/include/acuuid.h
index 5c42990ab93..5c2e31376ea 100644
--- a/sys/contrib/dev/acpica/include/acuuid.h
+++ b/sys/contrib/dev/acpica/include/acuuid.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/amlcode.h b/sys/contrib/dev/acpica/include/amlcode.h
index 640029b4428..401dfc3fb4d 100644
--- a/sys/contrib/dev/acpica/include/amlcode.h
+++ b/sys/contrib/dev/acpica/include/amlcode.h
@@ -7,7 +7,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/amlresrc.h b/sys/contrib/dev/acpica/include/amlresrc.h
index 960da1b3107..79aa5ba40c9 100644
--- a/sys/contrib/dev/acpica/include/amlresrc.h
+++ b/sys/contrib/dev/acpica/include/amlresrc.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/platform/acenv.h b/sys/contrib/dev/acpica/include/platform/acenv.h
index 06438700e68..58d5351c25a 100644
--- a/sys/contrib/dev/acpica/include/platform/acenv.h
+++ b/sys/contrib/dev/acpica/include/platform/acenv.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/platform/acenvex.h b/sys/contrib/dev/acpica/include/platform/acenvex.h
index d7da594b926..0261b0ce9e3 100644
--- a/sys/contrib/dev/acpica/include/platform/acenvex.h
+++ b/sys/contrib/dev/acpica/include/platform/acenvex.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/platform/acfreebsd.h b/sys/contrib/dev/acpica/include/platform/acfreebsd.h
index 928aaa64bd5..211b379361c 100644
--- a/sys/contrib/dev/acpica/include/platform/acfreebsd.h
+++ b/sys/contrib/dev/acpica/include/platform/acfreebsd.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/platform/acgcc.h b/sys/contrib/dev/acpica/include/platform/acgcc.h
index 732de2aabff..c053aa93494 100644
--- a/sys/contrib/dev/acpica/include/platform/acgcc.h
+++ b/sys/contrib/dev/acpica/include/platform/acgcc.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/include/platform/acgccex.h b/sys/contrib/dev/acpica/include/platform/acgccex.h
index 3c02ad50649..c17d93fb786 100644
--- a/sys/contrib/dev/acpica/include/platform/acgccex.h
+++ b/sys/contrib/dev/acpica/include/platform/acgccex.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/os_specific/service_layers/osgendbg.c b/sys/contrib/dev/acpica/os_specific/service_layers/osgendbg.c
index 0e9bfa65ec0..64ac4fc19a6 100644
--- a/sys/contrib/dev/acpica/os_specific/service_layers/osgendbg.c
+++ b/sys/contrib/dev/acpica/os_specific/service_layers/osgendbg.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c b/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c
index 1b05ef07910..571cce5b6b5 100644
--- a/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c
+++ b/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2016, Intel Corp.
+ * Copyright (C) 2000 - 2017, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -370,7 +370,7 @@ AcpiOsPhysicalTableOverride (
  * RETURN:      Status
  *
  * DESCRIPTION: A hook before writing sleep registers to enter the sleep
- *              state. Return AE_CTRL_SKIP to skip further sleep register
+ *              state. Return AE_CTRL_TERMINATE to skip further sleep register
  *              writes.
  *
  *****************************************************************************/
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index fe165c3daf8..0dcf1a24d13 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -1178,7 +1178,8 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
 			sc->sc_has_ldpc = 1;
 			device_printf(sc->sc_dev,
 			    "[HT] LDPC transmit/receive enabled\n");
-			ic->ic_htcaps |= IEEE80211_HTCAP_LDPC;
+			ic->ic_htcaps |= IEEE80211_HTCAP_LDPC |
+					 IEEE80211_HTC_TXLDPC;
 		}
 
 
@@ -1638,6 +1639,7 @@ ath_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
 	 * However, for now that's enforced by the TX path.
 	 */
 	vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_64K;
+	vap->iv_ampdu_limit = IEEE80211_HTCAP_MAXRXAMPDU_64K;
 
 	avp->av_bslot = -1;
 	if (needbeacon) {
diff --git a/sys/dev/ath/if_ath_tx_ht.c b/sys/dev/ath/if_ath_tx_ht.c
index 5226d4d52ad..ff79b78817d 100644
--- a/sys/dev/ath/if_ath_tx_ht.c
+++ b/sys/dev/ath/if_ath_tx_ht.c
@@ -239,7 +239,7 @@ ath_tx_rate_fill_rcflags(struct ath_softc *sc, struct ath_buf *bf)
 	 * it if any of the rate entries aren't 11n.
 	 */
 	do_ldpc = 0;
-	if ((ni->ni_vap->iv_htcaps & IEEE80211_HTCAP_LDPC) &&
+	if ((ni->ni_vap->iv_flags_ht & IEEE80211_FHT_LDPC_TX) &&
 	    (ni->ni_htcap & IEEE80211_HTCAP_LDPC))
 		do_ldpc = 1;
 
@@ -402,7 +402,7 @@ ath_tx_rate_fill_rcflags(struct ath_softc *sc, struct ath_buf *bf)
  */
 static int
 ath_compute_num_delims(struct ath_softc *sc, struct ath_buf *first_bf,
-    uint16_t pktlen)
+    uint16_t pktlen, int is_first)
 {
 #define	MS(_v, _f)	(((_v) & _f) >> _f##_S)
 	const HAL_RATE_TABLE *rt = sc->sc_currates;
@@ -458,11 +458,12 @@ ath_compute_num_delims(struct ath_softc *sc, struct ath_buf *first_bf,
 	 * For AR9380, there's a minimum number of delimeters
 	 * required when doing RTS.
 	 *
-	 * XXX TODO: this is only needed if (a) RTS/CTS is enabled, and
-	 * XXX (b) this is the first sub-frame in the aggregate.
+	 * XXX TODO: this is only needed if (a) RTS/CTS is enabled for
+	 * this exchange, and (b) (done) this is the first sub-frame
+	 * in the aggregate.
 	 */
 	if (sc->sc_use_ent && (sc->sc_ent_cfg & AH_ENT_RTSCTS_DELIM_WAR)
-	    && ndelim < AH_FIRST_DESC_NDELIMS)
+	    && ndelim < AH_FIRST_DESC_NDELIMS && is_first)
 		ndelim = AH_FIRST_DESC_NDELIMS;
 
 	/*
@@ -589,8 +590,14 @@ ath_get_aggr_limit(struct ath_softc *sc, struct ieee80211_node *ni,
 		amin = MIN(amin, bf->bf_state.bfs_rc[i].max4msframelen);
 	}
 
-	DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR, "%s: max frame len= %d\n",
-	    __func__, amin);
+	DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
+	    "%s: aggr_limit=%d, iv_ampdu_limit=%d, "
+	    "peer maxrxampdu=%d, max frame len=%d\n",
+	    __func__,
+	    sc->sc_aggr_limit,
+	    vap->iv_ampdu_limit,
+	    MS(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU),
+	    amin);
 
 	return amin;
 #undef	MS
@@ -969,7 +976,7 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_node *an,
 		 */
 		bf->bf_state.bfs_ndelim =
 		    ath_compute_num_delims(sc, bf_first,
-		    bf->bf_state.bfs_pktlen);
+		    bf->bf_state.bfs_pktlen, (bf_first == bf));
 
 		/*
 		 * Calculate the padding needed from this set of delimiters,
diff --git a/sys/dev/cxgbe/tom/t4_listen.c b/sys/dev/cxgbe/tom/t4_listen.c
index 836c9cb6fcf..0368cef10d8 100644
--- a/sys/dev/cxgbe/tom/t4_listen.c
+++ b/sys/dev/cxgbe/tom/t4_listen.c
@@ -1418,6 +1418,7 @@ found:
 		if (!(synqe->flags & TPF_SYNQE_EXPANDED))
 			send_reset_synqe(tod, synqe);
 		INP_WUNLOCK(inp);
+		CURVNET_RESTORE();
 
 		release_synqe(synqe);	/* extra hold */
 		return (__LINE__);
diff --git a/sys/dev/e1000/e1000_82575.c b/sys/dev/e1000/e1000_82575.c
index 24538cadca2..5d68e8b9718 100644
--- a/sys/dev/e1000/e1000_82575.c
+++ b/sys/dev/e1000/e1000_82575.c
@@ -101,7 +101,6 @@ static s32 e1000_validate_nvm_checksum_with_offset(struct e1000_hw *hw,
 						   u16 offset);
 static s32 e1000_validate_nvm_checksum_i350(struct e1000_hw *hw);
 static s32 e1000_update_nvm_checksum_i350(struct e1000_hw *hw);
-static void e1000_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value);
 static void e1000_clear_vfta_i350(struct e1000_hw *hw);
 
 static void e1000_i2c_start(struct e1000_hw *hw);
diff --git a/sys/dev/e1000/e1000_82575.h b/sys/dev/e1000/e1000_82575.h
index 45fe132e4a4..f81795605c0 100644
--- a/sys/dev/e1000/e1000_82575.h
+++ b/sys/dev/e1000/e1000_82575.h
@@ -493,6 +493,7 @@ enum e1000_promisc_type {
 void e1000_vfta_set_vf(struct e1000_hw *, u16, bool);
 void e1000_rlpml_set_vf(struct e1000_hw *, u16);
 s32 e1000_promisc_set_vf(struct e1000_hw *, enum e1000_promisc_type type);
+void e1000_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value);
 u16 e1000_rxpbs_adjust_82580(u32 data);
 s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data);
 s32 e1000_set_eee_i350(struct e1000_hw *hw, bool adv1G, bool adv100M);
diff --git a/sys/dev/e1000/e1000_defines.h b/sys/dev/e1000/e1000_defines.h
index e33fe0fb798..4c2b0903855 100644
--- a/sys/dev/e1000/e1000_defines.h
+++ b/sys/dev/e1000/e1000_defines.h
@@ -469,6 +469,8 @@
 
 #define ETHERNET_FCS_SIZE		4
 #define MAX_JUMBO_FRAME_SIZE		0x3F00
+/* The datasheet maximum supported RX size is 9.5KB (9728 bytes) */
+#define MAX_RX_JUMBO_FRAME_SIZE		0x2600
 #define E1000_TX_PTR_GAP		0x1F
 
 /* Extended Configuration Control and Size */
diff --git a/sys/dev/e1000/e1000_ich8lan.c b/sys/dev/e1000/e1000_ich8lan.c
index 4c50ce29638..0d8485ff3fa 100644
--- a/sys/dev/e1000/e1000_ich8lan.c
+++ b/sys/dev/e1000/e1000_ich8lan.c
@@ -243,8 +243,7 @@ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw)
 	if (ret_val)
 		return FALSE;
 out:
-	if ((hw->mac.type == e1000_pch_lpt) ||
-	    (hw->mac.type == e1000_pch_spt)) {
+	if (hw->mac.type >= e1000_pch_lpt) {
 		/* Only unforce SMBus if ME is not active */
 		if (!(E1000_READ_REG(hw, E1000_FWSM) &
 		    E1000_ICH_FWSM_FW_VALID)) {
@@ -641,7 +640,7 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
 
 	nvm->type = e1000_nvm_flash_sw;
 
-	if (hw->mac.type == e1000_pch_spt) {
+	if (hw->mac.type >= e1000_pch_spt) {
 		/* in SPT, gfpreg doesn't exist. NVM size is taken from the
 		 * STRAP register. This is because in SPT the GbE Flash region
 		 * is no longer accessed through the flash registers. Instead,
@@ -701,7 +700,7 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
 	/* Function Pointers */
 	nvm->ops.acquire	= e1000_acquire_nvm_ich8lan;
 	nvm->ops.release	= e1000_release_nvm_ich8lan;
-	if (hw->mac.type == e1000_pch_spt) {
+	if (hw->mac.type >= e1000_pch_spt) {
 		nvm->ops.read	= e1000_read_nvm_spt;
 		nvm->ops.update	= e1000_update_nvm_checksum_spt;
 	} else {
@@ -815,8 +814,7 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
 		break;
 	}
 
-	if ((mac->type == e1000_pch_lpt) ||
-	    (mac->type == e1000_pch_spt)) {
+	if (mac->type >= e1000_pch_lpt) {
 		mac->rar_entry_count = E1000_PCH_LPT_RAR_ENTRIES;
 		mac->ops.rar_set = e1000_rar_set_pch_lpt;
 		mac->ops.setup_physical_interface = e1000_setup_copper_link_pch_lpt;
@@ -1576,9 +1574,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 	 * aggressive resulting in many collisions. To avoid this, increase
 	 * the IPG and reduce Rx latency in the PHY.
 	 */
-	if (((hw->mac.type == e1000_pch2lan) ||
-	     (hw->mac.type == e1000_pch_lpt) ||
-	     (hw->mac.type == e1000_pch_spt)) && link) {
+	if ((hw->mac.type >= e1000_pch2lan) && link) {
 		u16 speed, duplex;
 
 		e1000_get_speed_and_duplex_copper_generic(hw, &speed, &duplex);
@@ -1589,7 +1585,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 			tipg_reg |= 0xFF;
 			/* Reduce Rx latency in analog PHY */
 			emi_val = 0;
-		} else if (hw->mac.type == e1000_pch_spt &&
+		} else if (hw->mac.type >= e1000_pch_spt &&
 			   duplex == FULL_DUPLEX && speed != SPEED_1000) {
 			tipg_reg |= 0xC;
 			emi_val = 1;
@@ -1611,8 +1607,8 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 			emi_addr = I217_RX_CONFIG;
 		ret_val = e1000_write_emi_reg_locked(hw, emi_addr, emi_val);
 
-		if (hw->mac.type == e1000_pch_lpt ||
-		    hw->mac.type == e1000_pch_spt) {
+
+		if (hw->mac.type >= e1000_pch_lpt) {
 			u16 phy_reg;
 
 			hw->phy.ops.read_reg_locked(hw, I217_PLL_CLOCK_GATE_REG,
@@ -1641,7 +1637,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 		if (ret_val)
 			return ret_val;
 
-		if (hw->mac.type == e1000_pch_spt) {
+		if (hw->mac.type >= e1000_pch_spt) {
 			u16 data;
 			u16 ptr_gap;
 
@@ -1690,8 +1686,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 	 * on power up.
 	 * Set the Beacon Duration for I217 to 8 usec
 	 */
-	if ((hw->mac.type == e1000_pch_lpt) ||
-	    (hw->mac.type == e1000_pch_spt)) {
+	if (hw->mac.type >= e1000_pch_lpt) {
 		u32 mac_reg;
 
 		mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM4);
@@ -1709,8 +1704,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 		if (ret_val)
 			return ret_val;
 	}
-	if ((hw->mac.type == e1000_pch_lpt) ||
-	    (hw->mac.type == e1000_pch_spt)) {
+	if (hw->mac.type >= e1000_pch_lpt) {
 		/* Set platform power management values for
 		 * Latency Tolerance Reporting (LTR)
 		 * Optimized Buffer Flush/Fill (OBFF)
@@ -1723,15 +1717,20 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 	/* Clear link partner's EEE ability */
 	hw->dev_spec.ich8lan.eee_lp_ability = 0;
 
-	/* FEXTNVM6 K1-off workaround */
-	if (hw->mac.type == e1000_pch_spt) {
-		u32 pcieanacfg = E1000_READ_REG(hw, E1000_PCIEANACFG);
+	if (hw->mac.type >= e1000_pch_lpt) {
 		u32 fextnvm6 = E1000_READ_REG(hw, E1000_FEXTNVM6);
 
-		if ((pcieanacfg & E1000_FEXTNVM6_K1_OFF_ENABLE) &&
-			(hw->dev_spec.ich8lan.disable_k1_off == FALSE))
-			fextnvm6 |= E1000_FEXTNVM6_K1_OFF_ENABLE;
-		else
+		if (hw->mac.type == e1000_pch_spt) {
+			/* FEXTNVM6 K1-off workaround - for SPT only */
+			u32 pcieanacfg = E1000_READ_REG(hw, E1000_PCIEANACFG);
+
+			if (pcieanacfg & E1000_FEXTNVM6_K1_OFF_ENABLE)
+				fextnvm6 |= E1000_FEXTNVM6_K1_OFF_ENABLE;
+			else
+				fextnvm6 &= ~E1000_FEXTNVM6_K1_OFF_ENABLE;
+		}
+
+		if (hw->dev_spec.ich8lan.disable_k1_off == TRUE)
 			fextnvm6 &= ~E1000_FEXTNVM6_K1_OFF_ENABLE;
 
 		E1000_WRITE_REG(hw, E1000_FEXTNVM6, fextnvm6);
@@ -3671,7 +3670,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
 	/* Clear FCERR and DAEL in hw status by writing 1 */
 	hsfsts.hsf_status.flcerr = 1;
 	hsfsts.hsf_status.dael = 1;
-	if (hw->mac.type == e1000_pch_spt)
+	if (hw->mac.type >= e1000_pch_spt)
 		E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
 				      hsfsts.regval & 0xFFFF);
 	else
@@ -3691,7 +3690,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
 		 * Begin by setting Flash Cycle Done.
 		 */
 		hsfsts.hsf_status.flcdone = 1;
-		if (hw->mac.type == e1000_pch_spt)
+		if (hw->mac.type >= e1000_pch_spt)
 			E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
 					      hsfsts.regval & 0xFFFF);
 		else
@@ -3718,7 +3717,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
 			 * now set the Flash Cycle Done.
 			 */
 			hsfsts.hsf_status.flcdone = 1;
-			if (hw->mac.type == e1000_pch_spt)
+			if (hw->mac.type >= e1000_pch_spt)
 				E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
 						      hsfsts.regval & 0xFFFF);
 			else
@@ -3748,13 +3747,13 @@ static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout)
 	DEBUGFUNC("e1000_flash_cycle_ich8lan");
 
 	/* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */
-	if (hw->mac.type == e1000_pch_spt)
+	if (hw->mac.type >= e1000_pch_spt)
 		hsflctl.regval = E1000_READ_FLASH_REG(hw, ICH_FLASH_HSFSTS)>>16;
 	else
 		hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
 	hsflctl.hsf_ctrl.flcgo = 1;
 
-	if (hw->mac.type == e1000_pch_spt)
+	if (hw->mac.type >= e1000_pch_spt)
 		E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
 				      hsflctl.regval << 16);
 	else
@@ -3837,7 +3836,7 @@ static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
 	/* In SPT, only 32 bits access is supported,
 	 * so this function should not be called.
 	 */
-	if (hw->mac.type == e1000_pch_spt)
+	if (hw->mac.type >= e1000_pch_spt)
 		return -E1000_ERR_NVM;
 	else
 		ret_val = e1000_read_flash_data_ich8lan(hw, offset, 1, &word);
@@ -3946,7 +3945,7 @@ static s32 e1000_read_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset,
 	DEBUGFUNC("e1000_read_flash_data_ich8lan");
 
 		if (offset > ICH_FLASH_LINEAR_ADDR_MASK ||
-		    hw->mac.type != e1000_pch_spt)
+		    hw->mac.type < e1000_pch_spt)
 			return -E1000_ERR_NVM;
 	flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) +
 			     hw->nvm.flash_base_addr);
@@ -4434,7 +4433,7 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
 
 	DEBUGFUNC("e1000_write_ich8_data");
 
-	if (hw->mac.type == e1000_pch_spt) {
+	if (hw->mac.type >= e1000_pch_spt) {
 		if (size != 4 || offset > ICH_FLASH_LINEAR_ADDR_MASK)
 			return -E1000_ERR_NVM;
 	} else {
@@ -4454,7 +4453,7 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
 		/* In SPT, This register is in Lan memory space, not
 		 * flash.  Therefore, only 32 bit access is supported
 		 */
-		if (hw->mac.type == e1000_pch_spt)
+		if (hw->mac.type >= e1000_pch_spt)
 			hsflctl.regval =
 			    E1000_READ_FLASH_REG(hw, ICH_FLASH_HSFSTS)>>16;
 		else
@@ -4468,7 +4467,7 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
 		 * not flash.  Therefore, only 32 bit access is
 		 * supported
 		 */
-		if (hw->mac.type == e1000_pch_spt)
+		if (hw->mac.type >= e1000_pch_spt)
 			E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
 					      hsflctl.regval << 16);
 		else
@@ -4530,7 +4529,7 @@ static s32 e1000_write_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset,
 
 	DEBUGFUNC("e1000_write_flash_data32_ich8lan");
 
-	if (hw->mac.type == e1000_pch_spt) {
+	if (hw->mac.type >= e1000_pch_spt) {
 		if (offset > ICH_FLASH_LINEAR_ADDR_MASK)
 			return -E1000_ERR_NVM;
 	}
@@ -4546,7 +4545,7 @@ static s32 e1000_write_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset,
 		/* In SPT, This register is in Lan memory space, not
 		 * flash.  Therefore, only 32 bit access is supported
 		 */
-		if (hw->mac.type == e1000_pch_spt)
+		if (hw->mac.type >= e1000_pch_spt)
 			hsflctl.regval = E1000_READ_FLASH_REG(hw,
 							      ICH_FLASH_HSFSTS)
 					 >> 16;
@@ -4561,7 +4560,7 @@ static s32 e1000_write_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset,
 		 * not flash.  Therefore, only 32 bit access is
 		 * supported
 		 */
-		if (hw->mac.type == e1000_pch_spt)
+		if (hw->mac.type >= e1000_pch_spt)
 			E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
 					      hsflctl.regval << 16);
 		else
@@ -4763,7 +4762,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
 			/* Write a value 11 (block Erase) in Flash
 			 * Cycle field in hw flash control
 			 */
-			if (hw->mac.type == e1000_pch_spt)
+			if (hw->mac.type >= e1000_pch_spt)
 				hsflctl.regval =
 				    E1000_READ_FLASH_REG(hw,
 							 ICH_FLASH_HSFSTS)>>16;
@@ -4773,7 +4772,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
 							   ICH_FLASH_HSFCTL);
 
 			hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE;
-			if (hw->mac.type == e1000_pch_spt)
+			if (hw->mac.type >= e1000_pch_spt)
 				E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
 						      hsflctl.regval << 16);
 			else
@@ -5211,8 +5210,7 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
 	E1000_WRITE_REG(hw, E1000_RFCTL, reg);
 
 	/* Enable ECC on Lynxpoint */
-	if ((hw->mac.type == e1000_pch_lpt) ||
-	    (hw->mac.type == e1000_pch_spt)) {
+	if (hw->mac.type >= e1000_pch_lpt) {
 		reg = E1000_READ_REG(hw, E1000_PBECCSTS);
 		reg |= E1000_PBECCSTS_ECC_ENABLE;
 		E1000_WRITE_REG(hw, E1000_PBECCSTS, reg);
@@ -5645,7 +5643,7 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)
 		    (device_id == E1000_DEV_ID_PCH_LPTLP_I218_V) ||
 		    (device_id == E1000_DEV_ID_PCH_I218_LM3) ||
 		    (device_id == E1000_DEV_ID_PCH_I218_V3) ||
-		    (hw->mac.type == e1000_pch_spt)) {
+		    (hw->mac.type >= e1000_pch_spt)) {
 			u32 fextnvm6 = E1000_READ_REG(hw, E1000_FEXTNVM6);
 
 			E1000_WRITE_REG(hw, E1000_FEXTNVM6,
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index e874fc31474..9ddf08bb224 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -159,6 +159,10 @@ static pci_vendor_info_t em_vendor_info_array[] =
 	PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_LM2, "Intel(R) PRO/1000 Network Connection"),
 	PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_V2, "Intel(R) PRO/1000 Network Connection"),
 	PVID(0x8086, E1000_DEV_ID_PCH_LBG_I219_LM3, "Intel(R) PRO/1000 Network Connection"),
+	PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_LM4, "Intel(R) PRO/1000 Network Connection"),
+	PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_V4, "Intel(R) PRO/1000 Network Connection"),
+	PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_LM5, "Intel(R) PRO/1000 Network Connection"),
+	PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_V5, "Intel(R) PRO/1000 Network Connection"),
 	/* required last entry */
 	PVID_END
 };
diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h
index d7290fd7245..cf9d13cbf3e 100644
--- a/sys/dev/e1000/if_em.h
+++ b/sys/dev/e1000/if_em.h
@@ -436,7 +436,7 @@ struct adapter {
 #define intr_type shared->isc_intr
 	/* FreeBSD operating-system-specific structures. */
 	struct e1000_osdep osdep;
-	struct device	*dev;
+	device_t	dev;
 	struct cdev	*led_dev;
 
         struct em_tx_queue *tx_queues;
diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c
index cf2231dc8fc..f54dbf7f573 100644
--- a/sys/dev/ixgbe/if_ix.c
+++ b/sys/dev/ixgbe/if_ix.c
@@ -3878,6 +3878,7 @@ ixgbe_handle_msf(void *context, int pending)
 	/* Adjust media types shown in ifconfig */
 	ifmedia_removeall(&adapter->media);
 	ixgbe_add_media_types(adapter);
+	ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
 	IXGBE_CORE_UNLOCK(adapter);
 	return;
 }
diff --git a/sys/dev/mlx5/cq.h b/sys/dev/mlx5/cq.h
index 85e48466806..60819f70f30 100644
--- a/sys/dev/mlx5/cq.h
+++ b/sys/dev/mlx5/cq.h
@@ -88,6 +88,7 @@ enum {
 	MLX5_CQ_MODIFY_PERIOD	= 1 << 0,
 	MLX5_CQ_MODIFY_COUNT	= 1 << 1,
 	MLX5_CQ_MODIFY_OVERRUN	= 1 << 2,
+	MLX5_CQ_MODIFY_PERIOD_MODE = 1 << 4,
 };
 
 enum {
@@ -165,6 +166,11 @@ int mlx5_core_modify_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
 int mlx5_core_modify_cq_moderation(struct mlx5_core_dev *dev,
 				   struct mlx5_core_cq *cq, u16 cq_period,
 				   u16 cq_max_count);
+int mlx5_core_modify_cq_moderation_mode(struct mlx5_core_dev *dev,
+					struct mlx5_core_cq *cq,
+					u16 cq_period,
+					u16 cq_max_count,
+					u8 cq_mode);
 int mlx5_debug_cq_add(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq);
 void mlx5_debug_cq_remove(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq);
 
diff --git a/sys/dev/mlx5/mlx5_core/mlx5_cq.c b/sys/dev/mlx5/mlx5_core/mlx5_cq.c
index bab3f294267..5a7b39d7e32 100644
--- a/sys/dev/mlx5/mlx5_core/mlx5_cq.c
+++ b/sys/dev/mlx5/mlx5_core/mlx5_cq.c
@@ -266,6 +266,28 @@ int mlx5_core_modify_cq_moderation(struct mlx5_core_dev *dev,
 	return mlx5_core_modify_cq(dev, cq, &in, sizeof(in));
 }
 
+int mlx5_core_modify_cq_moderation_mode(struct mlx5_core_dev *dev,
+					struct mlx5_core_cq *cq,
+					u16 cq_period,
+					u16 cq_max_count,
+					u8 cq_mode)
+{
+	struct mlx5_modify_cq_mbox_in in;
+
+	memset(&in, 0, sizeof(in));
+
+	in.cqn              = cpu_to_be32(cq->cqn);
+	in.ctx.cq_period    = cpu_to_be16(cq_period);
+	in.ctx.cq_max_count = cpu_to_be16(cq_max_count);
+	in.ctx.cqe_sz_flags = (cq_mode & 2) >> 1;
+	in.ctx.st	    = (cq_mode & 1) << 7;
+	in.field_select     = cpu_to_be32(MLX5_CQ_MODIFY_PERIOD |
+					  MLX5_CQ_MODIFY_COUNT |
+					  MLX5_CQ_MODIFY_PERIOD_MODE);
+
+	return mlx5_core_modify_cq(dev, cq, &in, sizeof(in));
+}
+
 int mlx5_init_cq_table(struct mlx5_core_dev *dev)
 {
 	struct mlx5_cq_table *table = &dev->priv.cq_table;
diff --git a/sys/dev/mlx5/mlx5_en/en.h b/sys/dev/mlx5/mlx5_en/en.h
index bbb71cae044..b05d13baff7 100644
--- a/sys/dev/mlx5/mlx5_en/en.h
+++ b/sys/dev/mlx5/mlx5_en/en.h
@@ -402,6 +402,7 @@ struct mlx5e_params {
   m(+1, u64 tx_coalesce_usecs, "tx_coalesce_usecs", "Limit in usec for joining tx packets") \
   m(+1, u64 tx_coalesce_pkts, "tx_coalesce_pkts", "Maximum number of tx packets to join") \
   m(+1, u64 tx_coalesce_mode, "tx_coalesce_mode", "0: EQE mode 1: CQE mode") \
+  m(+1, u64 tx_bufring_disable, "tx_bufring_disable", "0: Enable bufring 1: Disable bufring") \
   m(+1, u64 tx_completion_fact, "tx_completion_fact", "1..MAX: Completion event ratio") \
   m(+1, u64 tx_completion_fact_max, "tx_completion_fact_max", "Maximum completion event ratio") \
   m(+1, u64 hw_lro, "hw_lro", "set to enable hw_lro") \
@@ -507,10 +508,11 @@ struct mlx5e_sq {
 	u16	bf_offset;
 	u16	cev_counter;		/* completion event counter */
 	u16	cev_factor;		/* completion event factor */
-	u32	cev_next_state;		/* next completion event state */
+	u16	cev_next_state;		/* next completion event state */
 #define	MLX5E_CEV_STATE_INITIAL 0	/* timer not started */
 #define	MLX5E_CEV_STATE_SEND_NOPS 1	/* send NOPs */
 #define	MLX5E_CEV_STATE_HOLD_NOPS 2	/* don't send NOPs yet */
+	u16	stopped;		/* set if SQ is stopped */
 	struct callout cev_callout;
 	union {
 		u32	d32[2];
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c b/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
index 45500d786a9..fef3be71f2b 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
@@ -92,6 +92,7 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
 {
 	struct mlx5e_priv *priv = arg1;
 	uint64_t value;
+	int mode_modify;
 	int was_opened;
 	int error;
 
@@ -114,6 +115,7 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
 		goto done;
 	}
 	was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
+	mode_modify = MLX5_CAP_GEN(priv->mdev, cq_period_mode_modify);
 
 	switch (MLX5_PARAM_OFFSET(arg[arg2])) {
 	case MLX5_PARAM_OFFSET(rx_coalesce_usecs):
@@ -266,7 +268,7 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
 
 	case MLX5_PARAM_OFFSET(rx_coalesce_mode):
 		/* network interface must be down */
-		if (was_opened)
+		if (was_opened != 0 && mode_modify == 0)
 			mlx5e_close_locked(priv->ifp);
 
 		/* import RX coalesce mode */
@@ -276,13 +278,17 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
 		    priv->params_ethtool.rx_coalesce_mode;
 
 		/* restart network interface, if any */
-		if (was_opened)
-			mlx5e_open_locked(priv->ifp);
+		if (was_opened != 0) {
+			if (mode_modify == 0)
+				mlx5e_open_locked(priv->ifp);
+			else
+				error = mlx5e_refresh_channel_params(priv);
+		}
 		break;
 
 	case MLX5_PARAM_OFFSET(tx_coalesce_mode):
 		/* network interface must be down */
-		if (was_opened)
+		if (was_opened != 0 && mode_modify == 0)
 			mlx5e_close_locked(priv->ifp);
 
 		/* import TX coalesce mode */
@@ -292,8 +298,12 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
 		    priv->params_ethtool.tx_coalesce_mode;
 
 		/* restart network interface, if any */
-		if (was_opened)
-			mlx5e_open_locked(priv->ifp);
+		if (was_opened != 0) {
+			if (mode_modify == 0)
+				mlx5e_open_locked(priv->ifp);
+			else
+				error = mlx5e_refresh_channel_params(priv);
+		}
 		break;
 
 	case MLX5_PARAM_OFFSET(hw_lro):
@@ -342,6 +352,18 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
 			mlx5e_open_locked(priv->ifp);
 		break;
 
+	case MLX5_PARAM_OFFSET(tx_bufring_disable):
+		/* rangecheck input value */
+		priv->params_ethtool.tx_bufring_disable =
+		    priv->params_ethtool.tx_bufring_disable ? 1 : 0;
+
+		/* reconfigure the sendqueues, if any */
+		if (was_opened) {
+			mlx5e_close_locked(priv->ifp);
+			mlx5e_open_locked(priv->ifp);
+		}
+		break;
+
 	case MLX5_PARAM_OFFSET(tx_completion_fact):
 		/* network interface must be down */
 		if (was_opened)
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
index d61ada0bc23..fc73c8c3b4e 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
@@ -439,7 +439,8 @@ mlx5e_update_stats_work(struct work_struct *work)
 			tso_packets += sq_stats->tso_packets;
 			tso_bytes += sq_stats->tso_bytes;
 			tx_queue_dropped += sq_stats->dropped;
-			tx_queue_dropped += sq_br->br_drops;
+			if (sq_br != NULL)
+				tx_queue_dropped += sq_br->br_drops;
 			tx_defragged += sq_stats->defragged;
 			tx_offload_none += sq_stats->csum_offload_none;
 		}
@@ -987,34 +988,37 @@ mlx5e_create_sq(struct mlx5e_channel *c,
 	sq->priv = priv;
 	sq->tc = tc;
 
-	sq->br = buf_ring_alloc(MLX5E_SQ_TX_QUEUE_SIZE, M_MLX5EN,
-	    M_WAITOK, &sq->lock);
-	if (sq->br == NULL) {
-		if_printf(c->ifp, "%s: Failed allocating sq drbr buffer\n",
-		    __func__);
-		err = -ENOMEM;
-		goto err_free_sq_db;
-	}
+	/* check if we should allocate a second packet buffer */
+	if (priv->params_ethtool.tx_bufring_disable == 0) {
+		sq->br = buf_ring_alloc(MLX5E_SQ_TX_QUEUE_SIZE, M_MLX5EN,
+		    M_WAITOK, &sq->lock);
+		if (sq->br == NULL) {
+			if_printf(c->ifp, "%s: Failed allocating sq drbr buffer\n",
+			    __func__);
+			err = -ENOMEM;
+			goto err_free_sq_db;
+		}
 
-	sq->sq_tq = taskqueue_create_fast("mlx5e_que", M_WAITOK,
-	    taskqueue_thread_enqueue, &sq->sq_tq);
-	if (sq->sq_tq == NULL) {
-		if_printf(c->ifp, "%s: Failed allocating taskqueue\n",
-		    __func__);
-		err = -ENOMEM;
-		goto err_free_drbr;
-	}
+		sq->sq_tq = taskqueue_create_fast("mlx5e_que", M_WAITOK,
+		    taskqueue_thread_enqueue, &sq->sq_tq);
+		if (sq->sq_tq == NULL) {
+			if_printf(c->ifp, "%s: Failed allocating taskqueue\n",
+			    __func__);
+			err = -ENOMEM;
+			goto err_free_drbr;
+		}
 
-	TASK_INIT(&sq->sq_task, 0, mlx5e_tx_que, sq);
+		TASK_INIT(&sq->sq_task, 0, mlx5e_tx_que, sq);
 #ifdef RSS
-	cpu_id = rss_getcpu(c->ix % rss_getnumbuckets());
-	CPU_SETOF(cpu_id, &cpu_mask);
-	taskqueue_start_threads_cpuset(&sq->sq_tq, 1, PI_NET, &cpu_mask,
-	    "%s TX SQ%d.%d CPU%d", c->ifp->if_xname, c->ix, tc, cpu_id);
+		cpu_id = rss_getcpu(c->ix % rss_getnumbuckets());
+		CPU_SETOF(cpu_id, &cpu_mask);
+		taskqueue_start_threads_cpuset(&sq->sq_tq, 1, PI_NET, &cpu_mask,
+		    "%s TX SQ%d.%d CPU%d", c->ifp->if_xname, c->ix, tc, cpu_id);
 #else
-	taskqueue_start_threads(&sq->sq_tq, 1, PI_NET,
-	    "%s TX SQ%d.%d", c->ifp->if_xname, c->ix, tc);
+		taskqueue_start_threads(&sq->sq_tq, 1, PI_NET,
+		    "%s TX SQ%d.%d", c->ifp->if_xname, c->ix, tc);
 #endif
+	}
 	snprintf(buffer, sizeof(buffer), "txstat%dtc%d", c->ix, tc);
 	mlx5e_create_stats(&sq->stats.ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
 	    buffer, mlx5e_sq_stats_desc, MLX5E_SQ_STATS_NUM,
@@ -1047,9 +1051,12 @@ mlx5e_destroy_sq(struct mlx5e_sq *sq)
 	mlx5e_free_sq_db(sq);
 	mlx5_wq_destroy(&sq->wq_ctrl);
 	mlx5_unmap_free_uar(sq->priv->mdev, &sq->uar);
-	taskqueue_drain(sq->sq_tq, &sq->sq_task);
-	taskqueue_free(sq->sq_tq);
-	buf_ring_free(sq->br, M_MLX5EN);
+	if (sq->sq_tq != NULL) {
+		taskqueue_drain(sq->sq_tq, &sq->sq_task);
+		taskqueue_free(sq->sq_tq);
+	}
+	if (sq->br != NULL)
+		buf_ring_free(sq->br, M_MLX5EN);
 }
 
 int
@@ -1184,7 +1191,6 @@ done:
 		mlx5e_tx_notify_hw(sq, sq->doorbell.d32, 0);
 		sq->doorbell.d64 = 0;
 	}
-	return;
 }
 
 void
@@ -1219,8 +1225,25 @@ mlx5e_sq_cev_timeout(void *arg)
 void
 mlx5e_drain_sq(struct mlx5e_sq *sq)
 {
+	int error;
+
+	/*
+	 * Check if already stopped.
+	 *
+	 * NOTE: The "stopped" variable is only written when both the
+	 * priv's configuration lock and the SQ's lock is locked. It
+	 * can therefore safely be read when only one of the two locks
+	 * is locked. This function is always called when the priv's
+	 * configuration lock is locked.
+	 */
+	if (sq->stopped != 0)
+		return;
 
 	mtx_lock(&sq->lock);
+
+	/* don't put more packets into the SQ */
+	sq->stopped = 1;
+
 	/* teardown event factor timer, if any */
 	sq->cev_next_state = MLX5E_CEV_STATE_HOLD_NOPS;
 	callout_stop(&sq->cev_callout);
@@ -1232,14 +1255,29 @@ mlx5e_drain_sq(struct mlx5e_sq *sq)
 	/* make sure it is safe to free the callout */
 	callout_drain(&sq->cev_callout);
 
+	/* wait till SQ is empty or link is down */
+	mtx_lock(&sq->lock);
+	while (sq->cc != sq->pc &&
+	    (sq->priv->media_status_last & IFM_ACTIVE) != 0) {
+		mtx_unlock(&sq->lock);
+		msleep(1);
+		sq->cq.mcq.comp(&sq->cq.mcq);
+		mtx_lock(&sq->lock);
+	}
+	mtx_unlock(&sq->lock);
+
 	/* error out remaining requests */
-	mlx5e_modify_sq(sq, MLX5_SQC_STATE_RDY, MLX5_SQC_STATE_ERR);
+	error = mlx5e_modify_sq(sq, MLX5_SQC_STATE_RDY, MLX5_SQC_STATE_ERR);
+	if (error != 0) {
+		if_printf(sq->ifp,
+		    "mlx5e_modify_sq() from RDY to ERR failed: %d\n", error);
+	}
 
 	/* wait till SQ is empty */
 	mtx_lock(&sq->lock);
 	while (sq->cc != sq->pc) {
 		mtx_unlock(&sq->lock);
-		msleep(4);
+		msleep(1);
 		sq->cq.mcq.comp(&sq->cq.mcq);
 		mtx_lock(&sq->lock);
 	}
@@ -1465,9 +1503,10 @@ mlx5e_chan_mtx_init(struct mlx5e_channel *c)
 	for (tc = 0; tc < c->num_tc; tc++) {
 		struct mlx5e_sq *sq = c->sq + tc;
 
-		mtx_init(&sq->lock, "mlx5tx", MTX_NETWORK_LOCK, MTX_DEF);
-		mtx_init(&sq->comp_lock, "mlx5comp", MTX_NETWORK_LOCK,
-		    MTX_DEF);
+		mtx_init(&sq->lock, "mlx5tx",
+		    MTX_NETWORK_LOCK " TX", MTX_DEF);
+		mtx_init(&sq->comp_lock, "mlx5comp",
+		    MTX_NETWORK_LOCK " TX", MTX_DEF);
 
 		callout_init_mtx(&sq->cev_callout, &sq->lock, 0);
 
@@ -1766,6 +1805,25 @@ mlx5e_close_channels(struct mlx5e_priv *priv)
 static int
 mlx5e_refresh_sq_params(struct mlx5e_priv *priv, struct mlx5e_sq *sq)
 {
+
+	if (MLX5_CAP_GEN(priv->mdev, cq_period_mode_modify)) {
+		uint8_t cq_mode;
+
+		switch (priv->params.tx_cq_moderation_mode) {
+		case 0:
+			cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
+			break;
+		default:
+			cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_CQE;
+			break;
+		}
+
+		return (mlx5_core_modify_cq_moderation_mode(priv->mdev, &sq->cq.mcq,
+		    priv->params.tx_cq_moderation_usec,
+		    priv->params.tx_cq_moderation_pkts,
+		    cq_mode));
+	}
+
 	return (mlx5_core_modify_cq_moderation(priv->mdev, &sq->cq.mcq,
 	    priv->params.tx_cq_moderation_usec,
 	    priv->params.tx_cq_moderation_pkts));
@@ -1774,6 +1832,28 @@ mlx5e_refresh_sq_params(struct mlx5e_priv *priv, struct mlx5e_sq *sq)
 static int
 mlx5e_refresh_rq_params(struct mlx5e_priv *priv, struct mlx5e_rq *rq)
 {
+
+	if (MLX5_CAP_GEN(priv->mdev, cq_period_mode_modify)) {
+		uint8_t cq_mode;
+		int retval;
+
+		switch (priv->params.rx_cq_moderation_mode) {
+		case 0:
+			cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
+			break;
+		default:
+			cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_CQE;
+			break;
+		}
+
+		retval = mlx5_core_modify_cq_moderation_mode(priv->mdev, &rq->cq.mcq,
+		    priv->params.rx_cq_moderation_usec,
+		    priv->params.rx_cq_moderation_pkts,
+		    cq_mode);
+
+		return (retval);
+	}
+
 	return (mlx5_core_modify_cq_moderation(priv->mdev, &rq->cq.mcq,
 	    priv->params.rx_cq_moderation_usec,
 	    priv->params.rx_cq_moderation_pkts));
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c b/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c
index eae3d728dff..fe0eb20ab07 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c
@@ -81,11 +81,15 @@ static struct mlx5e_sq *
 mlx5e_select_queue(struct ifnet *ifp, struct mbuf *mb)
 {
 	struct mlx5e_priv *priv = ifp->if_softc;
+	struct mlx5e_channel * volatile *ppch;
+	struct mlx5e_channel *pch;
 	u32 ch;
 	u32 tc;
 
+	ppch = priv->channel;
+
 	/* check if channels are successfully opened */
-	if (unlikely(priv->channel == NULL))
+	if (unlikely(ppch == NULL))
 		return (NULL);
 
 	/* obtain VLAN information if present */
@@ -123,11 +127,11 @@ mlx5e_select_queue(struct ifnet *ifp, struct mbuf *mb)
 #endif
 	}
 
-	/* check if channel is allocated */
-	if (unlikely(priv->channel[ch] == NULL))
-		return (NULL);
-
-	return (&priv->channel[ch]->sq[tc]);
+	/* check if channel is allocated and not stopped */
+	pch = ppch[ch];
+	if (likely(pch != NULL && pch->sq[tc].stopped == 0))
+		return (&pch->sq[tc]);
+	return (NULL);
 }
 
 static inline u16
@@ -435,7 +439,8 @@ mlx5e_poll_tx_cq(struct mlx5e_sq *sq, int budget)
 
 	sq->cc = sqcc;
 
-	if (atomic_cmpset_int(&sq->queue_state, MLX5E_SQ_FULL, MLX5E_SQ_READY))
+	if (sq->sq_tq != NULL &&
+	    atomic_cmpset_int(&sq->queue_state, MLX5E_SQ_FULL, MLX5E_SQ_READY))
 		taskqueue_enqueue(sq->sq_tq, &sq->sq_task);
 }
 
@@ -445,18 +450,21 @@ mlx5e_xmit_locked(struct ifnet *ifp, struct mlx5e_sq *sq, struct mbuf *mb)
 	struct mbuf *next;
 	int err = 0;
 
-	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
-		if (mb)
-			err = drbr_enqueue(ifp, sq->br, mb);
-		return (err);
-	}
-
-	if (mb != NULL)
+	if (likely(mb != NULL)) {
 		/*
 		 * If we can't insert mbuf into drbr, try to xmit anyway.
 		 * We keep the error we got so we could return that after xmit.
 		 */
 		err = drbr_enqueue(ifp, sq->br, mb);
+	}
+
+	/*
+	 * Check if the network interface is closed or if the SQ is
+	 * being stopped:
+	 */
+	if (unlikely((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
+	    sq->stopped != 0))
+		return (err);
 
 	/* Process the queue */
 	while ((next = drbr_peek(ifp, sq->br)) != NULL) {
@@ -470,8 +478,6 @@ mlx5e_xmit_locked(struct ifnet *ifp, struct mlx5e_sq *sq, struct mbuf *mb)
 			break;
 		}
 		drbr_advance(ifp, sq->br);
-		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
-			break;
 	}
 	/* Check if we need to write the doorbell */
 	if (likely(sq->doorbell.d64 != 0)) {
@@ -493,6 +499,45 @@ mlx5e_xmit_locked(struct ifnet *ifp, struct mlx5e_sq *sq, struct mbuf *mb)
 	return (err);
 }
 
+static int
+mlx5e_xmit_locked_no_br(struct ifnet *ifp, struct mlx5e_sq *sq, struct mbuf *mb)
+{
+	int err = 0;
+
+	if (unlikely((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
+	    sq->stopped != 0)) {
+		m_freem(mb);
+		return (ENETDOWN);
+	}
+
+	/* Do transmit */
+	if (mlx5e_sq_xmit(sq, &mb) != 0) {
+		/* NOTE: m_freem() is NULL safe */
+		m_freem(mb);
+		err = ENOBUFS;
+	}
+
+	/* Check if we need to write the doorbell */
+	if (likely(sq->doorbell.d64 != 0)) {
+		mlx5e_tx_notify_hw(sq, sq->doorbell.d32, 0);
+		sq->doorbell.d64 = 0;
+	}
+
+	/*
+	 * Check if we need to start the event timer which flushes the
+	 * transmit ring on timeout:
+	 */
+	if (unlikely(sq->cev_next_state == MLX5E_CEV_STATE_INITIAL &&
+	    sq->cev_factor != 1)) {
+		/* start the timer */
+		mlx5e_sq_cev_timeout(sq);
+	} else {
+		/* don't send NOPs yet */
+		sq->cev_next_state = MLX5E_CEV_STATE_HOLD_NOPS;
+	}
+	return (err);
+}
+
 int
 mlx5e_xmit(struct ifnet *ifp, struct mbuf *mb)
 {
@@ -505,7 +550,13 @@ mlx5e_xmit(struct ifnet *ifp, struct mbuf *mb)
 		m_freem(mb);
 		return (ENXIO);
 	}
-	if (mtx_trylock(&sq->lock)) {
+
+	if (unlikely(sq->br == NULL)) {
+		/* rate limited traffic */
+		mtx_lock(&sq->lock);
+		ret = mlx5e_xmit_locked_no_br(ifp, sq, mb);
+		mtx_unlock(&sq->lock);
+	} else if (mtx_trylock(&sq->lock)) {
 		ret = mlx5e_xmit_locked(ifp, sq, mb);
 		mtx_unlock(&sq->lock);
 	} else {
diff --git a/sys/dev/mlx5/mlx5_ifc.h b/sys/dev/mlx5/mlx5_ifc.h
index cde74d8e0a9..425c86ccafe 100644
--- a/sys/dev/mlx5/mlx5_ifc.h
+++ b/sys/dev/mlx5/mlx5_ifc.h
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2013-2015, Mellanox Technologies, Ltd.  All rights reserved.
+ * Copyright (c) 2013-2017, Mellanox Technologies, Ltd.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,13 +23,8 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD$
+ */
 
-   Autogenerated file.
-   Date: 2015-04-13 14:59
-   Source Document Name: Mellanox 
-   Source Document Version: 0.28
-   Generated by adb_to_c.py (EAT.ME Version: 1.0.70)
-*/
 #ifndef MLX5_IFC_H
 #define MLX5_IFC_H
 
@@ -56,6 +51,8 @@ enum {
 	MLX5_EVENT_TYPE_CODING_TEMP_WARNING_EVENT                  = 0x17,
 	MLX5_EVENT_TYPE_REMOTE_CONFIG                              = 0x19,
 	MLX5_EVENT_TYPE_CODING_DCBX_CHANGE_EVENT                   = 0x1e,
+	MLX5_EVENT_TYPE_CODING_PPS_EVENT                           = 0x25,
+	MLX5_EVENT_TYPE_CODING_GENERAL_NOTIFICATION_EVENT          = 0x22,
 	MLX5_EVENT_TYPE_DB_BF_CONGESTION                           = 0x1a,
 	MLX5_EVENT_TYPE_STALL_EVENT                                = 0x1b,
 	MLX5_EVENT_TYPE_DROPPED_PACKET_LOGGED_EVENT                = 0x1f,
@@ -89,6 +86,8 @@ enum {
 	MLX5_CMD_OP_QUERY_ISSI                    = 0x10a,
 	MLX5_CMD_OP_SET_ISSI                      = 0x10b,
 	MLX5_CMD_OP_SET_DRIVER_VERSION            = 0x10d,
+	MLX5_CMD_OP_QUERY_OTHER_HCA_CAP           = 0x10e,
+	MLX5_CMD_OP_MODIFY_OTHER_HCA_CAP          = 0x10f,
 	MLX5_CMD_OP_CREATE_MKEY                   = 0x200,
 	MLX5_CMD_OP_QUERY_MKEY                    = 0x201,
 	MLX5_CMD_OP_DESTROY_MKEY                  = 0x202,
@@ -190,6 +189,12 @@ enum {
 	MLX5_CMD_OP_DELETE_L2_TABLE_ENTRY         = 0x82b,
 	MLX5_CMD_OP_SET_WOL_ROL                   = 0x830,
 	MLX5_CMD_OP_QUERY_WOL_ROL                 = 0x831,
+	MLX5_CMD_OP_CREATE_LAG                    = 0x840,
+	MLX5_CMD_OP_MODIFY_LAG                    = 0x841,
+	MLX5_CMD_OP_QUERY_LAG                     = 0x842,
+	MLX5_CMD_OP_DESTROY_LAG                   = 0x843,
+	MLX5_CMD_OP_CREATE_VPORT_LAG              = 0x844,
+	MLX5_CMD_OP_DESTROY_VPORT_LAG             = 0x845,
 	MLX5_CMD_OP_CREATE_TIR                    = 0x900,
 	MLX5_CMD_OP_MODIFY_TIR                    = 0x901,
 	MLX5_CMD_OP_DESTROY_TIR                   = 0x902,
@@ -206,6 +211,8 @@ enum {
 	MLX5_CMD_OP_MODIFY_RMP                    = 0x90d,
 	MLX5_CMD_OP_DESTROY_RMP                   = 0x90e,
 	MLX5_CMD_OP_QUERY_RMP                     = 0x90f,
+	MLX5_CMD_OP_SET_DELAY_DROP_PARAMS         = 0x910,
+	MLX5_CMD_OP_QUERY_DELAY_DROP_PARAMS       = 0x911,
 	MLX5_CMD_OP_CREATE_TIS                    = 0x912,
 	MLX5_CMD_OP_MODIFY_TIS                    = 0x913,
 	MLX5_CMD_OP_DESTROY_TIS                   = 0x914,
@@ -226,7 +233,10 @@ enum {
 	MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY       = 0x938,
 	MLX5_CMD_OP_ALLOC_FLOW_COUNTER            = 0x939,
 	MLX5_CMD_OP_DEALLOC_FLOW_COUNTER          = 0x93a,
-	MLX5_CMD_OP_QUERY_FLOW_COUNTER            = 0x93b
+	MLX5_CMD_OP_QUERY_FLOW_COUNTER            = 0x93b,
+	MLX5_CMD_OP_MODIFY_FLOW_TABLE             = 0x93c,
+	MLX5_CMD_OP_ALLOC_ENCAP_HEADER            = 0x93d,
+	MLX5_CMD_OP_DEALLOC_ENCAP_HEADER          = 0x93e,
 };
 
 enum {
@@ -271,7 +281,11 @@ struct mlx5_ifc_flow_table_fields_supported_bits {
 	u8         outer_gre_protocol[0x1];
 	u8         outer_gre_key[0x1];
 	u8         outer_vxlan_vni[0x1];
-	u8         reserved_2[0x5];
+	u8         outer_geneve_vni[0x1];
+	u8         outer_geneve_oam[0x1];
+	u8         outer_geneve_protocol_type[0x1];
+	u8         outer_geneve_opt_len[0x1];
+	u8         reserved_2[0x1];
 	u8         source_eswitch_port[0x1];
 
 	u8         inner_dmac[0x1];
@@ -299,10 +313,12 @@ struct mlx5_ifc_flow_table_fields_supported_bits {
 	u8         inner_tcp_flags[0x1];
 	u8         reserved_5[0x9];
 
-	u8         reserved_6[0x1f];
+	u8         reserved_6[0x1a];
+	u8         bth_dst_qp[0x1];
+	u8         reserved_7[0x4];
 	u8         source_sqn[0x1];
 
-	u8         reserved_7[0x20];
+	u8         reserved_8[0x20];
 };
 
 struct mlx5_ifc_eth_discard_cntrs_grp_bits {
@@ -356,7 +372,11 @@ struct mlx5_ifc_eth_discard_cntrs_grp_bits {
 
 	u8         egress_stp_filter_low[0x20];
 
-	u8         reserved_at_340[0x480];
+	u8         egress_hoq_stall_high[0x20];
+
+	u8         egress_hoq_stall_low[0x20];
+
+	u8         reserved_at_340[0x440];
 };
 struct mlx5_ifc_flow_table_prop_layout_bits {
 	u8         ft_support[0x1];
@@ -411,6 +431,7 @@ enum {
 	MLX5_FLOW_CONTEXT_DEST_TYPE_VPORT                    = 0x0,
 	MLX5_FLOW_CONTEXT_DEST_TYPE_FLOW_TABLE               = 0x1,
 	MLX5_FLOW_CONTEXT_DEST_TYPE_TIR                      = 0x2,
+	MLX5_FLOW_CONTEXT_DEST_TYPE_QP                       = 0x3,
 };
 
 struct mlx5_ifc_dest_format_struct_bits {
@@ -490,9 +511,14 @@ struct mlx5_ifc_fte_match_set_misc_bits {
 	u8         reserved_6[0xc];
 	u8         inner_ipv6_flow_label[0x14];
 
-	u8         reserved7[0x10];
+	u8         reserved_7[0xa];
+	u8         geneve_opt_len[0x6];
 	u8         geneve_protocol_type[0x10];
-	u8         reserved8[0xc0];
+
+	u8         reserved_8[0x8];
+	u8         bth_dst_qp[0x18];
+
+	u8         reserved_9[0xa0];
 };
 
 struct mlx5_ifc_cmd_pas_bits {
@@ -698,7 +724,8 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
 	u8         lro_psh_flag[0x1];
 	u8         lro_time_stamp[0x1];
 	u8         lro_max_msg_sz_mode[0x2];
-	u8         reserved_0[0x2];
+	u8         wqe_vlan_insert[0x1];
+	u8         self_lb_en_modifiable[0x1];
 	u8         self_lb_mc[0x1];
 	u8         self_lb_uc[0x1];
 	u8         max_lso_cap[0x5];
@@ -715,7 +742,8 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
 	u8         swp[0x1];
 	u8         swp_csum[0x1];
 	u8         swp_lso[0x1];
-	u8         reserved_2[0x1c];
+	u8         reserved_2[0x1b];
+	u8         max_geneve_opt_len[0x1];
 	u8         tunnel_stateless_geneve_rx[0x1];
 
 	u8         reserved_3[0x10];
@@ -910,7 +938,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {
 	u8         vport_counters[0x1];
 	u8         retransmission_q_counters[0x1];
 	u8         debug[0x1];
-	u8         reserved_16[0x2];
+	u8         modify_rq_counters_set_id[0x1];
+	u8         rq_delay_drop[0x1];
 	u8         max_qp_cnt[0xa];
 	u8         pkey_table_size[0x10];
 
@@ -980,7 +1009,9 @@ struct mlx5_ifc_cmd_hca_cap_bits {
 	u8         cq_oi[0x1];
 	u8         cq_resize[0x1];
 	u8         cq_moderation[0x1];
-	u8         reserved_31[0x3];
+	u8         cq_period_mode_modify[0x1];
+	u8         cq_invalidate[0x1];
+	u8         reserved_at_225[0x1];
 	u8         cq_eq_remap[0x1];
 	u8         pg[0x1];
 	u8         block_lb_mc[0x1];
@@ -1068,7 +1099,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {
 	u8         log_max_wq_sz[0x5];
 
 	u8         nic_vport_change_event[0x1];
-	u8         reserved_59[0xa];
+	u8         disable_local_lb[0x1];
+	u8         reserved_59[0x9];
 	u8         log_max_vlan_list[0x5];
 	u8         reserved_60[0x3];
 	u8         log_max_current_mc_list[0x5];
@@ -1312,6 +1344,8 @@ enum {
 	MLX5_MODIFY_FIELD_SELECT_MODIFY_FIELD_SELECT_CQ_MAX_COUNT  = 0x2,
 	MLX5_MODIFY_FIELD_SELECT_MODIFY_FIELD_SELECT_OI            = 0x4,
 	MLX5_MODIFY_FIELD_SELECT_MODIFY_FIELD_SELECT_C_EQN         = 0x8,
+	MLX5_MODIFY_FIELD_SELECT_MODIFY_FIELD_SELECT_CQ_PERIOD_MODE  = 0x10,
+	MLX5_MODIFY_FIELD_SELECT_MODIFY_FIELD_SELECT_STATUS          = 0x20,
 };
 
 struct mlx5_ifc_modify_field_select_bits {
@@ -2239,9 +2273,15 @@ enum {
 	MLX5_RQC_STATE_ERR  = 0x3,
 };
 
+enum {
+	MLX5_RQC_DROPLESS_MODE_DISABLE        = 0x0,
+	MLX5_RQC_DROPLESS_MODE_ENABLE         = 0x1,
+};
+
 struct mlx5_ifc_rqc_bits {
-	u8         rlky[0x1];
-	u8         reserved_0[0x2];
+	u8         rlkey[0x1];
+	u8         delay_drop_en[0x1];
+	u8         scatter_fcs[0x1];
 	u8         vlan_strip_disable[0x1];
 	u8         mem_rq_type[0x4];
 	u8         state[0x4];
@@ -2293,7 +2333,9 @@ enum {
 struct mlx5_ifc_nic_vport_context_bits {
 	u8         reserved_0[0x5];
 	u8         min_wqe_inline_mode[0x3];
-	u8         reserved_1[0x17];
+	u8         reserved_1[0x15];
+	u8         disable_mc_local_lb[0x1];
+	u8         disable_uc_local_lb[0x1];
 	u8         roce_en[0x1];
 
 	u8         arm_change_event[0x1];
@@ -3075,6 +3117,50 @@ struct mlx5_ifc_teardown_hca_in_bits {
 	u8         reserved_3[0x20];
 };
 
+struct mlx5_ifc_set_delay_drop_params_out_bits {
+	u8         status[0x8];
+	u8         reserved_at_8[0x18];
+
+	u8         syndrome[0x20];
+
+	u8         reserved_at_40[0x40];
+};
+
+struct mlx5_ifc_set_delay_drop_params_in_bits {
+	u8         opcode[0x10];
+	u8         reserved_at_10[0x10];
+
+	u8         reserved_at_20[0x10];
+	u8         op_mod[0x10];
+
+	u8         reserved_at_40[0x20];
+
+	u8         reserved_at_60[0x10];
+	u8         delay_drop_timeout[0x10];
+};
+
+struct mlx5_ifc_query_delay_drop_params_out_bits {
+	u8         status[0x8];
+	u8         reserved_at_8[0x18];
+
+	u8         syndrome[0x20];
+
+	u8         reserved_at_40[0x20];
+
+	u8         reserved_at_60[0x10];
+	u8         delay_drop_timeout[0x10];
+};
+
+struct mlx5_ifc_query_delay_drop_params_in_bits {
+	u8         opcode[0x10];
+	u8         reserved_at_10[0x10];
+
+	u8         reserved_at_20[0x10];
+	u8         op_mod[0x10];
+
+	u8         reserved_at_40[0x40];
+};
+
 struct mlx5_ifc_suspend_qp_out_bits {
 	u8         status[0x8];
 	u8         reserved_0[0x18];
@@ -4076,31 +4162,39 @@ struct mlx5_ifc_query_q_counter_out_bits {
 
 	u8         out_of_buffer[0x20];
 
-	u8	   reserved_7[0x20];
+	u8         reserved_7[0x20];
 
 	u8         out_of_sequence[0x20];
 
-	u8	   reserved_8[0x20];
+	u8         reserved_8[0x20];
 
-	u8	   duplicate_request[0x20];
+	u8         duplicate_request[0x20];
 
-	u8	   reserved_9[0x20];
+	u8         reserved_9[0x20];
 
-	u8	   rnr_nak_retry_err[0x20];
+	u8         rnr_nak_retry_err[0x20];
 
-	u8	   reserved_10[0x20];
+	u8         reserved_10[0x20];
 
-	u8	   packet_seq_err[0x20];
+	u8         packet_seq_err[0x20];
 
-	u8	   reserved_11[0x20];
+	u8         reserved_11[0x20];
 
-	u8	   implied_nak_seq_err[0x20];
+	u8         implied_nak_seq_err[0x20];
 
-	u8	   reserved_12[0x20];
+	u8         reserved_12[0x20];
 
-	u8	   local_ack_timeout_err[0x20];
+	u8         local_ack_timeout_err[0x20];
 
-	u8         reserved_13[0x4e0];
+	u8         reserved_13[0x20];
+
+	u8         resp_rnr_nak[0x20];
+
+	u8         reserved_14[0x20];
+
+	u8         req_rnr_retries_exceeded[0x20];
+
+	u8         reserved_15[0x460];
 };
 
 struct mlx5_ifc_query_q_counter_in_bits {
@@ -5204,7 +5298,9 @@ struct mlx5_ifc_modify_nic_vport_context_out_bits {
 };
 
 struct mlx5_ifc_modify_nic_vport_field_select_bits {
-	u8         reserved_0[0x16];
+	u8         reserved_0[0x14];
+	u8         disable_uc_local_lb[0x1];
+	u8         disable_mc_local_lb[0x1];
 	u8         node_guid[0x1];
 	u8         port_guid[0x1];
 	u8         min_wqe_inline_mode[0x1];
@@ -7958,6 +8054,42 @@ struct mlx5_ifc_phys_layer_cntrs_bits {
 	u8         reserved_0[0x180];
 };
 
+struct mlx5_ifc_phys_layer_statistical_cntrs_bits {
+	u8         time_since_last_clear_high[0x20];
+
+	u8         time_since_last_clear_low[0x20];
+
+	u8         phy_received_bits_high[0x20];
+
+	u8         phy_received_bits_low[0x20];
+
+	u8         phy_symbol_errors_high[0x20];
+
+	u8         phy_symbol_errors_low[0x20];
+
+	u8         phy_corrected_bits_high[0x20];
+
+	u8         phy_corrected_bits_low[0x20];
+
+	u8         phy_corrected_bits_lane0_high[0x20];
+
+	u8         phy_corrected_bits_lane0_low[0x20];
+
+	u8         phy_corrected_bits_lane1_high[0x20];
+
+	u8         phy_corrected_bits_lane1_low[0x20];
+
+	u8         phy_corrected_bits_lane2_high[0x20];
+
+	u8         phy_corrected_bits_lane2_low[0x20];
+
+	u8         phy_corrected_bits_lane3_high[0x20];
+
+	u8         phy_corrected_bits_lane3_low[0x20];
+
+	u8         reserved_at_200[0x5c0];
+};
+
 struct mlx5_ifc_infiniband_port_cntrs_bits {
 	u8         symbol_error_counter[0x10];
 	u8         link_error_recovery_counter[0x8];
@@ -9187,6 +9319,7 @@ union mlx5_ifc_eth_cntrs_grp_data_layout_auto_bits {
 	struct mlx5_ifc_eth_discard_cntrs_grp_bits eth_discard_cntrs_grp;
 	struct mlx5_ifc_eth_per_prio_grp_data_layout_bits eth_per_prio_grp_data_layout;
 	struct mlx5_ifc_phys_layer_cntrs_bits phys_layer_cntrs;
+	struct mlx5_ifc_phys_layer_statistical_cntrs_bits phys_layer_statistical_cntrs;
 	struct mlx5_ifc_infiniband_port_cntrs_bits infiniband_port_cntrs;
 	u8         reserved_0[0x7c0];
 };
diff --git a/sys/dev/mpr/mpr_sas.c b/sys/dev/mpr/mpr_sas.c
index 72219ee1b8a..09971faa6b0 100644
--- a/sys/dev/mpr/mpr_sas.c
+++ b/sys/dev/mpr/mpr_sas.c
@@ -349,7 +349,7 @@ mprsas_log_command(struct mpr_command *cm, u_int level, const char *fmt, ...)
 	sbuf_printf(&sb, "SMID %u ", cm->cm_desc.Default.SMID);
 	sbuf_vprintf(&sb, fmt, ap);
 	sbuf_finish(&sb);
-	mpr_dprint_field(cm->cm_sc, level, "%s", sbuf_data(&sb));
+	mpr_print_field(cm->cm_sc, "%s", sbuf_data(&sb));
 
 	va_end(ap);
 }
diff --git a/sys/dev/mpr/mpr_table.c b/sys/dev/mpr/mpr_table.c
index de715259de7..d7920034ac6 100644
--- a/sys/dev/mpr/mpr_table.c
+++ b/sys/dev/mpr/mpr_table.c
@@ -197,27 +197,26 @@ mpr_describe_devinfo(uint32_t devinfo, char *string, int len)
 }
 
 void
-mpr_print_iocfacts(struct mpr_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
+_mpr_print_iocfacts(struct mpr_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
 {
-
 	MPR_PRINTFIELD_START(sc, "IOCFacts");
 	MPR_PRINTFIELD(sc, facts, MsgVersion, 0x%x);
 	MPR_PRINTFIELD(sc, facts, HeaderVersion, 0x%x);
 	MPR_PRINTFIELD(sc, facts, IOCNumber, %d);
 	MPR_PRINTFIELD(sc, facts, IOCExceptions, 0x%x);
 	MPR_PRINTFIELD(sc, facts, MaxChainDepth, %d);
-	mpr_dprint_field(sc, MPR_XINFO, "WhoInit: %s\n",
+	mpr_print_field(sc, "WhoInit: %s\n",
 	    mpr_describe_table(mpr_whoinit_names, facts->WhoInit));
 	MPR_PRINTFIELD(sc, facts, NumberOfPorts, %d);
 	MPR_PRINTFIELD(sc, facts, MaxMSIxVectors, %d);
 	MPR_PRINTFIELD(sc, facts, RequestCredit, %d);
 	MPR_PRINTFIELD(sc, facts, ProductID, 0x%x);
-	mpr_dprint_field(sc, MPR_XINFO, "IOCCapabilities: %b\n",
+	mpr_print_field(sc, "IOCCapabilities: %b\n",
 	    facts->IOCCapabilities, "\20" "\3ScsiTaskFull" "\4DiagTrace"
 	    "\5SnapBuf" "\6ExtBuf" "\7EEDP" "\10BiDirTarg" "\11Multicast"
 	    "\14TransRetry" "\15IR" "\16EventReplay" "\17RaidAccel"
 	    "\20MSIXIndex" "\21HostDisc");
-	mpr_dprint_field(sc, MPR_XINFO, "FWVersion= %d-%d-%d-%d\n",
+	mpr_print_field(sc, "FWVersion= %d-%d-%d-%d\n",
 	    facts->FWVersion.Struct.Major,
 	    facts->FWVersion.Struct.Minor,
 	    facts->FWVersion.Struct.Unit,
@@ -227,7 +226,7 @@ mpr_print_iocfacts(struct mpr_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
 	MPR_PRINTFIELD(sc, facts, MaxTargets, %d);
 	MPR_PRINTFIELD(sc, facts, MaxSasExpanders, %d);
 	MPR_PRINTFIELD(sc, facts, MaxEnclosures, %d);
-	mpr_dprint_field(sc, MPR_XINFO, "ProtocolFlags: %b\n",
+	mpr_print_field(sc, "ProtocolFlags: %b\n",
 	    facts->ProtocolFlags, "\20" "\1ScsiTarg" "\2ScsiInit");
 	MPR_PRINTFIELD(sc, facts, HighPriorityCredit, %d);
 	MPR_PRINTFIELD(sc, facts, MaxReplyDescriptorPostQueueDepth, %d);
@@ -238,7 +237,7 @@ mpr_print_iocfacts(struct mpr_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
 }
 
 void
-mpr_print_portfacts(struct mpr_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
+_mpr_print_portfacts(struct mpr_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
 {
 
 	MPR_PRINTFIELD_START(sc, "PortFacts");
@@ -248,24 +247,24 @@ mpr_print_portfacts(struct mpr_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
 }
 
 void
-mpr_print_event(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
+_mpr_print_event(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 {
 
-	MPR_EVENTFIELD_START(sc, "EventReply");
-	MPR_EVENTFIELD(sc, event, EventDataLength, %d);
-	MPR_EVENTFIELD(sc, event, AckRequired, %d);
-	mpr_dprint_field(sc, MPR_EVENT, "Event: %s (0x%x)\n",
+	MPR_PRINTFIELD_START(sc, "EventReply");
+	MPR_PRINTFIELD(sc, event, EventDataLength, %d);
+	MPR_PRINTFIELD(sc, event, AckRequired, %d);
+	mpr_print_field(sc, "Event: %s (0x%x)\n",
 	    mpr_describe_table(mpr_event_names, event->Event), event->Event);
-	MPR_EVENTFIELD(sc, event, EventContext, 0x%x);
+	MPR_PRINTFIELD(sc, event, EventContext, 0x%x);
 }
 
 void
-mpr_print_sasdev0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
+_mpr_print_sasdev0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
 {
 	MPR_PRINTFIELD_START(sc, "SAS Device Page 0");
 	MPR_PRINTFIELD(sc, buf, Slot, %d);
 	MPR_PRINTFIELD(sc, buf, EnclosureHandle, 0x%x);
-	mpr_dprint_field(sc, MPR_XINFO, "SASAddress: 0x%jx\n",
+	mpr_print_field(sc, "SASAddress: 0x%jx\n",
 	    mpr_to_u64(&buf->SASAddress));
 	MPR_PRINTFIELD(sc, buf, ParentDevHandle, 0x%x);
 	MPR_PRINTFIELD(sc, buf, PhyNum, %d);
@@ -273,7 +272,7 @@ mpr_print_sasdev0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
 	MPR_PRINTFIELD(sc, buf, DevHandle, 0x%x);
 	MPR_PRINTFIELD(sc, buf, AttachedPhyIdentifier, 0x%x);
 	MPR_PRINTFIELD(sc, buf, ZoneGroup, %d);
-	mpr_dprint_field(sc, MPR_XINFO, "DeviceInfo: %b,%s\n", buf->DeviceInfo,
+	mpr_print_field(sc, "DeviceInfo: %b,%s\n", buf->DeviceInfo,
 	    "\20" "\4SataHost" "\5SmpInit" "\6StpInit" "\7SspInit"
 	    "\10SataDev" "\11SmpTarg" "\12StpTarg" "\13SspTarg" "\14Direct"
 	    "\15LsiDev" "\16AtapiDev" "\17SepDev",
@@ -281,7 +280,7 @@ mpr_print_sasdev0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
 	MPR_PRINTFIELD(sc, buf, Flags, 0x%x);
 	MPR_PRINTFIELD(sc, buf, PhysicalPort, %d);
 	MPR_PRINTFIELD(sc, buf, MaxPortConnections, %d);
-	mpr_dprint_field(sc, MPR_XINFO, "DeviceName: 0x%jx\n",
+	mpr_print_field(sc, "DeviceName: 0x%jx\n",
 	    mpr_to_u64(&buf->DeviceName));
 	MPR_PRINTFIELD(sc, buf, PortGroups, %d);
 	MPR_PRINTFIELD(sc, buf, DmaGroup, %d);
@@ -289,10 +288,10 @@ mpr_print_sasdev0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
 }
 
 void
-mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
+_mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 {
 
-	mpr_print_event(sc, event);
+	_mpr_print_event(sc, event);
 
 	switch(event->Event) {
 	case MPI2_EVENT_SAS_DISCOVERY:
@@ -300,12 +299,12 @@ mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 		MPI2_EVENT_DATA_SAS_DISCOVERY *data;
 
 		data = (MPI2_EVENT_DATA_SAS_DISCOVERY *)&event->EventData;
-		mpr_dprint_field(sc, MPR_EVENT, "Flags: %b\n", data->Flags,
+		mpr_print_field(sc, "Flags: %b\n", data->Flags,
 		    "\20" "\1InProgress" "\2DeviceChange");
-		mpr_dprint_field(sc, MPR_EVENT, "ReasonCode: %s\n",
+		mpr_print_field(sc, "ReasonCode: %s\n",
 		    mpr_describe_table(mpr_sasdisc_reason, data->ReasonCode));
-		MPR_EVENTFIELD(sc, data, PhysicalPort, %d);
-		mpr_dprint_field(sc, MPR_EVENT, "DiscoveryStatus: %b\n",
+		MPR_PRINTFIELD(sc, data, PhysicalPort, %d);
+		mpr_print_field(sc, "DiscoveryStatus: %b\n",
 		    data->DiscoveryStatus,  "\20"
 		    "\1Loop" "\2UnaddressableDev" "\3DupSasAddr" "\5SmpTimeout"
 		    "\6ExpRouteFull" "\7RouteIndexError" "\10SmpFailed"
@@ -324,26 +323,26 @@ mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 
 		data = (MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *)
 		    &event->EventData;
-		MPR_EVENTFIELD(sc, data, EnclosureHandle, 0x%x);
-		MPR_EVENTFIELD(sc, data, ExpanderDevHandle, 0x%x);
-		MPR_EVENTFIELD(sc, data, NumPhys, %d);
-		MPR_EVENTFIELD(sc, data, NumEntries, %d);
-		MPR_EVENTFIELD(sc, data, StartPhyNum, %d);
-		mpr_dprint_field(sc, MPR_EVENT, "ExpStatus: %s (0x%x)\n",
+		MPR_PRINTFIELD(sc, data, EnclosureHandle, 0x%x);
+		MPR_PRINTFIELD(sc, data, ExpanderDevHandle, 0x%x);
+		MPR_PRINTFIELD(sc, data, NumPhys, %d);
+		MPR_PRINTFIELD(sc, data, NumEntries, %d);
+		MPR_PRINTFIELD(sc, data, StartPhyNum, %d);
+		mpr_print_field(sc, "ExpStatus: %s (0x%x)\n",
 		    mpr_describe_table(mpr_sastopo_exp, data->ExpStatus),
 		    data->ExpStatus);
-		MPR_EVENTFIELD(sc, data, PhysicalPort, %d);
+		MPR_PRINTFIELD(sc, data, PhysicalPort, %d);
 		for (i = 0; i < data->NumEntries; i++) {
 			phy = &data->PHY[i];
 			phynum = data->StartPhyNum + i;
-			mpr_dprint_field(sc, MPR_EVENT,
+			mpr_print_field(sc,
 			    "PHY[%d].AttachedDevHandle: 0x%04x\n", phynum,
 			    phy->AttachedDevHandle);
-			mpr_dprint_field(sc, MPR_EVENT,
+			mpr_print_field(sc,
 			    "PHY[%d].LinkRate: %s (0x%x)\n", phynum,
 			    mpr_describe_table(mpr_linkrate_names,
 			    (phy->LinkRate >> 4) & 0xf), phy->LinkRate);
-			mpr_dprint_field(sc,MPR_EVENT,"PHY[%d].PhyStatus: %s\n",
+			mpr_print_field(sc, "PHY[%d].PhyStatus: %s\n",
 			    phynum, mpr_describe_table(mpr_phystatus_names,
 			    phy->PhyStatus));
 		}
@@ -355,13 +354,13 @@ mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 
 		data = (MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE *)
 		    &event->EventData;
-		MPR_EVENTFIELD(sc, data, EnclosureHandle, 0x%x);
-		mpr_dprint_field(sc, MPR_EVENT, "ReasonCode: %s\n",
+		MPR_PRINTFIELD(sc, data, EnclosureHandle, 0x%x);
+		mpr_print_field(sc, "ReasonCode: %s\n",
 		    mpr_describe_table(mpr_sastopo_exp, data->ReasonCode));
-		MPR_EVENTFIELD(sc, data, PhysicalPort, %d);
-		MPR_EVENTFIELD(sc, data, NumSlots, %d);
-		MPR_EVENTFIELD(sc, data, StartSlot, %d);
-		MPR_EVENTFIELD(sc, data, PhyBits, 0x%x);
+		MPR_PRINTFIELD(sc, data, PhysicalPort, %d);
+		MPR_PRINTFIELD(sc, data, NumSlots, %d);
+		MPR_PRINTFIELD(sc, data, StartSlot, %d);
+		MPR_PRINTFIELD(sc, data, PhyBits, 0x%x);
 		break;
 	}
 	case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
@@ -370,13 +369,13 @@ mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 
 		data = (MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
 		    &event->EventData;
-		MPR_EVENTFIELD(sc, data, TaskTag, 0x%x);
-		mpr_dprint_field(sc, MPR_EVENT, "ReasonCode: %s\n",
+		MPR_PRINTFIELD(sc, data, TaskTag, 0x%x);
+		mpr_print_field(sc, "ReasonCode: %s\n",
 		    mpr_describe_table(mpr_sasdev_reason, data->ReasonCode));
-		MPR_EVENTFIELD(sc, data, ASC, 0x%x);
-		MPR_EVENTFIELD(sc, data, ASCQ, 0x%x);
-		MPR_EVENTFIELD(sc, data, DevHandle, 0x%x);
-		mpr_dprint_field(sc, MPR_EVENT, "SASAddress: 0x%jx\n",
+		MPR_PRINTFIELD(sc, data, ASC, 0x%x);
+		MPR_PRINTFIELD(sc, data, ASCQ, 0x%x);
+		MPR_PRINTFIELD(sc, data, DevHandle, 0x%x);
+		mpr_print_field(sc, "SASAddress: 0x%jx\n",
 		    mpr_to_u64(&data->SASAddress));
 	}
 	default:
@@ -385,24 +384,24 @@ mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 }
 
 void
-mpr_print_expander1(struct mpr_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
+_mpr_print_expander1(struct mpr_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
 {
 	MPR_PRINTFIELD_START(sc, "SAS Expander Page 1 #%d", buf->Phy);
 	MPR_PRINTFIELD(sc, buf, PhysicalPort, %d);
 	MPR_PRINTFIELD(sc, buf, NumPhys, %d);
 	MPR_PRINTFIELD(sc, buf, Phy, %d);
 	MPR_PRINTFIELD(sc, buf, NumTableEntriesProgrammed, %d);
-	mpr_dprint_field(sc, MPR_XINFO, "ProgrammedLinkRate: %s (0x%x)\n",
+	mpr_print_field(sc, "ProgrammedLinkRate: %s (0x%x)\n",
 	    mpr_describe_table(mpr_linkrate_names,
 	    (buf->ProgrammedLinkRate >> 4) & 0xf), buf->ProgrammedLinkRate);
-	mpr_dprint_field(sc, MPR_XINFO, "HwLinkRate: %s (0x%x)\n",
+	mpr_print_field(sc, "HwLinkRate: %s (0x%x)\n",
 	    mpr_describe_table(mpr_linkrate_names,
 	    (buf->HwLinkRate >> 4) & 0xf), buf->HwLinkRate);
 	MPR_PRINTFIELD(sc, buf, AttachedDevHandle, 0x%04x);
-	mpr_dprint_field(sc, MPR_XINFO, "PhyInfo Reason: %s (0x%x)\n",
+	mpr_print_field(sc, "PhyInfo Reason: %s (0x%x)\n",
 	    mpr_describe_table(mpr_phyinfo_reason_names,
 	    (buf->PhyInfo >> 16) & 0xf), buf->PhyInfo);
-	mpr_dprint_field(sc, MPR_XINFO, "AttachedDeviceInfo: %b,%s\n",
+	mpr_print_field(sc, "AttachedDeviceInfo: %b,%s\n",
 	    buf->AttachedDeviceInfo, "\20" "\4SATAhost" "\5SMPinit" "\6STPinit"
 	    "\7SSPinit" "\10SATAdev" "\11SMPtarg" "\12STPtarg" "\13SSPtarg"
 	    "\14Direct" "\15LSIdev" "\16ATAPIdev" "\17SEPdev",
@@ -410,14 +409,14 @@ mpr_print_expander1(struct mpr_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
 	    buf->AttachedDeviceInfo & 0x03));
 	MPR_PRINTFIELD(sc, buf, ExpanderDevHandle, 0x%04x);
 	MPR_PRINTFIELD(sc, buf, ChangeCount, %d);
-	mpr_dprint_field(sc, MPR_XINFO, "NegotiatedLinkRate: %s (0x%x)\n",
+	mpr_print_field(sc, "NegotiatedLinkRate: %s (0x%x)\n",
 	    mpr_describe_table(mpr_linkrate_names,
 	    buf->NegotiatedLinkRate & 0xf), buf->NegotiatedLinkRate);
 	MPR_PRINTFIELD(sc, buf, PhyIdentifier, %d);
 	MPR_PRINTFIELD(sc, buf, AttachedPhyIdentifier, %d);
 	MPR_PRINTFIELD(sc, buf, DiscoveryInfo, 0x%x);
 	MPR_PRINTFIELD(sc, buf, AttachedPhyInfo, 0x%x);
-	mpr_dprint_field(sc, MPR_XINFO, "AttachedPhyInfo Reason: %s (0x%x)\n",
+	mpr_print_field(sc, "AttachedPhyInfo Reason: %s (0x%x)\n",
 	    mpr_describe_table(mpr_phyinfo_reason_names,
 	    buf->AttachedPhyInfo & 0xf), buf->AttachedPhyInfo);
 	MPR_PRINTFIELD(sc, buf, ZoneGroup, %d);
@@ -425,27 +424,27 @@ mpr_print_expander1(struct mpr_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
 }
 
 void
-mpr_print_sasphy0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
+_mpr_print_sasphy0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
 {
 	MPR_PRINTFIELD_START(sc, "SAS PHY Page 0");
 	MPR_PRINTFIELD(sc, buf, OwnerDevHandle, 0x%04x);
 	MPR_PRINTFIELD(sc, buf, AttachedDevHandle, 0x%04x);
 	MPR_PRINTFIELD(sc, buf, AttachedPhyIdentifier, %d);
-	mpr_dprint_field(sc, MPR_XINFO, "AttachedPhyInfo Reason: %s (0x%x)\n",
+	mpr_print_field(sc, "AttachedPhyInfo Reason: %s (0x%x)\n",
 	    mpr_describe_table(mpr_phyinfo_reason_names,
 	    buf->AttachedPhyInfo & 0xf), buf->AttachedPhyInfo);
-	mpr_dprint_field(sc, MPR_XINFO, "ProgrammedLinkRate: %s (0x%x)\n",
+	mpr_print_field(sc, "ProgrammedLinkRate: %s (0x%x)\n",
 	    mpr_describe_table(mpr_linkrate_names,
 	    (buf->ProgrammedLinkRate >> 4) & 0xf), buf->ProgrammedLinkRate);
-	mpr_dprint_field(sc, MPR_XINFO, "HwLinkRate: %s (0x%x)\n",
+	mpr_print_field(sc, "HwLinkRate: %s (0x%x)\n",
 	    mpr_describe_table(mpr_linkrate_names,
 	    (buf->HwLinkRate >> 4) & 0xf), buf->HwLinkRate);
 	MPR_PRINTFIELD(sc, buf, ChangeCount, %d);
 	MPR_PRINTFIELD(sc, buf, Flags, 0x%x);
-	mpr_dprint_field(sc, MPR_XINFO, "PhyInfo Reason: %s (0x%x)\n",
+	mpr_print_field(sc, "PhyInfo Reason: %s (0x%x)\n",
 	    mpr_describe_table(mpr_phyinfo_reason_names,
 	    (buf->PhyInfo >> 16) & 0xf), buf->PhyInfo);
-	mpr_dprint_field(sc, MPR_XINFO, "NegotiatedLinkRate: %s (0x%x)\n",
+	mpr_print_field(sc, "NegotiatedLinkRate: %s (0x%x)\n",
 	    mpr_describe_table(mpr_linkrate_names,
 	    buf->NegotiatedLinkRate & 0xf), buf->NegotiatedLinkRate);
 }
diff --git a/sys/dev/mpr/mpr_table.h b/sys/dev/mpr/mpr_table.h
index 6539232138e..45a8eed1837 100644
--- a/sys/dev/mpr/mpr_table.h
+++ b/sys/dev/mpr/mpr_table.h
@@ -41,13 +41,63 @@ extern struct mpr_table_lookup mpr_event_names[];
 extern struct mpr_table_lookup mpr_phystatus_names[];
 extern struct mpr_table_lookup mpr_linkrate_names[];
 
-void mpr_print_iocfacts(struct mpr_softc *, MPI2_IOC_FACTS_REPLY *);
-void mpr_print_portfacts(struct mpr_softc *, MPI2_PORT_FACTS_REPLY *);
-void mpr_print_event(struct mpr_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
-void mpr_print_sasdev0(struct mpr_softc *, MPI2_CONFIG_PAGE_SAS_DEV_0 *);
-void mpr_print_evt_sas(struct mpr_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
-void mpr_print_expander1(struct mpr_softc *, MPI2_CONFIG_PAGE_EXPANDER_1 *);
-void mpr_print_sasphy0(struct mpr_softc *, MPI2_CONFIG_PAGE_SAS_PHY_0 *);
+void _mpr_print_iocfacts(struct mpr_softc *, MPI2_IOC_FACTS_REPLY *);
+void _mpr_print_portfacts(struct mpr_softc *, MPI2_PORT_FACTS_REPLY *);
+void _mpr_print_event(struct mpr_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
+void _mpr_print_sasdev0(struct mpr_softc *, MPI2_CONFIG_PAGE_SAS_DEV_0 *);
+void _mpr_print_evt_sas(struct mpr_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
+void _mpr_print_expander1(struct mpr_softc *, MPI2_CONFIG_PAGE_EXPANDER_1 *);
+void _mpr_print_sasphy0(struct mpr_softc *, MPI2_CONFIG_PAGE_SAS_PHY_0 *);
 void mpr_print_sgl(struct mpr_softc *, struct mpr_command *, int);
 void mpr_print_scsiio_cmd(struct mpr_softc *, struct mpr_command *);
+
+static __inline void
+mpr_print_iocfacts(struct mpr_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
+{
+	if (sc->mpr_debug & MPR_XINFO)
+		_mpr_print_iocfacts(sc, facts);
+}
+
+static __inline void
+mpr_print_portfacts(struct mpr_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
+{
+	if (sc->mpr_debug & MPR_XINFO)
+		_mpr_print_portfacts(sc, facts);
+}
+
+static __inline void
+mpr_print_event(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
+{
+	if (sc->mpr_debug & MPR_EVENT)
+		_mpr_print_event(sc, event);
+}
+
+static __inline void
+mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
+{
+	if (sc->mpr_debug & MPR_EVENT)
+		_mpr_print_evt_sas(sc, event);
+}
+
+static __inline void
+mpr_print_sasdev0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
+{
+	if (sc->mpr_debug & MPR_XINFO)
+		_mpr_print_sasdev0(sc, buf);
+}
+
+static __inline void
+mpr_print_expander1(struct mpr_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
+{
+	if (sc->mpr_debug & MPR_XINFO)
+		_mpr_print_expander1(sc, buf);
+}
+
+static __inline void
+mpr_print_sasphy0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
+{
+	if (sc->mpr_debug & MPR_XINFO)
+		_mpr_print_sasphy0(sc, buf);
+}
+
 #endif
diff --git a/sys/dev/mpr/mprvar.h b/sys/dev/mpr/mprvar.h
index 0a9ccb61f37..4f0e9e70e09 100644
--- a/sys/dev/mpr/mprvar.h
+++ b/sys/dev/mpr/mprvar.h
@@ -584,6 +584,9 @@ mpr_unlock(struct mpr_softc *sc)
 #define mpr_printf(sc, args...)				\
 	device_printf((sc)->mpr_dev, ##args)
 
+#define mpr_print_field(sc, msg, args...)		\
+	printf("\t" msg, ##args)
+
 #define mpr_vprintf(sc, args...)			\
 do {							\
 	if (bootverbose)				\
@@ -596,25 +599,13 @@ do {							\
 		device_printf((sc)->mpr_dev, msg, ##args);	\
 } while (0)
 
-#define mpr_dprint_field(sc, level, msg, args...)		\
-do {								\
-	if ((sc)->mpr_debug & (level))				\
-		printf("\t" msg, ##args);			\
-} while (0)
-
 #define MPR_PRINTFIELD_START(sc, tag...)	\
-	mpr_dprint((sc), MPR_INFO, ##tag);	\
-	mpr_dprint_field((sc), MPR_INFO, ":\n")
+	mpr_printf((sc), ##tag);		\
+	mpr_print_field((sc), ":\n")
 #define MPR_PRINTFIELD_END(sc, tag)		\
-	mpr_dprint((sc), MPR_INFO, tag "\n")
+	mpr_printf((sc), tag "\n")
 #define MPR_PRINTFIELD(sc, facts, attr, fmt)	\
-	mpr_dprint_field((sc), MPR_INFO, #attr ": " #fmt "\n", (facts)->attr)
-
-#define MPR_EVENTFIELD_START(sc, tag...)	\
-	mpr_dprint((sc), MPR_EVENT, ##tag);	\
-	mpr_dprint_field((sc), MPR_EVENT, ":\n")
-#define MPR_EVENTFIELD(sc, facts, attr, fmt)	\
-	mpr_dprint_field((sc), MPR_EVENT, #attr ": " #fmt "\n", (facts)->attr)
+	mpr_print_field((sc), #attr ": " #fmt "\n", (facts)->attr)
 
 static __inline void
 mpr_from_u64(uint64_t data, U64 *mpr)
diff --git a/sys/dev/mps/mps_sas.c b/sys/dev/mps/mps_sas.c
index bfae67bbadd..ac7b5e2dc53 100644
--- a/sys/dev/mps/mps_sas.c
+++ b/sys/dev/mps/mps_sas.c
@@ -347,7 +347,7 @@ mpssas_log_command(struct mps_command *cm, u_int level, const char *fmt, ...)
 	sbuf_printf(&sb, "SMID %u ", cm->cm_desc.Default.SMID);
 	sbuf_vprintf(&sb, fmt, ap);
 	sbuf_finish(&sb);
-	mps_dprint_field(cm->cm_sc, level, "%s", sbuf_data(&sb));
+	mps_print_field(cm->cm_sc, "%s", sbuf_data(&sb));
 
 	va_end(ap);
 }
diff --git a/sys/dev/mps/mps_table.c b/sys/dev/mps/mps_table.c
index d85a71a2e55..b6c96edf2f0 100644
--- a/sys/dev/mps/mps_table.c
+++ b/sys/dev/mps/mps_table.c
@@ -196,7 +196,7 @@ mps_describe_devinfo(uint32_t devinfo, char *string, int len)
 }
 
 void
-mps_print_iocfacts(struct mps_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
+_mps_print_iocfacts(struct mps_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
 {
 
 	MPS_PRINTFIELD_START(sc, "IOCFacts");
@@ -205,18 +205,18 @@ mps_print_iocfacts(struct mps_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
 	MPS_PRINTFIELD(sc, facts, IOCNumber, %d);
 	MPS_PRINTFIELD(sc, facts, IOCExceptions, 0x%x);
 	MPS_PRINTFIELD(sc, facts, MaxChainDepth, %d);
-	mps_dprint_field(sc, MPS_XINFO, "WhoInit: %s\n",
+	mps_print_field(sc, "WhoInit: %s\n",
 	    mps_describe_table(mps_whoinit_names, facts->WhoInit));
 	MPS_PRINTFIELD(sc, facts, NumberOfPorts, %d);
 	MPS_PRINTFIELD(sc, facts, MaxMSIxVectors, %d);
 	MPS_PRINTFIELD(sc, facts, RequestCredit, %d);
 	MPS_PRINTFIELD(sc, facts, ProductID, 0x%x);
-	mps_dprint_field(sc, MPS_XINFO, "IOCCapabilities: %b\n",
+	mps_print_field(sc, "IOCCapabilities: %b\n",
 	    facts->IOCCapabilities, "\20" "\3ScsiTaskFull" "\4DiagTrace"
 	    "\5SnapBuf" "\6ExtBuf" "\7EEDP" "\10BiDirTarg" "\11Multicast"
 	    "\14TransRetry" "\15IR" "\16EventReplay" "\17RaidAccel"
 	    "\20MSIXIndex" "\21HostDisc");
-	mps_dprint_field(sc, MPS_XINFO, "FWVersion= %d-%d-%d-%d\n",
+	mps_print_field(sc, "FWVersion= %d-%d-%d-%d\n",
 	    facts->FWVersion.Struct.Major,
 	    facts->FWVersion.Struct.Minor,
 	    facts->FWVersion.Struct.Unit,
@@ -226,7 +226,7 @@ mps_print_iocfacts(struct mps_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
 	MPS_PRINTFIELD(sc, facts, MaxTargets, %d);
 	MPS_PRINTFIELD(sc, facts, MaxSasExpanders, %d);
 	MPS_PRINTFIELD(sc, facts, MaxEnclosures, %d);
-	mps_dprint_field(sc, MPS_XINFO, "ProtocolFlags: %b\n",
+	mps_print_field(sc, "ProtocolFlags: %b\n",
 	    facts->ProtocolFlags, "\20" "\1ScsiTarg" "\2ScsiInit");
 	MPS_PRINTFIELD(sc, facts, HighPriorityCredit, %d);
 	MPS_PRINTFIELD(sc, facts, MaxReplyDescriptorPostQueueDepth, %d);
@@ -237,7 +237,7 @@ mps_print_iocfacts(struct mps_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
 }
 
 void
-mps_print_portfacts(struct mps_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
+_mps_print_portfacts(struct mps_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
 {
 
 	MPS_PRINTFIELD_START(sc, "PortFacts");
@@ -247,24 +247,24 @@ mps_print_portfacts(struct mps_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
 }
 
 void
-mps_print_event(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
+_mps_print_event(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 {
 
-	MPS_EVENTFIELD_START(sc, "EventReply");
-	MPS_EVENTFIELD(sc, event, EventDataLength, %d);
-	MPS_EVENTFIELD(sc, event, AckRequired, %d);
-	mps_dprint_field(sc, MPS_EVENT, "Event: %s (0x%x)\n",
+	MPS_PRINTFIELD_START(sc, "EventReply");
+	MPS_PRINTFIELD(sc, event, EventDataLength, %d);
+	MPS_PRINTFIELD(sc, event, AckRequired, %d);
+	mps_print_field(sc, "Event: %s (0x%x)\n",
 	    mps_describe_table(mps_event_names, event->Event), event->Event);
-	MPS_EVENTFIELD(sc, event, EventContext, 0x%x);
+	MPS_PRINTFIELD(sc, event, EventContext, 0x%x);
 }
 
 void
-mps_print_sasdev0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
+_mps_print_sasdev0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
 {
 	MPS_PRINTFIELD_START(sc, "SAS Device Page 0");
 	MPS_PRINTFIELD(sc, buf, Slot, %d);
 	MPS_PRINTFIELD(sc, buf, EnclosureHandle, 0x%x);
-	mps_dprint_field(sc, MPS_XINFO, "SASAddress: 0x%jx\n",
+	mps_print_field(sc, "SASAddress: 0x%jx\n",
 	    mps_to_u64(&buf->SASAddress));
 	MPS_PRINTFIELD(sc, buf, ParentDevHandle, 0x%x);
 	MPS_PRINTFIELD(sc, buf, PhyNum, %d);
@@ -272,7 +272,7 @@ mps_print_sasdev0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
 	MPS_PRINTFIELD(sc, buf, DevHandle, 0x%x);
 	MPS_PRINTFIELD(sc, buf, AttachedPhyIdentifier, 0x%x);
 	MPS_PRINTFIELD(sc, buf, ZoneGroup, %d);
-	mps_dprint_field(sc, MPS_XINFO, "DeviceInfo: %b,%s\n", buf->DeviceInfo,
+	mps_print_field(sc, "DeviceInfo: %b,%s\n", buf->DeviceInfo,
 	    "\20" "\4SataHost" "\5SmpInit" "\6StpInit" "\7SspInit"
 	    "\10SataDev" "\11SmpTarg" "\12StpTarg" "\13SspTarg" "\14Direct"
 	    "\15LsiDev" "\16AtapiDev" "\17SepDev",
@@ -280,7 +280,7 @@ mps_print_sasdev0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
 	MPS_PRINTFIELD(sc, buf, Flags, 0x%x);
 	MPS_PRINTFIELD(sc, buf, PhysicalPort, %d);
 	MPS_PRINTFIELD(sc, buf, MaxPortConnections, %d);
-	mps_dprint_field(sc, MPS_XINFO, "DeviceName: 0x%jx\n",
+	mps_print_field(sc, "DeviceName: 0x%jx\n",
 	    mps_to_u64(&buf->DeviceName));
 	MPS_PRINTFIELD(sc, buf, PortGroups, %d);
 	MPS_PRINTFIELD(sc, buf, DmaGroup, %d);
@@ -288,10 +288,10 @@ mps_print_sasdev0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
 }
 
 void
-mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
+_mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 {
 
-	mps_print_event(sc, event);
+	_mps_print_event(sc, event);
 
 	switch(event->Event) {
 	case MPI2_EVENT_SAS_DISCOVERY:
@@ -299,12 +299,12 @@ mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 		MPI2_EVENT_DATA_SAS_DISCOVERY *data;
 
 		data = (MPI2_EVENT_DATA_SAS_DISCOVERY *)&event->EventData;
-		mps_dprint_field(sc, MPS_EVENT, "Flags: %b\n", data->Flags,
+		mps_print_field(sc, "Flags: %b\n", data->Flags,
 		    "\20" "\1InProgress" "\2DeviceChange");
-		mps_dprint_field(sc, MPS_EVENT, "ReasonCode: %s\n",
+		mps_print_field(sc, "ReasonCode: %s\n",
 		    mps_describe_table(mps_sasdisc_reason, data->ReasonCode));
-		MPS_EVENTFIELD(sc, data, PhysicalPort, %d);
-		mps_dprint_field(sc, MPS_EVENT, "DiscoveryStatus: %b\n",
+		MPS_PRINTFIELD(sc, data, PhysicalPort, %d);
+		mps_print_field(sc, "DiscoveryStatus: %b\n",
 		    data->DiscoveryStatus,  "\20"
 		    "\1Loop" "\2UnaddressableDev" "\3DupSasAddr" "\5SmpTimeout"
 		    "\6ExpRouteFull" "\7RouteIndexError" "\10SmpFailed"
@@ -323,26 +323,26 @@ mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 
 		data = (MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *)
 		    &event->EventData;
-		MPS_EVENTFIELD(sc, data, EnclosureHandle, 0x%x);
-		MPS_EVENTFIELD(sc, data, ExpanderDevHandle, 0x%x);
-		MPS_EVENTFIELD(sc, data, NumPhys, %d);
-		MPS_EVENTFIELD(sc, data, NumEntries, %d);
-		MPS_EVENTFIELD(sc, data, StartPhyNum, %d);
-		mps_dprint_field(sc, MPS_EVENT, "ExpStatus: %s (0x%x)\n",
+		MPS_PRINTFIELD(sc, data, EnclosureHandle, 0x%x);
+		MPS_PRINTFIELD(sc, data, ExpanderDevHandle, 0x%x);
+		MPS_PRINTFIELD(sc, data, NumPhys, %d);
+		MPS_PRINTFIELD(sc, data, NumEntries, %d);
+		MPS_PRINTFIELD(sc, data, StartPhyNum, %d);
+		mps_print_field(sc, "ExpStatus: %s (0x%x)\n",
 		    mps_describe_table(mps_sastopo_exp, data->ExpStatus),
 		    data->ExpStatus);
-		MPS_EVENTFIELD(sc, data, PhysicalPort, %d);
+		MPS_PRINTFIELD(sc, data, PhysicalPort, %d);
 		for (i = 0; i < data->NumEntries; i++) {
 			phy = &data->PHY[i];
 			phynum = data->StartPhyNum + i;
-			mps_dprint_field(sc, MPS_EVENT,
+			mps_print_field(sc,
 			    "PHY[%d].AttachedDevHandle: 0x%04x\n", phynum,
 			    phy->AttachedDevHandle);
-			mps_dprint_field(sc, MPS_EVENT,
+			mps_print_field(sc,
 			    "PHY[%d].LinkRate: %s (0x%x)\n", phynum,
 			    mps_describe_table(mps_linkrate_names,
 			    (phy->LinkRate >> 4) & 0xf), phy->LinkRate);
-			mps_dprint_field(sc,MPS_EVENT,"PHY[%d].PhyStatus: %s\n",
+			mps_print_field(sc, "PHY[%d].PhyStatus: %s\n",
 			    phynum, mps_describe_table(mps_phystatus_names,
 			    phy->PhyStatus));
 		}
@@ -354,13 +354,13 @@ mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 
 		data = (MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE *)
 		    &event->EventData;
-		MPS_EVENTFIELD(sc, data, EnclosureHandle, 0x%x);
-		mps_dprint_field(sc, MPS_EVENT, "ReasonCode: %s\n",
+		MPS_PRINTFIELD(sc, data, EnclosureHandle, 0x%x);
+		mps_print_field(sc, "ReasonCode: %s\n",
 		    mps_describe_table(mps_sastopo_exp, data->ReasonCode));
-		MPS_EVENTFIELD(sc, data, PhysicalPort, %d);
-		MPS_EVENTFIELD(sc, data, NumSlots, %d);
-		MPS_EVENTFIELD(sc, data, StartSlot, %d);
-		MPS_EVENTFIELD(sc, data, PhyBits, 0x%x);
+		MPS_PRINTFIELD(sc, data, PhysicalPort, %d);
+		MPS_PRINTFIELD(sc, data, NumSlots, %d);
+		MPS_PRINTFIELD(sc, data, StartSlot, %d);
+		MPS_PRINTFIELD(sc, data, PhyBits, 0x%x);
 		break;
 	}
 	case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
@@ -369,13 +369,13 @@ mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 
 		data = (MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
 		    &event->EventData;
-		MPS_EVENTFIELD(sc, data, TaskTag, 0x%x);
-		mps_dprint_field(sc, MPS_EVENT, "ReasonCode: %s\n",
+		MPS_PRINTFIELD(sc, data, TaskTag, 0x%x);
+		mps_print_field(sc, "ReasonCode: %s\n",
 		    mps_describe_table(mps_sasdev_reason, data->ReasonCode));
-		MPS_EVENTFIELD(sc, data, ASC, 0x%x);
-		MPS_EVENTFIELD(sc, data, ASCQ, 0x%x);
-		MPS_EVENTFIELD(sc, data, DevHandle, 0x%x);
-		mps_dprint_field(sc, MPS_EVENT, "SASAddress: 0x%jx\n",
+		MPS_PRINTFIELD(sc, data, ASC, 0x%x);
+		MPS_PRINTFIELD(sc, data, ASCQ, 0x%x);
+		MPS_PRINTFIELD(sc, data, DevHandle, 0x%x);
+		mps_print_field(sc, "SASAddress: 0x%jx\n",
 		    mps_to_u64(&data->SASAddress));
 	}
 	default:
@@ -384,24 +384,24 @@ mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 }
 
 void
-mps_print_expander1(struct mps_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
+_mps_print_expander1(struct mps_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
 {
 	MPS_PRINTFIELD_START(sc, "SAS Expander Page 1 #%d", buf->Phy);
 	MPS_PRINTFIELD(sc, buf, PhysicalPort, %d);
 	MPS_PRINTFIELD(sc, buf, NumPhys, %d);
 	MPS_PRINTFIELD(sc, buf, Phy, %d);
 	MPS_PRINTFIELD(sc, buf, NumTableEntriesProgrammed, %d);
-	mps_dprint_field(sc, MPS_XINFO, "ProgrammedLinkRate: %s (0x%x)\n",
+	mps_print_field(sc, "ProgrammedLinkRate: %s (0x%x)\n",
 	    mps_describe_table(mps_linkrate_names,
 	    (buf->ProgrammedLinkRate >> 4) & 0xf), buf->ProgrammedLinkRate);
-	mps_dprint_field(sc, MPS_XINFO, "HwLinkRate: %s (0x%x)\n",
+	mps_print_field(sc, "HwLinkRate: %s (0x%x)\n",
 	    mps_describe_table(mps_linkrate_names,
 	    (buf->HwLinkRate >> 4) & 0xf), buf->HwLinkRate);
 	MPS_PRINTFIELD(sc, buf, AttachedDevHandle, 0x%04x);
-	mps_dprint_field(sc, MPS_XINFO, "PhyInfo Reason: %s (0x%x)\n",
+	mps_print_field(sc, "PhyInfo Reason: %s (0x%x)\n",
 	    mps_describe_table(mps_phyinfo_reason_names,
 	    (buf->PhyInfo >> 16) & 0xf), buf->PhyInfo);
-	mps_dprint_field(sc, MPS_XINFO, "AttachedDeviceInfo: %b,%s\n",
+	mps_print_field(sc, "AttachedDeviceInfo: %b,%s\n",
 	    buf->AttachedDeviceInfo, "\20" "\4SATAhost" "\5SMPinit" "\6STPinit"
 	    "\7SSPinit" "\10SATAdev" "\11SMPtarg" "\12STPtarg" "\13SSPtarg"
 	    "\14Direct" "\15LSIdev" "\16ATAPIdev" "\17SEPdev",
@@ -409,14 +409,14 @@ mps_print_expander1(struct mps_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
 	    buf->AttachedDeviceInfo & 0x03));
 	MPS_PRINTFIELD(sc, buf, ExpanderDevHandle, 0x%04x);
 	MPS_PRINTFIELD(sc, buf, ChangeCount, %d);
-	mps_dprint_field(sc, MPS_XINFO, "NegotiatedLinkRate: %s (0x%x)\n",
+	mps_print_field(sc, "NegotiatedLinkRate: %s (0x%x)\n",
 	    mps_describe_table(mps_linkrate_names,
 	    buf->NegotiatedLinkRate & 0xf), buf->NegotiatedLinkRate);
 	MPS_PRINTFIELD(sc, buf, PhyIdentifier, %d);
 	MPS_PRINTFIELD(sc, buf, AttachedPhyIdentifier, %d);
 	MPS_PRINTFIELD(sc, buf, DiscoveryInfo, 0x%x);
 	MPS_PRINTFIELD(sc, buf, AttachedPhyInfo, 0x%x);
-	mps_dprint_field(sc, MPS_XINFO, "AttachedPhyInfo Reason: %s (0x%x)\n",
+	mps_print_field(sc, "AttachedPhyInfo Reason: %s (0x%x)\n",
 	    mps_describe_table(mps_phyinfo_reason_names,
 	    buf->AttachedPhyInfo & 0xf), buf->AttachedPhyInfo);
 	MPS_PRINTFIELD(sc, buf, ZoneGroup, %d);
@@ -424,27 +424,27 @@ mps_print_expander1(struct mps_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
 }
 
 void
-mps_print_sasphy0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
+_mps_print_sasphy0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
 {
 	MPS_PRINTFIELD_START(sc, "SAS PHY Page 0");
 	MPS_PRINTFIELD(sc, buf, OwnerDevHandle, 0x%04x);
 	MPS_PRINTFIELD(sc, buf, AttachedDevHandle, 0x%04x);
 	MPS_PRINTFIELD(sc, buf, AttachedPhyIdentifier, %d);
-	mps_dprint_field(sc, MPS_XINFO, "AttachedPhyInfo Reason: %s (0x%x)\n",
+	mps_print_field(sc, "AttachedPhyInfo Reason: %s (0x%x)\n",
 	    mps_describe_table(mps_phyinfo_reason_names,
 	    buf->AttachedPhyInfo & 0xf), buf->AttachedPhyInfo);
-	mps_dprint_field(sc, MPS_XINFO, "ProgrammedLinkRate: %s (0x%x)\n",
+	mps_print_field(sc, "ProgrammedLinkRate: %s (0x%x)\n",
 	    mps_describe_table(mps_linkrate_names,
 	    (buf->ProgrammedLinkRate >> 4) & 0xf), buf->ProgrammedLinkRate);
-	mps_dprint_field(sc, MPS_XINFO, "HwLinkRate: %s (0x%x)\n",
+	mps_print_field(sc, "HwLinkRate: %s (0x%x)\n",
 	    mps_describe_table(mps_linkrate_names,
 	    (buf->HwLinkRate >> 4) & 0xf), buf->HwLinkRate);
 	MPS_PRINTFIELD(sc, buf, ChangeCount, %d);
 	MPS_PRINTFIELD(sc, buf, Flags, 0x%x);
-	mps_dprint_field(sc, MPS_XINFO, "PhyInfo Reason: %s (0x%x)\n",
+	mps_print_field(sc, "PhyInfo Reason: %s (0x%x)\n",
 	    mps_describe_table(mps_phyinfo_reason_names,
 	    (buf->PhyInfo >> 16) & 0xf), buf->PhyInfo);
-	mps_dprint_field(sc, MPS_XINFO, "NegotiatedLinkRate: %s (0x%x)\n",
+	mps_print_field(sc, "NegotiatedLinkRate: %s (0x%x)\n",
 	    mps_describe_table(mps_linkrate_names,
 	    buf->NegotiatedLinkRate & 0xf), buf->NegotiatedLinkRate);
 }
diff --git a/sys/dev/mps/mps_table.h b/sys/dev/mps/mps_table.h
index 88aa2c38546..1fe6b1eedda 100644
--- a/sys/dev/mps/mps_table.h
+++ b/sys/dev/mps/mps_table.h
@@ -41,13 +41,63 @@ extern struct mps_table_lookup mps_event_names[];
 extern struct mps_table_lookup mps_phystatus_names[];
 extern struct mps_table_lookup mps_linkrate_names[];
 
-void mps_print_iocfacts(struct mps_softc *, MPI2_IOC_FACTS_REPLY *);
-void mps_print_portfacts(struct mps_softc *, MPI2_PORT_FACTS_REPLY *);
-void mps_print_event(struct mps_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
-void mps_print_sasdev0(struct mps_softc *, MPI2_CONFIG_PAGE_SAS_DEV_0 *);
-void mps_print_evt_sas(struct mps_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
-void mps_print_expander1(struct mps_softc *, MPI2_CONFIG_PAGE_EXPANDER_1 *);
-void mps_print_sasphy0(struct mps_softc *, MPI2_CONFIG_PAGE_SAS_PHY_0 *);
+void _mps_print_iocfacts(struct mps_softc *, MPI2_IOC_FACTS_REPLY *);
+void _mps_print_portfacts(struct mps_softc *, MPI2_PORT_FACTS_REPLY *);
+void _mps_print_event(struct mps_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
+void _mps_print_sasdev0(struct mps_softc *, MPI2_CONFIG_PAGE_SAS_DEV_0 *);
+void _mps_print_evt_sas(struct mps_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
+void _mps_print_expander1(struct mps_softc *, MPI2_CONFIG_PAGE_EXPANDER_1 *);
+void _mps_print_sasphy0(struct mps_softc *, MPI2_CONFIG_PAGE_SAS_PHY_0 *);
 void mps_print_sgl(struct mps_softc *, struct mps_command *, int);
 void mps_print_scsiio_cmd(struct mps_softc *, struct mps_command *);
+
+static __inline void
+mps_print_iocfacts(struct mps_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
+{
+	if (sc->mps_debug & MPS_XINFO)
+		_mps_print_iocfacts(sc, facts);
+}
+
+static __inline void
+mps_print_portfacts(struct mps_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
+{
+	if (sc->mps_debug & MPS_XINFO)
+		_mps_print_portfacts(sc, facts);
+}
+
+static __inline void
+mps_print_event(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
+{
+	if (sc->mps_debug & MPS_EVENT)
+		_mps_print_event(sc, event);
+}
+
+static __inline void
+mps_print_sasdev0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
+{
+	if (sc->mps_debug & MPS_XINFO)
+		_mps_print_sasdev0(sc, buf);
+}
+
+static __inline void
+mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
+{
+	if (sc->mps_debug & MPS_EVENT)
+		_mps_print_evt_sas(sc, event);
+}
+
+static __inline void
+mps_print_expander1(struct mps_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
+{
+	if (sc->mps_debug & MPS_XINFO)
+		_mps_print_expander1(sc, buf);
+}
+
+static __inline void
+mps_print_sasphy0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
+{
+	if (sc->mps_debug & MPS_XINFO)
+		_mps_print_sasphy0(sc, buf);
+}
+
 #endif
diff --git a/sys/dev/mps/mpsvar.h b/sys/dev/mps/mpsvar.h
index d8cda89dfc1..8c9fc8c8b34 100644
--- a/sys/dev/mps/mpsvar.h
+++ b/sys/dev/mps/mpsvar.h
@@ -609,6 +609,9 @@ mps_unlock(struct mps_softc *sc)
 #define mps_printf(sc, args...)				\
 	device_printf((sc)->mps_dev, ##args)
 
+#define mps_print_field(sc, msg, args...)		\
+	printf("\t" msg, ##args)
+
 #define mps_vprintf(sc, args...)			\
 do {							\
 	if (bootverbose)				\
@@ -621,25 +624,13 @@ do {							\
 		device_printf((sc)->mps_dev, msg, ##args);	\
 } while (0)
 
-#define mps_dprint_field(sc, level, msg, args...)		\
-do {								\
-	if ((sc)->mps_debug & (level))				\
-		printf("\t" msg, ##args);			\
-} while (0)
-
 #define MPS_PRINTFIELD_START(sc, tag...)	\
-	mps_dprint((sc), MPS_XINFO, ##tag);	\
-	mps_dprint_field((sc), MPS_XINFO, ":\n")
+	mps_printf((sc), ##tag);			\
+	mps_print_field((sc), ":\n")
 #define MPS_PRINTFIELD_END(sc, tag)		\
-	mps_dprint((sc), MPS_XINFO, tag "\n")
+	mps_printf((sc), tag "\n")
 #define MPS_PRINTFIELD(sc, facts, attr, fmt)	\
-	mps_dprint_field((sc), MPS_XINFO, #attr ": " #fmt "\n", (facts)->attr)
-
-#define MPS_EVENTFIELD_START(sc, tag...)	\
-	mps_dprint((sc), MPS_EVENT, ##tag);	\
-	mps_dprint_field((sc), MPS_EVENT, ":\n")
-#define MPS_EVENTFIELD(sc, facts, attr, fmt)	\
-	mps_dprint_field((sc), MPS_EVENT, #attr ": " #fmt "\n", (facts)->attr)
+	mps_print_field((sc), #attr ": " #fmt "\n", (facts)->attr)
 
 #define MPS_FUNCTRACE(sc)			\
 	mps_dprint((sc), MPS_TRACE, "%s\n", __func__)
diff --git a/sys/dev/rtwn/if_rtwn.c b/sys/dev/rtwn/if_rtwn.c
index bb8fb6a9c0e..c8bd19d2458 100644
--- a/sys/dev/rtwn/if_rtwn.c
+++ b/sys/dev/rtwn/if_rtwn.c
@@ -695,6 +695,7 @@ rtwn_ioctl_reset(struct ieee80211vap *vap, u_long cmd)
 	case IEEE80211_IOC_RTSTHRESHOLD:
 	case IEEE80211_IOC_PROTMODE:
 	case IEEE80211_IOC_HTPROTMODE:
+	case IEEE80211_IOC_LDPC:
 		error = 0;
 		break;
 	default:
@@ -1999,6 +2000,7 @@ rtwn_stop(struct rtwn_softc *sc)
 	sc->fwver = 0;
 	sc->thcal_temp = 0;
 	sc->cur_bcnq_id = RTWN_VAP_ID_INVALID;
+	bzero(&sc->last_physt, sizeof(sc->last_physt));
 
 #ifdef D4054
 	ieee80211_tx_watchdog_stop(&sc->sc_ic);
diff --git a/sys/dev/rtwn/if_rtwn_rx.c b/sys/dev/rtwn/if_rtwn_rx.c
index 1dea7a6d607..d6ccb159fc2 100644
--- a/sys/dev/rtwn/if_rtwn_rx.c
+++ b/sys/dev/rtwn/if_rtwn_rx.c
@@ -117,18 +117,19 @@ rtwn_set_basicrates(struct rtwn_softc *sc, uint32_t rates)
 }
 
 static void
-rtwn_update_avgrssi(struct rtwn_softc *sc, struct rtwn_node *un, int rate)
+rtwn_update_avgrssi(struct rtwn_softc *sc, struct rtwn_node *un, int8_t rssi,
+    int is_cck)
 {
 	int pwdb;
 
 	/* Convert antenna signal to percentage. */
-	if (un->last_rssi <= -100 || un->last_rssi >= 20)
+	if (rssi <= -100 || rssi >= 20)
 		pwdb = 0;
-	else if (un->last_rssi >= 0)
+	else if (rssi >= 0)
 		pwdb = 100;
 	else
-		pwdb = 100 + un->last_rssi;
-	if (RTWN_RATE_IS_CCK(rate)) {
+		pwdb = 100 + rssi;
+	if (is_cck) {
 		/* CCK gain is smaller than OFDM/MCS gain. */
 		pwdb += 6;
 		if (pwdb > 100)
@@ -155,11 +156,11 @@ rtwn_update_avgrssi(struct rtwn_softc *sc, struct rtwn_node *un, int rate)
 }
 
 static int8_t
-rtwn_get_rssi(struct rtwn_softc *sc, int rate, void *physt)
+rtwn_get_rssi(struct rtwn_softc *sc, void *physt, int is_cck)
 {
 	int8_t rssi;
 
-	if (RTWN_RATE_IS_CCK(rate))
+	if (is_cck)
 		rssi = rtwn_get_rssi_cck(sc, physt);
 	else	/* OFDM/HT. */
 		rssi = rtwn_get_rssi_ofdm(sc, physt);
@@ -188,81 +189,133 @@ rtwn_get_tsf(struct rtwn_softc *sc, uint64_t *buf, int id)
 	*buf += rtwn_get_tsf_low(sc, id);
 }
 
+static uint64_t
+rtwn_extend_rx_tsf(struct rtwn_softc *sc, const struct r92c_rx_stat *stat)
+{
+	uint64_t tsft;
+	uint32_t rxdw3, tsfl, tsfl_curr;
+	int id;
+
+	rxdw3 = le32toh(stat->rxdw3);
+	tsfl = le32toh(stat->tsf_low);
+	id = MS(rxdw3, R92C_RXDW3_BSSID_FIT);
+
+	switch (id) {
+	case 1:
+	case 2:
+		id >>= 1;
+		tsfl_curr = rtwn_get_tsf_low(sc, id);
+		break;
+	default:
+	{
+		uint32_t tsfl0, tsfl1;
+
+		tsfl0 = rtwn_get_tsf_low(sc, 0);
+		tsfl1 = rtwn_get_tsf_low(sc, 1);
+
+		if (abs(tsfl0 - tsfl) < abs(tsfl1 - tsfl)) {
+			id = 0;
+			tsfl_curr = tsfl0;
+		} else {
+			id = 1;
+			tsfl_curr = tsfl1;
+		}
+		break;
+	}
+	}
+
+	tsft = rtwn_get_tsf_high(sc, id);
+	if (tsfl > tsfl_curr && tsfl > 0xffff0000)
+		tsft--;
+	tsft <<= 32;
+	tsft += tsfl;
+
+	return (tsft);
+}
+
 struct ieee80211_node *
-rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc,
-    int8_t *rssi)
+rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc)
 {
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ieee80211_node *ni;
 	struct ieee80211_frame_min *wh;
+	struct ieee80211_rx_stats rxs;
 	struct rtwn_node *un;
 	struct r92c_rx_stat *stat;
-	uint32_t rxdw0, rxdw3;
-	int cipher, infosz, pktlen, rate, shift;
+	void *physt;
+	uint32_t rxdw0;
+	int8_t rssi;
+	int cipher, infosz, is_cck, pktlen, shift;
 
 	stat = desc;
 	rxdw0 = le32toh(stat->rxdw0);
-	rxdw3 = le32toh(stat->rxdw3);
 
 	cipher = MS(rxdw0, R92C_RXDW0_CIPHER);
 	infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
 	pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN);
 	shift = MS(rxdw0, R92C_RXDW0_SHIFT);
-	rate = MS(rxdw3, R92C_RXDW3_RATE);
 
 	wh = (struct ieee80211_frame_min *)(mtodo(m, shift + infosz));
 	if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
 	    cipher != R92C_CAM_ALGO_NONE)
 		m->m_flags |= M_WEP;
 
-	if (pktlen >= sizeof(*wh))
+	if (pktlen >= sizeof(*wh)) {
 		ni = ieee80211_find_rxnode(ic, wh);
-	else
+		if (ni != NULL && (ni->ni_flags & IEEE80211_NODE_HT))
+			m->m_flags |= M_AMPDU;
+	} else
 		ni = NULL;
 	un = RTWN_NODE(ni);
 
-	/* Get RSSI from PHY status descriptor if present. */
-	if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
-		*rssi = rtwn_get_rssi(sc, rate, mtod(m, void *));
-		RTWN_DPRINTF(sc, RTWN_DEBUG_RSSI, "%s: rssi %d, ridx %d\n",
-		    __func__, *rssi, rate);
+	if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST))
+		physt = (void *)mtodo(m, shift);
+	else
+		physt = (un != NULL) ? &un->last_physt : &sc->last_physt;
 
-		sc->last_rssi = *rssi;
-		if (un != NULL) {
-			un->last_rssi = *rssi;
+	bzero(&rxs, sizeof(rxs));
+	rtwn_get_rx_stats(sc, &rxs, desc, physt);
+	if (rxs.c_pktflags & IEEE80211_RX_F_AMPDU) {
+		/* Next MPDU will come without PHY info. */
+		memcpy(&sc->last_physt, physt, sizeof(sc->last_physt));
+		if (un != NULL)
+			memcpy(&un->last_physt, physt, sizeof(sc->last_physt));
+	}
 
-			/* Update our average RSSI. */
-			rtwn_update_avgrssi(sc, un, rate);
-		}
-	} else
-		*rssi = (un != NULL) ? un->last_rssi : sc->last_rssi;
+	/* Add some common bits. */
+	/* NB: should not happen. */
+	if (rxdw0 & R92C_RXDW0_CRCERR)
+		rxs.c_pktflags |= IEEE80211_RX_F_FAIL_FCSCRC;
+
+	rxs.r_flags |= IEEE80211_R_TSF_START;	/* XXX undocumented */
+	rxs.r_flags |= IEEE80211_R_TSF64;
+	rxs.c_rx_tsf = rtwn_extend_rx_tsf(sc, stat);
+
+	/* Get RSSI from PHY status descriptor. */
+	is_cck = (rxs.c_pktflags & IEEE80211_RX_F_CCK) != 0;
+	rssi = rtwn_get_rssi(sc, physt, is_cck);
+
+	/* XXX TODO: we really need a rate-to-string method */
+	RTWN_DPRINTF(sc, RTWN_DEBUG_RSSI, "%s: rssi %d, rate %d\n",
+	    __func__, rssi, rxs.c_rate);
+	if (un != NULL && infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
+		/* Update our average RSSI. */
+		rtwn_update_avgrssi(sc, un, rssi, is_cck);
+	}
+
+	rxs.r_flags |= IEEE80211_R_NF | IEEE80211_R_RSSI;
+	rxs.c_nf = RTWN_NOISE_FLOOR;
+	rxs.c_rssi = rssi - rxs.c_nf;
+	(void) ieee80211_add_rx_params(m, &rxs);
 
 	if (ieee80211_radiotap_active(ic)) {
 		struct rtwn_rx_radiotap_header *tap = &sc->sc_rxtap;
-		int id = RTWN_VAP_ID_INVALID;
-
-		if (ni != NULL)
-			id = RTWN_VAP(ni->ni_vap)->id;
-		if (id == RTWN_VAP_ID_INVALID)
-			id = 0;
 
 		tap->wr_flags = rtwn_rx_radiotap_flags(sc, desc);
-		tap->wr_tsft = rtwn_get_tsf_high(sc, id);
-		if (le32toh(stat->tsf_low) > rtwn_get_tsf_low(sc, id))
-			tap->wr_tsft--;
-		tap->wr_tsft = (uint64_t)htole32(tap->wr_tsft) << 32;
-		tap->wr_tsft += stat->tsf_low;
-
-		/* XXX 20/40? */
-
-		/* Map HW rate index to 802.11 rate. */
-		if (rate < RTWN_RIDX_MCS(0))
-			tap->wr_rate = ridx2rate[rate];
-		else	/* MCS0~15. */
-			tap->wr_rate = IEEE80211_RATE_MCS | (rate - 12);
-
-		tap->wr_dbm_antsignal = *rssi;
-		tap->wr_dbm_antnoise = RTWN_NOISE_FLOOR;
+		tap->wr_tsft = htole64(rxs.c_rx_tsf);
+		tap->wr_rate = rxs.c_rate;
+		tap->wr_dbm_antsignal = rssi;
+		tap->wr_dbm_antnoise = rxs.c_nf;
 	}
 
 	/* Drop PHY descriptor. */
diff --git a/sys/dev/rtwn/if_rtwn_rx.h b/sys/dev/rtwn/if_rtwn_rx.h
index dfdcc4bfe10..49897eb956b 100644
--- a/sys/dev/rtwn/if_rtwn_rx.h
+++ b/sys/dev/rtwn/if_rtwn_rx.h
@@ -26,7 +26,7 @@ void	rtwn_get_rates(struct rtwn_softc *, const struct ieee80211_rateset *,
 	    const struct ieee80211_htrateset *, uint32_t *, int *, int);
 void	rtwn_set_basicrates(struct rtwn_softc *, uint32_t);
 struct ieee80211_node *	rtwn_rx_common(struct rtwn_softc *, struct mbuf *,
-	    void *, int8_t *);
+	    void *);
 void	rtwn_adhoc_recv_mgmt(struct ieee80211_node *, struct mbuf *, int,
 	    const struct ieee80211_rx_stats *, int, int);
 void	rtwn_set_multi(struct rtwn_softc *);
diff --git a/sys/dev/rtwn/if_rtwnvar.h b/sys/dev/rtwn/if_rtwnvar.h
index 642cdbf2f89..e13cceea81a 100644
--- a/sys/dev/rtwn/if_rtwnvar.h
+++ b/sys/dev/rtwn/if_rtwnvar.h
@@ -76,6 +76,12 @@ struct rtwn_tx_buf {
 	uint8_t		txd[RTWN_TX_DESC_SIZE];
 } __attribute__((aligned(4)));
 
+#define RTWN_PHY_STATUS_SIZE	32
+struct rtwn_tx_phystat {
+	uint32_t	phydw[RTWN_PHY_STATUS_SIZE / sizeof(uint32_t)];
+};
+
+
 struct rtwn_softc;
 
 union sec_param {
@@ -95,7 +101,8 @@ struct rtwn_cmdq {
 struct rtwn_node {
 	struct ieee80211_node	ni;	/* must be the first */
 	int			id;
-	int8_t			last_rssi;
+
+	struct rtwn_tx_phystat	last_physt;
 	int			avg_pwdb;
 };
 #define RTWN_NODE(ni)		((struct rtwn_node *)(ni))
@@ -195,7 +202,7 @@ struct rtwn_softc {
 	const char		*name;
 	int			sc_ant;
 
-	int8_t			last_rssi;
+	struct rtwn_tx_phystat	last_physt;
 	uint8_t			thcal_temp;
 	int			cur_bcnq_id;
 
@@ -336,6 +343,9 @@ struct rtwn_softc {
 			    struct ieee80211vap *, int);
 	void		(*sc_set_rssi)(struct rtwn_softc *);
 #endif
+	void		(*sc_get_rx_stats)(struct rtwn_softc *,
+			    struct ieee80211_rx_stats *, const void *,
+			    const void *);
 	int8_t		(*sc_get_rssi_cck)(struct rtwn_softc *, void *);
 	int8_t		(*sc_get_rssi_ofdm)(struct rtwn_softc *, void *);
 	int		(*sc_classify_intr)(struct rtwn_softc *, void *, int);
@@ -478,6 +488,8 @@ void	rtwn_suspend(struct rtwn_softc *);
 	(((_sc)->sc_parse_rom)((_sc), (_rom)))
 #define rtwn_set_led(_sc, _led, _on) \
 	(((_sc)->sc_set_led)((_sc), (_led), (_on)))
+#define rtwn_get_rx_stats(_sc, _rxs, _desc, _physt) \
+	(((_sc)->sc_get_rx_stats((_sc), (_rxs), (_desc), (_physt))))
 #define rtwn_get_rssi_cck(_sc, _physt) \
 	(((_sc)->sc_get_rssi_cck)((_sc), (_physt)))
 #define rtwn_get_rssi_ofdm(_sc, _physt) \
diff --git a/sys/dev/rtwn/pci/rtwn_pci_rx.c b/sys/dev/rtwn/pci/rtwn_pci_rx.c
index 00f7409efeb..e505a3cb554 100644
--- a/sys/dev/rtwn/pci/rtwn_pci_rx.c
+++ b/sys/dev/rtwn/pci/rtwn_pci_rx.c
@@ -95,7 +95,6 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc, struct r92ce_rx_stat *rx_desc,
 	struct ieee80211_node *ni;
 	uint32_t rxdw0;
 	struct mbuf *m, *m1;
-	int8_t rssi = 0, nf;
 	int infosz, pktlen, shift, error;
 
 	/* Dump Rx descriptor. */
@@ -162,12 +161,11 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc, struct r92ce_rx_stat *rx_desc,
 	rx_data->m = m1;
 	m->m_pkthdr.len = m->m_len = pktlen + infosz + shift;
 
-	nf = RTWN_NOISE_FLOOR;
-	ni = rtwn_rx_common(sc, m, rx_desc, &rssi);
+	ni = rtwn_rx_common(sc, m, rx_desc);
 
 	RTWN_DPRINTF(sc, RTWN_DEBUG_RECV,
-	    "%s: Rx frame len %d, infosz %d, shift %d, rssi %d\n",
-	    __func__, pktlen, infosz, shift, rssi);
+	    "%s: Rx frame len %d, infosz %d, shift %d\n",
+	    __func__, pktlen, infosz, shift);
 
 	/* Update RX descriptor. */
 	rtwn_pci_setup_rx_desc(pc, rx_desc, rx_data->paddr, MJUMPAGESIZE,
@@ -176,11 +174,11 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc, struct r92ce_rx_stat *rx_desc,
 	/* Send the frame to the 802.11 layer. */
 	RTWN_UNLOCK(sc);
 	if (ni != NULL) {
-		(void)ieee80211_input(ni, m, rssi - nf, nf);
+		(void)ieee80211_input_mimo(ni, m);
 		/* Node is no longer needed. */
 		ieee80211_free_node(ni);
 	} else
-		(void)ieee80211_input_all(ic, m, rssi - nf, nf);
+		(void)ieee80211_input_mimo_all(ic, m);
 
 	RTWN_LOCK(sc);
 
diff --git a/sys/dev/rtwn/rtl8188e/r88e.h b/sys/dev/rtwn/rtl8188e/r88e.h
index 999ab400575..1c03ddd3182 100644
--- a/sys/dev/rtwn/rtl8188e/r88e.h
+++ b/sys/dev/rtwn/rtl8188e/r88e.h
@@ -85,6 +85,8 @@ void	r88e_ratectl_tx_complete(struct rtwn_softc *, uint8_t *, int);
 void	r88e_handle_c2h_report(struct rtwn_softc *, uint8_t *, int);
 int8_t	r88e_get_rssi_cck(struct rtwn_softc *, void *);
 int8_t	r88e_get_rssi_ofdm(struct rtwn_softc *, void *);
+void	r88e_get_rx_stats(struct rtwn_softc *, struct ieee80211_rx_stats *,
+	    const void *, const void *);
 
 /* r88e_tx.c */
 void	r88e_tx_enable_ampdu(void *, int);
diff --git a/sys/dev/rtwn/rtl8188e/r88e_rx.c b/sys/dev/rtwn/rtl8188e/r88e_rx.c
index 3f31393deb7..da60046aa6a 100644
--- a/sys/dev/rtwn/rtl8188e/r88e_rx.c
+++ b/sys/dev/rtwn/rtl8188e/r88e_rx.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
+#include 
 #include 
 #include 
 
@@ -209,3 +210,19 @@ r88e_get_rssi_ofdm(struct rtwn_softc *sc, void *physt)
 
 	return (rssi);
 }
+
+void
+r88e_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
+    const void *desc, const void *physt_ptr)
+{
+	const struct r88e_rx_phystat *physt = physt_ptr;
+
+	r92c_get_rx_stats(sc, rxs, desc, physt_ptr);
+
+	if (!sc->sc_ht40) {	/* XXX center channel */
+		rxs->r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ;
+		rxs->c_ieee = le16toh(physt->chan);
+		rxs->c_freq = ieee80211_ieee2mhz(rxs->c_ieee,
+		    IEEE80211_CHAN_2GHZ);
+	}
+}
diff --git a/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c b/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
index 33a5aaf93a0..bcdb3c5b508 100644
--- a/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
+++ b/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
@@ -127,6 +127,7 @@ r88eu_attach(struct rtwn_usb_softc *uc)
 	sc->sc_dump_tx_desc		= r92cu_dump_tx_desc;
 	sc->sc_tx_radiotap_flags	= r92c_tx_radiotap_flags;
 	sc->sc_rx_radiotap_flags	= r92c_rx_radiotap_flags;
+	sc->sc_get_rx_stats		= r88e_get_rx_stats;
 	sc->sc_get_rssi_cck		= r88e_get_rssi_cck;
 	sc->sc_get_rssi_ofdm		= r88e_get_rssi_ofdm;
 	sc->sc_classify_intr		= r88eu_classify_intr;
diff --git a/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c b/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
index f38782fced6..de5ef61888a 100644
--- a/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
+++ b/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
@@ -172,6 +172,7 @@ r92ce_attach(struct rtwn_pci_softc *pc)
 	sc->sc_dump_tx_desc		= r92ce_dump_tx_desc;
 	sc->sc_tx_radiotap_flags	= r92c_tx_radiotap_flags;
 	sc->sc_rx_radiotap_flags	= r92c_rx_radiotap_flags;
+	sc->sc_get_rx_stats		= r92c_get_rx_stats;
 	sc->sc_get_rssi_cck		= r92c_get_rssi_cck;
 	sc->sc_get_rssi_ofdm		= r92c_get_rssi_ofdm;
 	sc->sc_classify_intr		= r92ce_classify_intr;
diff --git a/sys/dev/rtwn/rtl8192c/r92c.h b/sys/dev/rtwn/rtl8192c/r92c.h
index 2b63179e79a..b88b941dada 100644
--- a/sys/dev/rtwn/rtl8192c/r92c.h
+++ b/sys/dev/rtwn/rtl8192c/r92c.h
@@ -99,6 +99,8 @@ void	r92c_parse_rom(struct rtwn_softc *, uint8_t *);
 int8_t	r92c_get_rssi_cck(struct rtwn_softc *, void *);
 int8_t	r92c_get_rssi_ofdm(struct rtwn_softc *, void *);
 uint8_t	r92c_rx_radiotap_flags(const void *);
+void	r92c_get_rx_stats(struct rtwn_softc *, struct ieee80211_rx_stats *,
+	    const void *, const void *);
 
 /* r92c_tx.c */
 void	r92c_tx_enable_ampdu(void *, int);
diff --git a/sys/dev/rtwn/rtl8192c/r92c_reg.h b/sys/dev/rtwn/rtl8192c/r92c_reg.h
index ff03d191b4e..de39a0ff8f9 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_reg.h
+++ b/sys/dev/rtwn/rtl8192c/r92c_reg.h
@@ -420,6 +420,7 @@
 #define R92C_PBP_1024		4
 
 /* Bits for R92C_TRXDMA_CTRL. */
+#define R92C_TRXDMA_CTRL_RX_SHIFT_EN		0x0002
 #define R92C_TRXDMA_CTRL_RXDMA_AGG_EN		0x0004
 #define R92C_TRXDMA_CTRL_TXDMA_VOQ_MAP_M	0x0030
 #define R92C_TRXDMA_CTRL_TXDMA_VOQ_MAP_S	4
@@ -593,7 +594,8 @@
 #define R92C_RCR_APPFCS		0x80000000
 
 /* Bits for R92C_RX_DRVINFO_SZ. */
-#define R92C_RX_DRVINFO_SZ_DEF	4	/* XXX other values will not work */
+/* XXX other values will not work */
+#define R92C_RX_DRVINFO_SZ_DEF	((RTWN_PHY_STATUS_SIZE) / 8)
 
 /* Bits for R92C_WMAC_TRXPTCL_CTL. */
 #define R92C_WMAC_TRXPTCL_SHPRE	0x00020000
diff --git a/sys/dev/rtwn/rtl8192c/r92c_rx.c b/sys/dev/rtwn/rtl8192c/r92c_rx.c
index aa9da3ebc5a..d1fdf531239 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_rx.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_rx.c
@@ -100,3 +100,47 @@ r92c_rx_radiotap_flags(const void *buf)
 		flags = IEEE80211_RADIOTAP_F_SHORTGI;
 	return (flags);
 }
+
+void
+r92c_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
+    const void *desc, const void *physt_ptr)
+{
+	const struct r92c_rx_stat *stat = desc;
+	uint32_t rxdw1, rxdw3;
+	uint8_t rate;
+
+	rxdw1 = le32toh(stat->rxdw1);
+	rxdw3 = le32toh(stat->rxdw3);
+	rate = MS(rxdw3, R92C_RXDW3_RATE);
+
+	if (rxdw1 & R92C_RXDW1_AMPDU)
+		rxs->c_pktflags |= IEEE80211_RX_F_AMPDU;
+	else if (rxdw1 & R92C_RXDW1_AMPDU_MORE)
+		rxs->c_pktflags |= IEEE80211_RX_F_AMPDU_MORE;
+	if ((rxdw3 & R92C_RXDW3_SPLCP) && rate >= RTWN_RIDX_MCS(0))
+		rxs->c_pktflags |= IEEE80211_RX_F_SHORTGI;
+
+	if (rxdw3 & R92C_RXDW3_HT40)
+		rxs->c_width = IEEE80211_RX_FW_40MHZ;
+	else
+		rxs->c_width = IEEE80211_RX_FW_20MHZ;
+
+	if (RTWN_RATE_IS_CCK(rate))
+		rxs->c_phytype = IEEE80211_RX_FP_11B;
+	else if (rate < RTWN_RIDX_MCS(0))
+		rxs->c_phytype = IEEE80211_RX_FP_11G;
+	else
+		rxs->c_phytype = IEEE80211_RX_FP_11NG;
+
+	/* Map HW rate index to 802.11 rate. */
+	if (rate < RTWN_RIDX_MCS(0)) {
+		rxs->c_rate = ridx2rate[rate];
+		if (RTWN_RATE_IS_CCK(rate))
+			rxs->c_pktflags |= IEEE80211_RX_F_CCK;
+		else
+			rxs->c_pktflags |= IEEE80211_RX_F_OFDM;
+	} else {	/* MCS0~15. */
+		rxs->c_rate = IEEE80211_RATE_MCS | (rate - 12);
+		rxs->c_pktflags |= IEEE80211_RX_F_HT;
+	}
+}
diff --git a/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h b/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h
index 7fec70bec0c..12dfd6656e4 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h
+++ b/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h
@@ -45,6 +45,9 @@ struct r92c_rx_stat {
 	uint32_t	rxdw1;
 #define R92C_RXDW1_MACID_M	0x0000001f
 #define R92C_RXDW1_MACID_S	0
+#define R92C_RXDW1_AMSDU	0x00002000
+#define R92C_RXDW1_AMPDU_MORE	0x00004000
+#define R92C_RXDW1_AMPDU	0x00008000
 #define R92C_RXDW1_MC		0x40000000
 #define R92C_RXDW1_BC		0x80000000
 
@@ -56,6 +59,8 @@ struct r92c_rx_stat {
 #define R92C_RXDW3_SPLCP	0x00000100
 #define R92C_RXDW3_HT40		0x00000200
 #define R92C_RXDW3_HTC		0x00000400
+#define R92C_RXDW3_BSSID_FIT_M	0x00003000
+#define R92C_RXDW3_BSSID_FIT_S	12
 
 	uint32_t	rxdw4;
 	uint32_t	tsf_low;
diff --git a/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c b/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
index c15d1e2a034..88522f6a53b 100644
--- a/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
+++ b/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
@@ -165,6 +165,7 @@ r92cu_attach(struct rtwn_usb_softc *uc)
 	sc->sc_dump_tx_desc		= r92cu_dump_tx_desc;
 	sc->sc_tx_radiotap_flags	= r92c_tx_radiotap_flags;
 	sc->sc_rx_radiotap_flags	= r92c_rx_radiotap_flags;
+	sc->sc_get_rx_stats		= r92c_get_rx_stats;
 	sc->sc_get_rssi_cck		= r92c_get_rssi_cck;
 	sc->sc_get_rssi_ofdm		= r92c_get_rssi_ofdm;
 	sc->sc_classify_intr		= r92cu_classify_intr;
diff --git a/sys/dev/rtwn/rtl8812a/r12a.h b/sys/dev/rtwn/rtl8812a/r12a.h
index ec1d61e1e33..e8de45aa9da 100644
--- a/sys/dev/rtwn/rtl8812a/r12a.h
+++ b/sys/dev/rtwn/rtl8812a/r12a.h
@@ -128,6 +128,8 @@ void	r12a_ratectl_tx_complete(struct rtwn_softc *, uint8_t *, int);
 void	r12a_handle_c2h_report(struct rtwn_softc *, uint8_t *, int);
 int	r12a_check_frame_checksum(struct rtwn_softc *, struct mbuf *);
 uint8_t	r12a_rx_radiotap_flags(const void *);
+void	r12a_get_rx_stats(struct rtwn_softc *, struct ieee80211_rx_stats *,
+	    const void *, const void *);
 
 /* r12a_tx.c */
 void	r12a_fill_tx_desc(struct rtwn_softc *, struct ieee80211_node *,
diff --git a/sys/dev/rtwn/rtl8812a/r12a_rx.c b/sys/dev/rtwn/rtl8812a/r12a_rx.c
index 319fcd58fb8..ba2ab9eca24 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_rx.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_rx.c
@@ -229,10 +229,99 @@ r12a_rx_radiotap_flags(const void *buf)
 
 	if (!(stat->rxdw4 & htole32(R12A_RXDW4_SPLCP)))
 		return (0);
-	rate = MS(le32toh(stat->rxdw3), R92C_RXDW3_RATE);
+	rate = MS(le32toh(stat->rxdw3), R12A_RXDW3_RATE);
 	if (RTWN_RATE_IS_CCK(rate))
 		flags = IEEE80211_RADIOTAP_F_SHORTPRE;
 	else
 		flags = IEEE80211_RADIOTAP_F_SHORTGI;
 	return (flags);
 }
+
+void
+r12a_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
+    const void *desc, const void *physt_ptr)
+{
+	const struct r92c_rx_stat *stat = desc;
+	const struct r12a_rx_phystat *physt = physt_ptr;
+	uint32_t rxdw0, rxdw1, rxdw3, rxdw4;
+	uint8_t rate;
+
+	rxdw0 = le32toh(stat->rxdw0);
+	rxdw1 = le32toh(stat->rxdw1);
+	rxdw3 = le32toh(stat->rxdw3);
+	rxdw4 = le32toh(stat->rxdw4);
+	rate = MS(rxdw3, R12A_RXDW3_RATE);
+
+	/* TODO: STBC */
+	if (rxdw4 & R12A_RXDW4_LDPC)
+		rxs->c_pktflags |= IEEE80211_RX_F_LDPC;
+	if (rxdw1 & R12A_RXDW1_AMPDU) {
+		if (rxdw0 & R92C_RXDW0_PHYST)
+			rxs->c_pktflags |= IEEE80211_RX_F_AMPDU;
+		else
+			rxs->c_pktflags |= IEEE80211_RX_F_AMPDU_MORE;
+	}
+
+	if ((rxdw4 & R12A_RXDW4_SPLCP) && rate >= RTWN_RIDX_MCS(0))
+		rxs->c_pktflags |= IEEE80211_RX_F_SHORTGI;
+
+	switch (MS(rxdw4, R12A_RXDW4_BW)) {
+	case R12A_RXDW4_BW20:
+		rxs->c_width = IEEE80211_RX_FW_20MHZ;
+		break;
+	case R12A_RXDW4_BW40:
+		rxs->c_width = IEEE80211_RX_FW_40MHZ;
+		break;
+	case R12A_RXDW4_BW80:
+		rxs->c_width = IEEE80211_RX_FW_80MHZ;
+		break;
+	default:
+		break;
+	}
+
+	if (RTWN_RATE_IS_CCK(rate))
+		rxs->c_phytype = IEEE80211_RX_FP_11B;
+	else {
+		int is5ghz;
+
+		/* XXX magic */
+		/* XXX check with RTL8812AU */
+		is5ghz = (physt->cfosho[2] != 0x01);
+
+		if (rate < RTWN_RIDX_MCS(0)) {
+			if (is5ghz)
+				rxs->c_phytype = IEEE80211_RX_FP_11A;
+			else
+				rxs->c_phytype = IEEE80211_RX_FP_11G;
+		} else {
+			if (is5ghz)
+				rxs->c_phytype = IEEE80211_RX_FP_11NA;
+			else
+				rxs->c_phytype = IEEE80211_RX_FP_11NG;
+		}
+	}
+
+	/* Map HW rate index to 802.11 rate. */
+	if (rate < RTWN_RIDX_MCS(0)) {
+		rxs->c_rate = ridx2rate[rate];
+		if (RTWN_RATE_IS_CCK(rate))
+			rxs->c_pktflags |= IEEE80211_RX_F_CCK;
+		else
+			rxs->c_pktflags |= IEEE80211_RX_F_OFDM;
+	} else {	/* MCS0~15. */
+		/* TODO: VHT rates */
+		rxs->c_rate = IEEE80211_RATE_MCS | (rate - 12);
+		rxs->c_pktflags |= IEEE80211_RX_F_HT;
+	}
+
+	/*
+	 * XXX always zero for RTL8821AU
+	 * (vendor driver does not check this field)
+	 */
+#if 0
+	rxs->r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ;
+	rxs->c_ieee = MS(le16toh(physt->phyw1), R12A_PHYW1_CHAN);
+	rxs->c_freq = ieee80211_ieee2mhz(rxs->c_ieee,
+	    (rxs->c_ieee < 36) ? IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ);
+#endif
+}
diff --git a/sys/dev/rtwn/rtl8812a/r12a_rx_desc.h b/sys/dev/rtwn/rtl8812a/r12a_rx_desc.h
index 8642ca85245..c3d19527dfb 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_rx_desc.h
+++ b/sys/dev/rtwn/rtl8812a/r12a_rx_desc.h
@@ -34,18 +34,26 @@
 /* Rx MAC descriptor defines (chip-specific). */
 /* Rx dword 1 */
 #define R12A_RXDW1_AMSDU	0x00002000
+#define R12A_RXDW1_AMPDU	0x00008000
 #define R12A_RXDW1_CKSUM_ERR	0x00100000
 #define R12A_RXDW1_IPV6		0x00200000
 #define R12A_RXDW1_UDP		0x00400000
 #define R12A_RXDW1_CKSUM	0x00800000
 /* Rx dword 2 */
 #define R12A_RXDW2_RPT_C2H	0x10000000
+/* Rx dword 3 */
+#define R12A_RXDW3_RATE_M	0x0000007f
+#define R12A_RXDW3_RATE_S	0
 /* Rx dword 4 */
 #define R12A_RXDW4_SPLCP	0x00000001
 #define R12A_RXDW4_LDPC		0x00000002
 #define R12A_RXDW4_STBC		0x00000004
 #define R12A_RXDW4_BW_M		0x00000030
 #define R12A_RXDW4_BW_S		4
+#define R12A_RXDW4_BW20		0
+#define R12A_RXDW4_BW40		1
+#define R12A_RXDW4_BW80		2
+#define R12A_RXDW4_BW160	3
 
 /* Rx PHY descriptor. */
 struct r12a_rx_phystat {
diff --git a/sys/dev/rtwn/rtl8812a/r12a_tx.c b/sys/dev/rtwn/rtl8812a/r12a_tx.c
index 3a286828a90..0f506241a19 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_tx.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_tx.c
@@ -214,6 +214,17 @@ r12a_tx_set_sgi(struct rtwn_softc *sc, void *buf, struct ieee80211_node *ni)
 		txd->txdw5 |= htole32(R12A_TXDW5_DATA_SHORT);
 }
 
+static void
+r12a_tx_set_ldpc(struct rtwn_softc *sc, struct r12a_tx_desc *txd,
+    struct ieee80211_node *ni)
+{
+	struct ieee80211vap *vap = ni->ni_vap;
+
+	if ((vap->iv_flags_ht & IEEE80211_FHT_LDPC_TX) &&
+	    (ni->ni_htcap & IEEE80211_HTCAP_LDPC))
+		txd->txdw5 |= htole32(R12A_TXDW5_DATA_LDPC);
+}
+
 void
 r12a_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni,
     struct mbuf *m, void *buf, uint8_t ridx, int maxretry)
@@ -284,6 +295,7 @@ r12a_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni,
 			if (ridx >= RTWN_RIDX_MCS(0)) {
 				r12a_tx_set_ht40(sc, txd, ni);
 				r12a_tx_set_sgi(sc, txd, ni);
+				r12a_tx_set_ldpc(sc, txd, ni);
 				prot = ic->ic_htprotmode;
 			} else if (ic->ic_flags & IEEE80211_F_USEPROT)
 				prot = ic->ic_protmode;
diff --git a/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c b/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
index 855d2b0b7c8..7417098f8b3 100644
--- a/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
+++ b/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
@@ -168,7 +168,15 @@ r12a_read_chipid_vendor(struct rtwn_softc *sc, uint32_t reg_sys_cfg)
 static void
 r12au_adj_devcaps(struct rtwn_softc *sc)
 {
-	/* TODO: LDPC, STBC etc */
+	struct r12a_softc *rs = sc->sc_priv;
+	struct ieee80211com *ic = &sc->sc_ic;
+
+	if (rs->chip & R12A_CHIP_C_CUT) {
+		ic->ic_htcaps |= IEEE80211_HTCAP_LDPC |
+				 IEEE80211_HTC_TXLDPC;
+	}
+
+	/* TODO: STBC, VHT etc */
 }
 
 void
@@ -190,6 +198,7 @@ r12au_attach(struct rtwn_usb_softc *uc)
 	sc->sc_dump_tx_desc		= r12au_dump_tx_desc;
 	sc->sc_tx_radiotap_flags	= r12a_tx_radiotap_flags;
 	sc->sc_rx_radiotap_flags	= r12a_rx_radiotap_flags;
+	sc->sc_get_rx_stats		= r12a_get_rx_stats;
 	sc->sc_get_rssi_cck		= r88e_get_rssi_cck;
 	sc->sc_get_rssi_ofdm		= r88e_get_rssi_ofdm;
 	sc->sc_classify_intr		= r12au_classify_intr;
diff --git a/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c b/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c
index 6382c85916e..952296978a8 100644
--- a/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c
+++ b/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c
@@ -157,10 +157,11 @@ r21au_adj_devcaps(struct rtwn_softc *sc)
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct r12a_softc *rs = sc->sc_priv;
 
+	ic->ic_htcaps |= IEEE80211_HTC_TXLDPC;
 	if (rs->rs_radar != 0)
 		ic->ic_caps |= IEEE80211_C_DFS;
 
-	/* TODO: LDPC etc */
+	/* TODO: VHT */
 }
 
 void
@@ -182,6 +183,7 @@ r21au_attach(struct rtwn_usb_softc *uc)
 	sc->sc_dump_tx_desc		= r12au_dump_tx_desc;
 	sc->sc_tx_radiotap_flags	= r12a_tx_radiotap_flags;
 	sc->sc_rx_radiotap_flags	= r12a_rx_radiotap_flags;
+	sc->sc_get_rx_stats		= r12a_get_rx_stats;
 	sc->sc_get_rssi_cck		= r21a_get_rssi_cck;
 	sc->sc_get_rssi_ofdm		= r88e_get_rssi_ofdm;
 	sc->sc_classify_intr		= r12au_classify_intr;
diff --git a/sys/dev/rtwn/usb/rtwn_usb_rx.c b/sys/dev/rtwn/usb/rtwn_usb_rx.c
index 1a8345933ee..63842222ff7 100644
--- a/sys/dev/rtwn/usb/rtwn_usb_rx.c
+++ b/sys/dev/rtwn/usb/rtwn_usb_rx.c
@@ -236,7 +236,7 @@ rtwn_report_intr(struct rtwn_usb_softc *uc, struct usb_xfer *xfer,
 }
 
 static struct ieee80211_node *
-rtwn_rx_frame(struct rtwn_softc *sc, struct mbuf *m, int8_t *rssi)
+rtwn_rx_frame(struct rtwn_softc *sc, struct mbuf *m)
 {
 	struct r92c_rx_stat stat;
 
@@ -244,7 +244,7 @@ rtwn_rx_frame(struct rtwn_softc *sc, struct mbuf *m, int8_t *rssi)
 	m_copydata(m, 0, sizeof(struct r92c_rx_stat), (caddr_t)&stat);
 	m_adj(m, sizeof(struct r92c_rx_stat));
 
-	return (rtwn_rx_common(sc, m, &stat, rssi));
+	return (rtwn_rx_common(sc, m, &stat));
 }
 
 void
@@ -256,7 +256,6 @@ rtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
 	struct ieee80211_node *ni;
 	struct mbuf *m = NULL, *next;
 	struct rtwn_data *data;
-	int8_t nf, rssi;
 
 	RTWN_ASSERT_LOCKED(sc);
 
@@ -291,19 +290,15 @@ tr_setup:
 			next = m->m_next;
 			m->m_next = NULL;
 
-			ni = rtwn_rx_frame(sc, m, &rssi);
+			ni = rtwn_rx_frame(sc, m);
 
 			RTWN_UNLOCK(sc);
 
-			nf = RTWN_NOISE_FLOOR;
 			if (ni != NULL) {
-				if (ni->ni_flags & IEEE80211_NODE_HT)
-					m->m_flags |= M_AMPDU;
-				(void)ieee80211_input(ni, m, rssi - nf, nf);
+				(void)ieee80211_input_mimo(ni, m);
 				ieee80211_free_node(ni);
 			} else {
-				(void)ieee80211_input_all(ic, m,
-				    rssi - nf, nf);
+				(void)ieee80211_input_mimo_all(ic, m);
 			}
 			RTWN_LOCK(sc);
 			m = next;
diff --git a/sys/dev/sdhci/sdhci_fdt_gpio.c b/sys/dev/sdhci/sdhci_fdt_gpio.c
index 9935f17c66a..be9f629aacf 100644
--- a/sys/dev/sdhci/sdhci_fdt_gpio.c
+++ b/sys/dev/sdhci/sdhci_fdt_gpio.c
@@ -90,7 +90,7 @@ cd_setup(struct sdhci_fdt_gpio *gpio, phandle_t node)
 		gpio->slot->opt |= SDHCI_NON_REMOVABLE;
 		gpio->cd_disabled = true;
 		if (bootverbose)
-			device_printf(dev, "Non-removable media");
+			device_printf(dev, "Non-removable media\n");
 		return;
 	}
 
@@ -177,8 +177,12 @@ wp_setup(struct sdhci_fdt_gpio *gpio, phandle_t node)
 
 	dev = gpio->dev;
 
-	if (OF_hasprop(node, "wp-disable"))
+	if (OF_hasprop(node, "wp-disable")) {
+		gpio->wp_disabled = true;
+		if (bootverbose)
+			device_printf(dev, "Write protect disabled\n");
 		return;
+	}
 
 	if (gpio_pin_get_by_ofw_property(dev, node, "wp-gpios", &gpio->wp_pin))
 		return;
diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c
index fcffbe522df..ac83d65f5a4 100644
--- a/sys/dev/sound/usb/uaudio.c
+++ b/sys/dev/sound/usb/uaudio.c
@@ -337,6 +337,11 @@ struct uaudio_hid {
 	uint8_t mute_id;
 };
 
+#define	UAUDIO_SPDIF_OUT	0x01	/* Enable S/PDIF output */
+#define	UAUDIO_SPDIF_OUT_48K	0x02	/* Out sample rate = 48K */
+#define	UAUDIO_SPDIF_OUT_96K	0x04	/* Out sample rate = 96K */
+#define	UAUDIO_SPDIF_IN_MIX	0x10	/* Input mix enable */
+
 struct uaudio_softc {
 	struct sbuf sc_sndstat;
 	struct sndcard_func sc_sndcard_func;
@@ -354,6 +359,7 @@ struct uaudio_softc {
 	struct usb_xfer *sc_mixer_xfer[1];
 	struct uaudio_mixer_node *sc_mixer_root;
 	struct uaudio_mixer_node *sc_mixer_curr;
+	int     (*sc_set_spdif_fn) (struct uaudio_softc *, int);
 
 	uint32_t sc_mix_info;
 	uint32_t sc_recsrc_info;
@@ -885,6 +891,46 @@ uaudio_probe(device_t dev)
 	return (ENXIO);
 }
 
+/*
+ * Set Cmedia CM6206 S/PDIF settings
+ * Source: CM6206 Datasheet v2.3.
+ */
+static int
+uaudio_set_spdif_cm6206(struct uaudio_softc *sc, int flags)
+{
+	uint8_t cmd[2][4] = {
+		{0x20, 0x20, 0x00, 0},
+		{0x20, 0x30, 0x02, 1}
+	};
+	int i;
+
+	if (flags & UAUDIO_SPDIF_OUT)
+		cmd[1][1] = 0x00;
+	else
+		cmd[1][1] = 0x02;
+
+	if (flags & UAUDIO_SPDIF_OUT_96K)
+		cmd[0][1] = 0x60;	/* 96K: 3'b110 */
+
+	if (flags & UAUDIO_SPDIF_IN_MIX)
+		cmd[1][1] = 0x03;	/* SPDIFMIX */
+
+	for (i = 0; i < 2; i++) {
+		if (usbd_req_set_report(sc->sc_udev, NULL,
+		    cmd[i], sizeof(cmd[0]),
+		    sc->sc_mixer_iface_index, UHID_OUTPUT_REPORT, 0) != 0) {
+			return (ENXIO);
+		}
+	}
+	return (0);
+}
+
+static int
+uaudio_set_spdif_dummy(struct uaudio_softc *sc, int flags)
+{
+	return (0);
+}
+
 static int
 uaudio_attach(device_t dev)
 {
@@ -919,6 +965,12 @@ uaudio_attach(device_t dev)
 	if (usb_test_quirk(uaa, UQ_AU_VENDOR_CLASS))
 		sc->sc_uq_au_vendor_class = 1;
 
+	/* set S/PDIF function */
+	if (usb_test_quirk(uaa, UQ_AU_SET_SPDIF_CM6206))
+		sc->sc_set_spdif_fn = uaudio_set_spdif_cm6206;
+	else
+		sc->sc_set_spdif_fn = uaudio_set_spdif_dummy;
+
 	umidi_init(dev);
 
 	device_set_usb_desc(dev);
@@ -1055,6 +1107,11 @@ uaudio_attach(device_t dev)
 	/* reload all mixer settings */
 	uaudio_mixer_reload_all(sc);
 
+	/* enable S/PDIF output, if any */
+	if (sc->sc_set_spdif_fn(sc,
+	    UAUDIO_SPDIF_OUT | UAUDIO_SPDIF_OUT_48K) != 0) {
+		device_printf(dev, "Failed to enable S/PDIF at 48K\n");
+	}
 	return (0);			/* success */
 
 detach:
@@ -1139,6 +1196,9 @@ uaudio_detach_sub(device_t dev)
 	struct uaudio_softc *sc = device_get_softc(device_get_parent(dev));
 	int error = 0;
 
+	/* disable S/PDIF output, if any */
+	(void) sc->sc_set_spdif_fn(sc, 0);
+
 repeat:
 	if (sc->sc_pcm_registered) {
 		error = pcm_unregister(dev);
diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c
index c403b4ba45a..b773c28a20b 100644
--- a/sys/dev/usb/controller/xhci.c
+++ b/sys/dev/usb/controller/xhci.c
@@ -347,6 +347,7 @@ xhci_start_controller(struct xhci_softc *sc)
 	struct usb_page_search buf_res;
 	struct xhci_hw_root *phwr;
 	struct xhci_dev_ctx_addr *pdctxa;
+	usb_error_t err;
 	uint64_t addr;
 	uint32_t temp;
 	uint16_t i;
@@ -358,22 +359,9 @@ xhci_start_controller(struct xhci_softc *sc)
 	sc->sc_command_ccs = 1;
 	sc->sc_command_idx = 0;
 
-	/* Reset controller */
-	XWRITE4(sc, oper, XHCI_USBCMD, XHCI_CMD_HCRST);
-
-	for (i = 0; i != 100; i++) {
-		usb_pause_mtx(NULL, hz / 100);
-		temp = (XREAD4(sc, oper, XHCI_USBCMD) & XHCI_CMD_HCRST) |
-		    (XREAD4(sc, oper, XHCI_USBSTS) & XHCI_STS_CNR);
-		if (!temp)
-			break;
-	}
-
-	if (temp) {
-		device_printf(sc->sc_bus.parent, "Controller "
-		    "reset timeout.\n");
-		return (USB_ERR_IOERROR);
-	}
+	err = xhci_reset_controller(sc);
+	if (err)
+		return (err);
 
 	/* set up number of device slots */
 	DPRINTF("CONFIG=0x%08x -> 0x%08x\n",
@@ -520,6 +508,33 @@ xhci_halt_controller(struct xhci_softc *sc)
 	return (0);
 }
 
+usb_error_t
+xhci_reset_controller(struct xhci_softc *sc)
+{
+	uint32_t temp = 0;
+	uint16_t i;
+
+	DPRINTF("\n");
+
+	/* Reset controller */
+	XWRITE4(sc, oper, XHCI_USBCMD, XHCI_CMD_HCRST);
+
+	for (i = 0; i != 100; i++) {
+		usb_pause_mtx(NULL, hz / 100);
+		temp = (XREAD4(sc, oper, XHCI_USBCMD) & XHCI_CMD_HCRST) |
+		    (XREAD4(sc, oper, XHCI_USBSTS) & XHCI_STS_CNR);
+		if (!temp)
+			break;
+	}
+
+	if (temp) {
+		device_printf(sc->sc_bus.parent, "Controller "
+		    "reset timeout.\n");
+		return (USB_ERR_IOERROR);
+	}
+	return (0);
+}
+
 usb_error_t
 xhci_init(struct xhci_softc *sc, device_t self, uint8_t dma32)
 {
@@ -671,10 +686,12 @@ xhci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
 	case USB_HW_POWER_SUSPEND:
 		DPRINTF("Stopping the XHCI\n");
 		xhci_halt_controller(sc);
+		xhci_reset_controller(sc);
 		break;
 	case USB_HW_POWER_SHUTDOWN:
 		DPRINTF("Stopping the XHCI\n");
 		xhci_halt_controller(sc);
+		xhci_reset_controller(sc);
 		break;
 	case USB_HW_POWER_RESUME:
 		DPRINTF("Starting the XHCI\n");
diff --git a/sys/dev/usb/controller/xhci.h b/sys/dev/usb/controller/xhci.h
index e8bc9addb6f..8ca628580c9 100644
--- a/sys/dev/usb/controller/xhci.h
+++ b/sys/dev/usb/controller/xhci.h
@@ -525,6 +525,7 @@ struct xhci_softc {
 
 uint8_t 	xhci_use_polling(void);
 usb_error_t xhci_halt_controller(struct xhci_softc *);
+usb_error_t xhci_reset_controller(struct xhci_softc *);
 usb_error_t xhci_init(struct xhci_softc *, device_t, uint8_t);
 usb_error_t xhci_start_controller(struct xhci_softc *);
 void	xhci_interrupt(struct xhci_softc *);
diff --git a/sys/dev/usb/controller/xhci_pci.c b/sys/dev/usb/controller/xhci_pci.c
index cb0f3dafef5..cada25ad500 100644
--- a/sys/dev/usb/controller/xhci_pci.c
+++ b/sys/dev/usb/controller/xhci_pci.c
@@ -348,6 +348,7 @@ xhci_pci_detach(device_t self)
 
 	usb_callout_drain(&sc->sc_callout);
 	xhci_halt_controller(sc);
+	xhci_reset_controller(sc);
 
 	pci_disable_busmaster(self);
 
diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
index 1c253585f40..ae915f98186 100644
--- a/sys/dev/usb/quirk/usb_quirk.c
+++ b/sys/dev/usb/quirk/usb_quirk.c
@@ -519,6 +519,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	/* Non-standard USB AUDIO devices */
 	USB_QUIRK(MAUDIO, FASTTRACKULTRA, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS),
 	USB_QUIRK(MAUDIO, FASTTRACKULTRA8R, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS),
+	USB_QUIRK(CMEDIA, CM6206, 0x0000, 0xffff, UQ_AU_SET_SPDIF_CM6206),
 
 	/*
 	 * Quirks for manufacturers which USB devices does not respond
@@ -605,6 +606,7 @@ static const char *usb_quirk_str[USB_QUIRK_MAX] = {
 	[UQ_AU_VENDOR_CLASS]		= "UQ_AU_VENDOR_CLASS",
 	[UQ_SINGLE_CMD_MIDI]		= "UQ_SINGLE_CMD_MIDI",
 	[UQ_MSC_DYMO_EJECT]		= "UQ_MSC_DYMO_EJECT",
+	[UQ_AU_SET_SPDIF_CM6206]	= "UQ_AU_SET_SPDIF_CM6206",
 };
 
 /*------------------------------------------------------------------------*
diff --git a/sys/dev/usb/quirk/usb_quirk.h b/sys/dev/usb/quirk/usb_quirk.h
index 7010916c42a..f7e490ceb6b 100644
--- a/sys/dev/usb/quirk/usb_quirk.h
+++ b/sys/dev/usb/quirk/usb_quirk.h
@@ -109,6 +109,7 @@ enum {
 	UQ_AU_VENDOR_CLASS,	/* audio device uses vendor and not audio class */
 	UQ_SINGLE_CMD_MIDI,	/* at most one command per USB packet */
 	UQ_MSC_DYMO_EJECT,	/* ejects Dymo MSC device */
+	UQ_AU_SET_SPDIF_CM6206,	/* enable S/PDIF audio output */
 
 	USB_QUIRK_MAX
 };
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 797077e16f8..d3b81b7f730 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -1443,6 +1443,9 @@ product CLIPSAL 5000CT2		0x0304	5000CT2 C-Bus Touch Screen
 product CLIPSAL C5000CT2	0x0305	C5000CT2 C-Bus Touch Screen
 product CLIPSAL L51xx		0x0401	L51xx C-Bus Dimmer
 
+/* C-Media products */
+product CMEDIA CM6206		0x0102	CM106 compatible sound device
+
 /* CMOTECH products */
 product CMOTECH CNU510		0x5141	CDMA Technologies USB modem
 product CMOTECH CNU550		0x5543	CDMA 2000 1xRTT/1xEVDO USB modem
diff --git a/sys/fs/tmpfs/tmpfs.h b/sys/fs/tmpfs/tmpfs.h
index 8cd1c4b6dcd..37e5bbb62e3 100644
--- a/sys/fs/tmpfs/tmpfs.h
+++ b/sys/fs/tmpfs/tmpfs.h
@@ -80,8 +80,10 @@ struct tmpfs_dirent {
 	uint32_t			td_hash;
 	u_int				td_namelen;
 
-	/* Pointer to the node this entry refers to.  In case this field
-	 * is NULL, the node is a whiteout. */
+	/*
+	 * Pointer to the node this entry refers to.  In case this field
+	 * is NULL, the node is a whiteout.
+	 */
 	struct tmpfs_node *		td_node;
 
 	union {
@@ -94,21 +96,24 @@ struct tmpfs_dirent {
 	} ud;
 };
 
-/* A directory in tmpfs holds a list of directory entries, which in
- * turn point to other files (which can be directories themselves).
+/*
+ * A directory in tmpfs holds a collection of directory entries, which
+ * in turn point to other files (which can be directories themselves).
  *
- * In tmpfs, this list is managed by a RB-Tree, whose head is defined by
- * the struct tmpfs_dir type.
+ * In tmpfs, this collection is managed by a RB-Tree, whose head is
+ * defined by the struct tmpfs_dir type.
  *
  * It is important to notice that directories do not have entries for . and
  * .. as other file systems do.  These can be generated when requested
  * based on information available by other means, such as the pointer to
  * the node itself in the former case or the pointer to the parent directory
  * in the latter case.  This is done to simplify tmpfs's code and, more
- * importantly, to remove redundancy. */
+ * importantly, to remove redundancy.
+ */
 RB_HEAD(tmpfs_dir, tmpfs_dirent);
 
-/* Each entry in a directory has a cookie that identifies it.  Cookies
+/*
+ * Each entry in a directory has a cookie that identifies it.  Cookies
  * supersede offsets within directories because, given how tmpfs stores
  * directories in memory, there is no such thing as an offset.
  *
@@ -139,51 +144,67 @@ RB_HEAD(tmpfs_dir, tmpfs_dirent);
  * a particular type.  The code must be careful to only access those
  * attributes that are actually allowed by the node's type.
  *
- *
  * Below is the key of locks used to protected the fields in the following
  * structures.
- *
+ * (v)  vnode lock in exclusive mode
+ * (vi) vnode lock in exclusive mode, or vnode lock in shared vnode and
+ *	tn_interlock
+ * (i)  tn_interlock
+ * (m)  tmpfs_mount tm_allnode_lock
+ * (c)  stable after creation
  */
 struct tmpfs_node {
-	/* Doubly-linked list entry which links all existing nodes for a
-	 * single file system.  This is provided to ease the removal of
-	 * all nodes during the unmount operation. */
-	LIST_ENTRY(tmpfs_node)	tn_entries;
+	/*
+	 * Doubly-linked list entry which links all existing nodes for
+	 * a single file system.  This is provided to ease the removal
+	 * of all nodes during the unmount operation, and to support
+	 * the implementation of VOP_VNTOCNP().  tn_attached is false
+	 * when the node is removed from list and unlocked.
+	 */
+	LIST_ENTRY(tmpfs_node)	tn_entries;	/* (m) */
+	bool			tn_attached;	/* (m) */
 
-	/* The node's type.  Any of 'VBLK', 'VCHR', 'VDIR', 'VFIFO',
+	/*
+	 * The node's type.  Any of 'VBLK', 'VCHR', 'VDIR', 'VFIFO',
 	 * 'VLNK', 'VREG' and 'VSOCK' is allowed.  The usage of vnode
 	 * types instead of a custom enumeration is to make things simpler
-	 * and faster, as we do not need to convert between two types. */
-	enum vtype		tn_type;
+	 * and faster, as we do not need to convert between two types.
+	 */
+	enum vtype		tn_type;	/* (c) */
 
 	/* Node identifier. */
-	ino_t			tn_id;
+	ino_t			tn_id;		/* (c) */
 
-	/* Node's internal status.  This is used by several file system
+	/*
+	 * Node's internal status.  This is used by several file system
 	 * operations to do modifications to the node in a delayed
-	 * fashion. */
-	int			tn_status;
+	 * fashion.
+	 */
+	int			tn_status;	/* (vi) */
 #define	TMPFS_NODE_ACCESSED	(1 << 1)
 #define	TMPFS_NODE_MODIFIED	(1 << 2)
 #define	TMPFS_NODE_CHANGED	(1 << 3)
 
-	/* The node size.  It does not necessarily match the real amount
-	 * of memory consumed by it. */
-	off_t			tn_size;
+	/*
+	 * The node size.  It does not necessarily match the real amount
+	 * of memory consumed by it.
+	 */
+	off_t			tn_size;	/* (v) */
 
 	/* Generic node attributes. */
-	uid_t			tn_uid;
-	gid_t			tn_gid;
-	mode_t			tn_mode;
-	u_long			tn_flags;
-	nlink_t			tn_links;
-	struct timespec		tn_atime;
-	struct timespec		tn_mtime;
-	struct timespec		tn_ctime;
-	struct timespec		tn_birthtime;
-	unsigned long		tn_gen;
+	uid_t			tn_uid;		/* (v) */
+	gid_t			tn_gid;		/* (v) */
+	mode_t			tn_mode;	/* (v) */
+	u_long			tn_flags;	/* (v) */
+	nlink_t			tn_links;	/* (v) */
+	struct timespec		tn_atime;	/* (vi) */
+	struct timespec		tn_mtime;	/* (vi) */
+	struct timespec		tn_ctime;	/* (vi) */
+	struct timespec		tn_birthtime;	/* (v) */
+	unsigned long		tn_gen;		/* (c) */
 
-	/* As there is a single vnode for each active file within the
+	/*
+	 * As there is a single vnode for each active file within the
 	 * system, care has to be taken to avoid allocating more than one
 	 * vnode per file.  In order to do this, a bidirectional association
 	 * is kept between vnodes and nodes.
@@ -196,76 +217,84 @@ struct tmpfs_node {
 	 * tn_vnode.
 	 *
 	 * May be NULL when the node is unused (that is, no vnode has been
-	 * allocated for it or it has been reclaimed). */
-	struct vnode *		tn_vnode;
+	 * allocated for it or it has been reclaimed).
+	 */
+	struct vnode *		tn_vnode;	/* (i) */
 
-	/* Interlock to protect tn_vpstate, and tn_status under shared
+	/*
+	 * Interlock to protect tn_vpstate, and tn_status under shared
 	 * vnode lock.
 	 */
 	struct mtx	tn_interlock;
 
-	/* Identify if current node has vnode assiocate with
+	/*
+	 * Identify if current node has vnode assiocate with
 	 * or allocating vnode.
 	 */
-	int		tn_vpstate;
+	int		tn_vpstate;		/* (i) */
+
+	/* Transient refcounter on this node. */
+	u_int		tn_refcount;		/* (m) + (i) */
 
 	/* misc data field for different tn_type node */
 	union {
 		/* Valid when tn_type == VBLK || tn_type == VCHR. */
-		dev_t			tn_rdev;
+		dev_t			tn_rdev;	/* (c) */
 
 		/* Valid when tn_type == VDIR. */
 		struct tn_dir {
-			/* Pointer to the parent directory.  The root
+			/*
+			 * Pointer to the parent directory.  The root
 			 * directory has a pointer to itself in this field;
-			 * this property identifies the root node. */
+			 * this property identifies the root node.
+			 */
 			struct tmpfs_node *	tn_parent;
 
-			/* Head of a tree that links the contents of
-			 * the directory together. */
+			/*
+			 * Head of a tree that links the contents of
+			 * the directory together.
+			 */
 			struct tmpfs_dir	tn_dirhead;
 
-			/* Head of a list the contains fake directory entries
+			/*
+			 * Head of a list the contains fake directory entries
 			 * heads, i.e. entries with TMPFS_DIRCOOKIE_DUPHEAD
-			 * flag. */
+			 * flag.
+			 */
 			struct tmpfs_dir_duphead tn_dupindex;
 
-			/* Number and pointer of the first directory entry
+			/*
+			 * Number and pointer of the first directory entry
 			 * returned by the readdir operation if it were
 			 * called again to continue reading data from the
 			 * same directory as before.  This is used to speed
 			 * up reads of long directories, assuming that no
 			 * more than one read is in progress at a given time.
-			 * Otherwise, these values are discarded. */
+			 * Otherwise, these values are discarded.
+			 */
 			off_t			tn_readdir_lastn;
 			struct tmpfs_dirent *	tn_readdir_lastp;
 		} tn_dir;
 
 		/* Valid when tn_type == VLNK. */
 		/* The link's target, allocated from a string pool. */
-		char *			tn_link;
+		char *			tn_link;	/* (c) */
 
 		/* Valid when tn_type == VREG. */
 		struct tn_reg {
-			/* The contents of regular files stored in a tmpfs
-			 * file system are represented by a single anonymous
-			 * memory object (aobj, for short).  The aobj provides
-			 * direct access to any position within the file,
-			 * because its contents are always mapped in a
-			 * contiguous region of virtual memory.  It is a task
-			 * of the memory management subsystem (see uvm(9)) to
-			 * issue the required page ins or page outs whenever
-			 * a position within the file is accessed. */
-			vm_object_t		tn_aobj;
-
-		}tn_reg;
-
-		/* Valid when tn_type = VFIFO */
-		struct tn_fifo {
-			fo_rdwr_t		*tn_fo_read;
-			fo_rdwr_t		*tn_fo_write;
-		}tn_fifo;
-	}tn_spec;
+			/*
+			 * The contents of regular files stored in a
+			 * tmpfs file system are represented by a
+			 * single anonymous memory object (aobj, for
+			 * short).  The aobj provides direct access to
+			 * any position within the file.  It is a task
+			 * of the memory management subsystem to issue
+			 * the required page ins or page outs whenever
+			 * a position within the file is accessed.
+			 */
+			vm_object_t		tn_aobj;	/* (c) */
+		} tn_reg;
+	} tn_spec;	/* (v) */
 };
 LIST_HEAD(tmpfs_node_list, tmpfs_node);
 
@@ -283,21 +312,12 @@ LIST_HEAD(tmpfs_node_list, tmpfs_node);
 
 #ifdef INVARIANTS
 #define TMPFS_ASSERT_LOCKED(node) do {					\
-		MPASS(node != NULL);					\
-		MPASS(node->tn_vnode != NULL);				\
-		if (!VOP_ISLOCKED(node->tn_vnode) &&			\
-		    !mtx_owned(TMPFS_NODE_MTX(node)))			\
-			panic("tmpfs: node is not locked: %p", node);	\
-	} while (0)
-#define TMPFS_ASSERT_ELOCKED(node) do {					\
 		MPASS((node) != NULL);					\
 		MPASS((node)->tn_vnode != NULL);			\
-		mtx_assert(TMPFS_NODE_MTX(node), MA_OWNED);		\
-		ASSERT_VOP_LOCKED((node)->tn_vnode, "tmpfs");		\
+		ASSERT_VOP_LOCKED((node)->tn_vnode, "tmpfs assert");	\
 	} while (0)
 #else
 #define TMPFS_ASSERT_LOCKED(node) (void)0
-#define TMPFS_ASSERT_ELOCKED(node) (void)0
 #endif
 
 #define TMPFS_VNODE_ALLOCATING	1
@@ -309,26 +329,32 @@ LIST_HEAD(tmpfs_node_list, tmpfs_node);
  * Internal representation of a tmpfs mount point.
  */
 struct tmpfs_mount {
-	/* Maximum number of memory pages available for use by the file
+	/*
+	 * Maximum number of memory pages available for use by the file
 	 * system, set during mount time.  This variable must never be
 	 * used directly as it may be bigger than the current amount of
 	 * free memory; in the extreme case, it will hold the ULONG_MAX
-	 * value. */
+	 * value.
+	 */
 	u_long			tm_pages_max;
 
 	/* Number of pages in use by the file system. */
 	u_long			tm_pages_used;
 
-	/* Pointer to the node representing the root directory of this
-	 * file system. */
+	/*
+	 * Pointer to the node representing the root directory of this
+	 * file system.
+	 */
 	struct tmpfs_node *	tm_root;
 
-	/* Maximum number of possible nodes for this file system; set
+	/*
+	 * Maximum number of possible nodes for this file system; set
 	 * during mount time.  We need a hard limit on the maximum number
 	 * of nodes to avoid allocating too much of them; their objects
 	 * cannot be released until the file system is unmounted.
 	 * Otherwise, we could easily run out of memory by creating lots
-	 * of empty files and then simply removing them. */
+	 * of empty files and then simply removing them.
+	 */
 	ino_t			tm_nodes_max;
 
 	/* unrhdr used to allocate inode numbers */
@@ -337,38 +363,33 @@ struct tmpfs_mount {
 	/* Number of nodes currently that are in use. */
 	ino_t			tm_nodes_inuse;
 
+	/* Refcounter on this struct tmpfs_mount. */
+	uint64_t		tm_refcount;
+
 	/* maximum representable file size */
 	u_int64_t		tm_maxfilesize;
 
-	/* Nodes are organized in two different lists.  The used list
-	 * contains all nodes that are currently used by the file system;
-	 * i.e., they refer to existing files.  The available list contains
-	 * all nodes that are currently available for use by new files.
-	 * Nodes must be kept in this list (instead of deleting them)
-	 * because we need to keep track of their generation number (tn_gen
-	 * field).
-	 *
-	 * Note that nodes are lazily allocated: if the available list is
-	 * empty and we have enough space to create more nodes, they will be
-	 * created and inserted in the used list.  Once these are released,
-	 * they will go into the available list, remaining alive until the
-	 * file system is unmounted. */
+	/*
+	 * The used list contains all nodes that are currently used by
+	 * the file system; i.e., they refer to existing files.
+	 */
 	struct tmpfs_node_list	tm_nodes_used;
 
-	/* All node lock to protect the node list and tmp_pages_used */
-	struct mtx allnode_lock;
+	/* All node lock to protect the node list and tmp_pages_used. */
+	struct mtx		tm_allnode_lock;
 
-	/* Pools used to store file system meta data.  These are not shared
-	 * across several instances of tmpfs for the reasons described in
-	 * tmpfs_pool.c. */
+	/* Zones used to store file system meta data, per tmpfs mount. */
 	uma_zone_t		tm_dirent_pool;
 	uma_zone_t		tm_node_pool;
 
 	/* Read-only status. */
-	int			tm_ronly;
+	bool			tm_ronly;
+	/* Do not use namecache. */
+	bool			tm_nonc;
 };
-#define TMPFS_LOCK(tm) mtx_lock(&(tm)->allnode_lock)
-#define TMPFS_UNLOCK(tm) mtx_unlock(&(tm)->allnode_lock)
+#define	TMPFS_LOCK(tm) mtx_lock(&(tm)->tm_allnode_lock)
+#define	TMPFS_UNLOCK(tm) mtx_unlock(&(tm)->tm_allnode_lock)
+#define	TMPFS_MP_ASSERT_LOCKED(tm) mtx_assert(&(tm)->tm_allnode_lock, MA_OWNED)
 
 /*
  * This structure maps a file identifier to a tmpfs node.  Used by the
@@ -381,15 +402,24 @@ struct tmpfs_fid {
 	unsigned long		tf_gen;
 };
 
+struct tmpfs_dir_cursor {
+	struct tmpfs_dirent	*tdc_current;
+	struct tmpfs_dirent	*tdc_tree;
+};
+
 #ifdef _KERNEL
 /*
  * Prototypes for tmpfs_subr.c.
  */
 
+void	tmpfs_ref_node(struct tmpfs_node *node);
+void	tmpfs_ref_node_locked(struct tmpfs_node *node);
 int	tmpfs_alloc_node(struct mount *mp, struct tmpfs_mount *, enum vtype,
 	    uid_t uid, gid_t gid, mode_t mode, struct tmpfs_node *,
 	    char *, dev_t, struct tmpfs_node **);
 void	tmpfs_free_node(struct tmpfs_mount *, struct tmpfs_node *);
+bool	tmpfs_free_node_locked(struct tmpfs_mount *, struct tmpfs_node *, bool);
+void	tmpfs_free_tmp(struct tmpfs_mount *);
 int	tmpfs_alloc_dirent(struct tmpfs_mount *, struct tmpfs_node *,
 	    const char *, u_int, struct tmpfs_dirent **);
 void	tmpfs_free_dirent(struct tmpfs_mount *, struct tmpfs_dirent *);
@@ -425,6 +455,10 @@ void	tmpfs_itimes(struct vnode *, const struct timespec *,
 void	tmpfs_set_status(struct tmpfs_node *node, int status);
 void	tmpfs_update(struct vnode *);
 int	tmpfs_truncate(struct vnode *, off_t);
+struct tmpfs_dirent *tmpfs_dir_first(struct tmpfs_node *dnode,
+	    struct tmpfs_dir_cursor *dc);
+struct tmpfs_dirent *tmpfs_dir_next(struct tmpfs_node *dnode,
+	    struct tmpfs_dir_cursor *dc);
 
 /*
  * Convenience macros to simplify some logical expressions.
@@ -449,10 +483,6 @@ int	tmpfs_truncate(struct vnode *, off_t);
 	MPASS((node)->tn_size % sizeof(struct tmpfs_dirent) == 0); \
 } while (0)
 
-/*
- * Memory management stuff.
- */
-
 /*
  * Amount of memory pages to reserve for the system (e.g., to not use by
  * tmpfs).
@@ -470,37 +500,41 @@ size_t tmpfs_pages_used(struct tmpfs_mount *tmp);
  * specific ones.
  */
 
-static inline
-struct tmpfs_mount *
+static inline struct tmpfs_mount *
 VFS_TO_TMPFS(struct mount *mp)
 {
 	struct tmpfs_mount *tmp;
 
-	MPASS((mp) != NULL && (mp)->mnt_data != NULL);
-	tmp = (struct tmpfs_mount *)(mp)->mnt_data;
-	return tmp;
+	MPASS(mp != NULL && mp->mnt_data != NULL);
+	tmp = (struct tmpfs_mount *)mp->mnt_data;
+	return (tmp);
 }
 
-static inline
-struct tmpfs_node *
+static inline struct tmpfs_node *
 VP_TO_TMPFS_NODE(struct vnode *vp)
 {
 	struct tmpfs_node *node;
 
-	MPASS((vp) != NULL && (vp)->v_data != NULL);
+	MPASS(vp != NULL && vp->v_data != NULL);
 	node = (struct tmpfs_node *)vp->v_data;
-	return node;
+	return (node);
 }
 
-static inline
-struct tmpfs_node *
+static inline struct tmpfs_node *
 VP_TO_TMPFS_DIR(struct vnode *vp)
 {
 	struct tmpfs_node *node;
 
 	node = VP_TO_TMPFS_NODE(vp);
 	TMPFS_VALIDATE_DIR(node);
-	return node;
+	return (node);
+}
+
+static inline bool
+tmpfs_use_nc(struct vnode *vp)
+{
+
+	return (!(VFS_TO_TMPFS(vp->v_mount)->tm_nonc));
 }
 
 #endif /* _FS_TMPFS_TMPFS_H_ */
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index 0af55eccf8b..b04d28ba405 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -62,11 +62,6 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
-struct tmpfs_dir_cursor {
-	struct tmpfs_dirent	*tdc_current;
-	struct tmpfs_dirent	*tdc_tree;
-};
-
 SYSCTL_NODE(_vfs, OID_AUTO, tmpfs, CTLFLAG_RW, 0, "tmpfs file system");
 
 static long tmpfs_pages_reserved = TMPFS_PAGES_MINRESERVED;
@@ -136,6 +131,26 @@ tmpfs_pages_check_avail(struct tmpfs_mount *tmp, size_t req_pages)
 	return (1);
 }
 
+void
+tmpfs_ref_node(struct tmpfs_node *node)
+{
+
+	TMPFS_NODE_LOCK(node);
+	tmpfs_ref_node_locked(node);
+	TMPFS_NODE_UNLOCK(node);
+}
+
+void
+tmpfs_ref_node_locked(struct tmpfs_node *node)
+{
+
+	TMPFS_NODE_ASSERT_LOCKED(node);
+	KASSERT(node->tn_refcount > 0, ("node %p zero refcount", node));
+	KASSERT(node->tn_refcount < UINT_MAX, ("node %p refcount %u", node,
+	    node->tn_refcount));
+	node->tn_refcount++;
+}
+
 /*
  * Allocates a new node of type 'type' inside the 'tmp' mount point, with
  * its owner set to 'uid', its group to 'gid' and its mode set to 'mode',
@@ -198,8 +213,8 @@ tmpfs_alloc_node(struct mount *mp, struct tmpfs_mount *tmp, enum vtype type,
 		return (EBUSY);
 	}
 
-	nnode = (struct tmpfs_node *)uma_zalloc_arg(
-				tmp->tm_node_pool, tmp, M_WAITOK);
+	nnode = (struct tmpfs_node *)uma_zalloc_arg(tmp->tm_node_pool, tmp,
+	    M_WAITOK);
 
 	/* Generic initialization. */
 	nnode->tn_type = type;
@@ -210,6 +225,7 @@ tmpfs_alloc_node(struct mount *mp, struct tmpfs_mount *tmp, enum vtype type,
 	nnode->tn_gid = gid;
 	nnode->tn_mode = mode;
 	nnode->tn_id = alloc_unr(tmp->tm_ino_unr);
+	nnode->tn_refcount = 1;
 
 	/* Type-specific initialization. */
 	switch (nnode->tn_type) {
@@ -257,58 +273,65 @@ tmpfs_alloc_node(struct mount *mp, struct tmpfs_mount *tmp, enum vtype type,
 		break;
 
 	default:
-		panic("tmpfs_alloc_node: type %p %d", nnode, (int)nnode->tn_type);
+		panic("tmpfs_alloc_node: type %p %d", nnode,
+		    (int)nnode->tn_type);
 	}
 
 	TMPFS_LOCK(tmp);
 	LIST_INSERT_HEAD(&tmp->tm_nodes_used, nnode, tn_entries);
+	nnode->tn_attached = true;
 	tmp->tm_nodes_inuse++;
+	tmp->tm_refcount++;
 	TMPFS_UNLOCK(tmp);
 
 	*node = nnode;
-	return 0;
+	return (0);
 }
 
 /*
  * Destroys the node pointed to by node from the file system 'tmp'.
- * If the node does not belong to the given mount point, the results are
- * unpredicted.
- *
- * If the node references a directory; no entries are allowed because
- * their removal could need a recursive algorithm, something forbidden in
- * kernel space.  Furthermore, there is not need to provide such
- * functionality (recursive removal) because the only primitives offered
- * to the user are the removal of empty directories and the deletion of
- * individual files.
- *
- * Note that nodes are not really deleted; in fact, when a node has been
- * allocated, it cannot be deleted during the whole life of the file
- * system.  Instead, they are moved to the available list and remain there
- * until reused.
+ * If the node references a directory, no entries are allowed.
  */
 void
 tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node)
 {
-	vm_object_t uobj;
-
-#ifdef INVARIANTS
-	TMPFS_NODE_LOCK(node);
-	MPASS(node->tn_vnode == NULL);
-	MPASS((node->tn_vpstate & TMPFS_VNODE_ALLOCATING) == 0);
-	TMPFS_NODE_UNLOCK(node);
-#endif
 
 	TMPFS_LOCK(tmp);
-	LIST_REMOVE(node, tn_entries);
-	tmp->tm_nodes_inuse--;
+	TMPFS_NODE_LOCK(node);
+	if (!tmpfs_free_node_locked(tmp, node, false)) {
+		TMPFS_NODE_UNLOCK(node);
+		TMPFS_UNLOCK(tmp);
+	}
+}
+
+bool
+tmpfs_free_node_locked(struct tmpfs_mount *tmp, struct tmpfs_node *node,
+    bool detach)
+{
+	vm_object_t uobj;
+
+	TMPFS_MP_ASSERT_LOCKED(tmp);
+	TMPFS_NODE_ASSERT_LOCKED(node);
+	KASSERT(node->tn_refcount > 0, ("node %p refcount zero", node));
+
+	node->tn_refcount--;
+	if (node->tn_attached && (detach || node->tn_refcount == 0)) {
+		MPASS(tmp->tm_nodes_inuse > 0);
+		tmp->tm_nodes_inuse--;
+		LIST_REMOVE(node, tn_entries);
+		node->tn_attached = false;
+	}
+	if (node->tn_refcount > 0)
+		return (false);
+
+#ifdef INVARIANTS
+	MPASS(node->tn_vnode == NULL);
+	MPASS((node->tn_vpstate & TMPFS_VNODE_ALLOCATING) == 0);
+#endif
+	TMPFS_NODE_UNLOCK(node);
 	TMPFS_UNLOCK(tmp);
 
 	switch (node->tn_type) {
-	case VNON:
-		/* Do not do anything.  VNON is provided to let the
-		 * allocation routine clean itself easily by avoiding
-		 * duplicating code in it. */
-		/* FALLTHROUGH */
 	case VBLK:
 		/* FALLTHROUGH */
 	case VCHR:
@@ -340,6 +363,9 @@ tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node)
 
 	free_unr(tmp->tm_ino_unr, node->tn_id);
 	uma_zfree(tmp->tm_node_pool, node);
+	TMPFS_LOCK(tmp);
+	tmpfs_free_tmp(tmp);
+	return (true);
 }
 
 static __inline uint32_t
@@ -485,13 +511,16 @@ tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, int lkflag,
     struct vnode **vpp)
 {
 	struct vnode *vp;
+	struct tmpfs_mount *tm;
 	vm_object_t object;
 	int error;
 
 	error = 0;
-loop:
+	tm = VFS_TO_TMPFS(mp);
 	TMPFS_NODE_LOCK(node);
-loop1:
+	tmpfs_ref_node_locked(node);
+loop:
+	TMPFS_NODE_ASSERT_LOCKED(node);
 	if ((vp = node->tn_vnode) != NULL) {
 		MPASS((node->tn_vpstate & TMPFS_VNODE_DOOMED) == 0);
 		VI_LOCK(vp);
@@ -511,12 +540,14 @@ loop1:
 				msleep(&node->tn_vnode, TMPFS_NODE_MTX(node),
 				    0, "tmpfsE", 0);
 			}
-			goto loop1;
+			goto loop;
 		}
 		TMPFS_NODE_UNLOCK(node);
 		error = vget(vp, lkflag | LK_INTERLOCK, curthread);
-		if (error == ENOENT)
+		if (error == ENOENT) {
+			TMPFS_NODE_LOCK(node);
 			goto loop;
+		}
 		if (error != 0) {
 			vp = NULL;
 			goto out;
@@ -528,6 +559,7 @@ loop1:
 		 */
 		if (node->tn_vnode == NULL || node->tn_vnode != vp) {
 			vput(vp);
+			TMPFS_NODE_LOCK(node);
 			goto loop;
 		}
 
@@ -549,11 +581,9 @@ loop1:
 	if (node->tn_vpstate & TMPFS_VNODE_ALLOCATING) {
 		node->tn_vpstate |= TMPFS_VNODE_WANT;
 		error = msleep((caddr_t) &node->tn_vpstate,
-		    TMPFS_NODE_MTX(node), PDROP | PCATCH,
-		    "tmpfs_alloc_vp", 0);
-		if (error)
-			return error;
-
+		    TMPFS_NODE_MTX(node), 0, "tmpfs_alloc_vp", 0);
+		if (error != 0)
+			goto out;
 		goto loop;
 	} else
 		node->tn_vpstate |= TMPFS_VNODE_ALLOCATING;
@@ -561,7 +591,8 @@ loop1:
 	TMPFS_NODE_UNLOCK(node);
 
 	/* Get a new vnode and associate it with our node. */
-	error = getnewvnode("tmpfs", mp, &tmpfs_vnodeop_entries, &vp);
+	error = getnewvnode("tmpfs", mp, VFS_TO_TMPFS(mp)->tm_nonc ?
+	    &tmpfs_vnodeop_nonc_entries : &tmpfs_vnodeop_entries, &vp);
 	if (error != 0)
 		goto unlock;
 	MPASS(vp != NULL);
@@ -609,7 +640,7 @@ loop1:
 		VN_LOCK_ASHARE(vp);
 
 	error = insmntque1(vp, mp, tmpfs_insmntque_dtr, NULL);
-	if (error)
+	if (error != 0)
 		vp = NULL;
 
 unlock:
@@ -627,18 +658,19 @@ unlock:
 		TMPFS_NODE_UNLOCK(node);
 
 out:
-	*vpp = vp;
+	if (error == 0) {
+		*vpp = vp;
 
 #ifdef INVARIANTS
-	if (error == 0) {
 		MPASS(*vpp != NULL && VOP_ISLOCKED(*vpp));
 		TMPFS_NODE_LOCK(node);
 		MPASS(*vpp == node->tn_vnode);
 		TMPFS_NODE_UNLOCK(node);
-	}
 #endif
+	}
+	tmpfs_free_node(tm, node);
 
-	return error;
+	return (error);
 }
 
 /*
@@ -681,7 +713,7 @@ tmpfs_alloc_file(struct vnode *dvp, struct vnode **vpp, struct vattr *vap,
 	struct tmpfs_node *node;
 	struct tmpfs_node *parent;
 
-	MPASS(VOP_ISLOCKED(dvp));
+	ASSERT_VOP_ELOCKED(dvp, "tmpfs_alloc_file");
 	MPASS(cnp->cn_flags & HASBUF);
 
 	tmp = VFS_TO_TMPFS(dvp->v_mount);
@@ -706,8 +738,8 @@ tmpfs_alloc_file(struct vnode *dvp, struct vnode **vpp, struct vattr *vap,
 
 	/* Allocate a node that represents the new file. */
 	error = tmpfs_alloc_node(dvp->v_mount, tmp, vap->va_type,
-	    cnp->cn_cred->cr_uid,
-	    dnode->tn_gid, vap->va_mode, parent, target, vap->va_rdev, &node);
+	    cnp->cn_cred->cr_uid, dnode->tn_gid, vap->va_mode, parent,
+	    target, vap->va_rdev, &node);
 	if (error != 0)
 		return (error);
 
@@ -736,7 +768,7 @@ tmpfs_alloc_file(struct vnode *dvp, struct vnode **vpp, struct vattr *vap,
 	return (0);
 }
 
-static struct tmpfs_dirent *
+struct tmpfs_dirent *
 tmpfs_dir_first(struct tmpfs_node *dnode, struct tmpfs_dir_cursor *dc)
 {
 	struct tmpfs_dirent *de;
@@ -750,7 +782,7 @@ tmpfs_dir_first(struct tmpfs_node *dnode, struct tmpfs_dir_cursor *dc)
 	return (dc->tdc_current);
 }
 
-static struct tmpfs_dirent *
+struct tmpfs_dirent *
 tmpfs_dir_next(struct tmpfs_node *dnode, struct tmpfs_dir_cursor *dc)
 {
 	struct tmpfs_dirent *de;
@@ -1115,9 +1147,8 @@ tmpfs_dir_getdotdotdent(struct tmpfs_node *node, struct uio *uio)
 	 * Return ENOENT if the current node is already removed.
 	 */
 	TMPFS_ASSERT_LOCKED(node);
-	if (node->tn_dir.tn_parent == NULL) {
+	if (node->tn_dir.tn_parent == NULL)
 		return (ENOENT);
-	}
 
 	TMPFS_NODE_LOCK(node->tn_dir.tn_parent);
 	dent.d_fileno = node->tn_dir.tn_parent->tn_id;
diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c
index 869b6f1feaf..4b336ba150d 100644
--- a/sys/fs/tmpfs/tmpfs_vfsops.c
+++ b/sys/fs/tmpfs/tmpfs_vfsops.c
@@ -79,7 +79,7 @@ static void	tmpfs_susp_clean(struct mount *);
 
 static const char *tmpfs_opts[] = {
 	"from", "size", "maxfilesize", "inodes", "uid", "gid", "mode", "export",
-	"union", NULL
+	"union", "nonc", NULL
 };
 
 static const char *tmpfs_updateopts[] = {
@@ -138,6 +138,7 @@ tmpfs_mount(struct mount *mp)
 	struct tmpfs_node *root;
 	struct thread *td = curthread;
 	int error;
+	bool nonc;
 	/* Size counters. */
 	u_quad_t pages;
 	off_t nodes_max, size_max, maxfilesize;
@@ -186,11 +187,12 @@ tmpfs_mount(struct mount *mp)
 		size_max = 0;
 	if (vfs_getopt_size(mp->mnt_optnew, "maxfilesize", &maxfilesize) != 0)
 		maxfilesize = 0;
+	nonc = vfs_getopt(mp->mnt_optnew, "nonc", NULL, NULL) == 0;
 
 	/* Do not allow mounts if we do not have enough memory to preserve
 	 * the minimum reserved pages. */
 	if (tmpfs_mem_avail() < TMPFS_PAGES_MINRESERVED)
-		return ENOSPC;
+		return (ENOSPC);
 
 	/* Get the maximum number of memory pages this file system is
 	 * allowed to use, based on the maximum size the user passed in
@@ -219,37 +221,35 @@ tmpfs_mount(struct mount *mp)
 	tmp = (struct tmpfs_mount *)malloc(sizeof(struct tmpfs_mount),
 	    M_TMPFSMNT, M_WAITOK | M_ZERO);
 
-	mtx_init(&tmp->allnode_lock, "tmpfs allnode lock", NULL, MTX_DEF);
+	mtx_init(&tmp->tm_allnode_lock, "tmpfs allnode lock", NULL, MTX_DEF);
 	tmp->tm_nodes_max = nodes_max;
 	tmp->tm_nodes_inuse = 0;
+	tmp->tm_refcount = 1;
 	tmp->tm_maxfilesize = maxfilesize > 0 ? maxfilesize : OFF_MAX;
 	LIST_INIT(&tmp->tm_nodes_used);
 
 	tmp->tm_pages_max = pages;
 	tmp->tm_pages_used = 0;
-	tmp->tm_ino_unr = new_unrhdr(2, INT_MAX, &tmp->allnode_lock);
+	tmp->tm_ino_unr = new_unrhdr(2, INT_MAX, &tmp->tm_allnode_lock);
 	tmp->tm_dirent_pool = uma_zcreate("TMPFS dirent",
-	    sizeof(struct tmpfs_dirent),
-	    NULL, NULL, NULL, NULL,
+	    sizeof(struct tmpfs_dirent), NULL, NULL, NULL, NULL,
 	    UMA_ALIGN_PTR, 0);
 	tmp->tm_node_pool = uma_zcreate("TMPFS node",
-	    sizeof(struct tmpfs_node),
-	    tmpfs_node_ctor, tmpfs_node_dtor,
-	    tmpfs_node_init, tmpfs_node_fini,
-	    UMA_ALIGN_PTR, 0);
+	    sizeof(struct tmpfs_node), tmpfs_node_ctor, tmpfs_node_dtor,
+	    tmpfs_node_init, tmpfs_node_fini, UMA_ALIGN_PTR, 0);
 	tmp->tm_ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
+	tmp->tm_nonc = nonc;
 
 	/* Allocate the root node. */
-	error = tmpfs_alloc_node(mp, tmp, VDIR, root_uid,
-	    root_gid, root_mode & ALLPERMS, NULL, NULL,
-	    VNOVAL, &root);
+	error = tmpfs_alloc_node(mp, tmp, VDIR, root_uid, root_gid,
+	    root_mode & ALLPERMS, NULL, NULL, VNOVAL, &root);
 
 	if (error != 0 || root == NULL) {
-	    uma_zdestroy(tmp->tm_node_pool);
-	    uma_zdestroy(tmp->tm_dirent_pool);
-	    delete_unrhdr(tmp->tm_ino_unr);
-	    free(tmp, M_TMPFSMNT);
-	    return error;
+		uma_zdestroy(tmp->tm_node_pool);
+		uma_zdestroy(tmp->tm_dirent_pool);
+		delete_unrhdr(tmp->tm_ino_unr);
+		free(tmp, M_TMPFSMNT);
+		return (error);
 	}
 	KASSERT(root->tn_id == 2,
 	    ("tmpfs root with invalid ino: %ju", (uintmax_t)root->tn_id));
@@ -308,25 +308,17 @@ tmpfs_unmount(struct mount *mp, int mntflags)
 
 	TMPFS_LOCK(tmp);
 	while ((node = LIST_FIRST(&tmp->tm_nodes_used)) != NULL) {
-		TMPFS_UNLOCK(tmp);
+		TMPFS_NODE_LOCK(node);
 		if (node->tn_type == VDIR)
 			tmpfs_dir_destroy(tmp, node);
-		tmpfs_free_node(tmp, node);
-		TMPFS_LOCK(tmp);
+		if (tmpfs_free_node_locked(tmp, node, true))
+			TMPFS_LOCK(tmp);
+		else
+			TMPFS_NODE_UNLOCK(node);
 	}
-	TMPFS_UNLOCK(tmp);
 
-	uma_zdestroy(tmp->tm_dirent_pool);
-	uma_zdestroy(tmp->tm_node_pool);
-	delete_unrhdr(tmp->tm_ino_unr);
-
-	mtx_destroy(&tmp->allnode_lock);
-	MPASS(tmp->tm_pages_used == 0);
-	MPASS(tmp->tm_nodes_inuse == 0);
-
-	/* Throw away the tmpfs_mount structure. */
-	free(mp->mnt_data, M_TMPFSMNT);
 	mp->mnt_data = NULL;
+	tmpfs_free_tmp(tmp);
 	vfs_write_resume(mp, VR_START_WRITE);
 
 	MNT_ILOCK(mp);
@@ -336,52 +328,74 @@ tmpfs_unmount(struct mount *mp, int mntflags)
 	return (0);
 }
 
+void
+tmpfs_free_tmp(struct tmpfs_mount *tmp)
+{
+
+	MPASS(tmp->tm_refcount > 0);
+	tmp->tm_refcount--;
+	if (tmp->tm_refcount > 0) {
+		TMPFS_UNLOCK(tmp);
+		return;
+	}
+	TMPFS_UNLOCK(tmp);
+
+	uma_zdestroy(tmp->tm_dirent_pool);
+	uma_zdestroy(tmp->tm_node_pool);
+	delete_unrhdr(tmp->tm_ino_unr);
+
+	mtx_destroy(&tmp->tm_allnode_lock);
+	MPASS(tmp->tm_pages_used == 0);
+	MPASS(tmp->tm_nodes_inuse == 0);
+
+	free(tmp, M_TMPFSMNT);
+}
+
 static int
 tmpfs_root(struct mount *mp, int flags, struct vnode **vpp)
 {
 	int error;
+
 	error = tmpfs_alloc_vp(mp, VFS_TO_TMPFS(mp)->tm_root, flags, vpp);
-
-	if (!error)
+	if (error == 0)
 		(*vpp)->v_vflag |= VV_ROOT;
-
-	return error;
+	return (error);
 }
 
 static int
 tmpfs_fhtovp(struct mount *mp, struct fid *fhp, int flags,
     struct vnode **vpp)
 {
-	boolean_t found;
 	struct tmpfs_fid *tfhp;
 	struct tmpfs_mount *tmp;
 	struct tmpfs_node *node;
+	int error;
 
 	tmp = VFS_TO_TMPFS(mp);
 
 	tfhp = (struct tmpfs_fid *)fhp;
 	if (tfhp->tf_len != sizeof(struct tmpfs_fid))
-		return EINVAL;
+		return (EINVAL);
 
 	if (tfhp->tf_id >= tmp->tm_nodes_max)
-		return EINVAL;
-
-	found = FALSE;
+		return (EINVAL);
 
 	TMPFS_LOCK(tmp);
 	LIST_FOREACH(node, &tmp->tm_nodes_used, tn_entries) {
 		if (node->tn_id == tfhp->tf_id &&
 		    node->tn_gen == tfhp->tf_gen) {
-			found = TRUE;
+			tmpfs_ref_node(node);
 			break;
 		}
 	}
 	TMPFS_UNLOCK(tmp);
 
-	if (found)
-		return (tmpfs_alloc_vp(mp, node, LK_EXCLUSIVE, vpp));
-
-	return (EINVAL);
+	if (node != NULL) {
+		error = tmpfs_alloc_vp(mp, node, LK_EXCLUSIVE, vpp);
+		tmpfs_free_node(tmp, node);
+	} else
+		error = EINVAL;
+	return (error);
 }
 
 /* ARGSUSED2 */
diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c
index 2e2fe9f11af..a2b01213d7a 100644
--- a/sys/fs/tmpfs/tmpfs_vnops.c
+++ b/sys/fs/tmpfs/tmpfs_vnops.c
@@ -76,13 +76,11 @@ tmpfs_vn_get_ino_alloc(struct mount *mp, void *arg, int lkflags,
 }
 
 static int
-tmpfs_lookup(struct vop_cachedlookup_args *v)
+tmpfs_lookup1(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
 {
-	struct vnode *dvp = v->a_dvp;
-	struct vnode **vpp = v->a_vpp;
-	struct componentname *cnp = v->a_cnp;
 	struct tmpfs_dirent *de;
-	struct tmpfs_node *dnode;
+	struct tmpfs_node *dnode, *pnode;
+	struct tmpfs_mount *tm;
 	int error;
 
 	dnode = VP_TO_TMPFS_DIR(dvp);
@@ -104,8 +102,12 @@ tmpfs_lookup(struct vop_cachedlookup_args *v)
 		goto out;
 	}
 	if (cnp->cn_flags & ISDOTDOT) {
+		tm = VFS_TO_TMPFS(dvp->v_mount);
+		pnode = dnode->tn_dir.tn_parent;
+		tmpfs_ref_node(pnode);
 		error = vn_vget_ino_gen(dvp, tmpfs_vn_get_ino_alloc,
-		    dnode->tn_dir.tn_parent, cnp->cn_lkflags, vpp);
+		    pnode, cnp->cn_lkflags, vpp);
+		tmpfs_free_node(tm, pnode);
 		if (error != 0)
 			goto out;
 	} else if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
@@ -117,10 +119,12 @@ tmpfs_lookup(struct vop_cachedlookup_args *v)
 		if (de != NULL && de->td_node == NULL)
 			cnp->cn_flags |= ISWHITEOUT;
 		if (de == NULL || de->td_node == NULL) {
-			/* The entry was not found in the directory.
+			/*
+			 * The entry was not found in the directory.
 			 * This is OK if we are creating or renaming an
 			 * entry and are working on the last component of
-			 * the path name. */
+			 * the path name.
+			 */
 			if ((cnp->cn_flags & ISLASTCN) &&
 			    (cnp->cn_nameiop == CREATE || \
 			    cnp->cn_nameiop == RENAME ||
@@ -132,8 +136,10 @@ tmpfs_lookup(struct vop_cachedlookup_args *v)
 				if (error != 0)
 					goto out;
 
-				/* Keep the component name in the buffer for
-				 * future uses. */
+				/*
+				 * Keep the component name in the buffer for
+				 * future uses.
+				 */
 				cnp->cn_flags |= SAVENAME;
 
 				error = EJUSTRETURN;
@@ -142,14 +148,18 @@ tmpfs_lookup(struct vop_cachedlookup_args *v)
 		} else {
 			struct tmpfs_node *tnode;
 
-			/* The entry was found, so get its associated
-			 * tmpfs_node. */
+			/*
+			 * The entry was found, so get its associated
+			 * tmpfs_node.
+			 */
 			tnode = de->td_node;
 
-			/* If we are not at the last path component and
+			/*
+			 * If we are not at the last path component and
 			 * found a non-directory or non-link entry (which
 			 * may itself be pointing to a directory), raise
-			 * an error. */
+			 * an error.
+			 */
 			if ((tnode->tn_type != VDIR &&
 			    tnode->tn_type != VLNK) &&
 			    !(cnp->cn_flags & ISLASTCN)) {
@@ -157,9 +167,11 @@ tmpfs_lookup(struct vop_cachedlookup_args *v)
 				goto out;
 			}
 
-			/* If we are deleting or renaming the entry, keep
+			/*
+			 * If we are deleting or renaming the entry, keep
 			 * track of its tmpfs_dirent so that it can be
-			 * easily deleted later. */
+			 * easily deleted later.
+			 */
 			if ((cnp->cn_flags & ISLASTCN) &&
 			    (cnp->cn_nameiop == DELETE ||
 			    cnp->cn_nameiop == RENAME)) {
@@ -175,8 +187,9 @@ tmpfs_lookup(struct vop_cachedlookup_args *v)
 					goto out;
 
 				if ((dnode->tn_mode & S_ISTXT) &&
-				  VOP_ACCESS(dvp, VADMIN, cnp->cn_cred, cnp->cn_thread) &&
-				  VOP_ACCESS(*vpp, VADMIN, cnp->cn_cred, cnp->cn_thread)) {
+				  VOP_ACCESS(dvp, VADMIN, cnp->cn_cred,
+				  cnp->cn_thread) && VOP_ACCESS(*vpp, VADMIN,
+				  cnp->cn_cred, cnp->cn_thread)) {
 					error = EPERM;
 					vput(*vpp);
 					*vpp = NULL;
@@ -192,18 +205,36 @@ tmpfs_lookup(struct vop_cachedlookup_args *v)
 		}
 	}
 
-	/* Store the result of this lookup in the cache.  Avoid this if the
+	/*
+	 * Store the result of this lookup in the cache.  Avoid this if the
 	 * request was for creation, as it does not improve timings on
-	 * emprical tests. */
-	if ((cnp->cn_flags & MAKEENTRY) != 0)
+	 * emprical tests.
+	 */
+	if ((cnp->cn_flags & MAKEENTRY) != 0 && tmpfs_use_nc(dvp))
 		cache_enter(dvp, *vpp, cnp);
 
 out:
-	/* If there were no errors, *vpp cannot be null and it must be
-	 * locked. */
+	/*
+	 * If there were no errors, *vpp cannot be null and it must be
+	 * locked.
+	 */
 	MPASS(IFF(error == 0, *vpp != NULLVP && VOP_ISLOCKED(*vpp)));
 
-	return error;
+	return (error);
+}
+
+static int
+tmpfs_cached_lookup(struct vop_cachedlookup_args *v)
+{
+
+	return (tmpfs_lookup1(v->a_dvp, v->a_vpp, v->a_cnp));
+}
+
+static int
+tmpfs_lookup(struct vop_lookup_args *v)
+{
+
+	return (tmpfs_lookup1(v->a_dvp, v->a_vpp, v->a_cnp));
 }
 
 static int
@@ -218,7 +249,7 @@ tmpfs_create(struct vop_create_args *v)
 	MPASS(vap->va_type == VREG || vap->va_type == VSOCK);
 
 	error = tmpfs_alloc_file(dvp, vpp, vap, cnp, NULL);
-	if (error == 0 && (cnp->cn_flags & MAKEENTRY) != 0)
+	if (error == 0 && (cnp->cn_flags & MAKEENTRY) != 0 && tmpfs_use_nc(dvp))
 		cache_enter(dvp, *vpp, cnp);
 	return (error);
 }
@@ -993,10 +1024,12 @@ tmpfs_rename(struct vop_rename_args *v)
 
 	tmpfs_dir_attach(tdvp, de);
 
-	cache_purge(fvp);
-	if (tvp != NULL)
-		cache_purge(tvp);
-	cache_purge_negative(tdvp);
+	if (tmpfs_use_nc(fvp)) {
+		cache_purge(fvp);
+		if (tvp != NULL)
+			cache_purge(tvp);
+		cache_purge_negative(tdvp);
+	}
 
 	error = 0;
 
@@ -1096,7 +1129,6 @@ tmpfs_rmdir(struct vop_rmdir_args *v)
 
 	/* No vnode should be allocated for this entry from this point */
 	TMPFS_NODE_LOCK(node);
-	TMPFS_ASSERT_ELOCKED(node);
 	node->tn_links--;
 	node->tn_dir.tn_parent = NULL;
 	node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED |
@@ -1105,14 +1137,15 @@ tmpfs_rmdir(struct vop_rmdir_args *v)
 	TMPFS_NODE_UNLOCK(node);
 
 	TMPFS_NODE_LOCK(dnode);
-	TMPFS_ASSERT_ELOCKED(dnode);
 	dnode->tn_links--;
 	dnode->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED |
 	    TMPFS_NODE_MODIFIED;
 	TMPFS_NODE_UNLOCK(dnode);
 
-	cache_purge(dvp);
-	cache_purge(vp);
+	if (tmpfs_use_nc(dvp)) {
+		cache_purge(dvp);
+		cache_purge(vp);
+	}
 
 	/* Free the directory entry we just deleted.  Note that the node
 	 * referred by it will not be removed until the vnode is really
@@ -1256,10 +1289,10 @@ tmpfs_reclaim(struct vop_reclaim_args *v)
 	else
 		vnode_destroy_vobject(vp);
 	vp->v_object = NULL;
-	cache_purge(vp);
+	if (tmpfs_use_nc(vp))
+		cache_purge(vp);
 
 	TMPFS_NODE_LOCK(node);
-	TMPFS_ASSERT_ELOCKED(node);
 	tmpfs_free_vp(vp);
 
 	/* If the node referenced by this vnode was deleted by the user,
@@ -1389,13 +1422,139 @@ tmpfs_whiteout(struct vop_whiteout_args *ap)
 	}
 }
 
+static int
+tmpfs_vptocnp_dir(struct tmpfs_node *tn, struct tmpfs_node *tnp,
+    struct tmpfs_dirent **pde)
+{
+	struct tmpfs_dir_cursor dc;
+	struct tmpfs_dirent *de;
+
+	for (de = tmpfs_dir_first(tnp, &dc); de != NULL;
+	     de = tmpfs_dir_next(tnp, &dc)) {
+		if (de->td_node == tn) {
+			*pde = de;
+			return (0);
+		}
+	}
+	return (ENOENT);
+}
+
+static int
+tmpfs_vptocnp_fill(struct vnode *vp, struct tmpfs_node *tn,
+    struct tmpfs_node *tnp, char *buf, int *buflen, struct vnode **dvp)
+{
+	struct tmpfs_dirent *de;
+	int error, i;
+
+	error = vn_vget_ino_gen(vp, tmpfs_vn_get_ino_alloc, tnp, LK_SHARED,
+	    dvp);
+	if (error != 0)
+		return (error);
+	error = tmpfs_vptocnp_dir(tn, tnp, &de);
+	if (error == 0) {
+		i = *buflen;
+		i -= de->td_namelen;
+		if (i < 0) {
+			error = ENOMEM;
+		} else {
+			bcopy(de->ud.td_name, buf + i, de->td_namelen);
+			*buflen = i;
+		}
+	}
+	if (error == 0) {
+		if (vp != *dvp)
+			VOP_UNLOCK(*dvp, 0);
+	} else {
+		if (vp != *dvp)
+			vput(*dvp);
+		else
+			vrele(vp);
+	}
+	return (error);
+}
+
+static int
+tmpfs_vptocnp(struct vop_vptocnp_args *ap)
+{
+	struct vnode *vp, **dvp;
+	struct tmpfs_node *tn, *tnp, *tnp1;
+	struct tmpfs_dirent *de;
+	struct tmpfs_mount *tm;
+	char *buf;
+	int *buflen;
+	int error;
+
+	vp = ap->a_vp;
+	dvp = ap->a_vpp;
+	buf = ap->a_buf;
+	buflen = ap->a_buflen;
+
+	tm = VFS_TO_TMPFS(vp->v_mount);
+	tn = VP_TO_TMPFS_NODE(vp);
+	if (tn->tn_type == VDIR) {
+		tnp = tn->tn_dir.tn_parent;
+		if (tnp == NULL)
+			return (ENOENT);
+		tmpfs_ref_node(tnp);
+		error = tmpfs_vptocnp_fill(vp, tn, tn->tn_dir.tn_parent, buf,
+		    buflen, dvp);
+		tmpfs_free_node(tm, tnp);
+		return (error);
+	}
+restart:
+	TMPFS_LOCK(tm);
+	LIST_FOREACH_SAFE(tnp, &tm->tm_nodes_used, tn_entries, tnp1) {
+		if (tnp->tn_type != VDIR)
+			continue;
+		TMPFS_NODE_LOCK(tnp);
+		tmpfs_ref_node_locked(tnp);
+
+		/*
+		 * tn_vnode cannot be instantiated while we hold the
+		 * node lock, so the directory cannot be changed while
+		 * we iterate over it.  Do this to avoid instantiating
+		 * vnode for directories which cannot point to our
+		 * node.
+		 */
+		error = tnp->tn_vnode == NULL ? tmpfs_vptocnp_dir(tn, tnp,
+		    &de) : 0;
+
+		if (error == 0) {
+			TMPFS_NODE_UNLOCK(tnp);
+			TMPFS_UNLOCK(tm);
+			error = tmpfs_vptocnp_fill(vp, tn, tnp, buf, buflen,
+			    dvp);
+			if (error == 0) {
+				tmpfs_free_node(tm, tnp);
+				return (0);
+			}
+			if ((vp->v_iflag & VI_DOOMED) != 0) {
+				tmpfs_free_node(tm, tnp);
+				return (ENOENT);
+			}
+			TMPFS_LOCK(tm);
+			TMPFS_NODE_LOCK(tnp);
+		}
+		if (tmpfs_free_node_locked(tm, tnp, false)) {
+			goto restart;
+		} else {
+			KASSERT(tnp->tn_refcount > 0,
+			    ("node %p refcount zero", tnp));
+			tnp1 = LIST_NEXT(tnp, tn_entries);
+			TMPFS_NODE_UNLOCK(tnp);
+		}
+	}
+	TMPFS_UNLOCK(tm);
+	return (ENOENT);
+}
+
 /*
- * vnode operations vector used for files stored in a tmpfs file system.
+ * Vnode operations vector used for files stored in a tmpfs file system.
  */
 struct vop_vector tmpfs_vnodeop_entries = {
 	.vop_default =			&default_vnodeops,
 	.vop_lookup =			vfs_cache_lookup,
-	.vop_cachedlookup =		tmpfs_lookup,
+	.vop_cachedlookup =		tmpfs_cached_lookup,
 	.vop_create =			tmpfs_create,
 	.vop_mknod =			tmpfs_mknod,
 	.vop_open =			tmpfs_open,
@@ -1421,5 +1580,13 @@ struct vop_vector tmpfs_vnodeop_entries = {
 	.vop_vptofh =			tmpfs_vptofh,
 	.vop_whiteout =			tmpfs_whiteout,
 	.vop_bmap =			VOP_EOPNOTSUPP,
+	.vop_vptocnp =			tmpfs_vptocnp,
 };
 
+/*
+ * Same vector for mounts which do not use namecache.
+ */
+struct vop_vector tmpfs_vnodeop_nonc_entries = {
+	.vop_default =			&tmpfs_vnodeop_entries,
+	.vop_lookup =			tmpfs_lookup,
+};
diff --git a/sys/fs/tmpfs/tmpfs_vnops.h b/sys/fs/tmpfs/tmpfs_vnops.h
index 1e06c135fe7..db614a05129 100644
--- a/sys/fs/tmpfs/tmpfs_vnops.h
+++ b/sys/fs/tmpfs/tmpfs_vnops.h
@@ -44,6 +44,7 @@
  */
 
 extern struct vop_vector tmpfs_vnodeop_entries;
+extern struct vop_vector tmpfs_vnodeop_nonc_entries;
 
 vop_access_t	tmpfs_access;
 vop_getattr_t	tmpfs_getattr;
diff --git a/sys/geom/multipath/g_multipath.c b/sys/geom/multipath/g_multipath.c
index b461747bf35..0c24cd35891 100644
--- a/sys/geom/multipath/g_multipath.c
+++ b/sys/geom/multipath/g_multipath.c
@@ -923,6 +923,7 @@ g_multipath_ctl_add_name(struct gctl_req *req, struct g_class *mp,
 	struct g_provider *pp;
 	const char *mpname;
 	static const char devpf[6] = "/dev/";
+	int error;
 
 	g_topology_assert();
 
@@ -972,10 +973,9 @@ g_multipath_ctl_add_name(struct gctl_req *req, struct g_class *mp,
 		return;
 	}
 
-	/*
-	 * Now add....
-	 */
-	(void) g_multipath_add_disk(gp, pp);
+	error = g_multipath_add_disk(gp, pp);
+	if (error != 0)
+		gctl_error(req, "Provider addition error: %d", error);
 }
 
 static void
diff --git a/sys/i386/cloudabi32/cloudabi32_sysvec.c b/sys/i386/cloudabi32/cloudabi32_sysvec.c
index 1ecd8d52df8..9e1dac4122a 100644
--- a/sys/i386/cloudabi32/cloudabi32_sysvec.c
+++ b/sys/i386/cloudabi32/cloudabi32_sysvec.c
@@ -156,7 +156,7 @@ cloudabi32_thread_setregs(struct thread *td,
 
 	/* Perform standard register initialization. */
 	stack.ss_sp = TO_PTR(attr->stack);
-	stack.ss_size = attr->stack_size - sizeof(args);
+	stack.ss_size = attr->stack_len - sizeof(args);
 	cpu_set_upcall(td, TO_PTR(attr->entry_point), NULL, &stack);
 
 	/*
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 1dc61ad4002..763c711ad8b 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -1283,16 +1283,16 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force)
 			return;
 #endif
 		/*
-		 * Otherwise, do per-cache line flush.  Use the mfence
+		 * Otherwise, do per-cache line flush.  Use the sfence
 		 * instruction to insure that previous stores are
 		 * included in the write-back.  The processor
 		 * propagates flush to other processors in the cache
 		 * coherence domain.
 		 */
-		mfence();
+		sfence();
 		for (; sva < eva; sva += cpu_clflush_line_size)
 			clflushopt(sva);
-		mfence();
+		sfence();
 	} else if ((cpu_feature & CPUID_CLFSH) != 0 &&
 	    eva - sva < PMAP_CLFLUSH_THRESHOLD) {
 #ifdef DEV_APIC
@@ -5300,12 +5300,14 @@ pmap_flush_page(vm_page_t m)
 		eva = sva + PAGE_SIZE;
 
 		/*
-		 * Use mfence despite the ordering implied by
+		 * Use mfence or sfence despite the ordering implied by
 		 * mtx_{un,}lock() because clflush on non-Intel CPUs
 		 * and clflushopt are not guaranteed to be ordered by
 		 * any other instruction.
 		 */
-		if (useclflushopt || cpu_vendor_id != CPU_VENDOR_INTEL)
+		if (useclflushopt)
+			sfence();
+		else if (cpu_vendor_id != CPU_VENDOR_INTEL)
 			mfence();
 		for (; sva < eva; sva += cpu_clflush_line_size) {
 			if (useclflushopt)
@@ -5313,7 +5315,9 @@ pmap_flush_page(vm_page_t m)
 			else
 				clflush(sva);
 		}
-		if (useclflushopt || cpu_vendor_id != CPU_VENDOR_INTEL)
+		if (useclflushopt)
+			sfence();
+		else if (cpu_vendor_id != CPU_VENDOR_INTEL)
 			mfence();
 		*cmap_pte2 = 0;
 		sched_unpin();
diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h
index f43319476d3..23be5a3cdd0 100644
--- a/sys/i386/include/cpufunc.h
+++ b/sys/i386/include/cpufunc.h
@@ -158,6 +158,13 @@ mfence(void)
 	__asm __volatile("mfence" : : : "memory");
 }
 
+static __inline void
+sfence(void)
+{
+
+	__asm __volatile("sfence" : : : "memory");
+}
+
 #ifdef _KERNEL
 
 #define	HAVE_INLINE_FFS
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index bb57edf4215..c25ef3f3c89 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -1160,7 +1160,7 @@ struct coredump_params {
 
 static void cb_put_phdr(vm_map_entry_t, void *);
 static void cb_size_segment(vm_map_entry_t, void *);
-static int core_write(struct coredump_params *, void *, size_t, off_t,
+static int core_write(struct coredump_params *, const void *, size_t, off_t,
     enum uio_seg);
 static void each_dumpable_segment(struct thread *, segment_callback, void *);
 static int __elfN(corehdr)(struct coredump_params *, int, void *, size_t,
@@ -1202,7 +1202,14 @@ compress_chunk(struct coredump_params *p, char *base, char *buf, u_int len)
 
 	while (len > 0) {
 		chunk_len = MIN(len, CORE_BUF_SIZE);
-		copyin(base, buf, chunk_len);
+
+		/*
+		 * We can get EFAULT error here.
+		 * In that case zero out the current chunk of the segment.
+		 */
+		error = copyin(base, buf, chunk_len);
+		if (error != 0)
+			bzero(buf, chunk_len);
 		error = gzio_write(p->gzs, buf, chunk_len);
 		if (error != 0)
 			break;
@@ -1222,12 +1229,12 @@ core_gz_write(void *base, size_t len, off_t offset, void *arg)
 #endif /* GZIO */
 
 static int
-core_write(struct coredump_params *p, void *base, size_t len, off_t offset,
-    enum uio_seg seg)
+core_write(struct coredump_params *p, const void *base, size_t len,
+    off_t offset, enum uio_seg seg)
 {
 
-	return (vn_rdwr_inchunks(UIO_WRITE, p->vp, base, len, offset,
-	    seg, IO_UNIT | IO_DIRECT | IO_RANGELOCKED,
+	return (vn_rdwr_inchunks(UIO_WRITE, p->vp, __DECONST(void *, base),
+	    len, offset, seg, IO_UNIT | IO_DIRECT | IO_RANGELOCKED,
 	    p->active_cred, p->file_cred, NULL, p->td));
 }
 
@@ -1235,12 +1242,32 @@ static int
 core_output(void *base, size_t len, off_t offset, struct coredump_params *p,
     void *tmpbuf)
 {
+	int error;
 
 #ifdef GZIO
 	if (p->gzs != NULL)
 		return (compress_chunk(p, base, tmpbuf, len));
 #endif
-	return (core_write(p, base, len, offset, UIO_USERSPACE));
+	/*
+	 * EFAULT is a non-fatal error that we can get, for example,
+	 * if the segment is backed by a file but extends beyond its
+	 * end.
+	 */
+	error = core_write(p, base, len, offset, UIO_USERSPACE);
+	if (error == EFAULT) {
+		log(LOG_WARNING, "Failed to fully fault in a core file segment "
+		    "at VA %p with size 0x%zx to be written at offset 0x%jx "
+		    "for process %s\n", base, len, offset, curproc->p_comm);
+
+		/*
+		 * Write a "real" zero byte at the end of the target region
+		 * in the case this is the last segment.
+		 * The intermediate space will be implicitly zero-filled.
+		 */
+		error = core_write(p, zero_region, 1, offset + len - 1,
+		    UIO_SYSSPACE);
+	}
+	return (error);
 }
 
 /*
diff --git a/sys/kern/kern_clocksource.c b/sys/kern/kern_clocksource.c
index 7f7769d7a51..8bacff61d2d 100644
--- a/sys/kern/kern_clocksource.c
+++ b/sys/kern/kern_clocksource.c
@@ -207,7 +207,7 @@ handleevents(sbintime_t now, int fake)
 		}
 	} else
 		state->nextprof = state->nextstat;
-	if (now >= state->nextcallopt) {
+	if (now >= state->nextcallopt || now >= state->nextcall) {
 		state->nextcall = state->nextcallopt = SBT_MAX;
 		callout_process(now);
 	}
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index 3ec2940bbd2..472017cdbbe 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -437,9 +437,7 @@ ktr_freeproc(struct proc *p, struct ucred **uc, struct vnode **vp)
 }
 
 void
-ktrsyscall(code, narg, args)
-	int code, narg;
-	register_t args[];
+ktrsyscall(int code, int narg, register_t args[])
 {
 	struct ktr_request *req;
 	struct ktr_syscall *ktp;
@@ -468,9 +466,7 @@ ktrsyscall(code, narg, args)
 }
 
 void
-ktrsysret(code, error, retval)
-	int code, error;
-	register_t retval;
+ktrsysret(int code, int error, register_t retval)
 {
 	struct ktr_request *req;
 	struct ktr_sysret *ktp;
@@ -637,9 +633,7 @@ ktrnamei(path)
 }
 
 void
-ktrsysctl(name, namelen)
-	int *name;
-	u_int namelen;
+ktrsysctl(int *name, u_int namelen)
 {
 	struct ktr_request *req;
 	u_int mib[CTL_MAXNAME + 2];
@@ -671,11 +665,7 @@ ktrsysctl(name, namelen)
 }
 
 void
-ktrgenio(fd, rw, uio, error)
-	int fd;
-	enum uio_rw rw;
-	struct uio *uio;
-	int error;
+ktrgenio(int fd, enum uio_rw rw, struct uio *uio, int error)
 {
 	struct ktr_request *req;
 	struct ktr_genio *ktg;
@@ -710,11 +700,7 @@ ktrgenio(fd, rw, uio, error)
 }
 
 void
-ktrpsig(sig, action, mask, code)
-	int sig;
-	sig_t action;
-	sigset_t *mask;
-	int code;
+ktrpsig(int sig, sig_t action, sigset_t *mask, int code)
 {
 	struct thread *td = curthread;
 	struct ktr_request *req;
@@ -733,9 +719,7 @@ ktrpsig(sig, action, mask, code)
 }
 
 void
-ktrcsw(out, user, wmesg)
-	int out, user;
-	const char *wmesg;
+ktrcsw(int out, int user, const char *wmesg)
 {
 	struct thread *td = curthread;
 	struct ktr_request *req;
@@ -756,10 +740,7 @@ ktrcsw(out, user, wmesg)
 }
 
 void
-ktrstruct(name, data, datalen)
-	const char *name;
-	void *data;
-	size_t datalen;
+ktrstruct(const char *name, void *data, size_t datalen)
 {
 	struct ktr_request *req;
 	char *buf;
@@ -782,10 +763,8 @@ ktrstruct(name, data, datalen)
 }
 
 void
-ktrcapfail(type, needed, held)
-	enum ktr_cap_fail_type type;
-	const cap_rights_t *needed;
-	const cap_rights_t *held;
+ktrcapfail(enum ktr_cap_fail_type type, const cap_rights_t *needed,
+    const cap_rights_t *held)
 {
 	struct thread *td = curthread;
 	struct ktr_request *req;
@@ -809,9 +788,7 @@ ktrcapfail(type, needed, held)
 }
 
 void
-ktrfault(vaddr, type)
-	vm_offset_t vaddr;
-	int type;
+ktrfault(vm_offset_t vaddr, int type)
 {
 	struct thread *td = curthread;
 	struct ktr_request *req;
@@ -828,8 +805,7 @@ ktrfault(vaddr, type)
 }
 
 void
-ktrfaultend(result)
-	int result;
+ktrfaultend(int result)
 {
 	struct thread *td = curthread;
 	struct ktr_request *req;
@@ -857,13 +833,11 @@ struct ktrace_args {
 #endif
 /* ARGSUSED */
 int
-sys_ktrace(td, uap)
-	struct thread *td;
-	register struct ktrace_args *uap;
+sys_ktrace(struct thread *td, struct ktrace_args *uap)
 {
 #ifdef KTRACE
-	register struct vnode *vp = NULL;
-	register struct proc *p;
+	struct vnode *vp = NULL;
+	struct proc *p;
 	struct pgrp *pg;
 	int facs = uap->facs & ~KTRFAC_ROOT;
 	int ops = KTROP(uap->ops);
@@ -1002,9 +976,7 @@ done:
 
 /* ARGSUSED */
 int
-sys_utrace(td, uap)
-	struct thread *td;
-	register struct utrace_args *uap;
+sys_utrace(struct thread *td, struct utrace_args *uap)
 {
 
 #ifdef KTRACE
@@ -1038,11 +1010,7 @@ sys_utrace(td, uap)
 
 #ifdef KTRACE
 static int
-ktrops(td, p, ops, facs, vp)
-	struct thread *td;
-	struct proc *p;
-	int ops, facs;
-	struct vnode *vp;
+ktrops(struct thread *td, struct proc *p, int ops, int facs, struct vnode *vp)
 {
 	struct vnode *tracevp = NULL;
 	struct ucred *tracecred = NULL;
@@ -1093,14 +1061,11 @@ ktrops(td, p, ops, facs, vp)
 }
 
 static int
-ktrsetchildren(td, top, ops, facs, vp)
-	struct thread *td;
-	struct proc *top;
-	int ops, facs;
-	struct vnode *vp;
+ktrsetchildren(struct thread *td, struct proc *top, int ops, int facs,
+    struct vnode *vp)
 {
-	register struct proc *p;
-	register int ret = 0;
+	struct proc *p;
+	int ret = 0;
 
 	p = top;
 	PROC_LOCK_ASSERT(p, MA_OWNED);
@@ -1260,9 +1225,7 @@ ktr_writerequest(struct thread *td, struct ktr_request *req)
  * so, only root may further change it.
  */
 static int
-ktrcanset(td, targetp)
-	struct thread *td;
-	struct proc *targetp;
+ktrcanset(struct thread *td, struct proc *targetp)
 {
 
 	PROC_LOCK_ASSERT(targetp, MA_OWNED);
diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c
index 8c2f0ac034d..03677663d80 100644
--- a/sys/kern/kern_racct.c
+++ b/sys/kern/kern_racct.c
@@ -443,12 +443,8 @@ racct_sub_racct(struct racct *dest, const struct racct *src)
 		}
 		if (RACCT_CAN_DROP(i)) {
 			dest->r_resources[i] -= src->r_resources[i];
-			if (dest->r_resources[i] < 0) {
-				KASSERT(RACCT_IS_SLOPPY(i) ||
-				    RACCT_IS_DECAYING(i),
-				    ("%s: resource %d usage < 0", __func__, i));
+			if (dest->r_resources[i] < 0)
 				dest->r_resources[i] = 0;
-			}
 		}
 	}
 }
diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c
index ea2f969a8ba..a3c502a6c4d 100644
--- a/sys/kern/kern_rwlock.c
+++ b/sys/kern/kern_rwlock.c
@@ -132,9 +132,12 @@ LOCK_DELAY_SYSINIT(rw_delay_sysinit);
  * Return a pointer to the owning thread if the lock is write-locked or
  * NULL if the lock is unlocked or read-locked.
  */
-#define	rw_wowner(rw)							\
-	((rw)->rw_lock & RW_LOCK_READ ? NULL :				\
-	    (struct thread *)RW_OWNER((rw)->rw_lock))
+
+#define	lv_rw_wowner(v)							\
+	((v) & RW_LOCK_READ ? NULL :					\
+	 (struct thread *)RW_OWNER((v)))
+
+#define	rw_wowner(rw)	lv_rw_wowner(RW_READ_VALUE(rw))
 
 /*
  * Returns if a write owner is recursed.  Write ownership is not assured
@@ -415,7 +418,10 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
 
 #ifdef KDTRACE_HOOKS
 	all_time -= lockstat_nsecs(&rw->lock_object);
-	state = rw->rw_lock;
+#endif
+	v = RW_READ_VALUE(rw);
+#ifdef KDTRACE_HOOKS
+	state = v;
 #endif
 	for (;;) {
 		/*
@@ -428,7 +434,6 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
 		 * completely unlocked rwlock since such a lock is encoded
 		 * as a read lock with no waiters.
 		 */
-		v = rw->rw_lock;
 		if (RW_CAN_READ(v)) {
 			/*
 			 * The RW_LOCK_READ_WAITERS flag should only be set
@@ -444,6 +449,7 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
 					    (void *)(v + RW_ONE_READER));
 				break;
 			}
+			v = RW_READ_VALUE(rw);
 			continue;
 		}
 #ifdef KDTRACE_HOOKS
@@ -471,9 +477,11 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
 				KTR_STATE1(KTR_SCHED, "thread",
 				    sched_tdname(curthread), "spinning",
 				    "lockname:\"%s\"", rw->lock_object.lo_name);
-				while ((struct thread*)RW_OWNER(rw->rw_lock) ==
-				    owner && TD_IS_RUNNING(owner))
+				do {
 					lock_delay(&lda);
+					v = RW_READ_VALUE(rw);
+					owner = lv_rw_wowner(v);
+				} while (owner != NULL && TD_IS_RUNNING(owner));
 				KTR_STATE0(KTR_SCHED, "thread",
 				    sched_tdname(curthread), "running");
 				continue;
@@ -484,11 +492,12 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
 			    "spinning", "lockname:\"%s\"",
 			    rw->lock_object.lo_name);
 			for (i = 0; i < rowner_loops; i++) {
-				v = rw->rw_lock;
+				v = RW_READ_VALUE(rw);
 				if ((v & RW_LOCK_READ) == 0 || RW_CAN_READ(v))
 					break;
 				cpu_spinwait();
 			}
+			v = RW_READ_VALUE(rw);
 #ifdef KDTRACE_HOOKS
 			lda.spin_cnt += rowner_loops - i;
 #endif
@@ -511,7 +520,7 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
 		 * The lock might have been released while we spun, so
 		 * recheck its state and restart the loop if needed.
 		 */
-		v = rw->rw_lock;
+		v = RW_READ_VALUE(rw);
 		if (RW_CAN_READ(v)) {
 			turnstile_cancel(ts);
 			continue;
@@ -549,6 +558,7 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
 			if (!atomic_cmpset_ptr(&rw->rw_lock, v,
 			    v | RW_LOCK_READ_WAITERS)) {
 				turnstile_cancel(ts);
+				v = RW_READ_VALUE(rw);
 				continue;
 			}
 			if (LOCK_LOG_TEST(&rw->lock_object, 0))
@@ -574,6 +584,7 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
 		if (LOCK_LOG_TEST(&rw->lock_object, 0))
 			CTR2(KTR_LOCK, "%s: %p resuming from turnstile",
 			    __func__, rw);
+		v = RW_READ_VALUE(rw);
 	}
 #ifdef KDTRACE_HOOKS
 	all_time += lockstat_nsecs(&rw->lock_object);
@@ -657,13 +668,12 @@ _rw_runlock_cookie(volatile uintptr_t *c, const char *file, int line)
 	LOCK_LOG_LOCK("RUNLOCK", &rw->lock_object, 0, 0, file, line);
 
 	/* TODO: drop "owner of record" here. */
-
+	x = RW_READ_VALUE(rw);
 	for (;;) {
 		/*
 		 * See if there is more than one read lock held.  If so,
 		 * just drop one and return.
 		 */
-		x = rw->rw_lock;
 		if (RW_READERS(x) > 1) {
 			if (atomic_cmpset_rel_ptr(&rw->rw_lock, x,
 			    x - RW_ONE_READER)) {
@@ -674,6 +684,7 @@ _rw_runlock_cookie(volatile uintptr_t *c, const char *file, int line)
 					    (void *)(x - RW_ONE_READER));
 				break;
 			}
+			x = RW_READ_VALUE(rw);
 			continue;
 		}
 		/*
@@ -690,6 +701,7 @@ _rw_runlock_cookie(volatile uintptr_t *c, const char *file, int line)
 					    __func__, rw);
 				break;
 			}
+			x = RW_READ_VALUE(rw);
 			continue;
 		}
 		/*
@@ -725,6 +737,7 @@ _rw_runlock_cookie(volatile uintptr_t *c, const char *file, int line)
 		if (!atomic_cmpset_rel_ptr(&rw->rw_lock, RW_READERS_LOCK(1) | v,
 		    x)) {
 			turnstile_chain_unlock(&rw->lock_object);
+			x = RW_READ_VALUE(rw);
 			continue;
 		}
 		if (LOCK_LOG_TEST(&rw->lock_object, 0))
@@ -790,8 +803,9 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
 	lock_delay_arg_init(&lda, NULL);
 #endif
 	rw = rwlock2rw(c);
+	v = RW_READ_VALUE(rw);
 
-	if (rw_wlocked(rw)) {
+	if (__predict_false(lv_rw_wowner(v) == (struct thread *)tid)) {
 		KASSERT(rw->lock_object.lo_flags & LO_RECURSABLE,
 		    ("%s: recursing but non-recursive rw %s @ %s:%d\n",
 		    __func__, rw->lock_object.lo_name, file, line));
@@ -807,11 +821,15 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
 
 #ifdef KDTRACE_HOOKS
 	all_time -= lockstat_nsecs(&rw->lock_object);
-	state = rw->rw_lock;
+	state = v;
 #endif
 	for (;;) {
-		if (rw->rw_lock == RW_UNLOCKED && _rw_write_lock(rw, tid))
-			break;
+		if (v == RW_UNLOCKED) {
+			if (_rw_write_lock(rw, tid))
+				break;
+			v = RW_READ_VALUE(rw);
+			continue;
+		}
 #ifdef KDTRACE_HOOKS
 		lda.spin_cnt++;
 #endif
@@ -826,8 +844,7 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
 		 * running on another CPU, spin until the owner stops
 		 * running or the state of the lock changes.
 		 */
-		v = rw->rw_lock;
-		owner = (struct thread *)RW_OWNER(v);
+		owner = lv_rw_wowner(v);
 		if (!(v & RW_LOCK_READ) && TD_IS_RUNNING(owner)) {
 			if (LOCK_LOG_TEST(&rw->lock_object, 0))
 				CTR3(KTR_LOCK, "%s: spinning on %p held by %p",
@@ -835,9 +852,11 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
 			KTR_STATE1(KTR_SCHED, "thread", sched_tdname(curthread),
 			    "spinning", "lockname:\"%s\"",
 			    rw->lock_object.lo_name);
-			while ((struct thread*)RW_OWNER(rw->rw_lock) == owner &&
-			    TD_IS_RUNNING(owner))
+			do {
 				lock_delay(&lda);
+				v = RW_READ_VALUE(rw);
+				owner = lv_rw_wowner(v);
+			} while (owner != NULL && TD_IS_RUNNING(owner));
 			KTR_STATE0(KTR_SCHED, "thread", sched_tdname(curthread),
 			    "running");
 			continue;
@@ -847,6 +866,7 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
 			if (!(v & RW_LOCK_WRITE_SPINNER)) {
 				if (!atomic_cmpset_ptr(&rw->rw_lock, v,
 				    v | RW_LOCK_WRITE_SPINNER)) {
+					v = RW_READ_VALUE(rw);
 					continue;
 				}
 			}
@@ -861,6 +881,7 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
 			}
 			KTR_STATE0(KTR_SCHED, "thread", sched_tdname(curthread),
 			    "running");
+			v = RW_READ_VALUE(rw);
 #ifdef KDTRACE_HOOKS
 			lda.spin_cnt += rowner_loops - i;
 #endif
@@ -869,7 +890,7 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
 		}
 #endif
 		ts = turnstile_trywait(&rw->lock_object);
-		v = rw->rw_lock;
+		v = RW_READ_VALUE(rw);
 
 #ifdef ADAPTIVE_RWLOCKS
 		/*
@@ -905,6 +926,7 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
 				break;
 			}
 			turnstile_cancel(ts);
+			v = RW_READ_VALUE(rw);
 			continue;
 		}
 		/*
@@ -916,6 +938,7 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
 			if (!atomic_cmpset_ptr(&rw->rw_lock, v,
 			    v | RW_LOCK_WRITE_WAITERS)) {
 				turnstile_cancel(ts);
+				v = RW_READ_VALUE(rw);
 				continue;
 			}
 			if (LOCK_LOG_TEST(&rw->lock_object, 0))
@@ -943,6 +966,7 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
 #ifdef ADAPTIVE_RWLOCKS
 		spintries = 0;
 #endif
+		v = RW_READ_VALUE(rw);
 	}
 #ifdef KDTRACE_HOOKS
 	all_time += lockstat_nsecs(&rw->lock_object);
diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c
index 0036734caff..d89df3b5bcc 100644
--- a/sys/kern/kern_sx.c
+++ b/sys/kern/kern_sx.c
@@ -563,8 +563,10 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
 	lock_delay_arg_init(&lda, NULL);
 #endif
 
+	x = SX_READ_VALUE(sx);
+
 	/* If we already hold an exclusive lock, then recurse. */
-	if (sx_xlocked(sx)) {
+	if (__predict_false(lv_sx_owner(x) == (struct thread *)tid)) {
 		KASSERT((sx->lock_object.lo_flags & LO_RECURSABLE) != 0,
 	    ("_sx_xlock_hard: recursed on non-recursive sx %s @ %s:%d\n",
 		    sx->lock_object.lo_name, file, line));
@@ -581,12 +583,15 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
 
 #ifdef KDTRACE_HOOKS
 	all_time -= lockstat_nsecs(&sx->lock_object);
-	state = sx->sx_lock;
+	state = x;
 #endif
 	for (;;) {
-		if (sx->sx_lock == SX_LOCK_UNLOCKED &&
-		    atomic_cmpset_acq_ptr(&sx->sx_lock, SX_LOCK_UNLOCKED, tid))
-			break;
+		if (x == SX_LOCK_UNLOCKED) {
+			if (atomic_cmpset_acq_ptr(&sx->sx_lock, x, tid))
+				break;
+			x = SX_READ_VALUE(sx);
+			continue;
+		}
 #ifdef KDTRACE_HOOKS
 		lda.spin_cnt++;
 #endif
@@ -601,11 +606,9 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
 		 * running on another CPU, spin until the owner stops
 		 * running or the state of the lock changes.
 		 */
-		x = sx->sx_lock;
 		if ((sx->lock_object.lo_flags & SX_NOADAPTIVE) == 0) {
 			if ((x & SX_LOCK_SHARED) == 0) {
-				x = SX_OWNER(x);
-				owner = (struct thread *)x;
+				owner = lv_sx_owner(x);
 				if (TD_IS_RUNNING(owner)) {
 					if (LOCK_LOG_TEST(&sx->lock_object, 0))
 						CTR3(KTR_LOCK,
@@ -616,9 +619,12 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
 					    "lockname:\"%s\"",
 					    sx->lock_object.lo_name);
 					GIANT_SAVE();
-					while (SX_OWNER(sx->sx_lock) == x &&
-					    TD_IS_RUNNING(owner))
+					do {
 						lock_delay(&lda);
+						x = SX_READ_VALUE(sx);
+						owner = lv_sx_owner(x);
+					} while (owner != NULL &&
+						    TD_IS_RUNNING(owner));
 					KTR_STATE0(KTR_SCHED, "thread",
 					    sched_tdname(curthread), "running");
 					continue;
@@ -645,6 +651,7 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
 				}
 				KTR_STATE0(KTR_SCHED, "thread",
 				    sched_tdname(curthread), "running");
+				x = SX_READ_VALUE(sx);
 				if (i != asx_loops)
 					continue;
 			}
@@ -652,7 +659,7 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
 #endif
 
 		sleepq_lock(&sx->lock_object);
-		x = sx->sx_lock;
+		x = SX_READ_VALUE(sx);
 
 		/*
 		 * If the lock was released while spinning on the
@@ -701,6 +708,7 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
 				break;
 			}
 			sleepq_release(&sx->lock_object);
+			x = SX_READ_VALUE(sx);
 			continue;
 		}
 
@@ -712,6 +720,7 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
 			if (!atomic_cmpset_ptr(&sx->sx_lock, x,
 			    x | SX_LOCK_EXCLUSIVE_WAITERS)) {
 				sleepq_release(&sx->lock_object);
+				x = SX_READ_VALUE(sx);
 				continue;
 			}
 			if (LOCK_LOG_TEST(&sx->lock_object, 0))
@@ -753,6 +762,7 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
 		if (LOCK_LOG_TEST(&sx->lock_object, 0))
 			CTR2(KTR_LOCK, "%s: %p resuming from sleep queue",
 			    __func__, sx);
+		x = SX_READ_VALUE(sx);
 	}
 #ifdef KDTRACE_HOOKS
 	all_time += lockstat_nsecs(&sx->lock_object);
@@ -872,20 +882,18 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line)
 	lock_delay_arg_init(&lda, NULL);
 #endif
 #ifdef KDTRACE_HOOKS
-	state = sx->sx_lock;
 	all_time -= lockstat_nsecs(&sx->lock_object);
 #endif
+	x = SX_READ_VALUE(sx);
+#ifdef KDTRACE_HOOKS
+	state = x;
+#endif
 
 	/*
 	 * As with rwlocks, we don't make any attempt to try to block
 	 * shared locks once there is an exclusive waiter.
 	 */
 	for (;;) {
-#ifdef KDTRACE_HOOKS
-		lda.spin_cnt++;
-#endif
-		x = sx->sx_lock;
-
 		/*
 		 * If no other thread has an exclusive lock then try to bump up
 		 * the count of sharers.  Since we have to preserve the state
@@ -903,8 +911,13 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line)
 					    (void *)(x + SX_ONE_SHARER));
 				break;
 			}
+			x = SX_READ_VALUE(sx);
 			continue;
 		}
+#ifdef KDTRACE_HOOKS
+		lda.spin_cnt++;
+#endif
+
 #ifdef HWPMC_HOOKS
 		PMC_SOFT_CALL( , , lock, failed);
 #endif
@@ -918,8 +931,7 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line)
 		 * changes.
 		 */
 		if ((sx->lock_object.lo_flags & SX_NOADAPTIVE) == 0) {
-			x = SX_OWNER(x);
-			owner = (struct thread *)x;
+			owner = lv_sx_owner(x);
 			if (TD_IS_RUNNING(owner)) {
 				if (LOCK_LOG_TEST(&sx->lock_object, 0))
 					CTR3(KTR_LOCK,
@@ -929,9 +941,11 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line)
 				    sched_tdname(curthread), "spinning",
 				    "lockname:\"%s\"", sx->lock_object.lo_name);
 				GIANT_SAVE();
-				while (SX_OWNER(sx->sx_lock) == x &&
-				    TD_IS_RUNNING(owner))
+				do {
 					lock_delay(&lda);
+					x = SX_READ_VALUE(sx);
+					owner = lv_sx_owner(x);
+				} while (owner != NULL && TD_IS_RUNNING(owner));
 				KTR_STATE0(KTR_SCHED, "thread",
 				    sched_tdname(curthread), "running");
 				continue;
@@ -944,7 +958,7 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line)
 		 * start the process of blocking.
 		 */
 		sleepq_lock(&sx->lock_object);
-		x = sx->sx_lock;
+		x = SX_READ_VALUE(sx);
 
 		/*
 		 * The lock could have been released while we spun.
@@ -966,6 +980,7 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line)
 			owner = (struct thread *)SX_OWNER(x);
 			if (TD_IS_RUNNING(owner)) {
 				sleepq_release(&sx->lock_object);
+				x = SX_READ_VALUE(sx);
 				continue;
 			}
 		}
@@ -980,6 +995,7 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line)
 			if (!atomic_cmpset_ptr(&sx->sx_lock, x,
 			    x | SX_LOCK_SHARED_WAITERS)) {
 				sleepq_release(&sx->lock_object);
+				x = SX_READ_VALUE(sx);
 				continue;
 			}
 			if (LOCK_LOG_TEST(&sx->lock_object, 0))
@@ -1020,6 +1036,7 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line)
 		if (LOCK_LOG_TEST(&sx->lock_object, 0))
 			CTR2(KTR_LOCK, "%s: %p resuming from sleep queue",
 			    __func__, sx);
+		x = SX_READ_VALUE(sx);
 	}
 #ifdef KDTRACE_HOOKS
 	all_time += lockstat_nsecs(&sx->lock_object);
@@ -1054,9 +1071,8 @@ _sx_sunlock_hard(struct sx *sx, const char *file, int line)
 	if (SCHEDULER_STOPPED())
 		return;
 
+	x = SX_READ_VALUE(sx);
 	for (;;) {
-		x = sx->sx_lock;
-
 		/*
 		 * We should never have sharers while at least one thread
 		 * holds a shared lock.
@@ -1078,6 +1094,8 @@ _sx_sunlock_hard(struct sx *sx, const char *file, int line)
 					    (void *)(x - SX_ONE_SHARER));
 				break;
 			}
+
+			x = SX_READ_VALUE(sx);
 			continue;
 		}
 
@@ -1094,6 +1112,7 @@ _sx_sunlock_hard(struct sx *sx, const char *file, int line)
 					    __func__, sx);
 				break;
 			}
+			x = SX_READ_VALUE(sx);
 			continue;
 		}
 
@@ -1115,6 +1134,7 @@ _sx_sunlock_hard(struct sx *sx, const char *file, int line)
 		    SX_SHARERS_LOCK(1) | SX_LOCK_EXCLUSIVE_WAITERS,
 		    SX_LOCK_UNLOCKED)) {
 			sleepq_release(&sx->lock_object);
+			x = SX_READ_VALUE(sx);
 			continue;
 		}
 		if (LOCK_LOG_TEST(&sx->lock_object, 0))
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index b1b497928c8..847c6d70ad9 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -152,8 +152,8 @@ _sleep(void *ident, struct lock_object *lock, int priority,
 	    "Sleeping on \"%s\"", wmesg);
 	KASSERT(sbt != 0 || mtx_owned(&Giant) || lock != NULL,
 	    ("sleeping without a lock"));
-	KASSERT(p != NULL, ("msleep1"));
-	KASSERT(ident != NULL && TD_IS_RUNNING(td), ("msleep"));
+	KASSERT(ident != NULL, ("_sleep: NULL ident"));
+	KASSERT(TD_IS_RUNNING(td), ("_sleep: curthread not running"));
 	if (priority & PDROP)
 		KASSERT(lock != NULL && lock != &Giant.lock_object,
 		    ("PDROP requires a non-Giant lock"));
@@ -247,8 +247,8 @@ msleep_spin_sbt(void *ident, struct mtx *mtx, const char *wmesg,
 	td = curthread;
 	p = td->td_proc;
 	KASSERT(mtx != NULL, ("sleeping without a mutex"));
-	KASSERT(p != NULL, ("msleep1"));
-	KASSERT(ident != NULL && TD_IS_RUNNING(td), ("msleep"));
+	KASSERT(ident != NULL, ("msleep_spin_sbt: NULL ident"));
+	KASSERT(TD_IS_RUNNING(td), ("msleep_spin_sbt: curthread not running"));
 
 	if (SCHEDULER_STOPPED())
 		return (0);
diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c
index f97da171468..534f59cd5a4 100644
--- a/sys/kern/sched_4bsd.c
+++ b/sys/kern/sched_4bsd.c
@@ -968,8 +968,8 @@ sched_switch(struct thread *td, struct thread *newtd, int flags)
 		sched_load_rem();
 
 	td->td_lastcpu = td->td_oncpu;
-	preempted = !((td->td_flags & TDF_SLICEEND) ||
-	    (flags & SWT_RELINQUISH));
+	preempted = (td->td_flags & TDF_SLICEEND) == 0 &&
+	    (flags & SW_PREEMPT) != 0;
 	td->td_flags &= ~(TDF_NEEDRESCHED | TDF_SLICEEND);
 	td->td_owepreempt = 0;
 	td->td_oncpu = NOCPU;
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index 8bbd7095275..b650f24db9e 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -1898,8 +1898,8 @@ sched_switch(struct thread *td, struct thread *newtd, int flags)
 	ts->ts_rltick = ticks;
 	td->td_lastcpu = td->td_oncpu;
 	td->td_oncpu = NOCPU;
-	preempted = !((td->td_flags & TDF_SLICEEND) ||
-	    (flags & SWT_RELINQUISH));
+	preempted = (td->td_flags & TDF_SLICEEND) == 0 &&
+	    (flags & SW_PREEMPT) != 0;
 	td->td_flags &= ~(TDF_NEEDRESCHED | TDF_SLICEEND);
 	td->td_owepreempt = 0;
 	if (!TD_IS_IDLETHREAD(td))
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index af33643a9a0..d7193d77f75 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -2699,6 +2699,14 @@ sosetopt(struct socket *so, struct sockopt *sopt)
 			so->so_ts_clock = optval;
 			break;
 
+		case SO_MAX_PACING_RATE:
+			error = sooptcopyin(sopt, &val32, sizeof(val32),
+			    sizeof(val32));
+			if (error)
+				goto bad;
+			so->so_max_pacing_rate = val32;
+			break;
+
 		default:
 			if (V_socket_hhh[HHOOK_SOCKET_OPT]->hhh_nhooks > 0)
 				error = hhook_run_socket(so, sopt,
@@ -2890,6 +2898,10 @@ integer:
 			optval = so->so_ts_clock;
 			goto integer;
 
+		case SO_MAX_PACING_RATE:
+			optval = so->so_max_pacing_rate;
+			goto integer;
+
 		default:
 			if (V_socket_hhh[HHOOK_SOCKET_OPT]->hhh_nhooks > 0)
 				error = hhook_run_socket(so, sopt,
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index d9c380c1002..792fbb610a8 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1489,12 +1489,14 @@ alloc:
 	vp->v_op = vops;
 	v_init_counters(vp);
 	vp->v_bufobj.bo_ops = &buf_ops_bio;
+#ifdef DIAGNOSTIC
+	if (mp == NULL && vops != &dead_vnodeops)
+		printf("NULL mp in getnewvnode(9), tag %s\n", tag);
+#endif
 #ifdef MAC
 	mac_vnode_init(vp);
 	if (mp != NULL && (mp->mnt_flag & MNT_MULTILABEL) == 0)
 		mac_vnode_associate_singlelabel(mp, vp);
-	else if (mp == NULL && vops != &dead_vnodeops)
-		printf("NULL mp in getnewvnode()\n");
 #endif
 	if (mp != NULL) {
 		vp->v_bufobj.bo_bsize = mp->mnt_stat.f_iosize;
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 026837be9ed..8e1bd621d64 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -1539,27 +1539,26 @@ _vn_lock(struct vnode *vp, int flags, char *file, int line)
 
 	VNASSERT((flags & LK_TYPE_MASK) != 0, vp,
 	    ("vn_lock called with no locktype."));
-	do {
 #ifdef DEBUG_VFS_LOCKS
-		KASSERT(vp->v_holdcnt != 0,
-		    ("vn_lock %p: zero hold count", vp));
+	KASSERT(vp->v_holdcnt != 0,
+			("vn_lock %p: zero hold count", vp));
 #endif
-		error = VOP_LOCK1(vp, flags, file, line);
-		flags &= ~LK_INTERLOCK;	/* Interlock is always dropped. */
-		KASSERT((flags & LK_RETRY) == 0 || error == 0,
-		    ("LK_RETRY set with incompatible flags (0x%x) or an error occurred (%d)",
-		    flags, error));
-		/*
-		 * Callers specify LK_RETRY if they wish to get dead vnodes.
-		 * If RETRY is not set, we return ENOENT instead.
-		 */
-		if (error == 0 && vp->v_iflag & VI_DOOMED &&
-		    (flags & LK_RETRY) == 0) {
+retry:
+	error = VOP_LOCK1(vp, flags, file, line);
+	flags &= ~LK_INTERLOCK;	/* Interlock is always dropped. */
+	KASSERT((flags & LK_RETRY) == 0 || error == 0,
+	    ("LK_RETRY set with incompatible flags (0x%x) or "
+	    " an error occurred (%d)", flags, error));
+
+	if ((flags & LK_RETRY) == 0) {
+		if (error == 0 && vp->v_iflag & VI_DOOMED) {
 			VOP_UNLOCK(vp, 0);
 			error = ENOENT;
-			break;
 		}
-	} while (flags & LK_RETRY && error != 0);
+	} else {
+		if (error != 0)
+			goto retry;
+	}
 	return (error);
 }
 
@@ -1578,12 +1577,12 @@ vn_closefile(fp, td)
 	vp = fp->f_vnode;
 	fp->f_ops = &badfileops;
 
-	if (fp->f_type == DTYPE_VNODE && fp->f_flag & FHASLOCK)
-		vref(vp);
+	if (__predict_false(fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE)
+		vrefact(vp);
 
 	error = vn_close(vp, fp->f_flag, fp->f_cred, td);
 
-	if (fp->f_type == DTYPE_VNODE && fp->f_flag & FHASLOCK) {
+	if (__predict_false(fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) {
 		lf.l_whence = SEEK_SET;
 		lf.l_start = 0;
 		lf.l_len = 0;
diff --git a/sys/mips/conf/std.MALTA b/sys/mips/conf/std.MALTA
index c0e5cdbd07b..3731eadf6ec 100644
--- a/sys/mips/conf/std.MALTA
+++ b/sys/mips/conf/std.MALTA
@@ -27,6 +27,8 @@ options 	NFS_ROOT		#NFS usable as /, requires NFSCL
 options 	PSEUDOFS		#Pseudo-filesystem framework
 options 	_KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
 
+options 	TMPFS			#Efficient memory filesystem
+
 options 	FFS			#Berkeley Fast Filesystem
 options 	SOFTUPDATES		#Enable FFS soft updates support
 options 	UFS_ACL			#Support for access control lists
diff --git a/sys/modules/ath/Makefile b/sys/modules/ath/Makefile
index 332eb75714d..9bfc29c15f5 100644
--- a/sys/modules/ath/Makefile
+++ b/sys/modules/ath/Makefile
@@ -31,8 +31,8 @@
 
 ATH_RATE?=	sample		# tx rate control algorithm
 
-.PATH:	${.CURDIR}/../../dev/ath
-.PATH:	${.CURDIR}/../../dev/ath/ath_hal
+.PATH:	${SRCTOP}/sys/dev/ath
+.PATH:	${SRCTOP}/sys/dev/ath/ath_hal
 
 KMOD=	if_ath
 SRCS=	if_ath.c if_ath_alq.c if_ath_debug.c if_ath_keycache.c if_ath_sysctl.c
@@ -46,7 +46,7 @@ SRCS+=	device_if.h bus_if.h pci_if.h opt_inet.h opt_ath.h opt_ah.h opt_wlan.h
 #
 # AR5210 support; these are first generation 11a-only devices.
 #
-.PATH:	${.CURDIR}/../../dev/ath/ath_hal/ar5210
+.PATH:	${SRCTOP}/sys/dev/ath/ath_hal/ar5210
 SRCS+=	ah_eeprom_v1.c \
 	ar5210_attach.c ar5210_beacon.c ar5210_interrupts.c \
 	ar5210_keycache.c ar5210_misc.c ar5210_phy.c ar5210_power.c \
@@ -56,7 +56,7 @@ SRCS+=	ah_eeprom_v1.c \
 # AR5211 support; these are second generation 11b/g/a devices
 # (but 11g was OFDM only and is not supported).
 #
-.PATH:	${.CURDIR}/../../dev/ath/ath_hal/ar5211
+.PATH:	${SRCTOP}/sys/dev/ath/ath_hal/ar5211
 SRCS+=	ar5211_attach.c ar5211_beacon.c ar5211_interrupts.c \
 	ar5211_keycache.c ar5211_misc.c	ar5211_phy.c ar5211_power.c \
 	ar5211_recv.c ar5211_reset.c ar5211_xmit.c
@@ -64,7 +64,7 @@ SRCS+=	ar5211_attach.c ar5211_beacon.c ar5211_interrupts.c \
 #
 # AR5212 support; this covers all other pci/cardbus legacy parts.
 #
-.PATH:	${.CURDIR}/../../dev/ath/ath_hal/ar5212
+.PATH:	${SRCTOP}/sys/dev/ath/ath_hal/ar5212
 SRCS+=	ar5212_ani.c ar5212_attach.c ar5212_beacon.c ar5212_eeprom.c \
 	ar5212_gpio.c ar5212_interrupts.c ar5212_keycache.c ar5212_misc.c \
 	ar5212_phy.c ar5212_power.c ar5212_recv.c ar5212_reset.c \
@@ -85,7 +85,7 @@ SRCS+=	ar5413.c
 # NB: 9160 depends on 5416 but 5416 does not require 9160
 #
 # + 5416 (Owl)
-.PATH:	${.CURDIR}/../../dev/ath/ath_hal/ar5416
+.PATH:	${SRCTOP}/sys/dev/ath/ath_hal/ar5416
 SRCS+=	ah_eeprom_v14.c ah_eeprom_v4k.c \
 	ar5416_ani.c ar5416_attach.c ar5416_beacon.c ar5416_btcoex.c \
 	ar5416_cal.c ar5416_cal_iq.c ar5416_cal_adcgain.c ar5416_cal_adcdc.c \
@@ -97,7 +97,7 @@ SRCS+=	ah_eeprom_v14.c ah_eeprom_v4k.c \
 SRCS+=	ar2133.c
 
 # + AR9160 (Sowl)
-.PATH:	${.CURDIR}/../../dev/ath/ath_hal/ar9001
+.PATH:	${SRCTOP}/sys/dev/ath/ath_hal/ar9001
 SRCS+=	ar9160_attach.c
 
 # + AR9130 - (Sowl) - Embedded (AR913x SoC)
@@ -111,7 +111,7 @@ SRCS+=	ar9130_attach.c ar9130_eeprom.c ar9130_phy.c
 
 # AR9002 series chips
 # + AR9220/AR9280 - Merlin
-.PATH:	${.CURDIR}/../../dev/ath/ath_hal/ar9002
+.PATH:	${SRCTOP}/sys/dev/ath/ath_hal/ar9002
 SRCS+=	ar9280.c ar9280_attach.c ar9280_olc.c
 
 # + AR9285 - Kite
@@ -119,13 +119,13 @@ SRCS+=	ar9285.c ar9285_reset.c ar9285_attach.c ar9285_cal.c ar9285_phy.c
 SRCS+=	ar9285_diversity.c ar9285_btcoex.c
 
 # + AR9287 - Kiwi
-.PATH:  ${.CURDIR}/../../dev/ath/ath_hal
+.PATH:  ${SRCTOP}/sys/dev/ath/ath_hal
 SRCS+=  ah_eeprom_9287.c
-.PATH:  ${.CURDIR}/../../dev/ath/ath_hal/ar9002
+.PATH:  ${SRCTOP}/sys/dev/ath/ath_hal/ar9002
 SRCS+=  ar9287.c ar9287_reset.c ar9287_attach.c ar9287_cal.c ar9287_olc.c
 
 # + AR9300 HAL
-.PATH:  ${.CURDIR}/../../contrib/dev/ath/ath_hal/ar9300
+.PATH:  ${SRCTOP}/sys/contrib/dev/ath/ath_hal/ar9300
 SRCS+= ar9300_interrupts.c ar9300_radar.c ar9300_ani.c ar9300_keycache.c
 SRCS+= ar9300_radio.c ar9300_xmit.c ar9300_attach.c ar9300_mci.c ar9300_stub.c
 SRCS+= ar9300_xmit_ds.c ar9300_beacon.c ar9300_misc.c ar9300_recv.c
@@ -135,22 +135,22 @@ SRCS+= ar9300_power.c ar9300_timer.c ar9300_spectral.c
 
 # NB: rate control is bound to the driver by symbol names so only pick one
 .if ${ATH_RATE} == "sample"
-.PATH:	${.CURDIR}/../../dev/ath/ath_rate/sample
+.PATH:	${SRCTOP}/sys/dev/ath/ath_rate/sample
 SRCS+=	sample.c
 .elif ${ATH_RATE} == "onoe"
-.PATH:	${.CURDIR}/../../dev/ath/ath_rate/onoe
+.PATH:	${SRCTOP}/sys/dev/ath/ath_rate/onoe
 SRCS+=	onoe.c
 .elif ${ATH_RATE} == "amrr"
-.PATH:	${.CURDIR}/../../dev/ath/ath_rate/amrr
+.PATH:	${SRCTOP}/sys/dev/ath/ath_rate/amrr
 SRCS+=	amrr.c
 .endif
 
 # DFS
-.PATH: ${.CURDIR}/../../dev/ath/ath_dfs/null
+.PATH: ${SRCTOP}/sys/dev/ath/ath_dfs/null
 SRCS+=	dfs_null.c
 
-CFLAGS+=  -I. -I${.CURDIR}/../../dev/ath -I${.CURDIR}/../../dev/ath/ath_hal
-CFLAGS+=  -I. -I${.CURDIR}/../../contrib/dev/ath/ath_hal/
+CFLAGS+=  -I. -I${SRCTOP}/sys/dev/ath -I${SRCTOP}/sys/dev/ath/ath_hal
+CFLAGS+=  -I. -I${SRCTOP}/sys/contrib/dev/ath/ath_hal/
 
 .if !defined(KERNBUILDDIR)
 opt_ah.h:
diff --git a/sys/modules/if_lagg/Makefile b/sys/modules/if_lagg/Makefile
index cdcc8928f6c..227c95f35ee 100644
--- a/sys/modules/if_lagg/Makefile
+++ b/sys/modules/if_lagg/Makefile
@@ -2,6 +2,6 @@
 
 .PATH:	${.CURDIR}/../../net
 KMOD=	if_lagg
-SRCS=	if_lagg.c ieee8023ad_lacp.c opt_inet.h opt_inet6.h
+SRCS=	if_lagg.c ieee8023ad_lacp.c opt_inet.h opt_inet6.h opt_ratelimit.h
 
 .include 
diff --git a/sys/modules/if_vlan/Makefile b/sys/modules/if_vlan/Makefile
index 9842619b35d..5f3f7e87794 100644
--- a/sys/modules/if_vlan/Makefile
+++ b/sys/modules/if_vlan/Makefile
@@ -4,6 +4,6 @@
 
 KMOD=	if_vlan
 SRCS=	if_vlan.c
-SRCS+=	opt_inet.h opt_vlan.h
+SRCS+=	opt_inet.h opt_vlan.h opt_ratelimit.h
 
 .include 
diff --git a/sys/net/ieee8023ad_lacp.c b/sys/net/ieee8023ad_lacp.c
index 4863ac98035..bf73a5c75e2 100644
--- a/sys/net/ieee8023ad_lacp.c
+++ b/sys/net/ieee8023ad_lacp.c
@@ -30,6 +30,8 @@
 #include 
 __FBSDID("$FreeBSD$");
 
+#include "opt_ratelimit.h"
+
 #include 
 #include 
 #include 
@@ -853,6 +855,35 @@ lacp_select_tx_port(struct lagg_softc *sc, struct mbuf *m)
 
 	return (lp->lp_lagg);
 }
+
+#ifdef RATELIMIT
+struct lagg_port *
+lacp_select_tx_port_by_hash(struct lagg_softc *sc, uint32_t flowid)
+{
+	struct lacp_softc *lsc = LACP_SOFTC(sc);
+	struct lacp_portmap *pm;
+	struct lacp_port *lp;
+	uint32_t hash;
+
+	if (__predict_false(lsc->lsc_suppress_distributing)) {
+		LACP_DPRINTF((NULL, "%s: waiting transit\n", __func__));
+		return (NULL);
+	}
+
+	pm = &lsc->lsc_pmap[lsc->lsc_activemap];
+	if (pm->pm_count == 0) {
+		LACP_DPRINTF((NULL, "%s: no active aggregator\n", __func__));
+		return (NULL);
+	}
+
+	hash = flowid >> sc->flowid_shift;
+	hash %= pm->pm_count;
+	lp = pm->pm_map[hash];
+
+	return (lp->lp_lagg);
+}
+#endif
+
 /*
  * lacp_suppress_distributing: drop transmit packets for a while
  * to preserve packet ordering.
diff --git a/sys/net/ieee8023ad_lacp.h b/sys/net/ieee8023ad_lacp.h
index 8f0f51a71c4..b26e2c9251f 100644
--- a/sys/net/ieee8023ad_lacp.h
+++ b/sys/net/ieee8023ad_lacp.h
@@ -284,6 +284,9 @@ struct lacp_softc {
 
 struct mbuf	*lacp_input(struct lagg_port *, struct mbuf *);
 struct lagg_port *lacp_select_tx_port(struct lagg_softc *, struct mbuf *);
+#ifdef RATELIMIT
+struct lagg_port *lacp_select_tx_port_by_hash(struct lagg_softc *, uint32_t);
+#endif
 void		lacp_attach(struct lagg_softc *);
 void		lacp_detach(void *);
 void		lacp_init(struct lagg_softc *);
diff --git a/sys/net/if.h b/sys/net/if.h
index 98ae0a823cd..26f07870010 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -239,6 +239,7 @@ struct if_data {
 #define	IFCAP_RXCSUM_IPV6	0x200000  /* can offload checksum on IPv6 RX */
 #define	IFCAP_TXCSUM_IPV6	0x400000  /* can offload checksum on IPv6 TX */
 #define	IFCAP_HWSTATS		0x800000 /* manages counters internally */
+#define	IFCAP_TXRTLMT		0x1000000 /* hardware supports TX rate limiting */
 
 #define IFCAP_HWCSUM_IPV6	(IFCAP_RXCSUM_IPV6 | IFCAP_TXCSUM_IPV6)
 
diff --git a/sys/net/if_dead.c b/sys/net/if_dead.c
index 8b36ab34862..0e32dcf2911 100644
--- a/sys/net/if_dead.c
+++ b/sys/net/if_dead.c
@@ -100,6 +100,30 @@ ifdead_get_counter(struct ifnet *ifp, ift_counter cnt)
 	return (0);
 }
 
+static int
+ifdead_snd_tag_alloc(struct ifnet *ifp, union if_snd_tag_alloc_params *params,
+    struct m_snd_tag **ppmt)
+{
+	return (EOPNOTSUPP);
+}
+
+static int
+ifdead_snd_tag_modify(struct m_snd_tag *pmt, union if_snd_tag_modify_params *params)
+{
+	return (EOPNOTSUPP);
+}
+
+static int
+ifdead_snd_tag_query(struct m_snd_tag *pmt, union if_snd_tag_query_params *params)
+{
+	return (EOPNOTSUPP);
+}
+
+static void
+ifdead_snd_tag_free(struct m_snd_tag *pmt)
+{
+}
+
 void
 if_dead(struct ifnet *ifp)
 {
@@ -112,4 +136,8 @@ if_dead(struct ifnet *ifp)
 	ifp->if_qflush = ifdead_qflush;
 	ifp->if_transmit = ifdead_transmit;
 	ifp->if_get_counter = ifdead_get_counter;
+	ifp->if_snd_tag_alloc = ifdead_snd_tag_alloc;
+	ifp->if_snd_tag_modify = ifdead_snd_tag_modify;
+	ifp->if_snd_tag_query = ifdead_snd_tag_query;
+	ifp->if_snd_tag_free = ifdead_snd_tag_free;
 }
diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c
index 0a5fc159e57..b44fdc6e6c9 100644
--- a/sys/net/if_lagg.c
+++ b/sys/net/if_lagg.c
@@ -23,6 +23,7 @@ __FBSDID("$FreeBSD$");
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
+#include "opt_ratelimit.h"
 
 #include 
 #include 
@@ -118,6 +119,11 @@ static void	lagg_port2req(struct lagg_port *, struct lagg_reqport *);
 static void	lagg_init(void *);
 static void	lagg_stop(struct lagg_softc *);
 static int	lagg_ioctl(struct ifnet *, u_long, caddr_t);
+#ifdef RATELIMIT
+static int	lagg_snd_tag_alloc(struct ifnet *,
+		    union if_snd_tag_alloc_params *,
+		    struct m_snd_tag **);
+#endif
 static int	lagg_ether_setmulti(struct lagg_softc *);
 static int	lagg_ether_cmdmulti(struct lagg_port *, int);
 static	int	lagg_setflag(struct lagg_port *, int, int,
@@ -503,7 +509,12 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 	ifp->if_ioctl = lagg_ioctl;
 	ifp->if_get_counter = lagg_get_counter;
 	ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
+#ifdef RATELIMIT
+	ifp->if_snd_tag_alloc = lagg_snd_tag_alloc;
+	ifp->if_capenable = ifp->if_capabilities = IFCAP_HWSTATS | IFCAP_TXRTLMT;
+#else
 	ifp->if_capenable = ifp->if_capabilities = IFCAP_HWSTATS;
+#endif
 
 	/*
 	 * Attach as an ordinary ethernet device, children will be attached
@@ -1549,6 +1560,52 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 	return (error);
 }
 
+#ifdef RATELIMIT
+static int
+lagg_snd_tag_alloc(struct ifnet *ifp,
+    union if_snd_tag_alloc_params *params,
+    struct m_snd_tag **ppmt)
+{
+	struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc;
+	struct lagg_port *lp;
+	struct lagg_lb *lb;
+	uint32_t p;
+
+	switch (sc->sc_proto) {
+	case LAGG_PROTO_FAILOVER:
+		lp = lagg_link_active(sc, sc->sc_primary);
+		break;
+	case LAGG_PROTO_LOADBALANCE:
+		if ((sc->sc_opts & LAGG_OPT_USE_FLOWID) == 0 ||
+		    params->hdr.flowtype == M_HASHTYPE_NONE)
+			return (EOPNOTSUPP);
+		p = params->hdr.flowid >> sc->flowid_shift;
+		p %= sc->sc_count;
+		lb = (struct lagg_lb *)sc->sc_psc;
+		lp = lb->lb_ports[p];
+		lp = lagg_link_active(sc, lp);
+		break;
+	case LAGG_PROTO_LACP:
+		if ((sc->sc_opts & LAGG_OPT_USE_FLOWID) == 0 ||
+		    params->hdr.flowtype == M_HASHTYPE_NONE)
+			return (EOPNOTSUPP);
+		lp = lacp_select_tx_port_by_hash(sc, params->hdr.flowid);
+		break;
+	default:
+		return (EOPNOTSUPP);
+	}
+	if (lp == NULL)
+		return (EOPNOTSUPP);
+	ifp = lp->lp_ifp;
+	if (ifp == NULL || ifp->if_snd_tag_alloc == NULL ||
+	    (ifp->if_capenable & IFCAP_TXRTLMT) == 0)
+		return (EOPNOTSUPP);
+
+	/* forward allocation request */
+	return (ifp->if_snd_tag_alloc(ifp, params, ppmt));
+}
+#endif
+
 static int
 lagg_ether_setmulti(struct lagg_softc *sc)
 {
diff --git a/sys/net/if_media.c b/sys/net/if_media.c
index abdfa2b0c4d..9834d525bef 100644
--- a/sys/net/if_media.c
+++ b/sys/net/if_media.c
@@ -107,6 +107,7 @@ ifmedia_removeall(ifm)
 		LIST_REMOVE(entry, ifm_list);
 		free(entry, M_IFADDR);
 	}
+	ifm->ifm_cur = NULL;
 }
 
 /*
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 62c4bfdd33f..7c8fd7ec80a 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -175,6 +175,49 @@ struct if_encap_req {
 
 #define	IFENCAP_FLAG_BROADCAST	0x02	/* Destination is broadcast */
 
+/*
+ * Network interface send tag support. The storage of "struct
+ * m_snd_tag" comes from the network driver and it is free to allocate
+ * as much additional space as it wants for its own use.
+ */
+struct m_snd_tag;
+
+#define	IF_SND_TAG_TYPE_RATE_LIMIT 0
+#define	IF_SND_TAG_TYPE_MAX 1
+
+struct if_snd_tag_alloc_header {
+	uint32_t type;		/* send tag type, see IF_SND_TAG_XXX */
+	uint32_t flowid;	/* mbuf hash value */
+	uint32_t flowtype;	/* mbuf hash type */
+};
+
+struct if_snd_tag_alloc_rate_limit {
+	struct if_snd_tag_alloc_header hdr;
+	uint64_t max_rate;	/* in bytes/s */
+};
+
+struct if_snd_tag_rate_limit_params {
+	uint64_t max_rate;	/* in bytes/s */
+};
+
+union if_snd_tag_alloc_params {
+	struct if_snd_tag_alloc_header hdr;
+	struct if_snd_tag_alloc_rate_limit rate_limit;
+};
+
+union if_snd_tag_modify_params {
+	struct if_snd_tag_rate_limit_params rate_limit;
+};
+
+union if_snd_tag_query_params {
+	struct if_snd_tag_rate_limit_params rate_limit;
+};
+
+typedef int (if_snd_tag_alloc_t)(struct ifnet *, union if_snd_tag_alloc_params *,
+    struct m_snd_tag **);
+typedef int (if_snd_tag_modify_t)(struct m_snd_tag *, union if_snd_tag_modify_params *);
+typedef int (if_snd_tag_query_t)(struct m_snd_tag *, union if_snd_tag_query_params *);
+typedef void (if_snd_tag_free_t)(struct m_snd_tag *);
 
 /*
  * Structure defining a network interface.
@@ -303,13 +346,20 @@ struct ifnet {
 	u_int	if_hw_tsomaxsegcount;	/* TSO maximum segment count */
 	u_int	if_hw_tsomaxsegsize;	/* TSO maximum segment size in bytes */
 
+	/*
+	 * Network adapter send tag support:
+	 */
+	if_snd_tag_alloc_t *if_snd_tag_alloc;
+	if_snd_tag_modify_t *if_snd_tag_modify;
+	if_snd_tag_query_t *if_snd_tag_query;
+	if_snd_tag_free_t *if_snd_tag_free;
+
 	/*
 	 * Spare fields to be added before branching a stable branch, so
 	 * that structure can be enhanced without changing the kernel
 	 * binary interface.
 	 */
-	void	*if_pspare[4];		/* packet pacing / general use */
-	int	if_ispare[4];		/* packet pacing / general use */
+	int	if_ispare[4];		/* general use */
 };
 
 /* for compatibility with other BSDs */
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 73470dc80e3..608826a6dc9 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
 
 #include "opt_inet.h"
 #include "opt_vlan.h"
+#include "opt_ratelimit.h"
 
 #include 
 #include 
@@ -212,6 +213,10 @@ static	void trunk_destroy(struct ifvlantrunk *trunk);
 static	void vlan_init(void *foo);
 static	void vlan_input(struct ifnet *ifp, struct mbuf *m);
 static	int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr);
+#ifdef RATELIMIT
+static	int vlan_snd_tag_alloc(struct ifnet *,
+    union if_snd_tag_alloc_params *, struct m_snd_tag **);
+#endif
 static	void vlan_qflush(struct ifnet *ifp);
 static	int vlan_setflag(struct ifnet *ifp, int flag, int status,
     int (*func)(struct ifnet *, int));
@@ -971,6 +976,9 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
 	ifp->if_transmit = vlan_transmit;
 	ifp->if_qflush = vlan_qflush;
 	ifp->if_ioctl = vlan_ioctl;
+#ifdef RATELIMIT
+	ifp->if_snd_tag_alloc = vlan_snd_tag_alloc;
+#endif
 	ifp->if_flags = VLAN_IFFLAGS;
 	ether_ifattach(ifp, eaddr);
 	/* Now undo some of the damage... */
@@ -1591,6 +1599,15 @@ vlan_capabilities(struct ifvlan *ifv)
 		TOEDEV(ifp) = TOEDEV(p);
 		ifp->if_capenable |= p->if_capenable & IFCAP_TOE;
 	}
+
+#ifdef RATELIMIT
+	/*
+	 * If the parent interface supports ratelimiting, so does the
+	 * VLAN interface.
+	 */
+	ifp->if_capabilities |= (p->if_capabilities & IFCAP_TXRTLMT);
+	ifp->if_capenable |= (p->if_capenable & IFCAP_TXRTLMT);
+#endif
 }
 
 static void
@@ -1801,3 +1818,19 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 
 	return (error);
 }
+
+#ifdef RATELIMIT
+static int
+vlan_snd_tag_alloc(struct ifnet *ifp,
+    union if_snd_tag_alloc_params *params,
+    struct m_snd_tag **ppmt)
+{
+
+	/* get trunk device */
+	ifp = vlan_trunkdev(ifp);
+	if (ifp == NULL || (ifp->if_capenable & IFCAP_TXRTLMT) == 0)
+		return (EOPNOTSUPP);
+	/* forward allocation request */
+	return (ifp->if_snd_tag_alloc(ifp, params, ppmt));
+}
+#endif
diff --git a/sys/net80211/_ieee80211.h b/sys/net80211/_ieee80211.h
index 12f3ad8c84d..e7ae5d0cb4f 100644
--- a/sys/net80211/_ieee80211.h
+++ b/sys/net80211/_ieee80211.h
@@ -517,9 +517,10 @@ struct ieee80211_mimo_info {
 #define	IEEE80211_HTC_RXMCS32	0x00400000	/* CAPABILITY: MCS32 support */
 #define	IEEE80211_HTC_TXUNEQUAL	0x00800000	/* CAPABILITY: TX unequal MCS */
 #define	IEEE80211_HTC_TXMCS32	0x01000000	/* CAPABILITY: MCS32 support */
+#define	IEEE80211_HTC_TXLDPC	0x02000000	/* CAPABILITY: TX using LDPC */
 
 #define	IEEE80211_C_HTCAP_BITS \
 	"\20\1LDPC\2CHWIDTH40\5GREENFIELD\6SHORTGI20\7SHORTGI40\10TXSTBC" \
-	"\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS"
+	"\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS\32TXLDPC"
 
 #endif /* _NET80211__IEEE80211_H_ */
diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h
index ff5635aaec9..9fef8c441d4 100644
--- a/sys/net80211/ieee80211.h
+++ b/sys/net80211/ieee80211.h
@@ -617,7 +617,7 @@ struct ieee80211_ie_htcap {
 } __packed;
 
 /* HT capability flags (ht_cap) */
-#define	IEEE80211_HTCAP_LDPC		0x0001	/* LDPC supported */
+#define	IEEE80211_HTCAP_LDPC		0x0001	/* LDPC rx supported */
 #define	IEEE80211_HTCAP_CHWIDTH40	0x0002	/* 20/40 supported */
 #define	IEEE80211_HTCAP_SMPS		0x000c	/* SM Power Save mode */
 #define	IEEE80211_HTCAP_SMPS_OFF	0x000c	/* disabled */
diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c
index 2f28f002ec3..9a14643c670 100644
--- a/sys/net80211/ieee80211_ht.c
+++ b/sys/net80211/ieee80211_ht.c
@@ -298,6 +298,11 @@ ieee80211_ht_vattach(struct ieee80211vap *vap)
 			vap->iv_flags_ht |= IEEE80211_FHT_STBC_TX;
 		if (vap->iv_htcaps & IEEE80211_HTCAP_RXSTBC)
 			vap->iv_flags_ht |= IEEE80211_FHT_STBC_RX;
+
+		if (vap->iv_htcaps & IEEE80211_HTCAP_LDPC)
+			vap->iv_flags_ht |= IEEE80211_FHT_LDPC_RX;
+		if (vap->iv_htcaps & IEEE80211_HTC_TXLDPC)
+			vap->iv_flags_ht |= IEEE80211_FHT_LDPC_TX;
 	}
 	/* NB: disable default legacy WDS, too many issues right now */
 	if (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY)
@@ -1649,6 +1654,20 @@ htcap_update_shortgi(struct ieee80211_node *ni)
 		ni->ni_flags |= IEEE80211_NODE_SGI40;
 }
 
+/*
+ * Update LDPC state according to received htcap
+ * and local settings.
+ */
+static __inline void
+htcap_update_ldpc(struct ieee80211_node *ni)
+{
+	struct ieee80211vap *vap = ni->ni_vap;
+
+	if ((ni->ni_htcap & IEEE80211_HTCAP_LDPC) &&
+	    (vap->iv_flags_ht & IEEE80211_FHT_LDPC_TX))
+		ni->ni_flags |= IEEE80211_NODE_LDPC;
+}
+
 /*
  * Parse and update HT-related state extracted from
  * the HT cap and info ie's.
@@ -1669,6 +1688,7 @@ ieee80211_ht_updateparams(struct ieee80211_node *ni,
 	if (vap->iv_htcaps & IEEE80211_HTCAP_SMPS)
 		htcap_update_mimo_ps(ni);
 	htcap_update_shortgi(ni);
+	htcap_update_ldpc(ni);
 
 	if (htinfoie[0] == IEEE80211_ELEMID_VENDOR)
 		htinfoie += 4;
@@ -1821,6 +1841,7 @@ ieee80211_ht_updatehtcap(struct ieee80211_node *ni, const uint8_t *htcapie)
 	if (vap->iv_htcaps & IEEE80211_HTCAP_SMPS)
 		htcap_update_mimo_ps(ni);
 	htcap_update_shortgi(ni);
+	htcap_update_ldpc(ni);
 }
 
 /*
@@ -3027,7 +3048,9 @@ ieee80211_add_htcap_body(uint8_t *frm, struct ieee80211_node *ni)
 	if ((vap->iv_flags_ht & IEEE80211_FHT_STBC_RX) == 0)
 		caps &= ~IEEE80211_HTCAP_RXSTBC;
 
-	/* XXX TODO: adjust LDPC based on receive capabilities */
+	/* adjust LDPC based on receive capabilites */
+	if ((vap->iv_flags_ht & IEEE80211_FHT_LDPC_RX) == 0)
+		caps &= ~IEEE80211_HTCAP_LDPC;
 
 	ADDSHORT(frm, caps);
 
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index 4675291d9da..613eb84a05e 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -1136,6 +1136,13 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd,
 		if (vap->iv_flags_ht & IEEE80211_FHT_STBC_RX)
 			ireq->i_val |= 2;
 		break;
+	case IEEE80211_IOC_LDPC:
+		ireq->i_val = 0;
+		if (vap->iv_flags_ht & IEEE80211_FHT_LDPC_TX)
+			ireq->i_val |= 1;
+		if (vap->iv_flags_ht & IEEE80211_FHT_LDPC_RX)
+			ireq->i_val |= 2;
+		break;
 
 	/* VHT */
 	case IEEE80211_IOC_VHTCONF:
@@ -2225,7 +2232,7 @@ checkmcs(int mcs)
 		return 1;
 	if ((mcs & IEEE80211_RATE_MCS) == 0)	/* MCS always have 0x80 set */
 		return 0;
-	return (mcs & 0x7f) <= 15;	/* XXX could search ht rate set */
+	return (mcs & 0x7f) <= 31;	/* XXX could search ht rate set */
 }
 
 static int
@@ -3372,6 +3379,31 @@ ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211r
 		if (isvapht(vap))
 			error = ERESTART;
 		break;
+	case IEEE80211_IOC_LDPC:
+		/* Check if we can do LDPC TX/RX before changing the setting */
+		if ((ireq->i_val & 1) &&
+		    (vap->iv_htcaps & IEEE80211_HTC_TXLDPC) == 0)
+			return EOPNOTSUPP;
+		if ((ireq->i_val & 2) &&
+		    (vap->iv_htcaps & IEEE80211_HTCAP_LDPC) == 0)
+			return EOPNOTSUPP;
+
+		/* TX */
+		if (ireq->i_val & 1)
+			vap->iv_flags_ht |= IEEE80211_FHT_LDPC_TX;
+		else
+			vap->iv_flags_ht &= ~IEEE80211_FHT_LDPC_TX;
+
+		/* RX */
+		if (ireq->i_val & 2)
+			vap->iv_flags_ht |= IEEE80211_FHT_LDPC_RX;
+		else
+			vap->iv_flags_ht &= ~IEEE80211_FHT_LDPC_RX;
+
+		/* NB: reset only if we're operating on an 11n channel */
+		if (isvapht(vap))
+			error = ERESTART;
+		break;
 
 	/* VHT */
 	case IEEE80211_IOC_VHTCONF:
diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h
index 7ca24c1862f..0ba500329c1 100644
--- a/sys/net80211/ieee80211_node.h
+++ b/sys/net80211/ieee80211_node.h
@@ -143,6 +143,7 @@ struct ieee80211_node {
 #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 */
+#define	IEEE80211_NODE_LDPC	0x200000	/* LDPC enabled */
 	uint16_t		ni_associd;	/* association ID */
 	uint16_t		ni_vlan;	/* vlan tag */
 	uint16_t		ni_txpower;	/* current transmit power */
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index 48b9196846e..5e48ba7afa1 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -641,6 +641,8 @@ MALLOC_DECLARE(M_80211_VAP);
 
 /* ic_flags_ht/iv_flags_ht */
 #define	IEEE80211_FHT_NONHT_PR	 0x00000001	/* STATUS: non-HT sta present */
+#define	IEEE80211_FHT_LDPC_TX	 0x00010000	/* CONF: LDPC tx enabled */
+#define	IEEE80211_FHT_LDPC_RX	 0x00020000	/* CONF: LDPC rx enabled */
 #define	IEEE80211_FHT_GF  	 0x00040000	/* CONF: Greenfield enabled */
 #define	IEEE80211_FHT_HT	 0x00080000	/* CONF: HT supported */
 #define	IEEE80211_FHT_AMPDU_TX	 0x00100000	/* CONF: A-MPDU tx supported */
diff --git a/sys/netgraph/ng_mppc.c b/sys/netgraph/ng_mppc.c
index 76f4c3b89b4..3ffcdcd62ae 100644
--- a/sys/netgraph/ng_mppc.c
+++ b/sys/netgraph/ng_mppc.c
@@ -66,7 +66,7 @@
 
 #if !defined(NETGRAPH_MPPC_COMPRESSION) && !defined(NETGRAPH_MPPC_ENCRYPTION)
 #ifdef KLD_MODULE
-/* XXX NETGRAPH_MPPC_COMPRESSION isn't functional yet */
+#define NETGRAPH_MPPC_COMPRESSION
 #define NETGRAPH_MPPC_ENCRYPTION
 #else
 /* This case is indicative of an error in sys/conf files */
@@ -81,7 +81,6 @@ static MALLOC_DEFINE(M_NETGRAPH_MPPC, "netgraph_mppc", "netgraph mppc node");
 #endif
 
 #ifdef NETGRAPH_MPPC_COMPRESSION
-/* XXX this file doesn't exist yet, but hopefully someday it will... */
 #include 
 #endif
 #ifdef NETGRAPH_MPPC_ENCRYPTION
@@ -543,7 +542,7 @@ err1:
 			&destCnt, d->history, flags, 0);
 
 		/* Check return value */
-		KASSERT(rtn != MPPC_INVALID, ("%s: invalid", __func__));
+		/* KASSERT(rtn != MPPC_INVALID, ("%s: invalid", __func__)); */
 		if ((rtn & MPPC_EXPANDED) == 0
 		    && (rtn & MPPC_COMP_OK) == MPPC_COMP_OK) {
 			outlen -= destCnt;     
@@ -805,7 +804,7 @@ failed:
 			&sourceCnt, &destCnt, d->history, flags);
 
 		/* Check return value */
-		KASSERT(rtn != MPPC_INVALID, ("%s: invalid", __func__));
+		/* KASSERT(rtn != MPPC_INVALID, ("%s: invalid", __func__)); */
 		if ((rtn & MPPC_DEST_EXHAUSTED) != 0
 		    || (rtn & MPPC_DECOMP_OK) != MPPC_DECOMP_OK) {
 			log(LOG_ERR, "%s: decomp returned 0x%x",
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index da64dd31a07..a14f78595e8 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
 #include "opt_ipsec.h"
 #include "opt_inet.h"
 #include "opt_inet6.h"
+#include "opt_ratelimit.h"
 #include "opt_pcbgroup.h"
 #include "opt_rss.h"
 
@@ -57,6 +58,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1140,6 +1142,10 @@ in_pcbdetach(struct inpcb *inp)
 
 	KASSERT(inp->inp_socket != NULL, ("%s: inp_socket == NULL", __func__));
 
+#ifdef RATELIMIT
+	if (inp->inp_snd_tag != NULL)
+		in_pcbdetach_txrtlmt(inp);
+#endif
 	inp->inp_socket->so_pcb = NULL;
 	inp->inp_socket = NULL;
 }
@@ -2677,3 +2683,253 @@ DB_SHOW_COMMAND(inpcb, db_show_inpcb)
 	db_print_inpcb(inp, "inpcb", 0);
 }
 #endif /* DDB */
+
+#ifdef RATELIMIT
+/*
+ * Modify TX rate limit based on the existing "inp->inp_snd_tag",
+ * if any.
+ */
+int
+in_pcbmodify_txrtlmt(struct inpcb *inp, uint32_t max_pacing_rate)
+{
+	union if_snd_tag_modify_params params = {
+		.rate_limit.max_rate = max_pacing_rate,
+	};
+	struct m_snd_tag *mst;
+	struct ifnet *ifp;
+	int error;
+
+	mst = inp->inp_snd_tag;
+	if (mst == NULL)
+		return (EINVAL);
+
+	ifp = mst->ifp;
+	if (ifp == NULL)
+		return (EINVAL);
+
+	if (ifp->if_snd_tag_modify == NULL) {
+		error = EOPNOTSUPP;
+	} else {
+		error = ifp->if_snd_tag_modify(mst, ¶ms);
+	}
+	return (error);
+}
+
+/*
+ * Query existing TX rate limit based on the existing
+ * "inp->inp_snd_tag", if any.
+ */
+int
+in_pcbquery_txrtlmt(struct inpcb *inp, uint32_t *p_max_pacing_rate)
+{
+	union if_snd_tag_query_params params = { };
+	struct m_snd_tag *mst;
+	struct ifnet *ifp;
+	int error;
+
+	mst = inp->inp_snd_tag;
+	if (mst == NULL)
+		return (EINVAL);
+
+	ifp = mst->ifp;
+	if (ifp == NULL)
+		return (EINVAL);
+
+	if (ifp->if_snd_tag_query == NULL) {
+		error = EOPNOTSUPP;
+	} else {
+		error = ifp->if_snd_tag_query(mst, ¶ms);
+		if (error == 0 &&  p_max_pacing_rate != NULL)
+			*p_max_pacing_rate = params.rate_limit.max_rate;
+	}
+	return (error);
+}
+
+/*
+ * Allocate a new TX rate limit send tag from the network interface
+ * given by the "ifp" argument and save it in "inp->inp_snd_tag":
+ */
+int
+in_pcbattach_txrtlmt(struct inpcb *inp, struct ifnet *ifp,
+    uint32_t flowtype, uint32_t flowid, uint32_t max_pacing_rate)
+{
+	union if_snd_tag_alloc_params params = {
+		.rate_limit.hdr.type = IF_SND_TAG_TYPE_RATE_LIMIT,
+		.rate_limit.hdr.flowid = flowid,
+		.rate_limit.hdr.flowtype = flowtype,
+		.rate_limit.max_rate = max_pacing_rate,
+	};
+	int error;
+
+	INP_WLOCK_ASSERT(inp);
+
+	if (inp->inp_snd_tag != NULL)
+		return (EINVAL);
+
+	if (ifp->if_snd_tag_alloc == NULL) {
+		error = EOPNOTSUPP;
+	} else {
+		error = ifp->if_snd_tag_alloc(ifp, ¶ms, &inp->inp_snd_tag);
+
+		/*
+		 * At success increment the refcount on
+		 * the send tag's network interface:
+		 */
+		if (error == 0)
+			if_ref(inp->inp_snd_tag->ifp);
+	}
+	return (error);
+}
+
+/*
+ * Free an existing TX rate limit tag based on the "inp->inp_snd_tag",
+ * if any:
+ */
+void
+in_pcbdetach_txrtlmt(struct inpcb *inp)
+{
+	struct m_snd_tag *mst;
+	struct ifnet *ifp;
+
+	INP_WLOCK_ASSERT(inp);
+
+	mst = inp->inp_snd_tag;
+	inp->inp_snd_tag = NULL;
+
+	if (mst == NULL)
+		return;
+
+	ifp = mst->ifp;
+	if (ifp == NULL)
+		return;
+
+	/*
+	 * If the device was detached while we still had reference(s)
+	 * on the ifp, we assume if_snd_tag_free() was replaced with
+	 * stubs.
+	 */
+	ifp->if_snd_tag_free(mst);
+
+	/* release reference count on network interface */
+	if_rele(ifp);
+}
+
+/*
+ * This function should be called when the INP_RATE_LIMIT_CHANGED flag
+ * is set in the fast path and will attach/detach/modify the TX rate
+ * limit send tag based on the socket's so_max_pacing_rate value.
+ */
+void
+in_pcboutput_txrtlmt(struct inpcb *inp, struct ifnet *ifp, struct mbuf *mb)
+{
+	struct socket *socket;
+	uint32_t max_pacing_rate;
+	bool did_upgrade;
+	int error;
+
+	if (inp == NULL)
+		return;
+
+	socket = inp->inp_socket;
+	if (socket == NULL)
+		return;
+
+	if (!INP_WLOCKED(inp)) {
+		/*
+		 * NOTE: If the write locking fails, we need to bail
+		 * out and use the non-ratelimited ring for the
+		 * transmit until there is a new chance to get the
+		 * write lock.
+		 */
+		if (!INP_TRY_UPGRADE(inp))
+			return;
+		did_upgrade = 1;
+	} else {
+		did_upgrade = 0;
+	}
+
+	/*
+	 * NOTE: The so_max_pacing_rate value is read unlocked,
+	 * because atomic updates are not required since the variable
+	 * is checked at every mbuf we send. It is assumed that the
+	 * variable read itself will be atomic.
+	 */
+	max_pacing_rate = socket->so_max_pacing_rate;
+
+	/*
+	 * NOTE: When attaching to a network interface a reference is
+	 * made to ensure the network interface doesn't go away until
+	 * all ratelimit connections are gone. The network interface
+	 * pointers compared below represent valid network interfaces,
+	 * except when comparing towards NULL.
+	 */
+	if (max_pacing_rate == 0 && inp->inp_snd_tag == NULL) {
+		error = 0;
+	} else if (!(ifp->if_capenable & IFCAP_TXRTLMT)) {
+		if (inp->inp_snd_tag != NULL)
+			in_pcbdetach_txrtlmt(inp);
+		error = 0;
+	} else if (inp->inp_snd_tag == NULL) {
+		/*
+		 * In order to utilize packet pacing with RSS, we need
+		 * to wait until there is a valid RSS hash before we
+		 * can proceed:
+		 */
+		if (M_HASHTYPE_GET(mb) == M_HASHTYPE_NONE) {
+			error = EAGAIN;
+		} else {
+			error = in_pcbattach_txrtlmt(inp, ifp, M_HASHTYPE_GET(mb),
+			    mb->m_pkthdr.flowid, max_pacing_rate);
+		}
+	} else {
+		error = in_pcbmodify_txrtlmt(inp, max_pacing_rate);
+	}
+	if (error == 0 || error == EOPNOTSUPP)
+		inp->inp_flags2 &= ~INP_RATE_LIMIT_CHANGED;
+	if (did_upgrade)
+		INP_DOWNGRADE(inp);
+}
+
+/*
+ * Track route changes for TX rate limiting.
+ */
+void
+in_pcboutput_eagain(struct inpcb *inp)
+{
+	struct socket *socket;
+	bool did_upgrade;
+
+	if (inp == NULL)
+		return;
+
+	socket = inp->inp_socket;
+	if (socket == NULL)
+		return;
+
+	if (inp->inp_snd_tag == NULL)
+		return;
+
+	if (!INP_WLOCKED(inp)) {
+		/*
+		 * NOTE: If the write locking fails, we need to bail
+		 * out and use the non-ratelimited ring for the
+		 * transmit until there is a new chance to get the
+		 * write lock.
+		 */
+		if (!INP_TRY_UPGRADE(inp))
+			return;
+		did_upgrade = 1;
+	} else {
+		did_upgrade = 0;
+	}
+
+	/* detach rate limiting */
+	in_pcbdetach_txrtlmt(inp);
+
+	/* make sure new mbuf send tag allocation is made */
+	inp->inp_flags2 |= INP_RATE_LIMIT_CHANGED;
+
+	if (did_upgrade)
+		INP_DOWNGRADE(inp);
+}
+#endif /* RATELIMIT */
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 4e3fbe5595b..3842695597c 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -181,6 +181,7 @@ struct	icmp6_filter;
  * read-lock usage during modification, this model can be applied to other
  * protocols (especially SCTP).
  */
+struct m_snd_tag;
 struct inpcb {
 	LIST_ENTRY(inpcb) inp_hash;	/* (h/i) hash list */
 	LIST_ENTRY(inpcb) inp_pcbgrouphash;	/* (g/i) hash list */
@@ -202,11 +203,11 @@ struct inpcb {
 	u_char	inp_ip_minttl;		/* (i) minimum TTL or drop */
 	uint32_t inp_flowid;		/* (x) flow id / queue id */
 	u_int	inp_refcount;		/* (i) refcount */
-	void	*inp_pspare[5];		/* (x) packet pacing / general use */
+	struct m_snd_tag *inp_snd_tag;	/* (i) send tag for outgoing mbufs */
+	void	*inp_pspare[4];		/* (x) general use */
 	uint32_t inp_flowtype;		/* (x) M_HASHTYPE value */
 	uint32_t inp_rss_listen_bucket;	/* (x) overridden RSS listen bucket */
-	u_int	inp_ispare[4];		/* (x) packet pacing / user cookie /
-					 *     general use */
+	u_int	inp_ispare[4];		/* (x) user cookie / general use */
 
 	/* Local and foreign ports, local and foreign addr. */
 	struct	in_conninfo inp_inc;	/* (i) list for PCB's local port */
@@ -616,6 +617,7 @@ short	inp_so_options(const struct inpcb *inp);
 #define	INP_RSS_BUCKET_SET	0x00000080 /* IP_RSS_LISTEN_BUCKET is set */
 #define	INP_RECVFLOWID		0x00000100 /* populate recv datagram with flow info */
 #define	INP_RECVRSSBUCKETID	0x00000200 /* populate recv datagram with bucket id */
+#define	INP_RATE_LIMIT_CHANGED	0x00000400 /* rate limit needs attention */
 
 /*
  * Flags passed to in_pcblookup*() functions.
@@ -736,6 +738,14 @@ int	in_getsockaddr(struct socket *so, struct sockaddr **nam);
 struct sockaddr *
 	in_sockaddr(in_port_t port, struct in_addr *addr);
 void	in_pcbsosetlabel(struct socket *so);
+#ifdef RATELIMIT
+int	in_pcbattach_txrtlmt(struct inpcb *, struct ifnet *, uint32_t, uint32_t, uint32_t);
+void	in_pcbdetach_txrtlmt(struct inpcb *);
+int	in_pcbmodify_txrtlmt(struct inpcb *, uint32_t);
+int	in_pcbquery_txrtlmt(struct inpcb *, uint32_t *);
+void	in_pcboutput_txrtlmt(struct inpcb *, struct ifnet *, struct mbuf *);
+void	in_pcboutput_eagain(struct inpcb *);
+#endif
 #endif /* _KERNEL */
 
 #endif /* !_NETINET_IN_PCB_H_ */
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 78a5cc37f03..81f8264ce5c 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -33,6 +33,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_inet.h"
+#include "opt_ratelimit.h"
 #include "opt_ipsec.h"
 #include "opt_mbuf_stress_test.h"
 #include "opt_mpath.h"
@@ -661,8 +662,23 @@ sendit:
 		 */
 		m_clrprotoflags(m);
 		IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL);
+#ifdef RATELIMIT
+		if (inp != NULL) {
+			if (inp->inp_flags2 & INP_RATE_LIMIT_CHANGED)
+				in_pcboutput_txrtlmt(inp, ifp, m);
+			/* stamp send tag on mbuf */
+			m->m_pkthdr.snd_tag = inp->inp_snd_tag;
+		} else {
+			m->m_pkthdr.snd_tag = NULL;
+		}
+#endif
 		error = (*ifp->if_output)(ifp, m,
 		    (const struct sockaddr *)gw, ro);
+#ifdef RATELIMIT
+		/* check for route change */
+		if (error == EAGAIN)
+			in_pcboutput_eagain(inp);
+#endif
 		goto done;
 	}
 
@@ -698,8 +714,23 @@ sendit:
 
 			IP_PROBE(send, NULL, NULL, mtod(m, struct ip *), ifp,
 			    mtod(m, struct ip *), NULL);
+#ifdef RATELIMIT
+			if (inp != NULL) {
+				if (inp->inp_flags2 & INP_RATE_LIMIT_CHANGED)
+					in_pcboutput_txrtlmt(inp, ifp, m);
+				/* stamp send tag on mbuf */
+				m->m_pkthdr.snd_tag = inp->inp_snd_tag;
+			} else {
+				m->m_pkthdr.snd_tag = NULL;
+			}
+#endif
 			error = (*ifp->if_output)(ifp, m,
 			    (const struct sockaddr *)gw, ro);
+#ifdef RATELIMIT
+			/* check for route change */
+			if (error == EAGAIN)
+				in_pcboutput_eagain(inp);
+#endif
 		} else
 			m_freem(m);
 	}
@@ -974,6 +1005,16 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
 				INP_WUNLOCK(inp);
 				error = 0;
 				break;
+			case SO_MAX_PACING_RATE:
+#ifdef RATELIMIT
+				INP_WLOCK(inp);
+				inp->inp_flags2 |= INP_RATE_LIMIT_CHANGED;
+				INP_WUNLOCK(inp);
+				error = 0;
+#else
+				error = EOPNOTSUPP;
+#endif
+				break;
 			default:
 				break;
 			}
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index 49b89564b97..be05c8ade52 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$");
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
+#include "opt_ratelimit.h"
 #include "opt_ipsec.h"
 #include "opt_sctp.h"
 #include "opt_route.h"
@@ -954,8 +955,23 @@ passout:
 			    m->m_pkthdr.len);
 			ifa_free(&ia6->ia_ifa);
 		}
+#ifdef RATELIMIT
+		if (inp != NULL) {
+			if (inp->inp_flags2 & INP_RATE_LIMIT_CHANGED)
+				in_pcboutput_txrtlmt(inp, ifp, m);
+			/* stamp send tag on mbuf */
+			m->m_pkthdr.snd_tag = inp->inp_snd_tag;
+		} else {
+			m->m_pkthdr.snd_tag = NULL;
+		}
+#endif
 		error = nd6_output_ifp(ifp, origifp, m, dst,
 		    (struct route *)ro);
+#ifdef RATELIMIT
+		/* check for route change */
+		if (error == EAGAIN)
+			in_pcboutput_eagain(inp);
+#endif
 		goto done;
 	}
 
@@ -1054,8 +1070,23 @@ sendorfree:
 				counter_u64_add(ia->ia_ifa.ifa_obytes,
 				    m->m_pkthdr.len);
 			}
+#ifdef RATELIMIT
+			if (inp != NULL) {
+				if (inp->inp_flags2 & INP_RATE_LIMIT_CHANGED)
+					in_pcboutput_txrtlmt(inp, ifp, m);
+				/* stamp send tag on mbuf */
+				m->m_pkthdr.snd_tag = inp->inp_snd_tag;
+			} else {
+				m->m_pkthdr.snd_tag = NULL;
+			}
+#endif
 			error = nd6_output_ifp(ifp, origifp, m, dst,
 			    (struct route *)ro);
+#ifdef RATELIMIT
+			/* check for route change */
+			if (error == EAGAIN)
+				in_pcboutput_eagain(inp);
+#endif
 		} else
 			m_freem(m);
 	}
@@ -1441,6 +1472,16 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt)
 				INP_WUNLOCK(in6p);
 				error = 0;
 				break;
+			case SO_MAX_PACING_RATE:
+#ifdef RATELIMIT
+				INP_WLOCK(in6p);
+				in6p->inp_flags2 |= INP_RATE_LIMIT_CHANGED;
+				INP_WUNLOCK(in6p);
+				error = 0;
+#else
+				error = EOPNOTSUPP;
+#endif
+				break;
 			default:
 				break;
 			}
diff --git a/sys/netpfil/ipfw/ip_fw_private.h b/sys/netpfil/ipfw/ip_fw_private.h
index 3b483625c86..ed8e57450cf 100644
--- a/sys/netpfil/ipfw/ip_fw_private.h
+++ b/sys/netpfil/ipfw/ip_fw_private.h
@@ -414,7 +414,7 @@ struct ipfw_ifc {
 #define	IPFW_PF_RUNLOCK(p)		IPFW_RUNLOCK(p)
 #else /* FreeBSD */
 #define	IPFW_LOCK_INIT(_chain) do {			\
-	rm_init(&(_chain)->rwmtx, "IPFW static rules");	\
+	rm_init_flags(&(_chain)->rwmtx, "IPFW static rules", RM_RECURSE); \
 	rw_init(&(_chain)->uh_lock, "IPFW UH lock");	\
 	} while (0)
 
diff --git a/sys/powerpc/aim/trap_subr32.S b/sys/powerpc/aim/trap_subr32.S
index 056c0732367..4f691e7edb5 100644
--- a/sys/powerpc/aim/trap_subr32.S
+++ b/sys/powerpc/aim/trap_subr32.S
@@ -406,7 +406,7 @@ im0:
 	mtctr %r1			/* load counter */
 im1:
 	lwzu %r1, 8(%r2)		/* get next pte */
-	cmp 0, %r1, %r3			/* see if found pte */
+	cmp 0, 0, %r1, %r3		/* see if found pte */
 	bdnzf 2, im1			/* dec count br if cmp ne and if
 					 * count not zero */
 	bne instr_sec_hash		/* if not found set up second hash
diff --git a/sys/powerpc/include/frame.h b/sys/powerpc/include/frame.h
index e6fb103c7af..667b58c4b44 100644
--- a/sys/powerpc/include/frame.h
+++ b/sys/powerpc/include/frame.h
@@ -109,7 +109,5 @@ struct callframe {
 /* Definitions for syscalls */
 #define	FIRSTARG	3				/* first arg in reg 3 */
 #define	NARGREG		8				/* 8 args in regs */
-#define	MOREARGS(sp)	((caddr_t)((uintptr_t)(sp) + \
-    sizeof(struct callframe) - 3*sizeof(register_t))) /* more args go here */
 
 #endif	/* _MACHINE_FRAME_H_ */
diff --git a/sys/powerpc/mpc85xx/fsl_diu.c b/sys/powerpc/mpc85xx/fsl_diu.c
index 91675e43ec0..2fffaae69a4 100644
--- a/sys/powerpc/mpc85xx/fsl_diu.c
+++ b/sys/powerpc/mpc85xx/fsl_diu.c
@@ -344,7 +344,7 @@ diu_init(struct diu_softc *sc)
 static int
 diu_attach(device_t dev)
 {
-	struct edid_info *edid;
+	struct edid_info edid;
 	struct diu_softc *sc;
 	const struct videomode *videomode;
 	void *edid_cells;
@@ -384,12 +384,12 @@ diu_attach(device_t dev)
 		}
 	}
 	if (edid_cells != NULL) {
-		if (edid_parse(edid_cells, edid) != 0) {
+		if (edid_parse(edid_cells, &edid) != 0) {
 			device_printf(dev, "Error parsing EDID\n");
 			OF_prop_free(edid_cells);
 			return (ENXIO);
 		}
-		videomode = edid->edid_preferred_mode;
+		videomode = edid.edid_preferred_mode;
 	} else {
 		/* Parse video-mode kenv variable. */
 		if ((err = sscanf(vm_name, "fslfb:%dx%d@%d", &w, &h, &r)) != 3) {
diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c
index 6611703771d..d58cba3e1c6 100644
--- a/sys/powerpc/powerpc/trap.c
+++ b/sys/powerpc/powerpc/trap.c
@@ -80,6 +80,9 @@ __FBSDID("$FreeBSD$");
 #define	FAULTBUF_CR	22
 #define	FAULTBUF_R14	3
 
+#define	MOREARGS(sp)	((caddr_t)((uintptr_t)(sp) + \
+    sizeof(struct callframe) - 3*sizeof(register_t))) /* more args go here */
+
 static void	trap_fatal(struct trapframe *frame);
 static void	printtrap(u_int vector, struct trapframe *frame, int isfatal,
 		    int user);
diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h
index 7db4f25542b..179a60955d1 100644
--- a/sys/sys/cdefs.h
+++ b/sys/sys/cdefs.h
@@ -793,6 +793,13 @@
 #if !(defined(__clang__) && __has_feature(nullability))
 #define	_Nonnull
 #define	_Nullable
+#define	_Null_unspecified
+#define	__NULLABILITY_PRAGMA_PUSH
+#define	__NULLABILITY_PRAGMA_POP
+#else
+#define	__NULLABILITY_PRAGMA_PUSH _Pragma("clang diagnostic push")	\
+	_Pragma("clang diagnostic ignored \"-Wnullability-completeness\"")
+#define	__NULLABILITY_PRAGMA_POP _Pragma("clang diagnostic pop")
 #endif
 
 /*
diff --git a/sys/sys/elf32.h b/sys/sys/elf32.h
index 03a546c892c..0aa3142ed11 100644
--- a/sys/sys/elf32.h
+++ b/sys/sys/elf32.h
@@ -254,4 +254,10 @@ typedef struct {
 	Elf32_Half	si_flags;	/* per symbol flags */
 } Elf32_Syminfo;
 
+typedef struct {
+	Elf32_Word	ch_type;
+	Elf32_Word	ch_size;
+	Elf32_Word	ch_addralign;
+} Elf32_Chdr;
+
 #endif /* !_SYS_ELF32_H_ */
diff --git a/sys/sys/elf64.h b/sys/sys/elf64.h
index f0696196d55..a309dfc6843 100644
--- a/sys/sys/elf64.h
+++ b/sys/sys/elf64.h
@@ -257,4 +257,11 @@ typedef struct {
 	Elf64_Half	si_flags;	/* per symbol flags */
 } Elf64_Syminfo;
 
+typedef struct {
+	Elf64_Word	ch_type;
+	Elf64_Word	ch_reserved;
+	Elf64_Xword	ch_size;
+	Elf64_Xword	ch_addralign;
+} Elf64_Chdr;
+
 #endif /* !_SYS_ELF64_H_ */
diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h
index ede4b13a2c5..e8a8709f37e 100644
--- a/sys/sys/elf_common.h
+++ b/sys/sys/elf_common.h
@@ -849,6 +849,13 @@ typedef struct {
 #define	SYMINFO_CURRENT		1
 #define	SYMINFO_NUM		2
 
+/* Values for ch_type (compressed section headers). */
+#define	ELFCOMPRESS_ZLIB	1	/* ZLIB/DEFLATE */
+#define	ELFCOMPRESS_LOOS	0x60000000	/* OS-specific */
+#define	ELFCOMPRESS_HIOS	0x6fffffff
+#define	ELFCOMPRESS_LOPROC	0x70000000	/* Processor-specific */
+#define	ELFCOMPRESS_HIPROC	0x7fffffff
+
 /*
  * Relocation types.
  *
diff --git a/sys/sys/extattr.h b/sys/sys/extattr.h
index ce5619bef16..2b358c92d74 100644
--- a/sys/sys/extattr.h
+++ b/sys/sys/extattr.h
@@ -57,10 +57,11 @@
 	EXTATTR_NAMESPACE_USER_STRING, \
 	EXTATTR_NAMESPACE_SYSTEM_STRING }
 
+#define	EXTATTR_MAXNAMELEN	NAME_MAX
+
 #ifdef _KERNEL
 #include 
 
-#define	EXTATTR_MAXNAMELEN	NAME_MAX
 struct thread;
 struct ucred;
 struct vnode;
diff --git a/sys/sys/gtaskqueue.h b/sys/sys/gtaskqueue.h
index 9a00a8a3434..3a9aeadc0a4 100644
--- a/sys/sys/gtaskqueue.h
+++ b/sys/sys/gtaskqueue.h
@@ -81,7 +81,7 @@ int	taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride);
 extern struct taskqgroup *qgroup_##name
 
 
-#ifdef EARLY_AP_STARTUP
+#if (!defined(SMP) || defined(EARLY_AP_STARTUP))
 #define TASKQGROUP_DEFINE(name, cnt, stride)				\
 									\
 struct taskqgroup *qgroup_##name;					\
@@ -95,7 +95,7 @@ taskqgroup_define_##name(void *arg)					\
 									\
 SYSINIT(taskqgroup_##name, SI_SUB_INIT_IF, SI_ORDER_FIRST,		\
 	taskqgroup_define_##name, NULL)
-#else
+#else /* SMP && !EARLY_AP_STARTUP */
 #define TASKQGROUP_DEFINE(name, cnt, stride)				\
 									\
 struct taskqgroup *qgroup_##name;					\
@@ -104,6 +104,15 @@ static void								\
 taskqgroup_define_##name(void *arg)					\
 {									\
 	qgroup_##name = taskqgroup_create(#name);			\
+	/* Adjustment will be null unless smp_cpus == 1. */		\
+	/*								\
+	 * XXX this was intended to fix the smp_cpus == 1 case, but	\
+	 * doesn't actually work for that.  It gives thes same strange	\
+	 * panic as adjustment at SI_SUB_INIT_IF:SI_ORDER_ANY for a	\
+	 * device that works with a pure UP kernel.			\
+	 */								\
+	/* XXX this code is common now, so should not be ifdefed. */	\
+	taskqgroup_adjust(qgroup_##name, (cnt), (stride));		\
 }									\
 									\
 SYSINIT(taskqgroup_##name, SI_SUB_INIT_IF, SI_ORDER_FIRST,		\
@@ -112,14 +121,18 @@ SYSINIT(taskqgroup_##name, SI_SUB_INIT_IF, SI_ORDER_FIRST,		\
 static void								\
 taskqgroup_adjust_##name(void *arg)					\
 {									\
+	/* 								\
+	 * Adjustment when smp_cpus > 1 only works accidentally		\
+	 * (when there is no device interrupt before adjustment).	\
+	 */								\
 	taskqgroup_adjust(qgroup_##name, (cnt), (stride));		\
 }									\
 									\
-SYSINIT(taskqgroup_adj_##name, SI_SUB_INIT_IF, SI_ORDER_ANY,		\
+SYSINIT(taskqgroup_adj_##name, SI_SUB_SMP, SI_ORDER_ANY,		\
 	taskqgroup_adjust_##name, NULL);				\
-									\
-struct __hack
-#endif
+
+#endif /* !SMP || EARLY_AP_STARTUP */
+
 TASKQGROUP_DECLARE(net);
 
 #endif /* !_SYS_GTASKQUEUE_H_ */
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index eac039a462b..1651767687d 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -129,6 +129,14 @@ struct m_tag {
 	void			(*m_tag_free)(struct m_tag *);
 };
 
+/*
+ * Static network interface owned tag.
+ * Allocated through ifp->if_snd_tag_alloc().
+ */
+struct m_snd_tag {
+	struct ifnet *ifp;		/* network interface tag belongs to */
+};
+
 /*
  * Record/packet header in first mbuf of chain; valid only if M_PKTHDR is set.
  * Size ILP32: 48
@@ -137,7 +145,10 @@ struct m_tag {
  * they are correct.
  */
 struct pkthdr {
-	struct ifnet	*rcvif;		/* rcv interface */
+	union {
+		struct m_snd_tag *snd_tag;	/* send tag, if any */
+		struct ifnet	*rcvif;		/* rcv interface */
+	};
 	SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
 	int32_t		 len;		/* total packet length */
 
diff --git a/sys/sys/rwlock.h b/sys/sys/rwlock.h
index 6b4f505e0d0..e5b1166cedc 100644
--- a/sys/sys/rwlock.h
+++ b/sys/sys/rwlock.h
@@ -76,6 +76,8 @@
 
 #define	rw_recurse	lock_object.lo_data
 
+#define	RW_READ_VALUE(x)	((x)->rw_lock)
+
 /* Very simple operations on rw_lock. */
 
 /* Try to obtain a write lock once. */
diff --git a/sys/sys/socket.h b/sys/sys/socket.h
index a97b1eefe05..68f7b5d4533 100644
--- a/sys/sys/socket.h
+++ b/sys/sys/socket.h
@@ -159,6 +159,7 @@ typedef	__uintptr_t	uintptr_t;
 #define	SO_PROTOCOL	0x1016		/* get socket protocol (Linux name) */
 #define	SO_PROTOTYPE	SO_PROTOCOL	/* alias for SO_PROTOCOL (SunOS name) */
 #define	SO_TS_CLOCK	0x1017		/* clock type used for SO_TIMESTAMP */
+#define	SO_MAX_PACING_RATE	0x1018	/* socket's max TX pacing rate (Linux name) */
 #endif
 
 #if __BSD_VISIBLE
@@ -424,28 +425,36 @@ struct msghdr {
 	int		 msg_flags;		/* flags on received message */
 };
 
-#define	MSG_OOB		0x1		/* process out-of-band data */
-#define	MSG_PEEK	0x2		/* peek at incoming message */
-#define	MSG_DONTROUTE	0x4		/* send without using routing tables */
-#define	MSG_EOR		0x8		/* data completes record */
-#define	MSG_TRUNC	0x10		/* data discarded before delivery */
-#define	MSG_CTRUNC	0x20		/* control data lost before delivery */
-#define	MSG_WAITALL	0x40		/* wait for full request or error */
-#if __POSIX_VISIBLE >= 200809
-#define	MSG_NOSIGNAL	0x20000		/* do not generate SIGPIPE on EOF */
-#endif
+#define	MSG_OOB		 0x00000001	/* process out-of-band data */
+#define	MSG_PEEK	 0x00000002	/* peek at incoming message */
+#define	MSG_DONTROUTE	 0x00000004	/* send without using routing tables */
+#define	MSG_EOR		 0x00000008	/* data completes record */
+#define	MSG_TRUNC	 0x00000010	/* data discarded before delivery */
+#define	MSG_CTRUNC	 0x00000020	/* control data lost before delivery */
+#define	MSG_WAITALL	 0x00000040	/* wait for full request or error */
 #if __BSD_VISIBLE
-#define	MSG_DONTWAIT	0x80		/* this message should be nonblocking */
-#define	MSG_EOF		0x100		/* data completes connection */
-#define	MSG_NOTIFICATION 0x2000         /* SCTP notification */
-#define	MSG_NBIO	0x4000		/* FIONBIO mode, used by fifofs */
-#define	MSG_COMPAT      0x8000		/* used in sendit() */
-#define	MSG_CMSG_CLOEXEC 0x40000	/* make received fds close-on-exec */
-#define	MSG_WAITFORONE	0x80000		/* for recvmmsg() */
+#define	MSG_DONTWAIT	 0x00000080	/* this message should be nonblocking */
+#define	MSG_EOF		 0x00000100	/* data completes connection */
+/*			 0x00000200	   unused */
+/*			 0x00000400	   unused */
+/*			 0x00000800	   unused */
+/*			 0x00001000	   unused */
+#define	MSG_NOTIFICATION 0x00002000	/* SCTP notification */
+#define	MSG_NBIO	 0x00004000	/* FIONBIO mode, used by fifofs */
+#define	MSG_COMPAT       0x00008000		/* used in sendit() */
 #endif
 #ifdef _KERNEL
-#define	MSG_SOCALLBCK   0x10000		/* for use by socket callbacks - soreceive (TCP) */
-#define	MSG_MORETOCOME	0x20000		/* additional data pending */
+#define	MSG_SOCALLBCK    0x00010000	/* for use by socket callbacks - soreceive (TCP) */
+#endif
+#if __POSIX_VISIBLE >= 200809
+#define	MSG_NOSIGNAL	 0x00020000	/* do not generate SIGPIPE on EOF */
+#endif
+#if __BSD_VISIBLE
+#define	MSG_CMSG_CLOEXEC 0x00040000	/* make received fds close-on-exec */
+#define	MSG_WAITFORONE	 0x00080000	/* for recvmmsg() */
+#endif
+#ifdef _KERNEL
+#define	MSG_MORETOCOME	 0x00100000	/* additional data pending */
 #endif
 
 /*
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
index 7dc341ca483..33d5b59e0f3 100644
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -128,9 +128,10 @@ struct socket {
 	uint32_t so_user_cookie;
 
 	int so_ts_clock;	/* type of the clock used for timestamps */
+	uint32_t so_max_pacing_rate;	/* (f) TX rate limit in bytes/s */
 
-	void *so_pspare[2];	/* packet pacing / general use */
-	int so_ispare[2];	/* packet pacing / general use */
+	void *so_pspare[2];	/* general use */
+	int so_ispare[2];	/* general use */
 };
 
 /*
diff --git a/sys/sys/sx.h b/sys/sys/sx.h
index 57a31d9aace..e8cffaa2593 100644
--- a/sys/sys/sx.h
+++ b/sys/sys/sx.h
@@ -88,6 +88,11 @@
 
 #define	sx_recurse	lock_object.lo_data
 
+#define	SX_READ_VALUE(sx)	((sx)->sx_lock)
+
+#define	lv_sx_owner(v) \
+	((v & SX_LOCK_SHARED) ? NULL : (struct thread *)SX_OWNER(v))
+
 /*
  * Function prototipes.  Routines that start with an underscore are not part
  * of the public interface and are wrappered with a macro.
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index f5a45f1c178..0b5c61765d7 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -100,6 +100,9 @@ __FBSDID("$FreeBSD$");
 #include "opt_directio.h"
 #include "opt_ffs.h"
 
+#define	ALIGNED_TO(ptr, s)	\
+	(((uintptr_t)(ptr) & (_Alignof(s) - 1)) == 0)
+
 #ifdef DIRECTIO
 extern int	ffs_rawread(struct vnode *vp, struct uio *uio, int *workdone);
 #endif
@@ -1100,46 +1103,30 @@ ffs_extwrite(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *ucred)
  * the length of the EA, and possibly the pointer to the entry and to the data.
  */
 static int
-ffs_findextattr(u_char *ptr, u_int length, int nspace, const char *name, u_char **eap, u_char **eac)
+ffs_findextattr(u_char *ptr, u_int length, int nspace, const char *name,
+    struct extattr **eapp, u_char **eac)
 {
-	u_char *p, *pe, *pn, *p0;
-	int eapad1, eapad2, ealength, ealen, nlen;
-	uint32_t ul;
+	struct extattr *eap, *eaend;
+	size_t nlen;
 
-	pe = ptr + length;
 	nlen = strlen(name);
-
-	for (p = ptr; p < pe; p = pn) {
-		p0 = p;
-		bcopy(p, &ul, sizeof(ul));
-		pn = p + ul;
+	KASSERT(ALIGNED_TO(ptr, struct extattr), ("unaligned"));
+	eap = (struct extattr *)ptr;
+	eaend = (struct extattr *)(ptr + length);
+	for (; eap < eaend; eap = EXTATTR_NEXT(eap)) {
 		/* make sure this entry is complete */
-		if (pn > pe)
+		if (EXTATTR_NEXT(eap) > eaend)
 			break;
-		p += sizeof(uint32_t);
-		if (*p != nspace)
+		if (eap->ea_namespace != nspace || eap->ea_namelength != nlen
+		    || memcmp(eap->ea_name, name, nlen) != 0)
 			continue;
-		p++;
-		eapad2 = *p++;
-		if (*p != nlen)
-			continue;
-		p++;
-		if (bcmp(p, name, nlen))
-			continue;
-		ealength = sizeof(uint32_t) + 3 + nlen;
-		eapad1 = 8 - (ealength % 8);
-		if (eapad1 == 8)
-			eapad1 = 0;
-		ealength += eapad1;
-		ealen = ul - ealength - eapad2;
-		p += nlen + eapad1;
-		if (eap != NULL)
-			*eap = p0;
+		if (eapp != NULL)
+			*eapp = eap;
 		if (eac != NULL)
-			*eac = p;
-		return (ealen);
+			*eac = EXTATTR_CONTENT(eap);
+		return (EXTATTR_CONTENT_SIZE(eap));
 	}
-	return(-1);
+	return (-1);
 }
 
 static int
@@ -1380,9 +1367,11 @@ vop_deleteextattr {
 {
 	struct inode *ip;
 	struct fs *fs;
-	uint32_t ealength, ul;
-	int ealen, olen, eapad1, eapad2, error, i, easize;
-	u_char *eae, *p;
+	struct extattr *eap;
+	uint32_t ul;
+	int olen, error, i, easize;
+	u_char *eae;
+	void *tmp;
 
 	ip = VTOI(ap->a_vp);
 	fs = ITOFS(ip);
@@ -1413,39 +1402,30 @@ vop_deleteextattr {
 	if (error)
 		return (error);
 
-	ealength = eapad1 = ealen = eapad2 = 0;
-
+	/* CEM: delete could be done in-place instead */
 	eae = malloc(ip->i_ea_len, M_TEMP, M_WAITOK);
 	bcopy(ip->i_ea_area, eae, ip->i_ea_len);
 	easize = ip->i_ea_len;
 
 	olen = ffs_findextattr(eae, easize, ap->a_attrnamespace, ap->a_name,
-	    &p, NULL);
+	    &eap, NULL);
 	if (olen == -1) {
 		/* delete but nonexistent */
 		free(eae, M_TEMP);
 		ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td);
-		return(ENOATTR);
+		return (ENOATTR);
 	}
-	bcopy(p, &ul, sizeof ul);
-	i = p - eae + ul;
-	if (ul != ealength) {
-		bcopy(p + ul, p + ealength, easize - i);
-		easize += (ealength - ul);
-	}
-	if (easize > NXADDR * fs->fs_bsize) {
-		free(eae, M_TEMP);
-		ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td);
-		if (ip->i_ea_area != NULL && ip->i_ea_error == 0)
-			ip->i_ea_error = ENOSPC;
-		return(ENOSPC);
-	}
-	p = ip->i_ea_area;
+	ul = eap->ea_length;
+	i = (u_char *)EXTATTR_NEXT(eap) - eae;
+	bcopy(EXTATTR_NEXT(eap), eap, easize - i);
+	easize -= ul;
+
+	tmp = ip->i_ea_area;
 	ip->i_ea_area = eae;
 	ip->i_ea_len = easize;
-	free(p, M_TEMP);
+	free(tmp, M_TEMP);
 	error = ffs_close_ea(ap->a_vp, 1, ap->a_cred, ap->a_td);
-	return(error);
+	return (error);
 }
 
 /*
@@ -1499,7 +1479,7 @@ vop_getextattr {
 		error = ENOATTR;
 
 	ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td);
-	return(error);
+	return (error);
 }
 
 /*
@@ -1519,9 +1499,7 @@ vop_listextattr {
 */
 {
 	struct inode *ip;
-	u_char *eae, *p, *pe, *pn;
-	unsigned easize;
-	uint32_t ul;
+	struct extattr *eap, *eaend;
 	int error, ealen;
 
 	ip = VTOI(ap->a_vp);
@@ -1537,31 +1515,31 @@ vop_listextattr {
 	error = ffs_open_ea(ap->a_vp, ap->a_cred, ap->a_td);
 	if (error)
 		return (error);
-	eae = ip->i_ea_area;
-	easize = ip->i_ea_len;
 
 	error = 0;
 	if (ap->a_size != NULL)
 		*ap->a_size = 0;
-	pe = eae + easize;
-	for(p = eae; error == 0 && p < pe; p = pn) {
-		bcopy(p, &ul, sizeof(ul));
-		pn = p + ul;
-		if (pn > pe)
+
+	KASSERT(ALIGNED_TO(ip->i_ea_area, struct extattr), ("unaligned"));
+	eap = (struct extattr *)ip->i_ea_area;
+	eaend = (struct extattr *)(ip->i_ea_area + ip->i_ea_len);
+	for (; error == 0 && eap < eaend; eap = EXTATTR_NEXT(eap)) {
+		/* make sure this entry is complete */
+		if (EXTATTR_NEXT(eap) > eaend)
 			break;
-		p += sizeof(ul);
-		if (*p++ != ap->a_attrnamespace)
+		if (eap->ea_namespace != ap->a_attrnamespace)
 			continue;
-		p++;	/* pad2 */
-		ealen = *p;
-		if (ap->a_size != NULL) {
+
+		ealen = eap->ea_namelength;
+		if (ap->a_size != NULL)
 			*ap->a_size += ealen + 1;
-		} else if (ap->a_uio != NULL) {
-			error = uiomove(p, ealen + 1, ap->a_uio);
-		}
+		else if (ap->a_uio != NULL)
+			error = uiomove(&eap->ea_namelength, ealen + 1,
+			    ap->a_uio);
 	}
+
 	ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td);
-	return(error);
+	return (error);
 }
 
 /*
@@ -1582,10 +1560,12 @@ vop_setextattr {
 {
 	struct inode *ip;
 	struct fs *fs;
+	struct extattr *eap;
 	uint32_t ealength, ul;
 	ssize_t ealen;
 	int olen, eapad1, eapad2, error, i, easize;
-	u_char *eae, *p;
+	u_char *eae;
+	void *tmp;
 
 	ip = VTOI(ap->a_vp);
 	fs = ITOFS(ip);
@@ -1625,29 +1605,33 @@ vop_setextattr {
 		return (error);
 
 	ealength = sizeof(uint32_t) + 3 + strlen(ap->a_name);
-	eapad1 = 8 - (ealength % 8);
-	if (eapad1 == 8)
-		eapad1 = 0;
-	eapad2 = 8 - (ealen % 8);
-	if (eapad2 == 8)
-		eapad2 = 0;
+	eapad1 = roundup2(ealength, 8) - ealength;
+	eapad2 = roundup2(ealen, 8) - ealen;
 	ealength += eapad1 + ealen + eapad2;
 
+	/*
+	 * CEM: rewrites of the same size or smaller could be done in-place
+	 * instead.  (We don't acquire any fine-grained locks in here either,
+	 * so we could also do bigger writes in-place.)
+	 */
 	eae = malloc(ip->i_ea_len + ealength, M_TEMP, M_WAITOK);
 	bcopy(ip->i_ea_area, eae, ip->i_ea_len);
 	easize = ip->i_ea_len;
 
-	olen = ffs_findextattr(eae, easize,
-	    ap->a_attrnamespace, ap->a_name, &p, NULL);
+	olen = ffs_findextattr(eae, easize, ap->a_attrnamespace, ap->a_name,
+	    &eap, NULL);
         if (olen == -1) {
 		/* new, append at end */
-		p = eae + easize;
+		KASSERT(ALIGNED_TO(eae + easize, struct extattr),
+		    ("unaligned"));
+		eap = (struct extattr *)(eae + easize);
 		easize += ealength;
 	} else {
-		bcopy(p, &ul, sizeof ul);
-		i = p - eae + ul;
+		ul = eap->ea_length;
+		i = (u_char *)EXTATTR_NEXT(eap) - eae;
 		if (ul != ealength) {
-			bcopy(p + ul, p + ealength, easize - i);
+			bcopy(EXTATTR_NEXT(eap), (u_char *)eap + ealength,
+			    easize - i);
 			easize += (ealength - ul);
 		}
 	}
@@ -1656,34 +1640,30 @@ vop_setextattr {
 		ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td);
 		if (ip->i_ea_area != NULL && ip->i_ea_error == 0)
 			ip->i_ea_error = ENOSPC;
-		return(ENOSPC);
+		return (ENOSPC);
 	}
-	bcopy(&ealength, p, sizeof(ealength));
-	p += sizeof(ealength);
-	*p++ = ap->a_attrnamespace;
-	*p++ = eapad2;
-	*p++ = strlen(ap->a_name);
-	strcpy(p, ap->a_name);
-	p += strlen(ap->a_name);
-	bzero(p, eapad1);
-	p += eapad1;
-	error = uiomove(p, ealen, ap->a_uio);
+	eap->ea_length = ealength;
+	eap->ea_namespace = ap->a_attrnamespace;
+	eap->ea_contentpadlen = eapad2;
+	eap->ea_namelength = strlen(ap->a_name);
+	memcpy(eap->ea_name, ap->a_name, strlen(ap->a_name));
+	bzero(&eap->ea_name[strlen(ap->a_name)], eapad1);
+	error = uiomove(EXTATTR_CONTENT(eap), ealen, ap->a_uio);
 	if (error) {
 		free(eae, M_TEMP);
 		ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td);
 		if (ip->i_ea_area != NULL && ip->i_ea_error == 0)
 			ip->i_ea_error = error;
-		return(error);
+		return (error);
 	}
-	p += ealen;
-	bzero(p, eapad2);
+	bzero((u_char *)EXTATTR_CONTENT(eap) + ealen, eapad2);
 
-	p = ip->i_ea_area;
+	tmp = ip->i_ea_area;
 	ip->i_ea_area = eae;
 	ip->i_ea_len = easize;
-	free(p, M_TEMP);
+	free(tmp, M_TEMP);
 	error = ffs_close_ea(ap->a_vp, 1, ap->a_cred, ap->a_td);
-	return(error);
+	return (error);
 }
 
 /*
diff --git a/sys/ufs/ufs/extattr.h b/sys/ufs/ufs/extattr.h
index 6b4987cc2b6..73f97556c6e 100644
--- a/sys/ufs/ufs/extattr.h
+++ b/sys/ufs/ufs/extattr.h
@@ -73,11 +73,12 @@ struct ufs_extattr_header {
  * This structure defines the required fields of an extended-attribute header.
  */
 struct extattr {
-	int32_t	ea_length;	    /* length of this attribute */
-	int8_t	ea_namespace;	    /* name space of this attribute */
-	int8_t	ea_contentpadlen;   /* bytes of padding at end of attribute */
-	int8_t	ea_namelength;	    /* length of attribute name */
-	char	ea_name[1];	    /* null-terminated attribute name */
+	uint32_t ea_length;	    /* length of this attribute */
+	uint8_t	ea_namespace;	    /* name space of this attribute */
+	uint8_t	ea_contentpadlen;   /* bytes of padding at end of attribute */
+	uint8_t	ea_namelength;	    /* length of attribute name */
+	char	ea_name[1];	    /* attribute name (NOT nul-terminated) */
+	/* padding, if any, to align attribute content to 8 byte boundary */
 	/* extended attribute content follows */
 };
 
@@ -90,26 +91,16 @@ struct extattr {
  *	content referenced by eap.
  * EXTATTR_CONTENT_SIZE(eap) returns the size of the extended attribute
  *	content referenced by eap.
- * EXTATTR_SET_LENGTHS(eap, contentsize) called after initializing the
- *	attribute name to calculate and set the ea_length, ea_namelength,
- *	and ea_contentpadlen fields of the extended attribute structure.
  */
 #define	EXTATTR_NEXT(eap) \
-	((struct extattr *)(((void *)(eap)) + (eap)->ea_length))
-#define	EXTATTR_CONTENT(eap) (((void *)(eap)) + EXTATTR_BASE_LENGTH(eap))
+	((struct extattr *)(((u_char *)(eap)) + (eap)->ea_length))
+#define	EXTATTR_CONTENT(eap) \
+	(void *)(((u_char *)(eap)) + EXTATTR_BASE_LENGTH(eap))
 #define	EXTATTR_CONTENT_SIZE(eap) \
 	((eap)->ea_length - EXTATTR_BASE_LENGTH(eap) - (eap)->ea_contentpadlen)
+/* -1 below compensates for ea_name[1] */
 #define	EXTATTR_BASE_LENGTH(eap) \
-	((sizeof(struct extattr) + (eap)->ea_namelength + 7) & ~7)
-#define	EXTATTR_SET_LENGTHS(eap, contentsize) do { \
-	KASSERT(((eap)->ea_name[0] != 0), \
-		("Must initialize name before setting lengths")); \
-	(eap)->ea_namelength = strlen((eap)->ea_name); \
-	(eap)->ea_contentpadlen = ((contentsize) % 8) ? \
-		8 - ((contentsize) % 8) : 0; \
-	(eap)->ea_length = EXTATTR_BASE_LENGTH(eap) + \
-		(contentsize) + (eap)->ea_contentpadlen; \
-} while (0)
+	roundup2((sizeof(struct extattr) - 1 + (eap)->ea_namelength), 8)
 
 #ifdef _KERNEL
 
@@ -149,13 +140,6 @@ int	ufs_deleteextattr(struct vop_deleteextattr_args *ap);
 int	ufs_setextattr(struct vop_setextattr_args *ap);
 void	ufs_extattr_vnode_inactive(struct vnode *vp, struct thread *td);
 
-#else
-
-/* User-level definition of KASSERT for macros above */
-#define	KASSERT(cond, str) do { \
-        if (!(cond)) { printf("panic: "); printf(str); printf("\n"); exit(1); }\
-} while (0)
-
 #endif /* !_KERNEL */
 
 #endif /* !_UFS_UFS_EXTATTR_H_ */
diff --git a/tools/tools/ath/athalq/ar9300_ds.c b/tools/tools/ath/athalq/ar9300_ds.c
index a554929f28e..541ee39eaf7 100644
--- a/tools/tools/ath/athalq/ar9300_ds.c
+++ b/tools/tools/ath/athalq/ar9300_ds.c
@@ -38,6 +38,24 @@ __FBSDID("$FreeBSD$");
 #define	MS(_v, _f)	( ((_v) & (_f)) >> _f##_S )
 #define	MF(_v, _f) ( !! ((_v) & (_f)))
 
+static uint32_t last_ts = 0;
+
+void
+ath_alq_print_edma_tx_fifo_push(struct if_ath_alq_payload *a)
+{
+	struct if_ath_alq_tx_fifo_push p;
+
+	memcpy(&p, &a->payload, sizeof(p));
+	printf("[%u.%06u] [%llu] TXPUSH txq=%d, nframes=%d, fifodepth=%d, frmcount=%d\n",
+	    (unsigned int) be32toh(a->hdr.tstamp_sec),
+	    (unsigned int) be32toh(a->hdr.tstamp_usec),
+	    (unsigned long long) be64toh(a->hdr.threadid),
+	    be32toh(p.txq),
+	    be32toh(p.nframes),
+	    be32toh(p.fifo_depth),
+	    be32toh(p.frame_cnt));
+}
+
 static void
 ar9300_decode_txstatus(struct if_ath_alq_payload *a)
 {
@@ -46,19 +64,25 @@ ar9300_decode_txstatus(struct if_ath_alq_payload *a)
 	/* XXX assumes txs is smaller than PAYLOAD_LEN! */
 	memcpy(&txs, &a->payload, sizeof(struct ar9300_txs));
 
-	printf("[%u.%06u] [%llu] TXSTATUS\n",
+	printf("[%u.%06u] [%llu] TXSTATUS TxTimestamp=%u (%u), DescId=0x%04x, QCU=%d\n",
 	    (unsigned int) be32toh(a->hdr.tstamp_sec),
 	    (unsigned int) be32toh(a->hdr.tstamp_usec),
-	    (unsigned long long) be64toh(a->hdr.threadid));
+	    (unsigned long long) be64toh(a->hdr.threadid),
+	    txs.status4,
+	    txs.status4 - last_ts,
+	    (unsigned int) MS(txs.status1, AR_tx_desc_id),
+	    (unsigned int) MS(txs.ds_info, AR_tx_qcu_num));
 	printf("    DescId=0x%08x\n", txs.status1);
 
+	last_ts = txs.status4;
+
 	printf("    DescLen=%d, TxQcuNum=%d, CtrlStat=%d, DescId=0x%04x\n",
 	    txs.ds_info & 0xff,
 	    MS(txs.ds_info, AR_tx_qcu_num),
 	    MS(txs.ds_info, AR_ctrl_stat),
 	    MS(txs.ds_info, AR_desc_id));
 
-	printf("    TxTimestamp=0x%08x\n", txs.status4);
+	printf("    TxTimestamp: %u\n", txs.status4);
 
 	printf("    TxDone=%d, SeqNo=%d, TxOpExceed=%d, TXBFStatus=%d\n",
 	    MF(txs.status8, AR_tx_done),
@@ -130,10 +154,11 @@ ar9300_decode_txdesc(struct if_ath_alq_payload *a)
 	/* XXX assumes txs is smaller than PAYLOAD_LEN! */
 	memcpy(&txc, &a->payload, 96);
 
-	printf("[%u.%06u] [%llu] TXD\n",
+	printf("[%u.%06u] [%llu] TXD DescId=0x%04x\n",
 	    (unsigned int) be32toh(a->hdr.tstamp_sec),
 	    (unsigned int) be32toh(a->hdr.tstamp_usec),
-	    (unsigned long long) be64toh(a->hdr.threadid));
+	    (unsigned long long) be64toh(a->hdr.threadid),
+	    (unsigned int) MS(txc.ds_ctl10, AR_tx_desc_id));
 
 	printf("  DescLen=%d, TxQcuNum=%d, CtrlStat=%d, DescId=0x%04x\n",
 	    txc.ds_info & 0xff,
@@ -313,10 +338,12 @@ ar9300_decode_rxstatus(struct if_ath_alq_payload *a)
 	/* XXX assumes rxs is smaller than PAYLOAD_LEN! */
 	memcpy(&rxs, &a->payload, sizeof(struct ar9300_rxs));
 
-	printf("[%u.%06u] [%llu] RXSTATUS\n",
+	printf("[%u.%06u] [%llu] RXSTATUS RxTimestamp: %u (%d)\n",
 	    (unsigned int) be32toh(a->hdr.tstamp_sec),
 	    (unsigned int) be32toh(a->hdr.tstamp_usec),
-	    (unsigned long long) be64toh(a->hdr.threadid));
+	    (unsigned long long) be64toh(a->hdr.threadid),
+	    rxs.status3,
+	    rxs.status3 - last_ts);
 
 	/* status1 */
 	/* .. and status5 */
@@ -338,7 +365,8 @@ ar9300_decode_rxstatus(struct if_ath_alq_payload *a)
 	    MS(rxs.status2, AR_hw_upload_data));
 
 	/* status3 */
-	printf("    RX timestamp: %d\n", rxs.status3);
+	printf("    RX timestamp: %u\n", rxs.status3);
+	last_ts = rxs.status3;
 
 	/* status4 */
 	printf("    GI: %d, 2040: %d, parallel40: %d, stbc=%d\n",
diff --git a/tools/tools/ath/athalq/ar9300_ds.h b/tools/tools/ath/athalq/ar9300_ds.h
index daf507bbb72..d0394cb3fe2 100644
--- a/tools/tools/ath/athalq/ar9300_ds.h
+++ b/tools/tools/ath/athalq/ar9300_ds.h
@@ -19,5 +19,6 @@
 #define	__AR9300_DS_H__
 
 extern	void ar9300_alq_payload(struct if_ath_alq_payload *a);
+extern	void ath_alq_print_edma_tx_fifo_push(struct if_ath_alq_payload *a);
 
 #endif	/* __AR9300_DS_H__ */
diff --git a/tools/tools/ath/athalq/main.c b/tools/tools/ath/athalq/main.c
index c5ba9ef5240..c8c2c335f56 100644
--- a/tools/tools/ath/athalq/main.c
+++ b/tools/tools/ath/athalq/main.c
@@ -186,6 +186,9 @@ main(int argc, const char *argv[])
 			case ATH_ALQ_RESUME_BEACON:
 				ath_alq_print_beacon_resume(a);
 				break;
+			case ATH_ALQ_TX_FIFO_PUSH:
+				ath_alq_print_edma_tx_fifo_push(a);
+				break;
 			default:
 				if (be32toh(hdr.sc_hal_magic) == AR5210_MAGIC)
 					ar5210_alq_payload(a);
@@ -195,10 +198,8 @@ main(int argc, const char *argv[])
 					ar5212_alq_payload(a);
 				else if (be32toh(hdr.sc_hal_magic) == AR5416_MAGIC)
 					ar5416_alq_payload(a);
-#if 1
 				else if (be32toh(hdr.sc_hal_magic) == AR9300_MAGIC)
 					ar9300_alq_payload(a);
-#endif
 				else
 					printf("[%d.%06d] [%lld] op: %d; len %d\n",
 					    be32toh(a->hdr.tstamp_sec),
diff --git a/usr.bin/cut/tests/Makefile b/usr.bin/cut/tests/Makefile
index 310994e0e61..aaf15d4ba43 100644
--- a/usr.bin/cut/tests/Makefile
+++ b/usr.bin/cut/tests/Makefile
@@ -2,6 +2,7 @@
 
 PACKAGE=	tests
 
+ATF_TESTS_SH+=	cut2_test
 NETBSD_ATF_TESTS_SH=	cut_test
 
 ${PACKAGE}FILES=		d_basic.out
diff --git a/usr.bin/cut/tests/cut2_test.sh b/usr.bin/cut/tests/cut2_test.sh
new file mode 100755
index 00000000000..e5aaa9a38fb
--- /dev/null
+++ b/usr.bin/cut/tests/cut2_test.sh
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2017 Dell EMC
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+atf_test_case s_flag
+s_flag_head()
+{
+	atf_set "descr" "Check -s flag"
+}
+
+s_flag_body()
+{
+	cat >input<
diff --git a/usr.bin/mandoc/Makefile.depend b/usr.bin/mandoc/Makefile.depend
index 7c705f5b3c9..1fe4610a2f0 100644
--- a/usr.bin/mandoc/Makefile.depend
+++ b/usr.bin/mandoc/Makefile.depend
@@ -10,8 +10,6 @@ DIRDEPS = \
 	lib/libc \
 	lib/libcompiler_rt \
 	lib/libopenbsd \
-	lib/libsqlite3 \
-	lib/libthr \
 	lib/libz \
 
 
diff --git a/usr.bin/sed/tests/Makefile b/usr.bin/sed/tests/Makefile
index 0d017e1299e..abd1a2bb51f 100644
--- a/usr.bin/sed/tests/Makefile
+++ b/usr.bin/sed/tests/Makefile
@@ -2,11 +2,16 @@
 
 PACKAGE=	tests
 
+ATF_TESTS_SH+=	sed2_test
+NETBSD_ATF_TESTS_SH+=	sed_test
 TAP_TESTS_SH=	legacy_test
 TAP_TESTS_SH+=	multi_test
 TEST_METADATA.multi_test+=	required_files="/usr/share/dict/words"
 TAP_TESTS_SH+=	inplace_race_test
 
+ATF_TESTS_SH_SED_sed_test+=	-e 's,atf_expect_fail "PR bin/28126",,g'
+${PACKAGE}FILES+=		d_c2048.in
+
 ${PACKAGE}FILES+=		hanoi.sed
 ${PACKAGE}FILES+=		math.sed
 ${PACKAGE}FILES+=		regress.G.out
@@ -35,4 +40,5 @@ ${PACKAGE}FILES+=		regress.y.out
 
 SUBDIR=		regress.multitest.out
 
+.include 
 .include 
diff --git a/usr.bin/sed/tests/sed2_test.sh b/usr.bin/sed/tests/sed2_test.sh
new file mode 100755
index 00000000000..3ce3008deeb
--- /dev/null
+++ b/usr.bin/sed/tests/sed2_test.sh
@@ -0,0 +1,61 @@
+#
+# Copyright 2017 Dell EMC.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+
+atf_test_case inplace_hardlink_src
+inplace_hardlink_src_head()
+{
+	atf_set "descr" "Verify -i works with a symlinked source file"
+}
+inplace_hardlink_src_body()
+{
+	echo foo > a
+	atf_check ln a b
+	atf_check sed -i '' -e 's,foo,bar,g' b
+	atf_check -o 'inline:bar\n' -s exit:0 cat b
+}
+
+atf_test_case inplace_symlink_src
+inplace_symlink_src_head()
+{
+	atf_set "descr" "Verify -i works with a symlinked source file"
+}
+inplace_symlink_src_body()
+{
+	atf_expect_fail "Check for S_IFREG reverted in r312404"
+
+	echo foo > a
+	atf_check ln -s a b
+	atf_check -e not-empty -s not-exit:0 sed -i '' -e 's,foo,bar,g' b
+}
+
+atf_init_test_cases()
+{
+	atf_add_test_case inplace_hardlink_src
+	atf_add_test_case inplace_symlink_src
+}
diff --git a/usr.sbin/bsnmpd/modules/Makefile b/usr.sbin/bsnmpd/modules/Makefile
index 8d118e7f826..60c253b7187 100644
--- a/usr.sbin/bsnmpd/modules/Makefile
+++ b/usr.sbin/bsnmpd/modules/Makefile
@@ -2,7 +2,7 @@
 
 .include 
 
-.PATH: ${.CURDIR}/../../../contrib/bsnmp/snmpd
+.PATH: ${SRCTOP}/contrib/bsnmp/snmpd
 
 .if ${MK_ATM} != "no"
 _snmp_atm= snmp_atm
@@ -36,4 +36,6 @@ SUBDIR+=snmp_wlan
 INCS=	snmpmod.h
 INCSDIR= ${INCLUDEDIR}/bsnmp
 
+SUBDIR_TARGETS+=	smilint
+
 .include 
diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile b/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile
index 0895f56de92..7166a4e41eb 100644
--- a/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile
+++ b/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile
@@ -75,8 +75,3 @@ LIBADD=	kvm devinfo m geom memstat
 
 printcap.pico: printcap.c
 	${CC} ${PICFLAG} -DPIC ${CFLAGS:C/^-W.*//} -c ${.IMPSRC} -o ${.TARGET}
-
-smilint: .PHONY
-smilint: ${BMIBS}
-	env SMIPATH=.:/usr/share/snmp/mibs:/usr/local/share/snmp/mibs \
-	    smilint -c /dev/null -l6 -i group-membership ${.ALLSRC}
diff --git a/usr.sbin/bsnmpd/modules/snmp_mibII/Makefile b/usr.sbin/bsnmpd/modules/snmp_mibII/Makefile
index 6362c0b7cf6..22be4123110 100644
--- a/usr.sbin/bsnmpd/modules/snmp_mibII/Makefile
+++ b/usr.sbin/bsnmpd/modules/snmp_mibII/Makefile
@@ -21,8 +21,3 @@ INCS=	snmp_${MOD}.h
 BMIBS=	BEGEMOT-IP-MIB.txt BEGEMOT-MIB2-MIB.txt
 
 .include 
-
-smilint: .PHONY
-smilint: ${BMIBS}
-	env SMIPATH=/usr/share/snmp/mibs:/usr/local/share/snmp/mibs \
-	    smilint -c /dev/null -l6 -i group-membership ${.ALLSRC}
diff --git a/usr.sbin/camdd/camdd.c b/usr.sbin/camdd/camdd.c
index 1bcd091cd2b..05225f6a86e 100644
--- a/usr.sbin/camdd/camdd.c
+++ b/usr.sbin/camdd/camdd.c
@@ -420,9 +420,9 @@ struct camdd_dev {
 };
 
 static sem_t camdd_sem;
-static int need_exit = 0;
-static int error_exit = 0;
-static int need_status = 0;
+static sig_atomic_t need_exit = 0;
+static sig_atomic_t error_exit = 0;
+static sig_atomic_t need_status = 0;
 
 #ifndef min
 #define	min(a, b) (a < b) ? a : b
@@ -712,11 +712,7 @@ camdd_alloc_buf(struct camdd_dev *dev, camdd_buf_type buf_type)
 	return (buf);
 
 bailout_error:
-	if (data_ptr != NULL)
-		free(data_ptr);
-
-	if (buf != NULL)
-		free(buf);
+	free(data_ptr);
 
 	return (NULL);
 }
@@ -2262,6 +2258,7 @@ camdd_file_run(struct camdd_dev *dev)
 		if (file_dev->tmp_buf == NULL) {
 			buf->status = CAMDD_STATUS_ERROR;
 			error_count++;
+			pthread_mutex_lock(&dev->mutex);
 			goto bailout;
 		}
 		for (i = 0, cur_offset = 0; i < data->sg_count; i++) {
@@ -2984,7 +2981,6 @@ int
 camdd_rw(struct camdd_io_opts *io_opts, int num_io_opts, uint64_t max_io,
 	 int retry_count, int timeout)
 {
-	char *device = NULL;
 	struct cam_device *new_cam_dev = NULL;
 	struct camdd_dev *devs[2];
 	struct timespec start_time;
@@ -3004,12 +3000,11 @@ camdd_rw(struct camdd_io_opts *io_opts, int num_io_opts, uint64_t max_io,
 	for (i = 0; i < num_io_opts; i++) {
 		switch (io_opts[i].dev_type) {
 		case CAMDD_DEV_PASS: {
-			camdd_argmask new_arglist = CAMDD_ARG_NONE;
-			int bus = 0, target = 0, lun = 0;
-			char name[30];
-			int rv;
-
 			if (isdigit(io_opts[i].dev_name[0])) {
+				camdd_argmask new_arglist = CAMDD_ARG_NONE;
+				int bus = 0, target = 0, lun = 0;
+				int rv;
+
 				/* device specified as bus:target[:lun] */
 				rv = parse_btl(io_opts[i].dev_name, &bus,
 				    &target, &lun, &new_arglist);
@@ -3025,23 +3020,21 @@ camdd_rw(struct camdd_io_opts *io_opts, int num_io_opts, uint64_t max_io,
 					lun = 0;
 					new_arglist |= CAMDD_ARG_LUN;
 				}
+				new_cam_dev = cam_open_btl(bus, target, lun,
+				    O_RDWR, NULL);
 			} else {
+				char name[30];
+
 				if (cam_get_device(io_opts[i].dev_name, name,
 						   sizeof name, &unit) == -1) {
 					warnx("%s", cam_errbuf);
 					error = 1;
 					goto bailout;
 				}
-				device = strdup(name);
-				new_arglist |= CAMDD_ARG_DEVICE |CAMDD_ARG_UNIT;
+				new_cam_dev = cam_open_spec_device(name, unit,
+				    O_RDWR, NULL);
 			}
 
-			if (new_arglist & (CAMDD_ARG_BUS | CAMDD_ARG_TARGET))
-				new_cam_dev = cam_open_btl(bus, target, lun,
-				    O_RDWR, NULL);
-			else
-				new_cam_dev = cam_open_spec_device(device, unit,
-				    O_RDWR, NULL);
 			if (new_cam_dev == NULL) {
 				warnx("%s", cam_errbuf);
 				error = 1;
diff --git a/usr.sbin/ctld/pdu.c b/usr.sbin/ctld/pdu.c
index 77b9526d420..189ab2ab1a0 100644
--- a/usr.sbin/ctld/pdu.c
+++ b/usr.sbin/ctld/pdu.c
@@ -106,9 +106,11 @@ pdu_new_response(struct pdu *request)
 static void
 pdu_receive_proxy(struct pdu *pdu)
 {
+	struct connection *conn;
 	size_t len;
 
 	assert(proxy_mode);
+	conn = pdu->pdu_connection;
 
 	kernel_receive(pdu);
 
@@ -117,7 +119,7 @@ pdu_receive_proxy(struct pdu *pdu)
 		log_errx(1, "protocol error: non-empty AHS");
 
 	len = pdu_data_segment_length(pdu);
-	assert(len <= pdu->pdu_connection->conn_max_recv_data_segment_length);
+	assert(len <= (size_t)conn->conn_max_recv_data_segment_length);
 	pdu->pdu_data_len = len;
 }
 
@@ -185,7 +187,7 @@ pdu_receive(struct pdu *pdu)
 
 	len = pdu_data_segment_length(pdu);
 	if (len > 0) {
-		if ((int)len > conn->conn_max_recv_data_segment_length) {
+		if (len > (size_t)conn->conn_max_recv_data_segment_length) {
 			log_errx(1, "protocol error: received PDU "
 			    "with DataSegmentLength exceeding %d",
 			    conn->conn_max_recv_data_segment_length);
diff --git a/usr.sbin/iscsid/pdu.c b/usr.sbin/iscsid/pdu.c
index 42224467b20..8db69ea3288 100644
--- a/usr.sbin/iscsid/pdu.c
+++ b/usr.sbin/iscsid/pdu.c
@@ -106,13 +106,15 @@ pdu_new_response(struct pdu *request)
 static void
 pdu_receive_proxy(struct pdu *pdu)
 {
+	struct connection *conn;
 	struct iscsi_daemon_receive *idr;
 	size_t len;
 	int error;
 
-	assert(pdu->pdu_connection->conn_conf.isc_iser != 0);
+	conn = pdu->pdu_connection;
+	assert(conn->conn_conf.isc_iser != 0);
 
-	pdu->pdu_data = malloc(ISCSI_MAX_DATA_SEGMENT_LENGTH);
+	pdu->pdu_data = malloc(conn->conn_max_recv_data_segment_length);
 	if (pdu->pdu_data == NULL)
 		log_err(1, "malloc");
 
@@ -120,12 +122,12 @@ pdu_receive_proxy(struct pdu *pdu)
 	if (idr == NULL)
 		log_err(1, "calloc");
 
-	idr->idr_session_id = pdu->pdu_connection->conn_session_id;
+	idr->idr_session_id = conn->conn_session_id;
 	idr->idr_bhs = pdu->pdu_bhs;
-	idr->idr_data_segment_len = ISCSI_MAX_DATA_SEGMENT_LENGTH;
+	idr->idr_data_segment_len = conn->conn_max_recv_data_segment_length;
 	idr->idr_data_segment = pdu->pdu_data;
 
-	error = ioctl(pdu->pdu_connection->conn_iscsi_fd, ISCSIDRECEIVE, idr);
+	error = ioctl(conn->conn_iscsi_fd, ISCSIDRECEIVE, idr);
 	if (error != 0)
 		log_err(1, "ISCSIDRECEIVE");
 
@@ -134,7 +136,7 @@ pdu_receive_proxy(struct pdu *pdu)
 		log_errx(1, "protocol error: non-empty AHS");
 
 	len = pdu_data_segment_length(pdu);
-	assert(len <= ISCSI_MAX_DATA_SEGMENT_LENGTH);
+	assert(len <= (size_t)conn->conn_max_recv_data_segment_length);
 	pdu->pdu_data_len = len;
 
 	free(idr);
@@ -143,10 +145,12 @@ pdu_receive_proxy(struct pdu *pdu)
 static void
 pdu_send_proxy(struct pdu *pdu)
 {
+	struct connection *conn;
 	struct iscsi_daemon_send *ids;
 	int error;
 
-	assert(pdu->pdu_connection->conn_conf.isc_iser != 0);
+	conn = pdu->pdu_connection;
+	assert(conn->conn_conf.isc_iser != 0);
 
 	pdu_set_data_segment_length(pdu, pdu->pdu_data_len);
 
@@ -154,12 +158,12 @@ pdu_send_proxy(struct pdu *pdu)
 	if (ids == NULL)
 		log_err(1, "calloc");
 
-	ids->ids_session_id = pdu->pdu_connection->conn_session_id;
+	ids->ids_session_id = conn->conn_session_id;
 	ids->ids_bhs = pdu->pdu_bhs;
 	ids->ids_data_segment_len = pdu->pdu_data_len;
 	ids->ids_data_segment = pdu->pdu_data;
 
-	error = ioctl(pdu->pdu_connection->conn_iscsi_fd, ISCSIDSEND, ids);
+	error = ioctl(conn->conn_iscsi_fd, ISCSIDSEND, ids);
 	if (error != 0)
 		log_err(1, "ISCSIDSEND");
 
@@ -204,18 +208,18 @@ pdu_read(const struct connection *conn, char *data, size_t len)
 void
 pdu_receive(struct pdu *pdu)
 {
+	struct connection *conn;
 	size_t len, padding;
 	char dummy[4];
 
+	conn = pdu->pdu_connection;
 #ifdef ICL_KERNEL_PROXY
-	if (pdu->pdu_connection->conn_conf.isc_iser != 0)
+	if (conn->conn_conf.isc_iser != 0)
 		return (pdu_receive_proxy(pdu));
 #endif
+	assert(conn->conn_conf.isc_iser == 0);
 
-	assert(pdu->pdu_connection->conn_conf.isc_iser == 0);
-
-	pdu_read(pdu->pdu_connection,
-	    (char *)pdu->pdu_bhs, sizeof(*pdu->pdu_bhs));
+	pdu_read(conn, (char *)pdu->pdu_bhs, sizeof(*pdu->pdu_bhs));
 
 	len = pdu_ahs_length(pdu);
 	if (len > 0)
@@ -223,10 +227,10 @@ pdu_receive(struct pdu *pdu)
 
 	len = pdu_data_segment_length(pdu);
 	if (len > 0) {
-		if (len > ISCSI_MAX_DATA_SEGMENT_LENGTH) {
+		if (len > (size_t)conn->conn_max_recv_data_segment_length) {
 			log_errx(1, "protocol error: received PDU "
 			    "with DataSegmentLength exceeding %d",
-			    ISCSI_MAX_DATA_SEGMENT_LENGTH);
+			    conn->conn_max_recv_data_segment_length);
 		}
 
 		pdu->pdu_data_len = len;
@@ -234,14 +238,12 @@ pdu_receive(struct pdu *pdu)
 		if (pdu->pdu_data == NULL)
 			log_err(1, "malloc");
 
-		pdu_read(pdu->pdu_connection,
-		    (char *)pdu->pdu_data, pdu->pdu_data_len);
+		pdu_read(conn, (char *)pdu->pdu_data, pdu->pdu_data_len);
 
 		padding = pdu_padding(pdu);
 		if (padding != 0) {
 			assert(padding < sizeof(dummy));
-			pdu_read(pdu->pdu_connection,
-			    (char *)dummy, padding);
+			pdu_read(conn, (char *)dummy, padding);
 		}
 	}
 }
@@ -249,18 +251,20 @@ pdu_receive(struct pdu *pdu)
 void
 pdu_send(struct pdu *pdu)
 {
+	struct connection *conn;
 	ssize_t ret, total_len;
 	size_t padding;
 	uint32_t zero = 0;
 	struct iovec iov[3];
 	int iovcnt;
 
+	conn = pdu->pdu_connection;
 #ifdef ICL_KERNEL_PROXY
-	if (pdu->pdu_connection->conn_conf.isc_iser != 0)
+	if (conn->conn_conf.isc_iser != 0)
 		return (pdu_send_proxy(pdu));
 #endif
 
-	assert(pdu->pdu_connection->conn_conf.isc_iser == 0);
+	assert(conn->conn_conf.isc_iser == 0);
 
 	pdu_set_data_segment_length(pdu, pdu->pdu_data_len);
 	iov[0].iov_base = pdu->pdu_bhs;
@@ -284,7 +288,7 @@ pdu_send(struct pdu *pdu)
 		}
 	}
 
-	ret = writev(pdu->pdu_connection->conn_socket, iov, iovcnt);
+	ret = writev(conn->conn_socket, iov, iovcnt);
 	if (ret < 0) {
 		if (timed_out())
 			log_errx(1, "exiting due to timeout");